cleanup
This commit is contained in:
26
apps/website/lib/utilities/LeagueMembershipUtility.ts
Normal file
26
apps/website/lib/utilities/LeagueMembershipUtility.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import { LeagueMembershipService } from '@/lib/services/leagues/LeagueMembershipService';
|
||||
import { LeagueRoleUtility } from '@/lib/utilities/LeagueRoleUtility';
|
||||
|
||||
export class LeagueMembershipUtility {
|
||||
/**
|
||||
* Derive a driver's primary league from cached memberships.
|
||||
* Prefers any active membership and returns the first matching league.
|
||||
*/
|
||||
static getPrimaryLeagueIdForDriver(driverId: string): string | null {
|
||||
for (const [leagueId, members] of LeagueMembershipService.getCachedMembershipsIterator()) {
|
||||
if (members.some((m) => m.driverId === driverId && m.status === 'active')) {
|
||||
return leagueId;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a driver is owner or admin of a league.
|
||||
*/
|
||||
static isOwnerOrAdmin(leagueId: string, driverId: string): boolean {
|
||||
const membership = LeagueMembershipService.getMembership(leagueId, driverId);
|
||||
if (!membership) return false;
|
||||
return LeagueRoleUtility.isLeagueAdminOrHigherRole(membership.role);
|
||||
}
|
||||
}
|
||||
40
apps/website/lib/utilities/LeagueRoleUtility.ts
Normal file
40
apps/website/lib/utilities/LeagueRoleUtility.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
import { LeagueRole } from '@/lib/types/LeagueRole';
|
||||
|
||||
export class LeagueRoleUtility {
|
||||
static isLeagueOwnerRole(role: LeagueRole): boolean {
|
||||
return role === 'owner';
|
||||
}
|
||||
|
||||
static isLeagueAdminRole(role: LeagueRole): boolean {
|
||||
return role === 'admin';
|
||||
}
|
||||
|
||||
static isLeagueStewardRole(role: LeagueRole): boolean {
|
||||
return role === 'steward';
|
||||
}
|
||||
|
||||
static isLeagueMemberRole(role: LeagueRole): boolean {
|
||||
return role === 'member';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true for roles that should be treated as having elevated permissions.
|
||||
* This keeps UI logic open for future roles like steward, streamer, sponsor.
|
||||
*/
|
||||
static isLeagueAdminOrHigherRole(role: LeagueRole): boolean {
|
||||
return role === 'owner' || role === 'admin' || role === 'steward';
|
||||
}
|
||||
|
||||
/**
|
||||
* Ordering helper for sorting memberships in tables.
|
||||
*/
|
||||
static getLeagueRoleOrder(role: LeagueRole): number {
|
||||
const order: Record<LeagueRole, number> = {
|
||||
owner: 0,
|
||||
admin: 1,
|
||||
steward: 2,
|
||||
member: 3,
|
||||
};
|
||||
return order[role] ?? 99;
|
||||
}
|
||||
}
|
||||
50
apps/website/lib/utilities/ScoringPresetApplier.ts
Normal file
50
apps/website/lib/utilities/ScoringPresetApplier.ts
Normal file
@@ -0,0 +1,50 @@
|
||||
// TODO: Move this business logic to core domain layer - scoring presets and their timing rules are domain concepts
|
||||
|
||||
type Timings = {
|
||||
practiceMinutes?: number;
|
||||
qualifyingMinutes?: number;
|
||||
sprintRaceMinutes?: number;
|
||||
mainRaceMinutes?: number;
|
||||
sessionCount?: number;
|
||||
roundsPlanned?: number;
|
||||
raceDayOfWeek?: number;
|
||||
raceTimeUtc?: string;
|
||||
};
|
||||
|
||||
export class ScoringPresetApplier {
|
||||
static applyToTimings(patternId: string, currentTimings: Timings): Timings {
|
||||
const lowerPresetId = patternId.toLowerCase();
|
||||
let updatedTimings: Timings = { ...currentTimings };
|
||||
|
||||
if (lowerPresetId.includes('sprint') || lowerPresetId.includes('double')) {
|
||||
updatedTimings = {
|
||||
...updatedTimings,
|
||||
practiceMinutes: 15,
|
||||
qualifyingMinutes: 20,
|
||||
sprintRaceMinutes: 20,
|
||||
mainRaceMinutes: 35,
|
||||
sessionCount: 2,
|
||||
};
|
||||
} else if (lowerPresetId.includes('endurance') || lowerPresetId.includes('long')) {
|
||||
updatedTimings = {
|
||||
...updatedTimings,
|
||||
practiceMinutes: 30,
|
||||
qualifyingMinutes: 30,
|
||||
mainRaceMinutes: 90,
|
||||
sessionCount: 1,
|
||||
};
|
||||
delete (updatedTimings as { sprintRaceMinutes?: number }).sprintRaceMinutes;
|
||||
} else {
|
||||
updatedTimings = {
|
||||
...updatedTimings,
|
||||
practiceMinutes: 20,
|
||||
qualifyingMinutes: 30,
|
||||
mainRaceMinutes: 40,
|
||||
sessionCount: 1,
|
||||
};
|
||||
delete (updatedTimings as { sprintRaceMinutes?: number }).sprintRaceMinutes;
|
||||
}
|
||||
|
||||
return updatedTimings;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user