White-label civic engagement platform (All Rights Reserved)
Find a file
Francisco Solla 01be1de7be feat(C176): página pública do corte — revisão de design (Closes #1086)
Corrige o fundo tintado (gradiente do body herdado de :root) com um
layout de segmento `data-theme="editorial"` + scroll interno, espelhando
`[type]/layout.tsx`, e porta o gate aprovado: vídeo herói, título à
esquerda, meta em relógio, prosa medida, kit WhatsApp-first responsivo,
secundárias em grade no mobile e estado indisponível redesenhado.

Extrai os botões do share kit no próprio dono (acervo/biblioteca
inalterados) e adiciona o guard e2e `data-theme="editorial"`.
2026-09-16 12:36:55 -03:00
.agents chore(OPS121): verificação pós-deploy em staging no fluxo work-issue (Closes #1079) 2026-09-16 11:53:54 -03:00
.codex chore(agents): reorganiza árvore de skills — .claude/.cursor → .agents 2026-08-03 21:24:11 -03:00
.cursor ops(OPS52): migra a media de produção do Vercel Blob para o Garage S3 2026-08-17 22:36:34 -03:00
.forgejo feat(OPS71): Fase 2 — remover arquivos do fluxo Forgejo (workflows/scripts/specs) pós-validação do GitHub Actions 2026-08-20 00:20:10 +00:00
.github fix(OPS111): setup-node 24 antes do pnpm/action-setup no auto-unblock (Closes #1035) 2026-09-15 16:02:29 -03:00
.husky feat(ops): auto-promote stage→main e merge em stage sem exigir head (#68) 2026-07-30 21:12:52 -03:00
.impeccable docs(B124): format intention plan and critique with Prettier 2026-08-02 15:16:23 -03:00
.opencode chore(OPS123): escopo de dispatch do designer frontier — só design de fato (Closes #1091) 2026-09-16 11:10:44 -03:00
.vscode feat: initial commit 2026-02-14 16:11:51 -03:00
.zed Tooling: prettier como autoridade de formatacao (organize-imports deterministico, scripts format/format:check, normalizacao mecanica de 312 arquivos; artefatos gerados e migrations excluidos via .prettierignore) 2026-07-25 17:22:20 -03:00
docker/postgres/init Isolate local/dev and tests from the production database 2026-07-15 13:52:30 -03:00
docs feat(C176): página pública do corte — revisão de design (Closes #1086) 2026-09-16 12:36:55 -03:00
private chore: public release tip — All Rights Reserved, sanitize field material 2026-07-31 12:53:12 -03:00
public feat(S13): cards personalizados da campanha no site público 2026-09-12 03:25:43 -03:00
scripts chore(OPS119++): blast radius de scripts/ — risk map das libs + static scope (Closes #1077) 2026-09-16 12:12:37 -03:00
src feat(C176): página pública do corte — revisão de design (Closes #1086) 2026-09-16 12:36:55 -03:00
tests feat(C176): página pública do corte — revisão de design (Closes #1086) 2026-09-16 12:36:55 -03:00
.cursorignore docs: agent ops + slice AGENTS.md + kernels + cursorignore + portable hooks + cloud env + PR template 2026-07-30 05:21:35 -03:00
.dockerignore chore(deploy): prepara imagem standalone para homeserver 2026-08-16 01:52:11 -03:00
.env.example feat(C167): corta o trecho [início,fim] do acervo e publica o arquivo numa página compartilhável 2026-09-15 10:24:36 -03:00
.env.test ops(OPS52): migra a media de produção do Vercel Blob para o Garage S3 2026-08-17 22:36:34 -03:00
.gitignore feat(C163): relatório de cidade pré-viagem (agente + skill → PDF A4) (Closes #1007) 2026-09-15 07:10:45 -03:00
.npmrc fix issues to run from cPanel 2026-03-15 14:03:28 -03:00
.nvmrc chore: pin Node to 24.x (CI, Vercel, engines) 2026-07-31 23:47:49 -03:00
.prettierignore feat(ops96): protocolo completo na SKILL.md + ignores do artefato coverage 2026-08-25 02:42:40 -03:00
.prettierrc.json Tooling: prettier como autoridade de formatacao (organize-imports deterministico, scripts format/format:check, normalizacao mecanica de 312 arquivos; artefatos gerados e migrations excluidos via .prettierignore) 2026-07-25 17:22:20 -03:00
.yarnrc feat: initial commit 2026-02-14 16:11:51 -03:00
AGENTS-campaign.md chore: reduce token overhead in agent workflow 2026-08-21 20:38:56 -03:00
AGENTS-infra.md feat(OPS110): sessões persistentes de agente com attach/detach (Closes #1019) 2026-09-15 09:31:45 -03:00
AGENTS-public.md chore: reduce token overhead in agent workflow 2026-08-21 20:38:56 -03:00
AGENTS.md chore(OPS123): reserva o provider openai aos agentes de design (Closes #1091) 2026-09-16 11:10:44 -03:00
components.json Including page mandato-no-whatsapp 2026-03-14 18:07:40 -03:00
DESIGN.md simplify(B13): corrige classe agregada, bolhas em pane proprio e registra debitos 2026-07-26 05:12:37 -03:00
docker-compose.yml feat(worktree): ambientes isolados por worktree — porta própria, bancos próprios, migrations no provision 2026-08-08 11:33:07 -03:00
Dockerfile feat(C167): corta o trecho [início,fim] do acervo e publica o arquivo numa página compartilhável 2026-09-15 10:24:36 -03:00
eslint-legacy-ignores.mjs test(ops96-audit): mover 4 specs puros de int para unit (relationship, schemaPrimitives, assertTestDatabase, petition-page-layout) 2026-08-25 02:42:40 -03:00
eslint-local-rules.mjs Add ESLint guard for invalid use server exports and fix plaza staff messages. 2026-07-21 20:07:06 -03:00
eslint.config.mjs fix(e2e): B196 atividades deriva a data da fixture de hoje — desbloqueia deploy verify 2026-09-12 02:17:13 -03:00
knip.json feat(C167): corta o trecho [início,fim] do acervo e publica o arquivo numa página compartilhável 2026-09-15 10:24:36 -03:00
LICENSE chore: public release tip — All Rights Reserved, sanitize field material 2026-07-31 12:53:12 -03:00
next.config.mjs fix(social-feed): capas do Instagram voltam a carregar e legendas longas não esticam o card 2026-09-11 18:09:03 -03:00
opencode.json chore(OPS92): consolidar MCPs — global só jina+playwright; penpot/postgres subagentes; gh CLI; re-homed (Closes #857) 2026-08-24 17:18:53 -03:00
package.json feat(OPS109): painel de issues e planos no terminal (via SSH) 2026-09-15 16:24:15 -03:00
playwright.config.ts feat(campaign): C149 — botão Conectar com o Google (OAuth) substitui a configuração manual da service account (Closes #934) 2026-09-12 19:49:24 -03:00
pnpm-lock.yaml fix(deploy): override sharp@0.32.6 → 0.34.2 — instalação do deps sem download do libvips 2026-08-27 09:55:50 -03:00
pnpm-workspace.yaml fix(deploy): override sharp@0.32.6 → 0.34.2 — instalação do deps sem download do libvips 2026-08-27 09:55:50 -03:00
postcss.config.mjs Migrate from unstable_cache to use cache. And start Petition Form 2026-02-17 22:16:53 -03:00
PRODUCT.md B34: editable município chips on the leaderships list. 2026-07-27 22:35:19 -03:00
README.md fix(OPS107): aprovação de produção não ocupa a lane do staging (Closes #1002) 2026-09-14 08:18:21 -03:00
skills-lock.json Add addyosmani agent skills and wire plan-issue to them 2026-08-02 13:28:58 -03:00
tailwind.config.ts feat: add Tailwind CSS integration 2026-02-14 16:47:25 -03:00
test.env feat: initial commit 2026-02-14 16:11:51 -03:00
tsconfig.json fix(ci): isola bundle e2e do servidor de desenvolvimento 2026-08-16 01:25:06 -03:00
vitest.config.mts test(int): retry once — gate flaka sob contenção paralela de DB em high-core (C113/C115) 2026-08-25 08:52:07 -03:00
vitest.setup.ts feat(worktree): ambientes isolados por worktree — porta própria, bancos próprios, migrations no provision 2026-08-08 11:33:07 -03:00
vitest.unit.config.mts Engineering Pass 3: consolidate patterns and lock them with guards. 2026-07-29 06:11:29 -03:00

Teqo

License: proprietary — All Rights Reserved (© Francisco Ignácio Fontoura Solla). Portfolio / demonstration only. Not open source. Use, copy, or redistribution requires prior written permission (fsolla@pm.me). See LICENSE.

Sensitive field material belongs in /private/ on local checkouts (gitignored). Cloud agents: use public-clean docs; report sensitive deliverables in chat — do not commit them.

Cheatsheet de operação agentic (humanos) — o fluxo em 5 linhas:

  1. O agente roda pnpm agent:claim (ou pnpm worktree next --issue N) e pega a próxima Issue ready por prioridade (prio:P0..P3). O tracker de Issues, o código, os PRs e o CI vivem no GitHub (github.com/fsolla/teqo).
  2. Ele implementa, roda o fast gate (lint + typecheck + unit) e pnpm push -u origin HEAD — abre a PR para main (Ready, Closes #N).
  3. CI verde (CI (PR) / checks) → o safety net agent-pr-ready-automerge.yml arma o auto-merge nativo (rebase) — o servidor só mergea com o required check verde.
  4. Deploy começa automático: o merge em main dispara o deploy.yml (suíte full no verify) → staging publica sozinho → produção só com o approve do reviewer no environment production (jorgesolla1313.com.br, runner self-hosted) — migrações aplicadas antes do rollout; o staging velho se atualiza via requeue (OPS104); desde a OPS107 o approval pendente não segura o staging nem a aprovação de runs novos — aprove só o run escolhido e rejeite os demais. workflow_dispatch segue como escape manual.
  5. Secrets humanos (uma vez): GITHUB_TOKEN (PAT com escopo repo + issues: write) para os scripts de agente/PR (pnpm issue/agent:*, github-pr.mjs); envs de prod em ~/stack/teqo-1313.env no homeserver. Branch protection de main já aplicada (reaplicar: pnpm configure:branch-protection).

Comandos: pnpm agent:claim | agent:register | agent:prioritize | agent:file-miss | worktree next e pnpm db:seed:minimal. Labels: estado ready|in-progress|blocked|done|in-prod, prio:P0..P3, kind:*, needs:migration|consent, requirements-changed. Agente faz sozinho: claim → implementar → PR → main (o merge já inicia o deploy de staging). Só humano: aprovar a produção no environment do run (desde a OPS107, só o run escolhido — rejeite os demais), envs do homeserver, branch protection, runbook de rollback. Tudo em detalhe: docs/AGENT-OPS.md · CI: .github/workflows/ci-pr.yml · Deploy: .github/workflows/deploy.yml.

Teqo starts as the official digital platform for deputado Jorge Solla and evolves into a white-label civic engagement platform for politicians in Brazil.

The goal is to help political teams build direct, durable relationships with their base without depending on Big Tech social platforms as the primary channel.

Mission

  • Strengthen direct communication between representatives and citizens.
  • Reduce platform dependency risk by owning audience and data channels.
  • Provide reusable building blocks so each political team can launch quickly.

Product Direction

Phase 1: Jorge Solla Website

Initial delivery focuses on Jorge Solla's public website, editorial CMS, and the internal /campanha tool:

  • Public-facing content and updates (news/post + tag live)
  • Institutional pages and biography (still pending a Pages collection)
  • Internal campaign operations: municípios (435, pré-definidos), leaderships, estimates, updates, WhatsApp invites
  • Editorial operations through Payload CMS

Phase 2: White-Label Platform

Teqo then becomes a configurable base product for other politicians in Brazil:

  • Multi-tenant and reusable architecture
  • Brand and content customization per mandate/campaign
  • Shared core modules for communication and engagement
  • Operational autonomy with self-hosted owned channels

Local Development

Production safety: the production database is a live Postgres on the homeserver (teqo_1313) holding real citizens' data. Local development and tests run against a local Postgres and must never point at production. pnpm dev refuses to start against a non-local database, and the test suite refuses any database whose name doesn't end in _test.

First-time setup

  1. Install dependencies: pnpm install
  2. Create your env file: cp .env.example .env.local
  3. Start Docker, then start the local database: pnpm db:start
    • This runs Postgres 17 (matching production) and auto-creates a teqo_test database for the test suite.
  4. Make sure DATABASE_URL in .env.local points at local:
    DATABASE_URL=postgresql://teqo:teqo@localhost:5432/teqo
    
  5. Load a schema + content into the local database — pick one:
    • Mirror production content (recommended): PROD_DATABASE_URL="<prod connection string>" pnpm db:pull Copies production's schema and content into local. It only reads production and excludes supporter PII (contact/signature/subscription data). The prod string is the DATABASE_URL of ~/stack/teqo-1313.env on the homeserver (Postgres teqo_1313).
    • Empty schema from migrations: pnpm migrate
  6. Start the dev server: pnpm dev
  7. Open: http://localhost:3000

Useful scripts: pnpm db:start / pnpm db:stop (local Postgres — always the same shared container via -p teqo, from any directory), pnpm db:pull (refresh local content from prod), pnpm db:seed:posts (import news posts/tags fresh from the live jorgesolla.com.br site into the local db; idempotent by slug, refuses a non-local database), pnpm db:seed:tse (import TSE 2014/2018/2022 Bahia election results into the local db; idempotent per year/office/turn scope, refuses a non-local database), pnpm build:election-aggregates (regenerate the committed TSE aggregate artifact in src/lib/electionAggregates/ from locally seeded data).

Parallel worktrees get isolated environments: pnpm worktree next derives a per-branch dev port (3100+slot) and its own databases (teqo_wt<slot> / teqo_wt<slot>_test), so agents never fight over port 3000 or the shared teqo_test. See .agents/skills/local-database.

Content & cache revalidation

Public news pages (/[type], /[type]/[category], articles, and the home news list) are cached under a shared posts tag. Editing a post or tag in the deployed admin self-revalidates via afterChange hooks. Any write that bypasses the deployed runtime — a direct-DB seed (pnpm db:seed:posts), SQL, Onda 0 migrations, or a restore — does not bust production's cache, so afterwards call the secured endpoint:

# News (default tag: posts)
curl -X POST "https://<prod-domain>/api/revalidate" -H "x-revalidate-secret: $REVALIDATE_SECRET"

# Privacy policy after Onda 0 provision (tag: global_privacy-policy)
curl -X POST "https://<prod-domain>/api/revalidate?tag=global_privacy-policy" -H "x-revalidate-secret: $REVALIDATE_SECRET"

REVALIDATE_SECRET must be set in the production env (~/stack/teqo-1313.env on the homeserver — see .env.example). See the "Posts & Tags" section of AGENTS.md for the full model.

Database migrations

Schema is managed by committed Payload migrations (src/migrations/); push is disabled everywhere.

To change the schema:

  1. Edit the collection/global/field config.
  2. Generate a migration: pnpm migrate:create <name>
  3. Review and commit the generated files in src/migrations/ (both .ts and .json, plus index.ts).
  4. Apply it locally: pnpm migrate (check status anytime with pnpm migrate:status).

Deploying to production: merges to main trigger deploy.yml automatically (OPS104) — the verify job runs the full suite, deploy-staging publishes on its own, and deploy-production waits for the production environment approval (OPS107: the pending approval no longer holds the shared deploy lane, so later runs still stage and stay approvable — approve only the chosen run and reject the rest). The remote script (scripts/deploy-homeserver.sh) builds on the homeserver and applies pending migrations through the compose maintenance service teqo-1313-migrate before the rollout. Do not run migrations against production by hand. Runbook (rollback, known failures): docs/ops/teqo-1313-deploy.md.

Running tests

Tests use the isolated teqo_test database (config in .env.test). Prepare its schema once with:

DATABASE_URL=postgresql://teqo:teqo@localhost:5432/teqo_test pnpm migrate

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

Quality gates (also enforced by CI on GitHub Actions — ci-pr.yml): pnpm lint (zero warnings — --max-warnings=0), pnpm typecheck, and pnpm exec knip (dead files/dependencies fail; delete what your change orphaned). Standards: .agents/rules/engineering-standards.mdc.

Tech Stack

  • Payload CMS
  • Next.js
  • PostgreSQL (via @payloadcms/db-postgres)
  • TypeScript

Campaign (/campanha)

Internal campaign tool for municípios (435 pré-definidos), local leaderships, vote estimates, field updates, and WhatsApp invites. Authenticated separately from /admin via the campaignUser collection (coordinator / advisor / leader / candidate). Operational status and decisions: .agents/rules/projects/nucleos-eleitorais.mdc. Conventions and deploy checklist: AGENTS.md (“Campaign auth” / “Campaign Municípios model”).

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 as tracked GitHub Issues (spec + deps + prio + model per issue; flow skills: plan-issue → work-issue → project-status; docs/roadmap.md is a frozen legacy stub).