Work with DB fixed including default Admin creation

This commit is contained in:
aodulov
2025-12-12 11:51:57 +02:00
parent bc1b747ef4
commit 3ede054766
14 changed files with 106 additions and 106 deletions

View File

@@ -9,7 +9,8 @@
"preview": "vite preview",
"dev:full": "npm-run-all --parallel dev \"dev --prefix server\"",
"dev:full:bg": "npm-run-all --parallel dev \"dev --prefix server\" &",
"prod:full": "npm-run-all --parallel preview \"start:prod --prefix server\"",
"prod:full": "npm-run-all --parallel preview server:prod",
"server:prod": "npm run start:prod --prefix server",
"server:test": "npm run start:test --prefix server",
"test:full": "npm-run-all --parallel dev server:test"
},

View File

@@ -1,12 +0,0 @@
const { PrismaClient } = require('@prisma/client');
(async () => {
const prisma = new PrismaClient();
try {
const admin = await prisma.user.findFirst({ where: { role: 'ADMIN' } });
console.log('Admin user:', admin);
} catch (e) {
console.error('Error:', e);
} finally {
await prisma.$disconnect();
}
})();

30
server/check_adapter.ts Normal file
View File

@@ -0,0 +1,30 @@
import { PrismaBetterSqlite3 } from '@prisma/adapter-better-sqlite3';
import Database from 'better-sqlite3';
try {
console.log("Attempting incorrect usage...");
// @ts-ignore
new PrismaBetterSqlite3({ url: 'file:./dev.db' });
console.log("Incorrect usage presumed worked? (Unexpected)");
} catch (e) {
console.log("Incorrect usage failed as expected:", e.message);
}
try {
console.log("Attempting correct usage...");
const db = new Database('./dev.db');
new PrismaBetterSqlite3(db);
console.log("Correct usage worked.");
} catch (e) {
console.log("Correct usage failed:", e);
}
try {
console.log("Attempting correct usage with file: prefix...");
const db = new Database('file:./dev.db');
new PrismaBetterSqlite3(db);
console.log("Correct usage with prefix worked.");
} catch (e) {
console.log("Correct usage with prefix failed:", e.message);
}

Binary file not shown.

View File

