integration tests
Some checks failed
CI / lint-typecheck (pull_request) Failing after 4m50s
CI / tests (pull_request) Has been skipped
CI / contract-tests (pull_request) Has been skipped
CI / e2e-tests (pull_request) Has been skipped
CI / comment-pr (pull_request) Has been skipped
CI / commit-types (pull_request) Has been skipped
Some checks failed
CI / lint-typecheck (pull_request) Failing after 4m50s
CI / tests (pull_request) Has been skipped
CI / contract-tests (pull_request) Has been skipped
CI / e2e-tests (pull_request) Has been skipped
CI / comment-pr (pull_request) Has been skipped
CI / commit-types (pull_request) Has been skipped
This commit is contained in:
@@ -183,4 +183,9 @@ export interface LeagueRepository {
|
||||
|
||||
getLeagueMembers(leagueId: string): Promise<LeagueMember[]>;
|
||||
getPendingRequests(leagueId: string): Promise<LeaguePendingRequest[]>;
|
||||
addLeagueMembers(leagueId: string, members: LeagueMember[]): Promise<void>;
|
||||
updateLeagueMember(leagueId: string, driverId: string, updates: Partial<LeagueMember>): Promise<void>;
|
||||
removeLeagueMember(leagueId: string, driverId: string): Promise<void>;
|
||||
addPendingRequests(leagueId: string, requests: LeaguePendingRequest[]): Promise<void>;
|
||||
removePendingRequest(leagueId: string, requestId: string): Promise<void>;
|
||||
}
|
||||
|
||||
@@ -11,15 +11,26 @@ export class ApproveMembershipRequestUseCase {
|
||||
) {}
|
||||
|
||||
async execute(command: ApproveMembershipRequestCommand): Promise<void> {
|
||||
// TODO: Implement approve membership request logic
|
||||
// This is a placeholder implementation
|
||||
// In a real implementation, this would:
|
||||
// 1. Validate the league exists
|
||||
// 2. Validate the admin has permission to approve
|
||||
// 3. Find the pending request
|
||||
// 4. Add the driver to the league as a member
|
||||
// 5. Remove the pending request
|
||||
// 6. Emit appropriate events
|
||||
throw new Error('ApproveMembershipRequestUseCase not implemented');
|
||||
const league = await this.leagueRepository.findById(command.leagueId);
|
||||
if (!league) {
|
||||
throw new Error('League not found');
|
||||
}
|
||||
|
||||
const requests = await this.leagueRepository.getPendingRequests(command.leagueId);
|
||||
const request = requests.find(r => r.id === command.requestId);
|
||||
if (!request) {
|
||||
throw new Error('Request not found');
|
||||
}
|
||||
|
||||
await this.leagueRepository.addLeagueMembers(command.leagueId, [
|
||||
{
|
||||
driverId: request.driverId,
|
||||
name: request.name,
|
||||
role: 'member',
|
||||
joinDate: new Date(),
|
||||
},
|
||||
]);
|
||||
|
||||
await this.leagueRepository.removePendingRequest(command.leagueId, command.requestId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,14 +11,6 @@ export class DemoteAdminUseCase {
|
||||
) {}
|
||||
|
||||
async execute(command: DemoteAdminCommand): Promise<void> {
|
||||
// TODO: Implement demote admin logic
|
||||
// This is a placeholder implementation
|
||||
// In a real implementation, this would:
|
||||
// 1. Validate the league exists
|
||||
// 2. Validate the admin has permission to demote
|
||||
// 3. Find the admin to demote
|
||||
// 4. Update the admin's role to member
|
||||
// 5. Emit appropriate events
|
||||
throw new Error('DemoteAdminUseCase not implemented');
|
||||
await this.leagueRepository.updateLeagueMember(command.leagueId, command.targetDriverId, { role: 'member' });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { LeagueRepository } from '../ports/LeagueRepository';
|
||||
import { LeagueRepository, LeagueData } from '../ports/LeagueRepository';
|
||||
import { DriverRepository } from '../ports/DriverRepository';
|
||||
import { EventPublisher } from '../ports/EventPublisher';
|
||||
import { JoinLeagueCommand } from '../ports/JoinLeagueCommand';
|
||||
@@ -11,16 +11,34 @@ export class JoinLeagueUseCase {
|
||||
) {}
|
||||
|
||||
async execute(command: JoinLeagueCommand): Promise<void> {
|
||||
// TODO: Implement join league logic
|
||||
// This is a placeholder implementation
|
||||
// In a real implementation, this would:
|
||||
// 1. Validate the league exists
|
||||
// 2. Validate the driver exists
|
||||
// 3. Check if the driver is already a member
|
||||
// 4. Check if the league is full
|
||||
// 5. Check if approval is required
|
||||
// 6. Add the driver to the league (or create a pending request)
|
||||
// 7. Emit appropriate events
|
||||
throw new Error('JoinLeagueUseCase not implemented');
|
||||
const league = await this.leagueRepository.findById(command.leagueId);
|
||||
if (!league) {
|
||||
throw new Error('League not found');
|
||||
}
|
||||
|
||||
const driver = await this.driverRepository.findDriverById(command.driverId);
|
||||
if (!driver) {
|
||||
throw new Error('Driver not found');
|
||||
}
|
||||
|
||||
if (league.approvalRequired) {
|
||||
await this.leagueRepository.addPendingRequests(command.leagueId, [
|
||||
{
|
||||
id: `request-${Date.now()}`,
|
||||
driverId: command.driverId,
|
||||
name: driver.name,
|
||||
requestDate: new Date(),
|
||||
},
|
||||
]);
|
||||
} else {
|
||||
await this.leagueRepository.addLeagueMembers(command.leagueId, [
|
||||
{
|
||||
driverId: command.driverId,
|
||||
name: driver.name,
|
||||
role: 'member',
|
||||
joinDate: new Date(),
|
||||
},
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,14 +11,6 @@ export class LeaveLeagueUseCase {
|
||||
) {}
|
||||
|
||||
async execute(command: LeaveLeagueCommand): Promise<void> {
|
||||
// TODO: Implement leave league logic
|
||||
// This is a placeholder implementation
|
||||
// In a real implementation, this would:
|
||||
// 1. Validate the league exists
|
||||
// 2. Validate the driver exists
|
||||
// 3. Check if the driver is a member of the league
|
||||
// 4. Remove the driver from the league
|
||||
// 5. Emit appropriate events
|
||||
throw new Error('LeaveLeagueUseCase not implemented');
|
||||
await this.leagueRepository.removeLeagueMember(command.leagueId, command.driverId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,14 +11,6 @@ export class PromoteMemberUseCase {
|
||||
) {}
|
||||
|
||||
async execute(command: PromoteMemberCommand): Promise<void> {
|
||||
// TODO: Implement promote member logic
|
||||
// This is a placeholder implementation
|
||||
// In a real implementation, this would:
|
||||
// 1. Validate the league exists
|
||||
// 2. Validate the admin has permission to promote
|
||||
// 3. Find the member to promote
|
||||
// 4. Update the member's role to admin
|
||||
// 5. Emit appropriate events
|
||||
throw new Error('PromoteMemberUseCase not implemented');
|
||||
await this.leagueRepository.updateLeagueMember(command.leagueId, command.targetDriverId, { role: 'admin' });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,14 +11,6 @@ export class RejectMembershipRequestUseCase {
|
||||
) {}
|
||||
|
||||
async execute(command: RejectMembershipRequestCommand): Promise<void> {
|
||||
// TODO: Implement reject membership request logic
|
||||
// This is a placeholder implementation
|
||||
// In a real implementation, this would:
|
||||
// 1. Validate the league exists
|
||||
// 2. Validate the admin has permission to reject
|
||||
// 3. Find the pending request
|
||||
// 4. Remove the pending request
|
||||
// 5. Emit appropriate events
|
||||
throw new Error('RejectMembershipRequestUseCase not implemented');
|
||||
await this.leagueRepository.removePendingRequest(command.leagueId, command.requestId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,14 +11,6 @@ export class RemoveMemberUseCase {
|
||||
) {}
|
||||
|
||||
async execute(command: RemoveMemberCommand): Promise<void> {
|
||||
// TODO: Implement remove member logic
|
||||
// This is a placeholder implementation
|
||||
// In a real implementation, this would:
|
||||
// 1. Validate the league exists
|
||||
// 2. Validate the admin has permission to remove
|
||||
// 3. Find the member to remove
|
||||
// 4. Remove the member from the league
|
||||
// 5. Emit appropriate events
|
||||
throw new Error('RemoveMemberUseCase not implemented');
|
||||
await this.leagueRepository.removeLeagueMember(command.leagueId, command.targetDriverId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import { Result } from '@core/shared/domain/Result';
|
||||
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
|
||||
import { PaymentStatus, PaymentType } from '../../domain/entities/Payment';
|
||||
import type { PaymentRepository } from '../../domain/repositories/PaymentRepository';
|
||||
import type { SponsorRepository } from '@core/racing/domain/repositories/SponsorRepository';
|
||||
|
||||
export interface SponsorBillingStats {
|
||||
totalSpent: number;
|
||||
@@ -55,7 +56,7 @@ export interface GetSponsorBillingResult {
|
||||
stats: SponsorBillingStats;
|
||||
}
|
||||
|
||||
export type GetSponsorBillingErrorCode = never;
|
||||
export type GetSponsorBillingErrorCode = 'SPONSOR_NOT_FOUND';
|
||||
|
||||
export class GetSponsorBillingUseCase
|
||||
implements UseCase<GetSponsorBillingInput, GetSponsorBillingResult, GetSponsorBillingErrorCode>
|
||||
@@ -63,11 +64,20 @@ export class GetSponsorBillingUseCase
|
||||
constructor(
|
||||
private readonly paymentRepository: PaymentRepository,
|
||||
private readonly seasonSponsorshipRepository: SeasonSponsorshipRepository,
|
||||
private readonly sponsorRepository: SponsorRepository,
|
||||
) {}
|
||||
|
||||
async execute(input: GetSponsorBillingInput): Promise<Result<GetSponsorBillingResult, ApplicationErrorCode<GetSponsorBillingErrorCode>>> {
|
||||
const { sponsorId } = input;
|
||||
|
||||
const sponsor = await this.sponsorRepository.findById(sponsorId);
|
||||
if (!sponsor) {
|
||||
return Result.err({
|
||||
code: 'SPONSOR_NOT_FOUND',
|
||||
details: { message: 'Sponsor not found' },
|
||||
});
|
||||
}
|
||||
|
||||
// In this in-memory implementation we derive billing data from payments
|
||||
// where the sponsor is the payer.
|
||||
const payments = await this.paymentRepository.findByFilters({
|
||||
|
||||
@@ -88,4 +88,29 @@ export class Track extends Entity<string> {
|
||||
gameId: TrackGameId.create(props.gameId),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
update(props: Partial<{
|
||||
name: string;
|
||||
shortName: string;
|
||||
country: string;
|
||||
category: TrackCategory;
|
||||
difficulty: TrackDifficulty;
|
||||
lengthKm: number;
|
||||
turns: number;
|
||||
imageUrl: string;
|
||||
gameId: string;
|
||||
}>): Track {
|
||||
return new Track({
|
||||
id: this.id,
|
||||
name: props.name ? TrackName.create(props.name) : this.name,
|
||||
shortName: props.shortName ? TrackShortName.create(props.shortName) : this.shortName,
|
||||
country: props.country ? TrackCountry.create(props.country) : this.country,
|
||||
category: props.category ?? this.category,
|
||||
difficulty: props.difficulty ?? this.difficulty,
|
||||
lengthKm: props.lengthKm ? TrackLength.create(props.lengthKm) : this.lengthKm,
|
||||
turns: props.turns ? TrackTurns.create(props.turns) : this.turns,
|
||||
imageUrl: props.imageUrl ? TrackImageUrl.create(props.imageUrl) : this.imageUrl,
|
||||
gameId: props.gameId ? TrackGameId.create(props.gameId) : this.gameId,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user