import { FastifyInstance } from "fastify" import { db } from "../db" import { projects } from "../db/schema" import { eq } from "drizzle-orm" import { z } from "zod" const ProjectSchema = z.object({ name: z.string().min(1), customerId: z.string().uuid() }) const ProjectUpdateSchema = ProjectSchema.partial() export default async function projectRoutes(fastify: FastifyInstance) { fastify.addHook("preHandler", async (request, reply) => { try { await request.jwtVerify() } catch (err) { return reply.code(401).send({ message: "Unauthorized" }) } }) fastify.get("/", async (request, reply) => { const { onlyActive, customerId } = request.query as { onlyActive?: string, customerId?: string } const isActiveDefault = onlyActive !== "false" const conds = [] if (isActiveDefault) conds.push(eq(projects.active, true)) if (customerId) conds.push(eq(projects.customerId, customerId)) const results = await db .select() .from(projects) .where(conds.length ? and(...conds) : undefined as any) .orderBy(projects.name) return results }) fastify.get("/:id", async (request, reply) => { const { id } = request.params as { id: string } const [project] = await db .select() .from(projects) .where(eq(projects.id, id)) .limit(1) if (!project) { return reply.code(404).send({ message: "Project not found" }) } return project }) fastify.post("/", async (request, reply) => { const body = ProjectSchema.parse(request.body) const [project] = await db .insert(projects) .values({ name: body.name, customerId: body.customerId }) .returning() return reply.code(201).send(project) }) fastify.patch("/:id", async (request, reply) => { const { id } = request.params as { id: string } const body = ProjectUpdateSchema.parse(request.body) const [project] = await db .update(projects) .set(body) .where(eq(projects.id, id)) .returning() if (!project) { return reply.code(404).send({ message: "Project not found" }) } return project }) fastify.delete("/:id", async (request, reply) => { const { id } = request.params as { id: string } const [project] = await db .update(projects) .set({ active: false }) .where(eq(projects.id, id)) .returning() if (!project) { return reply.code(404).send({ message: "Project not found" }) } return reply.code(204).send() }) } // Helper for the filter array since 'and' is needed function and(...conditions: any[]) { return conditions.length > 0 ? conditions : undefined } // Overriding the local 'and' to use drizzle's actual 'and' import { and as drizzleAnd } from "drizzle-orm" const andHelper = drizzleAnd;