Commit graph

1380 commits

Author SHA1 Message Date
Francisco Ignácio Fontoura Solla
4211a548f6 docs: registra débitos do /simplify pós-B23 no plano (paridade a11y da nota de tendência, wrapper Popover+tooltip) 2026-07-26 03:24:55 -03:00
Francisco Ignácio Fontoura Solla
d4b7aab50e B23: tooltip de conteudo nas celulas Assessores/Tendencia de /campanha/municipios
- openOnTouch/disabled em CampaignHoverTooltip para conviver com Popover
  sem roubar o tap nem sobreviver atras dele; falsy content agora renderiza
  o trigger sem wrapper (colapsa o ternario nos dois consumidores)
- formatAdvisorNamesTooltip + advisorEntriesFromIds compartilhado
  (MunicipalityAdvisorAvatarStack) para dedupe entre lista e controle
- MunicipalityListAdvisorsControl: hover mostra nomes completos (coordenador)
- MunicipalityListTrendControl: hover mostra a justificativa (politicalTrend.note,
  E4R), com whitespace-pre-wrap preservado; leitura tambem dentro do Popover em toque
- testes unit dos wrappers/no-op e do helper

/simplify (pos-rebase): corrigido HEADER_TOOLTIP_COUNT (4->10) no teste da
celula de assessores, que ficou obsoleto depois do rebase absorver o B22
(10 tooltips de header no thead staff) - o teste passava a comparar 5 vs 11
sem essa correcao; formatAdvisorNamesTooltip agora tipa ReactElement | null
em vez de ReactNode, removendo os casts 'as React.ReactElement' no teste;
comentarios de baixa informacao removidos/enxugados em CampaignHoverTooltip
e nos dois controles; docs: plano, roadmap e notebook do projeto marcados
como entregues.

Gate verde: tsc, lint (0 warnings), format, 446 unit, build anterior verde.
Aikido: 0 findings.
2026-07-26 03:21:45 -03:00
Francisco Ignácio Fontoura Solla
fb4ba831c8 B22: explicacao por coluna no header das listas — description em CampaignTableHead/MunicipalitySortableHead, campaignConceptOneLiner como fonte unica E18, municipalityColumnDescriptions cobrindo as 11 colunas de /campanha/municipios
/simplify: extrai campaignHoverExplanationClassName/campaignHoverTooltipAlign para CampaignHoverTooltip.tsx (elimina duplicacao entre CampaignTableHead, MunicipalitySortableHead e MunicipalityGoalAccountCard), troca non-null assertion de campaignConceptOneLiner por lookup em Record, corrige copy da coluna Assessores (coordenador, nao candidato) e restaura comentario de invariante do sort de goalCoverage
2026-07-26 02:58:54 -03:00
Francisco Ignácio Fontoura Solla
520613f862 E10+ registra os debitos do /simplify do E10 como fill-in de engenharia
Quatro fases num plano so (escala-dry-pos-e10): leitura unica da tabela na lista,
memo de processo dos potenciais por municipio, TooltipProvider unico no layout e
multi-filtros do mobile saindo das definitions.

A F1 nao e achado novo: o A11 ja tinha adiado a "hidratacao unica do sort derivado"
com gatilho "3o path derivado no loader" — com classe o loader chegou ao 4o
(votos, deficit, frescor, classe), entao o adiado do A11 fica riscado e apontando
para o item novo. Reforcada tambem a nota de gatilho do disclosure em
conta-da-cadeira.md (a classe entrou acima da dl, nao como 5a metrica).

Descartados no triage, com racional no plano: formatador de percentual proprio do
TerritoryListColumns, os tres caches do classificador e o ruido do knip com
payload.config.ts (ja ledgerado P3, e a evidencia da sessao contradiz).
2026-07-25 22:38:28 -03:00
Francisco Ignácio Fontoura Solla
63fe4431bf E10: classificacao territorial relativa (Reduto/Expansao/Manutencao/Marginal/Sem base) sobre o artefato TSE, com coluna+sort+filtro na lista, badge no card da conta da cadeira e na capa do dossie; seam generico cellTooltip na CampaignTable e promocao do CampaignHoverTooltip para shared 2026-07-25 21:59:20 -03:00
Francisco Ignácio Fontoura Solla
a9e1900290 B21: cria página própria dos territórios
Leva a leitura dos 27 Territórios de Identidade para o sistema de listas com estado canônico na URL e remove o painel duplicado do Início.
2026-07-25 21:50:24 -03:00
Francisco Ignácio Fontoura Solla
619666dd51 C13 pos-simplify: fecha os residuos da varredura e estreita os guards
O rename mecanico deixou um defeito silencioso e alguns fosseis: o fixture de
recentVisits perdeu o ${index} (todas as entradas com o mesmo label, invisivel
porque o label nao era asserido) e access/shared.ts guardava "action plan" em
prosa, forma que o guard de vocabulario nao cobria. O padrao agora tolera espaco
e a allowlist encolheu: o comentario de campaignMigrationReconciliation cita
activity e o arquivo saiu da excecao.

Na migration, a entrada action_plan_municipality_idx era inalcancavel (nenhuma
migration jamais criou esse nome) e saiu, deixando up() e down() com os mesmos
48 pares; as duas buscas de FK passam a usar to_regclass, que retorna NULL em vez
de lancar -- a unica consulta que contradizia a invariante do proprio cabecalho.

O detalhe de organizacao para de derivar o rotulo de status a mao e reusa
ActivityStatusBadge, com status tipado como ActivityStatus no loader.

Debitos do /simplify registrados: C8 F4b (o guard de formActions so inspeciona
arquivos chamados exatamente formActions.ts) no plano do C8; defers e descartes
com gatilho no plano do C13.
2026-07-25 21:29:32 -03:00
Francisco Ignácio Fontoura Solla
7b93c232ff C13: renomeia "Plano de Acao" para "Atividade" em toda a vertical /campanha
Collection actionPlan -> activity (labels "Atividade"/"Atividades"), campo
campaignDemand.actionPlan -> activity, rota /campanha/planos ->
/campanha/atividades (criacao em atividades/nova), sidebar "Atividades" e
rotulos alinhados a entidade ("Tipo de atividade", "Origem da atividade",
"Resultado da atividade"). Valores de enum kind/status/origin inalterados.

Schema movido por migration data-preserving escrita a mao
(20260725_213000_rename_action_plan_to_activity): 4 tabelas, 3 enums, 2
colunas, 39 indices (4 pkeys inclusos), 14 FKs e 2 sequences, cada statement
guardado na existencia do objeto de origem, com down() simetrico. O gerador do
Payload emitiria DROP+CREATE e nao ve o indice parcial escrito a mao
action_plan_upcoming_start_at_idx, entao a lista veio de
pg_indexes/pg_constraint/pg_type/pg_sequences e o snapshot .json foi derivado
do anterior por transformacao textual -- validado por migrate:create __probe
sem mudanca de schema. A mesma migration alinha os 8 indices fosseis %plaza%
que a remodelagem de municipios deixou (renomeou as colunas plaza_id, nao os
indices).

Guard: o describe "banned campaign terminology" de
codebaseConventions.unit.spec.ts virou tabela de termos varrendo src+tests+
scripts (migrations fora -- historia congelada), banindo os compostos
actionPlan, a copy "plano de acao" e a rota antiga, mas nao plan/plano isolado
(colidiria com os planos de assinatura da Fase 2). Allowlist: o proprio spec,
scripts/generate-remodel-municipalities-migration.mjs e o comentario historico
em campaignMigrationReconciliation.int.spec.ts.

