execute('DROP TABLE IF EXISTS project_members'); $database->execute('DROP TABLE IF EXISTS tasks'); $database->execute('DROP TABLE IF EXISTS activity_log'); $database->execute('DROP TABLE IF EXISTS projects'); $database->execute( 'CREATE TABLE IF NOT EXISTS projects ( id INTEGER PRIMARY KEY AUTOINCREMENT, code VARCHAR(32) NOT NULL UNIQUE, name VARCHAR(120) NOT NULL, client_name VARCHAR(120) NOT NULL, description TEXT NOT NULL, status VARCHAR(20) NOT NULL DEFAULT "planned", start_date DATE NOT NULL, due_date DATE NULL, budget_cents INTEGER NOT NULL DEFAULT 0, owner_name VARCHAR(120) NOT NULL, color_token VARCHAR(32) NOT NULL DEFAULT "teal", created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP )' ); $database->execute( 'CREATE TABLE IF NOT EXISTS project_members ( id INTEGER PRIMARY KEY AUTOINCREMENT, project_id INTEGER NOT NULL, full_name VARCHAR(120) NOT NULL, role VARCHAR(80) NOT NULL, allocation_percent INTEGER NOT NULL DEFAULT 0, is_primary INTEGER NOT NULL DEFAULT 0, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE )' ); $database->execute( 'CREATE TABLE IF NOT EXISTS tasks ( id INTEGER PRIMARY KEY AUTOINCREMENT, project_id INTEGER NOT NULL, title VARCHAR(140) NOT NULL, description TEXT NOT NULL, status VARCHAR(20) NOT NULL DEFAULT "backlog", priority VARCHAR(20) NOT NULL DEFAULT "normal", assignee VARCHAR(100) NOT NULL, estimate_hours REAL NULL, due_date DATE NULL, position INTEGER NOT NULL DEFAULT 0, completed_at DATETIME NULL, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE )' ); $database->execute( 'CREATE TABLE IF NOT EXISTS activity_log ( id INTEGER PRIMARY KEY AUTOINCREMENT, project_id INTEGER NULL, task_id INTEGER NULL, event_type VARCHAR(40) NOT NULL, headline VARCHAR(180) NOT NULL, detail TEXT NOT NULL, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE, FOREIGN KEY (task_id) REFERENCES tasks(id) ON DELETE CASCADE )' ); $database->execute('CREATE INDEX IF NOT EXISTS idx_tasks_project_status ON tasks (project_id, status, due_date)'); $database->execute('CREATE INDEX IF NOT EXISTS idx_activity_project_created ON activity_log (project_id, created_at DESC)'); $database->execute('CREATE INDEX IF NOT EXISTS idx_project_members_project_primary ON project_members (project_id, is_primary DESC)'); } public function down(Database $database): void { $database->execute('DROP TABLE IF EXISTS activity_log'); $database->execute('DROP TABLE IF EXISTS tasks'); $database->execute('DROP TABLE IF EXISTS project_members'); $database->execute('DROP TABLE IF EXISTS projects'); } };