# Schema do Supabase — Fechamento de Caixa ## Servidor - **URL:** `https://supabase.ofrangao.com.br` - **Instância:** O Frangão — PostgreSQL hospedado --- ## Tabela principal: `fechamentos_web` ```sql CREATE TABLE public.fechamentos_web ( id SERIAL PRIMARY KEY, id_fechamento TEXT UNIQUE NOT NULL, -- chave natural: {loja}_{data}_{operador} loja TEXT NOT NULL, -- "Uniao" | "Alianca" data DATE NOT NULL, -- data do fechamento (YYYY-MM-DD) operador TEXT NOT NULL, -- nome do operador turno TEXT NOT NULL, -- "manha" | "tarde" observacoes TEXT DEFAULT 'rascunho', -- "rascunho" | "finalizado" -- Totais de fechamento (campos escalares) fechamento_dinheiro REAL DEFAULT 0, -- dinheiro no caixa fechamento_cartoes REAL DEFAULT 0, -- total cartões fechamento_receber REAL DEFAULT 0, -- a receber fechamento REAL DEFAULT 0, -- TOTAL: dinheiro + cartões + receber -- Totais do sistema (valores lidos do sistema PAF-ECF) sys_total REAL DEFAULT 0, -- soma: troco+crédito+débito+alimentação+vales+receber+pixCartao+pixCnpj saldo_esperado REAL DEFAULT 0, -- quanto deveria ter (informado pelo operador) -- Controle criado_em TIMESTAMPTZ DEFAULT NOW(), atualizado_em TIMESTAMPTZ DEFAULT NOW(), enviado_por TEXT, ip_origem TEXT, user_agent TEXT, -- Dados variáveis em formato livre (JSONB) dados JSONB DEFAULT '{}'::jsonb ); ``` ### Comentários sobre colunas | Coluna | O que guarda | |--------|-------------| | `id_fechamento` | Chave natural única. Ex: `uniao_2026-06-19_filipe`. Formato: `{loja}_{data}_{operador}` em minúsculas, espaços → `_` | | `sys_total` | Total calculado pelo sistema — é a soma de **todos** os campos de cartão + vales + despesas + sangrias + etc | | `saldo_esperado` | Valor informado pelo operador — o quanto ele espera ter em caixa | | `dados` | JSONB com todos os arrays: `cartoes_credito[]`, `cartoes_debito[]`, `cartoes_alimentacao[]`, `cartoes_pix[]`, `despesas[]`, `sangrias[]`, `pixcnpj[]`, `vales[]`, `receber[]`, `cancelamentos[]` | | `observacoes` | `rascunho` enquanto.edita, `finalizado` quando o operador confirma | --- ## Fórmula de diferença ``` DIFERENÇA = sys_total − saldo_esperado − total_cancelamentos ``` Se `DIFERENÇA = 0` → ✅ OK (caixa fecha perfeito) Se `DIFERENÇA > 0` → ⚠️ Sobrou dinheiro Se `DIFERENÇA < 0` → 🔴 Faltou dinheiro --- ## Colunas dentro do JSONB `dados` ```json { "cartoes_credito": [152.00, 123.50, ...], "cartoes_debito": [15.45, 20.00, ...], "cartoes_alimentacao": [12.55, ...], "cartoes_pix": [112.50, ...], "despesas": [{"desc": "luz", "valor": 150.00}, ...], "sangrias": [{"hora": "14:30", "gerente": "João", "retirada": 50.00, "valor": 50.00}, ...], "pixcnpj": [{"nome": "João Silva", "valor": 80.00}, ...], "vales": [{"nome": "Maria", "obs": "vale transporte", "valor": 30.00}, ...], "receber": [{"nome": "Pedro", "valor": 45.00}, ...], "cancelamentos": [{"numero": "001", "motivo": "erro digitação", "valor": 25.00}, ...] } ``` --- ## Row Level Security (RLS) A tabela usa RLS com duas políticas: 1. **Anon (chave pública):** pode ler registros 2. **Service role:** pode ler + escrever registros (usado pelo app com JWT service_role) ### Chave anon (pública) Usada para consultasreadonly pelo frontend. ### Chave service_role Usada pelo app Tauri para INSERT/UPDATE via plugin `supabase.rs`. Esta chave **nunca deve ser exposta publicamente** — está embedada no binário compilado. --- ## Endpoints da API REST Base: `https://supabase.ofrangao.com.br/rest/v1/` | Método | Endpoint | Uso | |--------|----------|-----| | `GET` | `/fechamentos_web?loja=eq.uniao&data=eq.2026-06-19&select=*` | Lista fechamentos | | `GET` | `/fechamentos_web?id_fechamento=eq.uniao_2026-06-19_filipe` | Busca por chave | | `POST` | `/fechamentos_web` | Cria/atualiza (upsert via `Prefer: resolution=merge-duplicates`) | | `PATCH` | `/fechamentos_web?id_fechamento=eq.uniao_2026-06-19_filipe` | Atualiza campos | --- ## Header de autenticação ```http Authorization: Bearer {SUPABASE_SERVICE_ROLE_JWT} apikey: {SUPABASE_ANON_KEY} Content-Type: application/json Prefer: resolution=merge-duplicates (para upsert no POST) ``` --- ## Supabase — Configuração do projeto - **Projeto:** O Frangão - **Host:** `https://supabase.ofrangao.com.br` - **Banco:** PostgreSQL 15+ - **API:** REST via PostgREST - **Auth:** JWT (anon key + service role key) O app busca a service_role key via `config.json` local (em `%LOCALAPPDATA%/FechamentoCaixa/config.json`). O fallback é a chave embedada no binário. ```json // config.json (opcional — sobrepõe a embedada) { "SUPABASE_ANON_KEY": "sb_publishable_...", "SUPABASE_SERVICE_KEY": "sb_secret_..." } ```