Commit Graph
17 Commits
Author SHA1 Message Date
toanhoang 2a5792df67 fix: retrofit AssetItem.model to modelId FK
AssetItem.model was a free-text string with no referential integrity.
Now a required FK to AssetModel, mirroring the Request.employeeId and
License.vendorId retrofit precedent (no backfill needed, no real
AssetItem data existed).
2026-08-02 21:07:12 -04:00
toanhoang dc4c438ca9 feat: wire dynamic specs validation into AssetModel creation 2026-08-02 20:58:19 -04:00
toanhoang 1c530a3162 feat: add AssetModel validation + CRUD (src/lib/asset-models.ts) 2026-08-02 20:48:09 -04:00
toanhoang 123cbce2bc feat: add AssetCategoryAttributeDef validation + CRUD (src/lib/asset-category-attribute-defs.ts)
Zod schema + validate function, Prisma-backed CRUD following the
{ok,value}|{ok,error} pattern from the start. createAssetCategoryAttributeDef()
catches P2002 for the composite (categoryId, key) unique constraint (mirrors
createAssetItem()'s serialNumber handling) and P2003 for the categoryId FK
(mirrors createPurchaseOrder()).
2026-08-02 20:38:41 -04:00
toanhoang 20ec7a11df feat: add AssetCategory validation + CRUD (src/lib/asset-categories.ts) 2026-08-02 20:31:22 -04:00
toanhoang 65232fc62c feat: add Request.purchaseOrderId (nullable FK) 2026-08-02 20:24:59 -04:00
toanhoang abec58d239 feat: add License.purchaseOrderId (nullable FK)
Nullable FK from License to PurchaseOrder for supply-side traceability
(which PO a license came in through), mirroring AssetItem.purchaseOrderId's
just-merged pattern exactly. Separate commit from the earlier
License.vendorId retrofit per the project's 1-commit-per-business-change
convention.
2026-08-02 20:17:09 -04:00
toanhoang a6d7c7b302 feat: add AssetItem.purchaseOrderId (nullable FK) 2026-08-02 20:09:06 -04:00
toanhoang cc98ca4d51 feat: add PurchaseOrder validation + CRUD (src/lib/purchase-orders.ts) 2026-08-02 19:59:05 -04:00
toanhoang 9d99ebb425 fix: retrofit License.vendor to vendorId FK + createLicense error handling
License.vendor (free-text string) is now vendorId, a required FK to
Vendor, per docs/asset-license-management.md's "## Vendor (chốt
2026-08-02)" spec. Mirrors the Request.employeeId string->FK precedent:
Zod validates UUID format only, Prisma's own FK constraint (P2003) is
caught at insert time and translated into a clean 400 instead of a raw
500. No License data existed yet, so this is a pure column-type
migration, no backfill needed.

Also converts createLicense() to the {ok,value}|{ok,error} result
pattern used elsewhere (createRequest, createAssetItem) instead of
returning a bare LicenseRecord promise - closes the gap flagged in
CLAUDE.md now that License has its first FK-violation error case to
handle.
2026-08-02 19:41:33 -04:00
toanhoang 19b652142a feat: add Vendor validation + CRUD (src/lib/vendors.ts) 2026-08-02 19:28:25 -04:00
toanhoang e232658b3d feat: add License validation + CRUD (src/lib/licenses.ts) 2026-08-02 08:54:57 -04:00
toanhoang e7e359cbf7 feat: add AssetItem validation + CRUD (src/lib/assets.ts) 2026-07-31 16:04:22 +07:00
toanhoang 7e69efa4a8 fix: update Request validation/tests for Employee FK relation
- createRequestSchema now requires employee_id to be a UUID-format
  string (was a free-text non-empty check), matching the new FK to
  Employee in schema.prisma.
- createRequest() now returns a CreateRequestResult discriminated
  union and catches Prisma P2003 (FK violation), returning a friendly
  ok:false error instead of a raw 500 when employee_id does not
  reference an existing Employee. POST /api/requests branches on
  created.ok and returns 400 in that case.
- tests/requests.test.ts: every test that used to POST a fake string
  employee_id (emp-1, emp-2) now creates a real Employee first via
  createTestEmployee() and uses its id, since employee_id is now a
  real FK. Added coverage for a syntactically invalid UUID and for a
  well-formed but non-existent UUID (expects the friendly 400 from
  the P2003 catch, not a raw 500) - the exact case this retrofit was
  meant to protect against.
2026-07-31 15:14:55 +07:00
toanhoang eeaf946712 feat: add Employee validation + CRUD (src/lib/employees.ts)
Mirrors src/lib/requests.ts's shape: Zod schema, ValidationResult
discriminated union, CRUD via Prisma, toRecord() camelCase->snake_case
mapping. managerId is only format-checked as a UUID here; a
nonexistent managerId is caught via Prisma's P2003 FK-violation error
in createEmployee() and translated into a friendly {ok:false,error}
instead of leaking a raw Prisma error.
2026-07-31 14:54:48 +07:00
toanhoang 43a20d8530 feat: add User password hashing + account creation script 2026-07-31 11:51:08 +07:00
toanhoang afdbdbdcfb Initial commit: Next.js scaffold, Request entity, Prisma+Zod, Tailwind v4+shadcn
- Next.js 14 (TS, App Router) monolith
- Request entity (Draft state) via Prisma + Postgres, validated with Zod
- ESLint configured
- Tailwind v4 + shadcn/ui (new-york-v4 style)
- Vitest test suite (6 tests, runs against throwaway Postgres DB per file)
- Multi-agent dev workflow docs in CLAUDE.md and .claude/agents/
2026-07-30 18:14:36 +07:00