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

132 lines
3.2 KiB
TypeScript

import { FastifyInstance } from "fastify"
import { db } from "../db"
import { customers, projects, timeEntries } from "../db/schema"
import { eq, and, inArray, desc } from "drizzle-orm"
import { z } from "zod"
const CustomerSchema = z.object({
name: z.string().min(1)
})
const CustomerUpdateSchema = CustomerSchema.partial()
export default async function customerRoutes(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 } = request.query as { onlyActive?: string }
const isActiveDefault = onlyActive !== "false"
const results = await db
.select()
.from(customers)
.where(isActiveDefault ? eq(customers.active, true) : undefined)
.orderBy(customers.name)
return results
})
fastify.get("/:id", async (request, reply) => {
const { id } = request.params as { id: string }
const [customer] = await db
.select()
.from(customers)
.where(eq(customers.id, id))
.limit(1)
if (!customer) {
return reply.code(404).send({ message: "Customer not found" })
}
return customer
})
fastify.get("/:id/projects", async (request, reply) => {
const { id } = request.params as { id: string }
const results = await db
.select()
.from(projects)
.where(eq(projects.customerId, id))
.orderBy(projects.name)
return results
})
fastify.get("/:id/time-entries", async (request, reply) => {
const { id } = request.params as { id: string }
const customerProjects = await db
.select({ id: projects.id })
.from(projects)
.where(eq(projects.customerId, id))
if (customerProjects.length === 0) {
return []
}
const projectIds = customerProjects.map((p) => p.id)
const results = await db
.select()
.from(timeEntries)
.where(inArray(timeEntries.projectId, projectIds))
.orderBy(desc(timeEntries.startTime))
.limit(50)
return results
})
fastify.post("/", async (request, reply) => {
const body = CustomerSchema.parse(request.body)
const [customer] = await db
.insert(customers)
.values({
name: body.name
})
.returning()
return reply.code(201).send(customer)
})
fastify.patch("/:id", async (request, reply) => {
const { id } = request.params as { id: string }
const body = CustomerUpdateSchema.parse(request.body)
const [customer] = await db
.update(customers)
.set(body)
.where(eq(customers.id, id))
.returning()
if (!customer) {
return reply.code(404).send({ message: "Customer not found" })
}
return customer
})
fastify.delete("/:id", async (request, reply) => {
const { id } = request.params as { id: string }
const [customer] = await db
.update(customers)
.set({ active: false })
.where(eq(customers.id, id))
.returning()
if (!customer) {
return reply.code(404).send({ message: "Customer not found" })
}
return reply.code(204).send()
})
}