Commit graph

724 commits

Author SHA1 Message Date
Francisco Ignácio Fontoura Solla
c07969f4a7 Remove duplicated voteGoals; seed projection sheet into expectedVotes.
Meta Bom/Regular/Mínimo duplicated the estimate scenarios — keep a single municipality series (pessimista/média/otimista), backfill then drop the old columns, and map the spreadsheet onto expectedVotes.
2026-07-24 14:04:44 -03:00
Francisco Ignácio Fontoura Solla
d14ed67801 Ship E4R: always-overwrite seed of projection spreadsheet into voteGoals and priority.
One-shot CLI (`pnpm db:seed:projecao`) matches MAPA GERAL to municipalities, skips Salvador, and re-seeds when a newer sheet arrives; dry-run + docs/roadmap updated.
2026-07-24 13:13:46 -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
f23c2582ee Break up the god modules into deep domain modules
- campaignAccess.ts (990 lines, ~80 exports) is now a 130-line explicit
  re-export surface over 14 domain modules in src/utilities/access/
  (shared actor predicates + per-collection access); public surface
  AST-verified identical, import sites untouched
- actions/supporter.ts split: single-supporter lifecycle (407) vs the CSV
  import pipeline in supporterImport.ts (357); 'use server' re-export
  constraint honored with thin async delegates
- organization/stateDeputy clone twins deduped by POLICY:
  runStaffEntityMutation (fresh staff assert + unique-conflict translation)
  keeps each caller's concretely-typed Payload mutation
- runCampaignRedirectFormAction removes the copy-pasted try/map/redirect
  ladder from 4 create formActions (planos kept its genuinely custom flow)
- Plaza→Municipality identifier rename finished (context keys, list-label
  and leadership constants, fixture sequence, test constants)
- RefreshRouteOnSave (React component) moved out of utilities/ to components/
2026-07-23 23:44:45 -03:00
Francisco Ignácio Fontoura Solla
590d311364 Scope client state to where it is used
- MunicipalityMapSelection leaf owns hover/selection: a mouseover re-renders
  only the map + readout, not the whole panel (controls, legend, zone list);
  Leaflet paint stays ref-based (B6)
- municípios list: MunicipalityEstimateScenarioProvider now wraps only the
  results — scenario switches no longer re-render the filter controls
  (dashboard already scoped it to the map)
- LeaderContactsPanel is a server component again: header + contacts table
  render on the server; only LeaderContactForm (new client file) hydrates
- ledgered with rationale: map-bundle slimming deferred (gzip crushes the
  repeating keys; instant year/scenario switching is a core analysis flow);
  props-to-state effect mirrors reviewed and accepted as the correct
  server-echo reconciliation pattern
2026-07-23 23:26:28 -03:00
Francisco Ignácio Fontoura Solla
05a47b881c Make every campaign action feel immediate with honest pending
Closes the 'Feel the action' gaps (.cursor/rules/campanha-action-feedback.mdc):

- BUG: action-plan task checkbox was optimistic but never revalidated — a
  successful toggle visually reverted when the transition ended. The action
  now revalidates the plan page; checkbox disables while pending
- map compare + candidate compare picker: optimistic select value +
  useTransition; the map region dims with aria-busy and a live region
  instead of flashing the full-page skeleton
- CampaignListPendingBoundary/CampaignListResults: one shared transition so
  filters (municípios/apoiadores/planos), pagination, demandas status chips
  (new CampaignFilterChips), and the name-search pages (new
  CampaignSearchForm on lideranças/organizações/dobradinhas) dim the RESULTS
  region, not only the control — children stay server-rendered (composition)
- streaming: dashboard map section behind Suspense (KPI shell paints first;
  React cache() keeps the municipality scope shared, not reloaded);
  municipality detail tabs (elections/leaderships/updates) stream below the
  header; list-shaped loading.tsx for /municipios and /apoiadores
- logout button gets a pending state; BahiaMap init shows a visible spinner
  (was sr-only)
2026-07-23 23:21:46 -03:00
Francisco Ignácio Fontoura Solla
a32ba3b4f0 Cache the campaign hot path: committed TSE artifact + request-scoped dedup
- committed artifact src/lib/electionAggregates/bahia-federal-baseline.json
  (Solla nominal + federal T1 valid votes per catalog municipality × TSE year,
  Salvador split by zone) generated by pnpm build:election-aggregates from the
  locally seeded TSE data; typed loader src/lib/bahiaElectionAggregates.ts;
  snapshot spec pins artifact ↔ catalog ↔ baseline ticket
- map bundle: historical years now read the artifact (was 6 statewide
  city×zone scans per dashboard visit); compare mode keeps only the OTHER
  candidate on the DB path (Solla side from the artifact)
- loadMunicipalityScope (React cache()): one municipality find + pledge
  aggregate per request shared by dashboard KPIs, map bundle, and the
  municípios list overview (was 2-3 duplicate loads)
- unstable_cache + election-tse tag on the immutable elections-tab loaders
  (baseline, candidate comparison, candidate options); tag added to the
  /api/revalidate allowlist — runbook: re-seed then bust the tag
- municipalityMapContract.ts: client-safe map vocabulary/bundle types so the
  client panel no longer imports the server data module (build had pulled
  @payload-config into the client graph); municipalityMapData is server-only
  and re-exports the contract; PLAZA_MAP_* renamed to MUNICIPALITY_MAP_*
