import { randomUUID } from 'node:crypto'; import { getConnection } from '@/modules/database/connection.js'; type ProjectRow = { project_id: string; project_path: string; custom_project_name: string | null; isStarred: number; isArchived: number; }; export const projectsDb = { createProjectPath(projectPath: string, customProjectName: string | null = null): void { const db = getConnection(); db.prepare(` INSERT INTO projects (project_id, project_path, custom_project_name) VALUES (?, ?, ?) ON CONFLICT(project_path) DO UPDATE SET custom_project_name = CASE WHEN projects.custom_project_name IS NULL OR projects.custom_project_name = '' THEN excluded.custom_project_name ELSE projects.custom_project_name END `).run(randomUUID(), projectPath, customProjectName); }, getProjectPath(projectPath: string): ProjectRow | null { const db = getConnection(); const row = db.prepare(` SELECT project_id, project_path, custom_project_name, isStarred, isArchived FROM projects WHERE project_path = ? `).get(projectPath) as ProjectRow | undefined; return row ?? null; }, getProjectById(projectId: string): ProjectRow | null { const db = getConnection(); const row = db.prepare(` SELECT project_id, project_path, custom_project_name, isStarred, isArchived FROM projects WHERE project_id = ? `).get(projectId) as ProjectRow | undefined; return row ?? null; }, /** * Resolve the absolute project directory from a database project_id. * * This is the canonical lookup used after the projectName → projectId migration: * API routes receive the DB-assigned `projectId` and must resolve the real folder * path through this helper before touching the filesystem. Returns `null` when the * project row does not exist so callers can respond with a 404. */ getProjectPathById(projectId: string): string | null { const db = getConnection(); const row = db.prepare(` SELECT project_path FROM projects WHERE project_id = ? `).get(projectId) as Pick | undefined; return row?.project_path ?? null; }, getProjectPaths(): ProjectRow[] { const db = getConnection(); return db.prepare(` SELECT project_id, project_path, custom_project_name, isStarred, isArchived FROM projects `).all() as ProjectRow[]; }, getCustomProjectName(projectPath: string): string | null { const db = getConnection(); const row = db.prepare(` SELECT custom_project_name FROM projects WHERE project_path = ? `).get(projectPath) as Pick | undefined; return row?.custom_project_name ?? null; }, updateCustomProjectName(projectPath: string, customProjectName: string | null): void { const db = getConnection(); db.prepare(` INSERT INTO projects (project_id, project_path, custom_project_name) VALUES (?, ?, ?) ON CONFLICT(project_path) DO UPDATE SET custom_project_name = excluded.custom_project_name `).run(randomUUID(), projectPath, customProjectName); }, updateCustomProjectNameById(projectId: string, customProjectName: string | null): void { const db = getConnection(); db.prepare(` UPDATE projects SET custom_project_name = ? WHERE project_id = ? `).run(customProjectName, projectId); }, updateProjectIsStarred(projectPath: string, isStarred: boolean): void { const db = getConnection(); db.prepare(` UPDATE projects SET isStarred = ? WHERE project_path = ? `).run(isStarred ? 1 : 0, projectPath); }, updateProjectIsStarredById(projectId: string, isStarred: boolean): void { const db = getConnection(); db.prepare(` UPDATE projects SET isStarred = ? WHERE project_id = ? `).run(isStarred ? 1 : 0, projectId); }, updateProjectIsArchived(projectPath: string, isArchived: boolean): void { const db = getConnection(); db.prepare(` UPDATE projects SET isArchived = ? WHERE project_path = ? `).run(isArchived ? 1 : 0, projectPath); }, updateProjectIsArchivedById(projectId: string, isArchived: boolean): void { const db = getConnection(); db.prepare(` UPDATE projects SET isArchived = ? WHERE project_id = ? `).run(isArchived ? 1 : 0, projectId); }, deleteProjectPath(projectPath: string): void { const db = getConnection(); db.prepare(` DELETE FROM projects WHERE project_path = ? `).run(projectPath); }, deleteProjectById(projectId: string): void { const db = getConnection(); db.prepare(` DELETE FROM projects WHERE project_id = ? `).run(projectId); }, };