Dev, Test, and Prod DBs separated. .env is unified now.
This commit is contained in:
@@ -8,7 +8,9 @@
|
|||||||
"build": "vite build",
|
"build": "vite build",
|
||||||
"preview": "vite preview",
|
"preview": "vite preview",
|
||||||
"dev:full": "npm-run-all --parallel dev \"dev --prefix server\"",
|
"dev:full": "npm-run-all --parallel dev \"dev --prefix server\"",
|
||||||
"dev:full:bg": "npm-run-all --parallel dev \"dev --prefix server\" &"
|
"dev:full:bg": "npm-run-all --parallel dev \"dev --prefix server\" &",
|
||||||
|
"test:full": "npm-run-all --parallel dev \"start:test --prefix server\"",
|
||||||
|
"prod:full": "npm-run-all --parallel preview \"start:prod --prefix server\""
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@google/genai": "^1.30.0",
|
"@google/genai": "^1.30.0",
|
||||||
|
|||||||
26
server/package-lock.json
generated
26
server/package-lock.json
generated
@@ -26,6 +26,7 @@
|
|||||||
"@types/express": "*",
|
"@types/express": "*",
|
||||||
"@types/jsonwebtoken": "*",
|
"@types/jsonwebtoken": "*",
|
||||||
"@types/node": "*",
|
"@types/node": "*",
|
||||||
|
"cross-env": "^10.1.0",
|
||||||
"dotenv-cli": "^11.0.0",
|
"dotenv-cli": "^11.0.0",
|
||||||
"nodemon": "*",
|
"nodemon": "*",
|
||||||
"prisma": "^7.1.0",
|
"prisma": "^7.1.0",
|
||||||
@@ -112,6 +113,13 @@
|
|||||||
"@electric-sql/pglite": "0.3.2"
|
"@electric-sql/pglite": "0.3.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@epic-web/invariant": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@epic-web/invariant/-/invariant-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-lrTPqgvfFQtR/eY/qkIzp98OGdNJu0m5ji3q/nJI8v3SXkRKEnWiOxMmbvcSoAIzv/cGiuvRy57k4suKQSAdwA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/@google/generative-ai": {
|
"node_modules/@google/generative-ai": {
|
||||||
"version": "0.24.1",
|
"version": "0.24.1",
|
||||||
"resolved": "https://registry.npmjs.org/@google/generative-ai/-/generative-ai-0.24.1.tgz",
|
"resolved": "https://registry.npmjs.org/@google/generative-ai/-/generative-ai-0.24.1.tgz",
|
||||||
@@ -1038,6 +1046,24 @@
|
|||||||
"integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
|
"integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/cross-env": {
|
||||||
|
"version": "10.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/cross-env/-/cross-env-10.1.0.tgz",
|
||||||
|
"integrity": "sha512-GsYosgnACZTADcmEyJctkJIoqAhHjttw7RsFrVoJNXbsWWqaq6Ym+7kZjq6mS45O0jij6vtiReppKQEtqWy6Dw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@epic-web/invariant": "^1.0.0",
|
||||||
|
"cross-spawn": "^7.0.6"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"cross-env": "dist/bin/cross-env.js",
|
||||||
|
"cross-env-shell": "dist/bin/cross-env-shell.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=20"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/cross-spawn": {
|
"node_modules/cross-spawn": {
|
||||||
"version": "7.0.6",
|
"version": "7.0.6",
|
||||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
|
||||||
|
|||||||
@@ -4,11 +4,12 @@
|
|||||||
"description": "Backend for GymFlow AI",
|
"description": "Backend for GymFlow AI",
|
||||||
"main": "src/index.ts",
|
"main": "src/index.ts",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "node dist/index.js",
|
"start": "npm run start:prod",
|
||||||
"dev": "ts-node-dev -r dotenv/config --respawn --transpile-only src/index.ts",
|
"start:prod": "cross-env APP_MODE=prod node dist/index.js",
|
||||||
|
"start:test": "cross-env APP_MODE=test ts-node-dev -r dotenv/config --respawn --transpile-only src/index.ts",
|
||||||
|
"dev": "cross-env APP_MODE=dev ts-node-dev -r dotenv/config --respawn --transpile-only src/index.ts",
|
||||||
"build": "tsc",
|
"build": "tsc",
|
||||||
"migrate:deploy": "npx prisma migrate deploy"
|
"migrate:deploy": "npx prisma migrate deploy"
|
||||||
|
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@google/generative-ai": "^0.24.1",
|
"@google/generative-ai": "^0.24.1",
|
||||||
@@ -29,6 +30,7 @@
|
|||||||
"@types/express": "*",
|
"@types/express": "*",
|
||||||
"@types/jsonwebtoken": "*",
|
"@types/jsonwebtoken": "*",
|
||||||
"@types/node": "*",
|
"@types/node": "*",
|
||||||
|
"cross-env": "^10.1.0",
|
||||||
"dotenv-cli": "^11.0.0",
|
"dotenv-cli": "^11.0.0",
|
||||||
"nodemon": "*",
|
"nodemon": "*",
|
||||||
"prisma": "^7.1.0",
|
"prisma": "^7.1.0",
|
||||||
|
|||||||
5
server/prisma.config.js
Normal file
5
server/prisma.config.js
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
module.exports = {
|
||||||
|
datasource: {
|
||||||
|
url: process.env.DATABASE_URL,
|
||||||
|
},
|
||||||
|
};
|
||||||
Binary file not shown.
BIN
server/prisma/prod.db
Normal file
BIN
server/prisma/prod.db
Normal file
Binary file not shown.
BIN
server/prisma/test.db
Normal file
BIN
server/prisma/test.db
Normal file
Binary file not shown.
@@ -23,11 +23,27 @@ const app = express();
|
|||||||
// Ensure a default admin user exists on startup
|
// Ensure a default admin user exists on startup
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
async function ensureAdminUser() {
|
async function ensureAdminUser() {
|
||||||
const adminEmail = process.env.ADMIN_EMAIL;
|
const mode = process.env.APP_MODE || 'dev';
|
||||||
const adminPassword = process.env.ADMIN_PASSWORD;
|
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) {
|
if (!adminEmail || !adminPassword) {
|
||||||
console.warn('⚠️ ADMIN_EMAIL or ADMIN_PASSWORD not set in .env. Skipping default admin creation.');
|
console.warn(`⚠️ Admin credentials for mode ${mode} not found in .env. Skipping default admin creation.`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,10 +10,32 @@ declare global {
|
|||||||
var prisma: PrismaClient | undefined;
|
var prisma: PrismaClient | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
const dbUrl = process.env.DATABASE_URL;
|
const mode = process.env.APP_MODE || 'dev';
|
||||||
|
console.log(`[Prisma] Initializing in ${mode.toUpperCase()} mode`);
|
||||||
|
|
||||||
|
let dbUrl: string | undefined;
|
||||||
|
|
||||||
|
switch (mode) {
|
||||||
|
case 'test':
|
||||||
|
dbUrl = process.env.DATABASE_URL_TEST;
|
||||||
|
break;
|
||||||
|
case 'prod':
|
||||||
|
dbUrl = process.env.DATABASE_URL_PROD;
|
||||||
|
break;
|
||||||
|
case 'dev':
|
||||||
|
default:
|
||||||
|
dbUrl = process.env.DATABASE_URL_DEV;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallback to generic DATABASE_URL if specific one is missing
|
||||||
|
if (!dbUrl) {
|
||||||
|
console.warn(`[Prisma] DATABASE_URL_${mode.toUpperCase()} not found, falling back to DATABASE_URL`);
|
||||||
|
dbUrl = process.env.DATABASE_URL;
|
||||||
|
}
|
||||||
|
|
||||||
if (!dbUrl) {
|
if (!dbUrl) {
|
||||||
throw new Error("DATABASE_URL environment variable is not set. Please check your .env file.");
|
throw new Error(`DATABASE_URL environment variable is not set for mode ${mode}. Please check your .env file.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('Initializing Prisma Adapter with URL:', dbUrl);
|
console.log('Initializing Prisma Adapter with URL:', dbUrl);
|
||||||
|
|||||||
@@ -396,7 +396,7 @@ router.post('/active/log-set', async (req: any, res) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (plan) {
|
if (plan) {
|
||||||
const planExercises: { id: string }[] = JSON.parse(plan.exercises);
|
const planExercises: { id: string }[] = JSON.parse(plan.exercises || '[]');
|
||||||
const allPerformedSets = await prisma.workoutSet.findMany({
|
const allPerformedSets = await prisma.workoutSet.findMany({
|
||||||
where: { sessionId: activeSession.id }
|
where: { sessionId: activeSession.id }
|
||||||
});
|
});
|
||||||
|
|||||||
BIN
server/test.db
Normal file
BIN
server/test.db
Normal file
Binary file not shown.
Reference in New Issue
Block a user