- petition generateStaticParams enumerates bare ids (getPetitionIds)
2026-07-23 23:06:28 -03:00
Francisco Ignácio Fontoura Solla
0e4e6855dc Add the tooling gate: knip, CI, zero-warning lint, as-never ban
- knip (files/deps at error level; unused exports ledgered as warn) with
  config for Payload/Next entries; deleted the dead modules it confirmed:
  RecentlyVisited + UpcomingActionPlansCard + actionPlanUpcomingPreview,
  lazy-dialog helpers, tseZone, federalCandidateTotalsAggregate (test-only),
  unused ui kit files, one-shot rename script; pruned unused radix deps and
  typescript-eslint; added pg/@types/pg (pinned to drizzle's 8.10.2)
- GitHub Actions CI on the mirror: lint, typecheck, knip, unit, migrate, int
  against a Postgres 17 service
- eslint: unused-vars with ^_ ignore patterns (migrations args exempt),
  repo-wide ban on `as never` (no-restricted-syntax), lint gate at
  --max-warnings=0; fixed all 54 pre-existing warnings (dead imports,
  hooks deps, tracking-pixel img disable with impeccable config exception)
- tsconfig: include consolidated from 219 lines to 5 (wildcard covers all
  .next dist variants), noUnusedLocals on
- typed replacements for every as-never: hookFilledCreateData (actions
  create data completed by collection hooks), drizzle scopeColumn narrowing,
  tests' stub<T> helper (property-level checking kept, completeness waived)
- test infra: leased-consent generalization used by onda0 spec (shared
  leases over the stable consent keys; window race ledgered), purge fix
- docs: IMPROVE-CODE-QUALITY-PLAN.md tracker, TECH-DEBT.md ledger,
  TESTING.md safety-net map (package.json also gains the Phase 2
  build:election-aggregates script entry; the script lands next commit)
2026-07-23 23:06:12 -03:00
Francisco Ignácio Fontoura Solla
473c82d09d Lock down CMS/PII collection access and leader routes
- users/signature/subscription/consent: all operations Payload-admin-only
  (Payload's default allowed ANY authenticated user, incl. campaign JWTs
  via /api — privilege escalation + PII exposure)
- post/tag/media/petition: public read kept, writes admin-only,
  readVersions admin-only on drafted collections
- leader lockdown: staff gates on /campanha/demandas* and /campanha/planos*;
  removed the dead leader branch of the demand detail page
- fix createLeaderSupporter: scope now asserted via the leader's engaged
  leadership municipalities (canReadMunicipality always denied leaders)
- candidate alignment: supporter area, invite creation, and escalated
  demand decisions now treat candidate as unrestricted staff consistently
- tests: collectionAccessLockdown.int.spec pins the lockdown; leased-consent
  helpers generalized (supporter keys); fixtures purge deletes residue
  invites before leaderships; stale leader-phone tests updated to the
  lockdown model; 'sem Praça' copy renamed to 'sem município'
2026-07-23 22:25:18 -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
Francisco Ignácio Fontoura Solla
66dc64fe41 Fix prefer-const lint in vote estimate normalize helper. 2026-07-23 19:13:05 -03:00
Francisco Ignácio Fontoura Solla
aa12e173d8 Ship A10 vote estimate scenarios (pessimistic/central/optimistic) for Praças.
Staff surfaces share one Cenário control; leaders keep a single declaredVotes value. Unlocks E8.
2026-07-23 19:12:22 -03:00
Francisco Ignácio Fontoura Solla
d93e2aa72f Add admin CSV export for signatures and contacts.
Enables @payloadcms/plugin-import-export on signature (flattened contact/petition columns) and contact (native fields) so operations can download filtered lists for external ESP/SMS workflows.
2026-07-23 00:53:04 -03:00
Francisco Ignácio Fontoura Solla
0cb83bdfa6 Adopt TypeScript 6 for tooling and TypeScript 7 for typecheck.
Dual-package setup keeps ESLint/editor on the TS 6 API while pnpm typecheck uses Go tsc 7.0.2; tsconfig drops deprecated baseUrl and adds ambient CSS module declarations.
2026-07-21 20:32:15 -03:00
Francisco Ignácio Fontoura Solla
a864adc1b5 Add ESLint guard for invalid use server exports and fix plaza staff messages.
Catch Next.js invalid-use-server-value at lint time and move shared form-error copy out of plazaStaffFormActions so the use server module only exports async actions.
2026-07-21 20:07:06 -03:00
Francisco Ignácio Fontoura Solla
cd8002a6e1 Deliver B12 map viewport fit and hover fixes for filtered Praças.
Aproxima o mapa ao footprint filtrado e corrige hover fora do filtro, ênfase sticky e fill agressivo no Mapa das Praças.
2026-07-21 18:10:32 -03:00
Francisco Ignácio Fontoura Solla
c0bf440c76 Deliver C8 F4 shared plaza staff form actions and close simplify debts.
Unify list and /editar server actions in plazaStaffFormActions.ts so B9 inline edits and the edit page share one implementation without behavior changes.
2026-07-21 16:14:30 -03:00
Francisco Ignácio Fontoura Solla
e497fc3982 Deliver B8 F1 plaza zone neighborhoods catalog and absorb simplify debts.
Ship static zone-to-neighborhood mapping for Salvador/Camaçari Praças-zona, overview UI card, tests/fixture, and roadmap/plan updates including F2 prep follow-ups from capture-review-debts.
2026-07-21 16:08:34 -03:00
Francisco Ignácio Fontoura Solla
7f437741ba Deliver B6 incremental BahiaMap setStyle and absorb post-simplify debts.
Keep GeoJSON stable across metric/scale/hover changes via pathByKeyRef and O(2) restyle; extract bahiaMapStyle helpers with unit tests and close B10/B11 perf debt refs in plans.
2026-07-21 16:02:20 -03:00
Francisco Ignácio Fontoura Solla
0dcef662e7 Deliver A9+ shared Praças list loader and scoped revalidation.
Deduplicate pledge aggregation via loadPlazaListPageBundle, add plazaRevalidation with slug-scoped detail paths after inline saves, and document the fill-in as shipped.
2026-07-21 13:22:12 -03:00
Francisco Ignácio Fontoura Solla
9db80d815b Deliver B11 percent-of-valid-votes scale on Praças map.
Adds valid-votes denominators to the map bundle, a Total vs % dos válidos selector with fixed 0–100% coloring, and readout/legend alignment via scaleMax; updates roadmap and post-simplify debt docs.
2026-07-21 13:12:05 -03:00
Francisco Ignácio Fontoura Solla
248f896d05 Deliver auto-applied filters on Praças list and close filtros-auto fill-in.
Remove the Buscar step with debounced search, immediate select navigation, and pending UI; update roadmap, plan, and notebook.
2026-07-21 12:54:23 -03:00
Francisco Ignácio Fontoura Solla
bb5129d514 Deliver B10 hover/tap on Praças map and absorb perf debts into B6.
Adds polygon highlight, vote readout, and navigation (desktop click / mobile 2nd tap) on the filtered Praças choropleth, with simplify cleanup and B6 plan updates for incremental setStyle.
2026-07-21 11:58:49 -03:00
Francisco Ignácio Fontoura Solla
70c61ab49e Deliver B9 quick edit on Praças list and register simplify follow-ups.
Inline staff edits for advisors, political trend, and expected votes on /campanha/pracas; absorb post-simplify debts into A9+ and C8 plans.
2026-07-21 11:45:37 -03:00
Francisco Ignácio Fontoura Solla
936323c7ee Filter Praças map by the same URL filters as the list (B7).
Wire buildPlazaListWhere into loadPlazaMapBundle, export PlazaListSearchParams
from plazaUi, add integration tests, and mark B7 delivered in roadmap/docs.
2026-07-21 11:37:32 -03:00
Francisco Ignácio Fontoura Solla
b333609726 Deliver A9 plaza expectedVotes and register A9+ follow-up.
Add staff-only expectedVotes with migration, edit flow, and expectedVotes ?? pledge fallback across map, overview, and dashboard; document delivery and the A9+ loader dedup fill-in on the roadmap.
2026-07-21 11:02:11 -03:00
Francisco Ignácio Fontoura Solla
be1106f887 Add Meta Pixel tracking to public petition pages.
Let marketing configure a numeric facebookPixelId per petition in Payload, fire PageView on load and Lead after a successful signature, and mark the roadmap item delivered with deferred follow-ups documented.
2026-07-21 10:51:47 -03:00
Francisco Ignácio Fontoura Solla
cf13c441aa Remodel /campanha around predefined Praças replacing electoral nuclei.
436 seeded Praças (municipality-based; per-TSE-zone in Salvador/Camaçari) become
the operational unit; roles renamed to coordinator/advisor/leader with advisors
scoped to administered Praças. Leadership is one record per person across many
Praças/organizations; vote pledges split leader-declared vs staff-estimated
(estimates never serialized to leaders). Adds organizations, demand workflow
with staff-only cost/receipts, action-plan results with deputy presence, manual
political trend, multi-candidate comparison and the diverging red/white/blue
map mode. Migration 20260721_020109_remodel_plazas deliberately resets the
campaign vertical in production (public site untouched); test suite ported to
the new model (unit 187 / int 306 / e2e 9 green).
2026-07-21 02:28:00 -03:00
Francisco Ignácio Fontoura Solla
bbd9f627f5 Show a distinct message when campaign login is temporarily locked.
Users hitting Payload maxLoginAttempts now see lockout guidance instead of the generic invalid-credentials copy.
2026-07-20 18:24:19 -03:00
Francisco Ignácio Fontoura Solla
87c36e4856 Deliver A8 IBGE voter profile on Eleitorado tab with post-simplify scale plan.
Adds static SIDRA demographics, territory-weighted derivation, electorate UI with opt-in copy to manual profiles, shared territory-city resolution, and registers A8+ fill-in debt from capture-review-debts.
2026-07-19 23:05:27 -03:00
Francisco Ignácio Fontoura Solla
c2381cecde Deliver A7 Fase 2 cityCode TSE geography filters and absorb simplify debts.
Switch election geography queries from cityName to TSE cityCode via a static Bahia map and nucleusElectionGeography module, with simplify cleanup and plan updates for F3–F5 follow-ups.
2026-07-19 22:48:08 -03:00
Francisco Ignácio Fontoura Solla
ea579d2173 Deliver A5 mobilization insight and absorb E7 F2 int follow-up.
Surface brancos/nulos/abstenções as mobilization opportunity on nucleus detail and list overview, with loader aggregate and unit tests; register pending int coverage in escala-dry-pos-e2.
2026-07-19 22:34:35 -03:00
Francisco Ignácio Fontoura Solla
0460b08429 Add allowlisted global cache revalidation for Onda 0 F1.
Extend POST /api/revalidate with posts and global_privacy-policy tags so
direct-DB Onda 0 writes can bust /privacidade without an admin edit.
2026-07-19 22:21:16 -03:00
Francisco Ignácio Fontoura Solla
b75daab498 Refactor campaign dashboard UX and add product discovery artifacts.
Extract dashboard cards into focused components (queues, upcoming plans, leadership status, recently visited, choropleth legend), compile the roadmap for outcome-oriented tracking, document the customer job and improve-app journey, and tighten roadmap skills with decision-quality gates.
2026-07-19 21:56:01 -03:00
Francisco Ignácio Fontoura Solla
f5140b15a2 Polish campaign login auth UI after Impeccable critique.
Fix header alignment and rhythm, swap Megaphone for CampaignLogo, add progressive disclosure for first access, and extract shared auth shells with corrected individual-account copy; record closed critique items in RS+.
2026-07-19 19:24:12 -03:00
Francisco Ignácio Fontoura Solla
9e73b676db Fix PascalCase lint that broke Vercel builds and run lint on pre-push. 2026-07-19 18:36:33 -03:00
Francisco Ignácio Fontoura Solla
81b01b9907 Deliver A5-2 territorial classification insight and absorb review debts.
Classify nuclei as defesa/ataque/indecisa/perdida from 2022 baseline share, surface Alert + overview distribution, and register post-simplify follow-ups in A7/E7 plans.
2026-07-19 18:15:07 -03:00
Francisco Ignácio Fontoura Solla
909778eaea Fix leverage overview row typecheck for comparable ticket votes.
Narrow ticketVotes before pushing leverage rows so pre-push tsc passes.
2026-07-19 17:34:56 -03:00
Francisco Ignácio Fontoura Solla
94f0bd51f8 Deliver A5 ticket leverage and flip insights with simplify cleanup.
Surface majoritarian base conversion and proportional flip opportunity on nucleus detail and list overview, precompute ticketFlip on the baseline VM, and register post-simplify scale debts in A7 F5 and E7.
2026-07-19 17:34:06 -03:00
Francisco Ignácio Fontoura Solla
e2075a86af Fix BahiaMap Leaflet style callback typing for pre-push typecheck. 2026-07-19 17:14:23 -03:00
Francisco Ignácio Fontoura Solla
b8547ff292 Deliver B3 Leaflet choropleth maps and register post-simplify follow-ups.
Add BahiaMap surfaces on nuclei list, detail, and geral dashboard with server-side choropleth aggregation, lazy geometry loading (B5 F1), and roadmap plans for A7 F4, B5 F3, and B6 scale debts.
2026-07-19 17:13:27 -03:00
Francisco Ignácio Fontoura Solla
8420969b4b Deliver A7 Fase 1 federal ranking aggregate and register simplify follow-ups.
Replace full Local API federal T1 loads with drizzle GROUP BY on nucleus detail, gate election reads via assertCanReadElectionData, and absorb post-simplify cleanup into the A7 plan and roadmap.
2026-07-19 16:57:08 -03:00
Francisco Ignácio Fontoura Solla
429b31048f Deliver A5 slice 1 conversion-rate insight and absorb review debts.
Surface taxa de conversão on nucleus detail and list overview, with loader
optimizations and unit tests; update plan/roadmap follow-ups for E7, A7, and RS+.
2026-07-19 14:05:11 -03:00
Francisco Ignácio Fontoura Solla
1b6de775a0 Unify campaign auth pages with shared shell and improve login UX.
Extract CampaignAuthPageShell and shared copy tokens across login, forgot-password, and reset-password flows; add adaptive inputMode, credential error a11y, and roadmap skill updates from the FD2 critique pass.
2026-07-19 13:02:47 -03:00
Francisco Ignácio Fontoura Solla
7fb688ab95 Add pre-push typecheck hook and fix campaign avatar field access.
Wire husky with a typecheck script, await the async avatar update guard, harden Onda 0 consent unit tests, and extend the roadmap implementation skill with Impeccable UI gates.
2026-07-19 12:10:59 -03:00
Francisco Ignácio Fontoura Solla
e80f4030cb Polish /campanha Field Desk UX and register FD+/FD2 follow-ups.
Align the campaign desk with quieter KPI strips, queues-first dashboard, shared shells, and advanced filters; capture Impeccable design context and the remaining simplify/critique debts on the roadmap.
2026-07-19 08:17:12 -03:00
Francisco Ignácio Fontoura Solla
3b463173da Add campaign password reset, profile photo, and RS+ follow-up plan.
Deliver self-service forgot/reset via Resend, logged-in password change, and optional avatar on /campanha/perfil; register post-simplify engineering debts as RS+.
2026-07-19 05:26:56 -03:00
Francisco Ignácio Fontoura Solla
b0f4ebc1ed Add E2 TSE 2014/2018 vote series and historical trend insights.
Extends the electoral baseline with multi-year seeding, computeVoteTrend, list/detail UI, and registers post-simplify follow-ups as E7.
2026-07-19 05:09:43 -03:00
Francisco Ignácio Fontoura Solla
e5e051d175 Deliver E1 vote goals and E3 strategy fields on nuclei.
Wire schema, UI, aggregates, and tests for scenario goals, priority filter, staff-only dobradinha notes and next steps; register E6 scale follow-ups from simplify.
2026-07-19 04:38:07 -03:00
Francisco Ignácio Fontoura Solla
456b5d8a4e Add nucleus vote goals foundation for E1/E3.
Introduce voteGoals helpers, Metas 2026 UI card, migration, and unit tests as the first slice of scenario goals and priority work.
2026-07-19 04:36:58 -03:00
Francisco Ignácio Fontoura Solla
7ddd0feb0f Fix getCachedGlobal typing so production builds typecheck again.
The Onda 0 factory Map erased Slug generics to any, breaking keyword/social metadata inference during next build.
2026-07-19 04:27:04 -03:00
Francisco Ignácio Fontoura Solla
4ee7d12085 Extract supporter list SQL filters into a server-only module. 2026-07-19 04:16:47 -03:00
Francisco Ignácio Fontoura Solla
4e68e647d4 Merge branch 'cursor/667b8d6e': recent visits panel and VR+ follow-ups.
# Conflicts:
#	docs/roadmap.md
2026-07-19 04:10:57 -03:00
Francisco Ignácio Fontoura Solla
51364da29f Add recent visits panel to /campanha and register VR+ simplify follow-ups. 2026-07-19 04:06:14 -03:00
Francisco Ignácio Fontoura Solla
9efcf2832f Add missing C7 modules and register C11 simplify follow-ups. 2026-07-19 03:52:22 -03:00
Francisco Ignácio Fontoura Solla
15c756bb10 Deliver C7 scale/DRY for action plans: territory composition, tab-scoped reads, and hook shortcuts. 2026-07-19 03:50:58 -03:00
Francisco Ignácio Fontoura Solla
cc66ec3c31 Deliver Onda 0 MVP: provisional Consent, privacy policy, and /privacidade.
Auto-provision legal texts via migrations and db:seed:consent so local and
production deploy stay fail-closed-ready; register O0+ simplify follow-ups.
2026-07-19 03:38:21 -03:00
Francisco Ignácio Fontoura Solla
ced1b71771 Deliver C9 scale/DRY for supporters and register C10 follow-ups. 2026-07-19 03:23:25 -03:00
Francisco Ignácio Fontoura Solla
1e23b27b4f Deliver C8 scale/DRY for supporters and register C9 follow-ups.
Bulk import and list paths get single-round-trip locks, drizzle returning reads, pg_trgm search, shared drizzleBulk helpers, and consolidated campaign formActions; simplify debts land as C9 in the roadmap.
2026-07-19 00:31:06 -03:00
Francisco Ignácio Fontoura Solla
8b4ceae0ad Merge branch 'cursor/602456d7': C7 partial scale/DRY for action plans
Deliver denormalized task counters, shared territory FormData parsing, advisory locks, contact-search guard, and document remaining simplify debts.

# Conflicts:
#	docs/roadmap.md
2026-07-19 00:09:50 -03:00
Francisco Ignácio Fontoura Solla
73cfcc94d9 Deliver C7 partial scale/DRY for action plans and register remaining simplify debts.
Add denormalized task counters with list perf migration, shared territory FormData parsing, advisory locks on task/update mutations, and a shared contact-search guard; document what is still pending in the C7 plan and roadmap.
2026-07-19 00:07:31 -03:00
Francisco Ignácio Fontoura Solla
1f8b0c8c72 Add A4 electoral baseline in product with Gap vs 2022, and register A7.
Surface TSE 2022 aggregation on nucleus detail and list overview; document scale/DRY follow-ups from the simplify pass.
2026-07-18 22:50:10 -03:00
Francisco Ignácio Fontoura Solla
9ccfb3b704 Simplify C6 supporter paths and register C8 scale/DRY follow-ups.
Apply the /simplify cleanup to the C6 commit (identity maps, dead branches,
relationshipId reuse, native base64url, rowCount fix, canManageCampaignUsers
reuse) and register the unimplemented debits as roadmap item C8 with its plan.
2026-07-18 22:34:55 -03:00
Francisco Ignácio Fontoura Solla
9fdbae05d7 Add C6 scale/DRY for supporters: bulk import, KPI aggregate, shared shells.
Phase 1 UX: StrictCombobox municipality in SupporterForm, AlertDialog in
RemoveSupporterDataButton. Phase 2 DRY: campaignListUrl + CampaignListPagination
+ campaignFormFields + mapCampaignFormActionError shared across nuclei,
supporters and action plans. Phase 3: single SQL aggregate for supporter list
KPIs via drizzle in the Payload txn. Phase 4: bulk drizzle insert for CSV import
inside the existing Payload txn with ON CONFLICT DO NOTHING, plus a fail-closed
skipContactPhoneInvariant context flag. Phase 5: HMAC-signed single-use import
token backed by a new supporterImportBatch staging collection so the full ok-row
set never crosses the Server Action boundary twice.
2026-07-18 22:17:31 -03:00
Francisco Ignácio Fontoura Solla
e5968f81d5 Add static Bahia municipality and territory geometries for the campaign map.
Ship TopoJSON meshes, IBGE code lookups, a re-runnable build script, and evidence tests so B3 can render Leaflet surfaces without PostGIS.
2026-07-18 22:07:41 -03:00
Francisco Ignácio Fontoura Solla
b2856abceb Fix Vercel build failing on sync exports from supporter server actions.
Next.js requires every export from a 'use server' module to be async; move the import type guard into a shared util and mark createSupporterRecord async. Also mark C2 as merged in the roadmap/docs.
2026-07-18 21:17:58 -03:00
Francisco Ignácio Fontoura Solla
e995aefbd4 Add action-plan agenda vertical for /campanha/planos.
Ship C3 mobilization events with the actionPlan collection, list/detail/forms UI, upcoming-event blocks, access control, and migration.
2026-07-18 20:56:20 -03:00
Francisco Ignácio Fontoura Solla
a18e2f15f5 Simplify C2 supporter paths and register C6 scale follow-ups.
Tighten import/create view models after review, and capture the deferred DRY/import-scale work as roadmap item C6.
2026-07-18 20:33:50 -03:00
Francisco Ignácio Fontoura Solla
b079daa9bb Add C2 nominal supporter registry for /campanha.
Ship the supporter join collection, consent-keyed create/import/remove actions, and apoiadores UI so staff can build a phone-required nominal base before mass field ops.
2026-07-18 20:32:54 -03:00
Francisco Ignácio Fontoura Solla
ac7f2775cd Add opt-in TSE zone and territory suggestion chips for nuclei.
Ship A2 with a static Bahia municipality↔zone map, pure suggestion engine, and form chips that never auto-apply geography.
2026-07-18 20:04:04 -03:00
Francisco Ignácio Fontoura Solla
202f1579ec Align docs with cycle 2 delivery and add roadmap-item skill.
Mark A1/A3/B1/C1/D1 as shipped, revise the A2 zone-suggestion plan, and tighten the share dialog overflow.
2026-07-18 19:01:25 -03:00
Francisco Ignácio Fontoura Solla
b035cc4a2f Support multi-municipality and multi-neighborhood nucleus territory.
Replace scalar region/city/neighborhood with hasMany arrays so nuclei can span multiple Bahia municipalities while keeping neighborhoods scoped to a single city.
2026-07-18 18:31:51 -03:00
Francisco Ignácio Fontoura Solla
c42b16baab Add TSE 2022 election results model and local seed import. 2026-07-18 18:25:19 -03:00
Francisco Ignácio Fontoura Solla
040c36bed7 Add filtered overview panel to the nuclei list page.
Give coordinators aggregate vote estimates, coverage, and recent updates for the current list filters without leaving /campanha/nucleos.
2026-07-18 18:20:33 -03:00
Francisco Ignácio Fontoura Solla
b483e0cb32 Add nucleus detail share dialog for WhatsApp and copy-link.
Staff can open recipients for gerais, coordinators, and engaged leaderships without granting access, and coordenadores/lideranças can read geral phones for contact.
2026-07-18 18:14:49 -03:00
Francisco Ignácio Fontoura Solla
5bfa226a7e Add installable PWA foundation for the /campanha field app.
Scoped manifest and service worker unlock offline shell and future push, with an install toast and logout cache wipe.
2026-07-18 17:28:34 -03:00
Francisco Ignácio Fontoura Solla
9c338b2d28 Fix Vercel build by correcting UI component filename casing.
Badge, Sheet, and Sidebar were tracked lowercase while imports used PascalCase, which breaks Linux case-sensitive builds.
2026-07-18 15:10:39 -03:00
Francisco Ignácio Fontoura Solla
bcac665cb5 Ship /campanha nuclei MVP with RBAC, invites, and vote estimates.
Adds electoral nuclei, leaderships, updates, and WhatsApp invite flows behind campaign auth, plus the consolidated schema migration that Vercel applies on deploy.
2026-07-18 15:01:56 -03:00
Francisco Ignácio Fontoura Solla
198de05c18 Add campaign app shell with a light shadcn sidebar.
Gives authenticated /campanha pages a navigable rail (logo, nav, user/Sair)
so the internal area feels like a real app instead of a bare layout.
2026-07-15 23:17:51 -03:00
Francisco Ignácio Fontoura Solla
c4866fabc0 Add /campanha internal area with isolated Payload auth
Introduce the internal campaign-management area gated by its own
authentication, kept isolated from the Payload admin so a campaign
session and an admin session can coexist in one browser.

- Add separate `campaignUser` auth collection (not `users` + roles)
- Authenticate via an isolated httpOnly `campaign-token` cookie scoped
  to /campanha, distinct from the default `payload-token`
- Add loginCampaign/logoutCampaign server actions and getCampaignUser
  session verification helper
- Add public login route and a protected (app) route group whose
  layout enforces the auth barrier
- Add migration 20260716_010420_add_campaign_user and document the
  auth foundation in AGENTS.md
2026-07-15 22:33:26 -03:00
Francisco Ignácio Fontoura Solla
f96863fad1 Add secured on-demand revalidation endpoint for posts cache
Public post pages read through the `posts`-tagged unstable_cache wrappers,
so their data is frozen at build time until revalidateTag('posts') runs in
the deployed runtime. A direct-DB seed (pnpm db:seed:posts) writes past the
Payload afterChange hooks (next/cache is stubbed), so nothing busts the tag
in prod and seeded posts never surface publicly.

Add POST /api/revalidate, guarded by a REVALIDATE_SECRET shared secret
(constant-time compare), that calls revalidatePostsListing() to refresh the
home page, all listings, and all article routes at once. Document the env var
in .env.example; it must be set in Vercel for production.
2026-07-15 21:24:02 -03:00
Francisco Ignácio Fontoura Solla
28647e4760 Add Post and Tag collections for news and publications
- Add Post + Tag collections (notícias/publicações) with tag-based
  "Esconder" visibility control for electoral-law compliance
- Add static SEO routes /[type]/[category]/[slug] plus /[type] and
  /[type]/[category] listings, with shared header/breadcrumb and PostCard
- Recreate the homepage and refresh the site color palette (styles.css)
- Add posts/slug/seo utilities and revalidation wiring (documents.ts)
- Add live-fetch seed script (scripts/seed-posts.mjs + seed-loader.mjs,
  db:seed:posts)
- Upgrade Payload 3.79.0 -> 3.82.0 (fixes admin relationship-filter crash)
- Remove obsolete Header component; add shadcn card/badge/breadcrumb;
  update AGENTS.md and components rule docs
2026-07-15 19:12:11 -03:00
Francisco Ignácio Fontoura Solla
712649eecf Replace state/city selects with type-to-filter comboboxes
Turn StateSelect and CitySelect into autocomplete comboboxes so long
lists no longer bias people toward the top option. A shared FormCombobox
wraps shadcn's (Base UI) Combobox and bridges it to react-hook-form via
useController, storing the state code / city name while displaying a
label. Matching is accent-insensitive and prefix-based; the list opens
after 1 character and results are alphabetical. State searches by both
full name and initials (new StateNames map).

Adds @base-ui/react + shadcn combobox/input-group primitives, and
documents our export-const and named-hook-import conventions in the
components rule (with the src/components/ui/* shadcn carve-out).
2026-07-15 14:41:58 -03:00
Francisco Ignácio Fontoura Solla
4f22824d4f Fix ESLint flat config so pnpm lint runs
The flat config spread eslint-config-next's subpath imports as if they were
flat-config arrays, but that package ships legacy eslintrc configs, so lint
crashed before checking any file. Wrap them with FlatCompat (add
@eslint/eslintrc) and fix the two pre-existing react/no-unescaped-entities
errors so lint passes.
2026-07-15 13:56:53 -03:00
Francisco Ignácio Fontoura Solla
4f0f997c32 Isolate local/dev and tests from the production database
Local dev and the test suite previously defaulted to the live production
Neon database, and running the tests mutated prod data. Add guardrails plus
a proper local Postgres + migrations workflow so production can't be hit by
mistake:

- docker-compose: local Postgres 17 (matches prod) + auto-created teqo_test
- dev guard refuses a non-local DATABASE_URL; tests refuse non-_test databases
- .env.test isolates the suite; vitest/playwright load it and fail closed
- Payload migrations set up (push disabled); build runs `payload migrate`,
  so deploys apply pending migrations to prod automatically
- baseline `initial` migration + idempotent consent.text varchar->jsonb fix
- `pnpm db:pull` copies prod content locally, excluding supporter PII
- docs (README, AGENTS.md) + agent skills for the local-db/migration workflow
2026-07-15 13:52:30 -03:00
Francisco Ignácio Fontoura Solla
715e3d051e Fix optional chaining for image metadata fields 2026-05-01 10:28:32 -03:00
Francisco Ignácio Fontoura Solla
166104bbac Fetch live count on mount to override stale initialCount 2026-05-01 10:21:55 -03:00
Francisco Ignácio Fontoura Solla
260f75abe8 Add secureUrl and type to OG image metadata 2026-05-01 02:55:37 -03:00
Francisco Ignácio Fontoura Solla
9313eb7f29 feat: Add schema-dts to package.json and update SEO metadata
Adds the `schema-dts` dependency to `package.json` for structured data.
Updates the petition page to include JSON-LD schema markup for improved
SEO and rich results. This involves extracting the first image from the
Lexical editor or falling back to a global image for Open Graph and
schema.org metadata.
2026-05-01 02:13:39 -03:00
Francisco Ignácio Fontoura Solla
135b9229a4 Refactor: Improve petition details and privacy message
Update the descriptive text for the petition to better reflect its
purpose and clarify data usage.
2026-05-01 01:53:49 -03:00
Francisco Ignácio Fontoura Solla
a862d0c582 feat: Add signature counter and display
Integrate a real-time signature counter component into petition pages.
This includes:

- A new `SignatureCounter` component that displays and animates the
  signature count.
- Server action `getSignatureCount` to fetch current signatures from
  Payload.
- Updates to `submitPetitionSignature` to return the signature number
  for immediate display.
- Event listeners for real-time updates when new signatures are
  submitted.
- Integration of the counter into both the hero section and card views
  of the petition page.
- Improved dialog for displaying signature success and number.
2026-05-01 01:51:07 -03:00
Francisco Ignácio Fontoura Solla
918d6f62a2 add petition success dialog 2026-05-01 01:09:31 -03:00
Francisco Ignácio Fontoura Solla
01779dfd71 fix zip code input field 2026-05-01 00:22:18 -03:00
Francisco Ignácio Fontoura Solla
12cc55b663 petition styles update 2026-04-30 23:32:29 -03:00
Francisco Ignácio Fontoura Solla
aff72f26af Improve FormInput 2026-03-20 17:54:22 -03:00
Francisco Ignácio Fontoura Solla
c72cd6a86e Improve NameInput 2026-03-20 15:44:11 -03:00
Francisco Ignácio Fontoura Solla
e13b55dadb Improve Inputs readability 2026-03-20 12:46:16 -03:00
Francisco Ignácio Fontoura Solla
d3577ceb6a Improve Inputs 2026-03-20 12:36:16 -03:00
Francisco Ignácio Fontoura Solla
fd4266dde6 Improve FormInput readability 2026-03-20 12:20:30 -03:00
Francisco Ignácio Fontoura Solla
1e186e5296 Improve form field behavior, phone formatting 2026-03-20 12:17:16 -03:00
Francisco Ignácio Fontoura Solla
135f456543 Add ThankStep 2026-03-18 23:55:28 -03:00
Francisco Ignácio Fontoura Solla
c8b34613db fix responsiveness 2026-03-18 22:33:51 -03:00
Francisco Solla
046f8a539f fix type isssues 2026-03-15 17:41:24 -03:00
Francisco Solla
a2ad8f7e20 revert changes made to run on cPanel 2026-03-15 15:28:48 -03:00
Francisco Solla
3e2a0003d4 change path to whatsapp 2026-03-15 13:49:22 -03:00
Francisco Solla
f83d914133 prepare for deploy through cPanel 2026-03-15 13:46:44 -03:00
Francisco Ignácio Fontoura Solla
f804da60eb Including page mandato-no-whatsapp 2026-03-14 18:07:40 -03:00
Francisco Ignácio Fontoura Solla
81da3dc0d7 remove autosave from petition collection 2026-03-08 22:56:23 -03:00
Francisco Ignácio Fontoura Solla
5460eeee3c fix: Create petition: Downgraded back to Next 15, removed revalidation on first draft save, chaged reavlidation patter to factory mode to support a revalidation tag per document 2026-03-08 22:53:57 -03:00
Francisco Ignácio Fontoura Solla
4c59c965b0 chore: align Payload package versions and refresh admin import map
- pin @payloadcms/live-preview-react to 3.76.1
- pin @payloadcms/storage-vercel-blob to 3.76.1
- update lockfile accordingly
- regenerate Payload admin import map for Vercel Blob client upload handler
2026-02-23 01:15:43 -03:00
Francisco Ignácio Fontoura Solla
c841d59abe feat: configure Vercel Blob storage for Payload media uploads
- add @payloadcms/storage-vercel-blob dependency
- configure vercelBlobStorage plugin in payload config
- enable Blob-backed storage for media collection using BLOB_READ_WRITE_TOKEN
2026-02-23 01:01:29 -03:00
Francisco Ignácio Fontoura Solla
d8794c6e13 feat: add Vercel telemetry and wrap Payload layout in Suspense
- add @vercel/analytics and @vercel/speed-insights dependencies
- integrate Analytics and SpeedInsights into frontend root layout
- wrap (payload) RootLayout with Suspense to improve admin rendering compatibility
- apply minor formatting cleanup in revalidateGlobal
- update lockfile for dependency changes
2026-02-23 00:21:33 -03:00
Francisco Ignácio Fontoura Solla
dac78163c3 feat: add petition form config and server-action submission flow
- add  group to  collection with title, subtitle, and required consent relationship
- refactor  to:
  - use a dedicated shared zod schema
  - submit via server action (create contact + signature)
  - register RHF fields and handle pending/error states
  - load city options from selected state
- add server action
- add shared schema
- replace state source in  collection: derive select options from
- make  immutable with  and remove obsolete
- update generated payload types for petition  and consent references
2026-02-22 23:08:00 -03:00
Francisco Ignácio Fontoura Solla
14961c5fea feat: overhaul petition UX, add contact/signature data model, and refresh shadcn theming
- redesign petition page layout with responsive hero, content section, and form card
  ()
- refactor frontend theming setup:
  - add  with  in frontend layout
  - migrate/clean global style tokens and base styles in
  - adjust header/social visuals for theme-aware rendering
  (, ,
   , , )
- expand petition form with additional fields and new UI primitives
  (native select, textarea, button, state/city flow)
  (, , , )
- add new Payload collections and wire them into config:
  , ,
  (, ,
   , ,
   )
- update petition collection admin grouping and project config
  (, , )
- add supporting dependency/lockfile updates and workspace tooling tweaks
  (, , , )
2026-02-22 20:02:51 -03:00
Francisco Ignácio Fontoura Solla
8f3bd3845b Migrate from unstable_cache to use cache. And start Petition Form 2026-02-17 22:16:53 -03:00
Francisco Ignácio Fontoura Solla
0e9dcceb83 Update to NextJS 16 2026-02-17 01:56:16 -03:00
Francisco Ignácio Fontoura Solla
205b018bb4 Add petitions page with basic structure and shadcn components 2026-02-17 00:04:22 -03:00
Francisco Ignácio Fontoura Solla
84c7c738c4 feat(petition): add petition collection with live preview and public page
- create  collection with localized admin labels and rich text body
- enable drafts/autosave/scheduled publish and collection-level live preview URL
- register  in
- add frontend route  with static params and enabled check
- add  helper to fetch collection docs for static generation
- regenerate  and admin import map for new collection/editor imports
2026-02-15 23:52:33 -03:00
Francisco Ignácio Fontoura Solla
f26e5d7537 feat(cms): add Payload-driven site metadata global and wire Next.js SEO output
- add new metadata global with URL, title, description, keywords, Open Graph, Twitter, and image fields
- register Metadata global in payload.config.ts
- switch frontend layout to generateMetadata() and load metadata values from Payload globals
- resolve metadata image relation (ID or populated media) for OG/Twitter images
- update live preview globals config to use SiteSettings.slug and HomePage.slug
- keep SiteSettings revalidation hook in consistent position within config
- regenerate payload-types.ts for new global/schema types
2026-02-15 20:14:42 -03:00
Francisco Ignácio Fontoura Solla
b955c48091 feat(cms): add homepage global and wire frontend to Payload content
- add  global () with required media upload field
- register new global in  and include it in admin live preview
- replace hardcoded frontend landing content with CMS-driven homepage image
- add typed cached utilities for globals/documents + centralized revalidation helpers
- migrate components to new global utility module and remove deprecated  helper
- update  revalidation hook to use shared global revalidation
- refine frontend layout/header and simplify legacy homepage CSS
- regenerate  for new global/schema changes
2026-02-15 16:19:57 -03:00
Francisco Ignácio Fontoura Solla
375398af84 feat(live-preview): enable Payload live preview for site settings global
- add  dependency
- configure  in  for
- add  client utility to refresh Next routes on live updates
- mount live preview refresh bridge in frontend layout
- enable drafts/autosave/schedule publish for  global
- regenerate  and update lockfile
2026-02-15 11:13:29 -03:00
Francisco Ignácio Fontoura Solla
56f2d48d8d feat(payload): add pt-BR admin/frontend copy and site settings social links
- add  global and cached global fetch utility
- add , , and  components driven by global settings
- wire global registration in Payload config
- enable Payload admin i18n with Portuguese () language pack
- translate frontend metadata/homepage/custom route copy to pt-BR
- translate collection/global labels, descriptions, and validation messages
- improve social-link a11y with Portuguese fallback labels and external-link icon
- update francisco.solla and  admin labels/groups for Portuguese UX
- regenerate  for new global/schema changes
2026-02-15 01:17:26 -03:00
Francisco Ignácio Fontoura Solla
c3d1e5c717 feat: add Tailwind CSS integration
Install and configure Tailwind CSS v4 for the frontend app, wire PostCSS processing, and add a visible utility-class example to confirm styles are applied.
2026-02-14 16:47:25 -03:00
Francisco Ignácio Fontoura Solla
87ebb726d2 feat: initial commit 2026-02-14 16:11:51 -03:00