Commit graph

110 commits

Author SHA1 Message Date
Francisco Solla
fcefcac4e6 style: prettier format dos docs da entrega C120 2026-08-24 19:03:29 -03:00
Francisco Solla
6c582bbb3f fix(contact): C120 — serializa o append de telefone no reuso com lock de ficha (Closes #663) 2026-08-24 19:03:29 -03:00
Francisco Solla
d0161f6d69 test(e2e): unificar logins do usuário de teste no helper adminHeaders com advisory lock (Closes #767) 2026-08-24 18:42:03 -03:00
Francisco Solla
a180721e11 feat(campaign): C144 — forms de escrita com options de município write-scoped (Closes #769) 2026-08-24 18:37:59 -03:00
Francisco Solla
339508a7c1 test(e2e): B195-F1 — gate S: no spec do wizard Registrar pedido (cópia de stream duplica o form sob carga) 2026-08-24 18:37:33 -03:00
Francisco Solla
1423cf1758 test: scope C113 live feed to claimed municipality (E2E-FLAKE-C113) 2026-08-24 18:23:47 -03:00
Francisco Solla
0bb8a96485 feat(campanha): B155+ — migrar quick-edits de célula de lideranças para rota JSON (célula → rota)
F2: POST /campanha/liderancas/state-deputies substitui
setLeadershipStateDeputyMembershipFormAction (chips de /campanha/liderancas B31
e /campanha/dobradinhas B36 — mesma action record).
F3: POST /campanha/liderancas/municipalities substitui
setLeadershipMunicipalitiesFormAction (B34).
Wrappers 'use client' LeadershipStateDeputiesColumnCell /
LeadershipMunicipalitiesColumnCell mantêm o contrato (state, formData) das
shared cells (intocadas); rotas reusam os schemas exportados + allowlists
floor/cap/scope; revalidate herdado das actions record (contrato B34/B31).
F1 (sinal de municípios) não existe mais: C87 o substituiu por form
multi-campo, que por regra B155 permanece em server action — registrado
como já resolvido no plano de intenção.
Guards: whitelist sharedSheetHostConventions (+2 wrappers), prewarm e2e
(+2 rotas), B34 aponta para a rota nova. Sem migration/UI (Impeccable A).

Closes #368
2026-08-24 18:14:56 -03:00
Francisco Solla
5844f026db fix(social-feed): deadline próprio de 5s no hook do save de credenciais encurta a janela de row lock (Closes #762) 2026-08-24 18:03:37 -03:00
Francisco Solla
c66a863263 style(changelog): prettier no registro B160 2026-08-24 18:00:20 -03:00
Francisco Solla
23a061098a feat(campaign): serializa mutações do editor de relações por célula (Closes #378)
Fila encadeada por instância no MunicipalityRelationEditor: delta otimista
imediato + transporte serializado (próximo elo só dispara quando o anterior
assenta), falha reverte só o delta do próprio elo e a fila segue, busy
derivado da fila (nunca preso), drain aplica o último selectedIDs confirmado
só quando a resposta final o traz (JSON) — sem ele (dobradinhas) confia no
RSC. Substitui requestSeqRef/latestConfirmedRef-seq por fila; tempID de
create em contador próprio. Contratos dos wrappers e call sites intactos.
2026-08-24 18:00:20 -03:00
Francisco Solla
19683a0efb fix(petition): Lead tracking não falha mais assinatura commitada — guarda interna try/catch + spec (Closes #766) 2026-08-24 17:52:45 -03:00
Francisco Solla
b4484ec604 fix(social-feed): S11-POLISH rota sync 400 em não-configurado e dedup InstagramPersistDatabase (Closes #761)
Rota POST /api/social-feed/sync devolve 400 { ok:false, error } quando IG não configurado (antes 200 status:{}), alinhando ao impl doc S11; sem revalidateTag no branch 400. InstagramPersistDatabase deduplicado: alias de PostgresTransactionDatabase (owner único), instagramSync importa owner direto.

Co-authored-by: opencode/muse-spark-1.2-contributor-free
2026-08-24 17:46:50 -03:00
Francisco Solla
807d937e92 fix(test): DEBT-FLAKES-C100 — silence review sample 10→30 + ensureLeasedConsent ON CONFLICT idempotent (Closes #553) 2026-08-24 17:37:14 -03:00
Francisco Solla
facce55eda fix(OPS94): fila de claim não morre mais em issue ready sem frontmatter id (skip + aviso; #659 ganha id B195-F1)
- buildClaimQueue exclui Issues ready sem frontmatter id (não viram worktree
  por construção) e withoutIdReadyIssues() expõe as puladas
- agent:claim / worktree next / pnpm issue next avisam com os números em vez
  de morrer — uma Issue quebrada não trava mais a fila
- pin novo em agentPoolEligibility.unit.spec.ts

Closes #864
2026-08-24 17:23:59 -03:00
Francisco Solla
d816e3ff41 chore(OPS92): consolidar MCPs — global só jina+playwright; penpot/postgres subagentes; gh CLI; re-homed (Closes #857)
Global (~/.config/opencode/opencode.jsonc) fica só com jina+playwright (remove github/postgres/forgejo/stalwart/office-word/jobspy) — manual como OPS89.
Repo Teqo opencode.json: penpot+postgres com permission gated (penpot*/postgres*/query deny no build, allow só nos subagentes penpot/postgres).
Novos .opencode/agent/penpot.md + postgres.md (mode subagent, docs de limite teqo vs teqo_wt*).
Re-homed: jobspy→jobs, forgejo+office-word→lei-mercados-digitais, forgejo+stalwart→infra-solla (remove postgres pin, AGENTS.md sem office-word), forgejo→iara-pwa (limpa pins postgres/stalwart).
Prosa: AGENTS-infra.md, prompt-montagem-home.md, project-status/engineering-audit sem MCP/pnpm issue.
Validação: opencode debug config nos 5 repos (Teqo 4, jobs 3, lei 6, infra 7, iara 3 MCPs), gh auth ok, gate:fast verde.
2026-08-24 17:18:53 -03:00
Francisco Solla
2920aa9d63 docs(changelog): OPS93 flags de modelo no worktree CLI (Closes #859) 2026-08-24 17:08:39 -03:00
Francisco Solla
1b846463b0 test(e2e): OPS87 — migrar asserções de servidor para HTTP sem browser (Concepts + PermissionProfile + People) + medir −65% (Closes #833) 2026-08-24 16:57:08 -03:00
Francisco Solla
4ee25e31d8 fix(ci): curated result surfaces unmapped risk files before high-risk early-return
Hoist collectUnmappedSrc helper in selectE2eSpecs so unmapped risk-area
files are computed before the high-risk early-return. When high-risk wins
and risk files lack a manifest entry, the curated result now includes
them in unmapped and appends '; curated + risk files without mapping: ...'
to reason — mode stays curated.

Pin: testAffected gains combined case (migration + unmapped risk file →
curated with unmapped in reason). Closes #846.
2026-08-24 16:52:52 -03:00
Francisco Solla
87ffda56e7 docs(changelog): OPS77 — flip pós-merge GH_TOKEN→GITHUB_TOKEN fechado com evidência (Closes #783) 2026-08-24 16:41:03 -03:00
Francisco Solla
6eb40362d9 review(OPS88): simplify — build surface do reset, contrato high-risk, erros rotulados, docs canônicos 2026-08-24 16:12:44 -03:00
Francisco Solla
7d7fee1619 feat(OPS88): verify do CI/deploy com um Postgres e reset determinístico, um build por run (Closes #834) 2026-08-24 16:12:44 -03:00
Francisco Solla
d29b790306 chore(e2e): E2E-DEBT-S-GATE — extract waitForStreamSettled helper and migrate 21 sites across 5 specs (Closes #827) 2026-08-24 16:01:08 -03:00
Francisco Solla
9af4b92851 ops(OPS86): blast radius dos testes — curated e2e em high-risk, fail-closed para risco sem mapping, unit/int full na seleção vazia (Closes #832) 2026-08-24 15:19:52 -03:00
Francisco Solla
3b32dbc814 fix(OPS83-recurr): cast rotativa do verify #16 — serializar admin atrás do frontend (stub IG compartilhado) + notificação pula recipient sumido em vez de abortar transação 2026-08-24 15:11:39 -03:00
Francisco Solla
6f6e9fb4b4 ops(OPS91): sweep pós-cutover — textos vivos que apontavam o tracker ao Forgejo passam para o GitHub (Closes #841) 2026-08-24 15:08:14 -03:00
Francisco Solla
2aa445dd1d impl(OPS84): verificar valores (não só entidades) da migração — 13 tabelas, 0 diffs (Closes #828) 2026-08-24 15:03:31 -03:00
Francisco Solla
60a71eea4b feat(OPS85): matar o agregado commitado do changelog — registro por-arquivo + HISTORY congelado + leitura sob demanda (Closes #830) 2026-08-24 14:44:25 -03:00
Francisco Solla
b083840b8f docs(OPS90): codificar a pirâmide de testes unit→int→e2e-com-benefício nos donos certos (Closes #838) 2026-08-24 14:20:59 -03:00
Francisco Solla
ae79eb507c chore(OPS89): variantes Vercel AI Gateway para a config global do opencode (Closes #836)
- opencode.json: removido provider.vercel inteiro — repo fica $schema + mcp.penpot
- docblock de OPENCODE_PRESET_MODEL e prosa de worktree-next-issue/SKILL.md apontam para ~/.config/opencode/opencode.jsonc
- Forgejo → GitHub na linha reescrita da skill (rastro pós-cutover)
- impl plan + changelog da entrega; débito OPS91 (#841) registrado com plano
2026-08-24 14:05:59 -03:00
Francisco Solla
e4cb8d1006 fix(e2e): OPS83 — estabilizar os e2e do verify sem reduzir cobertura; AgendaFeed roda em prod (Closes #824) 2026-08-24 07:27:49 -03:00
Francisco Solla
a2db543e0c ops(OPS82): preset do launch opencode → DeepSeek V4 Flash 0731 (mais barato) + variantes low/high/max + remoção duplicata cheapest-inference (Closes #817) 2026-08-23 23:20:45 -03:00
Francisco Solla
bddbd5c085 ops(OPS79): última migração de dados em produção — reconciliação da vertical campanha (Neon→teqo_1313) + migração do residual público (Closes #797)
- scripts/reconcile-campaign-vertical.mjs: verificação read-only repetível (contagens + junta de IDs das 13 coleções da vertical + conteúdo semântico das rels); absorve os 3 links de edição de portfolio pós-OPS51; nunca imprime PII
- scripts/migrate-signature-orphan.mjs: migração one-off com guard OPS79_MIGRATE_CONFIRM=1, dry-run/apply, transação única, PII mascarada
- Execução 100% no homeserver: aplicado contact 2225 + signature 1486 preservada + subscription 1492; sequences ajustadas; pós-verificação signature 1485=1485 e reconcile 19/19
- Runbook (docs/ops/teqo-1313-deploy.md §OPS79): execução + rollback (DELETE 3 linhas + setval)
- docs: plano de intenção restaurado (deletado acidentalmente em C140) + impl plan + changelog
2026-08-23 22:45:43 -03:00
Francisco Solla
9039b1bbd3 fix(e2e): C142 — add C106 shell-settle before write-chrome assertions to unblock deploy
The FAB in campaignPermissionProfile:85/:101 (carteira/tudo write present)
and the advisor checkbox in campaignMunicipalities:115 (editar page) failed
consistently under 4-worker CI load because the RSC streaming shell's
S:* copies hadn't settled when networkidle resolved, and the default
expect/action timeout wasn't sufficient on the constrained hosted runner.

A probe proved the FAB SSR-renders correctly for carteira/tudo advisors
(profile scope is honored; no seed false-negative). The fix adds the
C106 shell-settle (document.querySelectorAll('div[id^=S:]').length === 0)
before the presence assertions, matching the established idiom used by
the sibling campaign spec tests.

21/21 passed at E2E_PROD=1 PLAYWRIGHT_WORKERS=4 repeat-each=3.
gate:fast (2439 unit tests) all green.
2026-08-23 22:13:52 -03:00
Francisco Solla
1d762755d9 feat(campaign): editor de permissão do assessor em modal central (desktop) + bottom drawer (mobile) no lugar do popover (Closes #813) 2026-08-23 20:41:29 -03:00
Francisco Solla
5b4e5ecf22 ops(OOPS80): cutoff fase 1 — desativar acesso pela URL antiga pt.jorgesolla.com.br (congelar a fonte)
- scripts/check-push-chain.mjs: default --site, usage, erro → canônico; prosa Neon/vercel → homeserver
- tests: fixtures unit (WebAuthn, JsonMutation, aiMarkdownLinks) + int (campaignMultiPhones) → canônico, semântica preservada
- campaignMultiPhones: adiciona ensureLeasedConsent para invite consent fixture (fix pre-existente)
- personas (.opencode/agent/designer, solla-comunicacao, skill): canônico + operação homeserver
- docs: intenção + impl plan + changelog entry; CHANGELOG-AGENTS append-only preservado
- Sem migration, sem schema, sem access/Consent, sem UI
- Closes #796
2026-08-23 20:14:59 -03:00
Francisco Solla
6f4a4bd689 docs(OPS76-DOCS): polish do banner histórico — wrap multi-linha e line refs corretos 2026-08-23 20:06:40 -03:00
Francisco Solla
1f31045dc8 docs(OPS76-DOCS): banner histórico em paradigma-agentes-paralelos.md (órfão pré-main com refs mortas) (Closes #800) 2026-08-23 20:06:40 -03:00
Francisco Solla
cd26fb8ce2 fix(e2e): serializa o beforeEach UI login do admin com o advisory lock 727001 (Closes #805) 2026-08-23 19:10:21 -03:00
Francisco Solla
368f138282 feat(campaign): C88 deliberação na atualização — responsável, fio e resolvido (Closes #397)
Migration 20260823_161905_add_municipality_update_deliberation + access por mutationKind + ilha client nas 3 superfícies + specs unit/int/e2e.
2026-08-23 18:58:26 -03:00
Francisco Solla
9467e0f292 fix(campaign): C140 — manual dispatch in 18 forms prevents React 19 form reset on error
Fix manual dispatch em 18 formulários de /campanha que usavam <form action={submitAction}>: campos não controlados voltavam ao defaultValue após qualquer action assentada (sucesso ou erro) do React 19.

- WizardStepFormChrome alterado uma vez (cobre 3 wizard steps)
- 15 forms recebem dispatch manual arquivo a arquivo
- AdvisorPasswordResetButton (2 micro-forms sem campo digitável) ficou como está
- Unit spec novo campaignWizardStepFormChrome.unit.spec.tsx
- CHANGELOG-AGENTS.md cleaned (98 duplicates removed)

Also fixes:
- campaignPageActor writable gate only blocks advisors (was blocking coordinators too)
- campaignLeaderships e2e stability (waitForLoadState before attribute assertion)
2026-08-23 17:54:19 -03:00
Francisco Solla
a97cd56fce fix(campaign): desbloqueia deploy — gate 'writable' libera coordinator/candidate e FAB ganha data-slot do e2e (C142)
Dois bugs do C142 que o e2e full do verify do deploy pegou (o PR rodou só o blast radius):
- requireCampaignPageActor gate 'writable' checava advisorEditingAccess(user)==='none', que retorna 'none' para QUALQUER papel não-advisor — barrava coordinator/candidate de páginas de escrita (municipios/[slug]/editar redirecionava o coordinator pro detalhe).
- CampaignQuickActionsFab não renderizava data-slot='campaign-quick-actions-fab', o locator do e2e campaignPermissionProfile.
Regressões pino: campaignPageActorGate.unit.spec.ts (5 casos) + assert de data-slot no spec do FAB.
Verificado: tsc/lint/format/cycles, unit 2435, int 819, e2e local dos specs afetados (os 3 casos que falhavam no deploy passam).
2026-08-23 16:41:40 -03:00
Francisco Solla
67c213585c ops(OPS78): launch do worktree opencode roteia pelo Vercel AI Gateway com variantes low/high/max (Closes #784) 2026-08-23 16:08:12 -03:00
Francisco Solla
9886347e5b style(OPS73-FOLLOWUP): prettier no changelog da entrega 2026-08-23 15:54:49 -03:00
Francisco Solla
5b7448832b ops(OPS73-FOLLOWUP): fecha #760 — resíduos da race do usuário compartilhado no e2e (lock único de login) + docs drift 2026-08-23 15:54:49 -03:00
Francisco Solla
038758eb81 docs(OPS47): alinha plano do agent-pool à política main-based pós-OPS71
- agent-pool-orchestrator.md: PR --base stage + issue-done-on-stage-merge.yml
  + promote stage→main viram --base main + issue-done-on-main-merge.yml
  + sem promote; migration-lock → countOpenSchemaPrs; model-selection →
  agent-pool-models.mjs; agent-github.mjs → agent-forgejo.mjs; workflow
  marcado removido OPS65 (caminho real .forgejo/workflows/agent-pool.yml)
- agent-pool/SKILL.md: L79 sem 'Antes do promote'; L105 agent-pool-github→forgejo
- comentário/label: agent-pool-state.mjs 'merge in stage'→main;
  agentPoolState.unit.spec.ts label 'on stage merge'→main
- changelog 2026-08-23-ops47.md (Closes #735)
2026-08-23 15:23:52 -03:00
Francisco Solla
dddbd920e0 fix(OPS46-S1): hook ESM tenta resolução bare do next/cache antes do remap (Closes #789) 2026-08-23 15:02:16 -03:00
Francisco Solla
f029c6f86e fix(S12): deep link #novidades aterrissa no formulário no mobile
A home é dona do container de scroll interno (h-dvh overflow-y-auto, body
overflow-hidden), então a navegação nativa por fragmento não aterrissa no
alvo; no mobile o reflow do h-dvh + imagens eager do hero deslocam o layout
após o scroll inicial.

Novo componente cliente CampaignHashScroll (renderiza null) montado no
layout da home: retenta o hash inicial até a seção entrar no viewport
(parando na primeira interação do usuário) e ouve hashchange para âncoras
in-page. scrollIntoView sem behavior herda scroll-smooth/motion-reduce.

E2E novos: describe mobile (load direto, CTA, reduced-motion) + load direto
desktop em describe próprio (evita corrida no beforeAll de consent).
2026-08-23 14:27:15 -03:00
Francisco Solla
89bf9d0854 ops(OPS46): e2e local coleta via hook ESM (next/cache + server-only) e allocator de município com registry anti-wrap (Closes #733)
Fase 1: playwright bare (--list, extensão VS Code, runs ad-hoc) quebrava na
coleta — next@15 sem exports não resolve 'next/cache' em ESM nativo e
server-only exige a condição react-server; o script test:e2e carregava ambas
via NODE_OPTIONS (por isso o CI passava). Hook de resolução ESM vitest-free
(e2eEsmResolve.mjs) registrada no main via module.register + propagada aos
workers via NODE_OPTIONS quando invocada bare; path do script intocado.

Fase 2: a sequência persistente campaign_fixture_municipality_alloc nunca é
resetada e um ciclo completo claima ~505 do catálogo de 435 — o wrap em todo
ciclo em DB de worktree fazia dois runs concorrentes receberem o mesmo índice
e purgarem as linhas vivas um do outro. Registry de claims compartilhado
vitest-free (campaignMunicipalityAllocator.ts): INSERT ON CONFLICT DO NOTHING
com skip de slot vivo, steal de claim stale (TTL 2h), release no cleanup dos
dois fixtures, erro claro de exaustão. Guard estático no
testMunicipalityAllocatorConventions + spec int de stress.
2026-08-23 14:02:19 -03:00
Francisco Solla
5ea288a88b docs(E1): changelog da extração do useAsyncSearchOptions 2026-08-23 13:16:47 -03:00
Francisco Solla
8fec5c0765 docs(C142): changelog da entrega do respeito ao perfil somente_leitura 2026-08-21 23:01:35 -03:00