CentralBackend/repositories/UserRepository.js
2025-09-07 12:44:01 +02:00

375 lines
15 KiB
JavaScript

const PersonalUser = require('../models/PersonalUser');
const CompanyUser = require('../models/CompanyUser');
const User = require('../models/User');
const { logger } = require('../middleware/logger');
class UserRepository {
constructor(unitOfWork) {
this.unitOfWork = unitOfWork;
}
async createUser(email, hashedPassword, userType) {
logger.info('UserRepository.createUser:start', { email, userType });
try {
const conn = this.unitOfWork.connection;
const query = `
INSERT INTO users (email, password, user_type, role)
VALUES (?, ?, ?, 'user')
`;
const [result] = await conn.query(query, [email, hashedPassword, userType]);
logger.info('UserRepository.createUser:success', { email, userType, userId: result.insertId });
return result.insertId;
} catch (error) {
logger.error('UserRepository.createUser:error', { email, userType, error: error.message });
throw error;
}
}
async findUserByEmail(email) {
logger.info('UserRepository.findUserByEmail:start', { email });
try {
const conn = this.unitOfWork.connection;
// Query user, company profile, and personal profile data
const query = `
SELECT u.*,
cp.company_name, cp.registration_number, cp.phone as company_phone,
cp.contact_person_name, cp.contact_person_phone,
pp.first_name, pp.last_name, pp.phone as personal_phone, pp.date_of_birth
FROM users u
LEFT JOIN company_profiles cp ON u.id = cp.user_id
LEFT JOIN personal_profiles pp ON u.id = pp.user_id
WHERE u.email = ?
`;
const [rows] = await conn.query(query, [email]);
if (rows.length > 0) {
logger.info('UserRepository.findUserByEmail:found', { email, userId: rows[0].id });
const row = rows[0];
if (row.user_type === 'personal') {
return new PersonalUser(
row.id, row.email, row.password, row.first_name || '', row.last_name || '',
row.phone || '', row.date_of_birth || null, null, row.created_at, row.updated_at, row.role
);
} else if (row.user_type === 'company') {
return new CompanyUser(
row.id, row.email, row.password, row.company_name || '', row.company_phone || '',
row.contact_person_name || '', row.contact_person_phone || '', row.registration_number || '',
row.created_at, row.updated_at, row.role
);
} else {
return new User(
row.id, row.email, row.password, row.user_type, row.created_at, row.updated_at, row.role
);
}
}
logger.info('UserRepository.findUserByEmail:not_found', { email });
return null;
} catch (error) {
logger.error('UserRepository.findUserByEmail:error', { email, error: error.message });
throw error;
}
}
async createPersonalProfile(userId, profileData) {
logger.info('UserRepository.createPersonalProfile:start', { userId });
try {
const conn = this.unitOfWork.connection;
const { firstName, lastName, phone } = profileData;
const query = `
INSERT INTO personal_profiles (user_id, first_name, last_name, phone)
VALUES (?, ?, ?, ?)
`;
await conn.query(query, [userId, firstName, lastName, phone]);
logger.info('UserRepository.createPersonalProfile:success', { userId });
} catch (error) {
logger.error('UserRepository.createPersonalProfile:error', { userId, error: error.message });
throw error;
}
}
async findPersonalUserByEmail(email) {
logger.info('UserRepository.findPersonalUserByEmail:start', { email });
try {
const conn = this.unitOfWork.connection;
const query = `
SELECT u.*, pp.first_name, pp.last_name, pp.phone, pp.date_of_birth
FROM users u
LEFT JOIN personal_profiles pp ON u.id = pp.user_id
WHERE u.email = ? AND u.user_type = 'personal'
`;
const [rows] = await conn.query(query, [email]);
if (rows.length > 0) {
logger.info('UserRepository.findPersonalUserByEmail:found', { email, userId: rows[0].id });
const row = rows[0];
return new PersonalUser(
row.id, row.email, row.password, row.first_name,
row.last_name, row.phone, row.date_of_birth, null,
row.created_at, row.updated_at
);
}
logger.info('UserRepository.findPersonalUserByEmail:not_found', { email });
return null;
} catch (error) {
logger.error('UserRepository.findPersonalUserByEmail:error', { email, error: error.message });
throw error;
}
}
async createCompanyProfile(userId, profileData) {
logger.info('UserRepository.createCompanyProfile:start', { userId });
try {
const conn = this.unitOfWork.connection;
const { companyName, registrationNumber, companyPhone, contactPersonName } = profileData;
const query = `
INSERT INTO company_profiles (user_id, company_name, registration_number, phone, contact_person_name)
VALUES (?, ?, ?, ?, ?)
`;
await conn.query(query, [userId, companyName, registrationNumber, companyPhone, contactPersonName]);
logger.info('UserRepository.createCompanyProfile:success', { userId });
} catch (error) {
logger.error('UserRepository.createCompanyProfile:error', { userId, error: error.message });
throw error;
}
}
async findCompanyUserByEmail(email) {
logger.info('UserRepository.findCompanyUserByEmail:start', { email });
try {
const conn = this.unitOfWork.connection;
const query = `
SELECT u.*, cp.company_name, cp.registration_number, cp.phone as company_phone, cp.contact_person_name
FROM users u
LEFT JOIN company_profiles cp ON u.id = cp.user_id
WHERE u.email = ? AND u.user_type = 'company'
`;
const [rows] = await conn.query(query, [email]);
if (rows.length > 0) {
logger.info('UserRepository.findCompanyUserByEmail:found', { email, userId: rows[0].id });
const row = rows[0];
return new CompanyUser(
row.id, row.email, row.password, row.company_name,
row.company_phone, row.contact_person_name, null,
row.registration_number, row.created_at, row.updated_at
);
}
logger.info('UserRepository.findCompanyUserByEmail:not_found', { email });
return null;
} catch (error) {
logger.error('UserRepository.findCompanyUserByEmail:error', { email, error: error.message });
throw error;
}
}
async createUserStatus(userId) {
logger.info('UserRepository.createUserStatus:start', { userId });
try {
const conn = this.unitOfWork.connection;
const query = `
INSERT INTO user_status (user_id, status, email_verified, profile_completed, registration_completed)
VALUES (?, 'pending', FALSE, TRUE, FALSE)
`;
await conn.query(query, [userId]);
logger.info('UserRepository.createUserStatus:success', { userId });
} catch (error) {
logger.error('UserRepository.createUserStatus:error', { userId, error: error.message });
throw error;
}
}
async findUserByEmailOrId(identifier) {
logger.info('UserRepository.findUserByEmailOrId:start', { identifier });
try {
const conn = this.unitOfWork.connection;
let query, params;
if (typeof identifier === 'number' || /^\d+$/.test(identifier)) {
query = `
SELECT u.*,
cp.company_name, cp.registration_number, cp.phone as company_phone,
cp.contact_person_name, cp.contact_person_phone,
pp.first_name, pp.last_name, pp.phone as personal_phone, pp.date_of_birth
FROM users u
LEFT JOIN company_profiles cp ON u.id = cp.user_id
LEFT JOIN personal_profiles pp ON u.id = pp.user_id
WHERE u.id = ?
`;
params = [identifier];
} else {
query = `
SELECT u.*,
cp.company_name, cp.registration_number, cp.phone as company_phone,
cp.contact_person_name, cp.contact_person_phone,
pp.first_name, pp.last_name, pp.phone as personal_phone, pp.date_of_birth
FROM users u
LEFT JOIN company_profiles cp ON u.id = cp.user_id
LEFT JOIN personal_profiles pp ON u.id = pp.user_id
WHERE u.email = ?
`;
params = [identifier];
}
const [rows] = await conn.query(query, params);
if (rows.length > 0) {
logger.info('UserRepository.findUserByEmailOrId:found', { identifier, userId: rows[0].id });
const row = rows[0];
if (row.user_type === 'company') {
return new CompanyUser(
row.id, row.email, row.password, row.company_name || '', row.company_phone || '',
row.contact_person_name || '', row.contact_person_phone || '', row.registration_number || '',
row.created_at, row.updated_at
);
} else if (row.user_type === 'personal') {
return new PersonalUser(
row.id, row.email, row.password, row.first_name || '', row.last_name || '',
row.personal_phone || '', row.date_of_birth || null, null,
row.created_at, row.updated_at
);
} else {
return new User(
row.id, row.email, row.password, row.user_type, row.created_at, row.updated_at
);
}
}
logger.info('UserRepository.findUserByEmailOrId:not_found', { identifier });
return null;
} catch (error) {
logger.error('UserRepository.findUserByEmailOrId:error', { identifier, error: error.message });
throw error;
}
}
async getIban(userId) {
logger.info('UserRepository.getIban:start', { userId });
try {
const conn = this.unitOfWork.connection;
const [rows] = await conn.query(
`SELECT iban FROM users WHERE id = ? LIMIT 1`, [userId]
);
logger.info('UserRepository.getIban:success', { userId, iban: rows.length ? rows[0].iban : null });
return rows.length ? rows[0].iban : null;
} catch (error) {
logger.error('UserRepository.getIban:error', { userId, error: error.message });
throw error;
}
}
async getProfile(userId, userType) {
logger.info('UserRepository.getProfile:start', { userId, userType });
try {
const conn = this.unitOfWork.connection;
if (userType === 'personal') {
const [rows] = await conn.query(
`SELECT * FROM personal_profiles WHERE user_id = ? LIMIT 1`, [userId]
);
logger.info('UserRepository.getProfile:success', { userId, userType });
return rows.length ? rows[0] : null;
} else if (userType === 'company') {
const [rows] = await conn.query(
`SELECT * FROM company_profiles WHERE user_id = ? LIMIT 1`, [userId]
);
logger.info('UserRepository.getProfile:success', { userId, userType });
return rows.length ? rows[0] : null;
}
logger.info('UserRepository.getProfile:not_found', { userId, userType });
return null;
} catch (error) {
logger.error('UserRepository.getProfile:error', { userId, userType, error: error.message });
throw error;
}
}
async getReferralEmail(userId, userType) {
logger.info('UserRepository.getReferralEmail:start', { userId, userType });
try {
const conn = this.unitOfWork.connection;
const [rows] = await conn.query(
`SELECT u.email AS referralEmail
FROM referral_token_usage rtu
JOIN referral_tokens rt ON rtu.referral_token_id = rt.id
JOIN users u ON rt.created_by_user_id = u.id
WHERE rtu.used_by_user_id = ? LIMIT 1`,
[userId]
);
logger.info('UserRepository.getReferralEmail:success', { userId, referralEmail: rows.length ? rows[0].referralEmail : null });
return rows.length ? rows[0].referralEmail : null;
} catch (error) {
logger.error('UserRepository.getReferralEmail:error', { userId, userType, error: error.message });
throw error;
}
}
async getPermissions(userId) {
logger.info('UserRepository.getPermissions:start', { userId });
try {
const conn = this.unitOfWork.connection;
const [permRows] = await conn.query(
`SELECT p.name FROM user_permissions up
JOIN permissions p ON up.permission_id = p.id
WHERE up.user_id = ? AND p.is_active = TRUE`,
[userId]
);
logger.info('UserRepository.getPermissions:success', { userId, count: permRows.length });
return permRows.map(row => row.name);
} catch (error) {
logger.error('UserRepository.getPermissions:error', { userId, error: error.message });
throw error;
}
}
async getUserStatus(userId) {
logger.info('UserRepository.getUserStatus:start', { userId });
try {
const conn = this.unitOfWork.connection;
const [rows] = await conn.query(
`SELECT * FROM user_status WHERE user_id = ? LIMIT 1`, [userId]
);
logger.info('UserRepository.getUserStatus:success', { userId, found: rows.length > 0 });
return rows.length ? rows[0] : null;
} catch (error) {
logger.error('UserRepository.getUserStatus:error', { userId, error: error.message });
throw error;
}
}
async getContracts(userId) {
logger.info('UserRepository.getContracts:start', { userId });
try {
const conn = this.unitOfWork.connection;
const [rows] = await conn.query(
`SELECT * FROM user_documents WHERE user_id = ? AND document_type = 'contract'`, [userId]
);
logger.info('UserRepository.getContracts:success', { userId, count: rows.length });
return rows;
} catch (error) {
logger.error('UserRepository.getContracts:error', { userId, error: error.message });
throw error;
}
}
async getIdDocuments(userId) {
logger.info('UserRepository.getIdDocuments:start', { userId });
try {
const conn = this.unitOfWork.connection;
const [rows] = await conn.query(
`SELECT * FROM user_id_documents WHERE user_id = ?`, [userId]
);
logger.info('UserRepository.getIdDocuments:success', { userId, count: rows.length });
return rows;
} catch (error) {
logger.error('UserRepository.getIdDocuments:error', { userId, error: error.message });
throw error;
}
}
async deleteUserById(userId) {
logger.info('UserRepository.deleteUserById:start', { userId });
try {
const conn = this.unitOfWork.connection;
await conn.query(`DELETE FROM users WHERE id = ?`, [userId]);
logger.info('UserRepository.deleteUserById:success', { userId });
} catch (error) {
logger.error('UserRepository.deleteUserById:error', { userId, error: error.message });
throw error;
}
}
}
module.exports = UserRepository;