151 lines
3.9 KiB
TypeScript
151 lines
3.9 KiB
TypeScript
/**
|
|
* Domain Entity: SponsorAccount
|
|
*
|
|
* Represents a sponsor's login account in the identity bounded context.
|
|
* Separate from the racing domain's Sponsor entity which holds business data.
|
|
*/
|
|
|
|
import { UserId } from '../value-objects/UserId';
|
|
import type { EmailValidationResult } from '../types/EmailAddress';
|
|
import { validateEmail } from '../types/EmailAddress';
|
|
|
|
export interface SponsorAccountProps {
|
|
id: UserId;
|
|
sponsorId: string; // Reference to racing domain's Sponsor entity
|
|
email: string;
|
|
passwordHash: string;
|
|
companyName: string;
|
|
isActive: boolean;
|
|
createdAt: Date;
|
|
lastLoginAt?: Date;
|
|
}
|
|
|
|
export class SponsorAccount {
|
|
private readonly id: UserId;
|
|
private readonly sponsorId: string;
|
|
private email: string;
|
|
private passwordHash: string;
|
|
private companyName: string;
|
|
private isActive: boolean;
|
|
private readonly createdAt: Date;
|
|
private lastLoginAt: Date | undefined;
|
|
|
|
private constructor(props: SponsorAccountProps) {
|
|
this.id = props.id;
|
|
this.sponsorId = props.sponsorId;
|
|
this.email = props.email;
|
|
this.passwordHash = props.passwordHash;
|
|
this.companyName = props.companyName;
|
|
this.isActive = props.isActive;
|
|
this.createdAt = props.createdAt ?? new Date();
|
|
this.lastLoginAt = props.lastLoginAt;
|
|
}
|
|
|
|
public static create(props: Omit<SponsorAccountProps, 'createdAt' | 'isActive'> & {
|
|
createdAt?: Date;
|
|
isActive?: boolean;
|
|
}): SponsorAccount {
|
|
if (!props.sponsorId || !props.sponsorId.trim()) {
|
|
throw new Error('SponsorAccount sponsorId is required');
|
|
}
|
|
|
|
if (!props.companyName || !props.companyName.trim()) {
|
|
throw new Error('SponsorAccount companyName is required');
|
|
}
|
|
|
|
if (!props.passwordHash || !props.passwordHash.trim()) {
|
|
throw new Error('SponsorAccount passwordHash is required');
|
|
}
|
|
|
|
const emailResult: EmailValidationResult = validateEmail(props.email);
|
|
if (!emailResult.success) {
|
|
throw new Error(emailResult.error);
|
|
}
|
|
|
|
return new SponsorAccount({
|
|
...props,
|
|
email: emailResult.email,
|
|
createdAt: props.createdAt ?? new Date(),
|
|
isActive: props.isActive ?? true,
|
|
});
|
|
}
|
|
|
|
public getId(): UserId {
|
|
return this.id;
|
|
}
|
|
|
|
public getSponsorId(): string {
|
|
return this.sponsorId;
|
|
}
|
|
|
|
public getEmail(): string {
|
|
return this.email;
|
|
}
|
|
|
|
public getPasswordHash(): string {
|
|
return this.passwordHash;
|
|
}
|
|
|
|
public getCompanyName(): string {
|
|
return this.companyName;
|
|
}
|
|
|
|
public getIsActive(): boolean {
|
|
return this.isActive;
|
|
}
|
|
|
|
public getCreatedAt(): Date {
|
|
return this.createdAt;
|
|
}
|
|
|
|
public getLastLoginAt(): Date | undefined {
|
|
return this.lastLoginAt;
|
|
}
|
|
|
|
public canLogin(): boolean {
|
|
return this.isActive;
|
|
}
|
|
|
|
public recordLogin(): SponsorAccount {
|
|
return new SponsorAccount({
|
|
id: this.id,
|
|
sponsorId: this.sponsorId,
|
|
email: this.email,
|
|
passwordHash: this.passwordHash,
|
|
companyName: this.companyName,
|
|
isActive: this.isActive,
|
|
createdAt: this.createdAt,
|
|
lastLoginAt: new Date(),
|
|
});
|
|
}
|
|
|
|
public deactivate(): SponsorAccount {
|
|
return new SponsorAccount({
|
|
id: this.id,
|
|
sponsorId: this.sponsorId,
|
|
email: this.email,
|
|
passwordHash: this.passwordHash,
|
|
companyName: this.companyName,
|
|
isActive: false,
|
|
createdAt: this.createdAt,
|
|
...(this.lastLoginAt ? { lastLoginAt: this.lastLoginAt } : {}),
|
|
});
|
|
}
|
|
|
|
public updatePassword(newPasswordHash: string): SponsorAccount {
|
|
if (!newPasswordHash || !newPasswordHash.trim()) {
|
|
throw new Error('Password hash cannot be empty');
|
|
}
|
|
|
|
return new SponsorAccount({
|
|
id: this.id,
|
|
sponsorId: this.sponsorId,
|
|
email: this.email,
|
|
passwordHash: newPasswordHash,
|
|
companyName: this.companyName,
|
|
isActive: this.isActive,
|
|
createdAt: this.createdAt,
|
|
...(this.lastLoginAt ? { lastLoginAt: this.lastLoginAt } : {}),
|
|
});
|
|
}
|
|
} |