resolve todos in core

This commit is contained in:
2025-12-20 11:02:15 +01:00
parent 7bbad511e2
commit a87cf27fb9
10 changed files with 396 additions and 199 deletions

View File

@@ -1,13 +1,14 @@
import type { ILeagueWalletRepository } from '../../domain/repositories/ILeagueWalletRepository';
import type { ITransactionRepository } from '../../domain/repositories/ITransactionRepository';
import type { GetLeagueWalletOutputPort } from '../ports/output/GetLeagueWalletOutputPort';
import type { GetLeagueWalletOutputPort, WalletTransactionOutputPort } from '../ports/output/GetLeagueWalletOutputPort';
import type { TransactionType } from '../../domain/entities/league-wallet/Transaction';
import { Result } from '@core/shared/application/Result';
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
export interface GetLeagueWalletUseCaseParams {
leagueId: string;
}
/**
* Use Case for retrieving league wallet information.
*/
@@ -16,84 +17,89 @@ export class GetLeagueWalletUseCase {
private readonly leagueWalletRepository: ILeagueWalletRepository,
private readonly transactionRepository: ITransactionRepository,
) {}
async execute(
params: GetLeagueWalletUseCaseParams,
): Promise<Result<GetLeagueWalletOutputPort, ApplicationErrorCode<'REPOSITORY_ERROR'>>> {
try {
// For now, return mock data to emulate previous state
// TODO: Implement full domain logic when wallet entities are properly seeded
const mockWallet: GetLeagueWalletOutputPort = {
balance: 2450.00,
currency: 'USD',
totalRevenue: 3200.00,
totalFees: 320.00,
totalWithdrawals: 430.00,
pendingPayouts: 150.00,
canWithdraw: false,
withdrawalBlockReason: 'Season 2 is still active. Withdrawals are available after season completion.',
transactions: [
{
id: 'txn-1',
type: 'sponsorship',
description: 'Main Sponsor - TechCorp',
amount: 1200.00,
fee: 120.00,
netAmount: 1080.00,
date: '2025-12-01T00:00:00.000Z',
status: 'completed',
reference: 'SP-2025-001',
},
{
id: 'txn-2',
type: 'sponsorship',
description: 'Secondary Sponsor - RaceFuel',
amount: 400.00,
fee: 40.00,
netAmount: 360.00,
date: '2025-12-01T00:00:00.000Z',
status: 'completed',
reference: 'SP-2025-002',
},
{
id: 'txn-3',
type: 'membership',
description: 'Season Fee - 32 drivers',
amount: 1600.00,
fee: 160.00,
netAmount: 1440.00,
date: '2025-11-15T00:00:00.000Z',
status: 'completed',
reference: 'MF-2025-032',
},
{
id: 'txn-4',
type: 'withdrawal',
description: 'Bank Transfer - Season 1 Payout',
amount: -430.00,
fee: 0,
netAmount: -430.00,
date: '2025-10-30T00:00:00.000Z',
status: 'completed',
reference: 'WD-2025-001',
},
{
id: 'txn-5',
type: 'prize',
description: 'Championship Prize Pool (reserved)',
amount: -150.00,
fee: 0,
netAmount: -150.00,
date: '2025-12-05T00:00:00.000Z',
status: 'pending',
reference: 'PZ-2025-001',
},
],
const wallet = await this.leagueWalletRepository.findByLeagueId(params.leagueId);
if (!wallet) {
return Result.err({ code: 'REPOSITORY_ERROR', message: 'Wallet not found' });
}
const transactions = await this.transactionRepository.findByWalletId(wallet.id.toString());
let totalRevenue = 0;
let totalFees = 0;
let totalWithdrawals = 0;
let pendingPayouts = 0;
const transactionViewModels: WalletTransactionOutputPort[] = transactions
.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime())
.map(transaction => {
const amount = transaction.amount.amount;
const fee = transaction.platformFee.amount;
const netAmount = transaction.netAmount.amount;
if (
transaction.type === 'sponsorship_payment' ||
transaction.type === 'membership_payment' ||
transaction.type === 'prize_payout'
) {
totalRevenue += amount;
totalFees += fee;
}
if (transaction.type === 'withdrawal' && transaction.status === 'completed') {
totalWithdrawals += netAmount;
}
if (transaction.type === 'prize_payout' && transaction.status === 'pending') {
pendingPayouts += netAmount;
}
return {
id: transaction.id.toString(),
type: this.mapTransactionType(transaction.type),
description: transaction.description ?? '',
amount,
fee,
netAmount,
date: transaction.createdAt.toISOString(),
status: transaction.status === 'cancelled' ? 'failed' : transaction.status,
};
});
const output: GetLeagueWalletOutputPort = {
balance: wallet.balance.amount,
currency: wallet.balance.currency,
totalRevenue,
totalFees,
totalWithdrawals,
pendingPayouts,
canWithdraw: true,
transactions: transactionViewModels,
};
return Result.ok(mockWallet);
return Result.ok(output);
} catch {
return Result.err({ code: 'REPOSITORY_ERROR', message: 'Failed to fetch league wallet' });
}
}
private mapTransactionType(type: TransactionType): WalletTransactionOutputPort['type'] {
switch (type) {
case 'sponsorship_payment':
return 'sponsorship';
case 'membership_payment':
return 'membership';
case 'prize_payout':
return 'prize';
case 'withdrawal':
return 'withdrawal';
case 'refund':
return 'sponsorship';
}
}
}