use rusqlite::Connection; pub fn init_db(conn: &Connection) -> Result<(), rusqlite::Error> { conn.execute( "CREATE TABLE IF NOT EXISTS clients ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, email TEXT, address TEXT, created_at TEXT DEFAULT CURRENT_TIMESTAMP )", [], )?; // Migrate clients table — add new columns (safe to re-run) let migration_columns = [ "ALTER TABLE clients ADD COLUMN company TEXT", "ALTER TABLE clients ADD COLUMN phone TEXT", "ALTER TABLE clients ADD COLUMN tax_id TEXT", "ALTER TABLE clients ADD COLUMN payment_terms TEXT", "ALTER TABLE clients ADD COLUMN notes TEXT", ]; for sql in &migration_columns { match conn.execute(sql, []) { Ok(_) => {} Err(e) => { let msg = e.to_string(); if !msg.contains("duplicate column") { return Err(e); } } } } conn.execute( "CREATE TABLE IF NOT EXISTS projects ( id INTEGER PRIMARY KEY AUTOINCREMENT, client_id INTEGER, name TEXT NOT NULL, hourly_rate REAL DEFAULT 0, color TEXT DEFAULT '#F59E0B', archived INTEGER DEFAULT 0, created_at TEXT DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (client_id) REFERENCES clients(id) )", [], )?; conn.execute( "CREATE TABLE IF NOT EXISTS tasks ( id INTEGER PRIMARY KEY AUTOINCREMENT, project_id INTEGER NOT NULL, name TEXT NOT NULL, created_at TEXT DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (project_id) REFERENCES projects(id) )", [], )?; conn.execute( "CREATE TABLE IF NOT EXISTS time_entries ( id INTEGER PRIMARY KEY AUTOINCREMENT, project_id INTEGER NOT NULL, task_id INTEGER, description TEXT, start_time TEXT NOT NULL, end_time TEXT, duration INTEGER DEFAULT 0, created_at TEXT DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (project_id) REFERENCES projects(id), FOREIGN KEY (task_id) REFERENCES tasks(id) )", [], )?; conn.execute( "CREATE TABLE IF NOT EXISTS invoices ( id INTEGER PRIMARY KEY AUTOINCREMENT, client_id INTEGER NOT NULL, invoice_number TEXT NOT NULL, date TEXT NOT NULL, due_date TEXT, subtotal REAL DEFAULT 0, tax_rate REAL DEFAULT 0, tax_amount REAL DEFAULT 0, discount REAL DEFAULT 0, total REAL DEFAULT 0, notes TEXT, status TEXT DEFAULT 'draft', created_at TEXT DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (client_id) REFERENCES clients(id) )", [], )?; conn.execute( "CREATE TABLE IF NOT EXISTS invoice_items ( id INTEGER PRIMARY KEY AUTOINCREMENT, invoice_id INTEGER NOT NULL, description TEXT NOT NULL, quantity REAL DEFAULT 1, rate REAL DEFAULT 0, amount REAL DEFAULT 0, time_entry_id INTEGER, FOREIGN KEY (invoice_id) REFERENCES invoices(id), FOREIGN KEY (time_entry_id) REFERENCES time_entries(id) )", [], )?; conn.execute( "CREATE TABLE IF NOT EXISTS settings ( key TEXT PRIMARY KEY, value TEXT )", [], )?; // Insert default settings conn.execute( "INSERT OR IGNORE INTO settings (key, value) VALUES ('hourly_rate', '50')", [], )?; conn.execute( "INSERT OR IGNORE INTO settings (key, value) VALUES ('idle_detection', 'true')", [], )?; conn.execute( "INSERT OR IGNORE INTO settings (key, value) VALUES ('idle_timeout', '5')", [], )?; conn.execute( "INSERT OR IGNORE INTO settings (key, value) VALUES ('reminder_interval', '30')", [], )?; Ok(()) }