mirror of
https://github.com/fsolla/teqo.git
synced 2026-11-14 17:43:04 +00:00
89 lines
4.8 KiB
Markdown
89 lines
4.8 KiB
Markdown
# Impl: Município v2 — rede (lista edit-in-place)
|
||
|
||
Status: aprovado
|
||
Atualizado em: 2026-08-03
|
||
Issue: #332
|
||
Intenção: docs/plans/municipio-v2-rede.md
|
||
Appetite restante: ~1 dia eng (herdado)
|
||
|
||
## Leitura da intenção
|
||
|
||
- **Outcome:** rede na dobra principal da v2 — lista densa (tabela desktop / lista mobile) com top-N lideranças, declarado e estimado editáveis no lugar (auto-save B9), caminho para ver todas e criar liderança; leader não vê estimado.
|
||
- **O que NÃO negociar:** assimetria estimado (staff-only); leader lockdown na página; não cards empilhados; não spreadsheet de colunas da ficha global; não substituir ficha completa (link ao detalhe).
|
||
- **O que reavaliar:** reusar `DeclareVotesForm`/`PledgeEstimateForm` (rejeitados — têm botão Salvar); twin de loaders vs composer fino; N do top-N.
|
||
|
||
## Abordagem recomendada
|
||
|
||
```mermaid
|
||
flowchart LR
|
||
Page["municipio/[slug]/v2/page.tsx"]
|
||
Loader["loadMunicipalityV2NetworkData"]
|
||
Panel["MunicipalityV2NetworkSection"]
|
||
List["MunicipalityV2NetworkList"]
|
||
Declared["MunicipalityV2DeclaredVotesCell"]
|
||
Estimated["MunicipalityV2EstimatedVotesCell"]
|
||
DeclAPI["POST municipios/pledge-declared-votes"]
|
||
EstAPI["POST municipios/pledge-estimated-votes"]
|
||
Page --> Loader --> Panel --> List
|
||
List --> Declared --> DeclAPI
|
||
List --> Estimated --> EstAPI
|
||
```
|
||
|
||
**Opções consideradas:**
|
||
|
||
| | A — Reusar panels atuais (cards + forms) | B — Lista densa + B9 cell autosave + JSON routes | C — CampaignTable completo com colunas B17 |
|
||
| --- | ---------------------------------------- | ------------------------------------------------ | ------------------------------------------ |
|
||
| | Rápido mas cards + Salvar | Alinha B9 e aceite | Overkill sem picker de colunas |
|
||
|
||
**Recomendação:** B — lista densa com `CampaignCellEditOverlay` + `useCampaignCellAutosave`; writes via `declareVotes`/`estimateVotes` existentes; revalidate v2 via `revalidateMunicipalityListPaths`.
|
||
|
||
**Rejeitadas:** A (cards + botão Salvar violam aceite). C (B17 não pedido; 4 colunas fixas).
|
||
|
||
### Decisões de engenharia
|
||
|
||
1. **Top-N = 8** — mesmo cap do dossiê (`DOSSIER_LEADERSHIP_LIMIT`). Ordenação: `effective(central)` desc, depois `declared` desc (assumido na intenção).
|
||
2. **Merge leadership × pledge** em pure `buildMunicipalityV2NetworkRows` — liderança sem pledge aparece com declarado/estimado vazios; estimado só editável quando existe `pledgeID`.
|
||
3. **JSON routes** em `municipios/pledge-declared-votes` e `municipios/pledge-estimated-votes` (paridade `expected-votes`); `safeMessages` de `votePledge` schemas.
|
||
4. **Estimado na célula** — trigger mostra média (cenário central); popover/sheet com `VoteEstimateScenarioInputs` compact (precedente `MunicipalityListExpectedVotesControl`).
|
||
5. **Declarado na célula** — popover/sheet com input numérico; autosave debounce 600ms + flush no close.
|
||
6. **CTAs** — "Ver todas" → `?tab=leaderships`; "Nova liderança" → `/campanha/liderancas/nova?municipality=` (textual, não FAB — B151).
|
||
|
||
### Componentes / mudanças
|
||
|
||
- **`loadMunicipalityV2NetworkData`** (`utilities/municipality/municipalityV2NetworkData.ts`): composer sobre `loadMunicipalityLeaderships` + `loadMunicipalityPledges`.
|
||
- **`municipalityV2NetworkView.ts`**: tipos + sort/merge puros (unit-tested).
|
||
- **`MunicipalityV2NetworkSection` + `MunicipalityV2NetworkList` + células** (`components/campaign/municipality/`).
|
||
- **Routes:** `pledge-declared-votes/route.ts`, `pledge-estimated-votes/route.ts` + `types.ts`.
|
||
- **`pledgeFormActions.ts`:** revalidate via `revalidateMunicipalityListPaths` (inclui v2).
|
||
- **Migration:** nenhuma.
|
||
- **Access:** `declareVotes`/`estimateVotes` existentes; página `noLeader`.
|
||
- **UI:** Impeccable B — lista densa; shells B9; `data-theme='campaign'`.
|
||
|
||
### Dados → forma
|
||
|
||
- Tabela 4 colunas (nome · status · declarado · estimado); mobile = mesma informação em linhas densas, não cards empilhados por pessoa com forms longos.
|
||
|
||
## Fases verificáveis
|
||
|
||
1. **Server** — view puro + loader + JSON routes + revalidate paths.
|
||
2. **UI** — section na página v2 + células autosave + CTAs.
|
||
3. **Gates** — unit sort/merge; `pnpm gate:fast`; `pnpm push`.
|
||
|
||
## Rabbit holes / Não escopo (engenharia)
|
||
|
||
- FAB B151; conta B148; agora B150; cutover B152.
|
||
- Edição de status de apoio na rede (fora das 4 colunas).
|
||
- Nota de estimativa na lista (ficha completa / popover longo).
|
||
|
||
## Riscos e mitigação
|
||
|
||
- **Conta não atualiza após edit:** `revalidateMunicipalityListPaths` busta página v2; aceite permite conta refresh posterior (B148).
|
||
- **Pledge inexistente:** declarado cria via `declareVotes`; estimado disabled até existir pledge.
|
||
|
||
## Aceite de engenharia
|
||
|
||
- [ ] Aceite de produto da intenção coberto
|
||
- [ ] Invariantes AGENTS/engineering-standards
|
||
- [ ] Unit tests em `municipalityV2NetworkView`
|
||
|
||
Self-score decision-quality: 4/5
|