mirror of
https://github.com/fsolla/teqo.git
synced 2026-11-13 23:53:05 +00:00
Pass 2: materializa tracker e planos por workstream (W0-W5, D1-D6)
This commit is contained in:
parent
c2a3d73702
commit
3812d81261
6 changed files with 240 additions and 0 deletions
|
|
@ -1,5 +1,7 @@
|
|||
# Improve Code Quality Plan
|
||||
|
||||
Two passes so far: **Pass 1** (2026-07-23/24, phases 0–6 below, all done) and **Pass 2** (started 2026-07-25, see [Pass 2](#pass-2--engineering-consolidation-2026-07-25)).
|
||||
|
||||
## Context
|
||||
|
||||
- **Started:** 2026-07-23
|
||||
|
|
@ -49,3 +51,53 @@ Statuses: pending · in-progress · awaiting-evidence · done · deferred: \<rea
|
|||
- [x] Phase 6 — documentation (`deca5c0`)
|
||||
- [x] E2E-driven fixes: leader home Forbidden, leader contact visibility, duplicate nav keys, RSC function-prop contracts, fixed e2e dist dir (`cb6c152`)
|
||||
- [ ] Remaining leftovers live in [TECH-DEBT.md](TECH-DEBT.md) Debt Ledger (drive knip `exports` warn→error, consent-window lease redesign, e2e local-latency flake, users roles migration)
|
||||
|
||||
---
|
||||
|
||||
# Pass 2 — Engineering Consolidation (2026-07-25)
|
||||
|
||||
## Context
|
||||
|
||||
- **Started:** 2026-07-25 (plan approved same day)
|
||||
- **Trigger:** everything shipped since Pass 1 (B15/B16/B19, E4R, E8/E9/E16/E18, A11, C12…) one-shotted per-feature infrastructure again. Six parallel audits (duplication, module boundaries, type honesty/dead code, safety net, docs drift, roadmap alignment) produced the evidence.
|
||||
- **Goal:** (1) generalized shared infrastructure where logic was per-feature (the campaign list/table system above all); (2) a deliberate, documented architecture; (3) an explicit mental model (`docs/ARCHITECTURE.md` + agent-facing map rule) that lets a human or agent orient in minutes.
|
||||
- **Method:** same `improve-code-quality` journey; each workstream is an independent delivery (full gate per delivery: `tsc --noEmit`, `pnpm lint` zero warnings, `pnpm exec knip`, `pnpm test`, `pnpm build`, Aikido scan), structure-only commits never mixed with behavior. Sequenced around the electoral calendar (window 1 → 05/08, window 2 → 16/08; nothing near the ~20/09 freeze).
|
||||
- **Audit headlines:** 12 `ui/Table` surfaces with a half-built shared spine; `src/lib/electionInsights.ts` 941 lines / 71 exports / **2 used in production**; `municipalityUi.ts` 765 lines / 59 exports (new god module); 21 loaders missing `server-only`, 9 `lib/`→`utilities/` inversions, 1 type cycle, client sidebar importing the access barrel; knip unused exports 158→164; safety net 41 unit / 46 int / 7 e2e with supporter/actionPlan/entity-list parsers+loaders unpinned; "Praça" copy ~96 hits in 53 files vs the ledger's ~15; AGENTS.md structure/route drift.
|
||||
|
||||
## Workstream Status
|
||||
|
||||
| WS | Content | Plan file | Status | Date |
|
||||
| --- | --------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------- | ------- | ---- |
|
||||
| W0 | Safety net: pin list URL parsers + list loaders (unit + int smokes); TESTING/TECH-DEBT truth-up | [pinagem-superficies-lista.md](plans/pinagem-superficies-lista.md) | pending | |
|
||||
| W1 | Generalized campaign list system (D1 core + municipality; D2 migrate entity triplet/demandas/apoiadores/assessores + delete superseded) | [sistema-listas-campanha.md](plans/sistema-listas-campanha.md) | pending | |
|
||||
| W2 | Architecture decision (DDD/clean-arch/SDP evaluation → conventions + boundary fixes) + staged `components/campaign` subfolders | [decisao-arquitetura-dominios.md](plans/decisao-arquitetura-dominios.md) | pending | |
|
||||
| W3 | `docs/ARCHITECTURE.md` + `.cursor/rules/codebase-map.mdc` | [mapa-mental-arquitetura.md](plans/mapa-mental-arquitetura.md) | pending | |
|
||||
| W4a | `electionInsights.ts` gut/split: extract `electionFormat`, keep voteTrend, delete dead clusters (before E10) | [split-election-insights.md](plans/split-election-insights.md) | pending | |
|
||||
| W4b | knip unused-exports warn→error: delete zero-ref exports, un-export in-file symbols, config, CI flip | (tracker only) | pending | |
|
||||
| W4c | Detail-page RSC extraction (`municipios/[slug]`, `planos/[slug]`) + dedupe detail-tab helper twins | (tracker only) | pending | |
|
||||
| W4d | formActions finish: `runCampaignFormAction` (stay-on-page) + migrate 9 hand-rolled ladders (closes C8 F4) | (tracker only) | pending | |
|
||||
| W4e | Single-source types: scenario triple, strategy VM, trend enum, duplicated constants/helpers, `DynamicFind` doc | (tracker only) | pending | |
|
||||
| W4f | "Praça"→"Município" user-visible copy sweep (~55 visible hits + admin labels; consent texts stay for the legal batch) | (tracker only) | pending | |
|
||||
| W5 | Documentation close-out: AGENTS.md refresh, ledger/TESTING reconcile, plan-status patches, roadmap fold-in, product-doc drift findings | (tracker only) | pending | |
|
||||
| D3 | `consent: 2` hardcode → Onda 0 provisional-key pattern (data migration + fail-closed switch; **migration SQL reviewed before landing**) | (tracker only) | pending | |
|
||||
|
||||
Statuses: pending · in-progress · awaiting-evidence · done · deferred: \<reason\> · skipped: \<reason\>
|
||||
|
||||
## Pass 2 Decisions (signed off 2026-07-25)
|
||||
|
||||
| ID | Decision | Rationale |
|
||||
| --- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| D1 | **No `src/domains/` reorg, no ports-and-adapters.** Conventions + mechanical boundary fixes + staged within-layer subfolders for `components/campaign/`; `utilities/` subfoldering deferred with trigger | Payload collections ARE the data model; a big-bang move freezes the repo mid-window and risks the importmap. Full evaluation in [decisao-arquitetura-dominios.md](plans/decisao-arquitetura-dominios.md) |
|
||||
| D2 | **Delete** the ~52 consumer-less `electionInsights` exports (+ their tests) rather than quarantining them | git history + plans carry the formulas; E10 replaces the 35/20/10 threshold approach with relative classification — keeping dead math invites accidental reuse |
|
||||
| D3 | `consent: 2` hardcode folded into the Onda 0 provisional-key pattern in-pass, as an isolated delivery with the migration SQL explicitly reviewed by the user before landing | Same fail-closed pattern as `lideranca-autopreenchimento`; leaving the hardcode makes the legal batch harder to verify |
|
||||
| D4 | users-roles migration stays ledgered/deferred | Schema migration; only blocks widening `/admin`, which isn't scheduled |
|
||||
| D5 | W1 scope boundary: planos stays cards (adopts toolbar/URL state only), `TerritoryOverviewTable` stays a documented client-sort exception, LeaderContacts/candidate-comparison/import-preview stay out | Anti-classitis: the system earns its migrations; small static tables don't pay for the abstraction |
|
||||
| D6 | Praça sweep = user-visible copy + admin labels; provisional Onda 0 consent texts untouched (legal batch) | Consent text versions are counsel-owned; code shouldn't edit them cosmetically |
|
||||
|
||||
## Next Actions
|
||||
|
||||
- [x] Materialize Pass 2 tracker section + per-workstream plans (this commit)
|
||||
- [ ] W0 → W1-D1 → W1-D2 (window 1), W4a/W4e/W4f interleaved
|
||||
- [ ] W2 → W4c/W4d → W3 (window 2)
|
||||
- [ ] W4b (last code delivery) → W5 (docs close-out)
|
||||
- [ ] D3 isolated delivery — migration SQL reviewed by the user before landing
|
||||
|
|
|
|||
41
docs/plans/decisao-arquitetura-dominios.md
Normal file
41
docs/plans/decisao-arquitetura-dominios.md
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
# Decisão de arquitetura: domínios vs camadas (Pass 2 — W2)
|
||||
|
||||
Status: aprovado (Pass 2, 2026-07-25) — veredito D1 assinado: NO-GO no reorg, GO em convenções + correções de fronteira
|
||||
Atualizado em: 2026-07-25
|
||||
Item pai: [IMPROVE-CODE-QUALITY-PLAN.md](../IMPROVE-CODE-QUALITY-PLAN.md) — Pass 2, W2
|
||||
Appetite: ~1,5 dia
|
||||
|
||||
## Pergunta
|
||||
|
||||
O layout layer-first (`collections/ → utilities/ → components/ → app/`) deve virar domain-first (`src/domains/{municipality,supporter,...}/`), possivelmente com ports-and-adapters? Avaliação corrida contra `domain-driven-design`, `clean-architecture` e `software-design-philosophy`.
|
||||
|
||||
## Veredito (D1, assinado 2026-07-25)
|
||||
|
||||
**NO-GO no `src/domains/` reorg e no ports-and-adapters. GO em: (a) convenções documentadas e endurecidas; (b) correções mecânicas de fronteira; (c) subpastas por domínio DENTRO da camada `components/campaign/` (por etapas); (d) subpastas em `utilities/` adiadas com gatilho.**
|
||||
|
||||
Racional registrado (alternativas rejeitadas):
|
||||
|
||||
- **`src/domains/` rejeitado:** Payload collections JÁ SÃO o modelo de domínio — a "camada de domínio" real vive em `src/collections/` + `src/utilities/access/` e não pode sair de lá (importmap do admin, convenções do framework). Um big-bang move de ~230 arquivos congela o repo no meio da janela 1–2 do calendário eleitoral e arrisca o importmap gerado. O ganho (navegação) é obtido com subpastas within-layer por fração do risco.
|
||||
- **Ports-and-adapters rejeitado:** só há um adapter de verdade (Payload/Postgres) e um framework (Next). Interfaces na frente do Payload Local API duplicariam a assinatura de cada query sem segundo backend plausível — abstração especulativa (SDP: shallow module).
|
||||
- **Aceito do DDD:** mapa de bounded contexts + linguagem ubíqua (glossário) — vão para `docs/ARCHITECTURE.md` (W3) independentemente do veredito; os prefixos de domínio (`municipality*`, `supporter*`, …) são a expressão within-layer disso.
|
||||
|
||||
## Correções de fronteira (parte mecânica desta entrega)
|
||||
|
||||
1. **9 inversões `lib/`→`utilities/`:** mover os helpers puros (`phone`, `slug`, `wordStartFilter`, validadores de `voteEstimate`, chave de consent do invite) de `utilities/` para `lib/` — `lib/` = puro/client-safe, `utilities/` = acoplado a Payload/Next (regra já escrita, agora cumprida).
|
||||
2. **21 loaders sem `server-only`:** marcar (`actionPlanPageData`, `campaignDashboardData`, os `*Data.ts` de lista, etc.).
|
||||
3. **Sidebar client importando o barrel de access:** `nav.ts` para de importar `campaignAccess` (85 exports, incl. helpers Payload); predicados de role client-safe num módulo de contrato (mesmo padrão de `municipalityMapContract.ts`).
|
||||
4. **Ciclo de tipos `supporterListFilters.ts` ↔ `supporterUi.ts`:** quebrar movendo o tipo compartilhado para um dos lados (ou módulo de tipos).
|
||||
5. **`votePledgeData.ts`:** separar views puras dos loaders Payload (padrão contract-module), destravando importação client-safe dos tipos de cenário.
|
||||
|
||||
## Subpastas por domínio em `components/campaign/` (por etapas)
|
||||
|
||||
106 arquivos flat é a pior dor de navegação do repo. Mover por domínio (`municipality/`, `actionPlan/`, `supporter/`, `leadership/`, `advisor/`, `demand/`, `map/`, `shared/`…), **uma entrega `git mv` por domínio em momento calmo** (branch curta, conflito improvável), imports atualizados por codemod + `tsc`. `utilities/` (92 arquivos) fica adiada: gatilho = quando um domínio ganhar o 3º módulo novo num mesmo mês, subpasta desse domínio junto.
|
||||
|
||||
## Impacto no roadmap
|
||||
|
||||
Nenhum item bloqueado (moves per-domain em branches curtas); navegação de agente melhora para todo item futuro. Sem migration, sem mudança de comportamento — apenas `git mv` + imports + marcações `server-only` (podem revelar violações latentes de client boundary; cada uma é corrigida ou documentada, nunca silenciada).
|
||||
|
||||
## Referências
|
||||
|
||||
- `.cursor/rules/engineering-standards.mdc` (regra lib/utilities), AGENTS.md (estrutura), auditoria de fronteiras 2026-07-25
|
||||
- `src/utilities/campaignAccess.ts` (precedente de split within-layer com re-export surface)
|
||||
32
docs/plans/mapa-mental-arquitetura.md
Normal file
32
docs/plans/mapa-mental-arquitetura.md
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
# Mapa mental da arquitetura (Pass 2 — W3)
|
||||
|
||||
Status: aprovado (Pass 2, 2026-07-25)
|
||||
Atualizado em: 2026-07-25
|
||||
Item pai: [IMPROVE-CODE-QUALITY-PLAN.md](../IMPROVE-CODE-QUALITY-PLAN.md) — Pass 2, W3 (depois de W1/W2)
|
||||
Appetite: ~1 dia; docs-only
|
||||
|
||||
## Objetivo
|
||||
|
||||
Um humano ou agente novo se orienta no repo em minutos, sem arqueologia de git/AGENTS.md. Dois artefatos:
|
||||
|
||||
**1. `docs/ARCHITECTURE.md`** — o documento de arquitetura canônico:
|
||||
|
||||
- Contexto de sistema: um app Next + Payload, três route groups (`(frontend)` público, `(payload)` admin, `(campaign)` interno), duas barreiras de auth independentes (cookie `payload-token` vs `campaign-token`).
|
||||
- Mapa de camadas + dependency rule como aplicada: `lib/` (puro, client-safe) ← `utilities/` (Payload/Next, `server-only` quando server-bound) ← `components/` ← `app/`; módulos de contrato para atravessar a fronteira client (padrão `municipalityMapContract`).
|
||||
- Fluxo de dados: collections → access helpers (`utilities/access/*`) → loaders (`*Data.ts`, `select`ed view models) → RSC → ilhas client.
|
||||
- Escada de caching (React `cache()` → `unstable_cache`+tag → artefato commitado) com os exemplos reais.
|
||||
- Modelo RBAC da campanha (coordinator/candidate/advisor/leader; assimetria de pledge; lockdown do leader).
|
||||
- Bounded contexts + glossário de linguagem ubíqua (W2): Município (unidade operacional ≠ município IBGE), Liderança, pledge `declaredVotes` vs `estimatedVotes`, Demanda, Plano, Apoiador, Dobradinha, termos da conta-da-cadeira (meta, cobertura, teto do campo, captura), contexts do site público (posts/tags/petições/consent).
|
||||
- Decision log: todas as decisões do Pass 2 (D1–D6) + as decisões estruturais herdadas (transações multi-collection, consent fail-closed, migrations only).
|
||||
- Cross-links para PRODUCT/DESIGN/CUSTOMER/research para o "porquê" — sem duplicar conteúdo.
|
||||
|
||||
**2. `.cursor/rules/codebase-map.mdc`** — mapa navegacional compacto (~150 linhas), always-applied, criado com o skill `create-rule`: onde vive cada coisa, como achar o dono de uma feature, convenção de manutenção ("atualizado no mesmo PR que move coisas").
|
||||
|
||||
## Regras
|
||||
|
||||
- ARCHITECTURE.md descreve o estado **pós-W1/W2** (por isso roda depois).
|
||||
- AGENTS.md continua sendo o guia operacional (setup, seeds, deploy); ARCHITECTURE.md é o mapa conceitual — sem sobreposição de conteúdo, com links cruzados.
|
||||
|
||||
## Impacto no roadmap
|
||||
|
||||
Nenhum item bloqueado. Todo item futuro (e todo agente) se beneficia.
|
||||
37
docs/plans/pinagem-superficies-lista.md
Normal file
37
docs/plans/pinagem-superficies-lista.md
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
# Pinagem das superfícies de lista (Pass 2 — W0)
|
||||
|
||||
Status: aprovado (Pass 2, 2026-07-25)
|
||||
Atualizado em: 2026-07-25
|
||||
Item pai: [IMPROVE-CODE-QUALITY-PLAN.md](../IMPROVE-CODE-QUALITY-PLAN.md) — Pass 2, W0 (GATE de W1)
|
||||
Appetite: ~1 dia; sem migration, sem UI
|
||||
|
||||
## Contexto
|
||||
|
||||
W1 vai generalizar o sistema de listas e migrar todas as superfícies. A auditoria de safety net (2026-07-25) mostrou que só a lista de municípios está fortemente pinada (`municipalityUi` unit + `municipalityPageData` int). Os parsers de URL e loaders de apoiadores, planos, assessores, lideranças, organizações, dobradinhas e demandas estão fracos ou sem pin — refatorá-los sem pin é mudar comportamento sem rede.
|
||||
|
||||
## Escopo (conjunto mínimo de pinagem)
|
||||
|
||||
**Unit (parsers/href — contrato de URL byte-idêntico):**
|
||||
|
||||
- `campaignListUrl.ts` — canonicalização, param desconhecido ignorado, clamp de página, geração de href.
|
||||
- `supporterUi.ts` — parse de URL (intenção de voto, território, busca) + hrefs.
|
||||
- `actionPlanUi.ts` — default de tab, matriz tab→where, parse de filtros (kind/municipality).
|
||||
- Um spec compartilhado para os 5 parsers simples de lista (advisor / leadership / organization / stateDeputy / demand) — hoje cada página tem um parser local de `first`/`page`/`q`.
|
||||
|
||||
**Int (5 smokes finos de loader — escopo, `q` vazia, shape da paginação):**
|
||||
|
||||
- `advisorData.ts`, `leadershipData.ts`, `organizationData.ts`, `stateDeputyData.ts`, `campaignDemandData.ts`.
|
||||
|
||||
**Truth-up de documentação (mesma entrega):**
|
||||
|
||||
- `TESTING.md`: contagens reais (41 unit / 46 int / 7 e2e), item do backlog do artefato eleitoral (entregue no Pass 1 fase 2) marcado, novo mapa de pin das listas.
|
||||
- `TECH-DEBT.md`: "Praça" ~96 hits em 53 arquivos (não ~15); e2e 7 specs (não 5); resolver o conflito de status do C8 F4 (ledger diz "partially done", plano diz remainder aberto — o remainder É o W4d).
|
||||
|
||||
## Regras
|
||||
|
||||
- Bug achado durante a pinagem é **ledgerado, nunca corrigido silenciosamente** (o pin registra o comportamento atual).
|
||||
- Sem refactor nesta entrega — só testes + docs.
|
||||
|
||||
## Impacto no roadmap
|
||||
|
||||
Nenhum item bloqueado; é o gate de W1 (que precisa terminar antes da janela 3, ~16/08).
|
||||
52
docs/plans/sistema-listas-campanha.md
Normal file
52
docs/plans/sistema-listas-campanha.md
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
# Sistema de listas da campanha (Pass 2 — W1)
|
||||
|
||||
Status: aprovado (Pass 2, 2026-07-25)
|
||||
Atualizado em: 2026-07-25
|
||||
Item pai: [IMPROVE-CODE-QUALITY-PLAN.md](../IMPROVE-CODE-QUALITY-PLAN.md) — Pass 2, W1 (2 entregas)
|
||||
Appetite: ~4 dias; sem migration, sem mudança de comportamento visível
|
||||
Gate: W0 ([pinagem-superficies-lista.md](pinagem-superficies-lista.md)) verde
|
||||
|
||||
## Contexto
|
||||
|
||||
12 superfícies `ui/Table` no `/campanha`, cada uma com parser de URL, header, paginação e filtros re-implementados por feature. Uma espinha compartilhada já existe pela metade (`campaignListUrl.ts` 6 importers, `CampaignListPagination` 9, `CampaignListPendingBoundary` 8, `CampaignSearchForm` 4) — mas a lista de municípios (a mais rica: sort, filtros no header, células editáveis B9, overview E8/E9) é um monolito (`MunicipalityList.tsx` 496 + `MunicipalityFilters` 354 + `MunicipalityHeaderFilter` 311 + `municipalityUi.ts` 765/59 exports), e as listas de lideranças/organizações/dobradinhas são clones de página com 5 parsers locais duplicados. B17 (seletor de colunas) e B18 (filtros salvos) pousariam em cima disso multiplicado.
|
||||
|
||||
## Objetivos
|
||||
|
||||
- Definições de coluna como dado: `id`, header, cell renderer, `sortKey?`, `filterDef?`, `mandatory?`, `defaultVisible?`, tratamento mobile.
|
||||
- Estado de URL genérico (parse/canonicalize/serialize) estendendo `campaignListUrl.ts` — contrato de URL existente **byte-idêntico** (pins de W0 verdes).
|
||||
- Tabela server-first + ilhas client generalizadas de `MunicipalitySortableHead`/`MunicipalityHeaderFilter`.
|
||||
- Slots de toolbar (busca, barra de filtros, botões futuros de B17/B18); empty state que mantém o chrome montado (lição de B16); slot de card-stack mobile; paginação/pending pelos shells existentes.
|
||||
- Superfície migrada = código antigo deletado na mesma entrega (knip limpo).
|
||||
|
||||
## Entregas
|
||||
|
||||
**D1 — núcleo + lista de municípios.** O sistema nasce extraído da lista mais rica, não inventado: column defs, URL state, ilhas, toolbar. Absorve o **B16+** ([escala-dry-pos-b16.md](escala-dry-pos-b16.md)): hook `useOptimistic` de navegação compartilhado, hrefs de opção a partir de uma base `URLSearchParams`, payload de facet por slugs. **Divide `municipalityUi.ts`** nas costuras naturais (url/filters/sort/labels/freshness). Células de edição inline (B9) viram cell-renderer islands.
|
||||
|
||||
**D2 — migra o resto + deleta o superado.** Tripé de entidades (lideranças/organizações/dobradinhas) numa composição de página compartilhada + parsers de `campaignListUrl` (fecha o débito de parser do C8 F3); demandas (`CampaignFilterChips` → filter def); apoiadores (mantém cards mobile); assessores (tabela client adota estado/toolbar/paginação; inline-create continua bespoke).
|
||||
|
||||
## Fora do escopo (D5 do sign-off — anti-classitis, documentado)
|
||||
|
||||
- `ActionPlanList` — domínio de cards, não de tabela; adota só toolbar/URL state.
|
||||
- `TerritoryOverviewTable` — exceção documentada de sort no cliente (dataset ≤27 linhas, já carregado).
|
||||
- `MunicipalityCandidateComparisonTable`, `LeaderContactsPanel`, preview do wizard de import — pequenas/estáticas demais.
|
||||
- B17/B18 **não são implementados** — o sistema deixa as costuras (visibilidade por column id, serializador de filtros) e para aí.
|
||||
|
||||
## Impacto no roadmap
|
||||
|
||||
- **Quase de graça depois:** B17 (seletor de colunas = toggle de visibilidade sobre column ids + localStorage), B18 (filtros salvos = serializador + slot na toolbar), "Cenário junto aos filtros" (slot na barra; cenário nunca entra na serialização de URL), ícone de prioridade (accessory slot na célula de nome).
|
||||
- **Costuras para:** E10/E14 (nova coluna = nova column def + ilha inline opcional), E12 (ponto de extensão de group-mode documentado, não construído).
|
||||
- **Absorve:** B16+ (plano marcado como absorvido).
|
||||
- **Conflitos:** precisa terminar antes do trabalho de colunas da janela 3 (~16/08) e antes de B17/B18 entrarem em desenvolvimento.
|
||||
- **Supersede premissas em:** [seletor-colunas-lista-municipios.md](seletor-colunas-lista-municipios.md), [filtros-salvos-municipios.md](filtros-salvos-municipios.md), [cenario-junto-filtros-municipios.md](cenario-junto-filtros-municipios.md), [escala-dry-pos-b16.md](escala-dry-pos-b16.md) (seções marcadas em W5).
|
||||
|
||||
## Rabbit holes
|
||||
|
||||
- **Generalizar `MunicipalityHeaderFilter` inteiro no D1.** As facetas de município (435 opções + busca) são as mais complexas; a generalização é a *interface* (filterDef + slot), a implementação rica continua específica até um segundo consumidor pedir.
|
||||
- **DataTable do shadcn como base.** Consultar composição, mas a casa já tem `ui/Table` + DESIGN.md; introduzir TanStack Table trocaria o modelo server-first por client state — não.
|
||||
- **Mexer na semântica de URL "aproveitando".** Congelada (B18 depende dela).
|
||||
|
||||
## Referências
|
||||
|
||||
- `src/utilities/campaignListUrl.ts`, `src/utilities/municipalityUi.ts`, `src/components/campaign/MunicipalityList.tsx`, `MunicipalitySortableHead.tsx`, `MunicipalityHeaderFilter.tsx`, `MunicipalityFilters.tsx`
|
||||
- `src/app/(campaign)/campanha/(app)/{liderancas,organizacoes,dobradinhas,demandas,apoiadores,assessores}/page.tsx`
|
||||
- [escala-dry-pos-c6.md](escala-dry-pos-c6.md) (C8 F3/F4), [filtros-no-header-lista-municipios.md](filtros-no-header-lista-municipios.md) (B16), DESIGN.md
|
||||
26
docs/plans/split-election-insights.md
Normal file
26
docs/plans/split-election-insights.md
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
# Split de electionInsights.ts (Pass 2 — W4a)
|
||||
|
||||
Status: aprovado (Pass 2, 2026-07-25) — decisão D2 assinada: DELETAR os clusters mortos
|
||||
Atualizado em: 2026-07-25
|
||||
Item pai: [IMPROVE-CODE-QUALITY-PLAN.md](../IMPROVE-CODE-QUALITY-PLAN.md) — Pass 2, W4a
|
||||
Appetite: ~0,5 dia; precisa terminar antes de E10 começar (~16/08)
|
||||
|
||||
## Contexto
|
||||
|
||||
`src/lib/electionInsights.ts`: 941 linhas, 71 exports, **2 usados em produção** — `formatElectionNumber` (13 importers) e `computeVoteTrend` (+ tipos, 1 importer: `MunicipalityBaselineCard`). O resto é a matemática de insights da era núcleos (A4: gap vs 2022, limiares 35/20/10, rankings por núcleo) cuja UI morreu no remodel de municípios; os testes que restam testam código sem consumidor.
|
||||
|
||||
## Decisão (D2, assinada 2026-07-25)
|
||||
|
||||
**Deletar** os ~52 exports sem consumidor + seus testes, com ponteiro para E10 no commit e neste plano. Rejeitado: módulo-quarentena (`electionInsightsLegacy.ts`) — manter matemática morta convida reuso acidental da abordagem de limiares absolutos que E10 explicitamente substitui por classificação relativa (quantis/LQ — ver `docs/research/` e [classificacao-territorial-relativa.md](classificacao-territorial-relativa.md)). As fórmulas ficam no git history e nos planos.
|
||||
|
||||
## Escopo
|
||||
|
||||
1. Extrair `formatElectionNumber` (+ helpers de formatação vivos) para `src/lib/electionFormat.ts`; atualizar os 13 importers.
|
||||
2. Manter o cluster `computeVoteTrend` (tipos + função) — em `electionFormat.ts` ou módulo próprio pequeno, o que a costura natural pedir.
|
||||
3. Deletar `electionInsights.ts` restante + specs correspondentes; knip limpo.
|
||||
4. Marcar em [classificacao-territorial-relativa.md](classificacao-territorial-relativa.md) que a premissa "editar electionInsights in place" foi superada — E10 nasce em módulo novo.
|
||||
|
||||
## Impacto no roadmap
|
||||
|
||||
- **E10** (classificação relativa): parte de terreno limpo em vez de herdar 900 linhas de abordagem rejeitada. Precisa desta entrega antes de começar (~16/08).
|
||||
- Derruba o maior ofensor do knip `exports` (25 findings) — pré-requisito prático de W4b (warn→error).
|
||||
Loading…
Reference in a new issue