Loading...
Loading...
[Pragmatic DDD Architecture] Guide for creating PostgreSQL tables and defining relations using Drizzle ORM. Use when creating new schemas, managing PostgreSQL indexes, enums, mapping column names to camelCase for the domain, and explicitly exporting constraint names.
npx skill4agent add leif-sync/pragmatic-ddd drizzle-schemasrc/shared/infrastructure/drizzle-postgres/schema.tspgTablepgEnumrelationssnake_caseaudit_logscamelCaseauditLogssnake_caseuuid("folder_id")camelCasecreatedAt.defaultNow().notNull()updatedAt.$onUpdate(...)pgEnum("enum_name", [...])import {
pgTable,
uuid,
varchar,
text,
timestamp,
uniqueIndex,
} from "drizzle-orm/pg-core";
// 1. Dependent Tables (Foreign Keys)
export const workspaces = pgTable("workspaces", {
id: uuid().primaryKey(),
name: varchar({ length: 40 }).notNull(),
ownerId: uuid("owner_id").notNull(),
createdAt: timestamp("created_at").defaultNow().notNull(),
updatedAt: timestamp("updated_at").defaultNow().notNull(),
});
// 2. Main Table & References
export const folders = pgTable(
"folders",
{
id: uuid().primaryKey(),
// Explicit snake_case -> camelCase mapping, with onDelete behavior
workspaceId: uuid("workspace_id")
.references(() => workspaces.id, { onDelete: "cascade" })
.notNull(),
name: varchar({ length: 30 }).notNull(),
createdAt: timestamp("created_at").defaultNow().notNull(),
updatedAt: timestamp("updated_at").defaultNow().notNull(),
},
// 3. Composite unique indexes
(table) => [uniqueIndex().on(table.workspaceId, table.name)],
);UniqueConstraintViolationgetTableNameimport { getTableName } from "drizzle-orm";
// ─── Constraint name constants ───
export const FK_FOLDERS_WORKSPACE =
`${getTableName(folders)}_${folders.workspaceId.name}_${getTableName(workspaces)}_${workspaces.id.name}_fk` as const;
export const UNIQUE_FOLDERS_WORKSPACE_NAME =
`${getTableName(folders)}_${folders.workspaceId.name}_${folders.name.name}_index` as const;schema.tsuserssessionsexport const users = pgTable("users", {
// Better-auth generated
id: uuid("id").primaryKey(),
name: text("name").notNull(),
email: text("email").notNull().unique(),
emailVerified: boolean("email_verified").default(false).notNull(),
image: text("image"),
// Custom columns
plan: subscriptionPlanEnum("subscription_plan").default("free").notNull(),
createdAt: timestamp("created_at").defaultNow().notNull(),
});npm run db:generateschema.tsnpm run db:pushnpm run db:studioschema.tsdrizzle.config.ts