Plano: docs/plans/renomear-plano-acao-para-atividade.md
2026-07-25 20:50:38 -03:00
Francisco Ignácio Fontoura Solla
228eb36e90 B26: registrar sinal tipado a partir da célula Último sinal na lista de municípios.
Fecha o laço da fila E9 — Popover/Drawer cria municipalityUpdate kind sinal sem sair da varredura; submit explícito multi-campo; revalidate da lista.
2026-07-25 20:42:01 -03:00
Francisco Ignácio Fontoura Solla
68bcaa3ab9 B20: municípios prioritários no Início com déficit E9 e CTA para a lista.
A seção deixa de truncar seis prioritárias sem critério; amostra oito por cobertura central, mostra o total e linka ?priority=alta alinhado à fila de alocação.
2026-07-25 20:01:51 -03:00
Francisco Ignácio Fontoura Solla
288a9265d7 Docs: registra B20–B37, C13 (Atividade) e fill-ins de listas no roadmap e notebook.
Inclui 19 planos de produto (municípios, lideranças, dobradinhas, territórios) e alinha E12/B21 com camada-territorios-identidade.
2026-07-25 19:40:07 -03:00
Francisco Ignácio Fontoura Solla
c00f83d870 Tooling: pnpm db:doctor + preflight no guard-dev-db (remedios nomeados, deteccao de volume compartilhado pos-corrupcao WAL), madge check:cycles e prettier no CI/pre-push, guard rails de data migration no skill, notas de processo (knip --fix, pipes) e gate atualizado nos docs/rules 2026-07-25 18:02:02 -03:00
Francisco Ignácio Fontoura Solla
e6f7c2e70f Tooling: prettier como autoridade de formatacao (organize-imports deterministico, scripts format/format:check, normalizacao mecanica de 312 arquivos; artefatos gerados e migrations excluidos via .prettierignore) 2026-07-25 17:22:20 -03:00
Francisco Ignácio Fontoura Solla
51dd779ddd Pass 2: formatacao da revisao (prettier em tabelas md + ordenacao de imports; SQL da migration inalterado) e remocao de duplicata stray do CampaignListEmptyState no path antigo 2026-07-25 16:53:51 -03:00
Francisco Ignácio Fontoura Solla
e8a440b837 Pass 2 W5: close-out de documentacao
- AGENTS.md: Known Gap #2 resolvido (D3), arvore de estrutura (+AllocationDecision, PrivacyPolicy, CampaignGoals; components por dominio), URLs novas (/campanha/assessores|conceitos|perfil), entrada 'Recently resolved' do Pass 2
- tracker: todos os workstreams done; secao de achados de drift de docs de produto (PRODUCT/DESIGN/CUSTOMER - reportados, nao aplicados)
- TESTING.md: 46/48/7 + linhas do safety net (formActions wrapper, voteTrend, submitWhatsapp)
- TECH-DEBT: smells fechados (municipalityUi split, detail RSCs, formActions, components subpastas, electionInsights)
- planos: status entregue nos 5 do Pass 2; escala-dry-pos-b16 absorvido; C8 F3/F4 fechados em escala-dry-pos-c6; notas de costura em B17/B18/cenario-junto; nota de conflito E4R em mapa-projecao
- roadmap: entrada Pass 2 no 'Ja entregue', B17/B18 marcados como triviais, B16+ riscado, header atualizado
- notebook do projeto: entrada Pass 2
- DESIGN.md: secao do sistema de listas (unico drift aplicado, conforme plano)
2026-07-25 16:08:38 -03:00
Francisco Ignácio Fontoura Solla
304eb34b64 Pass 2 D3: consent do WhatsApp resolvido por chave estavel (fim do consent: 2)
- submitWhatsapp resolve Consent.key = 'whatsapp-inscricao' via requireConsentByKey e FALHA FECHADO com mensagem clara enquanto o documento nao existir
- migration 20260725_170000 (data-only, idempotente, guardada): tagueia o documento vivo id 2 (key vazia/'') com a chave estavel; no-op se ja houver documento com a chave ou se id 2 tiver outra chave; NAO inventa texto juridico (politica Onda 0)
- chave em lib/campaignConsentKeys + lease key nas fixtures; int spec pina fail-closed + caminho feliz (contact + subscription -> consent.id)
- ATENCAO DEPLOY: revisar o SQL antes do push (aplica em producao no build da Vercel)
2026-07-25 16:02:57 -03:00
Francisco Ignácio Fontoura Solla
851f4bee3c Pass 2 W3: docs/ARCHITECTURE.md + .cursor/rules/codebase-map.mdc
- ARCHITECTURE.md: contexto de sistema (3 route groups, 2 barreiras de auth), regra de dependencia como aplicada, fluxo de dados collections->access->loaders->view models->RSC->ilhas, escada de caching, RBAC, bounded contexts + linguagem ubiqua, log de decisoes estruturais (incl. D1/D2/D5 do Pass 2)
- codebase-map.mdc: mapa navegacional compacto always-applied (onde vive o que, sistema de listas, como achar o dono de uma feature, invariantes); convencao: atualizado no mesmo PR que mover modulos
2026-07-25 15:54:13 -03:00
Francisco Ignácio Fontoura Solla
c01467547d Pass 2 W4b: zero exports mortos; knip exports/types/enumMembers em ERROR no CI
- ~190 findings zerados: knip --fix (grafo corrigido: tests como entries, migrations como consumidores) + delecao guardada dos orfaos (git grep -w antes de deletar) + reparos manuais dos corpos arrow pendurados
- pecas nao usadas do kit ui deletadas (PaginationLink/Next/Previous, familias Sidebar/Combobox/Sheet/Drawer/Dialog etc.) - shadcn add recoloca se precisar
- acoes mortas removidas (updateCampaignDemandDetails*, *Record orfaos), schemas/tipos mortos (campaignDemandDetailsUpdateSchema, Contact do zod), helpers mortos
- tipos de eleicao derivam direto das *_OPTIONS (consts intermediarias eliminadas)
- knip.json: rules exports/types/enumMembers=error, duplicates=off (unicos hits: 6 aliases deliberados canUpdateX=canReadX); hints aplicados (payload.config entry redundante, ignores de tsx/sharp/playwright/payload-types desnecessarios)
- ledger: linha P2 dos unused exports fechada
2026-07-25 15:51:52 -03:00
Francisco Ignácio Fontoura Solla
0c1127b35a Pass 2 W4a: electionInsights.ts deletado (941 linhas, 71 exports, 2 vivos)
- formatElectionNumber -> src/lib/electionFormat.ts (13 importers); computeVoteTrend + tipos -> src/lib/voteTrend.ts
- ~52 exports sem consumidor deletados (limiares 35/20/10 da era nucleos, gap vs 2022, conversao, mobilizacao, ticket flip/leverage) - decisao D2; formulas no git history; E10 nasce em modulo novo (nota no plano classificacao-territorial-relativa.md)
- specs: voteTrend.unit.spec.ts (pins vivos + pin do defeito E18 de fracao), electionPartySpectrum.unit.spec.ts sem os blocos de ticket; electionInsights.unit.spec.ts deletado
- fix de regressao W2 pega pelo knip: scripts/import-projecao.mjs importava voteEstimate/slug nos paths antigos (knip agora roda sem pipe mascarando exit code)
- knip unused exports: 157 -> 140
2026-07-25 14:57:49 -03:00
Francisco Ignácio Fontoura Solla
dc9a39f800 Pass 2 W0: pina contratos de URL e loaders das listas + truth-up TESTING/TECH-DEBT
- unit: campaignListUrl (canonicalize/clamp/redirect), supporterUi, actionPlanUi (matriz tab->where), 5 parsers de entidade
- int: campaignEntityListData smokes (escopo por role, busca por marker, shape de paginacao)
- fixtures: suporte a stateDeputy (create + cleanup)
- docs: contagens reais (45/47/7), Praca ~96 hits, conflito C8 F4 resolvido (10 ladders restantes -> W4d)
2026-07-25 13:30:39 -03:00
Francisco Ignácio Fontoura Solla
3812d81261 Pass 2: materializa tracker e planos por workstream (W0-W5, D1-D6) 2026-07-25 13:15:30 -03:00
Francisco Ignácio Fontoura Solla
8430bd0a9f B16: corrige filtros que se anulavam e registra os débitos pós-simplify
A revisão paralela do /simplify achou três defeitos funcionais na entrega
dos filtros no header, todos corrigidos aqui:

