Merge pull request #248 from fsolla/cursor/096e33fe
docs: clarify product locks vs editable engineering
This commit is contained in:
commit
0f4eec227e
3 changed files with 9 additions and 4 deletions
|
|
@ -47,4 +47,5 @@ Established 2026-07-23 by the engineering-standards hardening (tracker: `docs/IM
|
|||
|
||||
- `src/lib/` = pure logic and static data (client-safe unless marked). `src/utilities/` = Payload/Next-coupled server code (mark `server-only` when server-bound). React components never live in `utilities/`.
|
||||
- Follow the domain prefixes (`campaign*`, `municipality*`, `supporter*`, `actionPlan*`); the access domain has a real folder (`utilities/access/`).
|
||||
- Abstractions need 3+ call sites or a policy worth naming (`runCampaignRedirectFormAction`, `runStaffEntityMutation`); don't build generic services for 2 uses.
|
||||
- **Edit the owner, don't twin.** New behavior lands in the module that already owns that concern (`CampaignTable`, list URL helpers, form-action wrappers, portfolio/relation cells, access helpers, …). A parallel file that reimplements the same machine is a defect unless the delivery names a deliberate policy fork. Prefer changing existing code over adding beside it; delete what your change supersedes in the same delivery (see "Dead code dies immediately"). Product constraints in `AGENTS.md` and frozen migration files are not a ban on editing application code.
|
||||
- **Reuse vs premature abstraction.** Prefer extending the existing owner. Do **not** invent a new shared abstraction for a speculative third use. If you are about to copy an existing path and the knowledge is the same, **edit the owner** (or extract in the same delivery) — waiting for "call site #3" is how twins spawn. Defer only true look-alikes that differ in policy, with an explicit revisit trigger. Named policy wrappers (`runCampaignRedirectFormAction`, `runStaffEntityMutation`) stay justified even at few call sites.
|
||||
|
|
|
|||
|
|
@ -1,10 +1,12 @@
|
|||
---
|
||||
description: Estado do projeto da vertical /campanha (Núcleos → Praças → Municípios)
|
||||
description: Changelog / notebook da vertical /campanha (Núcleos → Praças → Municípios) — histórico de entregas, NÃO restrições de engenharia
|
||||
alwaysApply: false
|
||||
---
|
||||
|
||||
# Núcleos Eleitorais → Municípios
|
||||
|
||||
**Como ler este notebook:** as entradas "**entregue em código**", decisões de sessão e micro-escolhas de implementação abaixo são **changelog** (o que aconteceu e onde está o plano). Não são locks. Não impeçam editar o código que uma entrega anterior criou; não obriguem a espelhar um twin em vez de mudar o dono. Constraints reais de produto/segurança vivem em `AGENTS.md`, `docs/ARCHITECTURE.md` e `.cursor/rules/engineering-standards.mdc`. Para o estado vivo da fila, use Issues + `project-status` — não trate este arquivo como fonte canônica de "o que ainda pode mudar".
|
||||
|
||||
## Status
|
||||
|
||||
- **B53 entregue em código (2026-07-30):** sexto grupo da busca global do Início — **Demandas** via `searchHomeDemands` + `HomeSearchDemandGroup` (após Dobradinhas); `POST /campanha/home-search` agrega `demands`; match word-start no `title`; secundário `"{município} · {status}"`; staff access com `overrideAccess: false`; cap 25; int `homeSearchDemands.int.spec.ts`. WA = **B55**. Plano: [`busca-global-resultados-demandas.md`](../../../docs/plans/busca-global-resultados-demandas.md). Próximo na cadeia busca: **B54** grid/cap.
|
||||
|
|
|
|||
|
|
@ -6,7 +6,9 @@ You are an expert Payload CMS developer. When working with Payload projects, fol
|
|||
|
||||
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:**
|
||||
**Product constraints (reopen only with new product evidence):**
|
||||
|
||||
These are product/architecture constraints — not a ban on editing existing code. Engineering choices from past deliveries, plans, and project notebooks are **history**, not locks: prefer changing the module that already owns a concern over adding a twin beside it. What stays frozen for safety: shipped migration files (never edit retroactively), Consent/LGPD fail-closed behavior, and public URL contracts unless the delivery explicitly owns that change. See `.cursor/rules/engineering-standards.mdc` ("Edit the owner, don't twin").
|
||||
|
||||
- Single Next.js app, three route groups: `(frontend)` public site, `(payload)` admin, `(campaign)` internal campaign tool. No separate Rust service or frontend app for `/campanha`; it is modeled with Payload collections. The campaign roles are `coordinator` (label "Coordenador Geral"), `advisor` ("Assessor"), `leader` ("Liderança"), and `candidate` ("Candidato", unrestricted visibility), all on the separate auth collection `campaignUser` (see "Campaign auth" below). An advisor sees and manages ONLY the municipalities they administer; a leader is locked down to the supporter contact tool.
|
||||
- **2026-07-23 remodel (DEPLOYED to production 2026-07-23): "Município" is the operational unit** (it replaced "Praça", which replaced "Núcleo Eleitoral"). Municípios are PREDEFINED (seeded, geography read-only): 435 rows — one per Bahia municipality (416), except Salvador (19 zone Municípios, ZE 1–19); Camaçari is a single whole municipality (ZE 170/171 aggregated); shared/leaky TSE zones are cut at the municipal boundary. Code identifier: `municipality`. Leaderships are one record per person (`contact` UNIQUE) linked to N municipalities and N organizations; vote pledges are per leadership×municipality with `declaredVotes` (staff-entered, leader-visible) vs `estimatedVotes` (three scenarios, staff-only, hidden from the leader). Campaign production data was reset by the remodel migrations (public-site data untouched). Master plan: `docs/plans/remodelagem-municipios.md` (supersedes `remodelagem-pracas.md`). Details: "Campaign Municípios model" below.
|
||||
|
|
@ -15,7 +17,7 @@ Teqo is the digital platform for deputado federal Jorge Solla (PT-BA): public si
|
|||
|
||||
- **Embasamento de produto/domínio:** `docs/research/` guarda o compêndio de literatura (campanha de DF na Bahia, geografia do voto, cartografia eleitoral) e o relatório de discovery aprovado (2026-07-21) com o playbook dado→decisão. Para métricas, análises territoriais, mapa e priorização em `/campanha`, consulte-o antes de inventar — o kernel: a disputa de DF é conta de quociente fragmentada; leitura útil é relativa e local (captura, LQ, quantis, cobertura de meta por pledges), nunca % estadual absoluto.
|
||||
|
||||
**Real conventions already established in this codebase (follow these, not just the generic patterns below):**
|
||||
**Real conventions already established in this codebase (follow these patterns; extend or edit the owner when the concern already exists — do not invent a parallel path):**
|
||||
|
||||
- `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.
|
||||
|
|
|
|||
Loading…
Reference in a new issue