44da26820b
- Add buffer_rules table with serviceId/sizeCategory/coatType/bufferMinutes
- Add petSizeCategoryEnum (small/medium/large/extra_large) and coatTypeEnum
to schema; update pets table columns to use the typed enums
- Add defaultBufferMinutes to services table
- Add apps/api/src/routes/buffer-rules.ts with GET/POST/PATCH/DELETE,
all manager-only via requireRole("manager")
- Register /api/buffer-rules router in index.ts
- PATCH /api/services/:id accepts optional defaultBufferMinutes
- POST/PATCH /api/pets accepts optional sizeCategory and coatType
Co-Authored-By: Paperclip <noreply@paperclip.ing>
76 lines
2.1 KiB
TypeScript
76 lines
2.1 KiB
TypeScript
import { Hono } from "hono";
|
|
import { zValidator } from "@hono/zod-validator";
|
|
import { z } from "zod/v3";
|
|
import { eq, getDb, services } from "../db/index.js";
|
|
|
|
export const servicesRouter = new Hono();
|
|
|
|
const createServiceSchema = z.object({
|
|
name: z.string().min(1).max(200),
|
|
description: z.string().max(2000).optional(),
|
|
basePriceCents: z.number().int().positive(),
|
|
durationMinutes: z.number().int().positive().max(480),
|
|
active: z.boolean().default(true),
|
|
});
|
|
|
|
const updateServiceSchema = createServiceSchema.partial().extend({
|
|
defaultBufferMinutes: z.number().int().min(0).optional(),
|
|
});
|
|
|
|
servicesRouter.get("/", async (c) => {
|
|
const db = getDb();
|
|
const includeInactive = c.req.query("includeInactive") === "true";
|
|
const query = db.select().from(services).orderBy(services.name);
|
|
const rows = includeInactive
|
|
? await query
|
|
: await query.where(eq(services.active, true));
|
|
return c.json(rows);
|
|
});
|
|
|
|
servicesRouter.get("/:id", async (c) => {
|
|
const db = getDb();
|
|
const [row] = await db
|
|
.select()
|
|
.from(services)
|
|
.where(eq(services.id, c.req.param("id")));
|
|
if (!row) return c.json({ error: "Not found" }, 404);
|
|
return c.json(row);
|
|
});
|
|
|
|
servicesRouter.post(
|
|
"/",
|
|
zValidator("json", createServiceSchema),
|
|
async (c) => {
|
|
const db = getDb();
|
|
const body = c.req.valid("json");
|
|
const [row] = await db.insert(services).values(body).returning();
|
|
return c.json(row, 201);
|
|
}
|
|
);
|
|
|
|
servicesRouter.patch(
|
|
"/:id",
|
|
zValidator("json", updateServiceSchema),
|
|
async (c) => {
|
|
const db = getDb();
|
|
const body = c.req.valid("json");
|
|
const [row] = await db
|
|
.update(services)
|
|
.set({ ...body, updatedAt: new Date() })
|
|
.where(eq(services.id, c.req.param("id")))
|
|
.returning();
|
|
if (!row) return c.json({ error: "Not found" }, 404);
|
|
return c.json(row);
|
|
}
|
|
);
|
|
|
|
servicesRouter.delete("/:id", async (c) => {
|
|
const db = getDb();
|
|
const [row] = await db
|
|
.delete(services)
|
|
.where(eq(services.id, c.req.param("id")))
|
|
.returning();
|
|
if (!row) return c.json({ error: "Not found" }, 404);
|
|
return c.json({ ok: true });
|
|
});
|