diff --git a/PROJECT_HISTORY.md b/PROJECT_HISTORY.md new file mode 100644 index 0000000..779e8a3 --- /dev/null +++ b/PROJECT_HISTORY.md @@ -0,0 +1,164 @@ +# Histórico do Projeto — Fechamento de Caixa O Frangão + +## Contexto + +**Dono:** Filipe.Tavares — O Frangão (lojas União e Aliança) +**Problema original:** Planilhas manuais + webhooks n8n frágeis para registrar fechamento de caixa +**Solução:** App desktop Tauri 2 + SQLite offline + Supabase cloud + impressão térmica 80mm + +--- + +## Repositório + +``` +https://git.ofrangao.com.br/filipe/fechamento-caixa +``` + +--- + +## 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`) | + +--- + +## Releases + +| Tag | Data | Descrição | +|-----|------|-----------| +| `v2.0.4-alianca` | 2026-07-05 | Fix preview modal re-open + sys_total recalc | +| `v2.0.3-uniao` | 2026-07-05 | Fix diferença cálculo from array | +| `v2.0.2-uniao` | 2026-07-05 | Fix buildPrintHTML sys_total | +| `v2.0.1-uniao` | 2026-07-05 | Builds separadas + docs | +| `v2.0.0-uniao/alianca/ambos` | 2026-07-04 | Lançamento — app completo com Tauri 2 | + +--- + +## Bugs Corrigidos (desde v2.0.0) + +### Preview + Modal (v2.0.4) +- **237ceab** — `confirm-print` não fechava mais o modal antes de abrir o preview; `openPrintPreview` reabria o modal ao fechar se ele ainda estava aberto +- **73c2027** — `closeConfirmModal()` era chamada antes de `openPrintPreview()` — preview cobria o modal, mas ao fechar voltava pro form +- **56a2ed5** — `buildPrintHTML` usava `data.diferenca` (precomputado, stale) em vez de recalcular `sys_total - saldo_esperado - cancelamentos` inline + +### Cálculo da Diferença (v2.0.3) +- **acb90f0** — `diferenca` sempre recalculada da array de cancelamentos (não do escalar `total_cancelamentos`) +- **6eb08b6** — mesmo fix em `buildReportHTML`, `buildPrintHTML`, `buildConfirmHTML` +- **5a01264** — ignora `data.diferenca` pré-computado, recalcula sempre de `sys_total` + +### Rust ESCPOS (v2.0.3) +- **733519e** — Rust `to_escpos`: diferença = `sys_total - saldo_esperado - total_cancelamentos` (não mais `fechamento`) + +### CSS / Layout (v2.0.2) +- **6440b26** — `buildReportHTML`: diferença = `sysTotal - saldoEsp - cancelamentos` +- **420e104** — `buildConfirmHTML` e `buildPrintHTML` usavam `sysTotal`/`total_cancelamentos` em vez de `sys_total`/`cancelamentos` +- **b04e5ac** — `.main min-height:0` (footer invisível em resoluções pequenas) +- **65c444a** — seletor loja escondia errado (caracteres asiáticos no DOM) +- **2bfbf29** — values das options de loja sem acento (`Uniao`/`Alianca`) — alinhado com `LOJA_FIXA` do Rust + +### Impressão (v2.0.1) +- **b1585af / 155782f / 16972f4 / d3d5c4f** — fonte 18px→22px bold nos relatórios e preview +- **5f1d9a4 / cc45ed9** — botão "Dia Anterior" agora exige senha antes de abrir + +### Builds (v2.0.0) +- **659d977** — `DOBRADO_LOJA` injetado via env no build — 3 binários: `fc-uniao.exe`, `fc-alianca.exe`, `fc-ambos.exe` + +--- + +## Bugs Pendentes (conhecidos) + +| # | Bug | Prioridade | Status | +|---|-----|-----------|--------| +| #6 | `salvarEdicaoModal` reconstrói `id_fechamento` dos inputs em vez de usar `full.id_fechamento` — PATCH pode errar se operador mudar loja/data/operador | Média | Pendente | + +--- + +## Arquitetura de Dados + +### SQLite local (offline-first) +``` +%LOCALAPPDATA%/FechamentoCaixa/fechamento.db +``` + +### Supabase cloud +``` +https://supabase.ofrangao.com.br +Tabela: fechamentos_web +``` + +### Fluxo de sync +``` +App abre → carrega rascunho do SQLite → operador trabalha offline + ↓ + operador clica "Salvar/Sincronizar" + ↓ + 1. Salva em SQLite local + 2. Envia para Supabase (se online) + ↓ + operador clica "Imprimir" + ↓ + window.print() → receipt 80mm +``` + +--- + +## Comandos Tauri (frontend chama via `invoke`) + +| Comando | Descrição | +|---------|-----------| +| `salvar_fechamento` | Salva estado no SQLite local | +| `carregar_rascunho` | Carrega rascunho por loja+data | +| `sb_salvar_fechamento` | POST para Supabase | +| `sb_listar_recentes` | Lista fechamentos recentes | +| `sb_buscar_por_id` | Busca por ID numérico | +| `sb_buscar_por_uuid` | Busca por UUID | +| `detectar_impressora` | Detecta EPSON TM-T20 | +| `imprimir_recibo` | Imprime via ESCPOS ou fallback window.print() | + +--- + +## Builds — 3 versões + +| Binário | Loja | Seletor | +|---------|------|---------| +| `fc-uniao.exe` | Fixa: UNIÃO | Escondido | +| `fc-alianca.exe` | Fixa: ALIANÇA | Escondido | +| `fc-ambos.exe` | Livre | Dropdown visível | + +### Como buildar + +```bash +cd src-tauri/ + +# UNIÃO +DOBRADO_LOJA=Uniao cargo build --release --target x86_64-pc-windows-gnu + +# ALIANÇA +DOBRADO_LOJA=Alianca cargo build --release --target x86_64-pc-windows-gnu + +# AMBOS +cargo build --release --target x86_64-pc-windows-gnu +``` + +--- + +## Lições Aprendidas + +1. **Cálculos sempre inline** — nunca usar valores pré-computados (`data.diferenca`, `data.total_cancelamentos`) que podem estar stale. Sempre recalcular da fonte. +2. **Fechar modal ANTES de abrir overlay** — se um modal vai ser coberto por outro, fechar primeiro e reabrir depois (salvar estado). +3. **Cross-compile Linux→Windows** — funciona perfeitamente com `x86_64-pc-windows-gnu` target. +4. **Gitea API** — `Authorization: token {TOKEN}` (minúsculo `token`) funciona; `Token {TOKEN}` não. Upload de assets funciona; DELETE de assets retorna 404 (bug do Gitea?). + +--- + +## Autores + +- **Filipe.Tavares** — dono das lojas / demandante +- **Hermes Agent** — desenvolvimento + debugging