website refactor
This commit is contained in:
@@ -5,7 +5,7 @@
|
||||
* Achievements are categorized by role (driver, steward, admin) and type.
|
||||
*/
|
||||
|
||||
import type { Entity } from '@core/shared/domain/Entity';
|
||||
import { Entity } from '@core/shared/domain/Entity';
|
||||
|
||||
export type AchievementCategory = 'driver' | 'steward' | 'admin' | 'community';
|
||||
|
||||
@@ -32,8 +32,7 @@ export interface AchievementRequirement {
|
||||
operator: '>=' | '>' | '=' | '<' | '<=';
|
||||
}
|
||||
|
||||
export class Achievement implements Entity<string> {
|
||||
readonly id: string;
|
||||
export class Achievement extends Entity<string> {
|
||||
readonly name: string;
|
||||
readonly description: string;
|
||||
readonly category: AchievementCategory;
|
||||
@@ -45,7 +44,8 @@ export class Achievement implements Entity<string> {
|
||||
readonly createdAt: Date;
|
||||
|
||||
private constructor(props: AchievementProps) {
|
||||
this.id = props.id;
|
||||
super(props.id);
|
||||
|
||||
this.name = props.name;
|
||||
this.description = props.description;
|
||||
this.category = props.category;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { Entity, IEntity } from '@core/shared/domain/Entity';
|
||||
import { Entity } from '@core/shared/domain/Entity';
|
||||
import { IdentityDomainInvariantError, IdentityDomainValidationError } from '../errors/IdentityDomainError';
|
||||
|
||||
export interface AdminVote {
|
||||
@@ -42,8 +42,7 @@ export interface AdminVoteSessionProps {
|
||||
*
|
||||
* Based on ratings-architecture-concept.md sections 5.2.1 and 7.1.1
|
||||
*/
|
||||
export class AdminVoteSession implements Entity<string> {
|
||||
readonly id: string;
|
||||
export class AdminVoteSession extends Entity<string> {
|
||||
readonly leagueId: string;
|
||||
readonly adminId: string;
|
||||
readonly startDate: Date;
|
||||
@@ -56,7 +55,7 @@ export class AdminVoteSession implements Entity<string> {
|
||||
private _updatedAt: Date;
|
||||
|
||||
private constructor(props: AdminVoteSessionProps) {
|
||||
this.id = props.voteSessionId;
|
||||
super(props.voteSessionId);
|
||||
this.leagueId = props.leagueId;
|
||||
this.adminId = props.adminId;
|
||||
this.startDate = props.startDate;
|
||||
@@ -269,7 +268,7 @@ export class AdminVoteSession implements Entity<string> {
|
||||
return now >= this.startDate && now <= this.endDate && !this._closed;
|
||||
}
|
||||
|
||||
equals(other: IEntity<string>): boolean {
|
||||
equals(other: Entity<string>): boolean {
|
||||
return this.id === other.id;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { Entity, IEntity } from '@core/shared/domain/Entity';
|
||||
import { Entity } from '@core/shared/domain/Entity';
|
||||
import { IdentityDomainInvariantError, IdentityDomainValidationError } from '../errors/IdentityDomainError';
|
||||
import { RatingDelta } from '../value-objects/RatingDelta';
|
||||
import { RatingDimensionKey } from '../value-objects/RatingDimensionKey';
|
||||
@@ -34,8 +34,7 @@ export interface RatingEventProps {
|
||||
version: number;
|
||||
}
|
||||
|
||||
export class RatingEvent implements Entity<RatingEventId> {
|
||||
readonly id: RatingEventId;
|
||||
export class RatingEvent extends Entity<RatingEventId> {
|
||||
readonly userId: string;
|
||||
readonly dimension: RatingDimensionKey;
|
||||
readonly delta: RatingDelta;
|
||||
@@ -48,7 +47,8 @@ export class RatingEvent implements Entity<RatingEventId> {
|
||||
readonly version: number;
|
||||
|
||||
private constructor(props: RatingEventProps) {
|
||||
this.id = props.id;
|
||||
super(props.id);
|
||||
|
||||
this.userId = props.userId;
|
||||
this.dimension = props.dimension;
|
||||
this.delta = props.delta;
|
||||
@@ -118,7 +118,7 @@ export class RatingEvent implements Entity<RatingEventId> {
|
||||
return new RatingEvent(props);
|
||||
}
|
||||
|
||||
equals(other: IEntity<RatingEventId>): boolean {
|
||||
equals(other: Entity<RatingEventId>): boolean {
|
||||
return this.id.equals(other.id);
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* Represents an achievement earned by a specific user.
|
||||
*/
|
||||
|
||||
import type { Entity } from '@core/shared/domain/Entity';
|
||||
import { Entity } from '@core/shared/domain/Entity';
|
||||
|
||||
export interface UserAchievementProps {
|
||||
id: string;
|
||||
@@ -15,8 +15,7 @@ export interface UserAchievementProps {
|
||||
progress?: number; // For partial progress tracking (0-100)
|
||||
}
|
||||
|
||||
export class UserAchievement implements Entity<string> {
|
||||
readonly id: string;
|
||||
export class UserAchievement extends Entity<string> {
|
||||
readonly userId: string;
|
||||
readonly achievementId: string;
|
||||
readonly earnedAt: Date;
|
||||
@@ -24,7 +23,8 @@ export class UserAchievement implements Entity<string> {
|
||||
readonly progress: number;
|
||||
|
||||
private constructor(props: UserAchievementProps) {
|
||||
this.id = props.id;
|
||||
super(props.id);
|
||||
|
||||
this.userId = props.userId;
|
||||
this.achievementId = props.achievementId;
|
||||
this.earnedAt = props.earnedAt;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { DomainError, CommonDomainErrorKind } from '@core/shared/errors';
|
||||
import type { DomainError } from '@core/shared/errors/DomainError';
|
||||
import type { CommonDomainErrorKind } from '@core/shared/errors/DomainError';
|
||||
|
||||
export abstract class IdentityDomainError extends Error implements DomainError<CommonDomainErrorKind> {
|
||||
readonly type = 'domain' as const;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Repository Interface: IAchievementRepository
|
||||
* Repository Interface: AchievementRepository
|
||||
*
|
||||
* Defines operations for Achievement and UserAchievement entities
|
||||
*/
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { AdminVoteSession } from '../entities/AdminVoteSession';
|
||||
|
||||
/**
|
||||
* Repository Interface: IAdminVoteSessionRepository
|
||||
* Repository Interface: AdminVoteSessionRepository
|
||||
*
|
||||
* Port for persisting and retrieving admin vote sessions.
|
||||
* Sessions are scoped to leagues and control voting windows.
|
||||
|
||||
@@ -2,7 +2,7 @@ import { EmailAddress } from '../value-objects/EmailAddress';
|
||||
import { User } from '../entities/User';
|
||||
|
||||
/**
|
||||
* Domain Repository: IAuthRepository
|
||||
* Domain Repository: AuthRepository
|
||||
*
|
||||
* Repository interface for authentication operations.
|
||||
*/
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Company } from '../entities/Company';
|
||||
|
||||
/**
|
||||
* Domain Repository: ICompanyRepository
|
||||
* Domain Repository: CompanyRepository
|
||||
*
|
||||
* Repository interface for Company entity operations.
|
||||
*/
|
||||
|
||||
@@ -6,10 +6,10 @@ import { ExternalRating } from '../value-objects/ExternalRating';
|
||||
import { ExternalRatingProvenance } from '../value-objects/ExternalRatingProvenance';
|
||||
|
||||
/**
|
||||
* Test suite for IExternalGameRatingRepository interface
|
||||
* Test suite for ExternalGameRatingRepository interface
|
||||
* This tests the contract that all implementations must satisfy
|
||||
*/
|
||||
describe('IExternalGameRatingRepository', () => {
|
||||
describe('ExternalGameRatingRepository', () => {
|
||||
// Mock implementation for testing
|
||||
class MockExternalGameRatingRepository implements ExternalGameRatingRepository {
|
||||
private profiles: Map<string, ExternalGameRatingProfile> = new Map();
|
||||
@@ -105,7 +105,7 @@ describe('IExternalGameRatingRepository', () => {
|
||||
}
|
||||
}
|
||||
|
||||
let repository: IExternalGameRatingRepository;
|
||||
let repository: ExternalGameRatingRepository;
|
||||
|
||||
beforeEach(() => {
|
||||
repository = new MockExternalGameRatingRepository();
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { ExternalGameRatingProfile } from '../entities/ExternalGameRatingProfile';
|
||||
|
||||
/**
|
||||
* Repository Interface: IExternalGameRatingRepository
|
||||
* Repository Interface: ExternalGameRatingRepository
|
||||
*
|
||||
* Port for persisting and retrieving external game rating profiles.
|
||||
* Store/display only, no compute.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Unit tests for IRatingEventRepository
|
||||
* Unit tests for RatingEventRepository
|
||||
*/
|
||||
|
||||
import { RatingEvent } from '../entities/RatingEvent';
|
||||
@@ -110,7 +110,7 @@ class InMemoryRatingEventRepository implements RatingEventRepository {
|
||||
}
|
||||
}
|
||||
|
||||
describe('IRatingEventRepository', () => {
|
||||
describe('RatingEventRepository', () => {
|
||||
let repository: InMemoryRatingEventRepository;
|
||||
|
||||
beforeEach(() => {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Repository Interface: IRatingEventRepository
|
||||
* Repository Interface: RatingEventRepository
|
||||
*
|
||||
* Port for persisting and retrieving rating events (ledger).
|
||||
* Events are immutable and ordered by occurredAt for deterministic snapshot computation.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Repository Interface: ISponsorAccountRepository
|
||||
* Repository Interface: SponsorAccountRepository
|
||||
*
|
||||
* Defines persistence operations for SponsorAccount entities.
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Unit tests for IUserRatingRepository
|
||||
* Unit tests for UserRatingRepository
|
||||
*/
|
||||
|
||||
import { UserRating } from '../value-objects/UserRating';
|
||||
@@ -19,7 +19,7 @@ class InMemoryUserRatingRepository implements UserRatingRepository {
|
||||
}
|
||||
}
|
||||
|
||||
describe('IUserRatingRepository', () => {
|
||||
describe('UserRatingRepository', () => {
|
||||
let repository: InMemoryUserRatingRepository;
|
||||
|
||||
beforeEach(() => {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Repository Interface: IUserRatingRepository
|
||||
* Repository Interface: UserRatingRepository
|
||||
*
|
||||
* Port for persisting and retrieving UserRating snapshots.
|
||||
* Snapshots are derived from rating events for fast reads.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Domain Repository: IUserRepository
|
||||
* Domain Repository: UserRepository
|
||||
*
|
||||
* Repository interface for User entity operations.
|
||||
*/
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { DomainService } from '@core/shared/domain';
|
||||
import type { DomainService } from '@core/shared/domain/Service';
|
||||
import type { UserRatingRepository } from '../repositories/UserRatingRepository';
|
||||
import type { RatingEventRepository } from '../repositories/RatingEventRepository';
|
||||
import { RatingEventFactory } from './RatingEventFactory';
|
||||
@@ -21,8 +21,8 @@ export class RatingUpdateService implements DomainService {
|
||||
readonly serviceName = 'RatingUpdateService';
|
||||
|
||||
constructor(
|
||||
private readonly userRatingRepository: IUserRatingRepository,
|
||||
private readonly ratingEventRepository: IRatingEventRepository
|
||||
private readonly userRatingRepository: UserRatingRepository,
|
||||
private readonly ratingEventRepository: RatingEventRepository
|
||||
) {}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { ValueObject } from '@core/shared/domain';
|
||||
import type { ValueObject } from '@core/shared/domain/ValueObject';
|
||||
import { IdentityDomainValidationError } from '../errors/IdentityDomainError';
|
||||
|
||||
/**
|
||||
@@ -68,7 +68,7 @@ export class AdminTrustReasonCode implements ValueObject<AdminTrustReasonCodePro
|
||||
return { value: this.value };
|
||||
}
|
||||
|
||||
equals(other: IValueObject<AdminTrustReasonCodeProps>): boolean {
|
||||
equals(other: ValueObject<AdminTrustReasonCodeProps>): boolean {
|
||||
return this.value === other.props.value;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { ValueObject } from '@core/shared/domain';
|
||||
import type { ValueObject } from '@core/shared/domain/ValueObject';
|
||||
import { IdentityDomainValidationError } from '../errors/IdentityDomainError';
|
||||
|
||||
/**
|
||||
@@ -80,7 +80,7 @@ export class DrivingReasonCode implements ValueObject<DrivingReasonCodeProps> {
|
||||
return { value: this.value };
|
||||
}
|
||||
|
||||
equals(other: IValueObject<DrivingReasonCodeProps>): boolean {
|
||||
equals(other: ValueObject<DrivingReasonCodeProps>): boolean {
|
||||
return this.value === other.props.value;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { ValueObject } from '@core/shared/domain';
|
||||
import type { ValueObject } from '@core/shared/domain/ValueObject';
|
||||
import type { EmailValidationResult } from '../types/EmailAddress';
|
||||
import { validateEmail, isDisposableEmail } from '../types/EmailAddress';
|
||||
|
||||
@@ -35,7 +35,7 @@ export class EmailAddress implements ValueObject<EmailAddressProps> {
|
||||
return this.props.value;
|
||||
}
|
||||
|
||||
equals(other: IValueObject<EmailAddressProps>): boolean {
|
||||
equals(other: ValueObject<EmailAddressProps>): boolean {
|
||||
return this.props.value === other.props.value;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { ValueObject } from '@core/shared/domain';
|
||||
import type { ValueObject } from '@core/shared/domain/ValueObject';
|
||||
import { IdentityDomainValidationError } from '../errors/IdentityDomainError';
|
||||
import { GameKey } from './GameKey';
|
||||
|
||||
@@ -40,7 +40,7 @@ export class ExternalRating implements ValueObject<ExternalRatingProps> {
|
||||
};
|
||||
}
|
||||
|
||||
equals(other: IValueObject<ExternalRatingProps>): boolean {
|
||||
equals(other: ValueObject<ExternalRatingProps>): boolean {
|
||||
return (
|
||||
this.gameKey.equals(other.props.gameKey) &&
|
||||
this.type === other.props.type &&
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { ValueObject } from '@core/shared/domain';
|
||||
import type { ValueObject } from '@core/shared/domain/ValueObject';
|
||||
import { IdentityDomainValidationError } from '../errors/IdentityDomainError';
|
||||
|
||||
export interface ExternalRatingProvenanceProps {
|
||||
@@ -45,7 +45,7 @@ export class ExternalRatingProvenance implements ValueObject<ExternalRatingProve
|
||||
};
|
||||
}
|
||||
|
||||
equals(other: IValueObject<ExternalRatingProvenanceProps>): boolean {
|
||||
equals(other: ValueObject<ExternalRatingProvenanceProps>): boolean {
|
||||
return (
|
||||
this.source === other.props.source &&
|
||||
this.lastSyncedAt.getTime() === other.props.lastSyncedAt.getTime() &&
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { ValueObject } from '@core/shared/domain';
|
||||
import type { ValueObject } from '@core/shared/domain/ValueObject';
|
||||
import { IdentityDomainValidationError } from '../errors/IdentityDomainError';
|
||||
|
||||
export interface GameKeyProps {
|
||||
@@ -33,7 +33,7 @@ export class GameKey implements ValueObject<GameKeyProps> {
|
||||
return { value: this.value };
|
||||
}
|
||||
|
||||
equals(other: IValueObject<GameKeyProps>): boolean {
|
||||
equals(other: ValueObject<GameKeyProps>): boolean {
|
||||
return this.value === other.props.value;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import bcrypt from 'bcrypt';
|
||||
import type { ValueObject } from '@core/shared/domain';
|
||||
import type { ValueObject } from '@core/shared/domain/ValueObject';
|
||||
|
||||
export interface PasswordHashProps {
|
||||
value: string;
|
||||
@@ -35,7 +35,7 @@ export class PasswordHash implements ValueObject<PasswordHashProps> {
|
||||
return bcrypt.compare(plain, this.props.value);
|
||||
}
|
||||
|
||||
equals(other: IValueObject<PasswordHashProps>): boolean {
|
||||
equals(other: ValueObject<PasswordHashProps>): boolean {
|
||||
return this.props.value === other.props.value;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { ValueObject } from '@core/shared/domain';
|
||||
import type { ValueObject } from '@core/shared/domain/ValueObject';
|
||||
import { IdentityDomainValidationError } from '../errors/IdentityDomainError';
|
||||
|
||||
export interface RatingDeltaProps {
|
||||
@@ -30,7 +30,7 @@ export class RatingDelta implements ValueObject<RatingDeltaProps> {
|
||||
return { value: this.value };
|
||||
}
|
||||
|
||||
equals(other: IValueObject<RatingDeltaProps>): boolean {
|
||||
equals(other: ValueObject<RatingDeltaProps>): boolean {
|
||||
return this.value === other.props.value;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { ValueObject } from '@core/shared/domain';
|
||||
import type { ValueObject } from '@core/shared/domain/ValueObject';
|
||||
import { IdentityDomainValidationError } from '../errors/IdentityDomainError';
|
||||
|
||||
export interface RatingDimensionKeyProps {
|
||||
@@ -39,7 +39,7 @@ export class RatingDimensionKey implements ValueObject<RatingDimensionKeyProps>
|
||||
return { value: this.value };
|
||||
}
|
||||
|
||||
equals(other: IValueObject<RatingDimensionKeyProps>): boolean {
|
||||
equals(other: ValueObject<RatingDimensionKeyProps>): boolean {
|
||||
return this.value === other.props.value;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { ValueObject } from '@core/shared/domain';
|
||||
import type { ValueObject } from '@core/shared/domain/ValueObject';
|
||||
import { IdentityDomainValidationError } from '../errors/IdentityDomainError';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
|
||||
@@ -38,7 +38,7 @@ export class RatingEventId implements ValueObject<RatingEventIdProps> {
|
||||
return { value: this.value };
|
||||
}
|
||||
|
||||
equals(other: IValueObject<RatingEventIdProps>): boolean {
|
||||
equals(other: ValueObject<RatingEventIdProps>): boolean {
|
||||
return this.value === other.props.value;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { ValueObject } from '@core/shared/domain';
|
||||
import type { ValueObject } from '@core/shared/domain/ValueObject';
|
||||
import { IdentityDomainValidationError } from '../errors/IdentityDomainError';
|
||||
|
||||
export type RatingReferenceType = 'race' | 'penalty' | 'vote' | 'adminAction';
|
||||
@@ -38,7 +38,7 @@ export class RatingReference implements ValueObject<RatingReferenceProps> {
|
||||
return { type: this.type, id: this.id };
|
||||
}
|
||||
|
||||
equals(other: IValueObject<RatingReferenceProps>): boolean {
|
||||
equals(other: ValueObject<RatingReferenceProps>): boolean {
|
||||
return this.type === other.props.type && this.id === other.props.id;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { ValueObject } from '@core/shared/domain';
|
||||
import type { ValueObject } from '@core/shared/domain/ValueObject';
|
||||
import { IdentityDomainValidationError } from '../errors/IdentityDomainError';
|
||||
|
||||
export interface RatingValueProps {
|
||||
@@ -30,7 +30,7 @@ export class RatingValue implements ValueObject<RatingValueProps> {
|
||||
return { value: this.value };
|
||||
}
|
||||
|
||||
equals(other: IValueObject<RatingValueProps>): boolean {
|
||||
equals(other: ValueObject<RatingValueProps>): boolean {
|
||||
return this.value === other.props.value;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
import type { ValueObject } from '@core/shared/domain';
|
||||
import type { ValueObject } from '@core/shared/domain/ValueObject';
|
||||
|
||||
export interface UserIdProps {
|
||||
value: string;
|
||||
@@ -31,7 +31,7 @@ export class UserId implements ValueObject<UserIdProps> {
|
||||
return this.props.value;
|
||||
}
|
||||
|
||||
public equals(other: IValueObject<UserIdProps>): boolean {
|
||||
public equals(other: ValueObject<UserIdProps>): boolean {
|
||||
return this.props.value === other.props.value;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { ValueObject } from '@core/shared/domain';
|
||||
import type { ValueObject } from '@core/shared/domain/ValueObject';
|
||||
|
||||
/**
|
||||
* Value Object: UserRating
|
||||
@@ -111,7 +111,7 @@ export class UserRating implements ValueObject<UserRatingProps> {
|
||||
return new UserRating(props);
|
||||
}
|
||||
|
||||
equals(other: IValueObject<UserRatingProps>): boolean {
|
||||
equals(other: ValueObject<UserRatingProps>): boolean {
|
||||
return this.props.userId === other.props.userId;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user