refactor
This commit is contained in:
@@ -1,162 +1,72 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { GetEntitySponsorshipPricingResultDto, SponsorDto, GetSponsorsOutput, CreateSponsorInput, CreateSponsorOutput, GetSponsorDashboardQueryParams, SponsorDashboardDTO, GetSponsorSponsorshipsQueryParams, SponsorshipDetailDTO, SponsorSponsorshipsDTO, SponsoredLeagueDTO, SponsorDashboardMetricsDTO, SponsorDashboardInvestmentDTO } from './dto/SponsorDto';
|
||||
import { Injectable, Inject } from '@nestjs/common';
|
||||
import { GetEntitySponsorshipPricingResultDto, GetSponsorsOutput, CreateSponsorInput, CreateSponsorOutput, GetSponsorDashboardQueryParams, SponsorDashboardDTO, GetSponsorSponsorshipsQueryParams, SponsorSponsorshipsDTO, SponsorDto, SponsorDashboardMetricsDTO, SponsoredLeagueDTO, SponsorDashboardInvestmentDTO, SponsorshipDetailDTO } from './dto/SponsorDto';
|
||||
|
||||
const sponsors: Map<string, SponsorDto> = new Map();
|
||||
// Use cases
|
||||
import { GetSponsorshipPricingUseCase } from '@gridpilot/racing/application/use-cases/GetSponsorshipPricingUseCase';
|
||||
import { GetSponsorsUseCase } from '@gridpilot/racing/application/use-cases/GetSponsorsUseCase';
|
||||
import { CreateSponsorUseCase } from '@gridpilot/racing/application/use-cases/CreateSponsorUseCase';
|
||||
import { GetSponsorDashboardUseCase } from '@gridpilot/racing/application/use-cases/GetSponsorDashboardUseCase';
|
||||
import { GetSponsorSponsorshipsUseCase } from '@gridpilot/racing/application/use-cases/GetSponsorSponsorshipsUseCase';
|
||||
|
||||
// Presenters
|
||||
import { GetSponsorshipPricingPresenter } from './presenters/GetSponsorshipPricingPresenter';
|
||||
import { GetSponsorsPresenter } from './presenters/GetSponsorsPresenter';
|
||||
import { CreateSponsorPresenter } from './presenters/CreateSponsorPresenter';
|
||||
import { GetSponsorDashboardPresenter } from './presenters/GetSponsorDashboardPresenter';
|
||||
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 { Logger } from '@gridpilot/shared/application';
|
||||
|
||||
@Injectable()
|
||||
export class SponsorService {
|
||||
constructor(
|
||||
@Inject(GET_SPONSORSHIP_PRICING_USE_CASE_TOKEN) private readonly getSponsorshipPricingUseCase: GetSponsorshipPricingUseCase,
|
||||
@Inject(GET_SPONSORS_USE_CASE_TOKEN) private readonly getSponsorsUseCase: GetSponsorsUseCase,
|
||||
@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(LOGGER_TOKEN) private readonly logger: Logger,
|
||||
) {}
|
||||
|
||||
constructor() {
|
||||
// Seed some demo sponsors for dashboard if empty
|
||||
if (sponsors.size === 0) {
|
||||
const demoSponsor1: SponsorDto = {
|
||||
id: 'sponsor-demo-1',
|
||||
name: 'Demo Sponsor Co.',
|
||||
contactEmail: 'contact@demosponsor.com',
|
||||
websiteUrl: 'https://demosponsor.com',
|
||||
logoUrl: 'https://fakeimg.pl/200x100/aaaaaa/ffffff?text=DemoCo',
|
||||
createdAt: new Date(),
|
||||
};
|
||||
const demoSponsor2: SponsorDto = {
|
||||
id: 'sponsor-demo-2',
|
||||
name: 'Second Brand',
|
||||
contactEmail: 'info@secondbrand.net',
|
||||
websiteUrl: 'https://secondbrand.net',
|
||||
logoUrl: 'https://fakeimg.pl/200x100/cccccc/ffffff?text=Brand2',
|
||||
createdAt: new Date(Date.now() - 86400000 * 5),
|
||||
};
|
||||
sponsors.set(demoSponsor1.id, demoSponsor1);
|
||||
sponsors.set(demoSponsor2.id, demoSponsor2);
|
||||
}
|
||||
}
|
||||
async getEntitySponsorshipPricing(): Promise<GetEntitySponsorshipPricingResultDto> {
|
||||
this.logger.debug('[SponsorService] Fetching sponsorship pricing.');
|
||||
|
||||
getEntitySponsorshipPricing(): Promise<GetEntitySponsorshipPricingResultDto> {
|
||||
// This logic relies on external factors (e.g., pricing configuration, entity type)
|
||||
// For now, return mock data
|
||||
return Promise.resolve({
|
||||
pricing: [
|
||||
{ id: 'tier-bronze', level: 'Bronze', price: 100, currency: 'USD' },
|
||||
{ id: 'tier-silver', level: 'Silver', price: 250, currency: 'USD' },
|
||||
{ id: 'tier-gold', level: 'Gold', price: 500, currency: 'USD' },
|
||||
],
|
||||
});
|
||||
const presenter = new GetSponsorshipPricingPresenter();
|
||||
await this.getSponsorshipPricingUseCase.execute(undefined, presenter);
|
||||
return presenter.viewModel;
|
||||
}
|
||||
|
||||
async getSponsors(): Promise<GetSponsorsOutput> {
|
||||
return { sponsors: Array.from(sponsors.values()) };
|
||||
this.logger.debug('[SponsorService] Fetching sponsors.');
|
||||
|
||||
const presenter = new GetSponsorsPresenter();
|
||||
await this.getSponsorsUseCase.execute(undefined, presenter);
|
||||
return presenter.viewModel;
|
||||
}
|
||||
|
||||
async createSponsor(input: CreateSponsorInput): Promise<CreateSponsorOutput> {
|
||||
const id = `sponsor-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
||||
const newSponsor: SponsorDto = {
|
||||
id,
|
||||
name: input.name,
|
||||
contactEmail: input.contactEmail,
|
||||
websiteUrl: input.websiteUrl,
|
||||
logoUrl: input.logoUrl,
|
||||
createdAt: new Date(),
|
||||
};
|
||||
sponsors.set(id, newSponsor);
|
||||
return { sponsor: newSponsor };
|
||||
this.logger.debug('[SponsorService] Creating sponsor.', { input });
|
||||
|
||||
const presenter = new CreateSponsorPresenter();
|
||||
await this.createSponsorUseCase.execute(input, presenter);
|
||||
return presenter.viewModel;
|
||||
}
|
||||
|
||||
async getSponsorDashboard(params: GetSponsorDashboardQueryParams): Promise<SponsorDashboardDTO | null> {
|
||||
const { sponsorId } = params;
|
||||
this.logger.debug('[SponsorService] Fetching sponsor dashboard.', { params });
|
||||
|
||||
const sponsor = sponsors.get(sponsorId);
|
||||
if (!sponsor) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Simplified mock data for dashboard metrics and sponsored leagues
|
||||
const metrics: SponsorDashboardMetricsDTO = {
|
||||
impressions: 10000,
|
||||
impressionsChange: 12.5,
|
||||
uniqueViewers: 7000,
|
||||
viewersChange: 8.3,
|
||||
races: 50,
|
||||
drivers: 100,
|
||||
exposure: 75,
|
||||
exposureChange: 5.2,
|
||||
};
|
||||
|
||||
const sponsoredLeagues: SponsoredLeagueDTO[] = [
|
||||
{ id: 'league-1', name: 'League 1', tier: 'main', drivers: 50, races: 10, impressions: 5000, status: 'active' },
|
||||
{ id: 'league-2', name: 'League 2', tier: 'secondary', drivers: 30, races: 5, impressions: 1500, status: 'upcoming' },
|
||||
];
|
||||
|
||||
const investment: SponsorDashboardInvestmentDTO = {
|
||||
activeSponsorships: 2,
|
||||
totalInvestment: 5000,
|
||||
costPerThousandViews: 0.5,
|
||||
};
|
||||
|
||||
return {
|
||||
sponsorId,
|
||||
sponsorName: sponsor.name,
|
||||
metrics,
|
||||
sponsoredLeagues,
|
||||
investment,
|
||||
};
|
||||
const presenter = new GetSponsorDashboardPresenter();
|
||||
await this.getSponsorDashboardUseCase.execute(params, presenter);
|
||||
return presenter.viewModel as SponsorDashboardDTO | null;
|
||||
}
|
||||
|
||||
async getSponsorSponsorships(params: GetSponsorSponsorshipsQueryParams): Promise<SponsorSponsorshipsDTO | null> {
|
||||
const { sponsorId } = params;
|
||||
this.logger.debug('[SponsorService] Fetching sponsor sponsorships.', { params });
|
||||
|
||||
const sponsor = sponsors.get(sponsorId);
|
||||
if (!sponsor) {
|
||||
return null;
|
||||
};
|
||||
|
||||
const sponsorshipDetails: SponsorshipDetailDTO[] = [
|
||||
{
|
||||
id: 'sponsorship-1',
|
||||
leagueId: 'league-1',
|
||||
leagueName: 'League 1',
|
||||
seasonId: 'season-1',
|
||||
seasonName: 'Season 1',
|
||||
seasonStartDate: new Date('2025-01-01'),
|
||||
seasonEndDate: new Date('2025-12-31'),
|
||||
tier: 'main',
|
||||
status: 'active',
|
||||
pricing: { amount: 1000, currency: 'USD' },
|
||||
platformFee: { amount: 100, currency: 'USD' },
|
||||
netAmount: { amount: 900, currency: 'USD' },
|
||||
metrics: { drivers: 50, races: 10, completedRaces: 8, impressions: 5000 },
|
||||
createdAt: new Date('2024-12-01'),
|
||||
activatedAt: new Date('2025-01-01'),
|
||||
},
|
||||
{
|
||||
id: 'sponsorship-2',
|
||||
leagueId: 'league-2',
|
||||
leagueName: 'League 2',
|
||||
seasonId: 'season-2',
|
||||
seasonName: 'Season 2',
|
||||
tier: 'secondary',
|
||||
status: 'pending',
|
||||
pricing: { amount: 500, currency: 'USD' },
|
||||
platformFee: { amount: 50, currency: 'USD' },
|
||||
netAmount: { amount: 450, currency: 'USD' },
|
||||
metrics: { drivers: 30, races: 5, completedRaces: 0, impressions: 0 },
|
||||
createdAt: new Date('2025-03-15'),
|
||||
},
|
||||
];
|
||||
|
||||
const totalInvestment = sponsorshipDetails.reduce((sum, s) => sum + s.pricing.amount, 0);
|
||||
const totalPlatformFees = sponsorshipDetails.reduce((sum, s) => sum + s.platformFee.amount, 0);
|
||||
const activeSponsorships = sponsorshipDetails.filter(s => s.status === 'active').length;
|
||||
|
||||
return {
|
||||
sponsorId,
|
||||
sponsorName: sponsor.name,
|
||||
sponsorships: sponsorshipDetails,
|
||||
summary: {
|
||||
totalSponsorships: sponsorshipDetails.length,
|
||||
activeSponsorships,
|
||||
totalInvestment,
|
||||
totalPlatformFees,
|
||||
currency: 'USD',
|
||||
},
|
||||
};
|
||||
const presenter = new GetSponsorSponsorshipsPresenter();
|
||||
await this.getSponsorSponsorshipsUseCase.execute(params, presenter);
|
||||
return presenter.viewModel as SponsorSponsorshipsDTO | null;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user