Files
gridpilot.gg/core/identity/application/use-cases/RecomputeUserRatingSnapshotUseCase.ts
2025-12-29 22:27:33 +01:00

94 lines
3.1 KiB
TypeScript

import { IRatingEventRepository } from '../../domain/repositories/IRatingEventRepository';
import { IUserRatingRepository } from '../../domain/repositories/IUserRatingRepository';
import { RatingSnapshotCalculator } from '../../domain/services/RatingSnapshotCalculator';
import { UserRatingDto } from '../dtos/UserRatingDto';
/**
* Input for RecomputeUserRatingSnapshotUseCase
*/
export interface RecomputeUserRatingSnapshotInput {
userId: string;
}
/**
* Output for RecomputeUserRatingSnapshotUseCase
*/
export interface RecomputeUserRatingSnapshotOutput {
snapshot: UserRatingDto;
}
/**
* Use Case: RecomputeUserRatingSnapshotUseCase
*
* Recomputes a user's rating snapshot from all events in the ledger.
* Useful for:
* - Algorithm updates
* - Data corrections
* - Manual recomputation
*/
export class RecomputeUserRatingSnapshotUseCase {
constructor(
private readonly ratingEventRepository: IRatingEventRepository,
private readonly userRatingRepository: IUserRatingRepository,
) {}
async execute(input: RecomputeUserRatingSnapshotInput): Promise<RecomputeUserRatingSnapshotOutput> {
// 1. Load all events for the user
const events = await this.ratingEventRepository.getAllByUserId(input.userId);
// 2. Compute snapshot from events
const snapshot = RatingSnapshotCalculator.calculate(input.userId, events);
// 3. Save snapshot
await this.userRatingRepository.save(snapshot);
// 4. Convert to DTO for output
const dto: UserRatingDto = {
userId: snapshot.userId,
driver: {
value: snapshot.driver.value,
confidence: snapshot.driver.confidence,
sampleSize: snapshot.driver.sampleSize,
trend: snapshot.driver.trend,
lastUpdated: snapshot.driver.lastUpdated.toISOString(),
},
admin: {
value: snapshot.admin.value,
confidence: snapshot.admin.confidence,
sampleSize: snapshot.admin.sampleSize,
trend: snapshot.admin.trend,
lastUpdated: snapshot.admin.lastUpdated.toISOString(),
},
steward: {
value: snapshot.steward.value,
confidence: snapshot.steward.confidence,
sampleSize: snapshot.steward.sampleSize,
trend: snapshot.steward.trend,
lastUpdated: snapshot.steward.lastUpdated.toISOString(),
},
trust: {
value: snapshot.trust.value,
confidence: snapshot.trust.confidence,
sampleSize: snapshot.trust.sampleSize,
trend: snapshot.trust.trend,
lastUpdated: snapshot.trust.lastUpdated.toISOString(),
},
fairness: {
value: snapshot.fairness.value,
confidence: snapshot.fairness.confidence,
sampleSize: snapshot.fairness.sampleSize,
trend: snapshot.fairness.trend,
lastUpdated: snapshot.fairness.lastUpdated.toISOString(),
},
overallReputation: snapshot.overallReputation,
createdAt: snapshot.createdAt.toISOString(),
updatedAt: snapshot.updatedAt.toISOString(),
};
if (snapshot.calculatorVersion !== undefined) {
dto.calculatorVersion = snapshot.calculatorVersion;
}
return { snapshot: dto };
}
}