CentralBackend/services/user/guest/GuestUserService.js

113 lines
4.1 KiB
JavaScript

const PersonalUserRepository = require('../../../repositories/user/personal/PersonalUserRepository');
const UserStatusService = require('../../status/UserStatusService');
const UnitOfWork = require('../../../database/UnitOfWork');
const MailService = require('../../email/MailService');
const AbonemmentService = require('../../abonemments/AbonemmentService');
const User = require('../../../models/User');
const { logger } = require('../../../middleware/logger');
const abonemmentService = new AbonemmentService();
class GuestUserService {
/**
* Create a guest user account with role='guest'.
* Guest users only have access to subscriptions, nothing else.
*/
static async createGuestUser({ email, password, firstName, lastName, referralEmail, lang }) {
logger.info('GuestUserService.createGuestUser:start', { email, firstName, lastName });
const unitOfWork = new UnitOfWork();
await unitOfWork.start();
unitOfWork.registerRepository('personalUser', new PersonalUserRepository(unitOfWork));
try {
const personalRepo = unitOfWork.getRepository('personalUser');
// Check if user already exists
const existing = await personalRepo.findByEmail(email);
if (existing) {
await unitOfWork.rollback();
throw new Error('User already exists');
}
// Create user in DB with role='guest'
const conn = unitOfWork.connection;
const hashedPassword = await User.hashPassword(password);
const [userResult] = await conn.query(
`INSERT INTO users (email, password, user_type, role) VALUES (?, ?, 'personal', 'guest')`,
[email, hashedPassword]
);
const userId = userResult.insertId;
await conn.query(
`INSERT INTO personal_profiles (user_id, first_name, last_name) VALUES (?, ?, ?)`,
[userId, firstName, lastName]
);
// Initialize user status as active (skip full registration flow for guests)
await UserStatusService.initializeUserStatus(userId, 'personal', unitOfWork, 'active');
// Mark ALL status flags as completed for guests — they skip the entire quickaction flow
await conn.query(
`UPDATE user_status SET email_verified = TRUE, profile_completed = TRUE, documents_uploaded = TRUE, contract_signed = TRUE, registration_completed = TRUE, is_admin_verified = TRUE WHERE user_id = ?`,
[userId]
);
// Handle referral if provided
if (referralEmail) {
try {
const ReferralService = require('../../referral/ReferralService');
await ReferralService.processReferral(userId, referralEmail, unitOfWork);
} catch (refErr) {
logger.warn('GuestUserService.createGuestUser:referral_failed', { userId, error: refErr?.message });
}
}
// Link any pending gift subscriptions to this user
await abonemmentService.linkGiftFlagsToUser(email, userId);
// Send a welcome email
const chosenLang = lang || 'en';
await MailService.sendRegistrationEmail({
email,
firstName,
lastName,
userType: 'personal',
lang: chosenLang,
});
await unitOfWork.commit();
logger.info('GuestUserService.createGuestUser:success', { userId, email });
return { id: userId, email, firstName, lastName, role: 'guest' };
} catch (error) {
logger.error('GuestUserService.createGuestUser:error', { email, error: error.message });
await unitOfWork.rollback(error);
throw error;
}
}
static async findGuestByEmail(email) {
const unitOfWork = new UnitOfWork();
await unitOfWork.start();
try {
const conn = unitOfWork.connection;
const [rows] = await conn.query(
`SELECT u.id, u.email, u.role, pp.first_name, pp.last_name
FROM users u
LEFT JOIN personal_profiles pp ON u.id = pp.user_id
WHERE u.email = ? AND u.role = 'guest' LIMIT 1`,
[email]
);
await unitOfWork.commit();
return rows[0] || null;
} catch (error) {
await unitOfWork.rollback(error);
throw error;
}
}
}
module.exports = GuestUserService;