From ab713ba5bc5f3dd9f0e32b8acc463794a0174c51 Mon Sep 17 00:00:00 2001 From: imbytecat Date: Mon, 30 Mar 2026 21:26:25 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=20Better=20Auth=20?= =?UTF-8?q?=E8=AE=A4=E8=AF=81=20schema?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/server/src/server/auth/schema.ts | 70 +++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 apps/server/src/server/auth/schema.ts diff --git a/apps/server/src/server/auth/schema.ts b/apps/server/src/server/auth/schema.ts new file mode 100644 index 0000000..06a1636 --- /dev/null +++ b/apps/server/src/server/auth/schema.ts @@ -0,0 +1,70 @@ +import { boolean, pgTable, text, timestamp } from 'drizzle-orm/pg-core' + +/** + * Better Auth 认证表 + * + * 注意:所有 ID 使用 text 类型(Better Auth 自管 ID 生成), + * 不使用项目的 generatedFields(UUID v7)。 + */ + +export const userTable = pgTable('user', { + id: text('id').primaryKey(), + name: text('name').notNull(), + email: text('email').notNull().unique(), + emailVerified: boolean('email_verified').notNull().default(false), + image: text('image'), + createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(), + updatedAt: timestamp('updated_at', { withTimezone: true }) + .notNull() + .defaultNow() + .$onUpdateFn(() => new Date()), +}) + +export const sessionTable = pgTable('session', { + id: text('id').primaryKey(), + expiresAt: timestamp('expires_at', { withTimezone: true }).notNull(), + token: text('token').notNull().unique(), + createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(), + updatedAt: timestamp('updated_at', { withTimezone: true }) + .notNull() + .defaultNow() + .$onUpdateFn(() => new Date()), + ipAddress: text('ip_address'), + userAgent: text('user_agent'), + userId: text('user_id') + .notNull() + .references(() => userTable.id, { onDelete: 'cascade' }), +}) + +export const accountTable = pgTable('account', { + id: text('id').primaryKey(), + accountId: text('account_id').notNull(), + providerId: text('provider_id').notNull(), + userId: text('user_id') + .notNull() + .references(() => userTable.id, { onDelete: 'cascade' }), + accessToken: text('access_token'), + refreshToken: text('refresh_token'), + idToken: text('id_token'), + accessTokenExpiresAt: timestamp('access_token_expires_at', { withTimezone: true }), + refreshTokenExpiresAt: timestamp('refresh_token_expires_at', { withTimezone: true }), + scope: text('scope'), + password: text('password'), + createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(), + updatedAt: timestamp('updated_at', { withTimezone: true }) + .notNull() + .defaultNow() + .$onUpdateFn(() => new Date()), +}) + +export const verificationTable = pgTable('verification', { + id: text('id').primaryKey(), + identifier: text('identifier').notNull(), + value: text('value').notNull(), + expiresAt: timestamp('expires_at', { withTimezone: true }).notNull(), + createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(), + updatedAt: timestamp('updated_at', { withTimezone: true }) + .notNull() + .defaultNow() + .$onUpdateFn(() => new Date()), +})