import { EmailAddress } from '../../domain/value-objects/EmailAddress'; import { UserId } from '../../domain/value-objects/UserId'; import { User } from '../../domain/entities/User'; import { IAuthRepository } from '../../domain/repositories/IAuthRepository'; import { IPasswordHashingService } from '../../domain/services/PasswordHashingService'; import { Result } from '@core/shared/application/Result'; import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode'; import type { UseCaseOutputPort, Logger, UseCase } from '@core/shared/application'; export type SignupInput = { email: string; password: string; displayName: string; }; export type SignupResult = { user: User; }; export type SignupErrorCode = 'USER_ALREADY_EXISTS' | 'REPOSITORY_ERROR'; export type SignupApplicationError = ApplicationErrorCode; /** * Application Use Case: SignupUseCase * * Handles user registration. */ export class SignupUseCase implements UseCase { constructor( private readonly authRepo: IAuthRepository, private readonly passwordService: IPasswordHashingService, private readonly logger: Logger, private readonly output: UseCaseOutputPort, ) {} async execute(input: SignupInput): Promise> { try { const emailVO = EmailAddress.create(input.email); const existingUser = await this.authRepo.findByEmail(emailVO); if (existingUser) { return Result.err({ code: 'USER_ALREADY_EXISTS', details: { message: 'User already exists' }, }); } const hashedPassword = await this.passwordService.hash(input.password); const passwordHashModule = await import('../../domain/value-objects/PasswordHash'); const passwordHash = passwordHashModule.PasswordHash.fromHash(hashedPassword); const userId = UserId.create(); const user = User.create({ id: userId, displayName: input.displayName, email: emailVO.value, passwordHash, }); await this.authRepo.save(user); this.output.present({ user }); return Result.ok(undefined); } catch (error) { const message = error instanceof Error && error.message ? error.message : 'Failed to execute SignupUseCase'; this.logger.error('SignupUseCase.execute failed', error instanceof Error ? error : undefined, { input, }); return Result.err({ code: 'REPOSITORY_ERROR', details: { message }, }); } } }