inmemory to postgres

This commit is contained in:
2025-12-29 19:44:11 +01:00
parent f5639a367f
commit 12ae6e1dad
17 changed files with 361 additions and 94 deletions

View File

@@ -4,9 +4,13 @@ import { JoinRequest } from '@core/racing/domain/entities/JoinRequest';
import { LeagueMembership } from '@core/racing/domain/entities/LeagueMembership';
import { Race } from '@core/racing/domain/entities/Race';
import { RaceRegistration } from '@core/racing/domain/entities/RaceRegistration';
import { seedId } from './SeedIdHelper';
export class RacingMembershipFactory {
constructor(private readonly baseDate: Date) {}
constructor(
private readonly baseDate: Date,
private readonly persistence: 'postgres' | 'inmemory' = 'inmemory',
) {}
createLeagueMemberships(drivers: Driver[], leagues: League[]): LeagueMembership[] {
const memberships: LeagueMembership[] = [];
@@ -34,19 +38,20 @@ export class RacingMembershipFactory {
// Empty league: intentionally no memberships.
// (Keep `league-2` empty if it exists.)
// Widen the type to avoid TS2367 no overlap comparisons in some build modes.
const emptyLeagueId: string | undefined = leagueById.has('league-2') ? ('league-2' as string) : undefined;
// Widen the type to avoid TS2367 "no overlap" comparisons in some build modes.
const emptyLeagueId: string | undefined = leagueById.has(seedId('league-2', this.persistence)) ? (seedId('league-2', this.persistence) as string) : undefined;
// Demo league: "full" + overbooked with pending/inactive members.
const demoLeague = leagueById.get('league-5');
const demoLeague = leagueById.get(seedId('league-5', this.persistence));
if (demoLeague) {
const maxDrivers = demoLeague.settings.maxDrivers ?? 32;
const activeDrivers = drivers.slice(0, Math.min(maxDrivers, drivers.length));
activeDrivers.forEach((driver, idx) => {
const driverId = driver.id.toString();
const expectedDriverId = seedId('driver-1', this.persistence);
const role =
driverId === 'driver-1'
driverId === expectedDriverId
? 'owner'
: idx === 1 || idx === 2
? 'admin'
@@ -71,7 +76,7 @@ export class RacingMembershipFactory {
}
// League with mixed statuses and roles (but not full).
const league1 = leagueById.get('league-1');
const league1 = leagueById.get(seedId('league-1', this.persistence));
if (league1) {
const pick = drivers.slice(15, 25);
pick.forEach((driver, idx) => {
@@ -86,7 +91,7 @@ export class RacingMembershipFactory {
}
// League with only pending memberships (tests "pending list" UX).
const league4 = leagueById.get('league-4');
const league4 = leagueById.get(seedId('league-4', this.persistence));
if (league4) {
drivers.slice(40, 48).forEach((driver, idx) => {
add({
@@ -106,10 +111,10 @@ export class RacingMembershipFactory {
for (const league of leagues) {
const leagueId = league.id.toString();
if (leagueId === 'league-5') continue;
if (leagueId === seedId('league-5', this.persistence)) continue;
if (emptyLeagueId && leagueId === emptyLeagueId) continue;
if (driverNumber % 11 === 0 && leagueId === 'league-3') {
if (driverNumber % 11 === 0 && leagueId === seedId('league-3', this.persistence)) {
add({
leagueId,
driverId,
@@ -157,7 +162,7 @@ export class RacingMembershipFactory {
};
// League with lots of requests + membership/request conflicts (everyone is a member of league-5 already).
const demoLeagueId = 'league-5';
const demoLeagueId = seedId('league-5', this.persistence);
const demoDrivers = drivers.slice(10, 35);
demoDrivers.forEach((driver, idx) => {
const message =
@@ -178,7 +183,7 @@ export class RacingMembershipFactory {
});
// League with a few "normal" requests (only drivers who are NOT members already).
const targetLeagueId = 'league-1';
const targetLeagueId = seedId('league-1', this.persistence);
const nonMembers = drivers
.filter(driver => !membershipIds.has(`${targetLeagueId}:${driver.id.toString()}`))
.slice(0, 6);
@@ -193,11 +198,11 @@ export class RacingMembershipFactory {
});
// Single request with no message (explicit id).
const league3Exists = leagues.some(l => l.id.toString() === 'league-3');
const league3Exists = leagues.some(l => l.id.toString() === seedId('league-3', this.persistence));
if (league3Exists && drivers[0]) {
addRequest({
id: 'league-3-join-req-1',
leagueId: 'league-3',
id: seedId('league-3-join-req-1', this.persistence),
leagueId: seedId('league-3', this.persistence),
driverId: drivers[0].id.toString(),
requestedAt: this.addDays(this.baseDate, -9),
});
@@ -206,16 +211,16 @@ export class RacingMembershipFactory {
// Duplicate id edge case (last write wins in in-memory repo).
if (drivers[1]) {
addRequest({
id: 'dup-league-join-req-1',
leagueId: 'league-7',
id: seedId('dup-league-join-req-1', this.persistence),
leagueId: seedId('league-7', this.persistence),
driverId: drivers[1].id.toString(),
requestedAt: this.addDays(this.baseDate, -2),
message: 'First request message (will be overwritten).',
});
addRequest({
id: 'dup-league-join-req-1',
leagueId: 'league-7',
id: seedId('dup-league-join-req-1', this.persistence),
leagueId: seedId('league-7', this.persistence),
driverId: drivers[1].id.toString(),
requestedAt: this.addDays(this.baseDate, -1),
message: 'Updated request message (duplicate id).',
@@ -223,10 +228,11 @@ export class RacingMembershipFactory {
}
// Explicit conflict: join request exists even though membership exists.
const driver1 = drivers.find(d => d.id.toString() === 'driver-1');
const expectedDriverId = seedId('driver-1', this.persistence);
const driver1 = drivers.find(d => d.id.toString() === expectedDriverId);
if (driver1) {
addRequest({
id: 'conflict-req-league-5-driver-1',
id: seedId('conflict-req-league-5-driver-1', this.persistence),
leagueId: demoLeagueId,
driverId: driver1.id.toString(),
requestedAt: this.addDays(this.baseDate, -15),
@@ -311,12 +317,12 @@ export class RacingMembershipFactory {
}
// Keep a tiny curated "happy path" for the demo league as well
const upcomingDemoLeague = races.filter((r) => r.status.toString() === 'scheduled' && r.leagueId === 'league-5').slice(0, 3);
const upcomingDemoLeague = races.filter((r) => r.status.toString() === 'scheduled' && r.leagueId === seedId('league-5', this.persistence)).slice(0, 3);
for (const race of upcomingDemoLeague) {
registrations.push(
RaceRegistration.create({
raceId: race.id,
driverId: 'driver-1',
driverId: seedId('driver-1', this.persistence),
}),
);
}