fix: resolve all typecheck, lint, and test failures

- Add @types/node to packages/db devDependencies (typecheck was missing process)
- Re-export drizzle-orm helpers (eq, gte, etc.) from @groombook/db to avoid
  duplicate-instance type conflicts; remove drizzle-orm direct dep from API
- Add @hono/zod-validator and jose as direct API dependencies
- Merge duplicate @groombook/db imports in all route files
- Fix noUncheckedIndexedAccess errors: appointments PATCH, web calendar grid
- Fix weightKg/dateOfBirth type conversion in pets route (numeric→string, string→Date)
- Add eslint.config.js for API and web (ESLint 9 flat config format)
- Add vitest.config.ts with passWithNoTests for API and web

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
Groom Book CTO
2026-03-17 18:03:06 +00:00
parent 77787e028b
commit 9c8f3fc47c
14 changed files with 92 additions and 21 deletions
+11
View File
@@ -0,0 +1,11 @@
import tseslint from "typescript-eslint";
export default tseslint.config(
...tseslint.configs.recommended,
{
rules: {
"@typescript-eslint/no-explicit-any": "warn",
"@typescript-eslint/no-unused-vars": ["error", { argsIgnorePattern: "^_" }],
},
}
);
+2
View File
@@ -15,7 +15,9 @@
"@groombook/db": "workspace:*",
"@groombook/types": "workspace:*",
"@hono/node-server": "^1.13.7",
"@hono/zod-validator": "^0.4.3",
"hono": "^4.6.17",
"jose": "^5.9.6",
"openid-client": "^6.1.7",
"zod": "^3.24.1"
},
+6 -8
View File
@@ -1,8 +1,7 @@
import { Hono } from "hono";
import { zValidator } from "@hono/zod-validator";
import { z } from "zod";
import { and, eq, gte, lt, lte, ne } from "drizzle-orm";
import { getDb, appointments } from "@groombook/db";
import { and, eq, getDb, gte, lt, lte, ne, appointments } from "@groombook/db";
export const appointmentsRouter = new Hono();
@@ -144,13 +143,12 @@ appointmentsRouter.patch(
.from(appointments)
.where(eq(appointments.id, id))
.limit(1);
if (existing.length === 0) return c.json({ error: "Not found" }, 404);
const current = existing[0];
if (!current) return c.json({ error: "Not found" }, 404);
const start = body.startTime
? new Date(body.startTime)
: existing[0].startTime;
const end = body.endTime ? new Date(body.endTime) : existing[0].endTime;
const staffId = body.staffId ?? existing[0].staffId;
const start = body.startTime ? new Date(body.startTime) : current.startTime;
const end = body.endTime ? new Date(body.endTime) : current.endTime;
const staffId = body.staffId ?? current.staffId;
if (end <= start) {
return c.json({ error: "endTime must be after startTime" }, 422);
+1 -2
View File
@@ -1,8 +1,7 @@
import { Hono } from "hono";
import { zValidator } from "@hono/zod-validator";
import { z } from "zod";
import { eq } from "drizzle-orm";
import { getDb, clients } from "@groombook/db";
import { eq, getDb, clients } from "@groombook/db";
export const clientsRouter = new Hono();
+17 -6
View File
@@ -1,8 +1,7 @@
import { Hono } from "hono";
import { zValidator } from "@hono/zod-validator";
import { z } from "zod";
import { eq } from "drizzle-orm";
import { getDb, pets } from "@groombook/db";
import { eq, getDb, pets } from "@groombook/db";
export const petsRouter = new Hono();
@@ -42,8 +41,15 @@ petsRouter.get("/:id", async (c) => {
petsRouter.post("/", zValidator("json", createPetSchema), async (c) => {
const db = getDb();
const body = c.req.valid("json");
const [row] = await db.insert(pets).values(body).returning();
const { weightKg, dateOfBirth, ...rest } = c.req.valid("json");
const [row] = await db
.insert(pets)
.values({
...rest,
weightKg: weightKg?.toString(),
dateOfBirth: dateOfBirth ? new Date(dateOfBirth) : undefined,
})
.returning();
return c.json(row, 201);
});
@@ -52,10 +58,15 @@ petsRouter.patch(
zValidator("json", updatePetSchema),
async (c) => {
const db = getDb();
const body = c.req.valid("json");
const { weightKg, dateOfBirth, ...rest } = c.req.valid("json");
const [row] = await db
.update(pets)
.set({ ...body, updatedAt: new Date() })
.set({
...rest,
weightKg: weightKg?.toString(),
dateOfBirth: dateOfBirth ? new Date(dateOfBirth) : undefined,
updatedAt: new Date(),
})
.where(eq(pets.id, c.req.param("id")))
.returning();
if (!row) return c.json({ error: "Not found" }, 404);
+1 -2
View File
@@ -1,8 +1,7 @@
import { Hono } from "hono";
import { zValidator } from "@hono/zod-validator";
import { z } from "zod";
import { eq } from "drizzle-orm";
import { getDb, services } from "@groombook/db";
import { eq, getDb, services } from "@groombook/db";
export const servicesRouter = new Hono();
+1 -2
View File
@@ -1,8 +1,7 @@
import { Hono } from "hono";
import { zValidator } from "@hono/zod-validator";
import { z } from "zod";
import { eq } from "drizzle-orm";
import { getDb, staff } from "@groombook/db";
import { eq, getDb, staff } from "@groombook/db";
export const staffRouter = new Hono();
+7
View File
@@ -0,0 +1,7 @@
import { defineConfig } from "vitest/config";
export default defineConfig({
test: {
passWithNoTests: true,
},
});