resolve manual DTOs
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { Controller, Get, Post, Body, HttpCode, HttpStatus, Param } from '@nestjs/common';
|
||||
import { Controller, Get, Post, Body, HttpCode, HttpStatus, Param, Query } from '@nestjs/common';
|
||||
import { ApiTags, ApiResponse, ApiOperation } from '@nestjs/swagger';
|
||||
import { SponsorService } from './SponsorService';
|
||||
import { GetEntitySponsorshipPricingResultDTO } from './dtos/GetEntitySponsorshipPricingResultDTO';
|
||||
@@ -9,6 +9,10 @@ import { GetSponsorDashboardQueryParamsDTO } from './dtos/GetSponsorDashboardQue
|
||||
import { SponsorDashboardDTO } from './dtos/SponsorDashboardDTO';
|
||||
import { GetSponsorSponsorshipsQueryParamsDTO } from './dtos/GetSponsorSponsorshipsQueryParamsDTO';
|
||||
import { SponsorSponsorshipsDTO } from './dtos/SponsorSponsorshipsDTO';
|
||||
import { GetSponsorOutputDTO } from './dtos/GetSponsorOutputDTO';
|
||||
import { GetPendingSponsorshipRequestsOutputDTO } from './dtos/GetPendingSponsorshipRequestsOutputDTO';
|
||||
import { AcceptSponsorshipRequestInputDTO } from './dtos/AcceptSponsorshipRequestInputDTO';
|
||||
import { RejectSponsorshipRequestInputDTO } from './dtos/RejectSponsorshipRequestInputDTO';
|
||||
|
||||
@ApiTags('sponsors')
|
||||
@Controller('sponsors')
|
||||
@@ -52,4 +56,39 @@ export class SponsorController {
|
||||
async getSponsorSponsorships(@Param('sponsorId') sponsorId: string): Promise<SponsorSponsorshipsDTO | null> {
|
||||
return this.sponsorService.getSponsorSponsorships({ sponsorId } as GetSponsorSponsorshipsQueryParamsDTO);
|
||||
}
|
||||
|
||||
@Get(':sponsorId')
|
||||
@ApiOperation({ summary: 'Get a sponsor by ID' })
|
||||
@ApiResponse({ status: 200, description: 'Sponsor data', type: GetSponsorOutputDTO })
|
||||
@ApiResponse({ status: 404, description: 'Sponsor not found' })
|
||||
async getSponsor(@Param('sponsorId') sponsorId: string): Promise<GetSponsorOutputDTO | null> {
|
||||
return this.sponsorService.getSponsor(sponsorId);
|
||||
}
|
||||
|
||||
@Get('requests')
|
||||
@ApiOperation({ summary: 'Get pending sponsorship requests' })
|
||||
@ApiResponse({ status: 200, description: 'List of pending sponsorship requests', type: GetPendingSponsorshipRequestsOutputDTO })
|
||||
async getPendingSponsorshipRequests(@Query() query: { entityType: string; entityId: string }): Promise<GetPendingSponsorshipRequestsOutputDTO> {
|
||||
return this.sponsorService.getPendingSponsorshipRequests(query);
|
||||
}
|
||||
|
||||
@Post('requests/:requestId/accept')
|
||||
@HttpCode(HttpStatus.OK)
|
||||
@ApiOperation({ summary: 'Accept a sponsorship request' })
|
||||
@ApiResponse({ status: 200, description: 'Sponsorship request accepted' })
|
||||
@ApiResponse({ status: 400, description: 'Invalid request' })
|
||||
@ApiResponse({ status: 404, description: 'Request not found' })
|
||||
async acceptSponsorshipRequest(@Param('requestId') requestId: string, @Body() input: AcceptSponsorshipRequestInputDTO): Promise<any> {
|
||||
return this.sponsorService.acceptSponsorshipRequest(requestId, input.respondedBy);
|
||||
}
|
||||
|
||||
@Post('requests/:requestId/reject')
|
||||
@HttpCode(HttpStatus.OK)
|
||||
@ApiOperation({ summary: 'Reject a sponsorship request' })
|
||||
@ApiResponse({ status: 200, description: 'Sponsorship request rejected' })
|
||||
@ApiResponse({ status: 400, description: 'Invalid request' })
|
||||
@ApiResponse({ status: 404, description: 'Request not found' })
|
||||
async rejectSponsorshipRequest(@Param('requestId') requestId: string, @Body() input: RejectSponsorshipRequestInputDTO): Promise<any> {
|
||||
return this.sponsorService.rejectSponsorshipRequest(requestId, input.respondedBy, input.reason);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,10 @@ import { CreateSponsorUseCase } from '@core/racing/application/use-cases/CreateS
|
||||
import { GetSponsorDashboardUseCase } from '@core/racing/application/use-cases/GetSponsorDashboardUseCase';
|
||||
import { GetSponsorSponsorshipsUseCase } from '@core/racing/application/use-cases/GetSponsorSponsorshipsUseCase';
|
||||
import { GetEntitySponsorshipPricingUseCase } from '@core/racing/application/use-cases/GetEntitySponsorshipPricingUseCase';
|
||||
import { GetSponsorUseCase } from '@core/racing/application/use-cases/GetSponsorUseCase';
|
||||
import { GetPendingSponsorshipRequestsUseCase } from '@core/racing/application/use-cases/GetPendingSponsorshipRequestsUseCase';
|
||||
import { AcceptSponsorshipRequestUseCase } from '@core/racing/application/use-cases/AcceptSponsorshipRequestUseCase';
|
||||
import { RejectSponsorshipRequestUseCase } from '@core/racing/application/use-cases/RejectSponsorshipRequestUseCase';
|
||||
|
||||
// Import concrete in-memory implementations
|
||||
import { InMemorySponsorRepository } from '@adapters/racing/persistence/inmemory/InMemorySponsorRepository';
|
||||
@@ -49,6 +53,10 @@ export const CREATE_SPONSOR_USE_CASE_TOKEN = 'CreateSponsorUseCase';
|
||||
export const GET_SPONSOR_DASHBOARD_USE_CASE_TOKEN = 'GetSponsorDashboardUseCase';
|
||||
export const GET_SPONSOR_SPONSORSHIPS_USE_CASE_TOKEN = 'GetSponsorSponsorshipsUseCase';
|
||||
export const GET_ENTITY_SPONSORSHIP_PRICING_USE_CASE_TOKEN = 'GetEntitySponsorshipPricingUseCase';
|
||||
export const GET_SPONSOR_USE_CASE_TOKEN = 'GetSponsorUseCase';
|
||||
export const GET_PENDING_SPONSORSHIP_REQUESTS_USE_CASE_TOKEN = 'GetPendingSponsorshipRequestsUseCase';
|
||||
export const ACCEPT_SPONSORSHIP_REQUEST_USE_CASE_TOKEN = 'AcceptSponsorshipRequestUseCase';
|
||||
export const REJECT_SPONSORSHIP_REQUEST_USE_CASE_TOKEN = 'RejectSponsorshipRequestUseCase';
|
||||
|
||||
export const SponsorProviders: Provider[] = [
|
||||
SponsorService,
|
||||
@@ -131,4 +139,27 @@ export const SponsorProviders: Provider[] = [
|
||||
new GetEntitySponsorshipPricingUseCase(sponsorshipPricingRepo, sponsorshipRequestRepo, seasonSponsorshipRepo, logger),
|
||||
inject: [SPONSORSHIP_PRICING_REPOSITORY_TOKEN, SPONSORSHIP_REQUEST_REPOSITORY_TOKEN, SEASON_SPONSORSHIP_REPOSITORY_TOKEN, LOGGER_TOKEN],
|
||||
},
|
||||
{
|
||||
provide: GET_SPONSOR_USE_CASE_TOKEN,
|
||||
useFactory: (sponsorRepo: ISponsorRepository) => new GetSponsorUseCase(sponsorRepo),
|
||||
inject: [SPONSOR_REPOSITORY_TOKEN],
|
||||
},
|
||||
{
|
||||
provide: GET_PENDING_SPONSORSHIP_REQUESTS_USE_CASE_TOKEN,
|
||||
useFactory: (sponsorshipRequestRepo: ISponsorshipRequestRepository, sponsorRepo: ISponsorRepository) =>
|
||||
new GetPendingSponsorshipRequestsUseCase(sponsorshipRequestRepo, sponsorRepo),
|
||||
inject: [SPONSORSHIP_REQUEST_REPOSITORY_TOKEN, SPONSOR_REPOSITORY_TOKEN],
|
||||
},
|
||||
{
|
||||
provide: ACCEPT_SPONSORSHIP_REQUEST_USE_CASE_TOKEN,
|
||||
useFactory: (sponsorshipRequestRepo: ISponsorshipRequestRepository, seasonSponsorshipRepo: ISeasonSponsorshipRepository, seasonRepo: ISeasonRepository, notificationService: any, paymentGateway: any, walletRepository: any, leagueWalletRepository: any, logger: Logger) =>
|
||||
new AcceptSponsorshipRequestUseCase(sponsorshipRequestRepo, seasonSponsorshipRepo, seasonRepo, notificationService, paymentGateway, walletRepository, leagueWalletRepository, logger),
|
||||
inject: [SPONSORSHIP_REQUEST_REPOSITORY_TOKEN, SEASON_SPONSORSHIP_REPOSITORY_TOKEN, SEASON_REPOSITORY_TOKEN, 'INotificationService', 'IPaymentGateway', 'IWalletRepository', 'ILeagueWalletRepository', LOGGER_TOKEN],
|
||||
},
|
||||
{
|
||||
provide: REJECT_SPONSORSHIP_REQUEST_USE_CASE_TOKEN,
|
||||
useFactory: (sponsorshipRequestRepo: ISponsorshipRequestRepository, logger: Logger) =>
|
||||
new RejectSponsorshipRequestUseCase(sponsorshipRequestRepo, logger),
|
||||
inject: [SPONSORSHIP_REQUEST_REPOSITORY_TOKEN, LOGGER_TOKEN],
|
||||
},
|
||||
];
|
||||
|
||||
@@ -7,6 +7,10 @@ import { GetSponsorDashboardQueryParamsDTO } from './dtos/GetSponsorDashboardQue
|
||||
import { SponsorDashboardDTO } from './dtos/SponsorDashboardDTO';
|
||||
import { GetSponsorSponsorshipsQueryParamsDTO } from './dtos/GetSponsorSponsorshipsQueryParamsDTO';
|
||||
import { SponsorSponsorshipsDTO } from './dtos/SponsorSponsorshipsDTO';
|
||||
import { GetSponsorOutputDTO } from './dtos/GetSponsorOutputDTO';
|
||||
import { GetPendingSponsorshipRequestsOutputDTO } from './dtos/GetPendingSponsorshipRequestsOutputDTO';
|
||||
import { AcceptSponsorshipRequestInputDTO } from './dtos/AcceptSponsorshipRequestInputDTO';
|
||||
import { RejectSponsorshipRequestInputDTO } from './dtos/RejectSponsorshipRequestInputDTO';
|
||||
import { SponsorDTO } from './dtos/SponsorDTO';
|
||||
import { SponsorDashboardMetricsDTO } from './dtos/SponsorDashboardMetricsDTO';
|
||||
import { SponsoredLeagueDTO } from './dtos/SponsoredLeagueDTO';
|
||||
@@ -19,6 +23,10 @@ import { GetSponsorsUseCase } from '@core/racing/application/use-cases/GetSponso
|
||||
import { CreateSponsorUseCase } from '@core/racing/application/use-cases/CreateSponsorUseCase';
|
||||
import { GetSponsorDashboardUseCase } from '@core/racing/application/use-cases/GetSponsorDashboardUseCase';
|
||||
import { GetSponsorSponsorshipsUseCase } from '@core/racing/application/use-cases/GetSponsorSponsorshipsUseCase';
|
||||
import { GetSponsorUseCase } from '@core/racing/application/use-cases/GetSponsorUseCase';
|
||||
import { GetPendingSponsorshipRequestsUseCase } from '@core/racing/application/use-cases/GetPendingSponsorshipRequestsUseCase';
|
||||
import { AcceptSponsorshipRequestUseCase } from '@core/racing/application/use-cases/AcceptSponsorshipRequestUseCase';
|
||||
import { RejectSponsorshipRequestUseCase } from '@core/racing/application/use-cases/RejectSponsorshipRequestUseCase';
|
||||
|
||||
// Presenters
|
||||
import { GetSponsorshipPricingPresenter } from './presenters/GetSponsorshipPricingPresenter';
|
||||
@@ -28,7 +36,7 @@ import { GetSponsorDashboardPresenter } from './presenters/GetSponsorDashboardPr
|
||||
import { GetSponsorSponsorshipsPresenter } from './presenters/GetSponsorSponsorshipsPresenter';
|
||||
|
||||
// Tokens
|
||||
import { GET_SPONSORSHIP_PRICING_USE_CASE_TOKEN, GET_SPONSORS_USE_CASE_TOKEN, CREATE_SPONSOR_USE_CASE_TOKEN, GET_SPONSOR_DASHBOARD_USE_CASE_TOKEN, GET_SPONSOR_SPONSORSHIPS_USE_CASE_TOKEN, LOGGER_TOKEN } from './SponsorProviders';
|
||||
import { GET_SPONSORSHIP_PRICING_USE_CASE_TOKEN, GET_SPONSORS_USE_CASE_TOKEN, CREATE_SPONSOR_USE_CASE_TOKEN, GET_SPONSOR_DASHBOARD_USE_CASE_TOKEN, GET_SPONSOR_SPONSORSHIPS_USE_CASE_TOKEN, GET_SPONSOR_USE_CASE_TOKEN, GET_PENDING_SPONSORSHIP_REQUESTS_USE_CASE_TOKEN, ACCEPT_SPONSORSHIP_REQUEST_USE_CASE_TOKEN, REJECT_SPONSORSHIP_REQUEST_USE_CASE_TOKEN, LOGGER_TOKEN } from './SponsorProviders';
|
||||
import type { Logger } from '@core/shared/application';
|
||||
|
||||
@Injectable()
|
||||
@@ -39,6 +47,10 @@ export class SponsorService {
|
||||
@Inject(CREATE_SPONSOR_USE_CASE_TOKEN) private readonly createSponsorUseCase: CreateSponsorUseCase,
|
||||
@Inject(GET_SPONSOR_DASHBOARD_USE_CASE_TOKEN) private readonly getSponsorDashboardUseCase: GetSponsorDashboardUseCase,
|
||||
@Inject(GET_SPONSOR_SPONSORSHIPS_USE_CASE_TOKEN) private readonly getSponsorSponsorshipsUseCase: GetSponsorSponsorshipsUseCase,
|
||||
@Inject(GET_SPONSOR_USE_CASE_TOKEN) private readonly getSponsorUseCase: GetSponsorUseCase,
|
||||
@Inject(GET_PENDING_SPONSORSHIP_REQUESTS_USE_CASE_TOKEN) private readonly getPendingSponsorshipRequestsUseCase: GetPendingSponsorshipRequestsUseCase,
|
||||
@Inject(ACCEPT_SPONSORSHIP_REQUEST_USE_CASE_TOKEN) private readonly acceptSponsorshipRequestUseCase: AcceptSponsorshipRequestUseCase,
|
||||
@Inject(REJECT_SPONSORSHIP_REQUEST_USE_CASE_TOKEN) private readonly rejectSponsorshipRequestUseCase: RejectSponsorshipRequestUseCase,
|
||||
@Inject(LOGGER_TOKEN) private readonly logger: Logger,
|
||||
) {}
|
||||
|
||||
@@ -81,4 +93,48 @@ export class SponsorService {
|
||||
await this.getSponsorSponsorshipsUseCase.execute(params, presenter);
|
||||
return presenter.viewModel as SponsorSponsorshipsDTO | null;
|
||||
}
|
||||
|
||||
async getSponsor(sponsorId: string): Promise<GetSponsorOutputDTO | null> {
|
||||
this.logger.debug('[SponsorService] Fetching sponsor.', { sponsorId });
|
||||
|
||||
const result = await this.getSponsorUseCase.execute({ sponsorId });
|
||||
if (result.isErr()) {
|
||||
this.logger.error('[SponsorService] Failed to fetch sponsor.', result.error);
|
||||
return null;
|
||||
}
|
||||
return result.value as GetSponsorOutputDTO | null;
|
||||
}
|
||||
|
||||
async getPendingSponsorshipRequests(params: { entityType: string; entityId: string }): Promise<GetPendingSponsorshipRequestsOutputDTO> {
|
||||
this.logger.debug('[SponsorService] Fetching pending sponsorship requests.', { params });
|
||||
|
||||
const result = await this.getPendingSponsorshipRequestsUseCase.execute(params as any);
|
||||
if (result.isErr()) {
|
||||
this.logger.error('[SponsorService] Failed to fetch pending sponsorship requests.', result.error);
|
||||
return { entityType: params.entityType as any, entityId: params.entityId, requests: [], totalCount: 0 };
|
||||
}
|
||||
return result.value as GetPendingSponsorshipRequestsOutputDTO;
|
||||
}
|
||||
|
||||
async acceptSponsorshipRequest(requestId: string, respondedBy: string): Promise<{ requestId: string; sponsorshipId: string; status: string; acceptedAt: Date; platformFee: number; netAmount: number } | null> {
|
||||
this.logger.debug('[SponsorService] Accepting sponsorship request.', { requestId, respondedBy });
|
||||
|
||||
const result = await this.acceptSponsorshipRequestUseCase.execute({ requestId, respondedBy });
|
||||
if (result.isErr()) {
|
||||
this.logger.error('[SponsorService] Failed to accept sponsorship request.', result.error);
|
||||
return null;
|
||||
}
|
||||
return result.value;
|
||||
}
|
||||
|
||||
async rejectSponsorshipRequest(requestId: string, respondedBy: string, reason?: string): Promise<{ requestId: string; status: string; rejectedAt: Date } | null> {
|
||||
this.logger.debug('[SponsorService] Rejecting sponsorship request.', { requestId, respondedBy, reason });
|
||||
|
||||
const result = await this.rejectSponsorshipRequestUseCase.execute({ requestId, respondedBy, reason });
|
||||
if (result.isErr()) {
|
||||
this.logger.error('[SponsorService] Failed to reject sponsorship request.', result.error);
|
||||
return null;
|
||||
}
|
||||
return result.value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import { IsString, IsNotEmpty } from 'class-validator';
|
||||
|
||||
export class AcceptSponsorshipRequestInputDTO {
|
||||
@ApiProperty()
|
||||
@IsString()
|
||||
@IsNotEmpty()
|
||||
respondedBy: string;
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import { SponsorshipRequestDTO } from './SponsorshipRequestDTO';
|
||||
|
||||
export class GetPendingSponsorshipRequestsOutputDTO {
|
||||
@ApiProperty()
|
||||
entityType: string;
|
||||
|
||||
@ApiProperty()
|
||||
entityId: string;
|
||||
|
||||
@ApiProperty({ type: [SponsorshipRequestDTO] })
|
||||
requests: SponsorshipRequestDTO[];
|
||||
|
||||
@ApiProperty()
|
||||
totalCount: number;
|
||||
}
|
||||
7
apps/api/src/domain/sponsor/dtos/GetSponsorOutputDTO.ts
Normal file
7
apps/api/src/domain/sponsor/dtos/GetSponsorOutputDTO.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import { SponsorDTO } from './SponsorDTO';
|
||||
|
||||
export class GetSponsorOutputDTO {
|
||||
@ApiProperty({ type: SponsorDTO })
|
||||
sponsor: SponsorDTO;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import { IsString, IsNotEmpty, IsOptional } from 'class-validator';
|
||||
|
||||
export class RejectSponsorshipRequestInputDTO {
|
||||
@ApiProperty()
|
||||
@IsString()
|
||||
@IsNotEmpty()
|
||||
respondedBy: string;
|
||||
|
||||
@ApiProperty({ required: false })
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
reason?: string;
|
||||
}
|
||||
15
apps/api/src/domain/sponsor/dtos/SponsorDTO.ts
Normal file
15
apps/api/src/domain/sponsor/dtos/SponsorDTO.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
|
||||
export class SponsorDTO {
|
||||
@ApiProperty()
|
||||
id: string;
|
||||
|
||||
@ApiProperty()
|
||||
name: string;
|
||||
|
||||
@ApiProperty({ required: false })
|
||||
logoUrl?: string;
|
||||
|
||||
@ApiProperty({ required: false })
|
||||
websiteUrl?: string;
|
||||
}
|
||||
39
apps/api/src/domain/sponsor/dtos/SponsorshipRequestDTO.ts
Normal file
39
apps/api/src/domain/sponsor/dtos/SponsorshipRequestDTO.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
|
||||
export class SponsorshipRequestDTO {
|
||||
@ApiProperty()
|
||||
id: string;
|
||||
|
||||
@ApiProperty()
|
||||
sponsorId: string;
|
||||
|
||||
@ApiProperty()
|
||||
sponsorName: string;
|
||||
|
||||
@ApiProperty({ required: false })
|
||||
sponsorLogo?: string;
|
||||
|
||||
@ApiProperty()
|
||||
tier: string;
|
||||
|
||||
@ApiProperty()
|
||||
offeredAmount: number;
|
||||
|
||||
@ApiProperty()
|
||||
currency: string;
|
||||
|
||||
@ApiProperty()
|
||||
formattedAmount: string;
|
||||
|
||||
@ApiProperty({ required: false })
|
||||
message?: string;
|
||||
|
||||
@ApiProperty()
|
||||
createdAt: Date;
|
||||
|
||||
@ApiProperty()
|
||||
platformFee: number;
|
||||
|
||||
@ApiProperty()
|
||||
netAmount: number;
|
||||
}
|
||||
Reference in New Issue
Block a user