375 lines
15 KiB
JavaScript
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;
|