wip
This commit is contained in:
83
packages/identity/domain/entities/UserAchievement.ts
Normal file
83
packages/identity/domain/entities/UserAchievement.ts
Normal file
@@ -0,0 +1,83 @@
|
||||
/**
|
||||
* Domain Entity: UserAchievement
|
||||
*
|
||||
* Represents an achievement earned by a specific user.
|
||||
*/
|
||||
|
||||
export interface UserAchievementProps {
|
||||
id: string;
|
||||
userId: string;
|
||||
achievementId: string;
|
||||
earnedAt: Date;
|
||||
notifiedAt?: Date;
|
||||
progress?: number; // For partial progress tracking (0-100)
|
||||
}
|
||||
|
||||
export class UserAchievement {
|
||||
readonly id: string;
|
||||
readonly userId: string;
|
||||
readonly achievementId: string;
|
||||
readonly earnedAt: Date;
|
||||
readonly notifiedAt?: Date;
|
||||
readonly progress: number;
|
||||
|
||||
private constructor(props: UserAchievementProps) {
|
||||
this.id = props.id;
|
||||
this.userId = props.userId;
|
||||
this.achievementId = props.achievementId;
|
||||
this.earnedAt = props.earnedAt;
|
||||
this.notifiedAt = props.notifiedAt;
|
||||
this.progress = props.progress ?? 100;
|
||||
}
|
||||
|
||||
static create(props: UserAchievementProps): UserAchievement {
|
||||
if (!props.id || props.id.trim().length === 0) {
|
||||
throw new Error('UserAchievement ID is required');
|
||||
}
|
||||
|
||||
if (!props.userId || props.userId.trim().length === 0) {
|
||||
throw new Error('UserAchievement userId is required');
|
||||
}
|
||||
|
||||
if (!props.achievementId || props.achievementId.trim().length === 0) {
|
||||
throw new Error('UserAchievement achievementId is required');
|
||||
}
|
||||
|
||||
return new UserAchievement(props);
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark achievement as notified to user
|
||||
*/
|
||||
markNotified(): UserAchievement {
|
||||
return new UserAchievement({
|
||||
...this,
|
||||
notifiedAt: new Date(),
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Update progress towards achievement
|
||||
*/
|
||||
updateProgress(progress: number): UserAchievement {
|
||||
const clampedProgress = Math.max(0, Math.min(100, progress));
|
||||
return new UserAchievement({
|
||||
...this,
|
||||
progress: clampedProgress,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if achievement is fully earned
|
||||
*/
|
||||
isComplete(): boolean {
|
||||
return this.progress >= 100;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if user has been notified
|
||||
*/
|
||||
isNotified(): boolean {
|
||||
return this.notifiedAt !== undefined;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user