Módulos Iniciais

Clientes
- Cadastro PF/PJ com CPF/CNPJ, múltiplos endereços e histórico de interações.
- Tabelas: `clients`, `client_addresses`, `client_interactions`.
- Rotas exemplo: `GET /api/clientes`, `POST /api/clientes`.

Produtos
- Cadastro com código, EAN, NCM, PIS, COFINS, CEST, CFOP.
- Estoque: `inventory_movements`; preços e promoções (camadas futuras).
- Rotas exemplo: `GET /api/produtos`.
- Utilidades:
  - `GET /api/produtos/check-codigo?codigo=<SKU>` — verifica unicidade de código (JWT + permissão `produtos.read`).
  - UI: botão "Gerar SKU" no formulário de criação/edição e calculadora de preço embutida na aba "Preço".
  - Sugestões CEST: além de `cest_by_ncm.json`, há `public/assets/cest_extra.json` com mapeamentos adicionais e busca por prefixo de NCM.

Compras
- Notas fiscais de entrada; fornecedores e conciliação bancária.
- Tabelas: `suppliers`, `purchase_invoices`, `bank_reconciliation`.
- Rotas exemplo: `GET /api/compras/notas`.

Vendas
- Gestão de pedidos; emissão de NF-e; relatórios fiscais.
- Tabelas: `sales_orders`, `nfe_emissions`.
- Rotas exemplo: `GET /api/vendas/pedidos`.

PDV
- Integração com SAT/ECF; NFC-e e fechamento de caixa.
- Tabelas: `pos_sales`, `cash_closures`.
- Rotas exemplo: `GET /api/pdv/caixas`.

Admin (Gestão de Tenants)
- Funções: listar tenants, criar tenant, rodar migrações, semear usuário admin padrão e consultar auditoria de autenticação.
- Segurança: todas as rotas exigem o cabeçalho `x-admin-secret` com valor de `ADMIN_SECRET` definido no `.env` (padrão: `admin_secret`).
- Variáveis de ambiente relevantes:
  - `DB_HOST`, `DB_USERNAME`, `DB_PASSWORD`, `DB_BASE_PREFIX`
  - `ADMIN_SECRET`, `DEFAULT_ADMIN_EMAIL`, `DEFAULT_ADMIN_NAME`, `DEFAULT_ADMIN_PASSWORD`
- Endpoints:
  - `GET /api/admin/tenants` — lista tenants existentes (por prefixo de DB).
  - `POST /api/admin/tenants` — body `{ tenant_id: "<id>" }` cria o banco e aplica migrações.
  - `POST /api/admin/tenants/{tenant}/migrate` — roda migrações completas para o tenant.
  - `POST /api/admin/tenants/{tenant}/migrate-modules` — roda apenas migrações dos módulos.
  - `POST /api/admin/tenants/{tenant}/seed-admin` — semeia admin padrão (usa `DEFAULT_ADMIN_*`).
  - `GET /api/admin/tenants/{tenant}/verify-admin` — verifica existência e estado do(s) admin(s).
  - `GET /api/admin/tenants/{tenant}/audit-auth?limit=20` — últimos logs de login.
 - Exemplos (PowerShell):
   - `Invoke-WebRequest http://localhost:8000/api/admin/tenants -Headers @{ 'x-admin-secret'='admin_secret' }`
   - `Invoke-WebRequest -Method Post http://localhost:8000/api/admin/tenants/acme/migrate -Headers @{ 'x-admin-secret'='admin_secret' }`

Padrões de Dependência
- `Vendas` depende de `Clientes` e `Produtos`.
- `PDV` depende de `Vendas`.

Próximos Passos
- Adicionar autenticação JWT e RBAC.
- Validação de dependências de módulos.
- Paginação e filtros nas rotas de listagem.
- Logs de auditoria por tenant.

Convenções de API
- Autenticação e RBAC: todas as rotas protegidas exigem `Authorization: Bearer <token>` e permissões `*.read|create|update|delete` por módulo.
- Envelope de resposta:
  - Sucesso: `{ "data": <obj|array>, ...metadados }`
  - Erro: `{ "error": { "code": "codigo", "message": "mensagem" } }`
- Paginação: listagens retornam `data`, `page`, `per_page`, `total`, `total_pages`.
- Validações BR: `CPF`, `CNPJ`, `NCM`, `EAN`, `CFOP` têm regras específicas com códigos de erro `invalid_*`.
- Cache condicional:
  - Detalhe por ID suporta `ETag`/`If-None-Match` e `Last-Modified`/`If-Modified-Since`.
  - `304 Not Modified` quando o recurso não mudou; respostas incluem `ETag` e `Last-Modified`.
- CNPJ auto-preenchimento:
  - Endpoint público: `GET /api/clientes/cnpj/{cnpj}` (requer `clientes.create`).
  - Cache por tenant com TTL `CNPJ_CACHE_TTL_SECONDS`; proteção de refresh por `CNPJ_REFRESH_MIN_SECONDS`.
  - Erros: `invalid_cnpj`, `refresh_too_soon` (com `retry_in_seconds`), `cnpj_service_unavailable`.

Auditoria
- Ações registradas: `create`, `update`, `delete`, `read` (controlado por `AUDIT_LOG_READS`), `login_success`, `login_failed`.
- Estrutura: tabela `audit_logs` com `user_id`, `action`, `resource`, `resource_id`, `old_data`, `new_data`, `metadata`, `created_at`.
- Endpoints (administrativos, requer papel `admin`):
  - `GET /api/audit/{resource}` — parâmetros: `resource_id` (opcional), `limit` (padrão 50). Resposta: `{ "data": [ { "action": "update", "metadata": { ... }, ... } ] }`.
  - `POST /api/audit/prune` — body `{ "days": 30 }`. Resposta: `{ "deleted": <n> }`.
- Boas práticas:
  - Incluir `metadata.endpoint` com o nome lógico da operação.
  - Para atualizações, o logger calcula `changes` com pares `{ old, new }` por campo alterado.
  - `user_id` pode ser enviado em `metadata` quando disponível.