website refactor

This commit is contained in:
2026-01-16 16:46:57 +01:00
parent 37b1aa626c
commit 2f53727702
445 changed files with 1160 additions and 1150 deletions

View File

@@ -17,7 +17,7 @@ const mockRepository = {
create: vi.fn(), create: vi.fn(),
update: vi.fn(), update: vi.fn(),
delete: vi.fn(), delete: vi.fn(),
} as unknown as IAdminUserRepository; } as unknown as AdminUserRepository;
describe('ListUsersUseCase', () => { describe('ListUsersUseCase', () => {
let useCase: ListUsersUseCase; let useCase: ListUsersUseCase;

View File

@@ -44,7 +44,7 @@ export type ListUsersApplicationError = ApplicationErrorCode<ListUsersErrorCode,
*/ */
export class ListUsersUseCase { export class ListUsersUseCase {
constructor( constructor(
private readonly adminUserRepository: IAdminUserRepository, private readonly adminUserRepository: AdminUserRepository,
) {} ) {}
async execute( async execute(

View File

@@ -1,4 +1,4 @@
import type { Entity } from '@core/shared/domain/Entity'; import { Entity } from '@core/shared/domain/Entity';
import { AdminDomainInvariantError, AdminDomainValidationError } from '../errors/AdminDomainError'; import { AdminDomainInvariantError, AdminDomainValidationError } from '../errors/AdminDomainError';
import { Email } from '../value-objects/Email'; import { Email } from '../value-objects/Email';
import { UserId } from '../value-objects/UserId'; import { UserId } from '../value-objects/UserId';
@@ -17,8 +17,7 @@ export interface AdminUserProps {
primaryDriverId: string | undefined; primaryDriverId: string | undefined;
} }
export class AdminUser implements Entity<UserId> { export class AdminUser extends Entity<UserId> {
readonly id: UserId;
private _email: Email; private _email: Email;
private _roles: UserRole[]; private _roles: UserRole[];
private _status: UserStatus; private _status: UserStatus;
@@ -29,7 +28,8 @@ export class AdminUser implements Entity<UserId> {
private _primaryDriverId: string | undefined; private _primaryDriverId: string | undefined;
private constructor(props: AdminUserProps) { private constructor(props: AdminUserProps) {
this.id = props.id; super(props.id);
this._email = props.email; this._email = props.email;
this._roles = props.roles; this._roles = props.roles;
this._status = props.status; this._status = props.status;

View File

@@ -1,6 +1,6 @@
import type { DomainError, CommonDomainErrorKind } from '@core/shared/errors'; import type { DomainErrorProps, CommonDomainErrorKind } from '@core/shared/errors/DomainError';
export abstract class AdminDomainError extends Error implements DomainError<CommonDomainErrorKind> { export abstract class AdminDomainError extends Error implements DomainErrorProps<CommonDomainErrorKind> {
readonly type = 'domain' as const; readonly type = 'domain' as const;
readonly context = 'admin-domain'; readonly context = 'admin-domain';
abstract readonly kind: CommonDomainErrorKind; abstract readonly kind: CommonDomainErrorKind;

View File

@@ -1,4 +1,4 @@
import { ValueObject } from '@core/shared/domain'; import { ValueObject } from '@core/shared/domain/ValueObject';
import { AdminDomainValidationError } from '../errors/AdminDomainError'; import { AdminDomainValidationError } from '../errors/AdminDomainError';
export interface EmailProps { export interface EmailProps {
@@ -40,7 +40,7 @@ export class Email implements ValueObject<EmailProps> {
return this.value; return this.value;
} }
equals(other: IValueObject<EmailProps>): boolean { equals(other: ValueObject<EmailProps>): boolean {
return this.value === other.props.value; return this.value === other.props.value;
} }
} }

View File

@@ -1,4 +1,4 @@
import { ValueObject } from '@core/shared/domain'; import { ValueObject } from '@core/shared/domain/ValueObject';
import { AdminDomainValidationError } from '../errors/AdminDomainError'; import { AdminDomainValidationError } from '../errors/AdminDomainError';
export interface UserIdProps { export interface UserIdProps {
@@ -28,7 +28,7 @@ export class UserId implements ValueObject<UserIdProps> {
return { value: this.value }; return { value: this.value };
} }
equals(other: IValueObject<UserIdProps>): boolean { equals(other: ValueObject<UserIdProps>): boolean {
return this.value === other.props.value; return this.value === other.props.value;
} }

View File

@@ -1,4 +1,4 @@
import { ValueObject } from '@core/shared/domain'; import { ValueObject } from '@core/shared/domain/ValueObject';
import { AdminDomainValidationError } from '../errors/AdminDomainError'; import { AdminDomainValidationError } from '../errors/AdminDomainError';
export type UserRoleValue = string; export type UserRoleValue = string;
@@ -41,7 +41,7 @@ export class UserRole implements ValueObject<UserRoleProps> {
return this.value; return this.value;
} }
equals(other: IValueObject<UserRoleProps>): boolean { equals(other: ValueObject<UserRoleProps>): boolean {
return this.value === other.props.value; return this.value === other.props.value;
} }

View File

@@ -1,4 +1,4 @@
import { ValueObject } from '@core/shared/domain'; import { ValueObject } from '@core/shared/domain/ValueObject';
import { AdminDomainValidationError } from '../errors/AdminDomainError'; import { AdminDomainValidationError } from '../errors/AdminDomainError';
export type UserStatusValue = string; export type UserStatusValue = string;
@@ -41,7 +41,7 @@ export class UserStatus implements ValueObject<UserStatusProps> {
return this.value; return this.value;
} }
equals(other: IValueObject<UserStatusProps>): boolean { equals(other: ValueObject<UserStatusProps>): boolean {
return this.value === other.props.value; return this.value === other.props.value;
} }

View File

@@ -1,4 +1,5 @@
import type { Logger, UseCase } from '@core/shared/application'; import type { Logger } from '@core/shared/domain/Logger';
import type { UseCase } from '@core/shared/application/UseCase';
import { Result } from '@core/shared/domain/Result'; import { Result } from '@core/shared/domain/Result';
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode'; import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
import type { PageViewRepository } from '../repositories/PageViewRepository'; import type { PageViewRepository } from '../repositories/PageViewRepository';
@@ -20,7 +21,7 @@ export type GetAnalyticsMetricsErrorCode = 'REPOSITORY_ERROR';
export class GetAnalyticsMetricsUseCase implements UseCase<GetAnalyticsMetricsInput, GetAnalyticsMetricsOutput, GetAnalyticsMetricsErrorCode> { export class GetAnalyticsMetricsUseCase implements UseCase<GetAnalyticsMetricsInput, GetAnalyticsMetricsOutput, GetAnalyticsMetricsErrorCode> {
constructor( constructor(
private readonly logger: Logger, private readonly logger: Logger,
private readonly pageViewRepository?: IPageViewRepository, private readonly pageViewRepository?: PageViewRepository,
) {} ) {}
async execute( async execute(

View File

@@ -1,4 +1,5 @@
import type { Logger, UseCase } from '@core/shared/application'; import type { Logger } from '@core/shared/domain/Logger';
import type { UseCase } from '@core/shared/application/UseCase';
import { Result } from '@core/shared/domain/Result'; import { Result } from '@core/shared/domain/Result';
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode'; import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';

View File

@@ -32,8 +32,8 @@ describe('GetEntityAnalyticsQuery', () => {
} as unknown as Logger; } as unknown as Logger;
useCase = new GetEntityAnalyticsQuery( useCase = new GetEntityAnalyticsQuery(
pageViewRepository as unknown as IPageViewRepository, pageViewRepository as unknown as PageViewRepository,
engagementRepository as unknown as IEngagementRepository, engagementRepository as unknown as EngagementRepository,
logger, logger,
); );
}); });

View File

@@ -5,7 +5,8 @@
* Returns metrics formatted for display to sponsors and admins. * Returns metrics formatted for display to sponsors and admins.
*/ */
import type { AsyncUseCase , Logger } from '@core/shared/application'; import type { AsyncUseCase } from '@core/shared/application/AsyncUseCase';
import type { Logger } from '@core/shared/domain/Logger';
import type { PageViewRepository } from '../repositories/PageViewRepository'; import type { PageViewRepository } from '../repositories/PageViewRepository';
import type { EngagementRepository } from '@core/analytics/domain/repositories/EngagementRepository'; import type { EngagementRepository } from '@core/analytics/domain/repositories/EngagementRepository';
import type { EntityType } from '../../domain/types/PageView'; import type { EntityType } from '../../domain/types/PageView';
@@ -48,8 +49,8 @@ export type GetEntityAnalyticsErrorCode = 'REPOSITORY_ERROR';
export class GetEntityAnalyticsQuery export class GetEntityAnalyticsQuery
implements AsyncUseCase<GetEntityAnalyticsInput, EntityAnalyticsOutput, GetEntityAnalyticsErrorCode> { implements AsyncUseCase<GetEntityAnalyticsInput, EntityAnalyticsOutput, GetEntityAnalyticsErrorCode> {
constructor( constructor(
private readonly pageViewRepository: IPageViewRepository, private readonly pageViewRepository: PageViewRepository,
private readonly engagementRepository: IEngagementRepository, private readonly engagementRepository: EngagementRepository,
private readonly logger: Logger private readonly logger: Logger
) {} ) {}

View File

@@ -24,7 +24,7 @@ describe('RecordEngagementUseCase', () => {
} as unknown as Logger; } as unknown as Logger;
useCase = new RecordEngagementUseCase( useCase = new RecordEngagementUseCase(
engagementRepository as unknown as IEngagementRepository, engagementRepository as unknown as EngagementRepository,
logger, logger,
); );
}); });

View File

@@ -1,4 +1,5 @@
import type { Logger, UseCase } from '@core/shared/application'; import type { Logger } from '@core/shared/domain/Logger';
import type { UseCase } from '@core/shared/application/UseCase';
import { Result } from '@core/shared/domain/Result'; import { Result } from '@core/shared/domain/Result';
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode'; import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
import { EngagementEvent } from '../../domain/entities/EngagementEvent'; import { EngagementEvent } from '../../domain/entities/EngagementEvent';
@@ -24,7 +25,7 @@ export type RecordEngagementErrorCode = 'REPOSITORY_ERROR';
export class RecordEngagementUseCase implements UseCase<RecordEngagementInput, RecordEngagementOutput, RecordEngagementErrorCode> { export class RecordEngagementUseCase implements UseCase<RecordEngagementInput, RecordEngagementOutput, RecordEngagementErrorCode> {
constructor( constructor(
private readonly engagementRepository: IEngagementRepository, private readonly engagementRepository: EngagementRepository,
private readonly logger: Logger, private readonly logger: Logger,
) {} ) {}

View File

@@ -1,4 +1,5 @@
import type { Logger, UseCase } from '@core/shared/application'; import type { Logger } from '@core/shared/domain/Logger';
import type { UseCase } from '@core/shared/application/UseCase';
import type { PageViewRepository } from '../repositories/PageViewRepository'; import type { PageViewRepository } from '../repositories/PageViewRepository';
import { PageView } from '../../domain/entities/PageView'; import { PageView } from '../../domain/entities/PageView';
import type { EntityType, VisitorType } from '../../domain/types/PageView'; import type { EntityType, VisitorType } from '../../domain/types/PageView';
@@ -24,7 +25,7 @@ export type RecordPageViewErrorCode = 'REPOSITORY_ERROR';
export class RecordPageViewUseCase implements UseCase<RecordPageViewInput, RecordPageViewOutput, RecordPageViewErrorCode> { export class RecordPageViewUseCase implements UseCase<RecordPageViewInput, RecordPageViewOutput, RecordPageViewErrorCode> {
constructor( constructor(
private readonly pageViewRepository: IPageViewRepository, private readonly pageViewRepository: PageViewRepository,
private readonly logger: Logger, private readonly logger: Logger,
) {} ) {}

View File

@@ -5,7 +5,7 @@
* Pre-calculated metrics for sponsor dashboard and entity analytics. * Pre-calculated metrics for sponsor dashboard and entity analytics.
*/ */
import type { Entity } from '@core/shared/domain/Entity'; import { Entity } from '@core/shared/domain/Entity';
import type { import type {
AnalyticsMetrics, AnalyticsMetrics,
AnalyticsSnapshotProps, AnalyticsSnapshotProps,
@@ -15,8 +15,7 @@ import type {
import { AnalyticsEntityId } from '../value-objects/AnalyticsEntityId'; import { AnalyticsEntityId } from '../value-objects/AnalyticsEntityId';
export type { SnapshotEntityType, SnapshotPeriod } from '../types/AnalyticsSnapshot'; export type { SnapshotEntityType, SnapshotPeriod } from '../types/AnalyticsSnapshot';
export class AnalyticsSnapshot implements Entity<string> { export class AnalyticsSnapshot extends Entity<string> {
readonly id: string;
readonly entityType: SnapshotEntityType; readonly entityType: SnapshotEntityType;
readonly period: SnapshotPeriod; readonly period: SnapshotPeriod;
readonly startDate: Date; readonly startDate: Date;
@@ -27,7 +26,7 @@ export class AnalyticsSnapshot implements Entity<string> {
private readonly entityIdVo: AnalyticsEntityId; private readonly entityIdVo: AnalyticsEntityId;
private constructor(props: AnalyticsSnapshotProps) { private constructor(props: AnalyticsSnapshotProps) {
this.id = props.id; super(props.id);
this.entityType = props.entityType; this.entityType = props.entityType;
this.entityIdVo = AnalyticsEntityId.create(props.entityId); this.entityIdVo = AnalyticsEntityId.create(props.entityId);
this.period = props.period; this.period = props.period;

View File

@@ -5,7 +5,7 @@
* Tracks clicks, downloads, sign-ups, and other engagement actions. * Tracks clicks, downloads, sign-ups, and other engagement actions.
*/ */
import type { Entity } from '@core/shared/domain/Entity'; import { Entity } from '@core/shared/domain/Entity';
import type { import type {
EngagementAction, EngagementAction,
EngagementEntityType, EngagementEntityType,
@@ -15,8 +15,7 @@ import { AnalyticsEntityId } from '../value-objects/AnalyticsEntityId';
export type { EngagementAction, EngagementEntityType } from '../types/EngagementEvent'; export type { EngagementAction, EngagementEntityType } from '../types/EngagementEvent';
export class EngagementEvent implements Entity<string> { export class EngagementEvent extends Entity<string> {
readonly id: string;
readonly action: EngagementAction; readonly action: EngagementAction;
readonly entityType: EngagementEntityType; readonly entityType: EngagementEntityType;
readonly actorId: string | undefined; readonly actorId: string | undefined;
@@ -28,7 +27,8 @@ export class EngagementEvent implements Entity<string> {
private readonly entityIdVo: AnalyticsEntityId; private readonly entityIdVo: AnalyticsEntityId;
private constructor(props: EngagementEventProps) { private constructor(props: EngagementEventProps) {
this.id = props.id; super(props.id);
this.action = props.action; this.action = props.action;
this.entityType = props.entityType; this.entityType = props.entityType;
this.entityIdVo = AnalyticsEntityId.create(props.entityId); this.entityIdVo = AnalyticsEntityId.create(props.entityId);

View File

@@ -5,7 +5,7 @@
* Captures visitor interactions with leagues, drivers, teams, races. * Captures visitor interactions with leagues, drivers, teams, races.
*/ */
import type { Entity } from '@core/shared/domain/Entity'; import { Entity } from '@core/shared/domain/Entity';
import type { EntityType, PageViewProps, VisitorType } from '../types/PageView'; import type { EntityType, PageViewProps, VisitorType } from '../types/PageView';
import { AnalyticsEntityId } from '../value-objects/AnalyticsEntityId'; import { AnalyticsEntityId } from '../value-objects/AnalyticsEntityId';
import { AnalyticsSessionId } from '../value-objects/AnalyticsSessionId'; import { AnalyticsSessionId } from '../value-objects/AnalyticsSessionId';
@@ -13,7 +13,7 @@ import { PageViewId } from '../value-objects/PageViewId';
export type { EntityType, VisitorType } from '../types/PageView'; export type { EntityType, VisitorType } from '../types/PageView';
export class PageView implements Entity<string> { export class PageView extends Entity<string> {
readonly entityType: EntityType; readonly entityType: EntityType;
readonly visitorId: string | undefined; readonly visitorId: string | undefined;
readonly visitorType: VisitorType; readonly visitorType: VisitorType;
@@ -28,6 +28,7 @@ export class PageView implements Entity<string> {
private readonly sessionIdVo: AnalyticsSessionId; private readonly sessionIdVo: AnalyticsSessionId;
private constructor(props: PageViewProps) { private constructor(props: PageViewProps) {
super(props.id);
this.idVo = PageViewId.create(props.id); this.idVo = PageViewId.create(props.id);
this.entityType = props.entityType; this.entityType = props.entityType;
this.entityIdVo = AnalyticsEntityId.create(props.entityId); this.entityIdVo = AnalyticsEntityId.create(props.entityId);
@@ -41,10 +42,6 @@ export class PageView implements Entity<string> {
this.durationMs = props.durationMs; this.durationMs = props.durationMs;
} }
get id(): string {
return this.idVo.value;
}
get entityId(): string { get entityId(): string {
return this.entityIdVo.value; return this.entityIdVo.value;
} }

View File

@@ -1,5 +1,5 @@
/** /**
* Repository Interface: IAnalyticsSnapshotRepository * Repository Interface: AnalyticsSnapshotRepository
* *
* Defines persistence operations for AnalyticsSnapshot entities. * Defines persistence operations for AnalyticsSnapshot entities.
*/ */

View File

@@ -1,4 +1,4 @@
import type { ValueObject } from '@core/shared/domain'; import type { ValueObject } from '@core/shared/domain/ValueObject';
export interface AnalyticsEntityIdProps { export interface AnalyticsEntityIdProps {
value: string; value: string;
@@ -31,7 +31,7 @@ export class AnalyticsEntityId implements ValueObject<AnalyticsEntityIdProps> {
return this.props.value; return this.props.value;
} }
equals(other: IValueObject<AnalyticsEntityIdProps>): boolean { equals(other: ValueObject<AnalyticsEntityIdProps>): boolean {
return this.props.value === other.props.value; return this.props.value === other.props.value;
} }
} }

View File

@@ -1,4 +1,4 @@
import type { ValueObject } from '@core/shared/domain'; import type { ValueObject } from '@core/shared/domain/ValueObject';
export interface AnalyticsSessionIdProps { export interface AnalyticsSessionIdProps {
value: string; value: string;
@@ -30,7 +30,7 @@ export class AnalyticsSessionId implements ValueObject<AnalyticsSessionIdProps>
return this.props.value; return this.props.value;
} }
equals(other: IValueObject<AnalyticsSessionIdProps>): boolean { equals(other: ValueObject<AnalyticsSessionIdProps>): boolean {
return this.props.value === other.props.value; return this.props.value === other.props.value;
} }
} }

View File

@@ -1,4 +1,4 @@
import type { ValueObject } from '@core/shared/domain'; import type { ValueObject } from '@core/shared/domain/ValueObject';
export interface PageViewIdProps { export interface PageViewIdProps {
value: string; value: string;
@@ -30,7 +30,7 @@ export class PageViewId implements ValueObject<PageViewIdProps> {
return this.props.value; return this.props.value;
} }
equals(other: IValueObject<PageViewIdProps>): boolean { equals(other: ValueObject<PageViewIdProps>): boolean {
return this.props.value === other.props.value; return this.props.value === other.props.value;
} }
} }

View File

@@ -10,7 +10,7 @@
* Follows clean architecture and TDD principles. * Follows clean architecture and TDD principles.
*/ */
import type { ValueObject } from '@core/shared/domain'; import type { ValueObject } from '@core/shared/domain/ValueObject';
// Variant types for system-default references // Variant types for system-default references
export type MediaVariant = 'avatar' | 'logo'; export type MediaVariant = 'avatar' | 'logo';
@@ -236,7 +236,7 @@ export class MediaReference implements ValueObject<MediaReferenceProps> {
/** /**
* Equality comparison * Equality comparison
*/ */
equals(other: IValueObject<MediaReferenceProps>): boolean { equals(other: ValueObject<MediaReferenceProps>): boolean {
if (!(other instanceof MediaReference)) { if (!(other instanceof MediaReference)) {
return false; return false;
} }

View File

@@ -1,5 +1,5 @@
/** /**
* Port: IRaceResultsProvider * Port: RaceResultsProvider
* *
* Provider interface for race results data needed for rating calculations. * Provider interface for race results data needed for rating calculations.
* This is an application layer port that bridges racing context to identity context. * This is an application layer port that bridges racing context to identity context.

View File

@@ -13,15 +13,15 @@ import { UserRatingRepository } from '../../domain/repositories/UserRatingReposi
import { ExternalGameRatingRepository } from '../../domain/repositories/ExternalGameRatingRepository'; import { ExternalGameRatingRepository } from '../../domain/repositories/ExternalGameRatingRepository';
describe('GetLeagueEligibilityPreviewQuery', () => { describe('GetLeagueEligibilityPreviewQuery', () => {
let mockUserRatingRepo: IUserRatingRepository; let mockUserRatingRepo: UserRatingRepository;
let mockExternalRatingRepo: IExternalGameRatingRepository; let mockExternalRatingRepo: ExternalGameRatingRepository;
let handler: GetLeagueEligibilityPreviewQueryHandler; let handler: GetLeagueEligibilityPreviewQueryHandler;
beforeEach(() => { beforeEach(() => {
mockUserRatingRepo = { mockUserRatingRepo = {
findByUserId: vi.fn(), findByUserId: vi.fn(),
save: vi.fn(), save: vi.fn(),
} as unknown as IUserRatingRepository; } as unknown as UserRatingRepository;
mockExternalRatingRepo = { mockExternalRatingRepo = {
findByUserId: vi.fn(), findByUserId: vi.fn(),
@@ -32,7 +32,7 @@ describe('GetLeagueEligibilityPreviewQuery', () => {
delete: vi.fn(), delete: vi.fn(),
exists: vi.fn(), exists: vi.fn(),
findProfilesPaginated: vi.fn(), findProfilesPaginated: vi.fn(),
} as unknown as IExternalGameRatingRepository; } as unknown as ExternalGameRatingRepository;
handler = new GetLeagueEligibilityPreviewQueryHandler( handler = new GetLeagueEligibilityPreviewQueryHandler(
mockUserRatingRepo, mockUserRatingRepo,

View File

@@ -21,8 +21,8 @@ export class GetLeagueEligibilityPreviewQueryHandler {
private readonly evaluator: EligibilityEvaluator; private readonly evaluator: EligibilityEvaluator;
constructor( constructor(
private readonly userRatingRepo: IUserRatingRepository, private readonly userRatingRepo: UserRatingRepository,
private readonly externalRatingRepo: IExternalGameRatingRepository private readonly externalRatingRepo: ExternalGameRatingRepository
) { ) {
this.evaluator = new EligibilityEvaluator(); this.evaluator = new EligibilityEvaluator();
} }

View File

@@ -16,7 +16,7 @@ export interface GetUserRatingLedgerQuery {
export class GetUserRatingLedgerQueryHandler { export class GetUserRatingLedgerQueryHandler {
constructor( constructor(
private readonly ratingEventRepo: IRatingEventRepository private readonly ratingEventRepo: RatingEventRepository
) {} ) {}
async execute(query: GetUserRatingLedgerQuery): Promise<PaginatedLedgerResult> { async execute(query: GetUserRatingLedgerQuery): Promise<PaginatedLedgerResult> {

View File

@@ -16,9 +16,9 @@ export interface GetUserRatingsSummaryQuery {
export class GetUserRatingsSummaryQueryHandler { export class GetUserRatingsSummaryQueryHandler {
constructor( constructor(
private readonly userRatingRepo: IUserRatingRepository, private readonly userRatingRepo: UserRatingRepository,
private readonly externalRatingRepo: IExternalGameRatingRepository, private readonly externalRatingRepo: ExternalGameRatingRepository,
private readonly ratingEventRepo: IRatingEventRepository private readonly ratingEventRepo: RatingEventRepository
) {} ) {}
async execute(query: GetUserRatingsSummaryQuery): Promise<RatingSummaryDto> { async execute(query: GetUserRatingsSummaryQuery): Promise<RatingSummaryDto> {

View File

@@ -71,7 +71,7 @@ class MockRatingEventRepository {
return Array.from(this.events.values()).filter(e => e.userId === userId); return Array.from(this.events.values()).filter(e => e.userId === userId);
} }
async findEventsPaginated(userId: string, options?: import('@core/identity/domain/repositories/IRatingEventRepository').PaginatedQueryOptions): Promise<import('@core/identity/domain/repositories/IRatingEventRepository').PaginatedResult<RatingEvent>> { async findEventsPaginated(userId: string, options?: import('@core/identity/domain/repositories/RatingEventRepository').PaginatedQueryOptions): Promise<import('@core/identity/domain/repositories/RatingEventRepository').PaginatedResult<RatingEvent>> {
const allEvents = await this.findByUserId(userId); const allEvents = await this.findByUserId(userId);
// Apply filters // Apply filters
@@ -105,7 +105,7 @@ class MockRatingEventRepository {
const hasMore = offset + limit < total; const hasMore = offset + limit < total;
const nextOffset = hasMore ? offset + limit : undefined; const nextOffset = hasMore ? offset + limit : undefined;
const result: import('@core/identity/domain/repositories/IRatingEventRepository').PaginatedResult<RatingEvent> = { const result: import('@core/identity/domain/repositories/RatingEventRepository').PaginatedResult<RatingEvent> = {
items, items,
total, total,
limit, limit,

View File

@@ -8,8 +8,8 @@ import { UserRating } from '../../domain/value-objects/UserRating';
import { RatingEventId } from '../../domain/value-objects/RatingEventId'; import { RatingEventId } from '../../domain/value-objects/RatingEventId';
describe('AppendRatingEventsUseCase', () => { describe('AppendRatingEventsUseCase', () => {
let mockEventRepo: Partial<IRatingEventRepository>; let mockEventRepo: Partial<RatingEventRepository>;
let mockRatingRepo: Partial<IUserRatingRepository>; let mockRatingRepo: Partial<UserRatingRepository>;
beforeEach(() => { beforeEach(() => {
mockEventRepo = { mockEventRepo = {
@@ -24,16 +24,16 @@ describe('AppendRatingEventsUseCase', () => {
it('should be constructed with repositories', () => { it('should be constructed with repositories', () => {
const useCase = new AppendRatingEventsUseCase( const useCase = new AppendRatingEventsUseCase(
mockEventRepo as IRatingEventRepository, mockEventRepo as RatingEventRepository,
mockRatingRepo as IUserRatingRepository, mockRatingRepo as UserRatingRepository,
); );
expect(useCase).toBeInstanceOf(AppendRatingEventsUseCase); expect(useCase).toBeInstanceOf(AppendRatingEventsUseCase);
}); });
it('should handle empty input (no events)', async () => { it('should handle empty input (no events)', async () => {
const useCase = new AppendRatingEventsUseCase( const useCase = new AppendRatingEventsUseCase(
mockEventRepo as IRatingEventRepository, mockEventRepo as RatingEventRepository,
mockRatingRepo as IUserRatingRepository, mockRatingRepo as UserRatingRepository,
); );
const input: AppendRatingEventsInput = { const input: AppendRatingEventsInput = {
@@ -50,8 +50,8 @@ describe('AppendRatingEventsUseCase', () => {
it('should create and save events from direct input', async () => { it('should create and save events from direct input', async () => {
const useCase = new AppendRatingEventsUseCase( const useCase = new AppendRatingEventsUseCase(
mockEventRepo as IRatingEventRepository, mockEventRepo as RatingEventRepository,
mockRatingRepo as IUserRatingRepository, mockRatingRepo as UserRatingRepository,
); );
const input: AppendRatingEventsInput = { const input: AppendRatingEventsInput = {
@@ -79,8 +79,8 @@ describe('AppendRatingEventsUseCase', () => {
it('should create events from race results using factory', async () => { it('should create events from race results using factory', async () => {
const useCase = new AppendRatingEventsUseCase( const useCase = new AppendRatingEventsUseCase(
mockEventRepo as IRatingEventRepository, mockEventRepo as RatingEventRepository,
mockRatingRepo as IUserRatingRepository, mockRatingRepo as UserRatingRepository,
); );
const input: AppendRatingEventsInput = { const input: AppendRatingEventsInput = {
@@ -108,8 +108,8 @@ describe('AppendRatingEventsUseCase', () => {
it('should handle multiple race results', async () => { it('should handle multiple race results', async () => {
const useCase = new AppendRatingEventsUseCase( const useCase = new AppendRatingEventsUseCase(
mockEventRepo as IRatingEventRepository, mockEventRepo as RatingEventRepository,
mockRatingRepo as IUserRatingRepository, mockRatingRepo as UserRatingRepository,
); );
const input: AppendRatingEventsInput = { const input: AppendRatingEventsInput = {
@@ -129,8 +129,8 @@ describe('AppendRatingEventsUseCase', () => {
it('should handle DNF status', async () => { it('should handle DNF status', async () => {
const useCase = new AppendRatingEventsUseCase( const useCase = new AppendRatingEventsUseCase(
mockEventRepo as IRatingEventRepository, mockEventRepo as RatingEventRepository,
mockRatingRepo as IUserRatingRepository, mockRatingRepo as UserRatingRepository,
); );
const input: AppendRatingEventsInput = { const input: AppendRatingEventsInput = {
@@ -159,8 +159,8 @@ describe('AppendRatingEventsUseCase', () => {
}; };
const useCase = new AppendRatingEventsUseCase( const useCase = new AppendRatingEventsUseCase(
mockEventRepo as IRatingEventRepository, mockEventRepo as RatingEventRepository,
mockRatingRepo as IUserRatingRepository, mockRatingRepo as UserRatingRepository,
); );
const input: AppendRatingEventsInput = { const input: AppendRatingEventsInput = {

View File

@@ -42,8 +42,8 @@ export interface AppendRatingEventsOutput {
*/ */
export class AppendRatingEventsUseCase { export class AppendRatingEventsUseCase {
constructor( constructor(
private readonly ratingEventRepository: IRatingEventRepository, private readonly ratingEventRepository: RatingEventRepository,
private readonly userRatingRepository: IUserRatingRepository, private readonly userRatingRepository: UserRatingRepository,
) {} ) {}
async execute(input: AppendRatingEventsInput): Promise<AppendRatingEventsOutput> { async execute(input: AppendRatingEventsInput): Promise<AppendRatingEventsOutput> {

View File

@@ -11,7 +11,7 @@ import { CastAdminVoteInput, CastAdminVoteOutput } from '../dtos/AdminVoteSessio
*/ */
export class CastAdminVoteUseCase { export class CastAdminVoteUseCase {
constructor( constructor(
private readonly adminVoteSessionRepository: IAdminVoteSessionRepository, private readonly adminVoteSessionRepository: AdminVoteSessionRepository,
) {} ) {}
async execute(input: CastAdminVoteInput): Promise<CastAdminVoteOutput> { async execute(input: CastAdminVoteInput): Promise<CastAdminVoteOutput> {

View File

@@ -23,9 +23,9 @@ import { CloseAdminVoteSessionInput, CloseAdminVoteSessionOutput } from '../dtos
*/ */
export class CloseAdminVoteSessionUseCase { export class CloseAdminVoteSessionUseCase {
constructor( constructor(
private readonly adminVoteSessionRepository: IAdminVoteSessionRepository, private readonly adminVoteSessionRepository: AdminVoteSessionRepository,
private readonly ratingEventRepository: IRatingEventRepository, private readonly ratingEventRepository: RatingEventRepository,
private readonly userRatingRepository: IUserRatingRepository, private readonly userRatingRepository: UserRatingRepository,
private readonly appendRatingEventsUseCase: any, // Will be typed properly in integration private readonly appendRatingEventsUseCase: any, // Will be typed properly in integration
) {} ) {}

View File

@@ -42,9 +42,9 @@ describe('ForgotPasswordUseCase', () => {
} as unknown as Logger; } as unknown as Logger;
useCase = new ForgotPasswordUseCase( useCase = new ForgotPasswordUseCase(
authRepo as unknown as IAuthRepository, authRepo as unknown as AuthRepository,
magicLinkRepo as unknown as IMagicLinkRepository, magicLinkRepo as unknown as MagicLinkRepository,
notificationPort as unknown as IMagicLinkNotificationPort, notificationPort as unknown as MagicLinkNotificationPort,
logger, logger,
); );
}); });

View File

@@ -4,7 +4,8 @@ import { MagicLinkRepository } from '../../domain/repositories/MagicLinkReposito
import { MagicLinkNotificationPort } from '../../domain/ports/MagicLinkNotificationPort'; import { MagicLinkNotificationPort } from '../../domain/ports/MagicLinkNotificationPort';
import { Result } from '@core/shared/domain/Result'; import { Result } from '@core/shared/domain/Result';
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode'; import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
import type { Logger, UseCase } from '@core/shared/application'; import type { Logger } from '@core/shared/domain/Logger';
import type { UseCase } from '@core/shared/application/UseCase';
import { randomBytes } from 'crypto'; import { randomBytes } from 'crypto';
export type ForgotPasswordInput = { export type ForgotPasswordInput = {
@@ -29,9 +30,9 @@ export type ForgotPasswordApplicationError = ApplicationErrorCode<ForgotPassword
*/ */
export class ForgotPasswordUseCase implements UseCase<ForgotPasswordInput, ForgotPasswordResult, ForgotPasswordErrorCode> { export class ForgotPasswordUseCase implements UseCase<ForgotPasswordInput, ForgotPasswordResult, ForgotPasswordErrorCode> {
constructor( constructor(
private readonly authRepo: IAuthRepository, private readonly authRepo: AuthRepository,
private readonly magicLinkRepo: IMagicLinkRepository, private readonly magicLinkRepo: MagicLinkRepository,
private readonly notificationPort: IMagicLinkNotificationPort, private readonly notificationPort: MagicLinkNotificationPort,
private readonly logger: Logger, private readonly logger: Logger,
) {} ) {}

View File

@@ -30,7 +30,7 @@ describe('GetCurrentSessionUseCase', () => {
error: vi.fn(), error: vi.fn(),
} as unknown as Logger; } as unknown as Logger;
useCase = new GetCurrentSessionUseCase( useCase = new GetCurrentSessionUseCase(
mockUserRepo as IUserRepository, mockUserRepo as UserRepository,
logger, logger,
); );
}); });

View File

@@ -25,7 +25,7 @@ export type GetCurrentSessionApplicationError = ApplicationErrorCode<
*/ */
export class GetCurrentSessionUseCase { export class GetCurrentSessionUseCase {
constructor( constructor(
private readonly userRepo: IUserRepository, private readonly userRepo: UserRepository,
private readonly logger: Logger, private readonly logger: Logger,
) {} ) {}

View File

@@ -22,7 +22,7 @@ describe('GetUserUseCase', () => {
} as unknown as Logger; } as unknown as Logger;
useCase = new GetUserUseCase( useCase = new GetUserUseCase(
userRepo as unknown as IUserRepository, userRepo as unknown as UserRepository,
logger, logger,
); );
}); });

View File

@@ -2,7 +2,8 @@ import { User } from '../../domain/entities/User';
import { UserRepository } from '../../domain/repositories/UserRepository'; import { UserRepository } from '../../domain/repositories/UserRepository';
import { Result } from '@core/shared/domain/Result'; import { Result } from '@core/shared/domain/Result';
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode'; import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
import type { Logger, UseCase } from '@core/shared/application'; import type { Logger } from '@core/shared/domain/Logger';
import type { UseCase } from '@core/shared/application/UseCase';
export type GetUserInput = { export type GetUserInput = {
userId: string; userId: string;
@@ -21,7 +22,7 @@ export type GetUserApplicationError = ApplicationErrorCode<
export class GetUserUseCase implements UseCase<GetUserInput, GetUserResult, GetUserErrorCode> { export class GetUserUseCase implements UseCase<GetUserInput, GetUserResult, GetUserErrorCode> {
constructor( constructor(
private readonly userRepo: IUserRepository, private readonly userRepo: UserRepository,
private readonly logger: Logger, private readonly logger: Logger,
) {} ) {}

View File

@@ -32,8 +32,8 @@ describe('LoginUseCase', () => {
} as unknown as Logger; } as unknown as Logger;
useCase = new LoginUseCase( useCase = new LoginUseCase(
authRepo as unknown as IAuthRepository, authRepo as unknown as AuthRepository,
passwordService as unknown as IPasswordHashingService, passwordService as unknown as PasswordHashingService,
logger, logger,
); );
}); });

View File

@@ -4,7 +4,8 @@ import { AuthRepository } from '../../domain/repositories/AuthRepository';
import { PasswordHashingService } from '../../domain/services/PasswordHashingService'; import { PasswordHashingService } from '../../domain/services/PasswordHashingService';
import { Result } from '@core/shared/domain/Result'; import { Result } from '@core/shared/domain/Result';
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode'; import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
import type { Logger, UseCase } from '@core/shared/application'; import type { Logger } from '@core/shared/domain/Logger';
import type { UseCase } from '@core/shared/application/UseCase';
export type LoginInput = { export type LoginInput = {
email: string; email: string;
@@ -26,8 +27,8 @@ export type LoginApplicationError = ApplicationErrorCode<LoginErrorCode, { messa
*/ */
export class LoginUseCase implements UseCase<LoginInput, LoginResult, LoginErrorCode> { export class LoginUseCase implements UseCase<LoginInput, LoginResult, LoginErrorCode> {
constructor( constructor(
private readonly authRepo: IAuthRepository, private readonly authRepo: AuthRepository,
private readonly passwordService: IPasswordHashingService, private readonly passwordService: PasswordHashingService,
private readonly logger: Logger, private readonly logger: Logger,
) {} ) {}

View File

@@ -40,7 +40,7 @@ describe('LoginWithEmailUseCase', () => {
} as unknown as Logger; } as unknown as Logger;
useCase = new LoginWithEmailUseCase( useCase = new LoginWithEmailUseCase(
userRepository as unknown as IUserRepository, userRepository as unknown as UserRepository,
sessionPort as unknown as IdentitySessionPort, sessionPort as unknown as IdentitySessionPort,
logger, logger,
); );

View File

@@ -37,7 +37,7 @@ export type LoginWithEmailApplicationError = ApplicationErrorCode<
export class LoginWithEmailUseCase { export class LoginWithEmailUseCase {
constructor( constructor(
private readonly userRepository: IUserRepository, private readonly userRepository: UserRepository,
private readonly sessionPort: IdentitySessionPort, private readonly sessionPort: IdentitySessionPort,
private readonly logger: Logger, private readonly logger: Logger,
) {} ) {}

View File

@@ -1,7 +1,8 @@
import type { IdentitySessionPort } from '../ports/IdentitySessionPort'; import type { IdentitySessionPort } from '../ports/IdentitySessionPort';
import { Result } from '@core/shared/domain/Result'; import { Result } from '@core/shared/domain/Result';
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode'; import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
import type { Logger, UseCase } from '@core/shared/application'; import type { Logger } from '@core/shared/domain/Logger';
import type { UseCase } from '@core/shared/application/UseCase';
export type LogoutInput = {}; export type LogoutInput = {};

View File

@@ -12,7 +12,7 @@ import { OpenAdminVoteSessionInput, OpenAdminVoteSessionOutput } from '../dtos/A
*/ */
export class OpenAdminVoteSessionUseCase { export class OpenAdminVoteSessionUseCase {
constructor( constructor(
private readonly adminVoteSessionRepository: IAdminVoteSessionRepository, private readonly adminVoteSessionRepository: AdminVoteSessionRepository,
) {} ) {}
async execute(input: OpenAdminVoteSessionInput): Promise<OpenAdminVoteSessionOutput> { async execute(input: OpenAdminVoteSessionInput): Promise<OpenAdminVoteSessionOutput> {

View File

@@ -10,8 +10,8 @@ import { RatingDimensionKey } from '../../domain/value-objects/RatingDimensionKe
import { RatingDelta } from '../../domain/value-objects/RatingDelta'; import { RatingDelta } from '../../domain/value-objects/RatingDelta';
describe('RecomputeUserRatingSnapshotUseCase', () => { describe('RecomputeUserRatingSnapshotUseCase', () => {
let mockEventRepo: Partial<IRatingEventRepository>; let mockEventRepo: Partial<RatingEventRepository>;
let mockRatingRepo: Partial<IUserRatingRepository>; let mockRatingRepo: Partial<UserRatingRepository>;
beforeEach(() => { beforeEach(() => {
mockEventRepo = { mockEventRepo = {
@@ -25,16 +25,16 @@ describe('RecomputeUserRatingSnapshotUseCase', () => {
it('should be constructed with repositories', () => { it('should be constructed with repositories', () => {
const useCase = new RecomputeUserRatingSnapshotUseCase( const useCase = new RecomputeUserRatingSnapshotUseCase(
mockEventRepo as IRatingEventRepository, mockEventRepo as RatingEventRepository,
mockRatingRepo as IUserRatingRepository, mockRatingRepo as UserRatingRepository,
); );
expect(useCase).toBeInstanceOf(RecomputeUserRatingSnapshotUseCase); expect(useCase).toBeInstanceOf(RecomputeUserRatingSnapshotUseCase);
}); });
it('should compute snapshot from empty event list', async () => { it('should compute snapshot from empty event list', async () => {
const useCase = new RecomputeUserRatingSnapshotUseCase( const useCase = new RecomputeUserRatingSnapshotUseCase(
mockEventRepo as IRatingEventRepository, mockEventRepo as RatingEventRepository,
mockRatingRepo as IUserRatingRepository, mockRatingRepo as UserRatingRepository,
); );
const result = await useCase.execute({ userId: 'user-1' }); const result = await useCase.execute({ userId: 'user-1' });
@@ -64,8 +64,8 @@ describe('RecomputeUserRatingSnapshotUseCase', () => {
mockEventRepo.getAllByUserId = vi.fn().mockResolvedValue(events); mockEventRepo.getAllByUserId = vi.fn().mockResolvedValue(events);
const useCase = new RecomputeUserRatingSnapshotUseCase( const useCase = new RecomputeUserRatingSnapshotUseCase(
mockEventRepo as IRatingEventRepository, mockEventRepo as RatingEventRepository,
mockRatingRepo as IUserRatingRepository, mockRatingRepo as UserRatingRepository,
); );
const result = await useCase.execute({ userId: 'user-1' }); const result = await useCase.execute({ userId: 'user-1' });
@@ -78,8 +78,8 @@ describe('RecomputeUserRatingSnapshotUseCase', () => {
it('should return proper DTO format', async () => { it('should return proper DTO format', async () => {
const useCase = new RecomputeUserRatingSnapshotUseCase( const useCase = new RecomputeUserRatingSnapshotUseCase(
mockEventRepo as IRatingEventRepository, mockEventRepo as RatingEventRepository,
mockRatingRepo as IUserRatingRepository, mockRatingRepo as UserRatingRepository,
); );
const result = await useCase.execute({ userId: 'user-1' }); const result = await useCase.execute({ userId: 'user-1' });
@@ -117,8 +117,8 @@ describe('RecomputeUserRatingSnapshotUseCase', () => {
mockRatingRepo.save = vi.fn().mockResolvedValue(updated); mockRatingRepo.save = vi.fn().mockResolvedValue(updated);
const useCase = new RecomputeUserRatingSnapshotUseCase( const useCase = new RecomputeUserRatingSnapshotUseCase(
mockEventRepo as IRatingEventRepository, mockEventRepo as RatingEventRepository,
mockRatingRepo as IUserRatingRepository, mockRatingRepo as UserRatingRepository,
); );
const result = await useCase.execute({ userId: 'user-1' }); const result = await useCase.execute({ userId: 'user-1' });

View File

@@ -28,8 +28,8 @@ export interface RecomputeUserRatingSnapshotOutput {
*/ */
export class RecomputeUserRatingSnapshotUseCase { export class RecomputeUserRatingSnapshotUseCase {
constructor( constructor(
private readonly ratingEventRepository: IRatingEventRepository, private readonly ratingEventRepository: RatingEventRepository,
private readonly userRatingRepository: IUserRatingRepository, private readonly userRatingRepository: UserRatingRepository,
) {} ) {}
async execute(input: RecomputeUserRatingSnapshotInput): Promise<RecomputeUserRatingSnapshotOutput> { async execute(input: RecomputeUserRatingSnapshotInput): Promise<RecomputeUserRatingSnapshotOutput> {

View File

@@ -24,9 +24,9 @@ import { RecordRaceRatingEventsInput, RecordRaceRatingEventsOutput } from '../dt
*/ */
export class RecordRaceRatingEventsUseCase { export class RecordRaceRatingEventsUseCase {
constructor( constructor(
private readonly raceResultsProvider: IRaceResultsProvider, private readonly raceResultsProvider: RaceResultsProvider,
private readonly ratingEventRepository: IRatingEventRepository, private readonly ratingEventRepository: RatingEventRepository,
private readonly userRatingRepository: IUserRatingRepository, private readonly userRatingRepository: UserRatingRepository,
private readonly appendRatingEventsUseCase: AppendRatingEventsUseCase, private readonly appendRatingEventsUseCase: AppendRatingEventsUseCase,
) {} ) {}

View File

@@ -43,9 +43,9 @@ describe('ResetPasswordUseCase', () => {
} as unknown as Logger; } as unknown as Logger;
useCase = new ResetPasswordUseCase( useCase = new ResetPasswordUseCase(
authRepo as unknown as IAuthRepository, authRepo as unknown as AuthRepository,
magicLinkRepo as unknown as IMagicLinkRepository, magicLinkRepo as unknown as MagicLinkRepository,
passwordService as unknown as IPasswordHashingService, passwordService as unknown as PasswordHashingService,
logger, logger,
); );
}); });

View File

@@ -5,7 +5,8 @@ import { EmailAddress } from '../../domain/value-objects/EmailAddress';
import { PasswordHash } from '../../domain/value-objects/PasswordHash'; import { PasswordHash } from '../../domain/value-objects/PasswordHash';
import { Result } from '@core/shared/domain/Result'; import { Result } from '@core/shared/domain/Result';
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode'; import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
import type { Logger, UseCase } from '@core/shared/application'; import type { Logger } from '@core/shared/domain/Logger';
import type { UseCase } from '@core/shared/application/UseCase';
export type ResetPasswordInput = { export type ResetPasswordInput = {
token: string; token: string;
@@ -28,9 +29,9 @@ export type ResetPasswordApplicationError = ApplicationErrorCode<ResetPasswordEr
*/ */
export class ResetPasswordUseCase implements UseCase<ResetPasswordInput, ResetPasswordResult, ResetPasswordErrorCode> { export class ResetPasswordUseCase implements UseCase<ResetPasswordInput, ResetPasswordResult, ResetPasswordErrorCode> {
constructor( constructor(
private readonly authRepo: IAuthRepository, private readonly authRepo: AuthRepository,
private readonly magicLinkRepo: IMagicLinkRepository, private readonly magicLinkRepo: MagicLinkRepository,
private readonly passwordService: IPasswordHashingService, private readonly passwordService: PasswordHashingService,
private readonly logger: Logger, private readonly logger: Logger,
) {} ) {}

View File

@@ -42,9 +42,9 @@ describe('SignupSponsorUseCase', () => {
} as unknown as Logger; } as unknown as Logger;
useCase = new SignupSponsorUseCase( useCase = new SignupSponsorUseCase(
authRepo as unknown as IAuthRepository, authRepo as unknown as AuthRepository,
companyRepo as unknown as ICompanyRepository, companyRepo as unknown as CompanyRepository,
passwordService as unknown as IPasswordHashingService, passwordService as unknown as PasswordHashingService,
logger, logger,
); );
}); });

View File

@@ -7,7 +7,8 @@ import { CompanyRepository } from '../../domain/repositories/CompanyRepository';
import { PasswordHashingService } from '../../domain/services/PasswordHashingService'; import { PasswordHashingService } from '../../domain/services/PasswordHashingService';
import { Result } from '@core/shared/domain/Result'; import { Result } from '@core/shared/domain/Result';
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode'; import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
import type { Logger, UseCase } from '@core/shared/application'; import type { Logger } from '@core/shared/domain/Logger';
import type { UseCase } from '@core/shared/application/UseCase';
export type SignupSponsorInput = { export type SignupSponsorInput = {
email: string; email: string;
@@ -33,9 +34,9 @@ export type SignupSponsorApplicationError = ApplicationErrorCode<SignupSponsorEr
*/ */
export class SignupSponsorUseCase implements UseCase<SignupSponsorInput, SignupSponsorResult, SignupSponsorErrorCode> { export class SignupSponsorUseCase implements UseCase<SignupSponsorInput, SignupSponsorResult, SignupSponsorErrorCode> {
constructor( constructor(
private readonly authRepo: IAuthRepository, private readonly authRepo: AuthRepository,
private readonly companyRepo: ICompanyRepository, private readonly companyRepo: CompanyRepository,
private readonly passwordService: IPasswordHashingService, private readonly passwordService: PasswordHashingService,
private readonly logger: Logger, private readonly logger: Logger,
) {} ) {}

View File

@@ -34,8 +34,8 @@ describe('SignupUseCase', () => {
} as unknown as Logger; } as unknown as Logger;
useCase = new SignupUseCase( useCase = new SignupUseCase(
authRepo as unknown as IAuthRepository, authRepo as unknown as AuthRepository,
passwordService as unknown as IPasswordHashingService, passwordService as unknown as PasswordHashingService,
logger, logger,
); );
}); });

View File

@@ -6,7 +6,8 @@ import { PasswordHashingService } from '../../domain/services/PasswordHashingSer
import { PasswordHash } from '../../domain/value-objects/PasswordHash'; import { PasswordHash } from '../../domain/value-objects/PasswordHash';
import { Result } from '@core/shared/domain/Result'; import { Result } from '@core/shared/domain/Result';
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode'; import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
import type { Logger, UseCase } from '@core/shared/application'; import type { Logger } from '@core/shared/domain/Logger';
import type { UseCase } from '@core/shared/application/UseCase';
export type SignupInput = { export type SignupInput = {
email: string; email: string;
@@ -29,8 +30,8 @@ export type SignupApplicationError = ApplicationErrorCode<SignupErrorCode, { mes
*/ */
export class SignupUseCase implements UseCase<SignupInput, SignupResult, SignupErrorCode> { export class SignupUseCase implements UseCase<SignupInput, SignupResult, SignupErrorCode> {
constructor( constructor(
private readonly authRepo: IAuthRepository, private readonly authRepo: AuthRepository,
private readonly passwordService: IPasswordHashingService, private readonly passwordService: PasswordHashingService,
private readonly logger: Logger, private readonly logger: Logger,
) {} ) {}

View File

@@ -32,7 +32,7 @@ describe('SignupWithEmailUseCase', () => {
} as unknown as Logger; } as unknown as Logger;
useCase = new SignupWithEmailUseCase( useCase = new SignupWithEmailUseCase(
userRepository as unknown as IUserRepository, userRepository as unknown as UserRepository,
sessionPort as unknown as IdentitySessionPort, sessionPort as unknown as IdentitySessionPort,
logger, logger,
); );

View File

@@ -33,7 +33,7 @@ export type SignupWithEmailApplicationError = ApplicationErrorCode<
export class SignupWithEmailUseCase { export class SignupWithEmailUseCase {
constructor( constructor(
private readonly userRepository: IUserRepository, private readonly userRepository: UserRepository,
private readonly sessionPort: IdentitySessionPort, private readonly sessionPort: IdentitySessionPort,
private readonly logger: Logger, private readonly logger: Logger,
) {} ) {}

View File

@@ -10,7 +10,7 @@ import { vi, describe, it, expect, beforeEach } from 'vitest';
describe('UpsertExternalGameRatingUseCase', () => { describe('UpsertExternalGameRatingUseCase', () => {
let useCase: UpsertExternalGameRatingUseCase; let useCase: UpsertExternalGameRatingUseCase;
let mockRepository: IExternalGameRatingRepository; let mockRepository: ExternalGameRatingRepository;
beforeEach(() => { beforeEach(() => {
mockRepository = { mockRepository = {

View File

@@ -23,7 +23,7 @@ import { UpsertExternalGameRatingInput, UpsertExternalGameRatingOutput } from '.
*/ */
export class UpsertExternalGameRatingUseCase { export class UpsertExternalGameRatingUseCase {
constructor( constructor(
private readonly externalGameRatingRepository: IExternalGameRatingRepository private readonly externalGameRatingRepository: ExternalGameRatingRepository
) {} ) {}
async execute(input: UpsertExternalGameRatingInput): Promise<UpsertExternalGameRatingOutput> { async execute(input: UpsertExternalGameRatingInput): Promise<UpsertExternalGameRatingOutput> {

View File

@@ -1,6 +1,6 @@
import type { Logger } from '@core/shared/domain/Logger'; import type { Logger } from '@core/shared/domain/Logger';
import { describe, expect, it, vi, type Mock } from 'vitest'; import { describe, expect, it, vi, type Mock } from 'vitest';
import { CreateAchievementUseCase, type IAchievementRepository } from './CreateAchievementUseCase'; import { CreateAchievementUseCase, type AchievementRepository } from './CreateAchievementUseCase';
describe('CreateAchievementUseCase', () => { describe('CreateAchievementUseCase', () => {
let achievementRepository: { let achievementRepository: {
@@ -24,7 +24,7 @@ describe('CreateAchievementUseCase', () => {
} as unknown as Logger; } as unknown as Logger;
useCase = new CreateAchievementUseCase( useCase = new CreateAchievementUseCase(
achievementRepository as unknown as IAchievementRepository, achievementRepository as unknown as AchievementRepository,
logger, logger,
); );
}); });

View File

@@ -23,7 +23,7 @@ export type CreateAchievementApplicationError = ApplicationErrorCode<
export class CreateAchievementUseCase { export class CreateAchievementUseCase {
constructor( constructor(
private readonly achievementRepository: IAchievementRepository, private readonly achievementRepository: AchievementRepository,
private readonly logger: Logger, private readonly logger: Logger,
) {} ) {}

View File

@@ -5,7 +5,7 @@
* Achievements are categorized by role (driver, steward, admin) and type. * 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'; export type AchievementCategory = 'driver' | 'steward' | 'admin' | 'community';
@@ -32,8 +32,7 @@ export interface AchievementRequirement {
operator: '>=' | '>' | '=' | '<' | '<='; operator: '>=' | '>' | '=' | '<' | '<=';
} }
export class Achievement implements Entity<string> { export class Achievement extends Entity<string> {
readonly id: string;
readonly name: string; readonly name: string;
readonly description: string; readonly description: string;
readonly category: AchievementCategory; readonly category: AchievementCategory;
@@ -45,7 +44,8 @@ export class Achievement implements Entity<string> {
readonly createdAt: Date; readonly createdAt: Date;
private constructor(props: AchievementProps) { private constructor(props: AchievementProps) {
this.id = props.id; super(props.id);
this.name = props.name; this.name = props.name;
this.description = props.description; this.description = props.description;
this.category = props.category; this.category = props.category;

View File

@@ -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 { IdentityDomainInvariantError, IdentityDomainValidationError } from '../errors/IdentityDomainError';
export interface AdminVote { export interface AdminVote {
@@ -42,8 +42,7 @@ export interface AdminVoteSessionProps {
* *
* Based on ratings-architecture-concept.md sections 5.2.1 and 7.1.1 * Based on ratings-architecture-concept.md sections 5.2.1 and 7.1.1
*/ */
export class AdminVoteSession implements Entity<string> { export class AdminVoteSession extends Entity<string> {
readonly id: string;
readonly leagueId: string; readonly leagueId: string;
readonly adminId: string; readonly adminId: string;
readonly startDate: Date; readonly startDate: Date;
@@ -56,7 +55,7 @@ export class AdminVoteSession implements Entity<string> {
private _updatedAt: Date; private _updatedAt: Date;
private constructor(props: AdminVoteSessionProps) { private constructor(props: AdminVoteSessionProps) {
this.id = props.voteSessionId; super(props.voteSessionId);
this.leagueId = props.leagueId; this.leagueId = props.leagueId;
this.adminId = props.adminId; this.adminId = props.adminId;
this.startDate = props.startDate; this.startDate = props.startDate;
@@ -269,7 +268,7 @@ export class AdminVoteSession implements Entity<string> {
return now >= this.startDate && now <= this.endDate && !this._closed; return now >= this.startDate && now <= this.endDate && !this._closed;
} }
equals(other: IEntity<string>): boolean { equals(other: Entity<string>): boolean {
return this.id === other.id; return this.id === other.id;
} }

View File

@@ -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 { IdentityDomainInvariantError, IdentityDomainValidationError } from '../errors/IdentityDomainError';
import { RatingDelta } from '../value-objects/RatingDelta'; import { RatingDelta } from '../value-objects/RatingDelta';
import { RatingDimensionKey } from '../value-objects/RatingDimensionKey'; import { RatingDimensionKey } from '../value-objects/RatingDimensionKey';
@@ -34,8 +34,7 @@ export interface RatingEventProps {
version: number; version: number;
} }
export class RatingEvent implements Entity<RatingEventId> { export class RatingEvent extends Entity<RatingEventId> {
readonly id: RatingEventId;
readonly userId: string; readonly userId: string;
readonly dimension: RatingDimensionKey; readonly dimension: RatingDimensionKey;
readonly delta: RatingDelta; readonly delta: RatingDelta;
@@ -48,7 +47,8 @@ export class RatingEvent implements Entity<RatingEventId> {
readonly version: number; readonly version: number;
private constructor(props: RatingEventProps) { private constructor(props: RatingEventProps) {
this.id = props.id; super(props.id);
this.userId = props.userId; this.userId = props.userId;
this.dimension = props.dimension; this.dimension = props.dimension;
this.delta = props.delta; this.delta = props.delta;
@@ -118,7 +118,7 @@ export class RatingEvent implements Entity<RatingEventId> {
return new RatingEvent(props); return new RatingEvent(props);
} }
equals(other: IEntity<RatingEventId>): boolean { equals(other: Entity<RatingEventId>): boolean {
return this.id.equals(other.id); return this.id.equals(other.id);
} }

View File

@@ -4,7 +4,7 @@
* Represents an achievement earned by a specific user. * 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 { export interface UserAchievementProps {
id: string; id: string;
@@ -15,8 +15,7 @@ export interface UserAchievementProps {
progress?: number; // For partial progress tracking (0-100) progress?: number; // For partial progress tracking (0-100)
} }
export class UserAchievement implements Entity<string> { export class UserAchievement extends Entity<string> {
readonly id: string;
readonly userId: string; readonly userId: string;
readonly achievementId: string; readonly achievementId: string;
readonly earnedAt: Date; readonly earnedAt: Date;
@@ -24,7 +23,8 @@ export class UserAchievement implements Entity<string> {
readonly progress: number; readonly progress: number;
private constructor(props: UserAchievementProps) { private constructor(props: UserAchievementProps) {
this.id = props.id; super(props.id);
this.userId = props.userId; this.userId = props.userId;
this.achievementId = props.achievementId; this.achievementId = props.achievementId;
this.earnedAt = props.earnedAt; this.earnedAt = props.earnedAt;

View File

@@ -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> { export abstract class IdentityDomainError extends Error implements DomainError<CommonDomainErrorKind> {
readonly type = 'domain' as const; readonly type = 'domain' as const;

View File

@@ -1,5 +1,5 @@
/** /**
* Repository Interface: IAchievementRepository * Repository Interface: AchievementRepository
* *
* Defines operations for Achievement and UserAchievement entities * Defines operations for Achievement and UserAchievement entities
*/ */

View File

@@ -1,7 +1,7 @@
import type { AdminVoteSession } from '../entities/AdminVoteSession'; import type { AdminVoteSession } from '../entities/AdminVoteSession';
/** /**
* Repository Interface: IAdminVoteSessionRepository * Repository Interface: AdminVoteSessionRepository
* *
* Port for persisting and retrieving admin vote sessions. * Port for persisting and retrieving admin vote sessions.
* Sessions are scoped to leagues and control voting windows. * Sessions are scoped to leagues and control voting windows.

View File

@@ -2,7 +2,7 @@ import { EmailAddress } from '../value-objects/EmailAddress';
import { User } from '../entities/User'; import { User } from '../entities/User';
/** /**
* Domain Repository: IAuthRepository * Domain Repository: AuthRepository
* *
* Repository interface for authentication operations. * Repository interface for authentication operations.
*/ */

View File

@@ -1,7 +1,7 @@
import { Company } from '../entities/Company'; import { Company } from '../entities/Company';
/** /**
* Domain Repository: ICompanyRepository * Domain Repository: CompanyRepository
* *
* Repository interface for Company entity operations. * Repository interface for Company entity operations.
*/ */

View File

@@ -6,10 +6,10 @@ import { ExternalRating } from '../value-objects/ExternalRating';
import { ExternalRatingProvenance } from '../value-objects/ExternalRatingProvenance'; 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 * This tests the contract that all implementations must satisfy
*/ */
describe('IExternalGameRatingRepository', () => { describe('ExternalGameRatingRepository', () => {
// Mock implementation for testing // Mock implementation for testing
class MockExternalGameRatingRepository implements ExternalGameRatingRepository { class MockExternalGameRatingRepository implements ExternalGameRatingRepository {
private profiles: Map<string, ExternalGameRatingProfile> = new Map(); private profiles: Map<string, ExternalGameRatingProfile> = new Map();
@@ -105,7 +105,7 @@ describe('IExternalGameRatingRepository', () => {
} }
} }
let repository: IExternalGameRatingRepository; let repository: ExternalGameRatingRepository;
beforeEach(() => { beforeEach(() => {
repository = new MockExternalGameRatingRepository(); repository = new MockExternalGameRatingRepository();

View File

@@ -1,7 +1,7 @@
import { ExternalGameRatingProfile } from '../entities/ExternalGameRatingProfile'; import { ExternalGameRatingProfile } from '../entities/ExternalGameRatingProfile';
/** /**
* Repository Interface: IExternalGameRatingRepository * Repository Interface: ExternalGameRatingRepository
* *
* Port for persisting and retrieving external game rating profiles. * Port for persisting and retrieving external game rating profiles.
* Store/display only, no compute. * Store/display only, no compute.

View File

@@ -1,5 +1,5 @@
/** /**
* Unit tests for IRatingEventRepository * Unit tests for RatingEventRepository
*/ */
import { RatingEvent } from '../entities/RatingEvent'; import { RatingEvent } from '../entities/RatingEvent';
@@ -110,7 +110,7 @@ class InMemoryRatingEventRepository implements RatingEventRepository {
} }
} }
describe('IRatingEventRepository', () => { describe('RatingEventRepository', () => {
let repository: InMemoryRatingEventRepository; let repository: InMemoryRatingEventRepository;
beforeEach(() => { beforeEach(() => {

View File

@@ -1,5 +1,5 @@
/** /**
* Repository Interface: IRatingEventRepository * Repository Interface: RatingEventRepository
* *
* Port for persisting and retrieving rating events (ledger). * Port for persisting and retrieving rating events (ledger).
* Events are immutable and ordered by occurredAt for deterministic snapshot computation. * Events are immutable and ordered by occurredAt for deterministic snapshot computation.

View File

@@ -1,5 +1,5 @@
/** /**
* Repository Interface: ISponsorAccountRepository * Repository Interface: SponsorAccountRepository
* *
* Defines persistence operations for SponsorAccount entities. * Defines persistence operations for SponsorAccount entities.
*/ */

View File

@@ -1,5 +1,5 @@
/** /**
* Unit tests for IUserRatingRepository * Unit tests for UserRatingRepository
*/ */
import { UserRating } from '../value-objects/UserRating'; import { UserRating } from '../value-objects/UserRating';
@@ -19,7 +19,7 @@ class InMemoryUserRatingRepository implements UserRatingRepository {
} }
} }
describe('IUserRatingRepository', () => { describe('UserRatingRepository', () => {
let repository: InMemoryUserRatingRepository; let repository: InMemoryUserRatingRepository;
beforeEach(() => { beforeEach(() => {

View File

@@ -1,5 +1,5 @@
/** /**
* Repository Interface: IUserRatingRepository * Repository Interface: UserRatingRepository
* *
* Port for persisting and retrieving UserRating snapshots. * Port for persisting and retrieving UserRating snapshots.
* Snapshots are derived from rating events for fast reads. * Snapshots are derived from rating events for fast reads.

View File

@@ -1,5 +1,5 @@
/** /**
* Domain Repository: IUserRepository * Domain Repository: UserRepository
* *
* Repository interface for User entity operations. * Repository interface for User entity operations.
*/ */

View File

@@ -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 { UserRatingRepository } from '../repositories/UserRatingRepository';
import type { RatingEventRepository } from '../repositories/RatingEventRepository'; import type { RatingEventRepository } from '../repositories/RatingEventRepository';
import { RatingEventFactory } from './RatingEventFactory'; import { RatingEventFactory } from './RatingEventFactory';
@@ -21,8 +21,8 @@ export class RatingUpdateService implements DomainService {
readonly serviceName = 'RatingUpdateService'; readonly serviceName = 'RatingUpdateService';
constructor( constructor(
private readonly userRatingRepository: IUserRatingRepository, private readonly userRatingRepository: UserRatingRepository,
private readonly ratingEventRepository: IRatingEventRepository private readonly ratingEventRepository: RatingEventRepository
) {} ) {}
/** /**

View File

@@ -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 { IdentityDomainValidationError } from '../errors/IdentityDomainError';
/** /**
@@ -68,7 +68,7 @@ export class AdminTrustReasonCode implements ValueObject<AdminTrustReasonCodePro
return { value: this.value }; return { value: this.value };
} }
equals(other: IValueObject<AdminTrustReasonCodeProps>): boolean { equals(other: ValueObject<AdminTrustReasonCodeProps>): boolean {
return this.value === other.props.value; return this.value === other.props.value;
} }

View File

@@ -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 { IdentityDomainValidationError } from '../errors/IdentityDomainError';
/** /**
@@ -80,7 +80,7 @@ export class DrivingReasonCode implements ValueObject<DrivingReasonCodeProps> {
return { value: this.value }; return { value: this.value };
} }
equals(other: IValueObject<DrivingReasonCodeProps>): boolean { equals(other: ValueObject<DrivingReasonCodeProps>): boolean {
return this.value === other.props.value; return this.value === other.props.value;
} }

View File

@@ -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 type { EmailValidationResult } from '../types/EmailAddress';
import { validateEmail, isDisposableEmail } from '../types/EmailAddress'; import { validateEmail, isDisposableEmail } from '../types/EmailAddress';
@@ -35,7 +35,7 @@ export class EmailAddress implements ValueObject<EmailAddressProps> {
return this.props.value; return this.props.value;
} }
equals(other: IValueObject<EmailAddressProps>): boolean { equals(other: ValueObject<EmailAddressProps>): boolean {
return this.props.value === other.props.value; return this.props.value === other.props.value;
} }

View File

@@ -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 { IdentityDomainValidationError } from '../errors/IdentityDomainError';
import { GameKey } from './GameKey'; 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 ( return (
this.gameKey.equals(other.props.gameKey) && this.gameKey.equals(other.props.gameKey) &&
this.type === other.props.type && this.type === other.props.type &&

View File

@@ -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 { IdentityDomainValidationError } from '../errors/IdentityDomainError';
export interface ExternalRatingProvenanceProps { export interface ExternalRatingProvenanceProps {
@@ -45,7 +45,7 @@ export class ExternalRatingProvenance implements ValueObject<ExternalRatingProve
}; };
} }
equals(other: IValueObject<ExternalRatingProvenanceProps>): boolean { equals(other: ValueObject<ExternalRatingProvenanceProps>): boolean {
return ( return (
this.source === other.props.source && this.source === other.props.source &&
this.lastSyncedAt.getTime() === other.props.lastSyncedAt.getTime() && this.lastSyncedAt.getTime() === other.props.lastSyncedAt.getTime() &&

View File

@@ -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 { IdentityDomainValidationError } from '../errors/IdentityDomainError';
export interface GameKeyProps { export interface GameKeyProps {
@@ -33,7 +33,7 @@ export class GameKey implements ValueObject<GameKeyProps> {
return { value: this.value }; return { value: this.value };
} }
equals(other: IValueObject<GameKeyProps>): boolean { equals(other: ValueObject<GameKeyProps>): boolean {
return this.value === other.props.value; return this.value === other.props.value;
} }

View File

@@ -1,5 +1,5 @@
import bcrypt from 'bcrypt'; import bcrypt from 'bcrypt';
import type { ValueObject } from '@core/shared/domain'; import type { ValueObject } from '@core/shared/domain/ValueObject';
export interface PasswordHashProps { export interface PasswordHashProps {
value: string; value: string;
@@ -35,7 +35,7 @@ export class PasswordHash implements ValueObject<PasswordHashProps> {
return bcrypt.compare(plain, this.props.value); return bcrypt.compare(plain, this.props.value);
} }
equals(other: IValueObject<PasswordHashProps>): boolean { equals(other: ValueObject<PasswordHashProps>): boolean {
return this.props.value === other.props.value; return this.props.value === other.props.value;
} }
} }

View File

@@ -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 { IdentityDomainValidationError } from '../errors/IdentityDomainError';
export interface RatingDeltaProps { export interface RatingDeltaProps {
@@ -30,7 +30,7 @@ export class RatingDelta implements ValueObject<RatingDeltaProps> {
return { value: this.value }; return { value: this.value };
} }
equals(other: IValueObject<RatingDeltaProps>): boolean { equals(other: ValueObject<RatingDeltaProps>): boolean {
return this.value === other.props.value; return this.value === other.props.value;
} }

View File

@@ -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 { IdentityDomainValidationError } from '../errors/IdentityDomainError';
export interface RatingDimensionKeyProps { export interface RatingDimensionKeyProps {
@@ -39,7 +39,7 @@ export class RatingDimensionKey implements ValueObject<RatingDimensionKeyProps>
return { value: this.value }; return { value: this.value };
} }
equals(other: IValueObject<RatingDimensionKeyProps>): boolean { equals(other: ValueObject<RatingDimensionKeyProps>): boolean {
return this.value === other.props.value; return this.value === other.props.value;
} }

View File

@@ -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 { IdentityDomainValidationError } from '../errors/IdentityDomainError';
import { v4 as uuidv4 } from 'uuid'; import { v4 as uuidv4 } from 'uuid';
@@ -38,7 +38,7 @@ export class RatingEventId implements ValueObject<RatingEventIdProps> {
return { value: this.value }; return { value: this.value };
} }
equals(other: IValueObject<RatingEventIdProps>): boolean { equals(other: ValueObject<RatingEventIdProps>): boolean {
return this.value === other.props.value; return this.value === other.props.value;
} }

View File

@@ -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 { IdentityDomainValidationError } from '../errors/IdentityDomainError';
export type RatingReferenceType = 'race' | 'penalty' | 'vote' | 'adminAction'; export type RatingReferenceType = 'race' | 'penalty' | 'vote' | 'adminAction';
@@ -38,7 +38,7 @@ export class RatingReference implements ValueObject<RatingReferenceProps> {
return { type: this.type, id: this.id }; 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; return this.type === other.props.type && this.id === other.props.id;
} }

View File

@@ -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 { IdentityDomainValidationError } from '../errors/IdentityDomainError';
export interface RatingValueProps { export interface RatingValueProps {
@@ -30,7 +30,7 @@ export class RatingValue implements ValueObject<RatingValueProps> {
return { value: this.value }; return { value: this.value };
} }
equals(other: IValueObject<RatingValueProps>): boolean { equals(other: ValueObject<RatingValueProps>): boolean {
return this.value === other.props.value; return this.value === other.props.value;
} }

View File

@@ -1,5 +1,5 @@
import { v4 as uuidv4 } from 'uuid'; import { v4 as uuidv4 } from 'uuid';
import type { ValueObject } from '@core/shared/domain'; import type { ValueObject } from '@core/shared/domain/ValueObject';
export interface UserIdProps { export interface UserIdProps {
value: string; value: string;
@@ -31,7 +31,7 @@ export class UserId implements ValueObject<UserIdProps> {
return this.props.value; return this.props.value;
} }
public equals(other: IValueObject<UserIdProps>): boolean { public equals(other: ValueObject<UserIdProps>): boolean {
return this.props.value === other.props.value; return this.props.value === other.props.value;
} }
} }

View File

@@ -1,4 +1,4 @@
import type { ValueObject } from '@core/shared/domain'; import type { ValueObject } from '@core/shared/domain/ValueObject';
/** /**
* Value Object: UserRating * Value Object: UserRating
@@ -111,7 +111,7 @@ export class UserRating implements ValueObject<UserRatingProps> {
return new UserRating(props); return new UserRating(props);
} }
equals(other: IValueObject<UserRatingProps>): boolean { equals(other: ValueObject<UserRatingProps>): boolean {
return this.props.userId === other.props.userId; return this.props.userId === other.props.userId;
} }

View File

@@ -39,7 +39,7 @@ describe('DeleteMediaUseCase', () => {
} as unknown as Logger; } as unknown as Logger;
useCase = new DeleteMediaUseCase( useCase = new DeleteMediaUseCase(
mediaRepo as unknown as IMediaRepository, mediaRepo as unknown as MediaRepository,
mediaStorage as unknown as MediaStoragePort, mediaStorage as unknown as MediaStoragePort,
logger, logger,
); );

View File

@@ -26,7 +26,7 @@ export type DeleteMediaApplicationError = ApplicationErrorCode<
export class DeleteMediaUseCase { export class DeleteMediaUseCase {
constructor( constructor(
private readonly mediaRepo: IMediaRepository, private readonly mediaRepo: MediaRepository,
private readonly mediaStorage: MediaStoragePort, private readonly mediaStorage: MediaStoragePort,
private readonly logger: Logger, private readonly logger: Logger,
) {} ) {}

View File

@@ -31,7 +31,7 @@ describe('GetAvatarUseCase', () => {
} as unknown as Logger; } as unknown as Logger;
useCase = new GetAvatarUseCase( useCase = new GetAvatarUseCase(
avatarRepo as unknown as IAvatarRepository, avatarRepo as unknown as AvatarRepository,
logger, logger,
); );
}); });

View File

@@ -29,7 +29,7 @@ export type GetAvatarApplicationError = ApplicationErrorCode<
export class GetAvatarUseCase { export class GetAvatarUseCase {
constructor( constructor(
private readonly avatarRepo: IAvatarRepository, private readonly avatarRepo: AvatarRepository,
private readonly logger: Logger, private readonly logger: Logger,
) {} ) {}

View File

@@ -29,7 +29,7 @@ describe('GetMediaUseCase', () => {
} as unknown as Logger; } as unknown as Logger;
useCase = new GetMediaUseCase( useCase = new GetMediaUseCase(
mediaRepo as unknown as IMediaRepository, mediaRepo as unknown as MediaRepository,
logger, logger,
); );
}); });

View File

@@ -30,7 +30,7 @@ export type GetMediaErrorCode = 'MEDIA_NOT_FOUND' | 'REPOSITORY_ERROR';
export class GetMediaUseCase { export class GetMediaUseCase {
constructor( constructor(
private readonly mediaRepo: IMediaRepository, private readonly mediaRepo: MediaRepository,
private readonly logger: Logger, private readonly logger: Logger,
) {} ) {}

View File

@@ -43,7 +43,7 @@ describe('RequestAvatarGenerationUseCase', () => {
} as unknown as Logger; } as unknown as Logger;
useCase = new RequestAvatarGenerationUseCase( useCase = new RequestAvatarGenerationUseCase(
avatarRepo as unknown as IAvatarGenerationRepository, avatarRepo as unknown as AvatarGenerationRepository,
faceValidation as unknown as FaceValidationPort, faceValidation as unknown as FaceValidationPort,
avatarGeneration as unknown as AvatarGenerationPort, avatarGeneration as unknown as AvatarGenerationPort,
logger, logger,

View File

@@ -38,7 +38,7 @@ export type RequestAvatarGenerationApplicationError = ApplicationErrorCode<
export class RequestAvatarGenerationUseCase { export class RequestAvatarGenerationUseCase {
constructor( constructor(
private readonly avatarRepo: IAvatarGenerationRepository, private readonly avatarRepo: AvatarGenerationRepository,
private readonly faceValidation: FaceValidationPort, private readonly faceValidation: FaceValidationPort,
private readonly avatarGeneration: AvatarGenerationPort, private readonly avatarGeneration: AvatarGenerationPort,
private readonly logger: Logger, private readonly logger: Logger,

Some files were not shown because too many files have changed in this diff Show More