82 lines
2.6 KiB
TypeScript
82 lines
2.6 KiB
TypeScript
/**
|
|
* Query: GetTeamRatingsSummaryQuery
|
|
*
|
|
* Fast read query for team rating summary.
|
|
* Mirrors user slice 6 pattern but for teams.
|
|
*/
|
|
|
|
import { TeamRatingEventRepository } from '../../domain/repositories/TeamRatingEventRepository';
|
|
import { TeamRatingRepository } from '../../domain/repositories/TeamRatingRepository';
|
|
import { TeamRatingSummaryDto } from '../dtos/TeamRatingSummaryDto';
|
|
|
|
export interface GetTeamRatingsSummaryQuery {
|
|
teamId: string;
|
|
}
|
|
|
|
export class GetTeamRatingsSummaryQueryHandler {
|
|
constructor(
|
|
private readonly teamRatingRepo: TeamRatingRepository,
|
|
private readonly ratingEventRepo: TeamRatingEventRepository
|
|
) {}
|
|
|
|
async execute(query: GetTeamRatingsSummaryQuery): Promise<TeamRatingSummaryDto> {
|
|
const { teamId } = query;
|
|
|
|
// Fetch platform rating snapshot
|
|
const teamRating = await this.teamRatingRepo.findByTeamId(teamId);
|
|
|
|
// Get last event timestamp if available
|
|
let lastRatingEventAt: string | undefined;
|
|
if (teamRating) {
|
|
// Get all events to find the most recent one
|
|
const events = await this.ratingEventRepo.getAllByTeamId(teamId);
|
|
if (events.length > 0) {
|
|
const lastEvent = events[events.length - 1];
|
|
if (lastEvent) {
|
|
lastRatingEventAt = lastEvent.occurredAt.toISOString();
|
|
}
|
|
}
|
|
}
|
|
|
|
// Build platform rating dimensions
|
|
// For team ratings, we don't have confidence/sampleSize/trend per dimension
|
|
// We'll derive these from event count and recent activity
|
|
const eventCount = teamRating?.eventCount || 0;
|
|
const lastUpdated = teamRating?.lastUpdated || new Date(0);
|
|
|
|
const platform = {
|
|
driving: {
|
|
value: teamRating?.driving.value || 0,
|
|
confidence: Math.min(1, eventCount / 10), // Simple confidence based on event count
|
|
sampleSize: eventCount,
|
|
trend: 'stable' as const, // Could be calculated from recent events
|
|
lastUpdated: lastUpdated.toISOString(),
|
|
},
|
|
adminTrust: {
|
|
value: teamRating?.adminTrust.value || 0,
|
|
confidence: Math.min(1, eventCount / 10),
|
|
sampleSize: eventCount,
|
|
trend: 'stable' as const,
|
|
lastUpdated: lastUpdated.toISOString(),
|
|
},
|
|
overall: teamRating?.overall || 0,
|
|
};
|
|
|
|
// Get timestamps
|
|
const createdAt = lastUpdated.toISOString();
|
|
const updatedAt = lastUpdated.toISOString();
|
|
|
|
const result: TeamRatingSummaryDto = {
|
|
teamId,
|
|
platform,
|
|
createdAt,
|
|
updatedAt,
|
|
};
|
|
|
|
if (lastRatingEventAt) {
|
|
result.lastRatingEventAt = lastRatingEventAt;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
} |