import { RatingEvent } from '../entities/RatingEvent'; import { UserRating } from '../value-objects/UserRating'; /** * 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); // 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; } }