Skip to content

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”
  • 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 holerite DRAFT; ID existente retorna 409 sem sobrescrever dados financeiros.
  • PUT /api/atomic/payrollEntries: Executa somente DRAFT → APPROVED ou APPROVED → PAID, com expectedStatus obrigatório e compare-and-set no D1. Conflito retorna 409 com currentStatus e advancesAmount. 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 ciclo OPEN sem permitir overwrite; generatedAt e generatedBy são derivados no servidor. ID existente retorna 409, inclusive se o ciclo já estiver fechado.
  • PUT /api/atomic/payrollRuns: Fecha exclusivamente um ciclo OPEN com expectedStatus: "OPEN". O mesmo statement recusa tarefas abertas no intervalo e decisões concorrentes; closedAt e closedBy sã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 retorna 404; tarefa aberta ou ciclo já fechado retorna 409.
  • POST /api/atomic/payrollGenerate: Gera atomicamente um ciclo, seus holerites obrigatoriamente DRAFT e 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 retorna 200 com idempotent: true, enquanto conteúdo divergente sob o mesmo run.id retorna 409 sem 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: CloudClient e toda chamada direta às APIs próprias aplicam parseApiJson à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 retorna 409. 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(),
    });
  • POST /api/atomic/invoices: Gera ou altera o estado de uma fatura (DRAFT, ISSUED, PAID, OVERDUE).
  • POST /api/billing/invoice-operation: executa VOID, DISPATCH ou REMOVE_TASK para ADMIN/MANAGER. O corpo inclui invoiceId, 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 e invoice_items. Snapshot concorrente retorna 409 sem 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 em details, que são sanitizados e reduzidos a no máximo 8.000 caracteres antes do D1. user_id e timestamp são sempre derivados da sessão e do Worker. O orçamento é 20 relatórios por conta em 5 minutos; excesso retorna 429 e Retry-After: 300.
  • GET: disponível apenas a ADMIN e MANAGER; limit é normalizado entre 1 e 500 (default 200) e entityId aceita 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 ADMIN e MANAGER autenticados.
  • Recebe operationId UUID, clientId, startDate e endDate em YYYY-MM-DD; o intervalo máximo é 366 dias.
  • Cancela em um único statement somente visitas PENDING, PENDING_REVIEW e SCHEDULED, com motivo CLIENT_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.
  • POST /api/auth/phone/start recebe pendingToken e phone. 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/verify recebe 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 409 e nunca é transferido.
  • POST /api/leads/my-quote cria ou atualiza a única cotação OPEN do lead autenticado/convidado. A identidade vem da sessão ou bearer; leadId do corpo não é aceito.
  • GET /api/atomic/leadQuotes fornece a fila administrativa autenticada para ADMIN/MANAGER; decisões usam as rotas específicas abaixo.
  • POST /api/atomic/leadQuotes/:id/confirm exige 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/decline manté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.