wip
This commit is contained in:
@@ -16,5 +16,25 @@ export function useEffectiveDriverId(): string {
|
||||
}
|
||||
| undefined;
|
||||
|
||||
return user?.primaryDriverId ?? 'driver-1';
|
||||
// In alpha mode, if the user has no bound driver yet, fall back to the
|
||||
// first seeded driver from the in-memory repository instead of a hardcoded ID.
|
||||
if (user?.primaryDriverId) {
|
||||
return user.primaryDriverId;
|
||||
}
|
||||
|
||||
try {
|
||||
// Lazy-load to avoid importing DI facade at module evaluation time
|
||||
const { getDriverRepository } = require('./di-container') as typeof import('./di-container');
|
||||
const repo = getDriverRepository();
|
||||
// In-memory repository is synchronous for findAll in the demo implementation
|
||||
const allDrivers = repo.findAllSync?.() as Array<{ id: string }> | undefined;
|
||||
if (allDrivers && allDrivers.length > 0) {
|
||||
return allDrivers[0].id;
|
||||
}
|
||||
} catch {
|
||||
// Ignore and fall back to legacy default below
|
||||
}
|
||||
|
||||
// Legacy fallback: preserved only as a last resort for demo
|
||||
return '';
|
||||
}
|
||||
@@ -149,7 +149,7 @@ export function configureDIContainer(): void {
|
||||
|
||||
// Create seed data
|
||||
const seedData = createStaticRacingSeed(42);
|
||||
const primaryDriverId = seedData.drivers[0]?.id ?? 'driver-1';
|
||||
const primaryDriverId = seedData.drivers[0]!.id;
|
||||
|
||||
// Create driver statistics from seed data
|
||||
const driverStats = createDemoDriverStats(seedData.drivers);
|
||||
@@ -556,7 +556,7 @@ export function configureDIContainer(): void {
|
||||
name: t.name,
|
||||
tag: t.tag,
|
||||
description: t.description,
|
||||
ownerId: seedData.drivers[0]?.id ?? 'driver-1',
|
||||
ownerId: seedData.drivers[0]!.id,
|
||||
leagues: [t.primaryLeagueId],
|
||||
createdAt: new Date(),
|
||||
}))
|
||||
@@ -640,13 +640,8 @@ export function configureDIContainer(): void {
|
||||
);
|
||||
|
||||
const sponsorshipPricingRepo = new InMemorySponsorshipPricingRepository();
|
||||
// Seed sponsorship pricings from demo data
|
||||
seedData.sponsorshipPricings?.forEach(pricing => {
|
||||
(sponsorshipPricingRepo as any).pricings.set(
|
||||
`${pricing.entityType}-${pricing.entityId}`,
|
||||
pricing
|
||||
);
|
||||
});
|
||||
// Seed sponsorship pricings from demo data using domain SponsorshipPricing
|
||||
sponsorshipPricingRepo.seed(seedData.sponsorshipPricings ?? []);
|
||||
container.registerInstance<ISponsorshipPricingRepository>(
|
||||
DI_TOKENS.SponsorshipPricingRepository,
|
||||
sponsorshipPricingRepo
|
||||
|
||||
@@ -5,7 +5,6 @@ import type {
|
||||
MembershipRole,
|
||||
MembershipStatus,
|
||||
} from '@gridpilot/racing/domain/entities/LeagueMembership';
|
||||
import { leagues, memberships as seedMemberships, drivers } from '@gridpilot/testing-support';
|
||||
|
||||
/**
|
||||
* Lightweight league membership model mirroring the domain type but with
|
||||
@@ -18,112 +17,49 @@ export interface LeagueMembership extends Omit<DomainLeagueMembership, 'joinedAt
|
||||
const leagueMemberships = new Map<string, LeagueMembership[]>();
|
||||
|
||||
/**
|
||||
* Initialize league memberships once from static seed data.
|
||||
* Initialize league memberships once from the in-memory league membership repository
|
||||
* that is seeded via the static racing seed in the DI container.
|
||||
*
|
||||
* - All seeded memberships become active members.
|
||||
* - League owners are guaranteed to have an owner membership.
|
||||
* This avoids depending on raw testing-support seed exports and keeps all demo
|
||||
* membership data flowing through the same in-memory repositories used elsewhere.
|
||||
*/
|
||||
(function initializeLeagueMembershipsFromSeed() {
|
||||
(async function initializeLeagueMembershipsFromRepository() {
|
||||
if (leagueMemberships.size > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const byLeague = new Map<string, LeagueMembership[]>();
|
||||
try {
|
||||
const { getLeagueRepository, getLeagueMembershipRepository } = await import('./di-container');
|
||||
const leagueRepo = getLeagueRepository();
|
||||
const membershipRepo = getLeagueMembershipRepository();
|
||||
|
||||
for (const membership of seedMemberships) {
|
||||
const list = byLeague.get(membership.leagueId) ?? [];
|
||||
const joinedAt = new Date().toISOString();
|
||||
const allLeagues = await leagueRepo.findAll();
|
||||
const byLeague = new Map<string, LeagueMembership[]>();
|
||||
|
||||
list.push({
|
||||
leagueId: membership.leagueId,
|
||||
driverId: membership.driverId,
|
||||
role: 'member',
|
||||
status: 'active',
|
||||
joinedAt,
|
||||
});
|
||||
for (const league of allLeagues) {
|
||||
const memberships = await membershipRepo.getLeagueMembers(league.id);
|
||||
|
||||
byLeague.set(membership.leagueId, list);
|
||||
}
|
||||
const mapped: LeagueMembership[] = memberships.map((membership) => ({
|
||||
leagueId: membership.leagueId,
|
||||
driverId: membership.driverId,
|
||||
role: membership.role,
|
||||
status: membership.status,
|
||||
joinedAt:
|
||||
membership.joinedAt instanceof Date
|
||||
? membership.joinedAt.toISOString()
|
||||
: new Date().toISOString(),
|
||||
}));
|
||||
|
||||
for (const league of leagues) {
|
||||
const list = byLeague.get(league.id) ?? [];
|
||||
const existingOwner = list.find((m) => m.driverId === league.ownerId);
|
||||
|
||||
if (existingOwner) {
|
||||
existingOwner.role = 'owner';
|
||||
} else {
|
||||
const joinedAt = new Date().toISOString();
|
||||
list.unshift({
|
||||
leagueId: league.id,
|
||||
driverId: league.ownerId,
|
||||
role: 'owner',
|
||||
status: 'active',
|
||||
joinedAt,
|
||||
});
|
||||
byLeague.set(league.id, mapped);
|
||||
}
|
||||
|
||||
byLeague.set(league.id, list);
|
||||
}
|
||||
|
||||
// Seed sample league admins for the primary driver's league (alpha demo)
|
||||
const primaryDriverId = drivers[0]?.id ?? 'driver-1';
|
||||
const primaryLeagueForAdmins = leagues.find((l) => l.ownerId === primaryDriverId) ?? leagues[0];
|
||||
|
||||
if (primaryLeagueForAdmins) {
|
||||
const adminCandidates = drivers
|
||||
.filter((d) => d.id !== primaryLeagueForAdmins.ownerId)
|
||||
.slice(0, 2);
|
||||
|
||||
adminCandidates.forEach((driver) => {
|
||||
const list = byLeague.get(primaryLeagueForAdmins.id) ?? [];
|
||||
const existing = list.find((m) => m.driverId === driver.id);
|
||||
if (existing) {
|
||||
if (existing.role !== 'owner') {
|
||||
existing.role = 'admin';
|
||||
}
|
||||
} else {
|
||||
const joinedAt = new Date().toISOString();
|
||||
list.push({
|
||||
leagueId: primaryLeagueForAdmins.id,
|
||||
driverId: driver.id,
|
||||
role: 'admin',
|
||||
status: 'active',
|
||||
joinedAt,
|
||||
});
|
||||
}
|
||||
byLeague.set(primaryLeagueForAdmins.id, list);
|
||||
});
|
||||
}
|
||||
|
||||
// Seed sample league stewards for the primary driver's league (alpha demo)
|
||||
if (primaryLeagueForAdmins) {
|
||||
const stewardCandidates = drivers
|
||||
.filter((d) => d.id !== primaryLeagueForAdmins.ownerId)
|
||||
.slice(2, 5);
|
||||
|
||||
stewardCandidates.forEach((driver) => {
|
||||
const list = byLeague.get(primaryLeagueForAdmins.id) ?? [];
|
||||
const existing = list.find((m) => m.driverId === driver.id);
|
||||
if (existing) {
|
||||
if (existing.role !== 'owner' && existing.role !== 'admin') {
|
||||
existing.role = 'steward';
|
||||
}
|
||||
} else {
|
||||
const joinedAt = new Date().toISOString();
|
||||
list.push({
|
||||
leagueId: primaryLeagueForAdmins.id,
|
||||
driverId: driver.id,
|
||||
role: 'steward',
|
||||
status: 'active',
|
||||
joinedAt,
|
||||
});
|
||||
}
|
||||
byLeague.set(primaryLeagueForAdmins.id, list);
|
||||
});
|
||||
}
|
||||
|
||||
for (const [leagueId, list] of byLeague.entries()) {
|
||||
leagueMemberships.set(leagueId, list);
|
||||
for (const [leagueId, list] of byLeague.entries()) {
|
||||
leagueMemberships.set(leagueId, list);
|
||||
}
|
||||
} catch (error) {
|
||||
// In alpha/demo mode we tolerate failures here; callers will see empty memberships.
|
||||
// eslint-disable-next-line no-console
|
||||
console.error('Failed to initialize league memberships from repository', error);
|
||||
}
|
||||
})();
|
||||
|
||||
@@ -137,6 +73,19 @@ export function getLeagueMembers(leagueId: string): LeagueMembership[] {
|
||||
return [...(leagueMemberships.get(leagueId) ?? [])];
|
||||
}
|
||||
|
||||
/**
|
||||
* Derive a driver's primary league from in-memory league memberships.
|
||||
* Prefers any active membership and returns the first matching league.
|
||||
*/
|
||||
export function getPrimaryLeagueIdForDriver(driverId: string): string | null {
|
||||
for (const [leagueId, members] of leagueMemberships.entries()) {
|
||||
if (members.some((m) => m.driverId === driverId && m.status === 'active')) {
|
||||
return leagueId;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
export function isOwnerOrAdmin(leagueId: string, driverId: string): boolean {
|
||||
const membership = getMembership(leagueId, driverId);
|
||||
if (!membership) return false;
|
||||
|
||||
Reference in New Issue
Block a user