From 41381147f8b703ac3fb577a20a65d2144ac38e99 Mon Sep 17 00:00:00 2001 From: Toan Hoang Minh Date: Fri, 31 Jul 2026 15:16:12 +0700 Subject: [PATCH] docs: update CLAUDE.md for Employee entity + Request FK retrofit - Trang thai hien tai: Employee entity done (model, lib, API route, tests), Request.employee_id now a real FK to Employee - documents the intentional behavior change (employee_id must now be a valid UUID referencing a real Employee, not free text; non-existent references get a 400, not a 500). Also documents the vitest fileParallelism fix and the resulting 31/31 test count. - Viec con do: remove Employee from the remaining-entities list. --- CLAUDE.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index a44baaa..86c3e04 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -92,6 +92,8 @@ Với mỗi task cụ thể (vd "thêm API tạo Request", "màn hình bàn giao - `config.matcher` của middleware loại trừ toàn bộ `/api` (không chỉ `/api/auth`) — API route tự check `auth()` lấy session ngay trong handler (không dựa hoàn toàn vào middleware, theo đúng khuyến nghị chính thức của Auth.js: verify session càng gần chỗ fetch data càng tốt). `/api/requests` (`GET`/`POST`) đã thêm check `auth()`, trả `401 {"error":"Unauthorized"}` nếu chưa login — xem `src/app/api/requests/route.ts`. - `/` (home page placeholder) **có** yêu cầu login — chọn theo nguyên tắc "mặc định chặn hết, allowlist rõ ràng cho cái không cần" thay vì opt-in dễ quên route mới. - Test: `tests/requests.test.ts` mock `@/auth` (`vi.mock`) thay vì gọi `auth()` thật, vì `auth()` không tham số đọc cookie qua `next/headers` — chỉ hoạt động khi chạy trong request-handling thật của Next.js, không phải khi test import gọi thẳng `GET()`/`POST()` (bypass hoàn toàn Next). Test mặc định mock session hợp lệ (`beforeEach`) để không phá test nghiệp vụ cũ, có riêng 2 test set mock về `null` để xác nhận 401. `middleware.ts` bản thân **không** có test tự động (chạy Edge Runtime, không test được qua vitest theo cách hiện tại) — đã verify tay qua `next build` + `next start` thật (curl xác nhận: `GET /` → 307 → `/login`, `GET /login` → 200 không loop, `GET/POST /api/requests` chưa login → 401 JSON, `GET /api/auth/session` → 200 không bị chặn). **CONFIRMED**: `npx tsc --noEmit`, `npm run lint`, `npm test` (18/18, gồm 2 test 401 mới), `npm run build` đều sạch. +- **`Employee` entity xong + `Request.employee_id` retrofit sang FK thật (2026-07-31)**: `Employee` Prisma model (`prisma/schema.prisma` — `name`, `department` (string đơn giản, chưa tách entity riêng), `managerId` self-relation nullable), `src/lib/employees.ts` (Zod + CRUD, theo đúng pattern chuẩn ở "Coding conventions"), `src/app/api/employees/route.ts` (`POST`/`GET`, gate `auth()` như `/api/requests`), `tests/employees.test.ts` (11 test, Postgres thật). `Request.employeeId` — trước đây là `String` tự do, không có ràng buộc — giờ là FK thật tới `Employee` (`@relation`, migration `20260731075828_relate_request_to_employee`). **Đây là thay đổi hành vi có chủ ý tới API `Request` đã ship trước đó**: `employee_id` trong body `POST /api/requests` giờ **bắt buộc là UUID hợp lệ** (Zod `.uuid()`, không còn nhận string tuỳ ý như `"emp-1"`), và phải **trỏ tới một `Employee` có thật** — nếu không, `createRequest()` bắt lỗi FK violation của Prisma (`P2003`) và trả `400 {"error": "employee_id does not reference an existing employee"}` thay vì lỗi 500 thô. `tests/requests.test.ts` đã cập nhật: mọi test tạo `Request` giờ tạo `Employee` thật trước qua helper `createTestEmployee()` rồi dùng `.id` thật, có thêm 2 test mới cho đúng 2 case bị FK chặn (UUID sai format, UUID đúng format nhưng không tồn tại). + - **Bug hạ tầng test phát hiện + fix trong lượt này**: `tests/setup.ts` tạo DB Postgres tạm riêng cho mỗi file test bằng cách ghi đè `process.env.DATABASE_URL` trong `beforeAll` — cách này **không an toàn** khi Vitest chạy nhiều file test song song (mặc định): timing giữa `beforeAll`/query của 2 file có thể chồng nhau khiến cả 2 cùng thao tác nhầm lên 1 DB tạm. Trước đây không lộ ra vì chưa có 2 file test nào cùng đụng bảng có FK với nhau; lộ ra ngay khi `Request` có FK thật tới `Employee` (`tests/employees.test.ts` và `tests/requests.test.ts` xoá/đọc nhầm dữ liệu của nhau, lặp lại 100% mỗi lần chạy). Fix: `vitest.config.ts` thêm `fileParallelism: false` (chạy tuần tự từng file) — **CONFIRMED**: 31/31 test pass ổn định qua `npm test` (11 employees + 10 requests + 10 auth), `npx tsc --noEmit`/`npm run lint`/`npm run build` đều sạch. ## Việc còn dở @@ -102,10 +104,10 @@ Với mỗi task cụ thể (vd "thêm API tạo Request", "màn hình bàn giao - Rà lại advisory riêng của `next` (prod dependency, có vài high/moderate — vd SSRF qua WebSocket upgrade, middleware bypass) khi có dịp, tách biệt khỏi đợt retrofit Prisma/Zod này. - Test coverage gaps (chưa block gì, chỉ là follow-up): chưa test malformed JSON body, chưa test JSON body không phải object (array/string). - `Button` (shadcn) không `forwardRef`, React đang pin 18 — dormant risk, xem note ở "Trạng thái hiện tại". -- Các entity còn lại: `Employee`, `AssetItem`, `License`, `PurchaseOrder`, `Receipt`, `Assignment` +- Các entity còn lại: `AssetItem`, `License`, `PurchaseOrder`, `Receipt`, `Assignment` - Các state tiếp theo của Request: Pending Approval → Approved → Ordered → Received → Delivered → Closed, và nhánh Rejected/Cancelled - UI (hiện chỉ có placeholder home page) - Auth/phân quyền (ai được approve request, ai được xác nhận nhận hàng/bàn giao) --- -Cập nhật lần cuối: 2026-07-31 +Cập nhật lần cuối: 2026-07-31 (Employee + Request FK retrofit)