Skip to content

Latest commit

 

History

History
35 lines (28 loc) · 3.89 KB

CLAUDE.md

File metadata and controls

35 lines (28 loc) · 3.89 KB

Compasso

Aplicação web (PWA) de registro de horas. Documentos de produto, escopo e decisões (ADRs) ficam no Projeto "Compasso" no claude.ai: escopo-mvp-v1.md e plano-implementacao.md.

Stack

Next.js (App Router, TS estrito), Tailwind, shadcn/ui, Drizzle ORM + Neon (PostgreSQL), Better Auth, Zod, Vitest. Ler AGENTS.md e a documentação em node_modules/next/dist/docs/ antes de usar APIs do Next.js.

Modelo

Workspace (tenant, 1:1 com organização do Better Auth) -> Organização (empresa própria ou cliente) -> Projeto -> Tarefa. Tags são do workspace. Papéis por workspace: admin | member (membro vê só as próprias horas).

Design

Tokens, componentes e convenções estão em design-system.md; a referência viva fica em /design (oculta em produção). Usar apenas tokens (bg-background, text-muted-foreground...), nunca hex; vermelho só para cronômetro em andamento, ações destrutivas e alertas; horas sempre em tabular-nums.

Regras

  • Toda query operacional filtra por workspace_id; nunca confiar em IDs do cliente sem checar o tenant.
  • Autorização por recurso, não por caminho: toda página, route handler e Server Action protegido chama requireWorkspaceContext().
  • Dados do workspace (catálogo e, depois, registros de tempo) só pelo getTenant() (src/server/get-tenant.ts) / createTenant() (src/server/tenant.ts), nunca com getDb() direto em páginas, route handlers ou Server Actions. A camada carimba workspace_id da sessão, valida que IDs de pais pertencem ao workspace, trata IDs de outro workspace como inexistentes e restringe escrita do catálogo a admin (ADR-026). Nova tabela com workspace_id ganha repositório e teste de isolamento em src/server/tenant.test.ts (PGlite com as migrações reais).
  • Remoção sempre lógica (ADR-025): nada de DELETE físico em users/workspaces/membros. users.deleted_at (anonimizado, LGPD), workspaces.archived_at, workspace_members.removed_at; consultas de acesso filtram esses campos. Anonimização em src/server/auth/anonymize.ts (ADR-034; script scripts/anonymize-user.ts); provisionamento em src/server/auth/workspace-context.ts.
  • Service worker (public/sw.js, ADR-012): só serve /offline como fallback de navegação e cacheia ativos estáticos imutáveis; nunca cachear HTML de páginas do app, RSC, /api nem dados autenticados. Só registra em produção (para testar: npm run build && npm start).
  • Instantes em UTC (timestamptz); fuso IANA no usuário e no registro. Duração nunca é armazenada: derivar de ended_at - started_at (ver src/lib/time.ts).
  • Um único timer ativo por usuário (índice único parcial).
  • Valores monetários em Decimal (fora do MVP). Exportações escrevem números reais, nunca texto.
  • Código em inglês, UI em português do Brasil. Validar entradas com Zod. Testes para regras de negócio.
  • Migrações versionadas (npm run db:generate); explicar o impacto antes de alterar o schema.

Comandos

npm run dev | build | lint | typecheck | test | db:generate | db:migrate | db:studio

Fluxo de trabalho (gitflow)

  • main = produção (só recebe release/* e hotfix/*); develop = integração.
  • Trabalho novo: feature/<nome> a partir de develop, sempre via PR para develop. Nunca commitar direto em main ou develop.
  • Release: release/x.y.z a partir de develop → PR para main + tag + merge de volta em develop. Correção urgente: hotfix/* a partir de main.
  • Versões 0.x (enquanto a Vercel publica a develop): PR chore/release-x.y.z com a versão em package.json e a entrada no CHANGELOG.md; depois do merge, a tag vx.y.z no commit da develop. O fluxo release/* → main acima passa a valer na 1.0.0 (ver ADR-031).
  • Commits em Conventional Commits (feat:, fix:, chore:, docs:, test:).
  • Antes de abrir o PR: npm run typecheck && npm test && npm run build; depois revisão (code-review → simplify → security-review).