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/
This commit is contained in:
2026-07-30 18:14:36 +07:00
commit afdbdbdcfb
30 changed files with 13950 additions and 0 deletions
@@ -0,0 +1,14 @@
-- CreateEnum
CREATE TYPE "RequestType" AS ENUM ('asset', 'license');
-- CreateTable
CREATE TABLE "requests" (
"id" UUID NOT NULL,
"employee_id" TEXT NOT NULL,
"type" "RequestType" NOT NULL,
"reason" TEXT NOT NULL,
"status" TEXT NOT NULL DEFAULT 'Draft',
"created_at" TIMESTAMPTZ(6) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "requests_pkey" PRIMARY KEY ("id")
);
+3
View File
@@ -0,0 +1,3 @@
# Please do not edit this file manually
# It should be added in your version-control system (i.e. Git)
provider = "postgresql"
+40
View File
@@ -0,0 +1,40 @@
// Prisma schema — source of truth for the DB schema going forward,
// replacing the hand-written `CREATE TABLE IF NOT EXISTS` migration that
// used to live in src/lib/db.ts. Only the Request entity (Draft state only)
// exists so far — see ../processes/asset-license-management.md for the full
// data model / state machine this will grow into.
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
// Fixed, closed set of 2 values tied to the domain (asset vs license
// request) — a native Postgres enum is the idiomatic Prisma mapping here.
// This replaces the old `type TEXT NOT NULL CHECK (type IN ('asset',
// 'license'))` column with `type "RequestType" NOT NULL` backed by a
// `CREATE TYPE "RequestType" AS ENUM ('asset', 'license')`. Same validation
// guarantee (only these two values are ever storable), different mechanism.
// See feature-implementer report for the enum-vs-TEXT+CHECK trade-off.
enum RequestType {
asset
license
}
model Request {
id String @id @default(uuid()) @db.Uuid
employeeId String @map("employee_id")
type RequestType
reason String
// Only the 'Draft' state is implemented so far. Deliberately kept as a
// plain string (not an enum) until more states exist — see
// src/lib/requests.ts's RequestStatus type.
status String @default("Draft")
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(6)
@@map("requests")
}