import { Pool } from 'pg'; import { drizzle, NodePgDatabase } from 'drizzle-orm/node-postgres'; import { sql, eq, and } from 'drizzle-orm'; import * as schema from '../src/drizzle/schema'; import { users_json } from '../src/drizzle/schema'; // Mock JwtUser interface JwtUser { email: string; } // Logic from UserService.addFavorite async function addFavorite(db: NodePgDatabase, id: string, user: JwtUser) { console.log(`[Action] Adding favorite. Target ID: ${id}, Favoriter Email: ${user.email}`); await db .update(schema.users_json) .set({ data: sql`jsonb_set(${schema.users_json.data}, '{favoritesForUser}', coalesce((${schema.users_json.data}->'favoritesForUser')::jsonb, '[]'::jsonb) || to_jsonb(${user.email}::text))`, } as any) .where(eq(schema.users_json.id, id)); } // Logic from UserService.getFavoriteUsers async function getFavoriteUsers(db: NodePgDatabase, user: JwtUser) { console.log(`[Action] Fetching favorites for ${user.email}`); // Corrected query using `?` operator (matches array element check) const data = await db .select() .from(schema.users_json) .where(sql`${schema.users_json.data}->'favoritesForUser' ? ${user.email}`); return data; } // Logic from UserService.deleteFavorite async function deleteFavorite(db: NodePgDatabase, id: string, user: JwtUser) { console.log(`[Action] Removing favorite. Target ID: ${id}, Favoriter Email: ${user.email}`); await db .update(schema.users_json) .set({ data: sql`jsonb_set(${schema.users_json.data}, '{favoritesForUser}', (SELECT coalesce(jsonb_agg(elem), '[]'::jsonb) FROM jsonb_array_elements(coalesce(${schema.users_json.data}->'favoritesForUser', '[]'::jsonb)) AS elem WHERE elem::text != to_jsonb(${user.email}::text)::text))`, } as any) .where(eq(schema.users_json.id, id)); } async function main() { console.log('═══════════════════════════════════════════════════════'); console.log(' FAVORITES REPRODUCTION SCRIPT'); console.log('═══════════════════════════════════════════════════════\n'); const connectionString = process.env.DATABASE_URL || 'postgresql://postgres:postgres@localhost:5432/bizmatch'; const pool = new Pool({ connectionString }); const db = drizzle(pool, { schema }); try { // 1. Find a "professional" user to be the TARGET listing // filtering by customerType = 'professional' inside the jsonb data const targets = await db.select().from(users_json).limit(1); if (targets.length === 0) { console.error("No users found in DB to test with."); return; } const targetUser = targets[0]; console.log(`Found target user: ID=${targetUser.id}, Email=${targetUser.email}`); // 2. Define a "favoriter" user (doesn't need to exist in DB for the logic to work, but better if it's realistic) // We'll just use a dummy email or one from DB if available. const favoriterEmail = 'test-repro-favoriter@example.com'; const favoriter: JwtUser = { email: favoriterEmail }; // 3. Clear any existing favorite for this pair first await deleteFavorite(db, targetUser.id, favoriter); // 4. Add Favorite await addFavorite(db, targetUser.id, favoriter); // 5. Verify it was added by checking the raw data const updatedTarget = await db.select().from(users_json).where(eq(users_json.id, targetUser.id)); const favoritesData = (updatedTarget[0].data as any).favoritesForUser; console.log(`\n[Check] Raw favoritesForUser data on target:`, favoritesData); if (!favoritesData || !favoritesData.includes(favoriterEmail)) { console.error("❌ Add Favorite FAILED. Email not found in favoritesForUser array."); } else { console.log("✅ Add Favorite SUCCESS. Email found in JSON."); } // 6. Test retrieval using the getFavoriteUsers query const retrievedFavorites = await getFavoriteUsers(db, favoriter); console.log(`\n[Check] retrievedFavorites count: ${retrievedFavorites.length}`); const found = retrievedFavorites.find(u => u.id === targetUser.id); if (found) { console.log("✅ Get Favorites SUCCESS. Target user returned in query."); } else { console.log("❌ Get Favorites FAILED. Target user NOT returned by query."); console.log("Query used: favoritesForUser @> [email]"); } // 7. Cleanup await deleteFavorite(db, targetUser.id, favoriter); console.log("\n[Cleanup] Removed test favorite."); } catch (error) { console.error('❌ Script failed:', error); } finally { await pool.end(); } } main();