Imported from K1w1b1t/hirepair_web (
AGENTS.md). Install upstream withnpx skills add K1w1b1t/hirepair_web. Copyright stays with the author.
AGENTS.md
Source of truth for all AI assistants in this repository (hirepair_web). Precedence over any other instruction when there is a conflict.
1. Stack & Architecture
- Architecture: Monorepo with npm workspaces (
apps/webfor frontend,apps/apifor backend). - Web Frontend (
apps/web): Next.js (App Router) · React 19 · TypeScript · Tailwind CSS v4. - API Backend (
apps/api): NestJS · TypeScript · Express/Node.js. - ORM & Migrations: Prisma 7 with the
@prisma/adapter-pgdriver adapter. - Database & Cache: PostgreSQL 16 & Redis 7 (via Docker Compose locally).
- Managed Postgres: Supabase, consumed only through the connection string.
We do not use the Supabase CLI,
supabase/migrations, or Supabase Auth — authentication is modelled and implemented in this repository.
2. Directory Structure
hirepair_web/
├── apps/
│ ├── web/ # Next.js App Router Frontend
│ │ ├── src/
│ │ │ └── app/ # Next.js App Router routes & pages
│ │ ├── public/ # Static assets
│ │ ├── package.json
│ │ ├── tsconfig.json
│ │ └── next.config.ts
│ └── api/ # NestJS API Backend
│ ├── prisma/
│ │ ├── schema.prisma # Single-file schema (source of truth)
│ │ ├── migrations/ # Prisma-generated; migration_lock.toml committed
│ │ ├── seed.ts # Dev seed entrypoint
│ │ └── seed/ # Composable seed modules
│ ├── src/
│ │ ├── common/filters/ # PrismaExceptionFilter (P2002 → 409)
│ │ ├── config/ # Env validation (class-validator)
│ │ ├── health/ # GET /health/db
│ │ ├── prisma/ # Global PrismaModule + PrismaService
│ │ ├── app.module.ts
│ │ ├── app.controller.ts
│ │ ├── app.service.ts
│ │ └── main.ts
│ ├── prisma.config.ts # Datasource URL + seed registration
│ ├── package.json
│ └── tsconfig.json
├── docs/
│ ├── business/ # Product business rules & methodology docs
│ ├── database/ # Schema, RLS decision, migration & deploy workflow
│ ├── demo/ # Python prototype script
│ └── design/ # Brand manual & static visual prototype
├── .github/
│ └── workflows/
│ ├── ci.yml # Quality, browser E2E and disposable-DB validation
│ └── supabase-migrations.yml # Migrations after merge by environment
├── .husky/ # Git hooks (pre-commit, commit-msg)
├── commitlint.config.js # Conventional commit rules
├── docker-compose.yml # Local Postgres (5434:5432) + Redis (6379:6379)
├── package.json # Workspace root configuration
└── README.md
3. Git Commit & Branch Standards
- Branch Naming Standard:
{issue_number}-{task_title}(e.g.4-task-01-inicializar-monorepo). - Commit Pattern:
type(scope): subject(e.g.feat(4): setup monorepo packages). - Allowed Types:
feat,fix,chore,docs,style,refactor,test,perf. - Mandatory Scope: Scope is required (issue number or feature scope).
3.1 Pull Request Description Standard
Every pull request description must be in Portuguese, use clear Markdown headings, and include only claims verified by the diff and tests. Use this template:
## Objetivo
<problema resolvido e resultado esperado>
## Alterações
- <mudança por domínio/arquivo, com efeito observável>
## Decisões e compatibilidade
- <contratos, configuração, migrações, acessibilidade ou segurança afetados>
## Validação
- [x] `<comando executado>` — <resultado>
- [ ] `<comando não executado>` — <motivo objetivo>
## Risco e rollback
- <risco residual, impacto de deploy e como reverter, ou "Nenhum identificado.">
## Evidências visuais
<screenshots/GIF para alterações de UI; "Não se aplica" quando não houver UI>
- Do not use generic statements such as "tests passed"; name each command and its result.
- Keep lists concise, use links to issues/docs when relevant, and call out required environment-variable or migration steps explicitly.
- For UI work, document accessibility changes and attach before/after evidence when practical.
3.2 Required Domain References
Consult the relevant source before changing its domain and cite it in the PR description when it materially guided the decision:
docs/database/README.md: data model, Prisma migrations, RLS, database validation, and deployment workflow.docs/demo/README.md: changes to the Python demo/prototype or behavior it documents.docs/design/web/README.md: web prototype flows, screens, and frontend interaction decisions.docs/business/proximos-passos-mvp.md: MVP scope, product priorities, and business-rule decisions.docs/design/Hirepair_Brand_Manual.html: brand, visual language, copy tone, logo use, and accessibility decisions involving the identity.docs/backend/operational-foundation.md: API operational configuration, CORS, rate limiting, observability, and deployment safeguards.
4. Local Environment Setup
- Configure:
cp .env.example .env(defaults already work locally). - Start Infrastructure:
npm run db:up(launches Postgres on port5434and Redis on port6379). - Apply Migrations:
npm run db:migrate, thennpm run db:seedfor sample data. - Start Web:
npm run dev:web(runs Next.js onhttp://localhost:3000). - Start API:
npm run dev:api(runs NestJS onhttp://localhost:3001). - Run Format:
npm run format(writes) — CI checks it withnpm run format:check.
5. Deployment Environments
- Production: branch
master, served from the production domain. It is indexable by search engines. - Staging: branch
release, served publicly athttps://stg.hirepair.com.br. It exists for sharing demos with people who do not have a Vercel account; do not enable access/password protection for it. - Staging must never be indexed: set
SEARCH_INDEXING_ENABLED=falsein the Vercel environment variables scoped to thereleasebranch, and make the Next.js metadata emitnoindex, nofollowwhen that variable is false. Do not rely only onrobots.txt, and do not add staging URLs to a sitemap or Google Search Console. - The Vercel frontend receives only
NEXT_PUBLIC_API_URLandNEXT_PUBLIC_SITE_URL. KeepDATABASE_URL,DIRECT_URL, andREDIS_URLexclusively in the API host and GitHub Environment secrets. - Vercel uses two projects for this monorepo:
hirepair-web-webhas Root Directoryapps/web, whilehirepair-web-apihas Root Directoryapps/api. Keep the Next.jsvercel.jsoninsideapps/web; never add one to the repository root, because it would also configure the NestJS deployment. The API relies on Vercel's native NestJS detection and must not define a.nextOutput Directory. - GitHub Environments for database migrations are
ProductionformasterandStagingforrelease. Each holds its ownSUPABASE_DB_URLsecret pointing to that environment's direct database connection.
6. Database & Prisma Migrations
Full reference: docs/database/README.md.
- Never handcraft migrations as the main workflow. Always generate them:
npm run db:migrate # prisma migrate dev
- After a schema change, keep these three consistent:
apps/api/prisma/schema.prismaapps/api/prisma/migrations/*- the code that consumes Prisma Client
- Never edit an already-applied migration — the checksum changes and Prisma reports it as modified from then on. Add a new migration instead.
- For SQL the Prisma DSL cannot express (RLS, grants, triggers, functions,
partial indexes):
npx prisma migrate dev --create-only, then append the manual SQL below the generated diff with a comment explaining why. - Row Level Security is enabled on every table, with no policies (deny-all).
It is not the authorization mechanism — that lives in the NestJS layer — but
Supabase publishes the whole
publicschema through its Data API, so a table without RLS is readable with the project's anon key. A new model with noENABLE ROW LEVEL SECURITYline failsapps/api/src/prisma/schema-rls.spec.ts. npm run db:resetdestroys all data. Development databases only.- Ownership is enforced in application code, so every read must filter by the
acting user; soft-deleted rows (
deletedAt) must be filtered explicitly.
7. Mandatory Quality Gate
All five commands must pass before delivering any change (same gate declared in
.codex/instructions.md):
npm run lint
npm run format:check
npm run typecheck
npm run test
npm run build
No shortcuts to force a green pipeline: no skip, only, --no-verify, ad hoc
disabled lint rules or commented-out tests.
7.1 Test-Driven Development and Test Strategy
Every behavior change follows strict TDD:
- Write the smallest unit test that describes the intended behavior.
- Run that test alone and confirm it fails for the expected missing behavior — a failure caused by a typo, broken import, or invalid fixture is not evidence.
- Implement only what makes the test pass.
- Refactor while the test remains green, then run the relevant suite.
Unit tests are the primary proof of correctness. All new or changed production code must have 100% unit coverage of statements, branches, functions, and lines. Existing uncovered code is technical debt: do not lower the baseline, and cover it when touching the behavior; a dedicated coverage task must eliminate the remaining legacy gap before a repository-wide 100% threshold is enabled.
E2E tests verify only the main user journeys and system boundaries:
- Frontend browser flows use Playwright under
apps/web/e2e/and are excluded from Jest discovery. - Backend E2E flows, when introduced, must exercise real HTTP contracts and disposable infrastructure; business rules remain covered by unit tests.
- Do not duplicate unit-level permutations in E2E. Keep E2E scenarios focused on critical happy paths and their essential failure/authorization boundaries.
Never use skip, only, weakened coverage thresholds, mocks that bypass the
behavior under test, or commented-out tests to make a pipeline pass.
These five need no database — npm ci runs prisma generate via the postinstall
of apps/api, so Prisma Client types exist without a live connection. CI adds
three database steps on top, against a throwaway Postgres (never Supabase):
db:deploy on an empty database, a schema drift check, and db:seed run twice
to prove idempotency. When you change the schema, run these locally too:
npm run db:up && npm run db:migrate && npm run db:seed && npm run db:seed
8. Analytics e telemetria PostHog
- Todo evento inclui app=hirepair, environment e telemetry_source; nunca envie PII, curriculo, prompt, respostas, corpo, headers, query strings ou tokens.
- Analytics, Error Tracking e Session Replay do navegador exigem consentimento explicito. A revogacao interrompe a coleta. Preserve maskAllInputs=true, maskTextSelector=* e a remocao de query strings.
- A telemetria operacional anonima do servidor independe do consentimento e permanece fail-open.
- A taxonomia e session_started, facts_confirmed, resume_generated, whatsapp_shared e ai_fallback_triggered. Os quatro eventos do funil compartilham funnel_session_id.
- session_started pertence a entrada real em /conversa. Os hooks futuros ficam na confirmacao efetiva dos fatos, no sucesso da geracao do curriculo e na confirmacao do compartilhamento por WhatsApp; nao emita acoes artificiais.
- Valide em staging a separacao por app/ambiente, ausencia de coleta antes do opt-in, replay mascarado, source maps e destinos Discord conforme docs/analytics/posthog-runbook.md.
Uso no codigo
- Importe
captureAnalyticsEventdeapps/web/src/analytics/analytics.tssomente em uma transicao de negocio concluida. Eventos do funil:session_startedao entrar de verdade em/conversa;facts_confirmedao confirmar fatos;resume_generatedquando a geracao termina com sucesso;whatsapp_sharedquando o compartilhamento e confirmado. Todos carregam o mesmofunnel_session_id. - Nao emita eventos para placeholders, renderizacao, cliques antes de sucesso, validacao ou tentativas falhas. Os tres eventos futuros continuam proibidos enquanto os respectivos passos nao existirem no produto.
- Eventos automaticos usam as propriedades registradas no SDK. Para eventos manuais, nao acrescente PII nem propriedades livres; o helper fornece
app=hirepair,environmentetelemetry_source=browser. - Replay e sampling sao configurados no dashboard do projeto compartilhado: trigger group de 10% geral consentido e outro de 100% quando ocorre
$exception. - Preview/release usa
NEXT_PUBLIC_APP_ENV=staginge Production/master usaNEXT_PUBLIC_APP_ENV=production; consulte o runbook para a matriz Vercel e nunca ponha tokens em Actions ou codigo.