mirror of
https://github.com/fsolla/teqo.git
synced 2026-11-14 17:43:04 +00:00
Align project docs with the shipped nuclei MVP.
Update AGENTS, README, roadmap, and the Núcleos notebook so status, territory scope, tests, and the LGPD production blocker match main.
This commit is contained in:
parent
bcac665cb5
commit
a5903d52ad
4 changed files with 42 additions and 37 deletions
|
|
@ -7,16 +7,9 @@ alwaysApply: false
|
|||
|
||||
## Status
|
||||
|
||||
- Onda 1 (auth/RBAC e fundação visual): concluída e aprovada em 2026-07-16.
|
||||
- Onda 2 (domínio Núcleo): implementada em 2026-07-16; aguardando integração/revisão.
|
||||
- Onda 3B (domínio Liderança): implementada em 2026-07-16; migration aplicada nos bancos locais de desenvolvimento e teste.
|
||||
- Onda 3A (UI Núcleo): concluída e aprovada em 2026-07-16.
|
||||
- Onda 4A (UI Lideranças): implementada em 2026-07-16 com lista responsiva, filtros, ficha/formulário, contato principal e serialização específica por papel.
|
||||
- Onda 4B (Inteligência do Núcleo): implementada em 2026-07-17 com fluxo seguro de sugerir/confirmar estimativas, edição de forças/riscos/perfis/dobrada/contato principal e DTOs mínimos por papel.
|
||||
- Onda 6B (domínio de convites): implementada em 2026-07-17 com Consent por chave estável, convites WhatsApp com hash/expiração/revogação, consumo transacional de uso único, autopreenchimento restrito e criação/recuperação de acesso.
|
||||
- Onda 6A (dashboard e atualizações): implementada e revisada em 2026-07-17 com agregados só de núcleos ativos, semana exata `America/Bahia`, feed paginado por URL e contato contextual da coordenação.
|
||||
- Onda 7 (UI de convites): implementada em 2026-07-17 com ação WhatsApp por liderança, bloqueio por Consent/status e rota pública dinâmica de autopreenchimento/acesso/recuperação.
|
||||
- Onda 8 (hardening): implementada em 2026-07-17 com E2E por papel, negativa de escopo, convite público/WhatsApp sem navegação real, verificação responsiva 360/390/768/1440, correção de alvos de toque no login, documentação e checklist de deploy.
|
||||
- **MVP Ciclo 1 entregue e enviado em `main` (2026-07-18):** ondas 1–8 (auth/RBAC, domínio+UI de Núcleo/Liderança/Inteligência/Atualizações/Convites, dashboard, hardening) + refactors de composição Next.js, primitivos compartilhados, locks PostgreSQL, fixtures E2E e migration consolidada `20260718_010733_consolidate_campaign_schema`.
|
||||
- Fluxos operacionais cobertos: login isolado, CRUD/arquivo de núcleos por slug, designação de coordenador (`geral`), CRM de lideranças, estimativas sugerir/confirmar com versão UUID, feed de atualizações, convites WhatsApp (`wa.me` + hash de uso único), dashboard com agregados só de núcleos ativos.
|
||||
- Pendência operacional (não de código): Consent `lideranca-autopreenchimento` + lote jurídico LGPD antes de dados reais; smoke pós-deploy Vercel. Ver Onda 0 em [`docs/roadmap.md`](../../../docs/roadmap.md).
|
||||
- Em 2026-07-17, a listagem de Núcleos passou a aplicar filtros automaticamente pelo estado da URL, sem botão de confirmação, com comboboxes territoriais estritos compartilhados com o formulário.
|
||||
- Em 2026-07-17, o contato principal passou a usar busca remota limitada e escopada no detalhe do núcleo, sem serializar a lista completa de lideranças.
|
||||
- Em 2026-07-17, o feed paginado de atualizações e a prévia das três mais recentes passaram a usar loaders separados por aba, sem consulta de prévia fora da visão geral.
|
||||
|
|
@ -32,15 +25,15 @@ alwaysApply: false
|
|||
- Em 2026-07-17, a Refactor Phase 2D reduziu `actions/invite.ts` a uma orquestração de 44 linhas e separou repositório SQL, criação e resgate em módulos `server-only`, preservando 488 testes de integração.
|
||||
- Em 2026-07-17, a Refactor Phase 4A consolidou as dez migrations locais não publicadas de `20260717_*` em `20260718_010733_consolidate_campaign_schema`, mantendo intacta a história rastreada até `20260716_010420_add_campaign_user`; os bancos locais foram reconciliados sem alterar dados de aplicação.
|
||||
- Em 2026-07-18, o follow-up Phase 4C fixou o Playwright em dois workers por padrão, adicionou guardas automáticos de erros do navegador/console/5xx, fortaleceu privacidade HTML+Flight por papel e tornou o login por teclado uma interação real com Enter e cookie verificado.
|
||||
- Em 2026-07-18, a exceção concorrente de `SupportStatusBadge` foi rastreada a projeções em voo nas quais o acesso de campo podia omitir `supportStatus`; o agregado do dashboard agora valida o enum e omite registros incompletos sem inventar um status padrão.
|
||||
- Em 2026-07-18, a projeção do dashboard omite `supportStatus` ausente por redação de acesso e lança invariante genérico se um valor não-vazio inválido chegar à fronteira; agregação e badge são exaustivos no enum.
|
||||
|
||||
## Decisões
|
||||
|
||||
- Núcleo Eleitoral é a unidade operacional; Zona TSE é uma referência oficial adicional.
|
||||
- Todo núcleo exige geografia; natureza organizativa e setor são dimensões complementares.
|
||||
- Exclusão no app é substituída por arquivamento.
|
||||
- `lastUpdateAt` existe como placeholder até o domínio de atualizações.
|
||||
- `Contact` tem e-mail opcional no banco, telefone normalizado/indexado e acesso por escopo; os schemas públicos continuam exigindo e-mail.
|
||||
- `lastUpdateAt` é mantido pelo domínio de atualizações (`nucleusUpdate`) sob advisory lock; não é mais placeholder.
|
||||
- `Contact` tem e-mail e cidade opcionais no banco, telefone normalizado/indexado e acesso por escopo; os schemas públicos continuam exigindo e-mail (e cidade onde aplicável).
|
||||
- `Leadership` é a junção única contato↔núcleo; acesso de liderança e contato exige vínculo `engajado`, e avaliação interna não é serializada para a titular.
|
||||
- A UI de liderança usa view models separados: coordenação recebe avaliação interna; papel `lideranca` recebe somente a própria ficha sem `supportStatus`, `notes` ou `consentNote`.
|
||||
- A deduplicação de `Contact` por telefone usa `pg_advisory_xact_lock(hashtextextended(phone, 0))` na própria sessão Drizzle da transação Payload, evitando duplicatas entre instâncias concorrentes.
|
||||
|
|
|
|||
28
AGENTS.md
28
AGENTS.md
|
|
@ -4,7 +4,7 @@ You are an expert Payload CMS developer. When working with Payload projects, fol
|
|||
|
||||
## Teqo Project Context (read this first)
|
||||
|
||||
Teqo is the digital platform for deputado federal Jorge Solla (PT-BA): public site + editorial CMS + (soon) an internal `/campanha` campaign-management area, all in this one Next.js + Payload app. Full architecture/decision doc lives outside this repo at `plano-arquitetura-campanha-2026.md` (Cowork workspace) — check it for the "why" behind decisions below.
|
||||
Teqo is the digital platform for deputado federal Jorge Solla (PT-BA): public site + editorial CMS + an internal `/campanha` campaign-management area, all in this one Next.js + Payload app. Full architecture/decision doc lives outside this repo at `plano-arquitetura-campanha-2026.md` (Cowork workspace) — check it for the "why" behind decisions below.
|
||||
|
||||
**Locked decisions — do not relitigate without a new concrete reason:**
|
||||
|
||||
|
|
@ -16,7 +16,7 @@ Teqo is the digital platform for deputado federal Jorge Solla (PT-BA): public si
|
|||
|
||||
- `Contact` is the normalized "person" record (name, email, phone, state/city via `src/lib/cities.ts`, CEP). Don't create a parallel "person" collection for new features (e.g. líderanças/apoiadores) — add a join collection that relates to `Contact`, the same way `Signature` and `Subscription` do.
|
||||
- Every action that writes to more than one collection (see `src/app/(frontend)/actions/*.ts`) wraps the writes in a Payload transaction (`payload.db.beginTransaction/commitTransaction/rollbackTransaction`) and passes `req: { transactionID }` to every `payload.create`/`payload.update` call. Follow this pattern for any new multi-collection write.
|
||||
- LGPD consent is tracked via a `Consent` collection (richText, versioned) referenced by relationship from `Signature`/`Subscription`. Any new form/opt-in flow should link to a `Consent` document the same way — don't invent a new consent mechanism.
|
||||
- LGPD consent is tracked via a `Consent` collection (richText, versioned, optional stable `key`) referenced by relationship from `Signature`/`Subscription`/campaign `leadership`. New campaign opt-in flows resolve Consent by stable `key` (e.g. `lideranca-autopreenchimento`) and fail closed when missing — don't invent a parallel consent mechanism or hardcode document IDs for new work.
|
||||
- Cache invalidation: collections/globals call `revalidateDocumentById` (`src/utilities/documents.ts`) / `revalidateGlobal` (`src/utilities/globals.ts`) in an `afterChange` hook. Add the same hook to any new collection/global that backs a public page. Collections whose listing is cached under a shared tag also call the listing helper (`revalidateCollectionListing`, e.g. `revalidatePostsListing()` → `revalidateTag('posts')`) — see "Posts & Tags" below.
|
||||
- Admin UI is organized via `admin.group` (e.g. `'Abaixo-assinados'`, `'Contatos'`, `'Configurações'`, `'Paginas'`) — group new collections consistently instead of leaving them ungrouped.
|
||||
- i18n: Payload admin defaults to `pt` (not `pt-BR` — see `payload.config.ts`, `payload/i18n/pt`).
|
||||
|
|
@ -30,15 +30,16 @@ Teqo is the digital platform for deputado federal Jorge Solla (PT-BA): public si
|
|||
- To copy production content locally, use `pnpm db:pull` (`scripts/db-pull.mjs`): it only reads prod, only writes local, and excludes supporter PII (`contact`/`signature`/`subscription` row data).
|
||||
- To (re)populate news content, `pnpm db:seed:posts` fetches articles live from jorgesolla.com.br into the LOCAL db (same non-local `DATABASE_URL` guard as `pnpm dev`). It writes from a CLI process outside the deployed runtime, so after seeding — or after ANY direct-DB change — you must bust the production `posts` cache via `POST /api/revalidate`. See "Posts & Tags" below.
|
||||
|
||||
## Known Gaps (as of 2026-07-15 — resolve before relying on this file for onboarding new devs)
|
||||
## Known Gaps (as of 2026-07-18 — resolve before relying on this file for onboarding new devs)
|
||||
|
||||
Backlog consolidado (bloqueadores, site, campanha, white-label): [`docs/roadmap.md`](docs/roadmap.md).
|
||||
|
||||
1. **Payload admin RBAC is still absent.** The campaign auth collection now has `role`, but the `users` admin collection still has no roles; every admin user has full Payload admin access. Add admin roles before opening `/admin` to a broader team.
|
||||
2. **Legacy public consent flows still hardcode document IDs** (e.g. `consent: 2` in `submitWhatsapp.ts`). The campaign leadership flow does not: it requires `Consent.key = 'lideranca-autopreenchimento'` and fails closed when missing. Migrating the older public flows remains separate work.
|
||||
3. **`Post`/`Tag` ship the news system, but there is still no `Pages` collection for institutional content.** Partly resolved: the `post`/`tag` collections back the news/publications system, and the home "Últimas notícias" list plus the `/[type]`, `/[type]/[category]`, and article routes are live (see "Posts & Tags" below). Still hardcoded/pending: the home hero heading + subtitle copy (`HomePage` global still exposes only a single `image` field — the text lives in `src/app/(frontend)/(home)/page.tsx`), and there is no `Pages` collection yet for institutional content such as the bio and propostas.
|
||||
4. **Campaign LGPD consent text is not yet configured in production.** Invites and self-service leadership flows fail closed until an admin creates `Consent.key = 'lideranca-autopreenchimento'` with counsel-approved copy (see deploy checklist).
|
||||
|
||||
**Recently resolved (2026-07-15):** local Postgres now runs via `docker-compose.yml` (Postgres 17, matching prod, auto-creating `teqo_test`); Payload migrations are set up with prod baselined; dev/test database guards prevent accidental production access (see the two database skills). The `post`/`tag` collections and the public news/article/listing routes shipped and are deployed (see "Posts & Tags" below).
|
||||
**Recently resolved (2026-07-18):** the `/campanha` nuclei MVP shipped (auth/RBAC, nuclei, leaderships, vote estimates, updates, WhatsApp invites, dashboard) with consolidated migration `20260718_010733_consolidate_campaign_schema`. Earlier (2026-07-15): local Postgres via `docker-compose.yml` (Postgres 17, `teqo_test`); Payload migrations baselined; dev/test database guards; `post`/`tag` news routes deployed (see "Posts & Tags" below).
|
||||
|
||||
## Posts & Tags (news / publications)
|
||||
|
||||
|
|
@ -92,17 +93,18 @@ The first `/campanha` operational cycle is centered on `electoralNucleus`; a Nú
|
|||
|
||||
- **Collections:** `electoralNucleus` (territory, coordinators, TSE zone references, intelligence and vote estimates), `leadership` (unique `Contact`↔nucleus join with support status), `nucleusUpdate` (immutable field reports), and `campaignInvite` (single-use WhatsApp invite hashes). All are in admin group `Campanha`.
|
||||
- **Canonical nucleus URLs:** nuclei use a unique canonical `slug` generated from `name` and route through `/campanha/nucleos/[slug]`. IDs stay internal. Names are immutable after creation so existing shared links remain durable without an alias table.
|
||||
- **Role scope:** `geral` sees/manages all nuclei and confirms estimates; `coordenador` sees assigned nuclei and manages their leaderships, updates, invites, and estimates; `lideranca` sees only nuclei linked through an engaged leadership record, creates own updates, and suggests estimates.
|
||||
- **Sensitive fields:** `leadership.supportStatus`, internal notes, consent notes, and strategic nucleus intelligence are staff-only and are excluded from leadership view models. Revoking `engajado` revokes nucleus access immediately.
|
||||
- **Territory (current cycle):** Bahia is implicit. Nuclei use single `region` / `city` / `neighborhood` / `locality` / `territoryNotes` validated against official Bahia identity territories (`src/lib/bahiaTerritories.ts`). Multi-município/bairro arrays remain a planned follow-up (`docs/plans/territorio-multi-municipio-bairro.md`).
|
||||
- **Role scope:** `geral` sees/manages all nuclei, assigns coordinators, and confirms estimates; `coordenador` sees assigned nuclei and manages their leaderships, updates, invites, and estimates; `lideranca` sees only nuclei linked through an engaged leadership record, creates own updates, and suggests estimates.
|
||||
- **Sensitive fields:** `leadership.supportStatus`, internal notes, consent notes, and strategic nucleus intelligence are staff-only and are excluded from leadership view models. Revoking `engajado` revokes nucleus access immediately. Dashboard aggregates omit Payload-redacted missing statuses and fail closed on invalid enum values.
|
||||
- **People and consent:** leaderships always reuse `Contact`; multi-collection writes are transactional. Self-service updates accept a strict whitelist derived from the invite token. Campaign consent is looked up only by the stable key `lideranca-autopreenchimento`.
|
||||
- **Invites:** only SHA-256 token hashes are persisted. Public invite pages are dynamic, `no-store`, `noindex,nofollow`, `no-referrer`, and have no third-party application scripts. Login invites are allowed only for engaged leaderships.
|
||||
- **Vote estimates:** proposals never overwrite the confirmed value; only a coordinator assigned to the nucleus or `geral` may confirm.
|
||||
- **Invites:** only SHA-256 token hashes are persisted. Absolute invite URLs require a valid `NEXT_PUBLIC_SITE_URL` (exact HTTPS DNS origin in production). Public invite pages are dynamic, `no-store`, `noindex,nofollow`, `no-referrer`, and have no third-party application scripts. Login invites are allowed only for engaged leaderships.
|
||||
- **Vote estimates:** proposals never overwrite the confirmed value; each proposal carries a server-generated UUID version compared under advisory lock on confirm. Only a coordinator assigned to the nucleus or `geral` may confirm.
|
||||
|
||||
### Local verification and deploy checklist
|
||||
|
||||
1. Confirm `DATABASE_URL` is `postgresql://teqo:teqo@localhost:5432/teqo` and `.env.test` points to `teqo_test`; never use Neon for development, tests, E2E, or local builds.
|
||||
2. Run `pnpm db:start`, `pnpm migrate:status`, and `DATABASE_URL=postgresql://teqo:teqo@localhost:5432/teqo_test pnpm migrate:status`; every migration must show `Ran: Yes`.
|
||||
3. Run `pnpm generate:types`, `pnpm generate:importmap` when components changed, `pnpm exec tsc --noEmit`, `pnpm lint`, `pnpm test:int`, `pnpm test:e2e`, and `pnpm build` against the local database.
|
||||
3. Run `pnpm generate:types`, `pnpm generate:importmap` when components changed, `pnpm exec tsc --noEmit`, `pnpm lint`, `pnpm test` (unit + int), `pnpm test:e2e` (or `pnpm test:all`), and `pnpm build` against the local database. Payload CLI scripts (`migrate`, `generate:*`, `payload`) and the build migrate step use `--conditions=react-server` so `server-only` modules load correctly outside Next.js.
|
||||
4. Scan every edited runtime source file with Aikido and resolve new findings before handoff. Do not expand hardening work into unrelated pre-existing findings without an explicit scope change.
|
||||
5. Review Vercel environment variables and migration SQL before deploy; `pnpm build` applies pending migrations to production automatically.
|
||||
6. **Mandatory production blocker:** do not insert real leadership/support data or enable invites until electoral counsel documents the LGPD art. 11 basis, approves the specific versioned consent text, and an admin creates it with exactly `Consent.key = 'lideranca-autopreenchimento'`. The app intentionally fails closed when this key is absent.
|
||||
|
|
@ -132,11 +134,11 @@ src/
|
|||
│ ├── (frontend)/ # Frontend routes + server actions (src/app/(frontend)/actions/*.ts)
|
||||
│ ├── (payload)/ # Payload admin routes
|
||||
│ └── (campaign)/ # Internal campaign-management area (auth barrier, see "Campaign auth")
|
||||
├── collections/ # Collection configs (Users, CampaignUser, Media, Petition, Signature, Consent, Contact, Subscription, Post, Tag)
|
||||
├── collections/ # Users, CampaignUser, CampaignInvite, ElectoralNucleus, Leadership, NucleusUpdate, Media, Petition, Signature, Consent, Contact, Subscription, Post, Tag
|
||||
├── globals/ # Global configs (SiteSettings, HomePage, Metadata)
|
||||
├── components/ # Custom React components (incl. components/ui from shadcn)
|
||||
├── lib/ # cities.ts, zod schemas (lib/schemas/*)
|
||||
├── utilities/ # documents.ts / globals.ts / posts.ts (revalidation + posts helpers)
|
||||
├── components/ # Custom React components (campaign/*, ui from shadcn)
|
||||
├── lib/ # cities.ts, bahiaTerritories.ts, formData.ts, zod schemas (lib/schemas/*)
|
||||
├── utilities/ # campaign*, nucleus*, posts, documents, globals, locks, etc.
|
||||
└── payload.config.ts # Main config
|
||||
```
|
||||
|
||||
|
|
|
|||
20
README.md
20
README.md
|
|
@ -14,11 +14,11 @@ The goal is to help political teams build direct, durable relationships with the
|
|||
|
||||
### Phase 1: Jorge Solla Website
|
||||
|
||||
Initial delivery focuses on Jorge Solla's public website and communication workflows:
|
||||
Initial delivery focuses on Jorge Solla's public website, editorial CMS, and the internal `/campanha` tool:
|
||||
|
||||
- Public-facing content and updates
|
||||
- Institutional pages and biography
|
||||
- Media and campaign communication assets
|
||||
- Public-facing content and updates (news/`post` + `tag` live)
|
||||
- Institutional pages and biography (still pending a `Pages` collection)
|
||||
- Internal campaign operations: electoral nuclei, leaderships, estimates, updates, WhatsApp invites
|
||||
- Editorial operations through Payload CMS
|
||||
|
||||
### Phase 2: White-Label Platform
|
||||
|
|
@ -84,7 +84,11 @@ Tests use the isolated `teqo_test` database (config in `.env.test`). Prepare its
|
|||
DATABASE_URL=postgresql://teqo:teqo@localhost:5432/teqo_test pnpm migrate
|
||||
```
|
||||
|
||||
Then run `pnpm test` (or `pnpm test:int` / `pnpm test:e2e`).
|
||||
Then run:
|
||||
|
||||
- `pnpm test` — unit + integration
|
||||
- `pnpm test:e2e` — Playwright (requires the test DB schema and a free port)
|
||||
- `pnpm test:all` — unit + integration + E2E
|
||||
|
||||
## Tech Stack
|
||||
|
||||
|
|
@ -93,6 +97,12 @@ Then run `pnpm test` (or `pnpm test:int` / `pnpm test:e2e`).
|
|||
- PostgreSQL (via `@payloadcms/db-postgres`)
|
||||
- TypeScript
|
||||
|
||||
## Campaign (`/campanha`)
|
||||
|
||||
Internal campaign tool for electoral nuclei, local leaderships, vote estimates, field updates, and WhatsApp invites. Authenticated separately from `/admin` via the `campaignUser` collection (`geral` / `coordenador` / `lideranca`). Operational status and decisions: [`.cursor/rules/projects/nucleos-eleitorais.mdc`](.cursor/rules/projects/nucleos-eleitorais.mdc). Conventions and deploy checklist: `AGENTS.md` (“Campaign auth” / “Campaign nuclei MVP”).
|
||||
|
||||
**Production blocker:** do not load real leadership data or enable invites until counsel-approved `Consent.key = 'lideranca-autopreenchimento'` exists. Absolute invite URLs require `NEXT_PUBLIC_SITE_URL` as an exact HTTPS DNS origin in production.
|
||||
|
||||
## Roadmap
|
||||
|
||||
Backlog and future plans live in [`docs/roadmap.md`](docs/roadmap.md) (blockers, public site, `/campanha` next cycles, admin RBAC, white-label).
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# Roadmap — Teqo
|
||||
|
||||
Atualizado em: 2026-07-17 (revisão de priorização orientada ao calendário eleitoral)
|
||||
Atualizado em: 2026-07-18 (código do MVP de Núcleos enviado; priorização eleitoral mantida)
|
||||
|
||||
Registro canônico no repositório dos planos futuros e débitos conhecidos. Status operacional do ciclo atual de Núcleos fica em [`.cursor/rules/projects/nucleos-eleitorais.mdc`](../.cursor/rules/projects/nucleos-eleitorais.mdc); este arquivo lista o que ainda é futuro ou bloqueador, **em ordem de execução**, com dependências e paralelismo explícitos.
|
||||
|
||||
|
|
@ -29,7 +29,7 @@ Registro canônico no repositório dos planos futuros e débitos conhecidos. Sta
|
|||
|
||||
## Onda 0 — Caminho crítico para `/campanha` em produção
|
||||
|
||||
O MVP de Núcleos está **code-complete** (ondas 1–8). O que separa a vertical da produção não é engenharia — é jurídico + operação de deploy. Estes itens começam **imediatamente** e correm em paralelo a qualquer trilha de engenharia:
|
||||
O MVP de Núcleos está **entregue em código** (ondas 1–8 + refactors; commit em `main` em 2026-07-18). A migration `20260718_010733_consolidate_campaign_schema` aplica automaticamente no `pnpm build` da Vercel. O que ainda separa a vertical de uso operacional com dados reais é jurídico + smoke pós-deploy:
|
||||
|
||||
1. **Lote jurídico único de LGPD/Consent** _(externo — assessoria jurídica eleitoral; é o caminho crítico da vertical inteira)_. Uma única rodada cobrindo:
|
||||
- Base do art. 11 da LGPD + texto versionado de `Consent.key = 'lideranca-autopreenchimento'` (bloqueador do MVP de Núcleos; o app falha fechado sem a chave).
|
||||
|
|
@ -38,15 +38,15 @@ O MVP de Núcleos está **code-complete** (ondas 1–8). O que separa a vertical
|
|||
- **Aviso de Privacidade / política de privacidade institucional** (obrigação do controlador antes de coleta em massa; também é item do site público).
|
||||
- Avaliação de necessidade de RIPD (tratamento em larga escala + dado sensível).
|
||||
- Racional: fatiar em rodadas separadas multiplica o lead time externo; quatro textos + aviso numa rodada só.
|
||||
2. **Checklist de verificação e deploy** do AGENTS.md (migrations `Ran: Yes`, types, lint, testes int/E2E, build local, envs Vercel — incl. `REVALIDATE_SECRET`, `NEXT_PUBLIC_SITE_URL` HTTPS).
|
||||
3. **Lançamento do MVP assim que (1) liberar a chave de liderança + (2) fechar.** Decisão de sequenciamento: **não** esperar a migração multi-município para lançar. Prós de lançar antes: coordenadores estruturam núcleos reais durante as convenções (20/07–05/08), cada semana vale capacidade de campo; a migration multi-município é in-place com backfill seguro e pode rodar com dados reais pequenos. Contras: uma migration a mais pós-lançamento. O contra é barato; o pró é tempo de campanha, que não volta.
|
||||
2. **Smoke pós-deploy** _(após o build Vercel aplicar a migration)_: conferir `NEXT_PUBLIC_SITE_URL` HTTPS exato, login `/campanha`, criar núcleo de teste, e só então cadastrar o Consent de liderança. Checklist completo no AGENTS.md.
|
||||
3. **Ativação com dados reais assim que (1) liberar a chave de liderança.** Decisão de sequenciamento: **não** esperar a migração multi-município. Prós: coordenadores estruturam núcleos reais durante as convenções (20/07–05/08); a migration multi-município é in-place com backfill seguro e pode rodar com dados reais pequenos. Contras: uma migration a mais pós-lançamento. O contra é barato; o pró é tempo de campanha, que não volta.
|
||||
4. **Onboarding do time real** (usuários `geral`/`coordenador`, primeiros núcleos, treinamento básico de campo).
|
||||
|
||||
## Campanha (`/campanha`)
|
||||
|
||||
### Ciclo 1 — Núcleos (entregue)
|
||||
|
||||
MVP de território + reporte implementado (ondas 1–8): auth isolada `campaignUser` (`geral` / `coordenador` / `lideranca`), núcleos com slug canônico, lideranças, estimativas sugerir/confirmar, atualizações semanais, convites WhatsApp (`wa.me`, hash, uso único), dashboard e hardening. Detalhes: [`.cursor/rules/projects/nucleos-eleitorais.mdc`](../.cursor/rules/projects/nucleos-eleitorais.mdc).
|
||||
MVP de território + reporte implementado e enviado (ondas 1–8 + refactors de composição/infra/fixtures): auth isolada `campaignUser` (`geral` / `coordenador` / `lideranca`), núcleos com slug canônico, designação de coordenador, lideranças, estimativas sugerir/confirmar com versão UUID, atualizações semanais, convites WhatsApp (`wa.me`, hash, uso único), dashboard e hardening. Território atual ainda é `region`/`city`/`neighborhood` unitários; multi-município permanece no item A1. Detalhes: [`.cursor/rules/projects/nucleos-eleitorais.mdc`](../.cursor/rules/projects/nucleos-eleitorais.mdc).
|
||||
|
||||
### Grafo de dependências
|
||||
|
||||
|
|
@ -173,7 +173,7 @@ Itens sem seta de entrada (**paralelizáveis a qualquer momento**): A1, A3, B1,
|
|||
|
||||
| Item | Status | Fonte |
|
||||
| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------- | --------------------------------------------------------------------------- |
|
||||
| Lote jurídico único LGPD (4 textos de `Consent` + Aviso de Privacidade + avaliação de RIPD) — ver Onda 0. O app falha fechado sem as chaves | **caminho crítico; iniciar já** | notebook Núcleos; AGENTS checklist; planos cadastro-nominal e notifications |
|
||||
| Lote jurídico único LGPD (4 textos de `Consent` + Aviso de Privacidade + avaliação de RIPD) — ver Onda 0. Código do MVP já em `main`; o app falha fechado sem as chaves | **caminho crítico; iniciar já** | notebook Núcleos; AGENTS checklist; planos cadastro-nominal e notifications |
|
||||
| RBAC em `users` — todo usuário do admin Payload tem acesso total; necessário antes de abrir `/admin` a equipe maior. Nota: o import de apoiadores foi desenhado no `/campanha` justamente para não depender disso | pendente | AGENTS Known Gap #1 |
|
||||
| Fluxos públicos ainda hardcodam ID de Consent (ex. `consent: 2` em `submitWhatsapp.ts`); migrar para chave estável como na campanha | pendente | AGENTS Known Gap #2; plano-arquitetura |
|
||||
| Collection `Pages` inexistente; hero/copy da home ainda hardcoded — bio, propostas e páginas institucionais | pendente (não bloqueia `/campanha`) | AGENTS Known Gap #3 |
|
||||
|
|
|
|||
Loading…
Reference in a new issue