Commit graph

6 commits

Author SHA1 Message Date
Francisco Solla
6de8fad8f6 feat(C112): múltiplos telefones por pessoa — Contact.phones array (ordem = prioridade)
- Contact.phone (text único) → phones (array field Payload, subcampo value):
  fonte única; principal = phones[0]; beforeValidate normaliza, filtra vazios,
  rejeita inválido e duplicado DENTRO da ficha (C111 entre fichas preservado)
- migration add_contact_phones_array: backfill phone → phones[0] (gen_random_uuid)
  antes do drop da coluna + índice em value (hand-edit documentado; snapshot .json
  gerado mantém as colunas C99/C100 já existentes)
- primaryPhoneOf / phoneValuesOf / reorderWithPrimaryPhone em src/lib/phone.ts
  (ordem = prioridade; inline edit = seta o principal preservando o resto)
- findOrCreateContactByPhone aceita phones[] (dedupe pelo primário; reuse faz
  append dos faltantes; locks em todos os números digitados)
- sync conta→ficha (CampaignUser): phone da conta faz APPEND quando a ficha não
  tem (nunca reordena nem remove); tombstone LGPD substitui TODOS os telefones
- convite redemption: telefone digitado vira principal, demais preservados
- import CSV: preview sinaliza compartilhado também por número secundário;
  bulk insere contact_phones (JOIN nas leituras, uuid no insert)
- busca por telefone (apoiadores, pickers, combobox) casa qualquer número
- UI: PhonesFieldEditor compartilhado (repetível mascarado, remover, ↑/↓,
  modo inline com Salvar) nas 5 superfícies — liderança (form/ficha/lista),
  apoiador (form/ficha), dobradinha (ficha), assessor (ficha), wizard
- UI pública (petição/WhatsApp) intocada: zod e forms ficam com phone;
  as ações mapeiam phone → phones[0]
- testes: spec novo campaignMultiPhones (aceite completo), specs C111/C99
  atualizados, e2e wizard/apoiador ajustados
2026-08-11 10:47: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
c706c62098 Pass 2 W2: components/campaign em subpastas por dominio
106 arquivos flat -> 15 dominios (actionPlan, advisor, auth, dashboard, demand, invite, leadership, map, municipality, organization, stateDeputy, supporter, votePledge, shared, shell) via git mv; imports absolutos reescritos em 98 arquivos; excecao de lint do campaign-logo e paths dos specs de contrato (campaignInviteUi, campaignComponents) atualizados. Sem mudanca de conteudo nos componentes.
2026-07-25 14:52:17 -03:00
Francisco Ignácio Fontoura Solla
cf6ae6c47c Pass 2 W2: correcoes de fronteira lib/utilities e client boundary
- helpers puros movidos utilities->lib: slug, phone, wordStartFilter, voteEstimate (9 inversoes lib->utilities zeradas)
- chaves de consent em src/lib/campaignConsentKeys.ts (client-safe); campaignInvite/campaignConsent re-exportam; onda0ConsentTexts referencia as constantes
- 'server-only' em 21 loaders Payload/cache (CLI segue com --conditions=react-server)
- ciclo de tipos supporterListFilters <-> supporterUi quebrado (SupporterListFilterInput estrutural; sqlFilters idem)
- votePledgeData dividido: votePledgeViews (puro, client-safe) + votePledgeData (loaders, server-only) - padrao contract-module
- predicados de role client-safe em src/lib/campaignRoles.ts; access/shared deriva deles (fonte unica); nav.ts para de importar o barrel campaignAccess (casts 'as CampaignUser' eliminados)
2026-07-25 14:38:41 -03:00
Francisco Ignácio Fontoura Solla
52c402c049 Fix the three leader-flow bugs the e2e suite pinned + RSC prop contracts
E2E-driven fixes (the suite now passes 9/9; two journeys remain
latency-flaky on cold dev compiles and pass on retry):

- leader home crashed with Forbidden since the remodel:
  loadLeaderContactsPageData loaded municipality options through the
  staff-scoped loader (leaders are denied municipality reads); their scope
  now derives from the engaged leadership's linked municipalities
- leaders saw 'Contato — —' instead of their supporters' names:
  getAccessibleContactIds now mirrors canReadSupporter for leaders
  (contacts of supporters they created)
- leader nav had two items with the same /campanha href (duplicate React
  keys); the leader home IS the contact tool — one entry
- RSC serialization contracts: CampaignListPagination is a server component
  again (hrefForPage stays server-side; CampaignTransitionAnchor client leaf
  intercepts clicks with serializable props); CampaignSearchForm takes
  basePath instead of a function prop
- hasAnyEstimate moved from the 'use client' PledgeEstimateForm to
  voteEstimate.ts — server components may not call client-module exports
- playwright.config honors TEQO_TEST_DATABASE_URL (parity with
  vitest.setup.ts) and uses a fixed .next/e2e dist dir so Next stops
  appending per-PID entries to tsconfig include; report artifacts
  eslint-ignored
2026-07-24 00:38:40 -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