fix issues in core
This commit is contained in:
@@ -2,13 +2,13 @@
|
||||
* Enhanced Result entity with detailed incident tracking
|
||||
*/
|
||||
|
||||
import { RacingDomainValidationError } from '../errors/RacingDomainError';
|
||||
import type { IEntity } from '@core/shared/domain';
|
||||
import { RacingDomainValidationError } from '../errors/RacingDomainError';
|
||||
import { RaceIncidents, type IncidentRecord } from '../value-objects/RaceIncidents';
|
||||
import { RaceId } from './RaceId';
|
||||
import { DriverId } from './DriverId';
|
||||
import { Position } from './result/Position';
|
||||
import { RaceId } from './RaceId';
|
||||
import { LapTime } from './result/LapTime';
|
||||
import { Position } from './result/Position';
|
||||
|
||||
export class ResultWithIncidents implements IEntity<string> {
|
||||
readonly id: string;
|
||||
@@ -66,6 +66,7 @@ export class ResultWithIncidents implements IEntity<string> {
|
||||
});
|
||||
}
|
||||
|
||||
// TODO WE DONT NEED ANY LEGACY CODE WE ARE NOT EVEN LIVE
|
||||
/**
|
||||
* Create from legacy Result data (with incidents as number)
|
||||
*/
|
||||
|
||||
@@ -8,9 +8,9 @@ describe('SponsorshipRequest', () => {
|
||||
const validProps = {
|
||||
id: 'request-123',
|
||||
sponsorId: 'sponsor-456',
|
||||
entityType: 'driver',
|
||||
entityType: 'driver' as SponsorableEntityType,
|
||||
entityId: 'driver-789',
|
||||
tier: 'main',
|
||||
tier: 'main' as SponsorshipTier,
|
||||
offeredAmount: validMoney,
|
||||
};
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { LeagueWallet } from './LeagueWallet';
|
||||
import { Money } from '../value-objects/Money';
|
||||
import { Money } from '../../value-objects/Money';
|
||||
|
||||
describe('LeagueWallet', () => {
|
||||
it('should create a league wallet', () => {
|
||||
|
||||
@@ -11,7 +11,7 @@ import type { Money } from '../../value-objects/Money';
|
||||
import { Position } from '../championship/Position';
|
||||
import { PrizeId } from './PrizeId';
|
||||
import { PrizeStatus } from './PrizeStatus';
|
||||
import { SeasonId } from '../SeasonId';
|
||||
import { SeasonId } from '../season/SeasonId';
|
||||
import { DriverId } from '../DriverId';
|
||||
|
||||
export interface PrizeProps {
|
||||
|
||||
@@ -78,9 +78,9 @@ export class Sponsor implements IEntity<SponsorId> {
|
||||
id: this.id,
|
||||
name,
|
||||
contactEmail,
|
||||
logoUrl,
|
||||
websiteUrl,
|
||||
createdAt: this.createdAt,
|
||||
...(logoUrl !== undefined ? { logoUrl } : {}),
|
||||
...(websiteUrl !== undefined ? { websiteUrl } : {}),
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -4,13 +4,14 @@
|
||||
* Defines operations for Prize entity persistence
|
||||
*/
|
||||
|
||||
import type { Prize, PrizeStatus } from '../entities/Prize';
|
||||
import type { Prize } from '../entities/prize/Prize';
|
||||
import type { PrizeStatusValue } from '../entities/prize/PrizeStatus';
|
||||
|
||||
export interface IPrizeRepository {
|
||||
findById(id: string): Promise<Prize | null>;
|
||||
findBySeasonId(seasonId: string): Promise<Prize[]>;
|
||||
findByDriverId(driverId: string): Promise<Prize[]>;
|
||||
findByStatus(status: PrizeStatus): Promise<Prize[]>;
|
||||
findByStatus(status: PrizeStatusValue): Promise<Prize[]>;
|
||||
findBySeasonAndPosition(seasonId: string, position: number): Promise<Prize | null>;
|
||||
create(prize: Prize): Promise<Prize>;
|
||||
update(prize: Prize): Promise<Prize>;
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* Defines operations for Sponsor aggregate persistence
|
||||
*/
|
||||
|
||||
import type { Sponsor } from '../entities/Sponsor';
|
||||
import type { Sponsor } from '../entities/sponsor/Sponsor';
|
||||
|
||||
export interface ISponsorRepository {
|
||||
findById(id: string): Promise<Sponsor | null>;
|
||||
|
||||
@@ -6,12 +6,12 @@ import type { SessionType } from '@core/racing/domain/types/SessionType';
|
||||
import { PointsTable } from '@core/racing/domain/value-objects/PointsTable';
|
||||
import type { BonusRule } from '@core/racing/domain/types/BonusRule';
|
||||
import type { ChampionshipConfig } from '@core/racing/domain/types/ChampionshipConfig';
|
||||
import { Result } from '@core/racing/domain/entities/Result';
|
||||
import { Result } from '@core/racing/domain/entities/result/Result';
|
||||
import type { Penalty } from '@core/racing/domain/entities/Penalty';
|
||||
import type { ChampionshipType } from '@core/racing/domain/types/ChampionshipType';
|
||||
import { makeDriverRef } from '../../testing/factories/racing/DriverRefFactory';
|
||||
import { makePointsTable } from '../../testing/factories/racing/PointsTableFactory';
|
||||
import { makeChampionshipConfig } from '../../testing/factories/racing/ChampionshipConfigFactory';
|
||||
import { makeDriverRef } from '../../../testing/factories/racing/DriverRefFactory';
|
||||
import { makePointsTable } from '../../../testing/factories/racing/PointsTableFactory';
|
||||
import { makeChampionshipConfig } from '../../../testing/factories/racing/ChampionshipConfigFactory';
|
||||
|
||||
|
||||
describe('EventScoringService', () => {
|
||||
|
||||
@@ -6,6 +6,7 @@ import { RaceTimeOfDay } from '../value-objects/RaceTimeOfDay';
|
||||
import type { Weekday } from '../types/Weekday';
|
||||
import { weekdayToIndex } from '../types/Weekday';
|
||||
import type { IDomainCalculationService } from '@core/shared/domain';
|
||||
import { RacingDomainValidationError } from '../errors/RacingDomainError';
|
||||
|
||||
function cloneDate(date: Date): Date {
|
||||
return new Date(date.getTime());
|
||||
@@ -63,15 +64,15 @@ function generateWeeklyOrEveryNWeeksSlots(
|
||||
const result: ScheduledRaceSlot[] = [];
|
||||
const recurrence = schedule.recurrence;
|
||||
const weekdays =
|
||||
recurrence.kind === 'weekly' || recurrence.kind === 'everyNWeeks'
|
||||
? recurrence.weekdays.getAll()
|
||||
recurrence.props.kind === 'weekly' || recurrence.props.kind === 'everyNWeeks'
|
||||
? recurrence.props.weekdays.getAll()
|
||||
: [];
|
||||
|
||||
if (weekdays.length === 0) {
|
||||
throw new RacingDomainValidationError('RecurrenceStrategy has no weekdays');
|
||||
}
|
||||
|
||||
const intervalWeeks = recurrence.kind === 'everyNWeeks' ? recurrence.intervalWeeks : 1;
|
||||
const intervalWeeks = recurrence.props.kind === 'everyNWeeks' ? recurrence.props.intervalWeeks : 1;
|
||||
|
||||
let anchorWeekStart = cloneDate(schedule.startDate);
|
||||
let roundNumber = 1;
|
||||
@@ -123,11 +124,11 @@ function findNthWeekdayOfMonth(base: Date, ordinal: 1 | 2 | 3 | 4, weekday: Week
|
||||
function generateMonthlySlots(schedule: SeasonSchedule, maxRounds: number): ScheduledRaceSlot[] {
|
||||
const result: ScheduledRaceSlot[] = [];
|
||||
const recurrence = schedule.recurrence;
|
||||
if (recurrence.kind !== 'monthlyNthWeekday') {
|
||||
if (recurrence.props.kind !== 'monthlyNthWeekday') {
|
||||
return result;
|
||||
}
|
||||
|
||||
const { ordinal, weekday } = recurrence.monthlyPattern;
|
||||
const { ordinal, weekday } = recurrence.props.monthlyPattern;
|
||||
let currentMonthDate = new Date(
|
||||
schedule.startDate.getFullYear(),
|
||||
schedule.startDate.getMonth(),
|
||||
@@ -168,7 +169,7 @@ export class SeasonScheduleGenerator {
|
||||
|
||||
const recurrence: RecurrenceStrategy = schedule.recurrence;
|
||||
|
||||
if (recurrence.kind === 'monthlyNthWeekday') {
|
||||
if (recurrence.props.kind === 'monthlyNthWeekday') {
|
||||
return generateMonthlySlots(schedule, maxRounds);
|
||||
}
|
||||
|
||||
|
||||
@@ -4,12 +4,12 @@
|
||||
* Utility functions for working with league membership roles.
|
||||
*/
|
||||
|
||||
import type { MembershipRole } from '../entities/LeagueMembership';
|
||||
import type { MembershipRoleValue } from '../entities/MembershipRole';
|
||||
|
||||
/**
|
||||
* Role hierarchy (higher number = more authority)
|
||||
*/
|
||||
const ROLE_HIERARCHY: Record<MembershipRole, number> = {
|
||||
const ROLE_HIERARCHY: Record<MembershipRoleValue, number> = {
|
||||
member: 0,
|
||||
steward: 1,
|
||||
admin: 2,
|
||||
@@ -19,21 +19,21 @@ const ROLE_HIERARCHY: Record<MembershipRole, number> = {
|
||||
/**
|
||||
* Check if a role is at least steward level
|
||||
*/
|
||||
export function isLeagueStewardOrHigherRole(role: MembershipRole): boolean {
|
||||
export function isLeagueStewardOrHigherRole(role: MembershipRoleValue): boolean {
|
||||
return ROLE_HIERARCHY[role] >= ROLE_HIERARCHY.steward;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a role is at least admin level
|
||||
*/
|
||||
export function isLeagueAdminOrHigherRole(role: MembershipRole): boolean {
|
||||
export function isLeagueAdminOrHigherRole(role: MembershipRoleValue): boolean {
|
||||
return ROLE_HIERARCHY[role] >= ROLE_HIERARCHY.admin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a role is owner
|
||||
*/
|
||||
export function isLeagueOwnerRole(role: MembershipRole): boolean {
|
||||
export function isLeagueOwnerRole(role: MembershipRoleValue): boolean {
|
||||
return role === 'owner';
|
||||
}
|
||||
|
||||
@@ -41,33 +41,33 @@ export function isLeagueOwnerRole(role: MembershipRole): boolean {
|
||||
* Compare two roles
|
||||
* Returns positive if role1 > role2, negative if role1 < role2, 0 if equal
|
||||
*/
|
||||
export function compareRoles(role1: MembershipRole, role2: MembershipRole): number {
|
||||
export function compareRoles(role1: MembershipRoleValue, role2: MembershipRoleValue): number {
|
||||
return ROLE_HIERARCHY[role1] - ROLE_HIERARCHY[role2];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get role display name
|
||||
*/
|
||||
export function getRoleDisplayName(role: MembershipRole): string {
|
||||
const names: Record<MembershipRole, string> = {
|
||||
export function getRoleDisplayName(role: MembershipRoleValue): string {
|
||||
const names: Record<MembershipRoleValue, string> = {
|
||||
member: 'Member',
|
||||
steward: 'Steward',
|
||||
admin: 'Admin',
|
||||
owner: 'Owner',
|
||||
};
|
||||
return names[role];
|
||||
return names[role] || role;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all roles in order of hierarchy
|
||||
*/
|
||||
export function getAllRolesOrdered(): MembershipRole[] {
|
||||
export function getAllRolesOrdered(): MembershipRoleValue[] {
|
||||
return ['member', 'steward', 'admin', 'owner'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get roles that can be assigned (excludes owner as it's transferred, not assigned)
|
||||
*/
|
||||
export function getAssignableRoles(): MembershipRole[] {
|
||||
export function getAssignableRoles(): MembershipRoleValue[] {
|
||||
return ['member', 'steward', 'admin'];
|
||||
}
|
||||
21
core/racing/domain/types/LeagueScoringPreset.ts
Normal file
21
core/racing/domain/types/LeagueScoringPreset.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
/**
|
||||
* Domain Types: LeagueScoringPreset
|
||||
*
|
||||
* Local type definition for league scoring presets to avoid cross-module dependencies
|
||||
*/
|
||||
|
||||
export type LeagueScoringPresetPrimaryChampionshipType =
|
||||
| 'driver'
|
||||
| 'team'
|
||||
| 'nations'
|
||||
| 'trophy';
|
||||
|
||||
export interface LeagueScoringPreset {
|
||||
id: string;
|
||||
name: string;
|
||||
description: string;
|
||||
primaryChampionshipType: LeagueScoringPresetPrimaryChampionshipType;
|
||||
dropPolicySummary: string;
|
||||
sessionSummary: string;
|
||||
bonusSummary: string;
|
||||
}
|
||||
@@ -104,10 +104,10 @@ export class RaceIncidents implements IValueObject<IncidentRecord[]> {
|
||||
|
||||
return sortedThis.every((incident, index) => {
|
||||
const otherIncident = sortedOther[index];
|
||||
return incident.type === otherIncident.type &&
|
||||
incident.lap === otherIncident.lap &&
|
||||
incident.description === otherIncident.description &&
|
||||
incident.penaltyPoints === otherIncident.penaltyPoints;
|
||||
return incident.type === otherIncident?.type &&
|
||||
incident.lap === otherIncident?.lap &&
|
||||
incident.description === otherIncident?.description &&
|
||||
incident.penaltyPoints === otherIncident?.penaltyPoints;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user