//! Fechamento de Caixa — O Frangão //! App desktop nativo (Tauri 2 + Rust) //! Substitui: n8n webhooks + localStorage/IndexedDB + window.print() #![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] mod plugins; use log::LevelFilter; use plugins::printer::{self}; use plugins::storage::{self}; use plugins::supabase::{self}; use std::fs; use std::path::PathBuf; fn data_dir_path() -> PathBuf { dirs::data_local_dir() .unwrap_or_else(|| PathBuf::from(".")) .join("FechamentoCaixa") } fn load_config() -> (String, String) { let cfg_path = data_dir_path().join("config.json"); if let Ok(content) = fs::read_to_string(&cfg_path) { if let Ok(cfg) = serde_json::from_str::(&content) { let anon = cfg.get("SUPABASE_ANON_KEY") .and_then(|v| v.as_str()) .unwrap_or("") .to_string(); let service = cfg.get("SUPABASE_SERVICE_KEY") .and_then(|v| v.as_str()) .unwrap_or("") .to_string(); if !anon.is_empty() && !service.is_empty() { return (anon, service); } } } // Fallback: tenta variáveis de ambiente ( std::env::var("SUPABASE_ANON_KEY").unwrap_or_default(), std::env::var("SUPABASE_SERVICE_KEY").unwrap_or_default(), ) } fn main() { env_logger::Builder::new() .filter_level(LevelFilter::Info) .format_timestamp_millis() .init(); log::info!("=== Fechamento de Caixa (Tauri) ==="); let data_dir = data_dir_path(); fs::create_dir_all(&data_dir).expect("não foi possível criar diretório de dados"); log::info!("Data dir: {:?}", data_dir); // Carrega chaves do Supabase let (anon_key, service_key) = load_config(); if anon_key.is_empty() || service_key.is_empty() { log::warn!("SUPABASE_ANON_KEY ou SUPABASE_SERVICE_KEY não encontradas!"); log::warn!("Cole-as em: {:?}", data_dir.join("config.json")); log::warn!("Formato: {{\"SUPABASE_ANON_KEY\": \"...\", \"SUPABASE_SERVICE_KEY\": \"...\"}}"); } else { log::info!("Supabase: keys carregadas (anon={}..., service={}...)", &anon_key[..8.min(anon_key.len())], &service_key[..8.min(service_key.len())]); } // Inicializa plugins let storage = storage::init(data_dir.clone()) .expect("falha ao inicializar SQLite"); let supabase = supabase::init(anon_key, service_key); let printer = printer::init(); let app_state = plugins::app::init(data_dir.clone()); log::info!("Plugins inicializados: storage, supabase, printer"); tauri::Builder::default() .plugin(tauri_plugin_shell::init()) .plugin(tauri_plugin_dialog::init()) .plugin(tauri_plugin_fs::init()) .manage(storage) .manage(supabase) .manage(printer) .manage(app_state) .invoke_handler(tauri::generate_handler![ // Storage plugins::storage::salvar_fechamento, plugins::storage::carregar_rascunho, plugins::storage::listar_fechamentos, plugins::storage::buscar_fechamento_por_id, plugins::storage::pendentes_sync, // Supabase plugins::supabase::sb_salvar_fechamento, plugins::supabase::sb_carregar_rascunho, plugins::supabase::sb_listar_recentes, plugins::supabase::sb_buscar_por_id, plugins::supabase::sb_salvar_listas, plugins::supabase::sb_carregar_listas, plugins::supabase::sb_online, // Printer plugins::printer::detectar_impressora, plugins::printer::configurar_impressora, plugins::printer::caminho_impressora, plugins::printer::imprimir_recibo, plugins::printer::teste_impressora, plugins::printer::ativar_modo_teste_impressao, // App plugins::app::get_loja, plugins::app::set_loja, plugins::app::get_config, plugins::app::set_config, ]) .run(tauri::generate_context!()) .expect("erro ao inicializar Tauri"); }