Fechamento de Caixa — O Frangão

O que é

App desktop nativo para registrar o fechamento de caixa diário das lojas União e Aliança do O Frangão. Cada fechamento registra: saldo em dinheiro, cartões de crédito/débito/alimentação/PIX, vales, sangrias, despesas, PIX CNPJ, e itens a receber.

Ideia central

O app é um formulário inteligente que:

  1. Captura todos os dados de fechamento de caixa (dinheiro, cartões, despesas, etc.)
  2. Salva localmente em SQLite (funciona offline)
  3. Envia automaticamente para o Supabase (cloud) quando há conexão
  4. Gera um recibo térmico 80mm para impressão

O objetivo é substituir planilhas manuais e webhooks frágeis, dando uma fonte única de verdade para os dados de caixa.


Arquitetura geral

┌─────────────────┐     ┌──────────────────┐     ┌────────────────────┐
│  HTML/JS        │────▶│  Tauri (Rust)    │────▶│  SQLite (local)    │
│  (frontend)     │◀────│  plugins:        │◀────│  fechamentos.db     │
│                 │     │  app, storage,    │     │  - funciona offline │
│  - formulário   │     │  supabase,       │     │  - sync automático  │
│  - impressão    │     │  printer         │     └────────────────────┘
│  - estado JS    │     └────────┬─────────┘              │
└─────────────────┘              │                      ▼
                                │              ┌────────────────────┐
                                │              │  Supabase Cloud    │
                                │              │  (supabase.       │
                                └─────────────▶│   ofrangao.com.br) │
                                               │  - PostgreSQL     │
                                               │  - RLS + JWT auth │
                                               │  - API REST       │
                                               └────────────────────┘

Stack técnica

Camada Tecnologia
Frontend HTML5 + CSS + JavaScript vanilla (single-file src/index.html)
Runtime Tauri 2 (Rust + WebView2)
Dados local SQLite via rusqlite
Dados cloud Supabase — PostgreSQL + REST API
Impressão HTML → window.print() com CSS @media print (80mm)
Build Cross-compile Linux → Windows (x86_64-pc-windows-gnu)

Repositório

https://git.ofrangao.com.br/filipe/fechamento-caixa

Estrutura de arquivos

fechamento-caixa/
├── src/
│   └── index.html        ← Frontend completo (HTML + CSS + JS)
├── src-tauri/
│   ├── src/
│   │   ├── main.rs       ← Entry point + plugin initialization
│   │   └── plugins/
│   │       ├── app.rs      ← Config da app (loja, PDV, sync)
│   │       ├── storage.rs  ← SQLite local
│   │       ├── supabase.rs ← Sync com Supabase
│   │       ├── printer.rs  ← Impressão
│   │       └── escpos.rs   ← Helpers ESCPOS
│   └── tauri.conf.json   ← Config Tauri (janela, bundle, etc.)
├── SPEC.md              ← Este arquivo
├── SUPABASE_SCHEMA.md   ← Schema do banco de dados
├── API_INTEGRATION.md   ← Como o frontend se comunica com Supabase
└── BUILS_FARM.md        ← Como gerar fc-uniao.exe, fc-alianca.exe, fc-ambos.exe

Builds — 3 versões do app

O mesmo código gera 3 binários diferentes conforme a variável de ambiente DOBRADO_LOJA:

Downloads

Binário Loja Download
fc-uniao.exe Travada: UNIÃO Baixar
fc-alianca.exe Travada: ALIANÇA Baixar
fc-ambos.exe Seletor livre Baixar

Quando a loja é fixa, o seletor de loja no formulário é escondido via JavaScript e tentativas de mudar via API retornam erro.


Fluxo de um fechamento

1. Operador abre o app
   ↓
2. Seleciona Data, Operador, Turno, Loja (se não for fixa)
   ↓
3. Preenche os campos:
   - Saldo de Troy
   - Cartões (crédito, débito, alimentação, PIX) — um valor por vez
   - Despesas (descrição + valor)
   - Sangrias (hora + gerente + valor)
   - PIX CNPJ (nome + valor)
   - Vales (nome + observação + valor)
   - A Receber (nome + valor)
   - Cancelamentos (número + motivo + valor)
   ↓
4. App calcula:
   TOTAL SISTEMA = soma de todos os campos acima
   DIFERENÇA = TOTAL SISTEMA  Saldo Esperado  Cancelamentos
   ↓
5. Operador clica "💾 Salvar / Sincronizar"
   → Salva em SQLite local
   → Envia para Supabase (se online)
   ↓
6. Operador clica "🖨️ Imprimir"
   → Abre preview do recibo 80mm
   → window.print() para impressora térmica

Tauri — o runtime desktop

O app roda como Tauri 2, um runtime que embute um navegador WebView2 (Windows) dentro de um processo Rust.

O que o Tauri fornece

Recurso Como é usado
Janela nativa A janela do app com barra de título, controls de redimensionar, ícone
Sistema de arquivos Lê/escreve config.json e fechamento.db em %LOCALAPPDATA%/FechamentoCaixa/
Invocação de comandos Rust Frontend JS chama invoke('nome_comando', args) → Rust executa e retorna
HTTP client Plugin supabase.rs usa reqwest para falar com o Supabase
Shell Abre diálogo de impressoras, executa cmd /C copy para impressão
Diálogos nativos tauri_plugin_dialog para escolher arquivos, pastas, impressora

Comandos Tauri (Rust → JS)

O frontend nunca acessa Supabase, SQLite ou impressora diretamente. Tudo passa por invoke:

// Salvar fechamento (SQLite + Supabase)
await invoke('salvar_fechamento', { estado });

// Sync com Supabase
await invoke('sb_salvar_fechamento', { estado });

// Detectar impressora
await invoke('detectar_impressora');

// Imprimir
await invoke('imprimir_recibo', { html: reciboHTML });

Estrutura dos plugins Rust

src-tauri/src/plugins/
├── app.rs        — Config da app (loja, operador default, sync)
├── storage.rs    — SQLite local (fonte primária offline)
├── supabase.rs   — Cliente HTTP para Supabase (service_role JWT)
├── printer.rs    — Detecção EPSON TM-T20, fallback para window.print()
└── escpos.rs    — Helpers ESCPOS (alinhamento, negrito, corte)

Onde os dados ficam

Dado Local
Config (SUPABASE keys, loja default) %LOCALAPPDATA%/FechamentoCaixa/config.json
Banco SQLite (fechamentos) %LOCALAPPDATA%/FechamentoCaixa/fechamento.db
Rascunho auto-save %LOCALAPPDATA%/FechamentoCaixa/fechamento_rascunho.db

Autores & Contexto

  • Desenvolvedor: Filipe.Tavares
  • Dono das lojas: O Frangão — União e Aliança
  • Objetivo: Substituir planilhas manuais e webhooks n8n por um sistema de fechamento de caixa confiável e offline-first
S
Description
Fechamento de Caixa - O Frangão (Tauri 2)
Readme 62 MiB
v2.0.4-debug Latest
2026-07-05 18:58:38 +00:00
Languages
HTML 71.9%
Rust 28.1%