119 lines
4.2 KiB
TypeScript
119 lines
4.2 KiB
TypeScript
/**
|
|
* Query: GetUserRatingsSummaryQuery
|
|
*
|
|
* Fast read query for user rating summary.
|
|
* Combines platform snapshots and external game ratings.
|
|
*/
|
|
|
|
import { RatingSummaryDto } from '../dtos/RatingSummaryDto';
|
|
import { IUserRatingRepository } from '../../domain/repositories/IUserRatingRepository';
|
|
import { IExternalGameRatingRepository } from '../../domain/repositories/IExternalGameRatingRepository';
|
|
import { IRatingEventRepository } from '../../domain/repositories/IRatingEventRepository';
|
|
|
|
export interface GetUserRatingsSummaryQuery {
|
|
userId: string;
|
|
}
|
|
|
|
export class GetUserRatingsSummaryQueryHandler {
|
|
constructor(
|
|
private readonly userRatingRepo: IUserRatingRepository,
|
|
private readonly externalRatingRepo: IExternalGameRatingRepository,
|
|
private readonly ratingEventRepo: IRatingEventRepository
|
|
) {}
|
|
|
|
async execute(query: GetUserRatingsSummaryQuery): Promise<RatingSummaryDto> {
|
|
const { userId } = query;
|
|
|
|
// Fetch platform rating snapshot
|
|
const userRating = await this.userRatingRepo.findByUserId(userId);
|
|
|
|
// Fetch all external game ratings
|
|
const externalProfiles = await this.externalRatingRepo.findByUserId(userId);
|
|
|
|
// Get last event timestamp if available
|
|
let lastRatingEventAt: string | undefined;
|
|
if (userRating) {
|
|
// Get all events to find the most recent one
|
|
const events = await this.ratingEventRepo.getAllByUserId(userId);
|
|
if (events.length > 0) {
|
|
const lastEvent = events[events.length - 1];
|
|
if (lastEvent) {
|
|
lastRatingEventAt = lastEvent.occurredAt.toISOString();
|
|
}
|
|
}
|
|
}
|
|
|
|
// Build platform rating dimensions
|
|
const platform = {
|
|
driving: {
|
|
value: userRating?.driver.value || 0,
|
|
confidence: userRating?.driver.confidence || 0,
|
|
sampleSize: userRating?.driver.sampleSize || 0,
|
|
trend: userRating?.driver.trend || 'stable',
|
|
lastUpdated: userRating?.driver.lastUpdated?.toISOString() || new Date(0).toISOString(),
|
|
},
|
|
admin: {
|
|
value: userRating?.admin.value || 0,
|
|
confidence: userRating?.admin.confidence || 0,
|
|
sampleSize: userRating?.admin.sampleSize || 0,
|
|
trend: userRating?.admin.trend || 'stable',
|
|
lastUpdated: userRating?.admin.lastUpdated?.toISOString() || new Date(0).toISOString(),
|
|
},
|
|
steward: {
|
|
value: userRating?.steward.value || 0,
|
|
confidence: userRating?.steward.confidence || 0,
|
|
sampleSize: userRating?.steward.sampleSize || 0,
|
|
trend: userRating?.steward.trend || 'stable',
|
|
lastUpdated: userRating?.steward.lastUpdated?.toISOString() || new Date(0).toISOString(),
|
|
},
|
|
trust: {
|
|
value: userRating?.trust.value || 0,
|
|
confidence: userRating?.trust.confidence || 0,
|
|
sampleSize: userRating?.trust.sampleSize || 0,
|
|
trend: userRating?.trust.trend || 'stable',
|
|
lastUpdated: userRating?.trust.lastUpdated?.toISOString() || new Date(0).toISOString(),
|
|
},
|
|
fairness: {
|
|
value: userRating?.fairness.value || 0,
|
|
confidence: userRating?.fairness.confidence || 0,
|
|
sampleSize: userRating?.fairness.sampleSize || 0,
|
|
trend: userRating?.fairness.trend || 'stable',
|
|
lastUpdated: userRating?.fairness.lastUpdated?.toISOString() || new Date(0).toISOString(),
|
|
},
|
|
overallReputation: userRating?.overallReputation || 0,
|
|
};
|
|
|
|
// Build external ratings map
|
|
const external: { [gameKey: string]: { [type: string]: number } } = {};
|
|
|
|
for (const profile of externalProfiles) {
|
|
const gameKey = profile.gameKey.toString();
|
|
external[gameKey] = {};
|
|
|
|
// Convert Map to array and iterate
|
|
const ratingsArray = Array.from(profile.ratings.entries());
|
|
for (const [type, rating] of ratingsArray) {
|
|
external[gameKey][type] = rating.value;
|
|
}
|
|
}
|
|
|
|
// Get timestamps
|
|
const createdAt = userRating?.createdAt?.toISOString() || new Date().toISOString();
|
|
const updatedAt = userRating?.updatedAt?.toISOString() || new Date().toISOString();
|
|
|
|
const result: RatingSummaryDto = {
|
|
userId,
|
|
platform,
|
|
external,
|
|
createdAt,
|
|
updatedAt,
|
|
};
|
|
|
|
if (lastRatingEventAt) {
|
|
result.lastRatingEventAt = lastRatingEventAt;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
}
|