- as facetas omitiam só o param multi, então "Prioritária" escondia os
  municípios não-prioritários do popover onde o próprio check mora e
  "Sem assessor" esvaziava o popover de Assessores; cada faceta passa a
  omitir o grupo de params do seu popover (int test cobre os dois casos);
- "todas as tendências" tinha duas codificações — as três marcadas
  deixavam trend= inútil na URL com o funil se declarando inativo; o
  parse agora canonicaliza o conjunto completo para ausente;
- o filtro de Território havia sumido do mobile ao virar multi.

Também devolve o "Limpar" aos popovers curtos (estava preso ao limiar da
busca) e registra o que sobrou como B16+ (escala/DRY), com o
CampaignListEmptyState compartilhado e o firstValue duplicado absorvidos
no C8, e a fragilidade do build sem o global metadata no site público.
2026-07-25 03:44:25 -03:00
Francisco Ignácio Fontoura Solla
96bf362421 B16: Filtros no header da lista de municípios
Popover de filtro por coluna no desktop (multi-seleção OR em município,
território, assessores e tendência; busca acento-insensível e "Limpar"),
mantendo os selects empilhados no mobile. Header sticky com a página como
scroller e empty state que substitui só as linhas de conteúdo, preservando
overview e filtros. Remove a coluna "Assessoria": a ordenação foi para
"Assessores" e o com/sem assessor virou opção do mesmo popover.
2026-07-25 03:13:28 -03:00
Francisco Ignácio Fontoura Solla
2b4f62380e B19: registra gatilho de defer do N+1 no batch de território/ZE
Achado do /simplify pós-entrega (findByID por município ao atribuir um
território de identidade ou zona eleitoral inteira). Sem precedente para
o fix natural (payload.find com id: { in }) e mudaria semântica de erro
para IDs inexistentes; fica como gatilho no plano em vez de item de
roadmap.
2026-07-25 02:43:26 -03:00
Francisco Ignácio Fontoura Solla
01e52834e2 B19: Gerenciar assessores (/campanha/assessores)
Lista+detalhe única de edição para coordinator/candidate: nome, e-mail e
celular com auto-save debounced (edit-where-you-see-it); carteira de
municípios por chips com agregação de território de identidade,
adição/remoção com UI otimista; criação inline no topo da tabela; ação de
WhatsApp por assessor; reset de senha via e-mail (bloqueado para
placeholders @planilha.invalid). Alinha access de update/phone/atribuição
de município a isCampaignUnrestricted (coordinator + candidate).

Sem migration. Testes int (campaignAdvisorManagement) + unit (schema e
portfólio de municípios) cobrindo access, conflito de e-mail único, cap de
assessores por município e agregação por território/ZE.
2026-07-25 02:40:47 -03:00
Francisco Ignácio Fontoura Solla
31fcc20ffd E9 /simplify: consolidate duplicated helpers, dead passthrough, comment drift
Cross-checked by parallel code-quality/performance/reuse reviewers against
the E9 commit. Behavior-preserving:

- laterTimestamp/resolveMunicipalityLastSignalAt were the same "latest of
  two ISO timestamps" written twice; both now delegate to a new
  latestIsoTimestamp in campaignTime.ts, which documents the fixed-width
  UTC invariant that makes the string compare sound.
- Hoisted the frescor comparator's Date.now() out of the per-comparison
  accessor so the sort key stops drifting mid-sort.
- Deleted the unread baseTotal/growthFactor/belowBase passthrough from the
  statewide goal entry point and fixed a comment citing a symbol
  (goalDecompositionBelowBase) that never existed; renamed
  computeStatewideGoalDecomposition -> computeStatewideSuggestedGoals now
  that nothing is proportionally decomposed.
- Collapsed the advisor badge's two copies (desktop table vs mobile card)
  into one AdvisorStatusBadge; they had quietly diverged on which icon
  renders for the "no advisor" state.
- Renamed the sort-menu's stale "Cobertura" label for advisor coverage to
  "Assessoria" (E8 already renamed the list column for the same reason);
  derived the sort-key set from the label record instead of a third
  parallel list.
- Consolidated three zeroed-scenario-record literals into one
  zeroByVoteEstimateScenario() factory in voteEstimate.ts.
- Routed three separate votesByYear[2022] reads through one votesInYear
  helper in municipalityPotential.ts.
- Gated the goal card's empty-state copy on !usesMesaEstimate so it stops
  telling a município with an existing mesa estimate to enter one.
- Swapped a test assertion pinned to a raw Tailwind token for a stable
  data-signal="cold" hook, and tightened the "desert" test's bound to
  check against the actual growth factor (the old bound was true for
  every slug regardless of the formula).

Left alone (roadmap decision, not cleanup): sanityCheckSuggestedGoalsByTerritory
has no production caller yet (deferred to E11/E12); comment shortened
instead of deleting the dead-but-documented code.

Verified: tsc --noEmit, pnpm lint (0 warnings), 337 unit + 366 integration
tests, pnpm build all green.
2026-07-25 02:24:18 -03:00
Francisco Ignácio Fontoura Solla
51c13153fc E9: Fila de alocação (déficit como default do staff, frescor, coluna da vergonha)
A lista de municípios vira a fila de decisão, sem rota nova, sem coluna nova
e sem migration.

Fase 0 corrige a meta sintética do E8, que repartia a meta estadual
proporcionalmente só ao teto do campo e ignorava a votação própria (meta 2.911
para Vitória da Conquista, de 5.005 votos em 2022; 813 para Campo Formoso, de
47). `deriveSuggestedGoalsByScenario` substitui `decomposeStateGoal` e ancora a
meta na votação de 2022 por cenário — pessimista = base × (1 − margin), central
= base, otimista = base × (stateGoal ÷ Σ base), com clamp. `goalCoverage` passa
a receber `SuggestedGoalByScenario`, deixando `expectedVotes[S] ??
suggestedGoal[S]` simétrico. Só descrições do global mudaram.

Fase 1 adiciona frescor e ordenações: `declaredAt`/`estimatedAt` no select do
agregado de pledges (`lastPledgeAt`), `lastSignalAt` no view model via
`resolveMunicipalityLastSignalAt` (mesmo helper para o comparador do servidor e
a célula), e as sort keys `deficit` (novo default do staff) e `frescor`,
derivadas em memória no cenário central.

Fase 2 dobra os sinais nas células existentes: "há N dias" na coluna de última
atualização (frio ≥ 21 dias, em âmbar — vermelho já é da prioridade), badge
"sem responsável" em prioridade alta sem assessor, coluna da vergonha no
detalhe da métrica de assessoria, tooltip de cobertura nomeando o cenário e
copy Praças→Municípios.

Cortes: votos em jogo → B13, LQ/captura → E10, coluna dedicada de déficit
desnecessária.
2026-07-25 02:24:17 -03:00
Francisco Ignácio Fontoura Solla
9443a4e1f6 E18: documentação de conceitos de inteligência de campanha
Nova rota staff-only /campanha/conceitos (glossário curado em
src/lib/campaignIntelligenceConcepts.ts, revisado junto das fórmulas
que descreve em municipalityPotential.ts/goalCoverage.ts) com
descoberta por "Saiba mais" nos tooltips do card "Conta da cadeira" e
entrada fixa no rodapé da sidebar (staffSecondaryNav). Corrige defeito
E8 de formatElectionNumber (meta fracionária lida como cem mil em
pt-BR). Ajustes pós-/simplify: MetricExplanation.conceptID obrigatório,
href da sidebar desacoplado do módulo de conteúdo (client bundle).
2026-07-25 01:37:37 -03:00
Francisco Ignácio Fontoura Solla
2682078fe4 E16: Dossiê do município (pré-agenda) with print view and budgetNotes.
Composes existing loaders into a staff-only pre-visit tab, adds G11 manual emendas notes, and unlocks CSS print for 1–2 A4 pages.
2026-07-25 01:28:03 -03:00
Francisco Ignácio Fontoura Solla
3250300086 Anota gatilho de defer pós-critique no plano do E8
capture-review-debts (auto-confirm) triageou os achados restantes do
/impeccable critique de MunicipalityGoalAccountCard: os 3×P1+P2+P3
confirmados já foram fechados nesta sessão; o resto (naming, redesenho
hipotético de Captura/Share intracampo, disclosure não assentado para
futuras métricas) é cosmético ou prematuro — anotado como defer+gatilho
em "Adiado com gatilho" em vez de virar item novo no roadmap.
2026-07-24 22:57:40 -03:00
Francisco Ignácio Fontoura Solla
717d584f6d E8 follow-up: touch-friendly metric tooltips, 2014/2018 majoritarian seed, E18 docs plan
- MunicipalityHoverTooltip/MunicipalityGoalAccountCard: hover/focus tooltips on
  the 4 "Conta da cadeira" diagnostic numbers, hardened per /impeccable
  critique (touch dead-end fix via controlled open + pointerup toggle +
  outside-tap dismiss, tooltip no longer covers "Cobertura da meta", clearer
  two-tier copy, distinguishable button trigger, thicker 0% progress bar).
