| | import { eq } from "drizzle-orm"; |
| | import { drizzle } from "drizzle-orm/mysql2"; |
| | import { InsertUser, users } from "../drizzle/schema"; |
| | import { ENV } from './_core/env'; |
| |
|
| | let _db: ReturnType<typeof drizzle> | null = null; |
| |
|
| | |
| | export async function getDb() { |
| | if (!_db && process.env.DATABASE_URL) { |
| | try { |
| | _db = drizzle(process.env.DATABASE_URL); |
| | } catch (error) { |
| | console.warn("[Database] Failed to connect:", error); |
| | _db = null; |
| | } |
| | } |
| | return _db; |
| | } |
| |
|
| | export async function upsertUser(user: InsertUser): Promise<void> { |
| | if (!user.openId) { |
| | throw new Error("User openId is required for upsert"); |
| | } |
| |
|
| | const db = await getDb(); |
| | if (!db) { |
| | console.warn("[Database] Cannot upsert user: database not available"); |
| | return; |
| | } |
| |
|
| | try { |
| | const values: InsertUser = { |
| | openId: user.openId, |
| | }; |
| | const updateSet: Record<string, unknown> = {}; |
| |
|
| | const textFields = ["name", "email", "loginMethod"] as const; |
| | type TextField = (typeof textFields)[number]; |
| |
|
| | const assignNullable = (field: TextField) => { |
| | const value = user[field]; |
| | if (value === undefined) return; |
| | const normalized = value ?? null; |
| | values[field] = normalized; |
| | updateSet[field] = normalized; |
| | }; |
| |
|
| | textFields.forEach(assignNullable); |
| |
|
| | if (user.lastSignedIn !== undefined) { |
| | values.lastSignedIn = user.lastSignedIn; |
| | updateSet.lastSignedIn = user.lastSignedIn; |
| | } |
| | if (user.role !== undefined) { |
| | values.role = user.role; |
| | updateSet.role = user.role; |
| | } else if (user.openId === ENV.ownerOpenId) { |
| | values.role = 'admin'; |
| | updateSet.role = 'admin'; |
| | } |
| |
|
| | if (!values.lastSignedIn) { |
| | values.lastSignedIn = new Date(); |
| | } |
| |
|
| | if (Object.keys(updateSet).length === 0) { |
| | updateSet.lastSignedIn = new Date(); |
| | } |
| |
|
| | await db.insert(users).values(values).onDuplicateKeyUpdate({ |
| | set: updateSet, |
| | }); |
| | } catch (error) { |
| | console.error("[Database] Failed to upsert user:", error); |
| | throw error; |
| | } |
| | } |
| |
|
| | export async function getUserByOpenId(openId: string) { |
| | const db = await getDb(); |
| | if (!db) { |
| | console.warn("[Database] Cannot get user: database not available"); |
| | return undefined; |
| | } |
| |
|
| | const result = await db.select().from(users).where(eq(users.openId, openId)).limit(1); |
| |
|
| | return result.length > 0 ? result[0] : undefined; |
| | } |
| |
|
| | |
| |
|