""" SQLite database for simplicity. Can be swapped for PostgreSQL. """ import aiosqlite import os from datetime import datetime DB_PATH = os.getenv("DATABASE_PATH", "/data/tickethub.db") async def get_db(): db = await aiosqlite.connect(DB_PATH) db.row_factory = aiosqlite.Row return db async def init_db(): os.makedirs(os.path.dirname(DB_PATH), exist_ok=True) db = await get_db() await db.executescript(""" CREATE TABLE IF NOT EXISTS projects ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, key TEXT UNIQUE NOT NULL, description TEXT, webhook_url TEXT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, ticket_sequence INTEGER DEFAULT 0 ); CREATE TABLE IF NOT EXISTS tickets ( id INTEGER PRIMARY KEY AUTOINCREMENT, project_id INTEGER NOT NULL, key TEXT UNIQUE NOT NULL, title TEXT NOT NULL, description TEXT, status TEXT DEFAULT 'open', priority TEXT DEFAULT 'medium', labels TEXT DEFAULT '[]', created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (project_id) REFERENCES projects(id) ); CREATE TABLE IF NOT EXISTS comments ( id INTEGER PRIMARY KEY AUTOINCREMENT, ticket_id INTEGER NOT NULL, author TEXT NOT NULL, content TEXT NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (ticket_id) REFERENCES tickets(id) ); CREATE TABLE IF NOT EXISTS webhooks ( id INTEGER PRIMARY KEY AUTOINCREMENT, project_id INTEGER NOT NULL, url TEXT NOT NULL, events TEXT DEFAULT '["ticket.created","ticket.updated","comment.added"]', active INTEGER DEFAULT 1, FOREIGN KEY (project_id) REFERENCES projects(id) ); CREATE INDEX IF NOT EXISTS idx_tickets_project ON tickets(project_id); CREATE INDEX IF NOT EXISTS idx_tickets_status ON tickets(status); CREATE INDEX IF NOT EXISTS idx_comments_ticket ON comments(ticket_id); """) await db.commit() await db.close()