- seed-tse-results.mjs/electionResultsBuild/electionResultsParse: seed also
  imports presidente/governador for 2014/2018 (previously deputado federal
  only), with vote-em-transito duplicate merging so the unique constraints
  hold; artifact/formulas stay 2022-only by design.
- Registered E18 (documentacao-conceitos-campanha) roadmap item/plan for a
  future /campanha/conceitos glossary page.
2026-07-24 22:55:51 -03:00
Francisco Ignácio Fontoura Solla
5a4a9033ed E8: Conta da cadeira (metas derivadas, potencial por município, cobertura)
- campoParties.ts + committed election-aggregates artifact v2 (campo federal
  votes, federal tally, 2022 majoritarian presidente/governador)
- global campaignGoals (state goal + margin) with staff-only read /
  unrestricted-write access
- municipalityPotential.ts (teto do campo, captura, share intracampo,
  roll-off, proportional state-goal decomposition) and goalCoverage.ts
  (meta vs comprometido semantics locked this session)
- UI: dashboard + list overview 'Cobertura da meta' metric, new list column,
  detail page 'Conta da cadeira' card
- /simplify pass: dropped dead per-request TI-warning computation, O(1)
  potential lookup, deduped near-identical election loaders/tally types/
  percent formatters
2026-07-24 22:54:27 -03:00
Francisco Ignácio Fontoura Solla
7ac099be42 Register B19 plan for managing advisors in /campanha.
Gives Coordenador Geral and Candidato a path to create and maintain advisor accounts without Payload admin during Onda 0 onboarding.
2026-07-24 20:15:03 -03:00
Francisco Ignácio Fontoura Solla
63910014ad Implement C12 campaign foundation records
Preserve pledge history, type field signals, link plan demands, and record immutable ex-ante allocation decisions.
2026-07-24 19:27:15 -03:00
Francisco Ignácio Fontoura Solla
12d7de4cf1 Register B16–B18 municipality list UX plans and mark column reorder out of scope.
Capture header filters, column visibility, and named saved filters (sidebar shortcuts) in the roadmap, and document why drag-and-drop column reorder stays deferred.
2026-07-24 19:14:01 -03:00
Francisco Ignácio Fontoura Solla
166e1398a3 Document A11/B15 post-simplify deferrals after rebase onto B15. 2026-07-24 18:41:35 -03:00
Francisco Ignácio Fontoura Solla
3c95bc6174 A11: show municipality 2022 vote rank/share and default list sort by votos.
Dense catalog rank plus share of statewide votes on the baseline card and list column (header label 2022), with URL sort/dir and Impeccable polish.
2026-07-24 18:40:56 -03:00
Francisco Ignácio Fontoura Solla
aa94443008 B15: sortable municipality list headers with URL sort/dir state and /simplify cleanup 2026-07-24 18:27:00 -03:00
Francisco Ignácio Fontoura Solla
4cda9ad86a Register fill-in to replace the priority badge with an icon+tooltip on the municipalities list. 2026-07-24 18:25:36 -03:00
Francisco Ignácio Fontoura Solla
b6e5d8be57 Add comparative Identity Territory table to campaign dashboard (E17)
First regional surface in /campanha: a sortable 27-TI overview table on the
Início staff dashboard, next to the municipal map. Per-TI aggregates only
(sums and ratios of aggregates — MAUP safeguard); Metropolitano decomposed
into Salvador (19 zones) vs. demais RMS. Loader is server-only with
overrideAccess:true (regional context, not management; TI-level exposure
only); pure rollup stays client-safe for the sortable table. First slice of
E12, which extends with capture/LQ/meta coverage.
2026-07-24 17:17:31 -03:00
Francisco Ignácio Fontoura Solla
0407f02ce2 Import projection-sheet strategy columns into municipalities (E4R fase 2)
- pnpm db:seed:projecao now also imports SITUAÇÃO -> politicalTrend,
  DOBRADINHAS -> stateDeputy + stateDeputies + dobradinhaNotes,
  LIDERANÇAS -> name-only contact + leadership (statewide slug dedupe),
  ASSESSOR RESPONSÁVEL -> campaignUser + advisors (Edizio=coordinator,
  Solla=candidate, placeholder @planilha.invalid emails),
  ENCAMINHAMENTOS -> nextSteps, OBSERVAÇÃO -> strengths/risks (curated).
  PRIORITÁRIAS overrides MAPA GERAL when non-empty; Salvador stays skipped;
  relationships are unions; re-run is idempotent.
- parseSituationCell + splitNameCell (noise/collective/action filters,
  honorific protection, parenthetical extraction) with unit tests.
- Contact.phone optional (migration 20260724_175500_contact_phone_optional);
  phone invariant hooks skip phone-less contacts; invite flows guard.
- candidate role now eligible for municipality/action-plan advisors
  (eligibleCampaignStaffWhere) per product decision.
2026-07-24 15:58:06 -03:00
Francisco Ignácio Fontoura Solla
df0acc6500 Register B15 column-header sort on the municipalities list. 2026-07-24 14:11:34 -03:00
Francisco Ignácio Fontoura Solla
583a6099c2 Register fill-in to move the Cenário selector next to municipality list filters. 2026-07-24 14:08:28 -03:00
Francisco Ignácio Fontoura Solla
c07969f4a7 Remove duplicated voteGoals; seed projection sheet into expectedVotes.
Meta Bom/Regular/Mínimo duplicated the estimate scenarios — keep a single municipality series (pessimista/média/otimista), backfill then drop the old columns, and map the spreadsheet onto expectedVotes.
2026-07-24 14:04:44 -03:00
Francisco Ignácio Fontoura Solla
d14ed67801 Ship E4R: always-overwrite seed of projection spreadsheet into voteGoals and priority.
One-shot CLI (`pnpm db:seed:projecao`) matches MAPA GERAL to municipalities, skips Salvador, and re-seeds when a newer sheet arrives; dry-run + docs/roadmap updated.
2026-07-24 13:13:46 -03:00
Francisco Ignácio Fontoura Solla
2be41d4f59 Register B14 nearest-municipality geolocation shortcut on the campaign home.
Adds the roadmap item and plan for a staff-only, client-side proximity CTA with a once-per-session location prompt.
2026-07-24 12:45:18 -03:00
Francisco Ignácio Fontoura Solla
e468f4192e Sync roadmap and intel plans with the 2026-07-23 field session; add E4R/A11/E16/E17 plans 2026-07-24 02:54:28 -03:00
Francisco Ignácio Fontoura Solla
adc0f31f5b Sync all project docs with the deployed remodel and hardening; compile roadmap
- Compile docs/roadmap.md into a next-steps document (277→206 lines): R0–R5/M1–M5
  tables and the delivered map/list item paragraphs compressed into 'Já entregue';
  janelas, grafo and cortes list only open IDs; C10/C11/C8 fill-ins keep their
  original triggers; C5 moved under 'A validar'.
