Merge branch 'cursor/63b4db6b'
This commit is contained in:
commit
39cbce8d79
3 changed files with 118 additions and 1 deletions
|
|
@ -7,7 +7,9 @@ alwaysApply: false
|
|||
|
||||
## Status
|
||||
|
||||
- **Fill-in registrado (2026-07-24):** seletor **Cenário** de `/campanha/municipios` → fileira de `MunicipalityFilters` (provider envolve filtros+resultados; overview sem seletor). Plano: [`cenario-junto-filtros-municipios.md`](../../../docs/plans/cenario-junto-filtros-municipios.md).
|
||||
- **E4R entregue em código (2026-07-24):** `pnpm db:seed:projecao` (`scripts/import-projecao.mjs` + `src/lib/projectionSheetParse.ts`) importa MAPA GERAL canônico → `expectedVotes` (Bom→otimista, Regular→média, Mínimo→pessimista) + `priority` com **overwrite-always** (re-seed quando chegar planilha nova); Salvador pulado; zero PII; dry-run + runbook. No mesmo dia o grupo duplicado `voteGoals` foi removido do app (ver Decisões). Seed local: arquivo `docs/sheets/Mapa projeção de votos Solla 2026.xlsx`, **189** municípios com estimativas, **50** `priority=alta`, re-run delta=0. Produção: após smoke, `ALLOW_REMOTE_DB=true … pnpm db:seed:projecao -- --dry-run` → apply. Plano: [`import-planilha-projecao.md`](../../../docs/plans/import-planilha-projecao.md).
|
||||
|
||||
- **Sync roadmap × sessão de campo (2026-07-24):** os achados da sessão real do CG (2026-07-23, `docs/CUSTOMER.md`) foram incorporados ao roadmap e aos planos de inteligência — âncora da mesa = **% da própria votação** (A11 entrega a lente; E9/E10/B13 expõem ao lado de LQ/captura); piso 150 mil resolve a meta inicial de E8; O6 vira **E16 dossiê do município** + gap **G11 emendas por município**; O7 confirma C12 não cortável; E13 rebaixado na fila de corte ("perna" é a restrição dominante); gatilho de D3 reformulado (deltas do ZAP não absorvidos pelo fluxo sede-digita/C12); FD2 absorvido por R6; O8 "ilhas isoladas" em A validar. **Decisão de produto: E4 reaberto como E4R** — seed único via script das planilhas de `docs/sheets/` (arquivo com espaços = canônico de estratégia; underscore = referência Salvador; v1 só `voteGoals`/`priority`, sem PII; Salvador pulado com relatório). Novos itens: **E4R** (janela 1, não cortável), **A11**, **E17 tabela TI no Início** (pedido do candidato; primeira fatia de E12), **B14 município mais próximo** (geolocalização → atalho no Início staff; prompt 1×/sessão; client-only). Planos novos: `import-planilha-projecao.md`, `ranking-votos-municipio.md`, `tabela-ti-inicio.md`, `dossie-municipio.md`, `municipio-mais-proximo.md`.
|
||||
- **DEPLOY EM PRODUÇÃO REALIZADO (2026-07-23).** A cadeia destrutiva da remodelagem (`20260721_020109_remodel_municipalities` → `20260723_200000_remodel_municipalities` + `20260723_202000_reconcile_municipality_remodel`) foi aplicada em produção pelos builds Vercel de 2026-07-23 (deploys production READY dos commits `a7b8f1b`/`c7a1b74`/`59868a9`). **Este item supersede toda menção "deploy pendente" nas entradas abaixo.** Pendências operacionais: smoke pós-deploy + onboarding do time (Onda 0 §2/§4 em [`docs/roadmap.md`](../../../docs/roadmap.md)); hold de PII real segue no lote jurídico.
|
||||
- **Hardening de engenharia entregue e em produção (2026-07-23, Fases 0–6):** (0) access lockdown — `users`/`signature`/`subscription`/`consent` admin-only, escrita de CMS (`post`/`tag`/`media`/`petition`) admin-only, gates de rota do leader em `demandas*`/`planos*`, `createLeaderSupporter` com escopo correto, `candidate` tratado como staff irrestrito em todas as superfícies; (1) tooling gate — knip no CI (`.github/workflows/ci.yml`, mirror GitHub), `pnpm lint --max-warnings=0`, ban `as never` (helpers `hookFilledCreateData`/`stub<T>`), tsconfig consolidado + `noUnusedLocals`, ~12 módulos mortos deletados; (2) caching — artefato TSE commitado (`pnpm build:election-aggregates` → `src/lib/electionAggregates/`, loader `bahiaElectionAggregates.ts`), `unstable_cache` com tag `election-tse` nos loaders de eleições, `loadMunicipalityScope` (React `cache()`) dedupe dashboard+mapa+lista; (3) pending honesto — bug de revalidação do toggle de tarefa, `CampaignListPendingBoundary` esmaecendo resultados, transição no compare do mapa, mapa do dashboard + abas do detalhe em Suspense; (4) state scoping — hover do mapa isolado em `MunicipalityMapSelection`, provider de cenário estreitado, `LeaderContactForm` extraído como ilha cliente; (5) estrutura — `campaignAccess` dividido em `src/utilities/access/*` (re-export preservado), `supporterImport.ts` separado, `runStaffEntityMutation` + `runCampaignRedirectFormAction` dedupando twins e 4 ladders de formActions, rename `PLAZA_*`→`MUNICIPALITY_*` concluído; (6) docs + regra `.cursor/rules/engineering-standards.mdc`. Tracker: [`docs/IMPROVE-CODE-QUALITY-PLAN.md`](../../../docs/IMPROVE-CODE-QUALITY-PLAN.md) · ledger: [`docs/TECH-DEBT.md`](../../../docs/TECH-DEBT.md) · mapa de testes: [`docs/TESTING.md`](../../../docs/TESTING.md).
|
||||
|
|
|
|||
114
docs/plans/cenario-junto-filtros-municipios.md
Normal file
114
docs/plans/cenario-junto-filtros-municipios.md
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
# Seletor de Cenário junto aos filtros de Municípios
|
||||
|
||||
Status: rascunho
|
||||
Atualizado em: 2026-07-24
|
||||
Item do roadmap: [docs/roadmap.md](../roadmap.md) (Fill-ins)
|
||||
Impeccable: B — encaixe em `MunicipalityFilters` + `MunicipalityListOverview` (`/campanha/municipios`); sem rota nova
|
||||
Appetite: ~0,25–0,5 dia eng; relocação de controle + ajuste do provider; sem migration
|
||||
Responsável: —
|
||||
|
||||
## Design (Impeccable)
|
||||
|
||||
Âncoras: `PRODUCT.md` (princípios 2 — clareza sob pressão — e 8 — Feel the action) / `DESIGN.md` (register `product`; Field Desk) · tema `data-theme='campaign'` · shells `MunicipalityFilters`, `VoteEstimateScenarioField`, `MunicipalityEstimateScenarioProvider`.
|
||||
|
||||
Na implementação (`implement-roadmap-item`): craft compacto → critique → polish (só posição do controle; sem redesign da lista/overview).
|
||||
|
||||
Brief compacto:
|
||||
|
||||
- **Persona / contexto:** Assessor / CG monta o recorte de municípios (TI, tipo, prioridade…) e já quer escolher **qual cenário** lê na lista/overview no mesmo gesto — sem descer o olhar até o card de visão geral.
|
||||
- **Job principal:** um único eixo de controles de leitura da lista: filtros de recorte + cenário de estimativa.
|
||||
- **Estratégia de cor:** Restrained.
|
||||
- **Edit where you see:** não — o seletor só troca leitura (estado local A10); mutação de estimativas permanece nos Popovers/forms existentes.
|
||||
- **Anti-goals:** segundo seletor duplicado overview+filtros; meter Cenário na URL; redesign do layout de filtros; unificar com o seletor do mapa do Início neste item.
|
||||
|
||||
## Dados → decisão → apresentação
|
||||
|
||||
Dados: N/A — este item **não** muda métricas, agregação nem forma de apresentação; só relocação do controle de leitura já entregue em A10. Overview/lista continuam com número do cenário ativo + faixa secundária.
|
||||
|
||||
## Contexto
|
||||
|
||||
Em `/campanha/municipios` (staff), o seletor **Cenário** (`VoteEstimateScenarioField`) vive no header de `MunicipalityListOverview` — acima do `CampaignMetricStrip`, **abaixo** da barra de filtros (`MunicipalityFilters`: busca, TI, tipo, assessoria, tendência, prioridade). O estado é local via `MunicipalityEstimateScenarioProvider` (default `central`), sincronizando overview + células da lista; no Início o mapa tem seletor próprio quando Ano=2026.
|
||||
|
||||
A página hoje **embrulha o provider só em torno dos resultados**, de propósito — comentário em `municipios/page.tsx`: troca de cenário não deve re-renderizar os filtros. Pedido de produto (2026-07-24): o Cenário deve ficar **junto dos outros filtros** da página.
|
||||
|
||||
Polish anterior (notebook 2026-07-23) já tinha movido o seletor do mapa → overview; este item completa o agrupamento mental “controles de recorte/leitura da lista”.
|
||||
|
||||
## Objetivos
|
||||
|
||||
- Staff em `/campanha/municipios`: seletor **Cenário** renderizado na mesma fileira/região de `MunicipalityFilters` (visível com `showStaffFilters`), reusando `VoteEstimateScenarioField`.
|
||||
- Remover o seletor do header de `MunicipalityListOverview` (overview continua a reagir ao contexto: strip, labels, flash).
|
||||
- Expandir o `MunicipalityEstimateScenarioProvider` para envolver **filtros + resultados** quando staff — o controle nos filtros precisa do contexto; um único provider por página.
|
||||
- Cenário permanece **estado local** (não URL); **Limpar** continua zerando só query params / busca — não reseta cenário.
|
||||
- Guardrails: sem migration, sem collection, sem Consent, sem server action; semântica A10 intacta; `leader` não vê o seletor (página já redireciona; `showStaffFilters` false).
|
||||
|
||||
## Decisões travadas
|
||||
|
||||
- **Fill-in com plano próprio (não reabrir A10; não absorver só em R6; não item de trilha B).** Relocação barata, paralelizável, cortável; A10 já entregue a semântica. (2026-07-24, classificação roadmap-item.) **Rejeitado:** fase informal de A10 (mistura entrega fechada com polish de layout); só R6 (atrasa quick win no critique largo); ID B novo (infla grafo por ~½ dia).
|
||||
- **Provider envolve filtros + `CampaignListResults` (staff).** Necessário para o seletor viver em `MunicipalityFilters`. Custo: troca de cenário re-renderiza a árvore dos filtros — aceitável (controle local, sem navegação). **Rejeitado:** prop-drill `scenario`/`setScenario` sem provider; dois providers; manter seletor no overview *e* nos filtros (duplicata).
|
||||
- **Cenário continua fora da URL e fora de `buildMunicipalityFiltersKey` / Limpar.** Alinhado à decisão A10 (Ano/Escala locais; só `compare` na URL do mapa). **Rejeitado:** `?estimate=` neste item; Limpar resetar cenário (mistura recorte URL com lente de leitura).
|
||||
- **Hint:** adaptar copy do overview (hoje `VOTE_ESTIMATE_SCENARIO_OVERVIEW_HINT`) para o contexto dos filtros (“Troca o total da visão geral e os votos na lista…”); mapa no Início permanece com o hint próprio. **Rejeitado:** remover o `CampaignInfoHint`.
|
||||
- **i18n e naming** (AGENTS.md): identificadores existentes (`VoteEstimateScenarioField`, `MunicipalityEstimateScenarioProvider`); strings “Cenário” / Pessimista / Média / Otimista.
|
||||
|
||||
## Questões em aberto
|
||||
|
||||
- **Posição exata na fileira (antes ou depois dos selects de recorte)?** **Opções:** A) após Prioridade (fim dos staff filters, antes de Limpar) | B) logo após a busca | C) fileira própria abaixo. **Recomendação:** **A** — Cenário é lente de leitura do resultado, não critério de where; fica com os controles staff sem competir com busca/TI. _(assumido — validar no craft se a fileira quebrar em mobile)_
|
||||
- **Mapa do Início: espelhar “Cenário nos filtros do dashboard”?** **Opções:** A) neste item | B) fora / R6 se critique pedir. **Recomendação:** **B** — pedido é a página de municípios; mapa já agrupa Cenário com Ano/Escala.
|
||||
|
||||
## Abordagem proposta
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
page["municipios/page.tsx"] --> provider["MunicipalityEstimateScenarioProvider"]
|
||||
provider --> filters["MunicipalityFilters + VoteEstimateScenarioField"]
|
||||
provider --> results["CampaignListResults"]
|
||||
results --> overview["MunicipalityListOverview sem seletor"]
|
||||
results --> list["MunicipalityList células"]
|
||||
filters -.setScenario.-> provider
|
||||
provider -.scenario.-> overview
|
||||
provider -.scenario.-> list
|
||||
```
|
||||
|
||||
Componentes:
|
||||
|
||||
- **`MunicipalitiesPage`** (`src/app/(campaign)/campanha/(app)/municipios/page.tsx`): mover `MunicipalityEstimateScenarioProvider` para envolver `{filters}` + `{CampaignListResults…}` quando `isStaffView`; atualizar o comentário (provider deixa de ser “só results”).
|
||||
- **`MunicipalityFilters`** (`src/components/campaign/MunicipalityFilters.tsx`): se `showStaffFilters`, renderizar `VoteEstimateScenarioField` na fileira (id estável, ex. `municipality-filter-estimate-scenario`); consumir `useMunicipalityEstimateScenario()` — só montar essa página staff com provider ao redor.
|
||||
- **`MunicipalityListOverview`** (`src/components/campaign/MunicipalityListOverview.tsx`): remover o bloco do seletor no header; manter `useMunicipalityEstimateScenario`, strip, flash e métricas.
|
||||
- **`VoteEstimateScenarioField`**: reusar; ajustar hint exportado se o texto ainda falar só de “visão geral” como locus do controle.
|
||||
- **Migration**: Sem migration, sem collection, sem server action.
|
||||
|
||||
Depth check: reusa field + context + filters existentes; sem hook/shared shell novo (<3 call sites de “filtro+cenário”).
|
||||
|
||||
## Dependências
|
||||
|
||||
- Nenhuma de outro plano aberto. Reusa A10 entregue (`voteEstimate`, `MunicipalityEstimateScenarioProvider`, `VoteEstimateScenarioField`) e o fill-in filtros-auto ([filtros-auto-pracas.md](filtros-auto-pracas.md)).
|
||||
|
||||
## Não escopo
|
||||
|
||||
- Seletor de Cenário no mapa do Início / `MunicipalityMapPanel` (permanece com Ano=2026) — R6 ou pedido futuro.
|
||||
- Persistência de cenário em URL, cookie ou perfil.
|
||||
- Mudança de agregação, default `central`, ou assimetria leader.
|
||||
- Redesign do overview / metric strip / flash.
|
||||
- Unificar `MunicipalityFilters` com filtros de outras listas.
|
||||
|
||||
## Rabbit holes
|
||||
|
||||
- **`?estimate=` na URL “só para share”.** Explode RSC/key de filtros e diverge do mapa. **Mitigação:** Decisão travada — estado local; gatilho só com pedido explícito de share de cenário.
|
||||
- **Provider global de cenário em todo `/campanha`.** Acopla Início↔lista sem necessidade. **Mitigação:** provider só na página de municípios (como hoje, com escopo ampliado na página).
|
||||
- **Tratar Cenário como filtro de where / incluir em Limpar.** Muda semântica A10. **Mitigação:** fora de `MunicipalityListState` e de `hasActiveFilters`.
|
||||
|
||||
## Adiado com gatilho
|
||||
|
||||
- **Mesma colocação mental no dashboard (mapa).** Revisitar quando: R6 critique o Início ou produto pedir “um só lugar para Cenário” entre mapa e lista.
|
||||
|
||||
## Referências
|
||||
|
||||
- `docs/roadmap.md` (Fill-ins abertos)
|
||||
- `src/app/(campaign)/campanha/(app)/municipios/page.tsx` — composição filters / provider / results
|
||||
- `src/components/campaign/MunicipalityFilters.tsx` — fileira de controles
|
||||
- `src/components/campaign/MunicipalityListOverview.tsx` — seletor atual + flash
|
||||
- `src/components/campaign/VoteEstimateScenarioField.tsx` — controle reutilizado
|
||||
- `src/components/campaign/MunicipalityEstimateScenarioContext.tsx` — estado local
|
||||
- [cenarios-estimativa-votos.md](cenarios-estimativa-votos.md) (A10) — semântica e default
|
||||
- [filtros-auto-pracas.md](filtros-auto-pracas.md) — precedente de fill-in na mesma superfície
|
||||
- AGENTS.md — naming; campaign staff vs leader
|
||||
- `PRODUCT.md` / `DESIGN.md` — Field Desk, Feel the action
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
# Roadmap — Teqo
|
||||
|
||||
Atualizado em: 2026-07-24 (E4R entregue em código — seed local; B14 município mais próximo no roadmap; janela 1: smoke pós-deploy, A11/E17, R6, E8 — [CUSTOMER.md](CUSTOMER.md))
|
||||
Atualizado em: 2026-07-24 (fill-in: seletor Cenário junto aos filtros em `/campanha/municipios` — [plano](plans/cenario-junto-filtros-municipios.md); E4R ✓; B14; janela 1: smoke, A11/E17, R6, E8)
|
||||
|
||||
Registro canônico dos **próximos** planos e débitos. Histórico de entregas: resumo abaixo + planos em [`docs/plans/`](plans/) + notebook [`.cursor/rules/projects/nucleos-eleitorais.mdc`](../.cursor/rules/projects/nucleos-eleitorais.mdc).
|
||||
|
||||
|
|
@ -86,6 +86,7 @@ O discovery literatura→persona→entrevista ([relatório aprovado](research/re
|
|||
|
||||
### Fill-ins abertos
|
||||
|
||||
- **Cenário junto aos filtros** em `/campanha/municipios` — mover `VoteEstimateScenarioField` para a fileira de `MunicipalityFilters`; overview só consome o contexto · ~0,25–0,5d · Impeccable B · [plano](plans/cenario-junto-filtros-municipios.md)
|
||||
- **O0+** escala/DRY pós-Onda 0 · [plano](plans/escala-dry-pos-onda0.md)
|
||||
- **RS+** auth read leve + shells de senha · [plano](plans/escala-dry-pos-reset-senha-perfil.md)
|
||||
- **C10 / C11** escala apoiadores/planos · reavaliar nas superfícies remodeladas · gatilhos originais intactos: base nominal crescendo ([plano](plans/escala-dry-pos-c9.md)) / volume de planos medido ([plano](plans/escala-dry-pos-c7.md))
|
||||
|
|
|
|||
Loading…
Reference in a new issue