diff --git a/server/storage.ts b/server/storage.ts index 98a46ee..8aaa8a3 100644 --- a/server/storage.ts +++ b/server/storage.ts @@ -56,7 +56,7 @@ import { type InsertCcnlSetting, } from "@shared/schema"; import { db } from "./db"; -import { eq, and, gte, lte, desc } from "drizzle-orm"; +import { eq, and, gte, lte, desc, or } from "drizzle-orm"; export interface IStorage { // User operations (Replit Auth required) @@ -163,22 +163,39 @@ export class DatabaseStorage implements IStorage { } async upsertUser(userData: UpsertUser): Promise { - // Use onConflictDoUpdate to handle both insert and update cases - // This handles conflicts on both id (primary key) and email (unique constraint) - const [user] = await db - .insert(users) - .values(userData) - .onConflictDoUpdate({ - target: users.id, - set: { - email: userData.email, - name: userData.name, - role: userData.role, + // Handle conflicts on both id (primary key) and email (unique constraint) + // Check if user exists by id or email first + const existingUser = await db + .select() + .from(users) + .where( + userData.id + ? or(eq(users.id, userData.id), eq(users.email, userData.email || '')) + : eq(users.email, userData.email || '') + ) + .limit(1); + + if (existingUser.length > 0) { + // Update existing user - NEVER change the ID (it's a primary key) + const [updated] = await db + .update(users) + .set({ + ...(userData.email && { email: userData.email }), + ...(userData.name && { name: userData.name }), + ...(userData.role && { role: userData.role }), updatedAt: new Date(), - }, - }) - .returning(); - return user; + }) + .where(eq(users.id, existingUser[0].id)) + .returning(); + return updated; + } else { + // Insert new user + const [user] = await db + .insert(users) + .values(userData) + .returning(); + return user; + } } async getAllUsers(): Promise {