feat(01-01): Prisma schema with Tenant/User models and Vitest test setup
- prisma/schema.prisma with Tenant, User, Role, TenantStatus models - tenantId on all tenant-scoped models (RLS-ready convention) - @@unique([email, tenantId]) and @@index([tenantId]) on User - Grace period fields on Tenant (suspendedAt, gracePeriodEndsAt) - RLS comment block documenting tenantId convention for future models - src/lib/prisma.ts singleton PrismaClient pattern (hot-reload safe) - vitest.config.ts with node environment and @/* path alias - src/lib/__tests__/setup.test.ts smoke test (2 tests passing) - package.json scripts: test, test:watch, db:push, db:generate, db:studio - Schema synced to PostgreSQL 16 via prisma db push
This commit is contained in:
20
src/lib/__tests__/setup.test.ts
Normal file
20
src/lib/__tests__/setup.test.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* Smoke test: verifies that the Prisma client singleton is importable
|
||||
* and defined without needing an active database connection.
|
||||
*
|
||||
* This test validates the import chain:
|
||||
* src/lib/prisma.ts -> @prisma/client -> generated Prisma client
|
||||
*/
|
||||
import { prisma } from "@/lib/prisma";
|
||||
|
||||
describe("Prisma client singleton", () => {
|
||||
it("should be defined and importable", () => {
|
||||
expect(prisma).toBeDefined();
|
||||
});
|
||||
|
||||
it("should be a PrismaClient instance", () => {
|
||||
// PrismaClient instances have $connect and $disconnect methods
|
||||
expect(typeof prisma.$connect).toBe("function");
|
||||
expect(typeof prisma.$disconnect).toBe("function");
|
||||
});
|
||||
});
|
||||
25
src/lib/prisma.ts
Normal file
25
src/lib/prisma.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { PrismaClient } from "@prisma/client";
|
||||
|
||||
// Singleton pattern to prevent multiple PrismaClient instances during Next.js
|
||||
// hot-module replacement in development. Without this, each hot reload creates
|
||||
// a new PrismaClient and exhausts the PostgreSQL connection pool.
|
||||
//
|
||||
// In production, module caching ensures a single instance per process.
|
||||
|
||||
declare global {
|
||||
// eslint-disable-next-line no-var
|
||||
var __prisma: PrismaClient | undefined;
|
||||
}
|
||||
|
||||
export const prisma =
|
||||
globalThis.__prisma ??
|
||||
new PrismaClient({
|
||||
log:
|
||||
process.env.NODE_ENV === "development"
|
||||
? ["query", "error", "warn"]
|
||||
: ["error"],
|
||||
});
|
||||
|
||||
if (process.env.NODE_ENV !== "production") {
|
||||
globalThis.__prisma = prisma;
|
||||
}
|
||||
Reference in New Issue
Block a user