import { dbGlobal } from "drizzle-pkg/lib/db"; import { projects } from "drizzle-pkg/lib/schema/content"; import { desc, sql, eq } from "drizzle-orm"; // ============ Types ============ export interface ProjectItem { id: number; name: string; tags: string | null; description: string | null; path: string | null; createdAt: Date; updatedAt: Date; } export interface CreateProjectInput { name: string; tags?: string | null; description?: string | null; path?: string | null; } export interface UpdateProjectInput { name?: string; tags?: string | null; description?: string | null; path?: string | null; } // ============ CRUD ============ export async function listProjects(opts: { page?: number; pageSize?: number; }): Promise<{ items: ProjectItem[]; total: number; page: number; pageSize: number; hasMore: boolean }> { const page = opts.page ?? 1; const pageSize = opts.pageSize ?? 30; const [rows, countResult] = await Promise.all([ dbGlobal .select() .from(projects) .orderBy(desc(projects.createdAt)) .limit(pageSize) .offset((page - 1) * pageSize), dbGlobal .select({ count: sql`count(*)` }) .from(projects), ]); let total = 0; if (countResult && countResult.length > 0) { total = (countResult[0] as any).count ?? 0; } const items: ProjectItem[] = rows.map((row) => ({ id: row.id, name: row.name, tags: row.tags, description: row.description, path: row.path, createdAt: row.createdAt, updatedAt: row.updatedAt, })); return { items, total, page, pageSize, hasMore: page * pageSize < total, }; } export async function getProject(id: number): Promise { const [row] = await dbGlobal .select() .from(projects) .where(eq(projects.id, id)) .limit(1); if (!row) return null; return { id: row.id, name: row.name, tags: row.tags, description: row.description, path: row.path, createdAt: row.createdAt, updatedAt: row.updatedAt, }; } export async function createProject(input: CreateProjectInput): Promise { const [inserted] = await dbGlobal .insert(projects) .values({ name: input.name, tags: input.tags || null, description: input.description || null, path: input.path || null, }) .returning({ id: projects.id }); if (!inserted) throw new Error("Failed to create project"); return { id: inserted.id, name: input.name, tags: input.tags || null, description: input.description || null, path: input.path || null, createdAt: new Date(), updatedAt: new Date(), }; } export async function updateProject(id: number, input: UpdateProjectInput): Promise { const values: Record = {}; if (input.name !== undefined) values.name = input.name; if (input.tags !== undefined) values.tags = input.tags; if (input.description !== undefined) values.description = input.description; if (input.path !== undefined) values.path = input.path; await dbGlobal .update(projects) .set(values) .where(eq(projects.id, id)); } export async function deleteProject(id: number): Promise { await dbGlobal .delete(projects) .where(eq(projects.id, id)); }