import { Driver } from '@core/racing/domain/entities/Driver'; import { League } from '@core/racing/domain/entities/League'; import { Race } from '@core/racing/domain/entities/Race'; import type { FeedItem } from '@core/social/domain/types/FeedItem'; import type { Friendship } from './RacingSeed'; import { seedId } from './SeedIdHelper'; export class RacingFeedFactory { constructor( private readonly baseDate: Date, private readonly persistence: 'postgres' | 'inmemory' = 'inmemory', ) {} create(drivers: Driver[], friendships: Friendship[], races: Race[], leagues: League[]): FeedItem[] { const items: FeedItem[] = []; const friendMap = new Map(friendships.map((f) => [`${f.driverId}:${f.friendId}`, true] as const)); const completedRace = races.find((r) => r.status.toString() === 'completed'); const upcomingRace = races.find((r) => r.status.toString() === 'scheduled'); const league = leagues.find((l) => l.id.toString() === 'league-5') ?? leagues[0]!; const now = this.addMinutes(this.baseDate, 10); for (let i = 2; i <= 10; i++) { const actor = drivers.find((d) => d.id === seedId(`driver-${i}`, this.persistence)); if (!actor) continue; if (!friendMap.has(`driver-1:${actor.id}`)) continue; items.push({ id: seedId(`feed:${actor.id}:joined:${i}`, this.persistence), type: 'friend-joined-league', timestamp: this.addMinutes(now, -(i * 7)), actorDriverId: actor.id, actorFriendId: actor.id, leagueId: league.id.toString(), headline: `${actor.name} joined ${String(league.name)}`, body: 'Demo activity in in-memory mode.', ctaLabel: 'View league', ctaHref: `/leagues/${league.id.toString()}`, }); if (completedRace) { items.push({ id: seedId(`feed:${actor.id}:result:${i}`, this.persistence), type: 'friend-finished-race', timestamp: this.addMinutes(now, -(i * 7 + 3)), actorDriverId: actor.id, actorFriendId: actor.id, leagueId: completedRace.leagueId, raceId: completedRace.id, position: (i % 5) + 1, headline: `${actor.name} finished a race`, body: `Completed at ${completedRace.track}.`, ctaLabel: 'View results', ctaHref: `/races/${completedRace.id}/results`, }); } } if (upcomingRace) { items.push({ id: seedId(`feed:system:scheduled:${upcomingRace.id}`, this.persistence), type: 'new-race-scheduled', timestamp: this.addMinutes(now, -3), leagueId: upcomingRace.leagueId, raceId: upcomingRace.id, headline: `New race scheduled at ${upcomingRace.track}`, body: `${upcomingRace.car} • ${upcomingRace.scheduledAt.toISOString()}`, ctaLabel: 'View schedule', ctaHref: `/races/${upcomingRace.id}`, }); } return items.sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime()); } private addMinutes(date: Date, minutes: number): Date { return new Date(date.getTime() + minutes * 60 * 1000); } }