139 lines
3.8 KiB
JavaScript
139 lines
3.8 KiB
JavaScript
/**
|
|
* 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 };
|