107 lines
3.1 KiB
TypeScript
107 lines
3.1 KiB
TypeScript
import dotenv from 'dotenv';
|
|
import path from 'path';
|
|
|
|
// Load env from project root
|
|
dotenv.config({ path: path.join(__dirname, '../../.env') });
|
|
import express from 'express';
|
|
import cors from 'cors';
|
|
import authRoutes from './routes/auth';
|
|
import exerciseRoutes from './routes/exercises';
|
|
import sessionRoutes from './routes/sessions';
|
|
import planRoutes from './routes/plans';
|
|
import aiRoutes from './routes/ai';
|
|
import weightRoutes from './routes/weight';
|
|
|
|
import bcrypt from 'bcryptjs';
|
|
import { PrismaClient } from '@prisma/client';
|
|
import { PrismaBetterSqlite3 } from '@prisma/adapter-better-sqlite3';
|
|
import BetterSqlite3 from 'better-sqlite3';
|
|
|
|
const app = express();
|
|
|
|
// -------------------------------------------------------------------
|
|
// Ensure a default admin user exists on startup
|
|
// -------------------------------------------------------------------
|
|
async function ensureAdminUser() {
|
|
const mode = process.env.APP_MODE || 'dev';
|
|
let adminEmail, adminPassword;
|
|
|
|
switch (mode) {
|
|
case 'test':
|
|
adminEmail = process.env.ADMIN_EMAIL_TEST;
|
|
adminPassword = process.env.ADMIN_PASSWORD_TEST;
|
|
break;
|
|
case 'prod':
|
|
adminEmail = process.env.ADMIN_EMAIL_PROD;
|
|
adminPassword = process.env.ADMIN_PASSWORD_PROD;
|
|
break;
|
|
case 'dev':
|
|
default:
|
|
adminEmail = process.env.ADMIN_EMAIL_DEV;
|
|
adminPassword = process.env.ADMIN_PASSWORD_DEV;
|
|
break;
|
|
}
|
|
|
|
if (!adminEmail || !adminPassword) {
|
|
console.warn(`⚠️ Admin credentials for mode ${mode} not found in .env. Skipping default admin creation.`);
|
|
return;
|
|
}
|
|
|
|
// Use the singleton prisma client
|
|
const prisma = (await import('./lib/prisma')).default;
|
|
|
|
// Check for existing admin
|
|
const existingAdmin = await prisma.user.findFirst({
|
|
where: { role: 'ADMIN' },
|
|
});
|
|
|
|
if (existingAdmin) {
|
|
console.info(`✅ Admin user already exists (email: ${existingAdmin.email})`);
|
|
await prisma.$disconnect();
|
|
return;
|
|
}
|
|
|
|
// Create admin user
|
|
const hashed = await bcrypt.hash(adminPassword, 10);
|
|
const admin = await prisma.user.create({
|
|
data: {
|
|
email: adminEmail,
|
|
password: hashed,
|
|
role: 'ADMIN',
|
|
profile: { create: { weight: 70 } },
|
|
},
|
|
});
|
|
|
|
console.info(`🛠️ Created default admin user (email: ${admin.email})`);
|
|
await prisma.$disconnect();
|
|
}
|
|
|
|
const PORT = process.env.PORT || 3001;
|
|
|
|
app.use(cors());
|
|
app.use(express.json());
|
|
|
|
// Routes
|
|
app.use('/api/auth', authRoutes);
|
|
app.use('/api/exercises', exerciseRoutes);
|
|
app.use('/api/sessions', sessionRoutes);
|
|
app.use('/api/plans', planRoutes);
|
|
app.use('/api/ai', aiRoutes);
|
|
app.use('/api/weight', weightRoutes);
|
|
|
|
|
|
app.get('/', (req, res) => {
|
|
res.send('GymFlow AI API is running');
|
|
});
|
|
|
|
ensureAdminUser()
|
|
.catch((e) => {
|
|
console.error('❌ Failed to ensure admin user:', e);
|
|
process.exit(1);
|
|
})
|
|
.finally(() => {
|
|
app.listen(PORT, () => {
|
|
console.log(`Server running on port ${PORT}`);
|
|
});
|
|
});
|