@@ -5,7 +5,7 @@
"main": "src/index.ts",
"scripts": {
"start": "npm run start:prod",
"start:prod": "cross-env APP_MODE=prod node dist/index.js",
"start:prod": "cross-env APP_MODE=prod DATABASE_URL=file:./prod.db npx prisma db push && cross-env APP_MODE=prod DATABASE_URL_PROD=file:./prod.db ts-node-dev -r dotenv/config --respawn --transpile-only src/index.ts",
"start:test": "cross-env APP_MODE=test DATABASE_URL=file:./test.db DATABASE_URL_TEST=file:./test.db npx prisma db push --accept-data-loss && cross-env APP_MODE=test DATABASE_URL_TEST=file:./test.db 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",

View File

@@ -1,5 +1,9 @@
export default {
import 'dotenv/config';
import { defineConfig, env } from 'prisma/config';
export default defineConfig({
schema: 'prisma/schema.prisma',
datasource: {
url: process.env.DATABASE_URL || "file:./dev.db",
url: env('DATABASE_URL'),
},
};
});

Binary file not shown.

Binary file not shown.

Binary file not shown.

37
server/repro_login.ts Normal file
View File

@@ -0,0 +1,37 @@
import { AuthService } from './src/services/auth.service';
import prisma from './src/lib/prisma';
import bcrypt from 'bcryptjs';
// const prisma = new PrismaClient(); // Removed local instance
async function run() {
try {
console.log("Setting up test user...");
const email = 'repro_user@gymflow.ai';
const password = 'password123';
const hashed = await bcrypt.hash(password, 10);
await prisma.user.upsert({
where: { email },
update: { password: hashed, isBlocked: false },
create: {
email,
password: hashed,
role: 'USER',
profile: { create: { weight: 70 } }
}
});
console.log("Attempting login...");
const result = await AuthService.login(email, password);
console.log("Login success:", result ? "OK" : "No result");
} catch (error) {
console.error("Login failed with error:");
console.error(error);
} finally {
await prisma.$disconnect();
}
}
run();

View File

@@ -1,7 +1,5 @@
import { PrismaClient } from '@prisma/client';
import { PrismaBetterSqlite3 } from '@prisma/adapter-better-sqlite3';
// Ensure env vars are loaded
import 'dotenv/config';
declare global {
@@ -13,44 +11,46 @@ declare global {
const mode = process.env.APP_MODE || 'dev';
console.log(`[Prisma] Initializing in ${mode.toUpperCase()} mode`);
let dbUrl: string | undefined;
let dbPath: string;
switch (mode) {
case 'test':
dbUrl = process.env.DATABASE_URL_TEST;
dbPath = process.env.DATABASE_URL_TEST || './test.db';
break;
case 'prod':
dbUrl = process.env.DATABASE_URL_PROD;
dbPath = process.env.DATABASE_URL_PROD || './prod.db';
break;
case 'dev':
default:
dbUrl = process.env.DATABASE_URL_DEV;
dbPath = process.env.DATABASE_URL_DEV || './dev.db';
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;
// Remove 'file:' prefix if present
if (dbPath.startsWith('file:')) {
dbPath = dbPath.slice(5);
}
if (!dbUrl) {
throw new Error(`DATABASE_URL environment variable is not set for mode ${mode}. Please check your .env file.`);
console.log('Initializing Prisma Client with database:', dbPath);
let prisma: PrismaClient;
try {
const adapter = new PrismaBetterSqlite3({ url: dbPath });
prisma =
global.prisma ||
new PrismaClient({
adapter: adapter as any,
});
} catch (e: any) {
console.error('Failed to initialize Prisma Client:', e.message);
process.exit(1);
}
console.log('Initializing Prisma Adapter with URL:', dbUrl);
// Use the options object as required by the library definitions
const adapter = new PrismaBetterSqlite3({ url: dbUrl });
const prisma =
global.prisma ||
new PrismaClient({
adapter,
});
if (process.env.NODE_ENV !== 'production') {
global.prisma = prisma;
}
export default prisma;

View File

@@ -10,7 +10,11 @@ export const validate = (schema: ZodSchema<any>) => async (req: Request, res: Re
params: req.params,
});
return next();
} catch (error) {
return sendError(res, `Validation Error: ${JSON.stringify(error)}`, 400);
} catch (error: any) {
console.error('Validation error:', {
body: req.body,
error: error.errors || error
});
return sendError(res, `Validation Error: ${JSON.stringify(error.errors || error)}`, 400);
}
};

Binary file not shown.

View File

@@ -1,64 +0,0 @@
import { PrismaClient } from '@prisma/client';
import bcrypt from 'bcryptjs';
async function createTestUsers() {
const prisma = new PrismaClient();
// Create a regular user
const user1Email = 'user1@gymflow.ai';
const user1Password = 'user1pass';
const hashedUser1Password = await bcrypt.hash(user1Password, 10);
await prisma.user.upsert({
where: { email: user1Email },
update: { password: hashedUser1Password },
create: {
email: user1Email,
password: hashedUser1Password,
role: 'USER',
profile: { create: { weight: 70 } },
},
});
// Create another regular user
const user2Email = 'user2@gymflow.ai';
const user2Password = 'user2pass';
const hashedUser2Password = await bcrypt.hash(user2Password, 10);
await prisma.user.upsert({
where: { email: user2Email },
update: { password: hashedUser2Password },
create: {
email: user2Email,
password: hashedUser2Password,
role: 'USER',
profile: { create: { weight: 75 } },
},
});
// Create a user that will be blocked
const blockedUserEmail = 'blocked@gymflow.ai';
const blockedUserPassword = 'blockedpass';
const hashedBlockedUserPassword = await bcrypt.hash(blockedUserPassword, 10);
await prisma.user.upsert({
where: { email: blockedUserEmail },
update: { password: hashedBlockedUserPassword, isBlocked: true },
create: {
email: blockedUserEmail,
password: hashedBlockedUserPassword,
role: 'USER',
isBlocked: true,
profile: { create: { weight: 80 } },
},
});
console.log('Test users created or updated successfully.');
await prisma.$disconnect();
}
createTestUsers()
.catch((e) => {
console.error(e);
process.exit(1);
})
.finally(async () => {
// This script is meant to be run once to seed data, so we don't need to keep it running.
});