spb/chat-spboucher-ai
Public
1import { z } from "zod";2import { guarded, json, body } from "@/lib/api";3import { sql } from "@/lib/db";4import { newId } from "@/lib/ids";56export const GET = guarded(async () => {7 const projects = await sql`SELECT p.*, (SELECT count(*)::int FROM conversations c WHERE c.project_id = p.id AND c.archived_at IS NULL) AS conversation_count,8 (SELECT count(*)::int FROM attachments a WHERE a.project_id = p.id) AS file_count FROM projects p WHERE archived_at IS NULL ORDER BY sort_order, created_at`;9 return json({ projects });10});1112export const POST = guarded(async (req) => {13 const b = await body(req, z.object({ name: z.string().min(1).max(120), description: z.string().max(2000).optional(), instructions: z.string().max(20_000).optional(), defaultModel: z.string().nullable().optional(), color: z.string().max(20).optional(), icon: z.string().max(20).optional() }));14 const id = newId("proj");15 const rows = await sql`INSERT INTO projects (id, name, description, instructions, default_model, color, icon) VALUES (${id}, ${b.name}, ${b.description ?? null}, ${b.instructions ?? null}, ${b.defaultModel ?? null}, ${b.color ?? null}, ${b.icon ?? null}) RETURNING *`;16 return json({ project: rows[0] }, { status: 201 });17});18