From da5f08f8c1e7a6ea20bd73bf3c82c8b06edb8ae7 Mon Sep 17 00:00:00 2001 From: imbytecat Date: Wed, 21 Jan 2026 16:33:03 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=20UUID=20=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E5=8F=8A=E5=BE=85=E5=8A=9E=E4=BA=8B=E9=A1=B9=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E8=A1=A8=E5=AE=9A=E4=B9=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加 uuid 依赖以支持唯一标识符生成 - 移除对 todoTable 的导出,不再从数据库模式文件中暴露该表定义。 - 导出 todo 模式定义文件中的所有内容 - 添加待办事项数据表定义,包含标题和完成状态字段,并集成自动生成字段。 - 添加用于定义主键、创建时间和更新时间字段的实用工具函数,并支持不同 PostgreSQL 版本的 UUID 生成策略,同时提供生成字段的键名映射。 - 添加 uuid 依赖到项目中 --- apps/server/package.json | 1 + apps/server/src/db/schema.ts | 1 - apps/server/src/db/schema/index.ts | 1 + apps/server/src/db/schema/todo.ts | 8 ++++ apps/server/src/db/schema/utils/field.ts | 58 ++++++++++++++++++++++++ bun.lock | 1 + 6 files changed, 69 insertions(+), 1 deletion(-) delete mode 100644 apps/server/src/db/schema.ts create mode 100644 apps/server/src/db/schema/index.ts create mode 100644 apps/server/src/db/schema/todo.ts create mode 100644 apps/server/src/db/schema/utils/field.ts diff --git a/apps/server/package.json b/apps/server/package.json index fe27248..f180f29 100644 --- a/apps/server/package.json +++ b/apps/server/package.json @@ -32,6 +32,7 @@ "postgres": "catalog:", "react": "catalog:", "react-dom": "catalog:", + "uuid": "catalog:", "zod": "catalog:" }, "devDependencies": { diff --git a/apps/server/src/db/schema.ts b/apps/server/src/db/schema.ts deleted file mode 100644 index 23d4231..0000000 --- a/apps/server/src/db/schema.ts +++ /dev/null @@ -1 +0,0 @@ -export { todoTable } from '@furtherverse/database/postgres/schema/index' diff --git a/apps/server/src/db/schema/index.ts b/apps/server/src/db/schema/index.ts new file mode 100644 index 0000000..a1cad6c --- /dev/null +++ b/apps/server/src/db/schema/index.ts @@ -0,0 +1 @@ +export * from './todo' diff --git a/apps/server/src/db/schema/todo.ts b/apps/server/src/db/schema/todo.ts new file mode 100644 index 0000000..d6ee127 --- /dev/null +++ b/apps/server/src/db/schema/todo.ts @@ -0,0 +1,8 @@ +import { boolean, pgTable, text } from 'drizzle-orm/pg-core' +import { generatedFields } from './utils/field' + +export const todoTable = pgTable('todo', { + ...generatedFields, + title: text('title').notNull(), + completed: boolean('completed').notNull().default(false), +}) diff --git a/apps/server/src/db/schema/utils/field.ts b/apps/server/src/db/schema/utils/field.ts new file mode 100644 index 0000000..4ba0ef9 --- /dev/null +++ b/apps/server/src/db/schema/utils/field.ts @@ -0,0 +1,58 @@ +import { sql } from 'drizzle-orm' +import { timestamp, uuid } from 'drizzle-orm/pg-core' +import { v7 as uuidv7 } from 'uuid' + +// id + +export const id = (name: string) => uuid(name) +export const pk = (name: string, strategy?: 'native' | 'extension') => { + switch (strategy) { + // PG 18+ + case 'native': + return id(name).primaryKey().default(sql`uuidv7()`) + + // PG 13+ with extension + case 'extension': + return id(name).primaryKey().default(sql`uuid_generate_v7()`) + + // Any PG version + default: + return id(name) + .primaryKey() + .$defaultFn(() => uuidv7()) + } +} + +// timestamp + +export const createdAt = (name = 'created_at') => + timestamp(name, { withTimezone: true }).notNull().defaultNow() + +export const updatedAt = (name = 'updated_at') => + timestamp(name, { withTimezone: true }) + .notNull() + .defaultNow() + .$onUpdateFn(() => new Date()) + +// generated fields + +export const generatedFields = { + id: pk('id'), + createdAt: createdAt('created_at'), + updatedAt: updatedAt('updated_at'), +} + +// Helper to create omit keys from generatedFields +const createGeneratedFieldKeys = >( + fields: T, +): Record => { + return Object.keys(fields).reduce( + (acc, key) => { + acc[key as keyof T] = true + return acc + }, + {} as Record, + ) +} + +export const generatedFieldKeys = createGeneratedFieldKeys(generatedFields) diff --git a/bun.lock b/bun.lock index 1ccb37e..e389d09 100644 --- a/bun.lock +++ b/bun.lock @@ -37,6 +37,7 @@ "postgres": "catalog:", "react": "catalog:", "react-dom": "catalog:", + "uuid": "catalog:", "zod": "catalog:", }, "devDependencies": {