⚠
Estas regras são inegociáveis. Nenhum prazo, feature ou circunstância justifica violá-las.
Os 7 Mandamentos
Mandamento #1
Zero Hardcode
Nenhum valor literal no código que possa mudar entre ambientes, contextos ou tempo. URLs, tokens, strings de UI, cores, timeouts, limites, mensagens de erro, configurações de terceiros — tudo é variável de ambiente ou token do Design System.
Mandamento #2
Design System é Lei
Toda UI segue design.lzrtechnologies.com. Cores, tipografia, espaçamentos, componentes — tudo vem dos tokens do DS. Zero CSS "avulso" ou valores mágicos.
Mandamento #3
Segurança by Default
Na dúvida, escolha o caminho mais seguro. Default-deny em rotas, dados criptografados at rest, secrets em vaults, RBAC desde o dia 1. Segurança nunca é "próxima sprint".
Mandamento #4
Banco em Inglês Internacional
Todos os campos, tabelas e enums do banco de dados são em inglês, snake_case. Tabelas no plural. created_at sim, criado_em não. Migrations com número sequencial: 001_create_users.sql.
Mandamento #5
Português Primeiro na UI
PT-BR é a língua base da interface. Toda string visível ao usuário vem de arquivo de tradução (i18n). Internacionalização vem depois, mas a arquitetura está pronta desde o início.
Mandamento #6
Documentar Decisões
Se não tem ADR, não foi decidido. Toda decisão arquitetural relevante é registrada em docs/adrs/ com contexto, alternativas consideradas e consequências.
Mandamento #7
Libs Aprovadas
Não adicionar dependências sem verificar licença e aprovação. Manter lista de libs aprovadas por categoria. Licenças MIT/Apache OK. GPL requer avaliação jurídica.
Princípio vs Decisão de Stack
Separamos o que é permanente do que pode mudar com a tecnologia.
| Tipo | Exemplo | Onde vive | Pode mudar? |
| Princípio | Zero hardcode, segurança by default | Seção 00 | Nunca |
| Padrão técnico | Cursor pagination, RFC 9457 | Seções 01-14 | Raramente (com ADR) |
| Decisão de stack | Supabase, Next.js, timeout de 10s | Stack Playbooks | Sim (com ADR) |
⚠
Regra #1: Nunca commite secrets (API keys, senhas, tokens) no repositório. Use vaults ou variáveis de ambiente.
OWASP Top 10 — Checklist Obrigatório OWASP 2025
Cada item deve ser verificado antes de qualquer PR que toque autenticação, pagamentos ou acesso a dados.
- Broken Access Control — RBAC implementado, princípio do menor privilégio, default-deny em todas as rotas
- Injection Prevention — Queries parametrizadas sempre. Zero concatenação de strings em SQL/NoSQL
- Cryptographic Failures — TLS em toda comunicação, dados sensíveis criptografados at rest, bcrypt/argon2 para senhas
- Security Misconfiguration — Headers de segurança (CSP, HSTS, X-Frame-Options), defaults seguros, features não usadas desabilitadas
- Vulnerable Components — Dependabot/Snyk ativo, lock files commitados, SBOMs gerados
- Auth & Session — MFA disponível, tokens com expiração, refresh token rotation
- SSRF Prevention — Validar e sanitizar todas as URLs recebidas de usuários
- Logging de Segurança — Log de tentativas de auth, acessos negados, mudanças de permissão
Secrets Management
# ERRADO - nunca faça isso
API_KEY=sk-1234567890 # hardcoded no código
# CERTO - use variáveis de ambiente
const apiKey = process.env.API_KEY
# MELHOR - use um vault
const apiKey = await vault.getSecret('api-key')
Headers de Segurança Obrigatórios
| Header | Valor | Propósito |
Strict-Transport-Security | max-age=31536000; includeSubDomains | Força HTTPS |
Content-Security-Policy | default-src 'self' | Previne XSS |
X-Content-Type-Options | nosniff | Previne MIME sniffing |
X-Frame-Options | DENY | Previne clickjacking |
Referrer-Policy | strict-origin-when-cross-origin | Controla vazamento de URL |
Incident Response
Passo 1
Detectar
Alertas automáticos via observabilidade. On-call notificado em <5min.
Passo 2
Conter
Rotacionar secrets comprometidos. Isolar serviço afetado. Bloquear acesso.
Passo 3
Comunicar
Notificar usuários afetados. Postmortem blameless em 48h. Documentar aprendizados.
SLA de Correção por Severidade
| Severidade | SLA de Correção | Exemplo |
| Crítica (P0) | 4 horas | SQL injection, data breach, auth bypass |
| Alta (P1) | 24 horas | XSS, CSRF, escalação de privilégio |
| Média (P2) | 7 dias | Headers faltando, dependency vuln (CVSS 4-6) |
| Baixa (P3) | 30 dias | Informational, best practice não seguida |
Rotação de Secrets
| Tipo | Rotação | Automação |
| API Keys de terceiros | 90 dias | Alerta automático 7 dias antes |
| Database credentials | 90 dias | Rotação automática via vault |
| JWT signing keys | 180 dias | Key rotation com overlap de 24h |
| Service tokens | 30 dias | Automático via CI/CD |
Threat Modeling
Toda feature que toca autenticação, pagamentos ou dados sensíveis passa por threat modeling antes do desenvolvimento.
Passo 1
Identificar ativos
O que estamos protegendo? Dados pessoais, credenciais, documentos?
Passo 2
Mapear ameaças (STRIDE)
Spoofing, Tampering, Repudiation, Information Disclosure, DoS, Elevation of Privilege.
Passo 3
Avaliar risco
Probabilidade × Impacto. Priorizar mitigações.
Passo 4
Documentar
Registrar no ADR da feature. Listar mitigações implementadas.
Checklist de Segurança por Tipo de Mudança
| Tipo de PR | Verificações obrigatórias |
| Auth/Login | Threat model, rate limiting, brute force protection, session management |
| API endpoint novo | RBAC, input validation, rate limiting, error format RFC 9457 |
| Pagamento | Threat model, PCI compliance check, idempotency, audit log |
| Upload de arquivo | Validação de tipo/tamanho, scan de malware, storage isolado |
| Dependência nova | Licença verificada, CVE scan, size impact, alternativas avaliadas |
⚠LGPD: Multas de até 2% do faturamento (max R$50M por infração). A ANPD já está fiscalizando ativamente.
Privacy by Design — 7 Princípios ISO 31700
- Proativo, não reativo — Privacidade pensada desde o design, não como patch
- Privacidade como padrão — Dados protegidos por default, sem exigir ação do usuário
- Privacidade no design — Integrada na arquitetura, não adicionada depois
- Funcionalidade total — Sem trade-off privacidade vs funcionalidade
- Segurança fim-a-fim — Proteção durante todo o ciclo de vida do dado
- Transparência — Usuário sabe o que é coletado, por quê e por quanto tempo
- Respeito ao usuário — Usuário no controle dos seus dados
Direitos do Titular (LGPD Art. 18)
Todo produto LZR deve implementar endpoints ou interfaces para estes direitos:
Acesso
O usuário pode solicitar todos os dados que temos sobre ele. Endpoint GET /me/data
Correção
O usuário pode corrigir dados incorretos. Endpoint PATCH /me/data
Exclusão
O usuário pode pedir para apagar seus dados. Endpoint DELETE /me/data (hard delete ou anonimização)
Portabilidade
O usuário pode exportar seus dados em formato aberto. Endpoint GET /me/export (JSON/CSV)
Data Mapping Obrigatório
| Dado | Base Legal | Retenção | Acesso |
| Email/nome do usuário | Execução de contrato | Enquanto conta ativa + 6 meses | Backend + Supabase |
| Documentos de licitação | Execução de contrato | 5 anos (obrigação legal) | Storage criptografado |
| Logs de acesso | Interesse legítimo | 12 meses | Observabilidade |
| Analytics de uso | Consentimento | 24 meses | Anonimizado |
Matriz de Classificação de Dados
| Classificação | Exemplos | Controles obrigatórios |
| Restrito | Senhas, tokens, chaves de API, dados de cartão | Criptografia at rest + in transit, vault, zero logs, acesso mínimo |
| Confidencial | CPF, CNPJ, dados de licitação, contratos | Criptografia at rest, RLS, mascaramento em logs, audit trail |
| Interno | Email, nome, telefone, endereço comercial | RLS, acesso por role, mascaramento parcial em logs |
| Público | Nome da empresa, dados de edital público | Integridade garantida, cache permitido |
Conventional Commits Obrigatório
feat: adiciona dashboard de licitações
fix: corrige timeout na consulta PNCP
docs: atualiza README com instruções de setup
refactor: extrai lógica de validação para utils
test: adiciona testes para fluxo de auth
chore: atualiza dependências do projeto
security: corrige SQL injection no endpoint de busca
Branch Strategy
main # produção - protegida, só via PR
develop # integração - PRs mergeados aqui primeiro
feat/xxx # features novas
fix/xxx # bug fixes
hotfix/xxx # fix urgente direto para main
Code Review Checklist
- PR tem descrição clara do que mudou e por quê
- Testes adicionados ou atualizados para a mudança
- Sem secrets, tokens ou dados sensíveis no diff
- Sem console.log ou debuggers esquecidos
- Queries SQL parametrizadas (sem concatenação)
- Error handling adequado (sem catch vazio)
- Tipos definidos (sem
any em TypeScript)
- Performance: sem N+1 queries, sem loops desnecessários
Definition of Done
Código
Linter passa, tipos corretos, sem warnings
Testes
Unit + integration cobrem o fluxo
Review
Mínimo 1 reviewer aprovou
Docs
ADR se decisão arquitetural, changelog atualizado
Naming Convention OpenAPI 3.1
# Recursos no plural, substantivos, hierárquicos
GET /api/v1/companies # listar
POST /api/v1/companies # criar
GET /api/v1/companies/:id # detalhe
PATCH /api/v1/companies/:id # atualizar parcial
DELETE /api/v1/companies/:id # remover
GET /api/v1/companies/:id/bids # sub-recurso
Error Response Format RFC 9457
{
"type": "https://api.lzr.com/errors/validation",
"title": "Validation Error",
"status": 422,
"detail": "O campo 'cnpj' deve ter 14 dígitos.",
"instance": "/api/v1/companies",
"trace_id": "abc-123-def-456"
}
Paginação — Cursor-based (preferido)
GET /api/v1/bids?limit=20&cursor=eyJpZCI6MTAwfQ
// Response
{
"data": [...],
"meta": {
"next_cursor": "eyJpZCI6MTIwfQ",
"has_more": true
}
}
Rate Limiting
| Plano | Limite | Headers |
| Free | 100 req/min | X-RateLimit-Limit: 100 |
| Pro | 1000 req/min | X-RateLimit-Remaining: 842 |
| Enterprise | Custom | Retry-After: 30 |
Migrations Obrigatório
- Toda mudança de schema via migration versionada (nunca SQL manual em produção)
- Migrations são imutáveis — nunca editar uma migration já aplicada
- Backward-compatible: expand-and-contract para breaking changes
- Migrations rodam automaticamente no pipeline de deploy
- Testar rollback de toda migration antes de aplicar em produção
Multi-tenant Isolation
-- Todas as tabelas de dados de cliente TÊM que ter tenant_id
CREATE TABLE bids (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
tenant_id UUID NOT NULL REFERENCES companies(id),
title TEXT NOT NULL,
created_at TIMESTAMPTZ DEFAULT now()
);
-- RLS (Row Level Security) obrigatório no Supabase
ALTER TABLE bids ENABLE ROW LEVEL SECURITY;
CREATE POLICY "tenant_isolation" ON bids
USING (tenant_id = auth.jwt() ->> 'company_id');
Performance Checklist
Indexação
Index em toda FK, em colunas usadas em WHERE/ORDER BY. Revisar slow query log semanalmente.
N+1 Prevention
Usar eager loading / joins. Nunca fazer query dentro de loop.
Connection Pooling
PgBouncer ou Supabase pooler. Max connections definido por ambiente.
Backups
Diário automático. Point-in-time recovery habilitado. Testar restore trimestral.
Naming Conventions Obrigatório
⚠
Regra inviolável: Todos os nomes de tabelas, colunas e enums são em inglês internacional, snake_case. Sem exceção.
| Elemento | Convenção | Correto ✓ | Errado ✗ |
| Tabelas | Plural, snake_case | users, bid_documents | usuario, BidDocument |
| Colunas | Singular, snake_case | created_at, tenant_id | criado_em, tenantId |
| PKs | Sempre id | id UUID | user_id como PK |
| FKs | {tabela_singular}_id | company_id | fk_company, empresa_id |
| Booleans | Prefixo is_ ou has_ | is_active, has_mfa | ativo, active |
| Timestamps | Sufixo _at | created_at, deleted_at | creation_date |
| Enums | UPPER_SNAKE_CASE | STATUS_ACTIVE | active, Ativo |
Migrations — Nomenclatura Sequencial Obrigatório
# Formato: NNN_descricao_em_snake_case.sql
001_create_users.sql
002_create_companies.sql
003_create_bids.sql
004_add_tenant_id_to_bids.sql
005_create_bid_documents.sql
006_add_index_bids_tenant_id.sql
# Regras:
# - Número sequencial com 3 dígitos (001, 002...)
# - Descrição em inglês, snake_case
# - Verbo no imperativo: create, add, remove, update, drop
# - Uma migration = uma mudança lógica
# - Nunca editar uma migration já aplicada
Pipeline Stages DORA Metrics
# Pipeline padrão LZR - GitHub Actions
Stage 1: Lint # ESLint + Prettier + type-check
|
Stage 2: Test # Unit + Integration tests
|
Stage 3: Security # Dependency scan + SAST
|
Stage 4: Build # Compilação + bundle
|
Stage 5: Staging # Deploy automático em staging
|
Stage 6: E2E # Testes end-to-end em staging
|
Stage 7: Production # Deploy com aprovação manual
DORA Metrics — Targets
| Métrica | Target | Como medir |
| Deployment Frequency | Diário ou sob demanda | Contagem de deploys/semana |
| Lead Time for Changes | < 1 dia | Commit → produção |
| Change Failure Rate | < 15% | % de deploys que causam rollback |
| Recovery Time | < 1 hora | Tempo para restaurar serviço |
12-Factor App — Princípios Chave
Config
Configuração via env vars. Zero hardcode. Diferentes por ambiente.
Stateless
Processos stateless. Estado em banco/cache externo, nunca em memória local.
Paridade
Dev, staging e produção o mais similar possível. Mesma infra, mesmas deps.
Assinatura e Proveniência de Artefatos
- Build reproduzível — Mesmo commit gera mesmo artefato. Lock files commitados, versões fixas.
- Assinatura de imagens — Docker images assinadas via cosign/sigstore antes do push ao registry.
- SBOM (Software Bill of Materials) — Gerado automaticamente no pipeline. Anexado ao release.
- Proveniência — Metadados de build (quem, quando, de qual commit) registrados no artefato.
Três Pilares OpenTelemetry
Logs
O que aconteceu
Eventos discretos. JSON estruturado. Correlacionados por trace_id.
Métricas
Quanto/quantos
Contadores, gauges, histogramas. Latência P50/P95/P99. Error rate.
Traces
Como fluiu
Requisição fim-a-fim. Spans por serviço. Identifica gargalos.
Structured Logging — Formato Padrão
{
"timestamp": "2026-03-24T14:30:00.000Z",
"level": "error",
"message": "Failed to fetch bid from PNCP",
"service": "bid-agent",
"trace_id": "abc-123-def-456",
"tenant_id": "company-uuid",
"duration_ms": 5023
}
⚠Nunca logar: senhas, tokens, CPF/CNPJ completos, dados de cartão. Mascarar PII: email: j***@***.com
Padrões de Resiliência
Retry + Backoff
Tente de novo, com calma
Retry com exponential backoff + jitter para falhas transientes. Max 3 tentativas. Nunca retry em 4xx.
Circuit Breaker
Falhe rápido
Se um serviço externo está fora, pare de chamar. Abra o circuito após 5 falhas consecutivas. Tente novamente após 30s.
Timeout
Não espere para sempre
Timeout em TODA chamada externa. HTTP: 10s. DB: 5s. LLM: 30s. Nunca dependa do default.
Fallback
Degrade com graça
Se o PNCP está fora, mostre dados em cache. Se a IA falha, mostre o documento sem análise.
Cobertura Mínima por Tipo
| Tipo | Cobertura | Roda quando | Ferramenta |
| Unit | > 80% | Pre-commit + CI | Vitest / Jest |
| Integration | Fluxos críticos | CI (toda PR) | Vitest + Supabase local |
| E2E | Happy paths | CI (antes de deploy) | Playwright |
| Security | OWASP Top 10 | CI (weekly) | Snyk / OWASP ZAP |
ℹRegra de ouro: Testes de integração devem bater no banco real (Supabase local via Docker), nunca em mocks. Mocks escondem bugs de migration e RLS.
OWASP LLM Top 10 OWASP LLM 2025
- Prompt Injection — Separar system prompt de user input. Validar e sanitizar input. Filtrar output.
- Sensitive Data Disclosure — Nunca enviar PII no prompt. Mascarar dados antes de enviar ao LLM.
- Excessive Agency — IA nunca executa ações destrutivas sem confirmação humana. Princípio do menor privilégio.
- Unbounded Consumption — Limite de tokens por request. Rate limit por usuário. Cost caps por feature.
- Output Validation — Validar schema do output do LLM antes de agir. Nunca confiar cegamente.
- System Prompt Leakage — Proteger system prompts de extração via prompts adversários.
Cost Control
| Estratégia | Implementação | Economia estimada |
| Cache de respostas | Cache deterministic prompts (mesmo input = mesmo output) | 30-50% |
| Model routing | Haiku para tarefas simples, Sonnet para complexas, Opus para críticas | 40-60% |
| Token budgets | Max tokens por feature. Alertas quando budget atinge 80% | Previne surpresas |
| Prompt optimization | Prompts concisos. Remover redundâncias. Testar versões menores. | 10-20% |
Prompt Lifecycle & Versioning
Versionamento
Prompts são código
Todo prompt vive no repositório, versionado com git. Mudanças de prompt passam por PR e review como qualquer código.
Registry
Prompt Registry
Catálogo centralizado de prompts com: nome, versão, modelo alvo, tokens médios, custo estimado e owner.
Eval Sets & Regression Testing
Toda feature de IA tem um eval set associado — conjunto de inputs com outputs esperados para medir qualidade.
| Tipo de Eval | Quando roda | Critério de aprovação |
| Regression tests | Toda mudança de prompt | Score >= versão anterior |
| Golden set | CI (toda PR que toca IA) | 100% dos golden cases corretos |
| A/B eval | Antes de deploy de novo modelo | Nova versão >= 95% da baseline |
| Red-team suite | Semanal + antes de release | Zero prompt injection success |
Red-Team & Segurança de IA
- Prompt injection suite — Testes automáticos de tentativas de injection (DAN, jailbreak, role-play)
- Data extraction tests — Verificar que system prompt e dados internos não vazam
- Hallucination detection — Comparar output com fonte de verdade quando disponível
- Bias testing — Verificar fairness em outputs que afetam decisões (classificação de licitações)
Classificação de Risco por Feature
| Nível de Risco | Exemplo | Controles obrigatórios |
| Alto | IA que gera documentos legais, analisa contratos | Human-in-the-loop obrigatório, eval set extenso, red-team |
| Médio | Resumo de editais, classificação de documentos | Eval set, validação de output, fallback |
| Baixo | Sugestão de tags, autocomplete | Eval set básico, rate limiting |
Human-in-the-Loop Policy
⚠
Regra: Toda ação destrutiva, irreversível ou legalmente vinculante gerada por IA requer confirmação humana explícita antes da execução.
Grounding & Retrieval Standards
- RAG obrigatório — Para features que dependem de dados atualizados, usar Retrieval-Augmented Generation
- Citação de fontes — Output do LLM deve referenciar documentos fonte quando disponíveis
- Freshness — Dados do RAG com timestamp. Alertar usuário se dados > 24h
Rollout de Modelos
Fase 1
Shadow mode
Novo modelo roda em paralelo, sem afetar usuário. Comparar outputs.
Fase 2
Canary (5%)
5% dos usuários recebem novo modelo. Monitorar métricas.
Fase 3
Rollout gradual
25% → 50% → 100%. Rollback automático se métricas degradam.
Regras Fundamentais
- Zero hardcoded strings — Toda string visível ao usuário vem de arquivo de tradução
- UTF-8 everywhere — Banco, API, frontend, arquivos. Sem exceção
- Timezone: UTC no banco — Armazenar tudo em UTC. Converter para local apenas na exibição
- Intl API — Usar Intl.NumberFormat, Intl.DateTimeFormat para formatação locale-aware
- Pluralização — Usar ICU MessageFormat. "1 licitação" vs "5 licitações" por locale
- Text expansion — UI deve acomodar textos 30-40% maiores (alemão, finlandês)
Formatação por Locale
| Tipo | PT-BR | EN-US | DE-DE |
| Moeda | R$ 1.234,56 | $1,234.56 | 1.234,56 € |
| Data | 24/03/2026 | 03/24/2026 | 24.03.2026 |
| Número | 1.234.567,89 | 1,234,567.89 | 1.234.567,89 |
WCAG 2.2 AA — Checklist WCAG 2.2
- HTML Semântico — Usar headings corretos (h1-h6), landmarks (nav, main, aside), labels em forms
- Navegação por teclado — Todo elemento interativo acessível via Tab. Focus indicators visíveis.
- Contraste — 4.5:1 para texto normal. 3:1 para texto grande. Verificar em ambos os temas.
- Alt text — Todas as imagens informativas têm alt descritivo. Decorativas têm alt="".
- Cor não é único indicador — Status usa cor + ícone + texto. Nunca só cor.
- Touch targets — Mínimo 44x44px em mobile. Sem exceção.
- Focus Not Obscured — Elemento focado nunca escondido por sticky headers ou modals.
- Accessible Auth — Login não depende de cognitive function tests (CAPTCHA visual).
Alertas de Budget
50% do budget
Notificação
Slack notification para o time. Revisão do consumo.
80% do budget
Alerta
Email para engineering lead. Investigar causa. Plano de ação.
100% do budget
Crítico
Escalação imediata. Considerar throttling. Revisar arquitetura.
Checklist FinOps
- Tag everything — Todo recurso cloud tagado com: environment, service, team
- Right-sizing mensal — Revisar CPU/memória/storage. Downsizar recursos ociosos.
- Ambientes não-prod — Desligar staging/dev fora do horário comercial
- LLM costs — Maior centro de custo. Monitorar por feature. Cache agressivo.
- Cost per tenant — Rastrear custo por cliente. Garantir unit economics positivo.
- Log retention — Não guardar tudo por 90 dias. Hot: 7d, Warm: 30d, Cold: 90d.
Diátaxis Framework Diátaxis
Toda documentação LZR segue o framework Diátaxis — 4 tipos distintos, cada um com propósito diferente.
Aprender
Tutorials
Passo a passo para iniciantes. "Configure seu ambiente de dev em 30min."
Resolver
How-To Guides
Receitas práticas. "Como adicionar um novo endpoint de API."
Consultar
Reference
Documentação técnica exata. API docs, schema do banco, configs.
Entender
Explanation
Contexto e decisões. ADRs, trade-offs, por que fizemos X e não Y.
ADRs (Architecture Decision Records)
# ADR-001: Usar Supabase como backend principal
Status: Accepted
Date: 2026-01-15
Context:
Precisamos de auth, banco, storage e realtime.
Time pequeno, não pode gerenciar infra complexa.
Decision:
Usar Supabase (PostgreSQL + Auth + Storage + Edge Functions).
Consequences:
+ Setup rápido, menos infra para gerenciar
+ RLS nativo para multi-tenancy
- Vendor lock-in parcial
- Edge Functions limitadas vs servidor próprio
Documentação Obrigatória por Repositório
- README.md — O que faz, como rodar, como deployar. Dev novo produtivo em <1 dia.
- CHANGELOG.md — Semver. O que mudou em cada versão.
- .env.example — Todas as env vars com descrição e valor de exemplo.
- docs/adrs/ — Decisões arquiteturais documentadas.
- docs/runbooks/ — Como deployar, como fazer rollback, como responder incidentes.
- API docs — Auto-gerada via OpenAPI spec. Sempre em sync com o código.
TSConfig — Strict Mode Obrigatório
// tsconfig.json — configuração base LZR
{
"compilerOptions": {
"strict": true,
"noUncheckedIndexedAccess": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"forceConsistentCasingInFileNames": true,
"verbatimModuleSyntax": true
}
}
⚠Zero any. Se não sabe o tipo, use unknown e faça narrowing. any em PR = PR rejeitado.
Organização de Pastas — Feature-based
# Organização por feature, não por tipo
src/
├── features/
│ ├── bids/
│ │ ├── bids.service.ts
│ │ ├── bids.controller.ts
│ │ ├── bids.types.ts
│ │ ├── bids.validation.ts
│ │ └── __tests__/
│ └── companies/
│ ├── companies.service.ts
│ └── ...
├── shared/
│ ├── utils/
│ ├── types/
│ └── middleware/
├── config/
└── index.ts
Naming Conventions
| Elemento | Convenção | Exemplo |
| Arquivos | kebab-case | bid-analysis.service.ts |
| Classes | PascalCase | BidAnalysisService |
| Funções/variáveis | camelCase | analyzeBid() |
| Constantes | UPPER_SNAKE_CASE | MAX_RETRY_COUNT |
| Types/Interfaces | PascalCase (sem prefixo I) | BidResponse, não IBidResponse |
| Enums | PascalCase + UPPER values | BidStatus.DRAFT |
Padrões Obrigatórios
- Zod para validação — Schema validation em todo input externo (API, forms, env vars)
- Result pattern — Para operações que podem falhar, retornar
{ success, data, error } em vez de throw
- Barrel exports — Cada feature tem um
index.ts que exporta a API pública
- Dependency injection — Services recebem dependências via construtor, não import direto
App Router — Padrão LZR Next.js 14+
# Estrutura de pastas Next.js
app/
├── (auth)/
│ ├── login/page.tsx
│ └── register/page.tsx
├── (dashboard)/
│ ├── layout.tsx
│ ├── page.tsx
│ └── bids/
│ ├── page.tsx
│ └── [id]/page.tsx
├── api/
│ └── v1/
└── layout.tsx
# Componentes
components/
├── ui/ # Componentes base (do Design System)
├── forms/ # Formulários específicos
├── layouts/ # Layouts compartilhados
└── features/ # Componentes de feature (conectados a dados)
Padrões de Componentes
- Server Components por padrão — Só usar 'use client' quando precisa de interatividade (state, effects, event handlers)
- Co-location — Componente, types, tests e stories no mesmo diretório
- Props tipadas — Toda prop com tipo explícito. Sem
any. Sem props spreading desnecessário.
- Composição sobre herança — Usar children, render props e composition patterns
Estado & Data Fetching
Servidor
Server Actions + RSC
Fetch de dados em Server Components. Server Actions para mutations. Zero useEffect para data fetching.
Cliente
React Query (TanStack)
Para dados que precisam de cache, revalidação ou polling no cliente. Nunca SWR e React Query no mesmo projeto.
Global
Zustand (se necessário)
Estado global mínimo. Maioria do estado vive em Server Components ou URL params.
Forms
React Hook Form + Zod
Validação client-side com Zod schema. Mesma validação roda no servidor.
Performance Frontend
- Core Web Vitals — LCP < 2.5s, FID < 100ms, CLS < 0.1. Monitorar em produção.
- Bundle size — Revisar com
@next/bundle-analyzer. Lazy load para routes e componentes pesados.
- Imagens — Sempre usar
next/image. WebP/AVIF automático. Sizes definidos.
- Memoization consciente — useMemo/useCallback só quando há problema medido. Não otimizar prematuramente.
Stack Base
Framework
Expo (managed)
Expo SDK para build, OTA updates e dev workflow. Eject só se necessário (módulo nativo sem suporte).
Navegação
Expo Router
File-based routing. Mesma mental model do Next.js App Router.
Estilo
NativeWind (Tailwind)
Tokens do Design System via Tailwind config. Consistência com web.
Estado
Zustand + React Query
Mesmo padrão do web. Offline-first com persistência local.
Regras Mobile-Specific
- Offline-first — App funciona sem internet. Sync quando conectar. Feedback claro de status.
- Deep linking — Toda tela acessível via URL scheme. Configurado no Expo Router.
- Biometria — Usar expo-local-authentication. Fallback para PIN.
- Push notifications — Via Expo Notifications. Permissão solicitada no momento certo, não no primeiro launch.
SLOs & Error Budget
| Serviço | SLI (indicador) | SLO (objetivo) | Error Budget (30d) |
| API | % requests com status 2xx | 99.5% | ~3.6h de downtime |
| Dashboard | LCP < 2.5s | 95% | ~36h abaixo do target |
| AI Features | % respostas válidas | 98% | ~14.4h de falhas |
| Auth | % logins bem-sucedidos | 99.9% | ~43min de falhas |
⚠Deploy freeze automático: Quando o error budget de um serviço é consumido > 80%, deploys não-críticos são congelados até o budget ser restaurado.
Política de Incidentes
| Severidade | Impacto | Resposta | Comunicação |
| SEV-1 | Serviço completamente fora | Imediata. All-hands. | Status page + email em 15min |
| SEV-2 | Funcionalidade crítica degradada | < 30min. On-call + backup. | Status page em 1h |
| SEV-3 | Feature não-crítica com problemas | < 4h. On-call investiga. | Slack do time |
| SEV-4 | Inconveniência menor | Próximo dia útil | Ticket interno |
RTO & RPO
RTO
Recovery Time Objective
API: < 1h. Dashboard: < 2h. Features de IA: < 4h. Tempo máximo para restaurar o serviço após incidente.
RPO
Recovery Point Objective
Banco: < 1h (point-in-time recovery). Storage: < 24h (backup diário). Perda máxima aceitável de dados.
Disaster Recovery — Checklist
- Backup testado — Restore de backup testado trimestralmente. Resultado documentado.
- Runbook atualizado — Procedimento de DR revisado a cada 6 meses. Acessível offline.
- Multi-region aware — Saber o que acontece se a região do Supabase cai. Plano B documentado.
- Postmortem obrigatório — Todo SEV-1 e SEV-2 gera postmortem blameless em 48h.
Decisões Arquiteturais Vigentes
| Decisão | Escolha | ADR | Status |
| Backend principal | Supabase (Postgres + Auth + Storage) | ADR-001 | Accepted |
| Frontend web | Next.js (App Router) | ADR-002 | Accepted |
| Mobile | Expo (React Native) | ADR-003 | Proposed |
| IA/LLM | Claude API (Anthropic) | ADR-004 | Accepted |
| Monorepo vs Polyrepo | Polyrepo (1 repo por produto) | ADR-005 | Accepted |
Boundaries & Contratos
- API como contrato — Comunicação entre serviços sempre via API documentada. Zero acesso direto ao banco de outro serviço.
- Schema validation na fronteira — Zod valida todo input na borda do sistema. Dentro, tipos são confiáveis.
- Versionamento de API — Prefixo
/api/v1/. Nova versão major só com ADR e plano de migração.
- Depreciação — Endpoint deprecated fica ativo por mínimo 90 dias com header
Sunset.
CODEOWNERS Obrigatório
# .github/CODEOWNERS
# Default - todo PR precisa de review
* @lzr-tech/engineering
# Infraestrutura e CI/CD
.github/ @lzr-tech/devops
Dockerfile @lzr-tech/devops
docker-compose* @lzr-tech/devops
# Database migrations
supabase/migrations/ @lzr-tech/backend-leads
# Design System e UI
components/ui/ @lzr-tech/frontend-leads
# Segurança
**/auth* @lzr-tech/security
**/middleware* @lzr-tech/security
Branch Protection Rules
| Branch | Regras |
main | PR obrigatório, 1 approval mínimo, CI passando, CODEOWNERS review, no force push |
develop | PR obrigatório, 1 approval mínimo, CI passando |
feat/* | Livre para push, mas PR para develop requer CI verde |
Templates Obrigatórios
PR Template
Pull Request
O que mudou, por que mudou, como testar, screenshots (se UI), checklist de review.
Issue Template
Bug Report
Steps to reproduce, expected vs actual, environment, screenshots/logs.
Issue Template
Feature Request
Problema que resolve, solução proposta, alternativas, critérios de aceite.
Repo Scaffold — Arquivos Obrigatórios
- .github/CODEOWNERS — Ownership por área
- .github/pull_request_template.md — Template de PR
- .github/ISSUE_TEMPLATE/ — Templates de issue (bug, feature, ai-spec)
- .github/workflows/ — CI/CD pipelines
- .env.example — Todas env vars documentadas
- README.md — Setup em <30min para dev novo
- CHANGELOG.md — Semver, auto-gerado por conventional commits