- Record the production deploy of the destructive remodel chain (2026-07-23 Vercel
  builds) across roadmap, AGENTS.md, the project notebook and plans — supersedes
  every 'deploy pendente'; smoke pós-deploy + onboarding remain the open blockers.
- Fix AGENTS.md internal contradictions: Município locked-decisions bullet (435,
  Camaçari whole, candidate role), campaignUser role enum, deploy-checklist item 7
  as historical, access/* structure note, election-aggregates artifact +
  election-tse revalidate runbook.
- Sync open plans to real identifiers (plaza*/nucleus* → municipality*): the
  intelligence program (master + E8–E15/B13/C12 with artifact/caching context and
  satisfied deps), B8 rescoped to Salvador ZE 1–19 only, WhatsApp D3–D5, D2, A6
  (now the insight layer over stateDeputy), RS+, onda-0 smoke step.
- Close items verified done in code: C8 F4 (DRY de forms) complete, filtros-auto
  shared pending shell, petition generateStaticParams select/depth; ledger the
  surviving user-visible 'Praça' copy in src as new P2 debt.
- Banner delivered praça-era plans (production note + rename pointer); mark
  remodelagem-pracas.md superseded and remodelagem-municipios.md delivered.
- TECH-DEBT smell statuses, TESTING RBAC row, README quality gates, campanha
  UI rules updated to current component names.
2026-07-24 02:04:45 -03:00
Francisco Ignácio Fontoura Solla
801e969803 Close the hardening tracker: all phases done, e2e flake ledgered 2026-07-24 00:42:24 -03:00
Francisco Ignácio Fontoura Solla
e79f60822e Document the engineering standards for agents and humans
- .cursor/rules/engineering-standards.mdc (always applied): dead code dies
  immediately (knip after every change), zero-warning gate, as-never ban with
  the typed escape hatches, server-first composition and the client-safe
  contract-module pattern, the caching ladder (React cache → unstable_cache +
  tag → committed artifact), explicit collection access, lib vs utilities
  convention, rule-of-three for abstractions
- AGENTS.md: hardening entry with pointers to the tracker/ledger/testing map;
  drift fixed (TopoJSON decode is lazy, collections list post-remodel,
  election-tse in the revalidate allowlist, knip in the verification
  checklist); Known Gap #1 rewritten for the shipped access lockdown
- docs/roadmap.md: admin access item updated; engineering-debt section points
  at TECH-DEBT.md
- tracker phases updated; removed two stale pre-rename file copies
2026-07-23 23:45:20 -03:00
Francisco Ignácio Fontoura Solla
590d311364 Scope client state to where it is used
- MunicipalityMapSelection leaf owns hover/selection: a mouseover re-renders
  only the map + readout, not the whole panel (controls, legend, zone list);
  Leaflet paint stays ref-based (B6)
- municípios list: MunicipalityEstimateScenarioProvider now wraps only the
  results — scenario switches no longer re-render the filter controls
  (dashboard already scoped it to the map)
- LeaderContactsPanel is a server component again: header + contacts table
  render on the server; only LeaderContactForm (new client file) hydrates
- ledgered with rationale: map-bundle slimming deferred (gzip crushes the
  repeating keys; instant year/scenario switching is a core analysis flow);
  props-to-state effect mirrors reviewed and accepted as the correct
  server-echo reconciliation pattern
2026-07-23 23:26:28 -03:00
Francisco Ignácio Fontoura Solla
05a47b881c Make every campaign action feel immediate with honest pending
Closes the 'Feel the action' gaps (.cursor/rules/campanha-action-feedback.mdc):

- BUG: action-plan task checkbox was optimistic but never revalidated — a
  successful toggle visually reverted when the transition ended. The action
  now revalidates the plan page; checkbox disables while pending
- map compare + candidate compare picker: optimistic select value +
  useTransition; the map region dims with aria-busy and a live region
  instead of flashing the full-page skeleton
- CampaignListPendingBoundary/CampaignListResults: one shared transition so
  filters (municípios/apoiadores/planos), pagination, demandas status chips
  (new CampaignFilterChips), and the name-search pages (new
  CampaignSearchForm on lideranças/organizações/dobradinhas) dim the RESULTS
  region, not only the control — children stay server-rendered (composition)
- streaming: dashboard map section behind Suspense (KPI shell paints first;
  React cache() keeps the municipality scope shared, not reloaded);
  municipality detail tabs (elections/leaderships/updates) stream below the
  header; list-shaped loading.tsx for /municipios and /apoiadores
- logout button gets a pending state; BahiaMap init shows a visible spinner
  (was sr-only)
