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 non-email status flags as completed for guests — they skip ID upload, profile, and contract // email_verified stays FALSE so guests must verify their email on first login await conn.query( `UPDATE user_status SET email_verified = FALSE, 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;