EmberClone/apps/api/src/routes/projects.ts

115 lines
2.8 KiB
TypeScript

import { FastifyPluginAsync } 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: FastifyPluginAsync) {
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 filters = []
if (isActiveDefault) {
filters.push(eq(projects.active, true))
}
if (customerId) {
filters.push(eq(projects.customerId, customerId))
}
const results = await db
.select()
.from(projects)
.where(filters.length > 0 ? and(...filters) : undefined)
.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;