# Etapa 6/8 — Vendas, Parcelas e Dashboards ## Contexto do projeto Continuação do **SeConectai Vendas**. Já existem: setup, auth com RLS, painel master, integrações Evolution/e-mail, e CRUD de customers e produtos/serviços no painel do tenant. Esta etapa implementa o fluxo de vendas propriamente dito: registrar uma venda com itens, gerar parcelas a receber, e expor os dashboards de acompanhamento (resumo semanal/mensal, total recebido, total a receber). ## Tarefas 1. **Módulo `sales` (`src/modules/sales/`)** - `POST /tenant/vendas` — cria venda (`sales`) com seus itens (`sale_items`) em uma única transação: - Recebe `customer_id`, lista de itens (`product_service_id`, `quantidade`, `valor_unitario` — permitir sobrescrever o valor do catálogo caso tenha desconto pontual), `desconto` geral, `observacoes`, `data_venda`. - Calcula `valor_total` de cada item e da venda (soma dos itens menos desconto). - Recebe também a definição das parcelas (`sale_payments`): número de parcelas, ou lista explícita de `{valor, vencimento}` — validar que a soma das parcelas bate com `valor_total`. - Validar que `customer_id` e todos os `product_service_id` pertencem ao tenant autenticado (RLS já ajuda, mas validar explicitamente para retornar erro de negócio claro em vez de erro de banco). - `GET /tenant/vendas` — listagem com filtros por `status`, `customer_id`, período (`data_venda`), paginação. - `GET /tenant/vendas/:id` — detalhe completo (itens + parcelas). - `PATCH /tenant/vendas/:id/status` — transição de status (`orcamento` → `confirmada` → `concluida`, ou `cancelada`). Cancelar uma venda deve cancelar também as parcelas pendentes (`sale_payments.status = 'cancelado'`). - `PUT /tenant/vendas/:id` — editar venda em status `orcamento` apenas (venda `confirmada` não deve ser editável em itens/valores — só cancelada e recriada, para preservar histórico financeiro). 2. **Módulo `sale_payments` (parcelas)** - `GET /tenant/recebimentos` — listagem de parcelas com filtros por `status`, período de vencimento, `customer_id`; usar a view `vw_recebimentos` como base. - `PATCH /tenant/recebimentos/:id/marcar-pago` — marca parcela como paga (`pago_em = now()`, `forma_pagamento`). - Endpoint (preparando Etapa 7): `POST /tenant/recebimentos/atualizar-atrasadas` — marca como `atrasado` toda parcela `pendente` com `vencimento` no passado (vira job agendado na Etapa 7, aqui só o endpoint manual). 3. **Dashboard do tenant** - `GET /tenant/dashboard/resumo-semanal` e `GET /tenant/dashboard/resumo-mensal` — usando as views `vw_resumo_vendas_semanal` / `vw_resumo_vendas_mensal`, com filtro de período opcional. - `GET /tenant/dashboard/financeiro` — retorna: total recebido no mês corrente, total a receber (pendente + atrasado), total atrasado isolado (para destacar visualmente), próximas N parcelas a vencer. 4. **Regras de consistência** - Toda alteração relevante em `sales`/`sale_payments` grava em `audit_logs` (`usuario_tipo='tenant_user'`, incluindo `usuario_id` e `tenant_id`). - Usar transações do Prisma em toda operação que mexe em mais de uma tabela (venda + itens + parcelas) para evitar estado inconsistente. ## Critérios de aceite - [ ] Criar venda com itens e parcelas funciona em uma única transação; falha em qualquer parte reverte tudo - [ ] Soma das parcelas é validada contra o valor total da venda - [ ] Cancelar venda cancela as parcelas pendentes associadas - [ ] Venda confirmada não pode ser editada em itens/valores (só via cancelamento) - [ ] Marcar parcela como paga reflete corretamente no dashboard financeiro - [ ] Dashboards semanal/mensal retornam números batendo com os dados de teste inseridos manualmente - [ ] Endpoint de atualizar atrasadas muda status corretamente das parcelas vencidas - [ ] Todas as queries usam RLS corretamente — venda de um tenant nunca aparece para outro (reforçar teste de isolamento desta etapa também)