Commit graph

113 commits

Author SHA1 Message Date
Francisco Solla
c2ddbf6006 refactor(D6): simplify — find endpoint-only no subscribe, sslmode verify-full, guards no check-push-chain 2026-08-10 00:01:46 -03:00
Francisco Solla
f4873b8b3f fix(D6): push no device ponta a ponta — SW dinâmico, subscribe idempotente, check-push-chain
- /campanha/sw.js force-dynamic: buildId VERCEL_DEPLOYMENT_ID em runtime
  (deploys CLI --prebuilt não têm envs de build; prod servia campanha-dev)
- subscribeCampaignPush find-before-create (endpoint UNIQUE — 2º toque
  estourava com erro falso)
- scripts/check-push-chain.mjs + pnpm db:check:push-chain (read-only,
  veredito por elo: SW/envs/consent/inscrições/eventos)
- VAPID envs adicionadas no Vercel production (ops)
- impl plan + CHANGELOG-AGENTS
2026-08-09 23:41:00 -03:00
Francisco Solla
3838406a30
fix(worktree): define devUrl/testUrl antes do runMigrate em provision (#479)
provision() chamava runMigrate(dir, devUrl, ...) com variáveis nunca
definidas no escopo — 'devUrl is not defined' ao rodar pnpm worktree
next --go. Derivadas dos bancos do env (mesmo formato de
worktreeEnvFileContents).
2026-08-09 11:49:55 +00:00
Francisco Solla
7785c1088c fix(worktree): provisiona PLAYWRIGHT_BASE_URL no .env.test.local — e2e usa porta do slot (OPS20)
O .env.test.local (que o playwright.config.ts lê) passa a carregar
PLAYWRIGHT_BASE_URL na porta do slot (3100+slot); antes só o .env.local
(que o config não lê) o tinha, então dois test:e2e em worktrees paralelos
subiam dev servers na porta 3000. Causa-raiz tratada: os dois blocos env
inline do provision viraram um builder puro único (worktreeEnvFileContents
em scripts/lib/worktree-env.mjs) que deriva NEXT_PUBLIC_SITE_URL +
PLAYWRIGHT_BASE_URL do mesmo devPort para ambos os arquivos — paridade
estrutural, drift impossível + unit tests de paridade. playwright.config.ts
intocado (a variável certa já existia).
2026-08-09 02:19:26 -03:00
Francisco Solla
6c8c466b40 fix(worktree): plan cria um worktree diferente por invocação (paralelismo /plan-issue)
Cada 'pnpm worktree plan' agora deriva um branch próprio: plans/plan-issue-<bag>
quando um bag é passado (sufixo -2/-3 em colisão) ou o próximo sequencial
plans/plan-issue-<n> quando não. O prefixo minúsculo plans/… nunca colide com o
branch <Code>-<slug> de 'next'. planBranchName (scripts/lib/worktree.mjs)
unit-testado; docs e shell/command atualizados.
2026-08-08 16:40:05 -03:00
Francisco Solla
c399b918c3 feat(worktree): comando plan — worktree dedicado ao /plan-issue
Novo subcomando `pnpm worktree plan [--go] [--no-migrate]` cria/reutiliza o
worktree de planejamento no branch fixo `plans/plan-issue`
(`PLAN_WORKTREE_BRANCH`), sem vínculo com a fila de claim: um `next` posterior
da próxima Issue nunca colide em branch nem em slot (slot derivado por hash do
branch, bumpado entre worktrees vivos). Mesmo provisionamento isolado do
`next` — porta 3100+slot, bancos teqo_wt<slot>/teqo_wt<slot>_test, migrations.

- scripts/worktree.mjs: cmdPlan + provision() com purpose/issue opcionais
- scripts/lib/worktree.mjs: constante PLAN_WORKTREE_BRANCH
- tests/unit/worktree.unit.spec.ts: derivação de slot do plano
- docs: .opencode/commands/worktree.md, shell, skills, AGENTS.md, changelog
2026-08-08 16:00:27 -03:00
Francisco Solla
bd06018bde B164: barra de navegação inferior no mobile para staff
Mobile bottom nav (staff only): 5 items (Início, Municípios, Atualizações,
Agenda, Mais) with Drawer overflow for secondary destinations. Leader and
desktop remain sidebar-only. FAB + scroll padding adjusted for safe-area.

Resolves #400
2026-08-08 12:57:05 -03:00
Francisco Solla
8125334401 feat(worktree): ambientes isolados por worktree — porta própria, bancos próprios, migrations no provision
pnpm worktree next [--go] [--no-migrate] agora provisiona um ambiente
determinístico por worktree: slot = parte numérica do código da Issue
(C15→15; hash sem dígitos; bump em colisão entre worktrees vivos), dev
server em 3100+slot, bancos teqo_wt<slot> / teqo_wt<slot>_test no
container compartilhado (-p teqo) com a cadeia de migrations aplicada;
escreve .env.local + .env.test.local (gitignored, marcador gerado; envs
manuais nunca sobrescritos) e copia PAYLOAD_SECRET/Blob/VAPID do main.
kill remove o worktree e dropa os bancos gerados (WITH FORCE, best-effort).

Suites leem .env.test.local depois de .env.test (vitest.setup /
playwright / db-doctor / gate-ci espelham o layering) e
assertTestDatabase aceita teqo_test ou teqo_<worktree>_test em localhost
só (fail-closed preservado). db:start/db:stop fixam -p teqo (um
container de qualquer diretório); max_connections 200→400. Sem Docker
(Cursor Cloud): degrada ao compartilhado com aviso.

Derivação pura em scripts/lib/worktree-env.mjs (unit-tested); fluxo
validado end-to-end: provision → migrate → 598/598 int no banco do
worktree → kill sem resíduo.
2026-08-08 11:33:07 -03:00
Francisco Solla
55178247c8
Merge pull request #409 from fsolla/C15-fullcalendar-em-campanha-agenda
feat(campanha): C15 — FullCalendar em /campanha/agenda
2026-08-07 04:56:52 -03:00
Francisco Solla
59983b33f7 feat(campanha): C15 — FullCalendar em /campanha/agenda
Issue #390 — entrada operacional staff com FullCalendar v7 route-local
(semana/mês/lista), filtros compartilháveis por município/deputado/tag,
criação pelo slot, detalhe por URL e remarcação drag/resize sob RBAC,
transação e lock por atividade.

- /campanha/atividades e giros permanecem como lista/fluxos legados
- Sem migration/collection nova; reutiliza activity de C14
- Fuso Bahia, range exclusivo, erro/revert, loading/empty testados
- Leader negado, advisor limitado pelo access atual
- E2E cobre filtros, drag, mobile 390x844 e slot prefill
- Int specs cobrem RBAC, concorrência e defense-in-depth

Impl: docs/plans/fullcalendar-agenda-campanha-impl.md
2026-08-07 04:37:36 -03:00
Francisco Solla
af6ae72034 feat(scripts): worktree() shell function applies the --go cd 2026-08-07 01:37:02 -03:00
Francisco Solla
1c0648d59a feat(scripts): deterministic worktree + issue CLI (next --go, kill, all) 2026-08-07 01:27:22 -03:00
Francisco Ignácio Fontoura Solla
48623b0d06 fix(campanha): preserve StateDeputy migration identity 2026-08-06 18:38:47 -03:00
Francisco Ignácio Fontoura Solla
033c270a89 feat(campanha): B163 — editar contatos das dobradinhas 2026-08-06 16:52:55 -03:00
Francisco Solla
7700bff39d chore: update references to .cursor bootstrap paths
Point environment.json, hooks, skills, and docs at the relocated .cursor/ files.
2026-08-05 01:39:42 -03:00
Francisco Ignácio Fontoura Solla
896d957497 chore: migrate .cursor/ references to .agents/ folder
Replace all project-local .cursor/ path references with .agents/ across
rules, skills, environment config, hooks, and ignore files. Keep Cursor
editor paths (~/.cursor/, window.cursor, CURSOR_API_KEY) and vendored
Impeccable editor-hook paths unchanged.
2026-08-05 00:09:09 -03:00
Cursor Agent
30a5a8a5e3
B151 — FAB secundário no detalhe município v2 (#334)
- Catálogo v2 de ações rápidas: dossiê, eleições, nova liderança, giro
- Integra no chassis B126 via registry + context sync na rota v2
- Omitido registrar sinal (já na faixa de status B147)

Co-authored-by: Francisco Solla <fsolla@users.noreply.github.com>
2026-08-03 01:03:10 +00:00
Cursor Agent
07c884ee2e
style: prettier AGENT-OPS and promote-related script 2026-08-03 00:23:26 +00:00
Cursor Agent
7665b1062c
fix(ops): OPS18 simplify — Related regex, already-ready, job gate
Aperta parseRelatedIssueNumbers (anti hyphen), canPromotePlanIssue
already-ready, workflow só com Related # no body + PR_BODY, soft-fail
por Issue no Action script.

Co-authored-by: Francisco Solla <fsolla@users.noreply.github.com>
2026-08-03 00:22:55 +00:00
Cursor Agent
b7f4e16c0f
feat(ops): OPS18 — Action promote Related #N no merge
Safety net dual com agent:ready: no merge em main, workflow lê Related #N
e promove Issues ainda aguardando plano (canPromotePlanIssue), soft-skip
idempotente. Helper parseRelatedIssueNumbers + pins unitários.

Co-authored-by: Francisco Solla <fsolla@users.noreply.github.com>
2026-08-03 00:20:48 +00:00
Cursor Agent
6773bbb526
docs(ops): alinhar contrato agent:ready ao canPromotePlanIssue 2026-08-03 00:06:14 +00:00
Cursor Agent
9d6f80b464
style: format agent-plan-lifecycle with Prettier 2026-08-03 00:06:14 +00:00
Cursor Agent
d2cc1d2693
feat(ops): OPS17 — plan-issue blocked até plano em main
Register com --plan nasce blocked (não claimável); pnpm agent:ready
promove após o plano em main. Gate da skill plan-issue endurecido.

Co-authored-by: Francisco Solla <fsolla@users.noreply.github.com>
2026-08-03 00:06:14 +00:00
Cursor Agent
6b8aa8b6cf
fix(campanha): B147 simplify — sinal empty body + cold select
Allow empty motivo on sinal through collection beforeValidate; distinguish
warm-typeless vs cold in the v2 signal select; reuse list signal form action.

Co-authored-by: Francisco Solla <fsolla@users.noreply.github.com>
2026-08-02 23:33:46 +00:00
Cursor Agent
c66ffd598c
fix(campanha): map municipio v2 route in e2e affected manifest
Co-authored-by: Francisco Solla <fsolla@users.noreply.github.com>
2026-08-02 23:30:51 +00:00
Francisco Solla
1771c5c2c4
Merge pull request #282 from fsolla/cursor/pool-i265-cbfa8dec-92a1
B128 — Adotar barra omnibox nas demais listas /campanha
2026-08-02 18:12:49 -03:00
Cursor Agent
f59d4a6736
chore: format + e2e manifest mappings for B128 omnibox modules 2026-08-02 20:56:12 +00:00
Francisco Ignácio Fontoura Solla
0baeda22a0 Fix e2e failures from FAB chrome waits and B27 advisor strict-mode.
B126 mobile specs looked for a page heading that shell chrome replaced;
wait on campaignPageChrome with exact title text, and wrap the desktop
title so subtitle no longer collides. Pin B27 to the município-specific
assessores trigger and map home-search libs to campaignMunicipalities.
2026-08-02 17:49:08 -03:00
Cursor Agent
076c047c02
chore: map B127 omnibox paths in e2e affected manifest 2026-08-02 20:30:55 +00:00
Francisco Solla
7839a88a5a
Merge pull request #270 from fsolla/cursor/pool-i250-d89b6314-599f
B123 — Campanha — orientação na shell + aba (sem títulos grandes de seção)
2026-08-02 16:16:58 -03:00
Cursor Agent
b6e1f4b5ce
ci: invoke knip via pnpm script (fixes spawnSync exit 13 flake) 2026-08-02 19:01:57 +00:00
Francisco Solla
62fb4c66e8
Merge pull request #263 from fsolla/cursor/pool-i259-b024c8a7-cbc1
OPS16 — CI: cooldown de deploy de produção 30 → 15 min
2026-08-02 15:46:51 -03:00
Cursor Agent
cad3556bce
OPS16: reduce production deploy cooldown from 30 to 15 minutes
Change DEPLOY_COOLDOWN_MS constant, update ci.yml deferral log, and
adjust unit test pins. Closes #259.

Co-authored-by: Francisco Solla <fsolla@users.noreply.github.com>
2026-08-02 18:38:36 +00:00
Cursor Agent
7e6bc9d984
B125 — nearest município first in search suggest + wizard
- Restore B117 home search: scopeMunicipalities, merge prefix, session prompt
- Shared useNearestMunicipalitySlug (B14 key) for busca geral + wizard
- Wizard merge uses geoSlug only — no Perto de você / km copy on rows
- Impl plan: docs/plans/municipio-geo-topo-sugestoes-busca-impl.md

Co-authored-by: Francisco Solla <fsolla@users.noreply.github.com>
2026-08-02 18:21:52 +00:00
Francisco Ignácio Fontoura Solla
8bca9d8e82 Separate intention plans from engineering execution in agent skills.
plan-issue now shapes product intent only; agent-work-issue (pool) and
work-issue (human gate) deliberate the implementation plan before coding.
2026-08-02 14:02:18 -03:00
Francisco Ignácio Fontoura Solla
186950168b Raise agent pool hard max slots from 8 to 12.
Default remains 5; parsePoolConfig now clamps POOL_MAX_SLOTS up to 12.
2026-08-02 13:30:36 -03:00
Cursor Agent
fded303fe6
fix(ci): stop trusting GET /v13 alias for production domain ownership
CI short-circuited "already aliased" when v13 listed pt.jorgesolla.com.br
on a fresh --prod deploy while the domain still pointed at an older
Current. Verify only via GET /v2/.../aliases and /v4/aliases?domain=.
Also drop invalid --yes on vercel alias set (CLI 55).
2026-08-01 16:12:30 +00:00
Cursor Agent
fdd318692c
fix(ci): clear domain gitBranch so CLI prod deploys can alias
Git-branch-bound domains only move via Git Integration. With Git
auto-deploy OFF, clear the binding, then promote + alias + verify.
2026-08-01 15:59:41 +00:00
Cursor Agent
bcca5da92c
fix(ci): verify domain alias via aliases API + vercel alias set
Promote + POST aliases still left pt.jorgesolla.com.br off the staged
deployment's GET /v13 alias list. Verify with GET /v2/.../aliases and
GET /v4/aliases?domain=, log steps live, and also run `vercel alias set`
(recommended when Git Integration is off).
2026-08-01 15:48:59 +00:00
Cursor Agent
c59b3fe31d
fix(ci): explicitly alias pt.jorgesolla.com.br after Vercel promote
Promote alone left the staged deployment on *.vercel.app only. Assign the
custom hostname via POST /v2/deployments/{id}/aliases after verifying it is
attached to the project domains list.
2026-08-01 15:37:16 +00:00
Cursor Agent
baa8f14f82
fix(ci): promote Vercel deploy to pt.jorgesolla.com.br
Disabling Git auto-deploy is correct for Actions-gated production. The
separate project toggle "Auto-assign Custom Production Domains" must stay
ON — when OFF, `vercel deploy --prod` only aliases *.vercel.app and leaves
the custom domain on an older Current (exactly what we saw after #122).

After each deploy, ensure-production-alias re-enables auto-assign if needed,
promotes the deployment, and verifies pt.jorgesolla.com.br is attached.
Also adds workflow_dispatch "Vercel promote production" for promote-without-rebuild.
2026-08-01 15:26:31 +00:00
Cursor Agent
dcce160a4d
fix(ci): lazy-load dotenv in cli.mjs for deploy cooldown
vercel-deploy-cooldown.mjs only needs dieWithLabel from cli.mjs, but the
module eagerly imported dotenv. The deploy job runs the cooldown check
before pnpm install, so Node failed with ERR_MODULE_NOT_FOUND.

Require dotenv inside loadCliEnv() so lightweight CI steps can import
dieWithLabel without node_modules.
2026-08-01 14:13:10 +00:00
Francisco Solla
a7394d3b9e
Merge pull request #119 from fsolla/cursor/pool-i114-36b6c1a5-2d0b
B100 — Bottom drawer mobile — dock visível + recolhe no scroll
2026-08-01 08:49:14 -03:00
Cursor Agent
1ad8863994
OPS12 — CI bloqueia Closes/Fixes em PR só docs/plans
- Lógica pura em plansOnlyClosesGuard.mjs + CLI check-plans-only-pr-closes
- Job plans-only-closes em ci-pr.yml (rollup checks)
- Unit tests com fixture do incidente #115
- plan-issue, agent-pr-workflow, PR template e GUARDRAILS atualizados

Closes #116

Co-authored-by: Francisco Solla <fsolla@users.noreply.github.com>
2026-08-01 11:26:19 +00:00
Cursor Agent
0e510e2658
Map Drawer.tsx to campaignMunicipalities e2e in affected manifest 2026-08-01 11:20:14 +00:00
Cursor Agent
f7d6a6d77d
style: format vercel-deploy-cooldown.mjs 2026-08-01 10:55:36 +00:00
Cursor Agent
cbddd8c796
OPS11 — cooldown de 30 min entre deploys de produção (Vercel)
- Script vercel-deploy-cooldown consulta último deploy READY via API Vercel
- Job deploy em ci.yml adia upload quando idade < 30 min (sucesso, não falha)
- Job requeue espera o residual e re-dispara ci.yml
- vercel deploy passa --archive=tgz para reduzir pressão de upload
- Testes unitários para computeCooldownWait e fetch da API

Co-authored-by: Francisco Solla <fsolla@users.noreply.github.com>
2026-08-01 10:54:55 +00:00
Cursor Agent
8f52e17396
chore: map B94 paths in e2e affected manifest 2026-08-01 07:44:00 +00:00
Cursor Agent
feb44cd3db
fix(agent-pool): stop exporting unused POOL_DEFAULT_MODEL_SLUG
Knip treats unused exports as errors; the slug stays a module-local const.
2026-08-01 06:58:33 +00:00
Cursor Agent
196e15b827
fix(agent-pool): pin fast=false on Cloud Agent spawns
Cursor's Create-Agent API defaults omitted `fast` to true, so pool
workers requesting composer-2.5 were billed as composer-2.5-fast.

Co-authored-by: Francisco Solla <fsolla@users.noreply.github.com>
2026-08-01 06:56:57 +00:00