104 lines
3.5 KiB
JavaScript
104 lines
3.5 KiB
JavaScript
const { execSync } = require('child_process');
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
const bcrypt = require('bcryptjs');
|
|
const { PrismaClient } = require('@prisma/client');
|
|
const dotenv = require('dotenv');
|
|
|
|
// Load .env from root
|
|
const envPath = path.resolve(process.cwd(), '../.env');
|
|
if (fs.existsSync(envPath)) {
|
|
dotenv.config({ path: envPath });
|
|
} else {
|
|
// Try current dir just in case, but preference is root
|
|
dotenv.config({ path: path.resolve(process.cwd(), '.env') });
|
|
}
|
|
|
|
async function resetDb() {
|
|
const adminEmail = process.env.ADMIN_EMAIL_PROD || 'admin-prod@gymflow.ai';
|
|
const adminPassword = process.env.ADMIN_PASSWORD_PROD || 'secure-prod-password-change-me';
|
|
|
|
// 1. Determine DB path (relative to server dir where app runs)
|
|
const dbPath = path.resolve(process.cwd(), 'prod.db');
|
|
const prismaSchemaPath = path.resolve(process.cwd(), 'prisma/schema.prisma');
|
|
|
|
console.log(`--- Database Reset ---`);
|
|
console.log(`Admin Email: ${adminEmail}`);
|
|
console.log(`DB Path: ${dbPath}`);
|
|
|
|
// 2. Delete existing DB
|
|
if (fs.existsSync(dbPath)) {
|
|
console.log(`Deleting existing database...`);
|
|
fs.unlinkSync(dbPath);
|
|
}
|
|
|
|
// 3. Initialize fresh DB schema using Prisma
|
|
console.log(`Initializing schema via Prisma...`);
|
|
try {
|
|
// Set DATABASE_URL for prisma CLI (used by prisma.config.ts)
|
|
const absoluteDbPath = `file:${dbPath}`;
|
|
console.log(`Setting DATABASE_URL=${absoluteDbPath}`);
|
|
|
|
execSync(`npx prisma db push`, {
|
|
stdio: 'inherit',
|
|
env: {
|
|
...process.env,
|
|
DATABASE_URL: absoluteDbPath
|
|
}
|
|
});
|
|
} catch (error) {
|
|
console.error(`Failed to initialize schema:`, error.message);
|
|
process.exit(1);
|
|
}
|
|
|
|
// 4. Create the Admin user
|
|
console.log(`Creating fresh admin user...`);
|
|
|
|
// In Prisma 7, PrismaBetterSqlite3 is a factory.
|
|
// We use the factory to create the adapter, then we access the internal client
|
|
// to disable WAL mode for NAS/Network share compatibility (journal_mode = DELETE).
|
|
const { PrismaBetterSqlite3 } = require('@prisma/adapter-better-sqlite3');
|
|
const factory = new PrismaBetterSqlite3({ url: dbPath });
|
|
|
|
const adapterWrapper = {
|
|
provider: 'sqlite',
|
|
adapterName: '@prisma/adapter-better-sqlite3',
|
|
async connect() {
|
|
const adapter = await factory.connect();
|
|
if (adapter.client) {
|
|
console.log(`Setting journal_mode = DELETE for NAS compatibility`);
|
|
adapter.client.pragma('journal_mode = DELETE');
|
|
}
|
|
return adapter;
|
|
},
|
|
async connectToShadowDb() {
|
|
const adapter = await factory.connectToShadowDb();
|
|
if (adapter.client) {
|
|
adapter.client.pragma('journal_mode = DELETE');
|
|
}
|
|
return adapter;
|
|
}
|
|
};
|
|
|
|
const prisma = new PrismaClient({ adapter: adapterWrapper });
|
|
|
|
try {
|
|
const hashedPassword = await bcrypt.hash(adminPassword, 10);
|
|
await prisma.user.create({
|
|
data: {
|
|
email: adminEmail,
|
|
password: hashedPassword,
|
|
role: 'ADMIN',
|
|
profile: { create: { weight: 70 } }
|
|
}
|
|
});
|
|
console.log(`✅ Success! Admin user created.`);
|
|
} catch (error) {
|
|
console.error(`Failed to create admin:`, error.message);
|
|
} finally {
|
|
await prisma.$disconnect();
|
|
}
|
|
}
|
|
|
|
resetDb();
|