gemma: generate apps/api/src/routes/time-entries.ts
This commit is contained in:
parent
3a52c4a230
commit
82a9f14341
147
apps/api/src/routes/time-entries.ts
Normal file
147
apps/api/src/routes/time-entries.ts
Normal file
@ -0,0 +1,147 @@
|
||||
import { FastifyPluginAsync } from "fastify"
|
||||
import { db } from "../db"
|
||||
import { timeEntries } from "../db/schema"
|
||||
import { eq, and, gte, lte, or } from "drizzle-orm"
|
||||
import { z } from "zod"
|
||||
|
||||
const TimeEntrySchema = z.object({
|
||||
projectId: z.string().uuid().optional(),
|
||||
description: z.string().min(1),
|
||||
startTime: z.string().datetime(),
|
||||
endTime: z.string().datetime().optional()
|
||||
})
|
||||
|
||||
const TimeEntryUpdateSchema = TimeEntrySchema.partial()
|
||||
|
||||
export default async function timeEntryRoutes(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 { from, to } = request.query as { from?: string; to?: string }
|
||||
const user = request.user as { sub: string; role: string }
|
||||
|
||||
const filters = []
|
||||
|
||||
if (user.role !== "admin") {
|
||||
filters.push(eq(timeEntries.userId, user.sub))
|
||||
}
|
||||
|
||||
if (from) {
|
||||
filters.push(gte(timeEntries.startTime, new Date(from)))
|
||||
}
|
||||
|
||||
if (to) {
|
||||
filters.push(lte(timeEntries.startTime, new Date(to)))
|
||||
}
|
||||
|
||||
const entries = await db
|
||||
.select()
|
||||
.from(timeEntries)
|
||||
.where(and(...filters))
|
||||
.orderBy(timeEntries.startTime)
|
||||
|
||||
return entries
|
||||
})
|
||||
|
||||
fastify.get("/:id", async (request, reply) => {
|
||||
const { id } = request.params as { id: string }
|
||||
const user = request.user as { sub: string; role: string }
|
||||
|
||||
const [entry] = await db
|
||||
.select()
|
||||
.from(timeEntries)
|
||||
.where(
|
||||
and(
|
||||
eq(timeEntries.id, id),
|
||||
user.role === "admin" ? undefined : eq(timeEntries.userId, user.sub)
|
||||
)
|
||||
)
|
||||
.limit(1)
|
||||
|
||||
if (!entry) {
|
||||
return reply.code(404).send({ message: "Time entry not found" })
|
||||
}
|
||||
|
||||
return entry
|
||||
})
|
||||
|
||||
fastify.post("/", async (request, reply) => {
|
||||
const user = request.user as { sub: string }
|
||||
const body = TimeEntrySchema.parse(request.body)
|
||||
|
||||
const [entry] = await db
|
||||
.insert(timeEntries)
|
||||
.values({
|
||||
...body,
|
||||
userId: user.sub,
|
||||
startTime: new Date(body.startTime),
|
||||
endTime: body.endTime ? new Date(body.endTime) : null
|
||||
})
|
||||
.returning()
|
||||
|
||||
return reply.code(201).send(entry)
|
||||
})
|
||||
|
||||
fastify.patch("/:id", async (request, reply) => {
|
||||
const { id } = request.params as { id: string }
|
||||
const user = request.user as { sub: string; role: string }
|
||||
const body = TimeEntryUpdateSchema.parse(request.body)
|
||||
|
||||
const [entry] = await db
|
||||
.select()
|
||||
.from(timeEntries)
|
||||
.where(
|
||||
and(
|
||||
eq(timeEntries.id, id),
|
||||
user.role === "admin" ? undefined : eq(timeEntries.userId, user.sub)
|
||||
)
|
||||
)
|
||||
.limit(1)
|
||||
|
||||
if (!entry) {
|
||||
return reply.code(404).send({ message: "Time entry not found" })
|
||||
}
|
||||
|
||||
const updateData: any = { ...body }
|
||||
if (body.startTime) updateData.startTime = new Date(body.startTime)
|
||||
if (body.endTime) updateData.endTime = body.endTime ? new Date(body.endTime) : null
|
||||
|
||||
const [updated] = await db
|
||||
.update(timeEntries)
|
||||
.set(updateData)
|
||||
.where(eq(timeEntries.id, id))
|
||||
.returning()
|
||||
|
||||
return updated
|
||||
})
|
||||
|
||||
fastify.delete("/:id", async (request, reply) => {
|
||||
const { id } = request.params as { id: string }
|
||||
const user = request.user as { sub: string; role: string }
|
||||
|
||||
const [entry] = await db
|
||||
.select()
|
||||
.from(timeEntries)
|
||||
.where(
|
||||
and(
|
||||
eq(timeEntries.id, id),
|
||||
user.role === "admin" ? undefined : eq(timeEntries.userId, user.sub)
|
||||
)
|
||||
)
|
||||
.limit(1)
|
||||
|
||||
if (!entry) {
|
||||
return reply.code(404).send({ message: "Time entry not found" })
|
||||
}
|
||||
|
||||
await db.delete(timeEntries).where(eq(timeEntries.id, id))
|
||||
|
||||
return reply.code(204).send()
|
||||
})
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user