Files
root c2c9a29247
Build Fechamento de Caixa / build (macos-14, app) (push) Has been cancelled
Build Fechamento de Caixa / build (ubuntu-22.04, deb) (push) Has been cancelled
Build Fechamento de Caixa / build (windows-2022, msi) (push) Has been cancelled
docs: adicionar SPEC, SUPABASE_SCHEMA, API_INTEGRATION, BUILDS_FARM
2026-07-02 22:26:57 +00:00

5.1 KiB

Integração Frontend ↔ Tauri (Rust) ↔ Supabase

Visão geral da comunicação

┌─────────────────┐         ┌─────────────────┐         ┌──────────────────┐
│  JavaScript     │ invoke  │  Tauri/Rust     │ HTTP    │  Supabase       │
│  (index.html)   │────────▶│  commands       │────────▶│  (cloud)        │
│                 │◀────────│                 │◀────────│                 │
└─────────────────┘ response└─────────────────┘ response└──────────────────┘

O frontend nunca faz requisições HTTP direto para o Supabase. Toda comunicação passa pelos comandos Tauri (Rust).


Comandos Tauri disponíveis

App

Comando O que faz
get_loja Retorna a loja configurada
get_loja_fixa Retorna "Uniao", "Alianca" ou null (se build fixa)
set_loja(loja) Define a loja (bloqueado se build fixa)
get_config Retorna config completo { loja, pdv_nome, operador_default, ... }
set_config(cfg) Salva config

Storage (SQLite local)

Comando O que faz
salvar_fechamento(estado) Salva estado completo no SQLite local
carregar_rascunho(loja, data) Retorna último rascunho para loja+data
listar_fechamentos(loja, limite) Lista fechamentos de uma loja
buscar_fechamento_por_id(id) Busca por ID local
pendentes_sync Retorna fechamentos que ainda não foram syncados

Supabase

Comando O que faz
sb_salvar_fechamento(estado) Upsert no Supabase via service_role JWT
sb_carregar_rascunho(loja, data) Busca rascunho mais recente
sb_listar_recentes(loja, limite) Lista fechamentos recentes
sb_buscar_por_id(id) Busca por ID
sb_buscar_por_uuid(uuid) Busca por UUID
sb_buscar_por_id_fechamento(id_fechamento) Busca por chave natural
sb_atualizar_fechamento(id_fechamento, updates) PATCH campos específicos
sb_salvar_listas(loja, listas) Salva operadores/gerentes customizados
sb_carregar_listas(loja) Carrega listas salvas
sb_online Retorna true/false se Supabase está acessível

Printer

Comando O que faz
detectar_impressora Detecta EPSON TM-T20 USB
configurar_impressora(caminho) Define caminho da impressora
caminho_impressora Retorna caminho configurado
imprimir_recibo(html) Envia HTML puro para impressora
teste_impressora Imprime página de teste
ativar_modo_teste_impressao Ativa modo teste (salva PDF em vez de imprimir)

Fluxo de salvar um fechamento

// No frontend (index.html), quando operador clica "Salvar":
async function salvarFechamento() {
  const estado = buildEstado(); // coleta todos os campos do formulário

  // 1. Salva localmente (sempre funciona offline)
  await invoke('salvar_fechamento', { estado });

  // 2. Tenta sync com Supabase
  try {
    await invoke('sb_salvar_fechamento', { estado });
    toast('✅ Salvo e sincronizado');
  } catch(e) {
    // Supabase offline — fica pendente no SQLite
    toast('💾 Salvo localmente (sync pendente)');
  }
}

Como o Rust conversa com o Supabase

Em supabase.rs, o plugin usa reqwest (HTTP client) com:

fn headers(&self, use_service: bool) -> reqwest::header::HeaderMap {
    let key = if use_service { &self.service_role_key } else { &self.anon_key };
    let mut headers = reqwest::header::HeaderMap::new();
    headers.insert(
        reqwest::header::AUTHORIZATION,
        format!("Bearer {}", key).parse().unwrap(),
    );
    headers
}
  • use_service = true: para INSERT/UPDATE (salvar fechamento)
  • use_service = false: para GET (listar, buscar)

Upsert — salvar sem duplicar

O Supabase não tem UPSERT nativo via REST. O plugin usa um truque:

POST /fechamentos_web HTTP/1.1
Prefer: resolution=merge-duplicates

Se o id_fechamento já existe, o PostgREST faz um UPDATE em vez de INSERT. Se não existe, faz INSERT.


UUID vs id_fechamento

Campo O que é Quem gera
id ID sequencial do PostgreSQL Supabase (auto)
uuid UUID único do registro local Frontend JS (crypto.randomUUID())
id_fechamento Chave natural: {loja}_{data}_{operador} Frontend JS (construído na hora)

O id_fechamento é a chave de negócio. O uuid é para rastrear registros entre local e cloud.


Offline first — como funciona

  1. Operador/editasalvar_fechamento → SQLite (sempre funciona)
  2. Operador/editasb_salvar_fechamento → Supabase (só se online)
  3. Se offline: o fechamento fica no SQLite com sync_status = "local"
  4. Quando conecta: pendentes_sync retorna os pendentes → sync automático

O sync automático é controlado por sync_automatico na config da app.