2026-07-23 23:21:46 -03:00
Francisco Ignácio Fontoura Solla
0e4e6855dc Add the tooling gate: knip, CI, zero-warning lint, as-never ban
- knip (files/deps at error level; unused exports ledgered as warn) with
  config for Payload/Next entries; deleted the dead modules it confirmed:
  RecentlyVisited + UpcomingActionPlansCard + actionPlanUpcomingPreview,
  lazy-dialog helpers, tseZone, federalCandidateTotalsAggregate (test-only),
  unused ui kit files, one-shot rename script; pruned unused radix deps and
  typescript-eslint; added pg/@types/pg (pinned to drizzle's 8.10.2)
- GitHub Actions CI on the mirror: lint, typecheck, knip, unit, migrate, int
  against a Postgres 17 service
- eslint: unused-vars with ^_ ignore patterns (migrations args exempt),
  repo-wide ban on `as never` (no-restricted-syntax), lint gate at
  --max-warnings=0; fixed all 54 pre-existing warnings (dead imports,
  hooks deps, tracking-pixel img disable with impeccable config exception)
- tsconfig: include consolidated from 219 lines to 5 (wildcard covers all
  .next dist variants), noUnusedLocals on
- typed replacements for every as-never: hookFilledCreateData (actions
  create data completed by collection hooks), drizzle scopeColumn narrowing,
  tests' stub<T> helper (property-level checking kept, completeness waived)
- test infra: leased-consent generalization used by onda0 spec (shared
  leases over the stable consent keys; window race ledgered), purge fix
- docs: IMPROVE-CODE-QUALITY-PLAN.md tracker, TECH-DEBT.md ledger,
  TESTING.md safety-net map (package.json also gains the Phase 2
  build:election-aggregates script entry; the script lands next commit)
2026-07-23 23:06:12 -03:00
Francisco Ignácio Fontoura Solla
e2724c10da Remodel the campaign vertical from Praça to Município
Rename the operational unit "Praça"/"Núcleo" to "Município" (code identifier
`municipality`) and land the 2026-07-23 course changes:

- New `candidate` role with unrestricted visibility (`isCampaignStaff` now
  includes it) alongside coordinator/advisor; leader is locked down to the
  supporter contact tool only.
- Demandas become staff-only; dobradinhas modeled via a `stateDeputy` entity.
- Camaçari consolidated to a single município (ZE 170/171 aggregated);
  Salvador keeps its 19 zone municípios.
- Map moves to the staff dashboard; `/campanha/municipios` is list/overview.
- Vote pledges keep the declared vs estimated (scenario) asymmetry; leaders
  never see estimates.

Destructive migration for the campaign vertical (drops nucleus/plaza-era
tables, wipes campaign rows, seeds 435 municípios). Public-site data untouched.

Includes the post-delivery /simplify cleanups: shared reloadStaffActor /
reloadCoordinatorActor helpers, req.context cache for getFreshCampaignUser,
parallelized dashboard loads, candidate dashboard-copy fix, and dead
leader-dashboard / roleKind code removal.
2026-07-23 21:36:20 -03:00
Francisco Ignácio Fontoura Solla
aa12e173d8 Ship A10 vote estimate scenarios (pessimistic/central/optimistic) for Praças.
Staff surfaces share one Cenário control; leaders keep a single declaredVotes value. Unlocks E8.
2026-07-23 19:12:22 -03:00
Francisco Ignácio Fontoura Solla
21228dc022 Document coordenador geral interview and register A10 plus WhatsApp D3–D5.
Capture field evidence from the anchor session, update CUSTOMER/roadmap plans, and add vote-scenario and internal WhatsApp bridge specs with interview audio and transcripts.
2026-07-23 12:24:53 -03:00
Francisco Ignácio Fontoura Solla
d93e2aa72f Add admin CSV export for signatures and contacts.
Enables @payloadcms/plugin-import-export on signature (flattened contact/petition columns) and contact (native fields) so operations can download filtered lists for external ESP/SMS workflows.
2026-07-23 00:53:04 -03:00
Francisco Ignácio Fontoura Solla
a5ab2c238c Register campaign intelligence discovery and E8–E15 roadmap program.
Embeds approved literature→persona→interview research in docs/research/, adds inteligencia-campanha master plan with child specs, updates roadmap/PRODUCT/AGENTS, and extends roadmap skills with data-presentation guidance.
2026-07-22 00:04:50 -03:00
Francisco Ignácio Fontoura Solla
cd8002a6e1 Deliver B12 map viewport fit and hover fixes for filtered Praças.
Aproxima o mapa ao footprint filtrado e corrige hover fora do filtro, ênfase sticky e fill agressivo no Mapa das Praças.
2026-07-21 18:10:32 -03:00
Francisco Ignácio Fontoura Solla
c0bf440c76 Deliver C8 F4 shared plaza staff form actions and close simplify debts.
Unify list and /editar server actions in plazaStaffFormActions.ts so B9 inline edits and the edit page share one implementation without behavior changes.
2026-07-21 16:14:30 -03:00
Francisco Ignácio Fontoura Solla
e497fc3982 Deliver B8 F1 plaza zone neighborhoods catalog and absorb simplify debts.
Ship static zone-to-neighborhood mapping for Salvador/Camaçari Praças-zona, overview UI card, tests/fixture, and roadmap/plan updates including F2 prep follow-ups from capture-review-debts.
2026-07-21 16:08:34 -03:00
Francisco Ignácio Fontoura Solla
7f437741ba Deliver B6 incremental BahiaMap setStyle and absorb post-simplify debts.
Keep GeoJSON stable across metric/scale/hover changes via pathByKeyRef and O(2) restyle; extract bahiaMapStyle helpers with unit tests and close B10/B11 perf debt refs in plans.
2026-07-21 16:02:20 -03:00
Francisco Ignácio Fontoura Solla
e099b70002 Register B12 to fit Praças map viewport to filtered footprint.
Promotes the deferred B7 fitBounds follow-up into its own roadmap item and plan so the map can zoom to the filtered region without re-zooming on year/scale changes.
2026-07-21 15:53:46 -03:00
Francisco Ignácio Fontoura Solla
0dcef662e7 Deliver A9+ shared Praças list loader and scoped revalidation.
Deduplicate pledge aggregation via loadPlazaListPageBundle, add plazaRevalidation with slug-scoped detail paths after inline saves, and document the fill-in as shipped.
2026-07-21 13:22:12 -03:00
Francisco Ignácio Fontoura Solla
9db80d815b Deliver B11 percent-of-valid-votes scale on Praças map.
Adds valid-votes denominators to the map bundle, a Total vs % dos válidos selector with fixed 0–100% coloring, and readout/legend alignment via scaleMax; updates roadmap and post-simplify debt docs.
2026-07-21 13:12:05 -03:00
Francisco Ignácio Fontoura Solla
248f896d05 Deliver auto-applied filters on Praças list and close filtros-auto fill-in.
Remove the Buscar step with debounced search, immediate select navigation, and pending UI; update roadmap, plan, and notebook.
2026-07-21 12:54:23 -03:00
Francisco Ignácio Fontoura Solla
7fe45ea963 Mark B9 and B10 as delivered in roadmap and plans.
Align docs with code already on main so Janela 1 open work points at B11, R6, and deploy.
2026-07-21 12:33:45 -03:00
Francisco Ignácio Fontoura Solla
bb5129d514 Deliver B10 hover/tap on Praças map and absorb perf debts into B6.
Adds polygon highlight, vote readout, and navigation (desktop click / mobile 2nd tap) on the filtered Praças choropleth, with simplify cleanup and B6 plan updates for incremental setStyle.
2026-07-21 11:58:49 -03:00
Francisco Ignácio Fontoura Solla
70c61ab49e Deliver B9 quick edit on Praças list and register simplify follow-ups.
Inline staff edits for advisors, political trend, and expected votes on /campanha/pracas; absorb post-simplify debts into A9+ and C8 plans.
2026-07-21 11:45:37 -03:00
Francisco Ignácio Fontoura Solla
936323c7ee Filter Praças map by the same URL filters as the list (B7).
Wire buildPlazaListWhere into loadPlazaMapBundle, export PlazaListSearchParams
from plazaUi, add integration tests, and mark B7 delivered in roadmap/docs.
2026-07-21 11:37:32 -03:00
Francisco Ignácio Fontoura Solla
b333609726 Deliver A9 plaza expectedVotes and register A9+ follow-up.
Add staff-only expectedVotes with migration, edit flow, and expectedVotes ?? pledge fallback across map, overview, and dashboard; document delivery and the A9+ loader dedup fill-in on the roadmap.
2026-07-21 11:02:11 -03:00
Francisco Ignácio Fontoura Solla
be1106f887 Add Meta Pixel tracking to public petition pages.
Let marketing configure a numeric facebookPixelId per petition in Payload, fire PageView on load and Lead after a successful signature, and mark the roadmap item delivered with deferred follow-ups documented.
2026-07-21 10:51:47 -03:00
Francisco Ignácio Fontoura Solla
b7cfc609e1 Register Praças map and vote-estimate roadmap items with implementation plans. 2026-07-21 10:26:33 -03:00
Francisco Ignácio Fontoura Solla
cf13c441aa Remodel /campanha around predefined Praças replacing electoral nuclei.
436 seeded Praças (municipality-based; per-TSE-zone in Salvador/Camaçari) become
the operational unit; roles renamed to coordinator/advisor/leader with advisors
scoped to administered Praças. Leadership is one record per person across many
Praças/organizations; vote pledges split leader-declared vs staff-estimated
(estimates never serialized to leaders). Adds organizations, demand workflow
with staff-only cost/receipts, action-plan results with deputy presence, manual
political trend, multi-candidate comparison and the diverging red/white/blue
map mode. Migration 20260721_020109_remodel_plazas deliberately resets the
campaign vertical in production (public site untouched); test suite ported to
the new model (unit 187 / int 306 / e2e 9 green).
2026-07-21 02:28:00 -03:00
Francisco Ignácio Fontoura Solla
87c36e4856 Deliver A8 IBGE voter profile on Eleitorado tab with post-simplify scale plan.
Adds static SIDRA demographics, territory-weighted derivation, electorate UI with opt-in copy to manual profiles, shared territory-city resolution, and registers A8+ fill-in debt from capture-review-debts.
2026-07-19 23:05:27 -03:00
Francisco Ignácio Fontoura Solla
c2381cecde Deliver A7 Fase 2 cityCode TSE geography filters and absorb simplify debts.
Switch election geography queries from cityName to TSE cityCode via a static Bahia map and nucleusElectionGeography module, with simplify cleanup and plan updates for F3–F5 follow-ups.
2026-07-19 22:48:08 -03:00
Francisco Ignácio Fontoura Solla
3f6220c9d4 Mark A5 mobilization as delivered on the roadmap.
Leave only competitive intelligence as the remaining A5 insight; update graph, window table, and design refs for consistency.
2026-07-19 22:36:56 -03:00
Francisco Ignácio Fontoura Solla
ea579d2173 Deliver A5 mobilization insight and absorb E7 F2 int follow-up.
Surface brancos/nulos/abstenções as mobilization opportunity on nucleus detail and list overview, with loader aggregate and unit tests; register pending int coverage in escala-dry-pos-e2.
2026-07-19 22:34:35 -03:00
Francisco Ignácio Fontoura Solla
0460b08429 Add allowlisted global cache revalidation for Onda 0 F1.
Extend POST /api/revalidate with posts and global_privacy-policy tags so
direct-DB Onda 0 writes can bust /privacidade without an admin edit.
2026-07-19 22:21:16 -03:00
Francisco Ignácio Fontoura Solla
387cd46fd3 Mark E4 spreadsheet import as cut in roadmap and project docs.
Product decision: strategic nucleus data will be entered manually via E1+E3 UI instead of a one-shot pnpm db:seed:mapa import.
2026-07-19 22:06:25 -03:00
Francisco Ignácio Fontoura Solla
b75daab498 Refactor campaign dashboard UX and add product discovery artifacts.
Extract dashboard cards into focused components (queues, upcoming plans, leadership status, recently visited, choropleth legend), compile the roadmap for outcome-oriented tracking, document the customer job and improve-app journey, and tighten roadmap skills with decision-quality gates.
2026-07-19 21:56:01 -03:00
Francisco Ignácio Fontoura Solla
f5140b15a2 Polish campaign login auth UI after Impeccable critique.
Fix header alignment and rhythm, swap Megaphone for CampaignLogo, add progressive disclosure for first access, and extract shared auth shells with corrected individual-account copy; record closed critique items in RS+.
2026-07-19 19:24:12 -03:00
Francisco Ignácio Fontoura Solla
81b01b9907 Deliver A5-2 territorial classification insight and absorb review debts.
Classify nuclei as defesa/ataque/indecisa/perdida from 2022 baseline share, surface Alert + overview distribution, and register post-simplify follow-ups in A7/E7 plans.
2026-07-19 18:15:07 -03:00
Francisco Ignácio Fontoura Solla
94f0bd51f8 Deliver A5 ticket leverage and flip insights with simplify cleanup.
Surface majoritarian base conversion and proportional flip opportunity on nucleus detail and list overview, precompute ticketFlip on the baseline VM, and register post-simplify scale debts in A7 F5 and E7.
2026-07-19 17:34:06 -03:00
Francisco Ignácio Fontoura Solla
b8547ff292 Deliver B3 Leaflet choropleth maps and register post-simplify follow-ups.
Add BahiaMap surfaces on nuclei list, detail, and geral dashboard with server-side choropleth aggregation, lazy geometry loading (B5 F1), and roadmap plans for A7 F4, B5 F3, and B6 scale debts.
2026-07-19 17:13:27 -03:00
Francisco Ignácio Fontoura Solla
8420969b4b Deliver A7 Fase 1 federal ranking aggregate and register simplify follow-ups.
Replace full Local API federal T1 loads with drizzle GROUP BY on nucleus detail, gate election reads via assertCanReadElectionData, and absorb post-simplify cleanup into the A7 plan and roadmap.
2026-07-19 16:57:08 -03:00
Francisco Ignácio Fontoura Solla
96329bd46e Deliver E7 Fase 2 int tests for nucleus list election overview.
Add integration coverage for loadNucleusListElectionOverview (gap, trend,
conversion), extend TSE fixtures for multi-year seeding, register E7 Fase 4
test-helper debts on the roadmap, and simplify seed-consent exit handling.
2026-07-19 16:45:36 -03:00
Francisco Ignácio Fontoura Solla
14cfcdb3f6 Restore full roadmap detail and align project documentation.
Expand the compiled next-steps doc back into the full delivery history, cross-reference plan statuses, and sync AGENTS.md, PRODUCT.md, and the Núcleos project notebook.
2026-07-19 16:19:36 -03:00
Francisco Ignácio Fontoura Solla
71421c725c Compile the roadmap into next-steps docs and align project references.
Replace the delivery diary with open items and windows, and sync AGENTS, notebook, README, and plan pointers with provisional Onda 0 Consent hold.
2026-07-19 16:13:47 -03:00
Francisco Ignácio Fontoura Solla
429b31048f Deliver A5 slice 1 conversion-rate insight and absorb review debts.
Surface taxa de conversão on nucleus detail and list overview, with loader
optimizations and unit tests; update plan/roadmap follow-ups for E7, A7, and RS+.
2026-07-19 14:05:11 -03:00
Francisco Ignácio Fontoura Solla
8b4ae2bf36 Mark E1+E3 as delivered in roadmap and project docs.
Sync Trilha E status after the nucleus goals/strategy fields shipped in main.
2026-07-19 12:06:47 -03:00
Francisco Ignácio Fontoura Solla
e80f4030cb Polish /campanha Field Desk UX and register FD+/FD2 follow-ups.
Align the campaign desk with quieter KPI strips, queues-first dashboard, shared shells, and advanced filters; capture Impeccable design context and the remaining simplify/critique debts on the roadmap.
2026-07-19 08:17:12 -03:00
Francisco Ignácio Fontoura Solla
3b463173da Add campaign password reset, profile photo, and RS+ follow-up plan.
Deliver self-service forgot/reset via Resend, logged-in password change, and optional avatar on /campanha/perfil; register post-simplify engineering debts as RS+.
2026-07-19 05:26:56 -03:00
Francisco Ignácio Fontoura Solla
e1203a665e Merge branch 'cursor/56b3203e' into main
E2 série TSE 2014/2018 + tendência automática, simplify pass e débito E7 registrado no roadmap.
2026-07-19 05:13:52 -03:00
Francisco Ignácio Fontoura Solla
b0f4ebc1ed Add E2 TSE 2014/2018 vote series and historical trend insights.
Extends the electoral baseline with multi-year seeding, computeVoteTrend, list/detail UI, and registers post-simplify follow-ups as E7.
2026-07-19 05:09:43 -03:00
Francisco Ignácio Fontoura Solla
364611eea3 Register A8 IBGE voter profiles on roadmap and plan.
Document derived Censo-based electorate profile alongside existing manual voterProfiles in the nucleus Eleitorado tab.
2026-07-19 05:02:20 -03:00
Francisco Ignácio Fontoura Solla
117eba1024 Anchor A5 party spectrum on Bolognesi et al. expert survey.
Lock flip-opportunity rules (≥1 majoritarian left, Alert copy without "direita") to the 2022 Opinião Pública classification and Dataverse scores.
2026-07-19 04:54:30 -03:00
Francisco Ignácio Fontoura Solla
9855d557f9 Expand A5 ticket leverage plan with flip-opportunity phase 2.
Absorb the virada insight into insight-alavancagem-chapa (winner or right-share triggers), align dobradinha taxonomy with electionPartySpectrum, and update roadmap and project notebook.
2026-07-19 04:49:03 -03:00
Francisco Ignácio Fontoura Solla
e5e051d175 Deliver E1 vote goals and E3 strategy fields on nuclei.
Wire schema, UI, aggregates, and tests for scenario goals, priority filter, staff-only dobradinha notes and next steps; register E6 scale follow-ups from simplify.
2026-07-19 04:38:07 -03:00
Francisco Ignácio Fontoura Solla
4e68e647d4 Merge branch 'cursor/667b8d6e': recent visits panel and VR+ follow-ups.
# Conflicts:
#	docs/roadmap.md
2026-07-19 04:10:57 -03:00
Francisco Ignácio Fontoura Solla
51364da29f Add recent visits panel to /campanha and register VR+ simplify follow-ups. 2026-07-19 04:06:14 -03:00
Francisco Ignácio Fontoura Solla
9efcf2832f Add missing C7 modules and register C11 simplify follow-ups. 2026-07-19 03:52:22 -03:00
Francisco Ignácio Fontoura Solla
15c756bb10 Deliver C7 scale/DRY for action plans: territory composition, tab-scoped reads, and hook shortcuts. 2026-07-19 03:50:58 -03:00
Francisco Ignácio Fontoura Solla
cc66ec3c31 Deliver Onda 0 MVP: provisional Consent, privacy policy, and /privacidade.
Auto-provision legal texts via migrations and db:seed:consent so local and
production deploy stay fail-closed-ready; register O0+ simplify follow-ups.
2026-07-19 03:38:21 -03:00
Francisco Ignácio Fontoura Solla
ced1b71771 Deliver C9 scale/DRY for supporters and register C10 follow-ups. 2026-07-19 03:23:25 -03:00
Francisco Ignácio Fontoura Solla
1e23b27b4f Deliver C8 scale/DRY for supporters and register C9 follow-ups.
Bulk import and list paths get single-round-trip locks, drizzle returning reads, pg_trgm search, shared drizzleBulk helpers, and consolidated campaign formActions; simplify debts land as C9 in the roadmap.
2026-07-19 00:31:06 -03:00
Francisco Ignácio Fontoura Solla
39f7edb10f Register Trilha E plan to match and exceed the 2026 vote projection spreadsheets.
Adds mapa-projecao-municipios.md (E1–E5), updates the roadmap graph and execution windows, and records the product decisions in the nuclei notebook.
2026-07-19 00:28:47 -03:00
Francisco Ignácio Fontoura Solla
8b4ceae0ad Merge branch 'cursor/602456d7': C7 partial scale/DRY for action plans
Deliver denormalized task counters, shared territory FormData parsing, advisory locks, contact-search guard, and document remaining simplify debts.

# Conflicts:
#	docs/roadmap.md
2026-07-19 00:09:50 -03:00
Francisco Ignácio Fontoura Solla
73cfcc94d9 Deliver C7 partial scale/DRY for action plans and register remaining simplify debts.
Add denormalized task counters with list perf migration, shared territory FormData parsing, advisory locks on task/update mutations, and a shared contact-search guard; document what is still pending in the C7 plan and roadmap.
2026-07-19 00:07:31 -03:00
Francisco Ignácio Fontoura Solla
dc39fc937d Document A4 merge to main and A7 follow-ups.
Mark baseline product delivery as merged in the roadmap, plans, AGENTS, and project notebook.
2026-07-18 22:56:10 -03:00
Francisco Ignácio Fontoura Solla
1f8b0c8c72 Add A4 electoral baseline in product with Gap vs 2022, and register A7.
Surface TSE 2022 aggregation on nucleus detail and list overview; document scale/DRY follow-ups from the simplify pass.
2026-07-18 22:50:10 -03:00
Francisco Ignácio Fontoura Solla
512df25f09 Document C6 merge to main, simplify pass, and C8 registration.
Mark C6 as merged to main in the roadmap and C6 plan (with a simplify note),
add the supporter_import_batch migration to the Onda 0 list, and record the
C6 scale layer + C8 follow-ups in AGENTS.md.
2026-07-18 22:38:50 -03:00
Francisco Ignácio Fontoura Solla
9ccfb3b704 Simplify C6 supporter paths and register C8 scale/DRY follow-ups.
Apply the /simplify cleanup to the C6 commit (identity maps, dead branches,
relationshipId reuse, native base64url, rowCount fix, canManageCampaignUsers
reuse) and register the unimplemented debits as roadmap item C8 with its plan.
2026-07-18 22:34:55 -03:00
Francisco Ignácio Fontoura Solla
9fdbae05d7 Add C6 scale/DRY for supporters: bulk import, KPI aggregate, shared shells.
Phase 1 UX: StrictCombobox municipality in SupporterForm, AlertDialog in
RemoveSupporterDataButton. Phase 2 DRY: campaignListUrl + CampaignListPagination
+ campaignFormFields + mapCampaignFormActionError shared across nuclei,
supporters and action plans. Phase 3: single SQL aggregate for supporter list
KPIs via drizzle in the Payload txn. Phase 4: bulk drizzle insert for CSV import
inside the existing Payload txn with ON CONFLICT DO NOTHING, plus a fail-closed
skipContactPhoneInvariant context flag. Phase 5: HMAC-signed single-use import
token backed by a new supporterImportBatch staging collection so the full ok-row
set never crosses the Server Action boundary twice.
2026-07-18 22:17:31 -03:00
Francisco Ignácio Fontoura Solla
8e0ee43844 Document B2 map geometries as-built delivery and helpers. 2026-07-18 22:14:26 -03:00
Francisco Ignácio Fontoura Solla
f04dbe07f9 Register B5 scale/DRY follow-ups after the B2 geometries simplify pass. 2026-07-18 22:10:47 -03:00
Francisco Ignácio Fontoura Solla
e5968f81d5 Add static Bahia municipality and territory geometries for the campaign map.
Ship TopoJSON meshes, IBGE code lookups, a re-runnable build script, and evidence tests so B3 can render Leaflet surfaces without PostGIS.
2026-07-18 22:07:41 -03:00
Francisco Ignácio Fontoura Solla
b2856abceb Fix Vercel build failing on sync exports from supporter server actions.
Next.js requires every export from a 'use server' module to be async; move the import type guard into a shared util and mark createSupporterRecord async. Also mark C2 as merged in the roadmap/docs.
2026-07-18 21:17:58 -03:00
Francisco Ignácio Fontoura Solla
c12fc0787c Register C7 scale/DRY follow-ups after the C3 action-plan simplify pass. 2026-07-18 20:59:36 -03:00
Francisco Ignácio Fontoura Solla
e995aefbd4 Add action-plan agenda vertical for /campanha/planos.
Ship C3 mobilization events with the actionPlan collection, list/detail/forms UI, upcoming-event blocks, access control, and migration.
2026-07-18 20:56:20 -03:00
Francisco Ignácio Fontoura Solla
a18e2f15f5 Simplify C2 supporter paths and register C6 scale follow-ups.
Tighten import/create view models after review, and capture the deferred DRY/import-scale work as roadmap item C6.
2026-07-18 20:33:50 -03:00
Francisco Ignácio Fontoura Solla
b079daa9bb Add C2 nominal supporter registry for /campanha.
Ship the supporter join collection, consent-keyed create/import/remove actions, and apoiadores UI so staff can build a phone-required nominal base before mass field ops.
2026-07-18 20:32:54 -03:00
Francisco Ignácio Fontoura Solla
3b703d42a3 Align docs with A2 as-built delivery on main.
Record the merged municipality↔TSE zone suggestions in AGENTS, the nuclei notebook, roadmap, and the zonas plan (post-simplify API shape).
2026-07-18 20:07:33 -03:00
Francisco Ignácio Fontoura Solla
ac7f2775cd Add opt-in TSE zone and territory suggestion chips for nuclei.
Ship A2 with a static Bahia municipality↔zone map, pure suggestion engine, and form chips that never auto-apply geography.
2026-07-18 20:04:04 -03:00
Francisco Ignácio Fontoura Solla
202f1579ec Align docs with cycle 2 delivery and add roadmap-item skill.
Mark A1/A3/B1/C1/D1 as shipped, revise the A2 zone-suggestion plan, and tighten the share dialog overflow.
2026-07-18 19:01:25 -03:00
Francisco Ignácio Fontoura Solla
b035cc4a2f Support multi-municipality and multi-neighborhood nucleus territory.
Replace scalar region/city/neighborhood with hasMany arrays so nuclei can span multiple Bahia municipalities while keeping neighborhoods scoped to a single city.
2026-07-18 18:31:51 -03:00
Francisco Ignácio Fontoura Solla
c42b16baab Add TSE 2022 election results model and local seed import. 2026-07-18 18:25:19 -03:00
Francisco Ignácio Fontoura Solla
b0c86cf8e3 Version UX Pilot design refs and map them to roadmap plans
Add the 11 UX Pilot design pairs (.png + .html) under
docs/design-refs/latest/ and link each to its roadmap item and plan.
Record the decision that UX/structure is the reference but the old
palette is not — implementation uses the light campaign theme tokens.
2026-07-18 16:36:09 -03:00
Francisco Ignácio Fontoura Solla
a5903d52ad Align project docs with the shipped nuclei MVP.
Update AGENTS, README, roadmap, and the Núcleos notebook so status, territory scope, tests, and the LGPD production blocker match main.
2026-07-18 15:04:32 -03:00
Francisco Ignácio Fontoura Solla
bcac665cb5 Ship /campanha nuclei MVP with RBAC, invites, and vote estimates.
Adds electoral nuclei, leaderships, updates, and WhatsApp invite flows behind campaign auth, plus the consolidated schema migration that Vercel applies on deploy.
2026-07-18 15:01:56 -03:00