rating
This commit is contained in:
118
core/identity/application/queries/GetUserRatingsSummaryQuery.ts
Normal file
118
core/identity/application/queries/GetUserRatingsSummaryQuery.ts
Normal file
@@ -0,0 +1,118 @@
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user