You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

136 lines
3.2 KiB

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<number>`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<ProjectItem | null> {
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<ProjectItem> {
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<void> {
const values: Record<string, any> = {};
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<void> {
await dbGlobal
.delete(projects)
.where(eq(projects.id, id));
}