Extract groombook/api from monorepo with CI workflow

- Add source code from apps/api
- Add packages/db and packages/types workspace dependencies
- Add GitHub Actions CI workflow (lint, typecheck, test, docker)
- Generate pnpm-lock.yaml
- Add .gitignore

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
2026-05-11 01:26:56 +00:00
committed by Flea Flicker [agent]
parent 4d7baec939
commit abac9dfe6c
114 changed files with 31941 additions and 0 deletions
+73
View File
@@ -0,0 +1,73 @@
import { Hono } from "hono";
import { zValidator } from "@hono/zod-validator";
import { z } from "zod/v3";
import { eq, getDb, services } from "@groombook/db";
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();
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 });
});