Commit graph

963 commits

Author SHA1 Message Date
Francisco Solla
977dab044e
Merge pull request #729 from fsolla/plans/plan-issue-43
plan(C139): Contatos - pagina da entidade Contact + cancelamento dos planos abertos de Pessoas
2026-08-13 15:56:35 +00:00
Francisco Solla
72d189cfd7 style(plan): prettier no rascunho UI do C139 + re-render PNGs 2026-08-13 12:55:24 -03:00
Francisco Solla
65a5881b2d plan(C139): Contatos — página da entidade Contact; cancela planos abertos de Pessoas (C121/C130+/C132/C135-C138) 2026-08-13 12:53:12 -03:00
Francisco Solla
c2296701e2 style(plans): C135 — formata HTML do rascunho UI (prettier) 2026-08-13 12:05:24 -03:00
Francisco Solla
8ed3da8982 docs(plans): C135 — pessoas mobile feed/cards edge-to-edge com drawer de edição e faixa de status 2026-08-13 12:05:24 -03:00
Francisco Solla
98b03d8e91
Merge pull request #718 from fsolla/C130-pessoas-ajustes-da-tabela-desktop-contato-completo-base
C130 — Pessoas: ajustes da tabela desktop (contato completo, base sob o nome, caret, tooltips, Dobra em, filtro/ordenação por partido)
2026-08-12 16:20:44 -03:00
Francisco Solla
ef41e0c6a3
Merge pull request #726 from fsolla/B200-municipios-mobile-encaixes-dos-cards-densidade-alinhame
B200 — Municípios mobile: encaixes dos cards — densidade, alinhamento de labels e avatares (pós-B196)
2026-08-12 16:01:40 -03:00
Francisco Solla
65659bac2f C130: ajustes da tabela desktop de pessoas (contato completo, base sob o nome, caret, tooltips, Dobra em, filtro/ordenação por partido) 2026-08-12 16:01:25 -03:00
Francisco Solla
98f8ec9b9b
Merge pull request #710 from fsolla/C128-pessoas-qualquer-pessoa-pode-assessorar-liderar-e-ou-do
C128 — Pessoas: qualquer pessoa pode assessorar, liderar e/ou dobrar — ciclo de vida nas tabelas pela lista
2026-08-12 15:45:55 -03:00
Francisco Solla
3ee2d83350 feat(B200): encaixes dos cards mobile de municípios — densidade, alinhamento de labels e pilha de avatares (pós-B196) 2026-08-12 15:40:02 -03:00
Francisco Solla
6f89a8ff59 fix(C128): separadores entre entradas do changelog pós-rebase (C123) 2026-08-12 15:31:01 -03:00
Francisco Solla
c0645067f1 feat(C128): ciclo de vida das capacidades pelas células de /campanha/pessoas (Closes #695)
Qualquer pessoa visível ganha/perde Assessora, Lidera e Aliada em pela
lista: a primeira cidade cria a entidade (conta staff sem credenciais
utilizáveis / liderança / dobradinha), a última remove da tabela com
confirmação destrutiva (manifest: votos+convites da liderança, conta+
autorias+assessorado da assessora; dobradinha sem diálogo). Saída
destrutiva por escopo: assessor encerra Lidera/Aliada com a capacidade
inteira na carteira; Assessora segue coordenação/candidato. Escritas
person-centric por contactId com extração dos deltas B34/B37 e da
cascata de conta (deleteCampaignUserAccount, nextFreeStubCampaignEmail,
matchers de conflito) — sem twin. commitGuard/commitWithNullOwner/
extraFormFields como opt-ins no RelationChipCell. Corrige bug latente
C116 (célula Assessora nunca salvava — contactId faltava no FormData).
Sem migration. Int: 28, unit: 6, e2e: +2.
2026-08-12 15:29:56 -03:00
Francisco Solla
4202462e17 docs(plans): OPS43 — migration-lock bloqueia PRs sem schema por colateral (#721) 2026-08-12 15:03:20 -03:00
Francisco Solla
99a3a5f590 test(OPS42): e2e dev — quiescência do router antes de interagir (login + chat Sollinha) (Closes #691) 2026-08-12 15:03:20 -03:00
Francisco Solla
db8102b47e feat(C123): agenda — overlay modal central como única superfície de criação/edição de atividade (Closes #667) 2026-08-12 14:16:20 -03:00
Francisco Solla
508350fcf1 chore(plan-issue): formata o rascunho do OPS44 (prettier) 2026-08-12 14:12:52 -03:00
Francisco Solla
057eebfbb1 plans(OPS44): redesenhar fluxo de registros/compartilhados para menos conflitos (Related #713) 2026-08-12 14:12:52 -03:00
Francisco Solla
7e05dc925d feat(C131): Salvador como opção agregada no dropdown de municípios das células de capacidade
O dropdown de adição de municípios (pessoas ×3, assessores, lideranças,
dobradinhas) oferece 'Salvador — Todas as zonas' como primeiro hit da busca:
um toque adiciona as 19 ZEs num lote, via máquina existente do RelationChipCell
(delta otimista, cap/floor, undo, colapso 'Salvador (19)' B178, exact-match C116).

- searchMunicipalityPortfolio ganha kind 'city' (NORMALIZED_ZONE_CITIES,
  derivado do catálogo) com gate de escopo por contagem: o agregado só aparece
  quando a cidade inteira está no escopo addableIds do ator — a label 'Todas as
  zonas' nunca mente para assessor com carteira parcial.
- hitDescription ganha o branch 'Todas as zonas'; sem migration/access/schema.
- Testes: unit busca pura (19 ids, soma, escopo parcial, tudo atribuído,
  posição), cell render, e2e em campaignPeople (agregado → chip → 19 zonas no
  DB).
2026-08-12 14:02:34 -03:00
Francisco Solla
a6d5a2695c
Merge pull request #727 from fsolla/ci-remove-migration-lock
chore(ci): remove o migration-lock — deadlock de CI com PRs de schema paralelos
2026-08-12 13:58:35 -03:00
Francisco Solla
4626a2ea06 chore(ci): remove o migration-lock — deadlock de CI com PRs de schema paralelos (checks passa a ser o único required)
O check falhava quando >1 PR aberto tocava src/migrations/ + payload-types.ts,
deadlockando AMBOS os PRs (9 de 13 runs de CI falhos desde 11/08). A validação
real da cadeia de migrations já roda em todo PR e na main: pnpm migrate +
test:int (incl. campaignMigrationReconciliation). Pool mantém a serialização
de spawn de issues needs:migration via countOpenSchemaPrs.
2026-08-12 13:42:05 -03:00
Francisco Solla
1326d54413 style(OPS30): prettier no changelog pós-rebase 2026-08-12 13:34:42 -03:00
Francisco Solla
48088d8162 refactor(OPS30): fixes do /simplify — pessoas no prewarm, login com sub-budgets, retry da demanda via existência, B24 no helper do arquivo
Review 3× read-only (0 P1):
- setup: /campanha/pessoas faltava (campaignPeople); log do 1º hit
  quando o retry salva; comentário do budget ancorado no medido.
- login: sub-budgets 15+5+30 (antes 30+5+30 estourava o test timeout
  e credencial errada morria de timeout genérico); retry bifurca pela
  URL real (dashboard/fora do login/re-submit) — re-submit cego
  contra página que saiu do login falhava com fill na dashboard.
- :713: retry cego criaria duplicata que o UNIQUE do slug refuta —
  o retry consulta por título e navega ao detail quando o 1º POST
  criou mas o redirect se perdeu.
- B24: locator reusa visibleMunicipalityButton (escapeRegExp +
  fronteira de nome, 23/435 com prefixo) e ensureWideMunicipalityList
  re-rodado pós-reload (padrão do irmão dobradinhas).
- :1063: waitForResponse com timeout 5s para o toPass decidir.

Re-prova: campaignMunicipalities 22/22 (arquivo atual, B193+OPS29 do
main) ×3 consecutivos em dev a 2 workers (load 5-17).
2026-08-12 13:34:42 -03:00
Francisco Solla
02beea808b chore(OPS30): hardening e2e em dev — prewarm completo, login resiliente a compile-frio, fechamento do P4-L
- setup.e2e.spec.ts: prewarm GET 13→26 rotas (rota /editar, alvos de
  redirect, wizards, PWA artifacts, rotas do chat Sollinha) + POST
  ganhou next-steps, home-search, ai-chat, ai-transcribe; prewarmGet
  com retry-único (abort do compile aborta a conexão do próprio
  prewarm); budget explícito 420s no lugar do test.slow().
- campaignE2EFixtures.ts: campaign.login com retry-único do submit
  (re-fill+re-click com grace-wait do destino exato) — submit abortado
  pelo full-page reload do compile frio nunca navega.
- campaignMunicipalities.e2e.spec.ts: refactor mínimo por evidência —
  B24 (estágio largo B158 + toggle do trigger pós-reload), :713 (retry
  do server action de criação), :1063 (seed parity via db:seed:minimal
  — achado do OPS28 — + retry do suggest).
- P4-L fechado com evidência: campaignLeaderships ×3 dev + ×1
  E2E_PROD=1 (TECH-DEBT row 59 + TESTING.md caveat).
- Aceite: campaignMunicipalities 17/17 ×3 consecutivos em dev a 2
  workers (load 5-18).

Sem migration/access/Consent/UI.
2026-08-12 13:34:42 -03:00
Francisco Solla
d7acb5aa48 feat(C129): nome de legenda da dobradinha — campo ballotName + display discreto sob o nome (Closes #696) 2026-08-12 12:52:35 -03:00
Francisco Solla
9d330f48e4 merge(C115): rebase em main (C126 activityWhere, C124 tasks, C122 e2e estados, OPS40/41) — spec portado para runSync escopado 2026-08-11 22:48:14 -03:00
Francisco Solla
1fb62039d8 style(C115): format pós-rebase no CHANGELOG 2026-08-11 22:42:36 -03:00
Francisco Solla
6a83dbcc25 docs(C115): débito pós-review — corrida do snapshot + hermeticidade int (#694) 2026-08-11 22:42:05 -03:00
Francisco Solla
2f247d40a6 fix(C115): revisão /simplify — relógio com baseline de espelho, reopen sem re-cancelamento, hardening do webhook
- lastMirroredChangeAt (activity, migration): clock rule compara contra a
  última mudança espelhada, não updatedAt (task toggle não silencia edição
  pendente do Google)
- snapshot exclui ids que o motor deletou (removedEventIds separado do
  remoteEventIds): reopen pós-cancelamento não vira re-cancelamento fantasma
- cancelamento do Google respeita o relógio: cancel mais novo cancela; Teqo
  mais novo (reopen) limpa o trashed e recria
- escrita reversa sem req.user: autoria do registro correta + sem gate 403
  do deputado; hook de sync pula a própria escrita reversa (sem passada aninhada)
- canal: segredo rotaciona por criação; novo canal persistido antes do stop
  do antigo; identity fields read:false; create admin-only; leitura prefere
  linha configurada; pre-filter do webhook antes do bootstrap do Payload
- testes: all-day ida-e-volta, task-toggle, reopen, slug congelado, e2e dos
  caminhos 200, render tests do dialog/feed; asserções herméticas a
  atividades ambiente dos arquivos irmãos (DB compartilhado)
2026-08-11 22:42:05 -03:00
Francisco Solla
7629a505e0 feat(C115): edição pelo Google Calendar volta para o Teqo (motor bidirecional + webhook push)
- runSyncPass bidirecional: regra do relógio decide direção (Google mais novo
  aplica título/horário; Teqo re-asserta), cancelamento via showDeleted +
  snapshot lastSeenEventIds, registro no updates feed
- webhook público /campanha/agenda/google-webhook/[secret] fail-closed
  (secret + X-Goog headers constant-time), canal lazy sem cron (ensure em
  toda passada, renovação com id novo + stop do antigo)
- migration hand-written (campos de canal/snapshot em googleCalendarSync);
  mutationKind dedicado libera título via Google sem quebrar slug canônico
- UI: seção 'Edições pelo Google' no dialog + autor 'Google Calendar' no feed
- testes: unit (reverse mapping, validação webhook), int (motor bidirecional
  com stub, 10 cenários), e2e (webhook 404 fail-closed)
2026-08-11 22:38:53 -03:00
Francisco Solla
c69990a3f0 fix(C126): isola o escopo do espelho Google nos int specs (fim do flake paralelo) 2026-08-11 21:33:07 -03:00
Francisco Solla
c08be6c46a
Merge pull request #707 from fsolla/C125-c125-pessoas-pos-c117-ux-descoberta-de-ordenacao-no-mob
C125: Pessoas pós-C117 UX — descoberta de ordenação no mobile e facet de ausência completo
2026-08-12 00:04:50 +00:00
Francisco Solla
6d41517a05
Merge pull request #705 from fsolla/C122-c114-follow-up-cobertura-de-testes-dos-estados-do-espel
C122 — cobertura de testes dos estados do espelho Google (componente + e2e + action)
2026-08-11 23:49:39 +00:00
Francisco Solla
e3ffb9d8a7
Merge pull request #706 from fsolla/plans/plan-issue-39
docs(plans): B200 — Municípios mobile: encaixes dos cards (densidade, labels, avatares)
2026-08-11 23:42:01 +00:00
Francisco Solla
d004a2b0eb chore(plan-issue): formata o rascunho UI do B200 (prettier) 2026-08-11 20:39:45 -03:00
Francisco Solla
4ad644d8ca
Merge pull request #702 from fsolla/B199-sollinha-fechar-o-drawer-durante-streaming-pode-reabri-
fix(B199): fechar o drawer mid-stream persiste open:false imediato — reload não ressuscita
2026-08-11 23:37:59 +00:00
Francisco Solla
7fabb72df8 feat(C125): facet de ausência completo (qualquer_ausencia) e descoberta de ordenação no mobile
- PEOPLE_ABSENCES ganha o 4º valor qualquer_ausencia ("Qualquer ausência"),
  a união exata das três ausências em UM chip — o 3º clique dos específicos
  deixa de colapsar o facet (3 de 4 membros) e o parse absorve o guarda-chuva
  sobre os específicos, sem tocar no B18 genérico de capacity/status
- peopleListSortPrimaryOptions: seeds do grupo Ordenação viram as 7 direções
  primárias com emptyQueryVisible, então o mobile descobre as 7 chaves ao
  tocar no bar (e "ordenar" não corta aliada/assessorado/base no cap 8)
- CampaignListOmnibox reabre o popover no mousedown: clicar num input já
  focado (logo após commitar busca com Enter) não disparava focus, deixando
  a descoberta morta no mobile até digitar
- tests: contrato de URL (absorção + não-colapso), predicado + AND, novo spec
  de omnibox, e2e do 3º clique e da descoberta mobile (390×844)
2026-08-11 20:34:51 -03:00
Francisco Solla
980f66983a docs(plans): B200 — Municípios mobile: encaixes dos cards (densidade, labels, avatares) 2026-08-11 20:34:13 -03:00
Francisco Solla
d6dfdf70ed fix(OPS41): resolve marcadores de conflito commitados no AGENTS.md + guardrail anti-reincidência (#689)
O commit OPS33 (f0f5b73f) entrou com o arquivo já conflitado na região do
bullet 'Per-worktree environments' (<<<<<<< HEAD indentado + lado HEAD
pré-OPS33 com artefato '- # ' + fechamento corrompido '> > > > > > >'; o
======= foi removido no próprio commit) e o OPS37 herdou o estado.

Resolução perda zero validada por diff: manter o lado superset (OPS28 +
OPS31 + OPS33 — claim determinístico, --issue N, prompt citado) e
descartar o lado HEAD; -3 linhas no total; scan de todos os trackeados
confirmou AGENTS.md como único arquivo afetado.

Guardrail: describe 'no conflict markers in committed files' em
codebaseConventions.unit.spec.ts — varre git ls-files e falha em
<<<<<<< / >>>>>>> (tolerante a indentação) e na forma corrompida
^\s*(> ){7}; validado negativo contra o estado sujo (AGENTS.md:37, 40).
2026-08-11 20:23:50 -03:00
Francisco Solla
5940c4c61e fix(OPS40): pnpm dev honra o PORT do .env.local — next dev -p via scripts/dev.mjs (Closes #682)
next dev resolve a porta antes de @next/env carregar env-files (commander
.env('PORT') no bin/next), então o PORT=3100+slot do provisionador de
worktree era ignorado e todo dev server subia em 3000. pnpm dev/devsafe
passam por scripts/dev.mjs: preflight do guard-dev-db inline, env com a
mesma precedência (real > .env.local > .env, override:false) e porta como
flag CLI -p (resolveDevPort/nextDevArgs em scripts/lib/cli.mjs,
unit-testados). Sem PORT → nenhum -p → default 3000 + allowRetry intactos.
2026-08-11 20:04:07 -03:00
Francisco Solla
1ed585a084
Merge pull request #700 from fsolla/plans/plan-issue-38
docs(plans): C128–C132 — ajustes de Pessoas (capacidades, legenda, tabela, Salvador, criação rápida)
2026-08-11 22:59:53 +00:00
Francisco Solla
1a71e5d021 docs(plans): C128–C132 — ajustes de Pessoas (capacidades, legenda, tabela, Salvador, criação rápida) 2026-08-11 19:54:13 -03:00
Francisco Solla
c7c9556ff3 test(C122): cobertura dos estados do espelho Google — unit do chrome, e2e dos 4 estados + FAB, int da action de desativar 2026-08-11 19:43:19 -03:00
Francisco Solla
54205fb093 fix(B199): fechar o drawer mid-stream persiste open:false imediato — reload não ressuscita (Closes #672) 2026-08-11 19:41:48 -03:00
Francisco Solla
631635ee89 chore(plan-issue): rascunho UI/UX do gate vira HTML+Tailwind commitado no repo (ad-hoc) 2026-08-11 19:14:21 -03:00
Francisco Solla
b604157fc7
Merge pull request #685 from fsolla/OPS39-prewarm-e2e-dev-adicionar-campanha-home-search-post-e-
OPS39 — Prewarm e2e: home-search POST e mudar-tendencia GET no setup spec
2026-08-11 20:14:51 +00:00
Francisco Solla
4043573152 fix(C118): fecha describe do e2e campaignPeople (merge com C117) e formata changelog 2026-08-11 16:32:49 -03:00
Francisco Solla
c0ffc22026 feat(C118): página de detalhe da pessoa — seções montadas pelas capacidades (Closes #657) 2026-08-11 16:32:21 -03:00
Francisco Solla
94c89a57a1 feat(C124): tarefa de atividade só com texto, responsável e concluída (sem prazo) 2026-08-11 16:05:07 -03:00
Francisco Solla
15461d7abf
Merge pull request #679 from fsolla/B197+-assessores-menu-do-picker-de-colunas-derivado-da-mesma
B197+: picker de colunas de assessores derivado da mesma fonte do AdvisorsTable
2026-08-11 18:53:09 +00:00
Francisco Solla
fdca8ff9c4 format: prettier no impl plan OPS39 2026-08-11 15:47:12 -03:00