team rating
This commit is contained in:
35
core/racing/domain/repositories/IDriverStatsRepository.ts
Normal file
35
core/racing/domain/repositories/IDriverStatsRepository.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
/**
|
||||
* Application Port: IDriverStatsRepository
|
||||
*
|
||||
* Repository interface for storing and retrieving computed driver statistics.
|
||||
* This is used for caching computed stats and serving frontend data.
|
||||
*/
|
||||
|
||||
import type { DriverStats } from '../../application/use-cases/IDriverStatsUseCase';
|
||||
|
||||
export interface IDriverStatsRepository {
|
||||
/**
|
||||
* Get stats for a specific driver
|
||||
*/
|
||||
getDriverStats(driverId: string): Promise<DriverStats | null>;
|
||||
|
||||
/**
|
||||
* Get stats for a specific driver (synchronous)
|
||||
*/
|
||||
getDriverStatsSync(driverId: string): DriverStats | null;
|
||||
|
||||
/**
|
||||
* Save stats for a specific driver
|
||||
*/
|
||||
saveDriverStats(driverId: string, stats: DriverStats): Promise<void>;
|
||||
|
||||
/**
|
||||
* Get all driver stats
|
||||
*/
|
||||
getAllStats(): Promise<Map<string, DriverStats>>;
|
||||
|
||||
/**
|
||||
* Clear all stats
|
||||
*/
|
||||
clear(): Promise<void>;
|
||||
}
|
||||
38
core/racing/domain/repositories/IMediaRepository.ts
Normal file
38
core/racing/domain/repositories/IMediaRepository.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
* Application Port: IMediaRepository
|
||||
*
|
||||
* Repository interface for static media assets (logos, images, icons).
|
||||
* Handles frontend assets like team logos, driver avatars, etc.
|
||||
*/
|
||||
|
||||
export interface IMediaRepository {
|
||||
/**
|
||||
* Get driver avatar URL
|
||||
*/
|
||||
getDriverAvatar(driverId: string): Promise<string | null>;
|
||||
|
||||
/**
|
||||
* Get team logo URL
|
||||
*/
|
||||
getTeamLogo(teamId: string): Promise<string | null>;
|
||||
|
||||
/**
|
||||
* Get track image URL
|
||||
*/
|
||||
getTrackImage(trackId: string): Promise<string | null>;
|
||||
|
||||
/**
|
||||
* Get category icon URL
|
||||
*/
|
||||
getCategoryIcon(categoryId: string): Promise<string | null>;
|
||||
|
||||
/**
|
||||
* Get sponsor logo URL
|
||||
*/
|
||||
getSponsorLogo(sponsorId: string): Promise<string | null>;
|
||||
|
||||
/**
|
||||
* Clear all media data (for reseeding)
|
||||
*/
|
||||
clear(): Promise<void>;
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/**
|
||||
* Repository Interface: ITeamRatingEventRepository
|
||||
*
|
||||
* Port for persisting and retrieving team rating events (ledger).
|
||||
* Events are immutable and ordered by occurredAt for deterministic snapshot computation.
|
||||
*/
|
||||
|
||||
import type { TeamRatingEvent } from '../entities/TeamRatingEvent';
|
||||
import type { TeamRatingEventId } from '../value-objects/TeamRatingEventId';
|
||||
|
||||
export interface FindByTeamIdOptions {
|
||||
/** Only return events after this ID (for pagination/streaming) */
|
||||
afterId?: TeamRatingEventId;
|
||||
/** Maximum number of events to return */
|
||||
limit?: number;
|
||||
}
|
||||
|
||||
export interface TeamRatingEventFilter {
|
||||
/** Filter by dimension keys */
|
||||
dimensions?: string[];
|
||||
/** Filter by source types */
|
||||
sourceTypes?: ('race' | 'penalty' | 'vote' | 'adminAction' | 'manualAdjustment')[];
|
||||
/** Filter by date range (inclusive) */
|
||||
from?: Date;
|
||||
to?: Date;
|
||||
/** Filter by reason codes */
|
||||
reasonCodes?: string[];
|
||||
/** Filter by visibility */
|
||||
visibility?: 'public' | 'private';
|
||||
}
|
||||
|
||||
export interface PaginatedQueryOptions {
|
||||
limit?: number;
|
||||
offset?: number;
|
||||
filter?: TeamRatingEventFilter;
|
||||
}
|
||||
|
||||
export interface PaginatedResult<T> {
|
||||
items: T[];
|
||||
total: number;
|
||||
limit: number;
|
||||
offset: number;
|
||||
hasMore: boolean;
|
||||
nextOffset?: number;
|
||||
}
|
||||
|
||||
export interface ITeamRatingEventRepository {
|
||||
/**
|
||||
* Save a rating event to the ledger
|
||||
*/
|
||||
save(event: TeamRatingEvent): Promise<TeamRatingEvent>;
|
||||
|
||||
/**
|
||||
* Find all rating events for a team, ordered by occurredAt (ascending)
|
||||
* Options allow for pagination and streaming
|
||||
*/
|
||||
findByTeamId(teamId: string, options?: FindByTeamIdOptions): Promise<TeamRatingEvent[]>;
|
||||
|
||||
/**
|
||||
* Find multiple events by their IDs
|
||||
*/
|
||||
findByIds(ids: TeamRatingEventId[]): Promise<TeamRatingEvent[]>;
|
||||
|
||||
/**
|
||||
* Get all events for a team (for snapshot recomputation)
|
||||
*/
|
||||
getAllByTeamId(teamId: string): Promise<TeamRatingEvent[]>;
|
||||
|
||||
/**
|
||||
* Find events with pagination and filtering
|
||||
*/
|
||||
findEventsPaginated(teamId: string, options?: PaginatedQueryOptions): Promise<PaginatedResult<TeamRatingEvent>>;
|
||||
}
|
||||
20
core/racing/domain/repositories/ITeamRatingRepository.ts
Normal file
20
core/racing/domain/repositories/ITeamRatingRepository.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* Repository Interface: ITeamRatingRepository
|
||||
*
|
||||
* Port for persisting and retrieving TeamRating snapshots.
|
||||
* Snapshots are derived from rating events for fast reads.
|
||||
*/
|
||||
|
||||
import type { TeamRatingSnapshot } from '../services/TeamRatingSnapshotCalculator';
|
||||
|
||||
export interface ITeamRatingRepository {
|
||||
/**
|
||||
* Find rating snapshot by team ID
|
||||
*/
|
||||
findByTeamId(teamId: string): Promise<TeamRatingSnapshot | null>;
|
||||
|
||||
/**
|
||||
* Save or update a team rating snapshot
|
||||
*/
|
||||
save(teamRating: TeamRatingSnapshot): Promise<TeamRatingSnapshot>;
|
||||
}
|
||||
44
core/racing/domain/repositories/ITeamStatsRepository.ts
Normal file
44
core/racing/domain/repositories/ITeamStatsRepository.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
/**
|
||||
* Application Port: ITeamStatsRepository
|
||||
*
|
||||
* Repository interface for storing and retrieving computed team statistics.
|
||||
* This is used for caching computed stats and serving frontend data.
|
||||
*/
|
||||
|
||||
export interface TeamStats {
|
||||
logoUrl: string;
|
||||
performanceLevel: 'beginner' | 'intermediate' | 'advanced' | 'pro';
|
||||
specialization: 'endurance' | 'sprint' | 'mixed';
|
||||
region: string;
|
||||
languages: string[];
|
||||
totalWins: number;
|
||||
totalRaces: number;
|
||||
rating: number;
|
||||
}
|
||||
|
||||
export interface ITeamStatsRepository {
|
||||
/**
|
||||
* Get stats for a specific team
|
||||
*/
|
||||
getTeamStats(teamId: string): Promise<TeamStats | null>;
|
||||
|
||||
/**
|
||||
* Get stats for a specific team (synchronous)
|
||||
*/
|
||||
getTeamStatsSync(teamId: string): TeamStats | null;
|
||||
|
||||
/**
|
||||
* Save stats for a specific team
|
||||
*/
|
||||
saveTeamStats(teamId: string, stats: TeamStats): Promise<void>;
|
||||
|
||||
/**
|
||||
* Get all team stats
|
||||
*/
|
||||
getAllStats(): Promise<Map<string, TeamStats>>;
|
||||
|
||||
/**
|
||||
* Clear all stats
|
||||
*/
|
||||
clear(): Promise<void>;
|
||||
}
|
||||
Reference in New Issue
Block a user