Catálogo Completo da API REST & Schemas Zod
Catálogo Completo da API REST & Schemas Zod
Section titled “Catálogo Completo da API REST & Schemas Zod”Todos os endpoints sob /api/atomic/ seguem o padrão de mutação atômica atemporal, validando entradas via Zod schemas antes de interagir com o Cloudflare D1.
📡 1. Matriz de Endpoints Atômicos (/api/atomic/*)
Section titled “📡 1. Matriz de Endpoints Atômicos (/api/atomic/*)”graph LR
subgraph Client ["Client Services (EntitiesApiClient)"]
Req["syncAtomic() / EntitiesApiClient"]
end
subgraph API ["Pages Functions Handlers"]
C["/api/atomic/clients"]
E["/api/atomic/employees"]
R["/api/atomic/requests"]
I["/api/atomic/invoices"]
P["/api/atomic/payroll-runs"]
end
subgraph DB ["Cloudflare D1 (SQLite)"]
D1[("Tables: clients, employees, service_requests...")]
end
Req --> C
Req --> E
Req --> R
Req --> I
Req --> P
C --> D1
E --> D1
R --> D1
I --> D1
P --> D1
📋 2. Detalhamento dos Principais Endpoints
Section titled “📋 2. Detalhamento dos Principais Endpoints”A. Clientes (/api/atomic/clients)
Section titled “A. Clientes (/api/atomic/clients)”- GET
/api/atomic/clients: Retorna a lista completa de clientes cadastrados. - POST
/api/atomic/clients: Cria ou atualiza um cliente. - Schema Zod:
const clientSchema = z.object({id: z.string().optional(),name: z.string().min(2, "Nome é obrigatório"),email: z.string().email("E-mail inválido"),phone: z.string().min(8, "Telefone é obrigatório"),address: z.string().min(5, "Endereço é obrigatório"),preferredLanguage: z.enum(["pt-BR", "en-GB", "es-ES"]).default("en-GB"),});
B. Solicitações de Serviço (/api/atomic/requests)
Section titled “B. Solicitações de Serviço (/api/atomic/requests)”- GET
/api/atomic/requests: Retorna os agendamentos. - POST
/api/atomic/requests: Insere ou atualiza o status de um serviço. - POST
/api/atomic/payrollEntries: Cria exclusivamente um holeriteDRAFT; ID existente retorna409sem sobrescrever dados financeiros. - PUT
/api/atomic/payrollEntries: Executa somenteDRAFT → APPROVEDouAPPROVED → PAID, comexpectedStatusobrigatório e compare-and-set no D1. Conflito retorna409comcurrentStatuseadvancesAmount. A liquidação vencedora usa um único batch D1 tokenizado para mudar o status, liquidar adiantamentos pendentes e reconciliar o total descontado antes da resposta. - POST
/api/atomic/payrollRuns: Cria um cicloOPENsem permitir overwrite;generatedAtegeneratedBysão derivados no servidor. ID existente retorna409, inclusive se o ciclo já estiver fechado. - PUT
/api/atomic/payrollRuns: Fecha exclusivamente um cicloOPENcomexpectedStatus: "OPEN". O mesmo statement recusa tarefas abertas no intervalo e decisões concorrentes;closedAteclosedBysão autoritativos e retornam ao cliente. Os horários de criação, geração e fechamento retornados por essas rotas são ISO 8601 UTC (Z) para parsing idêntico nas quatro plataformas. Ciclo inexistente retorna404; tarefa aberta ou ciclo já fechado retorna409. - POST
/api/atomic/payrollGenerate: Gera atomicamente um ciclo, seus holerites obrigatoriamenteDRAFTe o depósito opcional da reserva. Um token interno limita dependentes ao batch que venceu a criação do ciclo; colisão reverte o conjunto. Retry equivalente retorna200comidempotent: true, enquanto conteúdo divergente sob o mesmorun.idretorna409sem anexar linhas. Saldo, autoria e horários são derivados no servidor e retornados ao cliente. - Contrato temporal de
/api/boot: campos de instante no formato SQLite (YYYY-MM-DD HH:mm:ss) são normalizados para ISO 8601 UTC antes da resposta. O contrato inclui registros principais e objetos aninhados montados a partir das tabelas normalizadas: incidentes, check-in/out, edições, carteira, pagamentos, adiantamentos e último sync de calendário. Datas civis sem horário, rótulos e valores já zonados permanecem inalterados, evitando mudança de hora/dia entre Safari e Chromium. - Contrato temporal incremental:
CloudCliente toda chamada direta às APIs próprias aplicamparseApiJsonàs respostas JSON, incluindo autenticação, portais públicos, uploads, IA, WhatsApp e ações operacionais. O parser percorre objetos/arrays recém-criados e converte apenas campos de instante camelCase ou snake_case com a forma SQLite exata; datas civis, texto comum, valores já zonados e respostas primitivas não mudam. Um teste de contrato impede novos parsings diretos fora do parser compartilhado e de integrações externas explicitamente permitidas. Assim uma mutação não reintroduz divergência até o próximo/api/boot. - POST
/api/atomic/cashReserve: Registra uma retirada manual de reserva para ADMIN. O saldo e o autor são derivados no servidor; saldo insuficiente ou reutilização conflitante do ID retorna409. Retry idêntico devolve a linha já aceita. - Schema Zod:
const requestSchema = z.object({id: z.string().optional(),clientId: z.string(),serviceId: z.string(),status: z.enum(["REQUESTED", "PENDING", "CONFIRMED", "IN_PROGRESS", "COMPLETED", "CANCELLED"]),scheduledDate: z.string(),totalPrice: z.number().positive(),});
C. Faturas (/api/atomic/invoices)
Section titled “C. Faturas (/api/atomic/invoices)”- POST
/api/atomic/invoices: Gera ou altera o estado de uma fatura (DRAFT,ISSUED,PAID,OVERDUE). - POST
/api/billing/invoice-operation: executaVOID,DISPATCHouREMOVE_TASKpara ADMIN/MANAGER. O corpo incluiinvoiceId, status/IDs esperados e, na remoção, a invoice recalculada. O Worker revalida a transição e os vínculos persistidos; um único batch D1 atualiza payment status/versão das visitas, fatura einvoice_items. Snapshot concorrente retorna409sem alteração parcial.
D. Telemetria do cliente (/api/atomic/system-logs)
Section titled “D. Telemetria do cliente (/api/atomic/system-logs)”- POST: disponível a usuários autenticados exceto
CLIENT; aceita IDs/ação/entidade limitados por Zod e até 100 kB brutos emdetails, que são sanitizados e reduzidos a no máximo 8.000 caracteres antes do D1.user_idetimestampsão sempre derivados da sessão e do Worker. O orçamento é 20 relatórios por conta em 5 minutos; excesso retorna429eRetry-After: 300. - GET: disponível apenas a
ADMINeMANAGER;limité normalizado entre 1 e 500 (default 200) eentityIdaceita no máximo 256 caracteres. - Credenciais em URLs, mensagens, stacks ou contexto são redigidas novamente no servidor, independentemente da versão do aplicativo cliente. Erros internos retornam mensagem estável sem detalhes do D1.
E. Pausa de férias (POST /api/scheduling/holiday-suspension)
Section titled “E. Pausa de férias (POST /api/scheduling/holiday-suspension)”- Disponível somente para
ADMINeMANAGERautenticados. - Recebe
operationIdUUID,clientId,startDateeendDateemYYYY-MM-DD; o intervalo máximo é 366 dias. - Cancela em um único statement somente visitas
PENDING,PENDING_REVIEWeSCHEDULED, com motivoCLIENT_HOLIDAY, atualização financeira e incremento de versão. - Repetir o mesmo UUID e payload devolve o conjunto original sem reaplicar a mutação. Reutilizar o UUID com cliente ou datas diferentes retorna
409.
F. Cadastro verificado por telefone
Section titled “F. Cadastro verificado por telefone”POST /api/auth/phone/startrecebependingTokenephone. O token pendente prova que senha/Google/Apple já validou a primeira etapa; o endpoint aplica rate limit D1 e envia o OTP por WhatsApp.POST /api/auth/phone/verifyrecebe o mesmo token, telefone e código de seis dígitos. Somente uma verificação válida cria/vincula a conta e emite cookies de sessão.- Códigos expirados, errados e tentativas esgotadas possuem respostas distintas; telefone que já autentica outra conta retorna
409e nunca é transferido.
G. Cotações de leads
Section titled “G. Cotações de leads”POST /api/leads/my-quotecria ou atualiza a única cotaçãoOPENdo lead autenticado/convidado. A identidade vem da sessão ou bearer;leadIddo corpo não é aceito.GET /api/atomic/leadQuotesfornece a fila administrativa autenticada para ADMIN/MANAGER; decisões usam as rotas específicas abaixo.POST /api/atomic/leadQuotes/:id/confirmexige ADMIN/MANAGER, entidade fiscal e preço; cria/reutiliza cliente, cria atendimento, aplica VAT e reponta a conta ligada ao lead.POST /api/atomic/leadQuotes/:id/declinemantém o contato como lead, preserva a cotação como histórico, registra a decisão no chat e cancela follow-ups pendentes.- As rotas públicas antigas de conversão direta não existem mais. Cliente e atendimento só nascem na confirmação administrativa.