"""FlowDeck — Database layer (SQLite with WAL mode).""" from __future__ import annotations import sqlite3 from contextlib import contextmanager from pathlib import Path def get_db_path() -> Path: from app.config import settings return settings.db_path def init_db(): """Create tables if they don't exist.""" db_path = get_db_path() db_path.parent.mkdir(parents=True, exist_ok=True) with get_conn() as conn: conn.execute("PRAGMA journal_mode=WAL") conn.execute("PRAGMA foreign_keys=ON") conn.executescript(""" CREATE TABLE IF NOT EXISTS boards ( id INTEGER PRIMARY KEY AUTOINCREMENT, project_owner TEXT NOT NULL, project_name TEXT NOT NULL, columns_json TEXT NOT NULL DEFAULT '["Backlog","À faire","En cours","Révision","Terminé"]', wip_limits_json TEXT DEFAULT '{}', created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, UNIQUE(project_owner, project_name) ); CREATE TABLE IF NOT EXISTS cards ( id INTEGER PRIMARY KEY AUTOINCREMENT, board_id INTEGER NOT NULL REFERENCES boards(id), gitea_issue_id INTEGER, column_name TEXT NOT NULL DEFAULT 'Backlog', position INTEGER NOT NULL DEFAULT 0, priority TEXT DEFAULT 'Medium', due_date TEXT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE IF NOT EXISTS notes ( id INTEGER PRIMARY KEY AUTOINCREMENT, project_owner TEXT NOT NULL, project_name TEXT NOT NULL, title TEXT NOT NULL DEFAULT 'Notes', content TEXT NOT NULL DEFAULT '', created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, UNIQUE(project_owner, project_name, title) ); CREATE TABLE IF NOT EXISTS col_mapping ( id INTEGER PRIMARY KEY AUTOINCREMENT, board_id INTEGER NOT NULL REFERENCES boards(id), column_name TEXT NOT NULL, gitea_label TEXT NOT NULL, close_issue BOOLEAN NOT NULL DEFAULT 0, UNIQUE(board_id, column_name) ); """) conn.commit() @contextmanager def get_conn(): """Yield a SQLite connection (WAL mode, foreign keys on).""" db_path = get_db_path() conn = sqlite3.connect(str(db_path)) conn.row_factory = sqlite3.Row conn.execute("PRAGMA journal_mode=WAL") conn.execute("PRAGMA foreign_keys=ON") try: yield conn finally: conn.close()