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:
@@ -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: "^_" }],
|
||||
},
|
||||
}
|
||||
);
|
||||
@@ -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"
|
||||
},
|
||||
|
||||
@@ -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,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();
|
||||
|
||||
|
||||
@@ -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,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,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();
|
||||
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
import { defineConfig } from "vitest/config";
|
||||
|
||||
export default defineConfig({
|
||||
test: {
|
||||
passWithNoTests: true,
|
||||
},
|
||||
});
|
||||
@@ -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: "^_" }],
|
||||
},
|
||||
}
|
||||
);
|
||||
@@ -268,7 +268,7 @@ export function AppointmentsPage() {
|
||||
</button>
|
||||
</div>
|
||||
<div style={{ padding: "0.3rem" }}>
|
||||
{apptsByDay[i].map((a) => {
|
||||
{(apptsByDay[i] ?? []).map((a) => {
|
||||
const svc = services.find((s) => s.id === a.serviceId);
|
||||
const cli = clients.find((c) => c.id === a.clientId);
|
||||
return (
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
import { defineConfig } from "vitest/config";
|
||||
|
||||
export default defineConfig({
|
||||
test: {
|
||||
passWithNoTests: true,
|
||||
},
|
||||
});
|
||||
@@ -15,6 +15,7 @@
|
||||
"postgres": "^3.4.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^22.10.7",
|
||||
"drizzle-kit": "^0.30.4",
|
||||
"typescript": "^5.7.3"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ import postgres from "postgres";
|
||||
import * as schema from "./schema.js";
|
||||
|
||||
export * from "./schema.js";
|
||||
export { and, asc, desc, eq, gte, gt, lt, lte, ne, or, sql } from "drizzle-orm";
|
||||
|
||||
let _db: ReturnType<typeof drizzle> | null = null;
|
||||
|
||||
|
||||
Generated
+25
@@ -19,9 +19,15 @@ importers:
|
||||
'@hono/node-server':
|
||||
specifier: ^1.13.7
|
||||
version: 1.19.11(hono@4.12.8)
|
||||
'@hono/zod-validator':
|
||||
specifier: ^0.4.3
|
||||
version: 0.4.3(hono@4.12.8)(zod@3.25.76)
|
||||
hono:
|
||||
specifier: ^4.6.17
|
||||
version: 4.12.8
|
||||
jose:
|
||||
specifier: ^5.9.6
|
||||
version: 5.10.0
|
||||
openid-client:
|
||||
specifier: ^6.1.7
|
||||
version: 6.8.2
|
||||
@@ -100,6 +106,9 @@ importers:
|
||||
specifier: ^3.4.5
|
||||
version: 3.4.8
|
||||
devDependencies:
|
||||
'@types/node':
|
||||
specifier: ^22.10.7
|
||||
version: 22.19.15
|
||||
drizzle-kit:
|
||||
specifier: ^0.30.4
|
||||
version: 0.30.6
|
||||
@@ -1265,6 +1274,12 @@ packages:
|
||||
peerDependencies:
|
||||
hono: ^4
|
||||
|
||||
'@hono/zod-validator@0.4.3':
|
||||
resolution: {integrity: sha512-xIgMYXDyJ4Hj6ekm9T9Y27s080Nl9NXHcJkOvkXPhubOLj8hZkOL8pDnnXfvCf5xEE8Q4oMFenQUZZREUY2gqQ==}
|
||||
peerDependencies:
|
||||
hono: '>=3.9.0'
|
||||
zod: ^3.19.1
|
||||
|
||||
'@humanfs/core@0.19.1':
|
||||
resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==}
|
||||
engines: {node: '>=18.18.0'}
|
||||
@@ -2370,6 +2385,9 @@ packages:
|
||||
engines: {node: '>=10'}
|
||||
hasBin: true
|
||||
|
||||
jose@5.10.0:
|
||||
resolution: {integrity: sha512-s+3Al/p9g32Iq+oqXxkW//7jk2Vig6FF1CFqzVXoTUXt2qz89YWbL+OwS17NFYEvxC35n0FKeGO2LGYSxeM2Gg==}
|
||||
|
||||
jose@6.2.1:
|
||||
resolution: {integrity: sha512-jUaKr1yrbfaImV7R2TN/b3IcZzsw38/chqMpo2XJ7i2F8AfM/lA4G1goC3JVEwg0H7UldTmSt3P68nt31W7/mw==}
|
||||
|
||||
@@ -4171,6 +4189,11 @@ snapshots:
|
||||
dependencies:
|
||||
hono: 4.12.8
|
||||
|
||||
'@hono/zod-validator@0.4.3(hono@4.12.8)(zod@3.25.76)':
|
||||
dependencies:
|
||||
hono: 4.12.8
|
||||
zod: 3.25.76
|
||||
|
||||
'@humanfs/core@0.19.1': {}
|
||||
|
||||
'@humanfs/node@0.16.7':
|
||||
@@ -5367,6 +5390,8 @@ snapshots:
|
||||
filelist: 1.0.6
|
||||
picocolors: 1.1.1
|
||||
|
||||
jose@5.10.0: {}
|
||||
|
||||
jose@6.2.1: {}
|
||||
|
||||
js-tokens@4.0.0: {}
|
||||
|
||||
Reference in New Issue
Block a user