143 lines
4.9 KiB
Markdown
143 lines
4.9 KiB
Markdown
# 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_..."
|
||
}
|
||
```
|