Files
gridpilot.gg/core/identity/domain/services/RatingSnapshotCalculator.ts
2025-12-29 22:27:33 +01:00

56 lines
2.0 KiB
TypeScript

import { UserRating } from '../value-objects/UserRating';
import { RatingEvent } from '../entities/RatingEvent';
/**
* Domain Service: RatingSnapshotCalculator
*
* Pure, stateless calculator that derives a UserRating snapshot from events.
* STUB IMPLEMENTATION - will be evolved in future slices.
*/
export class RatingSnapshotCalculator {
/**
* Calculate UserRating snapshot from events
*
* STUB: Currently creates a basic snapshot by summing deltas per dimension.
* Future: Will implement:
* - Confidence calculation based on sample size
* - Trend detection from recent events
* - Exponential moving averages
* - Calculator version tracking
*/
static calculate(userId: string, events: RatingEvent[]): UserRating {
// Start with default UserRating
let snapshot = UserRating.create(userId);
// Group events by dimension
const eventsByDimension = events.reduce((acc, event) => {
const dimension = event.dimension.value;
if (!acc[dimension]) acc[dimension] = [];
acc[dimension].push(event);
return acc;
}, {} as Record<string, RatingEvent[]>);
// Apply events to each dimension
for (const [dimension, dimensionEvents] of Object.entries(eventsByDimension)) {
const totalDelta = dimensionEvents.reduce((sum, e) => sum + e.delta.value, 0);
const sampleSize = dimensionEvents.length;
// Calculate new value (base 50 + delta)
const newValue = Math.max(0, Math.min(100, 50 + totalDelta));
// Update the appropriate dimension
if (dimension === 'driving') {
snapshot = snapshot.updateDriverRating(newValue, sampleSize);
} else if (dimension === 'adminTrust') {
snapshot = snapshot.updateAdminRating(newValue, sampleSize);
} else if (dimension === 'stewardTrust') {
snapshot = snapshot.updateStewardRating(newValue, sampleSize);
} else if (dimension === 'broadcasterTrust') {
// Future dimension - would need to add to UserRating
// For now, skip
}
}
return snapshot;
}
}