/** * Migration Script: Fix gym assignments for users without gymId * * This script: * 1. Finds all users with null gymId * 2. For admins: Assigns them to gym where they are adminUserId * 3. For trainers: Gets gymId from their trainerClients records * 4. For clients: Gets gymId from trainerClients or leaves as null for manual review * * Run with: node apps/admin/src/lib/migrations/fix-gym-assignments.js * * Note: Run this AFTER setting up the database, before starting the app */ const Database = require("better-sqlite3"); // Use absolute path to the database - this is where the app stores data const dbPath = "/home/echo/dev/prototype/apps/admin/data/fitai.db"; function fixGymAssignments() { console.log("Starting gym assignment migration...\n"); console.log(`Database path: ${dbPath}\n`); const db = new Database(dbPath); // Step 1: Find all users without gymId const usersWithoutGym = db .prepare( ` SELECT id, email, role FROM users WHERE gym_id IS NULL `, ) .all(); console.log(`Found ${usersWithoutGym.length} users without gymId`); let adminsFixed = 0; let trainersFixed = 0; let clientsFixed = 0; const unableToFix = []; for (const user of usersWithoutGym) { try { if (user.role === "admin") { // Find gym where this user is admin const gym = db .prepare( ` SELECT id, name FROM gyms WHERE admin_user_id = ? `, ) .get(user.id); if (gym) { db.prepare( ` UPDATE users SET gym_id = ? WHERE id = ? `, ).run(gym.id, user.id); console.log(` ✓ Fixed admin ${user.email} -> gym ${gym.name}`); adminsFixed++; } else { unableToFix.push(`Admin ${user.email} (no gym found)`); } } else if (user.role === "trainer") { // Get gym from trainerClients const tc = db .prepare( ` SELECT gym_id FROM trainer_clients WHERE trainer_user_id = ? LIMIT 1 `, ) .get(user.id); if (tc) { db.prepare( ` UPDATE users SET gym_id = ? WHERE id = ? `, ).run(tc.gym_id, user.id); console.log(` ✓ Fixed trainer ${user.email} -> gym ${tc.gym_id}`); trainersFixed++; } else { unableToFix.push(`Trainer ${user.email} (no trainerClients record)`); } } else if (user.role === "client") { // Get gym from trainerClients const tc = db .prepare( ` SELECT gym_id FROM trainer_clients WHERE client_user_id = ? LIMIT 1 `, ) .get(user.id); if (tc) { db.prepare( ` UPDATE users SET gym_id = ? WHERE id = ? `, ).run(tc.gym_id, user.id); console.log(` ✓ Fixed client ${user.email} -> gym ${tc.gym_id}`); clientsFixed++; } else { unableToFix.push(`Client ${user.email} (no trainer assignment)`); } } } catch (error) { console.error(` ✗ Error fixing user ${user.email}:`, error.message); unableToFix.push(`User ${user.email} (error: ${error.message})`); } } db.close(); console.log("\n=== Migration Summary ==="); console.log(`Admins fixed: ${adminsFixed}`); console.log(`Trainers fixed: ${trainersFixed}`); console.log(`Clients fixed: ${clientsFixed}`); console.log(`Unable to fix: ${unableToFix.length}`); if (unableToFix.length > 0) { console.log("\nUsers requiring manual review:"); unableToFix.forEach((u) => console.log(` - ${u}`)); } console.log("\nMigration complete!"); } // Run if called directly if (require.main === module) { fixGymAssignments(); } module.exports = { fixGymAssignments };