fix docker setup

This commit is contained in:
2025-12-25 15:24:54 +01:00
parent 3ceb837e15
commit f1c01b73ad
18 changed files with 419 additions and 132 deletions

View File

@@ -55,6 +55,11 @@ html-dumps
html-dumps-optimized html-dumps-optimized
backups backups
.husky .husky
docs
plans
tests
testing
resources
# Development files # Development files
.prettierrc .prettierrc

View File

@@ -5,14 +5,16 @@ WORKDIR /app
# Install bash for better shell capabilities # Install bash for better shell capabilities
RUN apk add --no-cache bash RUN apk add --no-cache bash
# Copy root package.json and install dependencies # Copy package manifests and install dependencies (incl. workspaces)
COPY package.json package-lock.json ./ COPY package.json package-lock.json ./
RUN npm ci COPY apps/api/package.json apps/api/package.json
RUN npm ci --workspaces --include-workspace-root
RUN find ./node_modules -name "ts-node-dev" -print || true # Debugging line RUN find ./node_modules -name "ts-node-dev" -print || true # Debugging line
# Copy apps/api and packages for development # Copy sources for development (monorepo)
COPY apps/api apps/api/ COPY apps/api apps/api/
COPY packages core/ COPY core core/
COPY adapters adapters/
COPY apps/api/tsconfig.json apps/api/ COPY apps/api/tsconfig.json apps/api/
COPY tsconfig.base.json ./ COPY tsconfig.base.json ./
@@ -21,4 +23,4 @@ EXPOSE 9229
# Command to run the NestJS application in development with hot-reloading # Command to run the NestJS application in development with hot-reloading
# Run from the correct workspace context # Run from the correct workspace context
CMD ["npm", "run", "start:dev", "--workspace=api"] CMD ["npm", "run", "start:dev", "--workspace=@gridpilot/api"]

View File

@@ -2,20 +2,21 @@ FROM node:20-alpine AS builder
WORKDIR /app WORKDIR /app
# Copy root package.json and install dependencies (for monorepo) # Copy package manifests and install dependencies (incl. workspaces)
COPY package.json package-lock.json ./ COPY package.json package-lock.json ./
RUN npm ci COPY apps/api/package.json apps/api/package.json
RUN npm ci --workspaces --include-workspace-root
# Copy apps/api and packages for building # Copy sources for building (monorepo)
COPY apps/api apps/api/ COPY apps/api apps/api/
COPY packages core/ COPY core core/
COPY adapters adapters/
COPY apps/api/tsconfig.json apps/api/ COPY apps/api/tsconfig.json apps/api/
COPY tsconfig.base.json ./ COPY tsconfig.base.json ./
# Build the NestJS application (ensuring correct workspace context) # Build shared libs + API (so runtime imports resolve)
# Run from the root workspace context RUN npx tsc -b core/tsconfig.json adapters/tsconfig.json
# RUN node ./node_modules/@nestjs/cli/bin/nest.js build --workspace=api # Not needed, npm run handles it RUN npm run build --workspace=@gridpilot/api
RUN npm run build --workspace=api
# Production stage: slim image with only production dependencies # Production stage: slim image with only production dependencies
@@ -34,8 +35,9 @@ RUN npm ci --omit=dev
# Copy built application from builder stage # Copy built application from builder stage
COPY --from=builder /app/apps/api/dist ./apps/api/dist COPY --from=builder /app/apps/api/dist ./apps/api/dist
# Copy packages (needed for runtime dependencies) # Provide runtime module resolution for @core/* and @adapters/*
COPY --from=builder /app/packages ./packages COPY --from=builder /app/dist/core /app/node_modules/@core
COPY --from=builder /app/dist/adapters /app/node_modules/@adapters
EXPOSE 3000 EXPOSE 3000

View File

@@ -5,7 +5,7 @@
"main": "dist/index.js", "main": "dist/index.js",
"scripts": { "scripts": {
"build": "tsc --build --verbose", "build": "tsc --build --verbose",
"start:dev": "ts-node-dev --respawn --inspect=0.0.0.0:9229 src/main.ts", "start:dev": "npx ts-node-dev --respawn --inspect=0.0.0.0:9229 -r tsconfig-paths/register src/main.ts",
"start:prod": "node dist/main", "start:prod": "node dist/main",
"test": "vitest run --config vitest.api.config.ts --root ../..", "test": "vitest run --config vitest.api.config.ts --root ../..",
"test:coverage": "vitest run --config vitest.api.config.ts --root ../.. --coverage", "test:coverage": "vitest run --config vitest.api.config.ts --root ../.. --coverage",
@@ -17,7 +17,8 @@
"license": "ISC", "license": "ISC",
"devDependencies": { "devDependencies": {
"@nestjs/testing": "^10.4.20", "@nestjs/testing": "^10.4.20",
"ts-node-dev": "^2.0.0" "ts-node-dev": "^2.0.0",
"tsconfig-paths": "^3.15.0"
}, },
"dependencies": { "dependencies": {
"@nestjs/common": "^10.4.20", "@nestjs/common": "^10.4.20",

View File

@@ -5,13 +5,17 @@ import { TypeOrmModule } from '@nestjs/typeorm';
imports: [ imports: [
TypeOrmModule.forRoot({ TypeOrmModule.forRoot({
type: 'postgres', type: 'postgres',
host: process.env.DATABASE_HOST || 'localhost', ...(process.env.DATABASE_URL
port: parseInt(process.env.DATABASE_PORT || '5432', 10), ? { url: process.env.DATABASE_URL }
username: process.env.DATABASE_USER || 'user', : {
password: process.env.DATABASE_PASSWORD || 'password', host: process.env.DATABASE_HOST || 'localhost',
database: process.env.DATABASE_NAME || 'gridpilot', port: parseInt(process.env.DATABASE_PORT || '5432', 10),
username: process.env.DATABASE_USER || 'user',
password: process.env.DATABASE_PASSWORD || 'password',
database: process.env.DATABASE_NAME || 'gridpilot',
}),
// entities: [AnalyticsSnapshotOrmEntity, EngagementOrmEntity], // entities: [AnalyticsSnapshotOrmEntity, EngagementOrmEntity],
synchronize: true, // Use carefully in production synchronize: process.env.NODE_ENV !== 'production',
}), }),
], ],
exports: [TypeOrmModule], exports: [TypeOrmModule],

View File

@@ -7,6 +7,11 @@ import { HelloService } from './HelloService';
export class HelloController { export class HelloController {
constructor(private readonly helloService: HelloService) {} constructor(private readonly helloService: HelloService) {}
@Get('health')
health() {
return { status: 'ok' };
}
@Get() @Get()
getHello() { getHello() {
return this.helloService.getHello(); return this.helloService.getHello();

View File

@@ -1,9 +1,10 @@
import { Module } from "@nestjs/common"; import { Module } from '@nestjs/common';
import { HelloController } from "./HelloController"; import { HelloController } from './HelloController';
import { HelloService } from "./HelloService"; import { HelloService } from './HelloService';
@Module({ @Module({
controllers: [HelloController], controllers: [HelloController],
providers: [HelloService],
exports: [HelloService], exports: [HelloService],
}) })
export class HelloModule {} export class HelloModule {}

View File

@@ -61,11 +61,28 @@ import { WithdrawFromLeagueWalletUseCase } from '@core/racing/application/use-ca
// Import presenters // Import presenters
import { AllLeaguesWithCapacityPresenter } from './presenters/AllLeaguesWithCapacityPresenter'; import { AllLeaguesWithCapacityPresenter } from './presenters/AllLeaguesWithCapacityPresenter';
import { ApproveLeagueJoinRequestPresenter } from './presenters/ApproveLeagueJoinRequestPresenter';
import { CreateLeaguePresenter } from './presenters/CreateLeaguePresenter';
import { GetLeagueAdminPermissionsPresenter } from './presenters/GetLeagueAdminPermissionsPresenter';
import { GetLeagueMembershipsPresenter } from './presenters/GetLeagueMembershipsPresenter';
import { GetLeagueOwnerSummaryPresenter } from './presenters/GetLeagueOwnerSummaryPresenter';
import { GetLeagueProtestsPresenter } from './presenters/GetLeagueProtestsPresenter'; import { GetLeagueProtestsPresenter } from './presenters/GetLeagueProtestsPresenter';
import { GetLeagueSeasonsPresenter } from './presenters/GetLeagueSeasonsPresenter';
import { GetLeagueWalletPresenter } from './presenters/GetLeagueWalletPresenter';
import { GetSeasonSponsorshipsPresenter } from './presenters/GetSeasonSponsorshipsPresenter'; import { GetSeasonSponsorshipsPresenter } from './presenters/GetSeasonSponsorshipsPresenter';
import { JoinLeaguePresenter } from './presenters/JoinLeaguePresenter';
import { LeagueConfigPresenter } from './presenters/LeagueConfigPresenter';
import { LeagueJoinRequestsPresenter } from './presenters/LeagueJoinRequestsPresenter';
import { LeagueSchedulePresenter, LeagueRacesPresenter } from './presenters/LeagueSchedulePresenter';
import { LeagueScoringConfigPresenter } from './presenters/LeagueScoringConfigPresenter';
import { LeagueScoringPresetsPresenter } from './presenters/LeagueScoringPresetsPresenter'; import { LeagueScoringPresetsPresenter } from './presenters/LeagueScoringPresetsPresenter';
import { LeagueStandingsPresenter } from './presenters/LeagueStandingsPresenter'; import { LeagueStandingsPresenter } from './presenters/LeagueStandingsPresenter';
import { GetLeagueWalletPresenter } from './presenters/GetLeagueWalletPresenter'; import { LeagueStatsPresenter } from './presenters/LeagueStatsPresenter';
import { RejectLeagueJoinRequestPresenter } from './presenters/RejectLeagueJoinRequestPresenter';
import { RemoveLeagueMemberPresenter } from './presenters/RemoveLeagueMemberPresenter';
import { TotalLeaguesPresenter } from './presenters/TotalLeaguesPresenter';
import { TransferLeagueOwnershipPresenter } from './presenters/TransferLeagueOwnershipPresenter';
import { UpdateLeagueMemberRolePresenter } from './presenters/UpdateLeagueMemberRolePresenter';
import { WithdrawFromLeagueWalletPresenter } from './presenters/WithdrawFromLeagueWalletPresenter'; import { WithdrawFromLeagueWalletPresenter } from './presenters/WithdrawFromLeagueWalletPresenter';
export const LEAGUE_REPOSITORY_TOKEN = 'ILeagueRepository'; export const LEAGUE_REPOSITORY_TOKEN = 'ILeagueRepository';
@@ -204,11 +221,29 @@ export const LeagueProviders: Provider[] = [
}, },
// Presenters // Presenters
AllLeaguesWithCapacityPresenter, AllLeaguesWithCapacityPresenter,
LeagueStandingsPresenter, ApproveLeagueJoinRequestPresenter,
CreateLeaguePresenter,
GetLeagueAdminPermissionsPresenter,
GetLeagueMembershipsPresenter,
GetLeagueOwnerSummaryPresenter,
GetLeagueProtestsPresenter, GetLeagueProtestsPresenter,
GetSeasonSponsorshipsPresenter, GetLeagueSeasonsPresenter,
LeagueScoringPresetsPresenter,
GetLeagueWalletPresenter, GetLeagueWalletPresenter,
GetSeasonSponsorshipsPresenter,
JoinLeaguePresenter,
LeagueConfigPresenter,
LeagueJoinRequestsPresenter,
LeagueRacesPresenter,
LeagueSchedulePresenter,
LeagueScoringConfigPresenter,
LeagueScoringPresetsPresenter,
LeagueStandingsPresenter,
LeagueStatsPresenter,
RejectLeagueJoinRequestPresenter,
RemoveLeagueMemberPresenter,
TotalLeaguesPresenter,
TransferLeagueOwnershipPresenter,
UpdateLeagueMemberRolePresenter,
WithdrawFromLeagueWalletPresenter, WithdrawFromLeagueWalletPresenter,
// Output ports // Output ports
{ {
@@ -231,6 +266,70 @@ export const LeagueProviders: Provider[] = [
provide: LIST_LEAGUE_SCORING_PRESETS_OUTPUT_PORT_TOKEN, provide: LIST_LEAGUE_SCORING_PRESETS_OUTPUT_PORT_TOKEN,
useExisting: LeagueScoringPresetsPresenter, useExisting: LeagueScoringPresetsPresenter,
}, },
{
provide: APPROVE_LEAGUE_JOIN_REQUEST_OUTPUT_PORT_TOKEN,
useExisting: ApproveLeagueJoinRequestPresenter,
},
{
provide: CREATE_LEAGUE_OUTPUT_PORT_TOKEN,
useExisting: CreateLeaguePresenter,
},
{
provide: GET_LEAGUE_ADMIN_PERMISSIONS_OUTPUT_PORT_TOKEN,
useExisting: GetLeagueAdminPermissionsPresenter,
},
{
provide: GET_LEAGUE_MEMBERSHIPS_OUTPUT_PORT_TOKEN,
useExisting: GetLeagueMembershipsPresenter,
},
{
provide: GET_LEAGUE_OWNER_SUMMARY_OUTPUT_PORT_TOKEN,
useExisting: GetLeagueOwnerSummaryPresenter,
},
{
provide: GET_LEAGUE_SEASONS_OUTPUT_PORT_TOKEN,
useExisting: GetLeagueSeasonsPresenter,
},
{
provide: JOIN_LEAGUE_OUTPUT_PORT_TOKEN,
useExisting: JoinLeaguePresenter,
},
{
provide: GET_LEAGUE_SCHEDULE_OUTPUT_PORT_TOKEN,
useExisting: LeagueSchedulePresenter,
},
{
provide: GET_LEAGUE_STATS_OUTPUT_PORT_TOKEN,
useExisting: LeagueStatsPresenter,
},
{
provide: REJECT_LEAGUE_JOIN_REQUEST_OUTPUT_PORT_TOKEN,
useExisting: RejectLeagueJoinRequestPresenter,
},
{
provide: REMOVE_LEAGUE_MEMBER_OUTPUT_PORT_TOKEN,
useExisting: RemoveLeagueMemberPresenter,
},
{
provide: TOTAL_LEAGUES_OUTPUT_PORT_TOKEN,
useExisting: TotalLeaguesPresenter,
},
{
provide: TRANSFER_LEAGUE_OWNERSHIP_OUTPUT_PORT_TOKEN,
useExisting: TransferLeagueOwnershipPresenter,
},
{
provide: UPDATE_LEAGUE_MEMBER_ROLE_OUTPUT_PORT_TOKEN,
useExisting: UpdateLeagueMemberRolePresenter,
},
{
provide: GET_LEAGUE_FULL_CONFIG_OUTPUT_PORT_TOKEN,
useExisting: LeagueConfigPresenter,
},
{
provide: GET_LEAGUE_SCORING_CONFIG_OUTPUT_PORT_TOKEN,
useExisting: LeagueScoringConfigPresenter,
},
{ {
provide: GET_LEAGUE_WALLET_OUTPUT_PORT_TOKEN, provide: GET_LEAGUE_WALLET_OUTPUT_PORT_TOKEN,
useExisting: GetLeagueWalletPresenter, useExisting: GetLeagueWalletPresenter,
@@ -248,9 +347,16 @@ export const LeagueProviders: Provider[] = [
}, },
{ {
provide: GET_LEAGUE_STANDINGS_USE_CASE, provide: GET_LEAGUE_STANDINGS_USE_CASE,
useFactory: (standingRepo: IStandingRepository, driverRepo: IDriverRepository, presenter: LeagueStandingsPresenter) => useFactory: (
new GetLeagueStandingsUseCase(standingRepo, driverRepo, presenter), standingRepo: IStandingRepository,
inject: [STANDING_REPOSITORY_TOKEN, DRIVER_REPOSITORY_TOKEN, 'LeagueStandingsPresenter'], driverRepo: IDriverRepository,
output: LeagueStandingsPresenter,
) => new GetLeagueStandingsUseCase(standingRepo, driverRepo, output),
inject: [
STANDING_REPOSITORY_TOKEN,
DRIVER_REPOSITORY_TOKEN,
GET_LEAGUE_STANDINGS_OUTPUT_PORT_TOKEN,
],
}, },
{ {
provide: GET_LEAGUE_STATS_USE_CASE, provide: GET_LEAGUE_STATS_USE_CASE,
@@ -303,9 +409,15 @@ export const LeagueProviders: Provider[] = [
protestRepo: IProtestRepository, protestRepo: IProtestRepository,
driverRepo: IDriverRepository, driverRepo: IDriverRepository,
leagueRepo: ILeagueRepository, leagueRepo: ILeagueRepository,
presenter: GetLeagueProtestsPresenter, output: GetLeagueProtestsPresenter,
) => new GetLeagueProtestsUseCase(raceRepo, protestRepo, driverRepo, leagueRepo, presenter), ) => new GetLeagueProtestsUseCase(raceRepo, protestRepo, driverRepo, leagueRepo, output),
inject: [RACE_REPOSITORY_TOKEN, PROTEST_REPOSITORY_TOKEN, DRIVER_REPOSITORY_TOKEN, LEAGUE_REPOSITORY_TOKEN, 'GetLeagueProtestsPresenter'], inject: [
RACE_REPOSITORY_TOKEN,
PROTEST_REPOSITORY_TOKEN,
DRIVER_REPOSITORY_TOKEN,
LEAGUE_REPOSITORY_TOKEN,
GET_LEAGUE_PROTESTS_OUTPUT_PORT_TOKEN,
],
}, },
{ {
provide: GET_LEAGUE_SEASONS_USE_CASE, provide: GET_LEAGUE_SEASONS_USE_CASE,
@@ -329,9 +441,14 @@ export const LeagueProviders: Provider[] = [
leagueRepo: ILeagueRepository, leagueRepo: ILeagueRepository,
walletRepo: ILeagueWalletRepository, walletRepo: ILeagueWalletRepository,
transactionRepo: ITransactionRepository, transactionRepo: ITransactionRepository,
presenter: GetLeagueWalletPresenter, output: GetLeagueWalletPresenter,
) => new GetLeagueWalletUseCase(leagueRepo, walletRepo, transactionRepo, presenter), ) => new GetLeagueWalletUseCase(leagueRepo, walletRepo, transactionRepo, output),
inject: [LEAGUE_REPOSITORY_TOKEN, LEAGUE_WALLET_REPOSITORY_TOKEN, TRANSACTION_REPOSITORY_TOKEN, 'GetLeagueWalletPresenter'], inject: [
LEAGUE_REPOSITORY_TOKEN,
LEAGUE_WALLET_REPOSITORY_TOKEN,
TRANSACTION_REPOSITORY_TOKEN,
GET_LEAGUE_WALLET_OUTPUT_PORT_TOKEN,
],
}, },
{ {
provide: WITHDRAW_FROM_LEAGUE_WALLET_USE_CASE, provide: WITHDRAW_FROM_LEAGUE_WALLET_USE_CASE,
@@ -340,9 +457,15 @@ export const LeagueProviders: Provider[] = [
walletRepo: ILeagueWalletRepository, walletRepo: ILeagueWalletRepository,
transactionRepo: ITransactionRepository, transactionRepo: ITransactionRepository,
logger: Logger, logger: Logger,
presenter: WithdrawFromLeagueWalletPresenter, output: WithdrawFromLeagueWalletPresenter,
) => new WithdrawFromLeagueWalletUseCase(leagueRepo, walletRepo, transactionRepo, logger, presenter), ) => new WithdrawFromLeagueWalletUseCase(leagueRepo, walletRepo, transactionRepo, logger, output),
inject: [LEAGUE_REPOSITORY_TOKEN, LEAGUE_WALLET_REPOSITORY_TOKEN, TRANSACTION_REPOSITORY_TOKEN, LOGGER_TOKEN, 'WithdrawFromLeagueWalletPresenter'], inject: [
LEAGUE_REPOSITORY_TOKEN,
LEAGUE_WALLET_REPOSITORY_TOKEN,
TRANSACTION_REPOSITORY_TOKEN,
LOGGER_TOKEN,
WITHDRAW_FROM_LEAGUE_WALLET_OUTPUT_PORT_TOKEN,
],
}, },
{ {
provide: GET_SEASON_SPONSORSHIPS_USE_CASE, provide: GET_SEASON_SPONSORSHIPS_USE_CASE,
@@ -352,21 +475,30 @@ export const LeagueProviders: Provider[] = [
leagueRepo: ILeagueRepository, leagueRepo: ILeagueRepository,
leagueMembershipRepo: ILeagueMembershipRepository, leagueMembershipRepo: ILeagueMembershipRepository,
raceRepo: IRaceRepository, raceRepo: IRaceRepository,
presenter: GetSeasonSponsorshipsPresenter, output: GetSeasonSponsorshipsPresenter,
) => new GetSeasonSponsorshipsUseCase(seasonSponsorshipRepo, seasonRepo, leagueRepo, leagueMembershipRepo, raceRepo, presenter), ) =>
new GetSeasonSponsorshipsUseCase(
seasonSponsorshipRepo,
seasonRepo,
leagueRepo,
leagueMembershipRepo,
raceRepo,
output,
),
inject: [ inject: [
'ISeasonSponsorshipRepository', 'ISeasonSponsorshipRepository',
SEASON_REPOSITORY_TOKEN, SEASON_REPOSITORY_TOKEN,
LEAGUE_REPOSITORY_TOKEN, LEAGUE_REPOSITORY_TOKEN,
LEAGUE_MEMBERSHIP_REPOSITORY_TOKEN, LEAGUE_MEMBERSHIP_REPOSITORY_TOKEN,
RACE_REPOSITORY_TOKEN, RACE_REPOSITORY_TOKEN,
'GetSeasonSponsorshipsPresenter', GET_SEASON_SPONSORSHIPS_OUTPUT_PORT_TOKEN,
], ],
}, },
{ // TODO wtf is this here? doesn't look like it adhers to our concepts { // TODO wtf is this here? doesn't look like it adhers to our concepts
provide: LIST_LEAGUE_SCORING_PRESETS_USE_CASE, provide: LIST_LEAGUE_SCORING_PRESETS_USE_CASE,
useFactory: (presenter: LeagueScoringPresetsPresenter) => new ListLeagueScoringPresetsUseCase(listLeagueScoringPresets(), presenter), useFactory: (output: LeagueScoringPresetsPresenter) =>
inject: ['LeagueScoringPresetsPresenter'], new ListLeagueScoringPresetsUseCase(listLeagueScoringPresets(), output),
inject: [LIST_LEAGUE_SCORING_PRESETS_OUTPUT_PORT_TOKEN],
}, },
{ {
provide: JOIN_LEAGUE_USE_CASE, provide: JOIN_LEAGUE_USE_CASE,

View File

@@ -94,31 +94,31 @@ import { UpdateLeagueMemberRolePresenter } from './presenters/UpdateLeagueMember
import { GetLeagueWalletPresenter } from './presenters/GetLeagueWalletPresenter'; import { GetLeagueWalletPresenter } from './presenters/GetLeagueWalletPresenter';
import { WithdrawFromLeagueWalletPresenter } from './presenters/WithdrawFromLeagueWalletPresenter'; import { WithdrawFromLeagueWalletPresenter } from './presenters/WithdrawFromLeagueWalletPresenter';
// Tokens // Tokens
import { import {
LOGGER_TOKEN, LOGGER_TOKEN,
GET_ALL_LEAGUES_WITH_CAPACITY_USE_CASE, GET_ALL_LEAGUES_WITH_CAPACITY_USE_CASE,
GET_LEAGUE_STANDINGS_USE_CASE, GET_LEAGUE_STANDINGS_USE_CASE,
GET_LEAGUE_STATS_USE_CASE, GET_LEAGUE_STATS_USE_CASE,
GET_LEAGUE_FULL_CONFIG_USE_CASE, GET_LEAGUE_FULL_CONFIG_USE_CASE,
GET_LEAGUE_SCORING_CONFIG_USE_CASE, GET_LEAGUE_SCORING_CONFIG_USE_CASE,
LIST_LEAGUE_SCORING_PRESETS_USE_CASE, LIST_LEAGUE_SCORING_PRESETS_USE_CASE,
JOIN_LEAGUE_USE_CASE, JOIN_LEAGUE_USE_CASE,
TRANSFER_LEAGUE_OWNERSHIP_USE_CASE, TRANSFER_LEAGUE_OWNERSHIP_USE_CASE,
CREATE_LEAGUE_WITH_SEASON_AND_SCORING_USE_CASE, CREATE_LEAGUE_WITH_SEASON_AND_SCORING_USE_CASE,
GET_TOTAL_LEAGUES_USE_CASE, GET_TOTAL_LEAGUES_USE_CASE,
GET_LEAGUE_JOIN_REQUESTS_USE_CASE, GET_LEAGUE_JOIN_REQUESTS_USE_CASE,
APPROVE_LEAGUE_JOIN_REQUEST_USE_CASE, APPROVE_LEAGUE_JOIN_REQUEST_USE_CASE,
REJECT_LEAGUE_JOIN_REQUEST_USE_CASE, REJECT_LEAGUE_JOIN_REQUEST_USE_CASE,
REMOVE_LEAGUE_MEMBER_USE_CASE, REMOVE_LEAGUE_MEMBER_USE_CASE,
UPDATE_LEAGUE_MEMBER_ROLE_USE_CASE, UPDATE_LEAGUE_MEMBER_ROLE_USE_CASE,
GET_LEAGUE_OWNER_SUMMARY_USE_CASE, GET_LEAGUE_OWNER_SUMMARY_USE_CASE,
GET_LEAGUE_PROTESTS_USE_CASE, GET_LEAGUE_PROTESTS_USE_CASE,
GET_LEAGUE_SEASONS_USE_CASE, GET_LEAGUE_SEASONS_USE_CASE,
GET_LEAGUE_MEMBERSHIPS_USE_CASE, GET_LEAGUE_MEMBERSHIPS_USE_CASE,
GET_LEAGUE_SCHEDULE_USE_CASE, GET_LEAGUE_SCHEDULE_USE_CASE,
GET_LEAGUE_ADMIN_PERMISSIONS_USE_CASE, GET_LEAGUE_ADMIN_PERMISSIONS_USE_CASE,
GET_LEAGUE_WALLET_USE_CASE, GET_LEAGUE_WALLET_USE_CASE,
WITHDRAW_FROM_LEAGUE_WALLET_USE_CASE, WITHDRAW_FROM_LEAGUE_WALLET_USE_CASE,
GET_SEASON_SPONSORSHIPS_USE_CASE, GET_SEASON_SPONSORSHIPS_USE_CASE,
GET_ALL_LEAGUES_WITH_CAPACITY_OUTPUT_PORT_TOKEN, GET_ALL_LEAGUES_WITH_CAPACITY_OUTPUT_PORT_TOKEN,
GET_LEAGUE_STANDINGS_OUTPUT_PORT_TOKEN, GET_LEAGUE_STANDINGS_OUTPUT_PORT_TOKEN,
@@ -143,7 +143,7 @@ import {
GET_LEAGUE_SCORING_CONFIG_OUTPUT_PORT_TOKEN, GET_LEAGUE_SCORING_CONFIG_OUTPUT_PORT_TOKEN,
GET_LEAGUE_WALLET_OUTPUT_PORT_TOKEN, GET_LEAGUE_WALLET_OUTPUT_PORT_TOKEN,
WITHDRAW_FROM_LEAGUE_WALLET_OUTPUT_PORT_TOKEN, WITHDRAW_FROM_LEAGUE_WALLET_OUTPUT_PORT_TOKEN,
} from './LeagueProviders'; } from './LeagueTokens';
@Injectable() @Injectable()
export class LeagueService { export class LeagueService {
@@ -197,8 +197,8 @@ export class LeagueService {
@Inject(GET_LEAGUE_SCORING_CONFIG_OUTPUT_PORT_TOKEN) private readonly leagueScoringConfigPresenter: LeagueScoringConfigPresenter, @Inject(GET_LEAGUE_SCORING_CONFIG_OUTPUT_PORT_TOKEN) private readonly leagueScoringConfigPresenter: LeagueScoringConfigPresenter,
@Inject(GET_LEAGUE_WALLET_OUTPUT_PORT_TOKEN) private readonly getLeagueWalletPresenter: GetLeagueWalletPresenter, @Inject(GET_LEAGUE_WALLET_OUTPUT_PORT_TOKEN) private readonly getLeagueWalletPresenter: GetLeagueWalletPresenter,
@Inject(WITHDRAW_FROM_LEAGUE_WALLET_OUTPUT_PORT_TOKEN) private readonly withdrawFromLeagueWalletPresenter: WithdrawFromLeagueWalletPresenter, @Inject(WITHDRAW_FROM_LEAGUE_WALLET_OUTPUT_PORT_TOKEN) private readonly withdrawFromLeagueWalletPresenter: WithdrawFromLeagueWalletPresenter,
@Inject(GET_LEAGUE_JOIN_REQUESTS_USE_CASE) private readonly leagueJoinRequestsPresenter: LeagueJoinRequestsPresenter, private readonly leagueJoinRequestsPresenter: LeagueJoinRequestsPresenter,
@Inject(GET_LEAGUE_SCHEDULE_USE_CASE) private readonly leagueRacesPresenter: LeagueRacesPresenter, private readonly leagueRacesPresenter: LeagueRacesPresenter,
) {} ) {}
async getAllLeaguesWithCapacity(): Promise<AllLeaguesWithCapacityViewModel> { async getAllLeaguesWithCapacity(): Promise<AllLeaguesWithCapacityViewModel> {

View File

@@ -0,0 +1,63 @@
export const LEAGUE_REPOSITORY_TOKEN = 'ILeagueRepository';
export const LEAGUE_MEMBERSHIP_REPOSITORY_TOKEN = 'ILeagueMembershipRepository';
export const LEAGUE_STANDINGS_REPOSITORY_TOKEN = 'ILeagueStandingsRepository';
export const STANDING_REPOSITORY_TOKEN = 'IStandingRepository';
export const SEASON_REPOSITORY_TOKEN = 'ISeasonRepository';
export const LEAGUE_SCORING_CONFIG_REPOSITORY_TOKEN = 'ILeagueScoringConfigRepository';
export const GAME_REPOSITORY_TOKEN = 'IGameRepository';
export const PROTEST_REPOSITORY_TOKEN = 'IProtestRepository';
export const RACE_REPOSITORY_TOKEN = 'IRaceRepository';
export const DRIVER_REPOSITORY_TOKEN = 'IDriverRepository';
export const LEAGUE_WALLET_REPOSITORY_TOKEN = 'ILeagueWalletRepository';
export const TRANSACTION_REPOSITORY_TOKEN = 'ITransactionRepository';
export const LOGGER_TOKEN = 'Logger';
export const GET_LEAGUE_STANDINGS_USE_CASE = 'GetLeagueStandingsUseCase';
export const GET_ALL_LEAGUES_WITH_CAPACITY_USE_CASE = 'GetAllLeaguesWithCapacityUseCase';
export const GET_LEAGUE_STATS_USE_CASE = 'GetLeagueStatsUseCase';
export const GET_LEAGUE_FULL_CONFIG_USE_CASE = 'GetLeagueFullConfigUseCase';
export const GET_LEAGUE_SCORING_CONFIG_USE_CASE = 'GetLeagueScoringConfigUseCase';
export const LIST_LEAGUE_SCORING_PRESETS_USE_CASE = 'ListLeagueScoringPresetsUseCase';
export const JOIN_LEAGUE_USE_CASE = 'JoinLeagueUseCase';
export const TRANSFER_LEAGUE_OWNERSHIP_USE_CASE = 'TransferLeagueOwnershipUseCase';
export const CREATE_LEAGUE_WITH_SEASON_AND_SCORING_USE_CASE = 'CreateLeagueWithSeasonAndScoringUseCase';
export const GET_RACE_PROTESTS_USE_CASE = 'GetRaceProtestsUseCase';
export const GET_TOTAL_LEAGUES_USE_CASE = 'GetTotalLeaguesUseCase';
export const GET_LEAGUE_JOIN_REQUESTS_USE_CASE = 'GetLeagueJoinRequestsUseCase';
export const APPROVE_LEAGUE_JOIN_REQUEST_USE_CASE = 'ApproveLeagueJoinRequestUseCase';
export const REJECT_LEAGUE_JOIN_REQUEST_USE_CASE = 'RejectLeagueJoinRequestUseCase';
export const REMOVE_LEAGUE_MEMBER_USE_CASE = 'RemoveLeagueMemberUseCase';
export const UPDATE_LEAGUE_MEMBER_ROLE_USE_CASE = 'UpdateLeagueMemberRoleUseCase';
export const GET_LEAGUE_OWNER_SUMMARY_USE_CASE = 'GetLeagueOwnerSummaryUseCase';
export const GET_LEAGUE_PROTESTS_USE_CASE = 'GetLeagueProtestsUseCase';
export const GET_LEAGUE_SEASONS_USE_CASE = 'GetLeagueSeasonsUseCase';
export const GET_LEAGUE_MEMBERSHIPS_USE_CASE = 'GetLeagueMembershipsUseCase';
export const GET_LEAGUE_SCHEDULE_USE_CASE = 'GetLeagueScheduleUseCase';
export const GET_LEAGUE_ADMIN_PERMISSIONS_USE_CASE = 'GetLeagueAdminPermissionsUseCase';
export const GET_LEAGUE_WALLET_USE_CASE = 'GetLeagueWalletUseCase';
export const WITHDRAW_FROM_LEAGUE_WALLET_USE_CASE = 'WithdrawFromLeagueWalletUseCase';
export const GET_SEASON_SPONSORSHIPS_USE_CASE = 'GetSeasonSponsorshipsUseCase';
export const GET_ALL_LEAGUES_WITH_CAPACITY_OUTPUT_PORT_TOKEN = 'GetAllLeaguesWithCapacityOutputPort_TOKEN';
export const GET_LEAGUE_STANDINGS_OUTPUT_PORT_TOKEN = 'GetLeagueStandingsOutputPort_TOKEN';
export const GET_LEAGUE_PROTESTS_OUTPUT_PORT_TOKEN = 'GetLeagueProtestsOutputPort_TOKEN';
export const GET_SEASON_SPONSORSHIPS_OUTPUT_PORT_TOKEN = 'GetSeasonSponsorshipsOutputPort_TOKEN';
export const LIST_LEAGUE_SCORING_PRESETS_OUTPUT_PORT_TOKEN = 'ListLeagueScoringPresetsOutputPort_TOKEN';
export const APPROVE_LEAGUE_JOIN_REQUEST_OUTPUT_PORT_TOKEN = 'ApproveLeagueJoinRequestOutputPort_TOKEN';
export const CREATE_LEAGUE_OUTPUT_PORT_TOKEN = 'CreateLeagueOutputPort_TOKEN';
export const GET_LEAGUE_ADMIN_PERMISSIONS_OUTPUT_PORT_TOKEN = 'GetLeagueAdminPermissionsOutputPort_TOKEN';
export const GET_LEAGUE_MEMBERSHIPS_OUTPUT_PORT_TOKEN = 'GetLeagueMembershipsOutputPort_TOKEN';
export const GET_LEAGUE_OWNER_SUMMARY_OUTPUT_PORT_TOKEN = 'GetLeagueOwnerSummaryOutputPort_TOKEN';
export const GET_LEAGUE_SEASONS_OUTPUT_PORT_TOKEN = 'GetLeagueSeasonsOutputPort_TOKEN';
export const JOIN_LEAGUE_OUTPUT_PORT_TOKEN = 'JoinLeagueOutputPort_TOKEN';
export const GET_LEAGUE_SCHEDULE_OUTPUT_PORT_TOKEN = 'GetLeagueScheduleOutputPort_TOKEN';
export const GET_LEAGUE_STATS_OUTPUT_PORT_TOKEN = 'GetLeagueStatsOutputPort_TOKEN';
export const REJECT_LEAGUE_JOIN_REQUEST_OUTPUT_PORT_TOKEN = 'RejectLeagueJoinRequestOutputPort_TOKEN';
export const REMOVE_LEAGUE_MEMBER_OUTPUT_PORT_TOKEN = 'RemoveLeagueMemberOutputPort_TOKEN';
export const TOTAL_LEAGUES_OUTPUT_PORT_TOKEN = 'TotalLeaguesOutputPort_TOKEN';
export const TRANSFER_LEAGUE_OWNERSHIP_OUTPUT_PORT_TOKEN = 'TransferLeagueOwnershipOutputPort_TOKEN';
export const UPDATE_LEAGUE_MEMBER_ROLE_OUTPUT_PORT_TOKEN = 'UpdateLeagueMemberRoleOutputPort_TOKEN';
export const GET_LEAGUE_FULL_CONFIG_OUTPUT_PORT_TOKEN = 'GetLeagueFullConfigOutputPort_TOKEN';
export const GET_LEAGUE_SCORING_CONFIG_OUTPUT_PORT_TOKEN = 'GetLeagueScoringConfigOutputPort_TOKEN';
export const GET_LEAGUE_WALLET_OUTPUT_PORT_TOKEN = 'GetLeagueWalletOutputPort_TOKEN';
export const WITHDRAW_FROM_LEAGUE_WALLET_OUTPUT_PORT_TOKEN = 'WithdrawFromLeagueWalletOutputPort_TOKEN';

View File

@@ -32,8 +32,11 @@ import { RejectSponsorshipRequestUseCase } from '@core/racing/application/use-ca
// Import concrete in-memory implementations // Import concrete in-memory implementations
import { ConsoleLogger } from '@adapters/logging/ConsoleLogger'; import { ConsoleLogger } from '@adapters/logging/ConsoleLogger';
import { InMemoryPaymentRepository } from '@adapters/payments/persistence/inmemory/InMemoryPaymentRepository';
import { InMemoryWalletRepository } from '@adapters/payments/persistence/inmemory/InMemoryWalletRepository';
import { InMemoryLeagueMembershipRepository } from '@adapters/racing/persistence/inmemory/InMemoryLeagueMembershipRepository'; import { InMemoryLeagueMembershipRepository } from '@adapters/racing/persistence/inmemory/InMemoryLeagueMembershipRepository';
import { InMemoryLeagueRepository } from '@adapters/racing/persistence/inmemory/InMemoryLeagueRepository'; import { InMemoryLeagueRepository } from '@adapters/racing/persistence/inmemory/InMemoryLeagueRepository';
import { InMemoryLeagueWalletRepository } from '@adapters/racing/persistence/inmemory/InMemoryLeagueWalletRepository';
import { InMemoryRaceRepository } from '@adapters/racing/persistence/inmemory/InMemoryRaceRepository'; import { InMemoryRaceRepository } from '@adapters/racing/persistence/inmemory/InMemoryRaceRepository';
import { InMemorySeasonRepository } from '@adapters/racing/persistence/inmemory/InMemorySeasonRepository'; import { InMemorySeasonRepository } from '@adapters/racing/persistence/inmemory/InMemorySeasonRepository';
import { InMemorySeasonSponsorshipRepository } from '@adapters/racing/persistence/inmemory/InMemorySeasonSponsorshipRepository'; import { InMemorySeasonSponsorshipRepository } from '@adapters/racing/persistence/inmemory/InMemorySeasonSponsorshipRepository';
@@ -62,6 +65,10 @@ export const LEAGUE_MEMBERSHIP_REPOSITORY_TOKEN = 'ILeagueMembershipRepository';
export const RACE_REPOSITORY_TOKEN = 'IRaceRepository'; export const RACE_REPOSITORY_TOKEN = 'IRaceRepository';
export const SPONSORSHIP_PRICING_REPOSITORY_TOKEN = 'ISponsorshipPricingRepository'; export const SPONSORSHIP_PRICING_REPOSITORY_TOKEN = 'ISponsorshipPricingRepository';
export const SPONSORSHIP_REQUEST_REPOSITORY_TOKEN = 'ISponsorshipRequestRepository'; export const SPONSORSHIP_REQUEST_REPOSITORY_TOKEN = 'ISponsorshipRequestRepository';
export const PAYMENT_REPOSITORY_TOKEN = 'IPaymentRepository';
export const WALLET_REPOSITORY_TOKEN = 'IWalletRepository';
export const LEAGUE_WALLET_REPOSITORY_TOKEN = 'ILeagueWalletRepository';
export const NOTIFICATION_SERVICE_TOKEN = 'INotificationService';
export const LOGGER_TOKEN = 'Logger'; export const LOGGER_TOKEN = 'Logger';
// Presenter tokens // Presenter tokens
@@ -145,6 +152,30 @@ export const SponsorProviders: Provider[] = [
useFactory: (logger: Logger) => new InMemorySponsorshipRequestRepository(logger), useFactory: (logger: Logger) => new InMemorySponsorshipRequestRepository(logger),
inject: [LOGGER_TOKEN], inject: [LOGGER_TOKEN],
}, },
{
provide: PAYMENT_REPOSITORY_TOKEN,
useFactory: (logger: Logger) => new InMemoryPaymentRepository(logger),
inject: [LOGGER_TOKEN],
},
{
provide: WALLET_REPOSITORY_TOKEN,
useFactory: (logger: Logger) => new InMemoryWalletRepository(logger),
inject: [LOGGER_TOKEN],
},
{
provide: LEAGUE_WALLET_REPOSITORY_TOKEN,
useFactory: (logger: Logger) => new InMemoryLeagueWalletRepository(logger),
inject: [LOGGER_TOKEN],
},
{
provide: NOTIFICATION_SERVICE_TOKEN,
useFactory: (logger: Logger): NotificationService => ({
async sendNotification(command: any): Promise<void> {
logger.info('[InMemoryNotificationService] sendNotification', { command });
},
}),
inject: [LOGGER_TOKEN],
},
{ {
provide: LOGGER_TOKEN, provide: LOGGER_TOKEN,
useClass: ConsoleLogger, useClass: ConsoleLogger,
@@ -161,6 +192,10 @@ export const SponsorProviders: Provider[] = [
RejectSponsorshipRequestPresenter, RejectSponsorshipRequestPresenter,
SponsorBillingPresenter, SponsorBillingPresenter,
// Output ports // Output ports
{
provide: GET_SPONSORSHIP_PRICING_OUTPUT_PORT_TOKEN,
useExisting: GetEntitySponsorshipPricingPresenter,
},
{ {
provide: GET_ENTITY_SPONSORSHIP_PRICING_OUTPUT_PORT_TOKEN, provide: GET_ENTITY_SPONSORSHIP_PRICING_OUTPUT_PORT_TOKEN,
useExisting: GetEntitySponsorshipPricingPresenter, useExisting: GetEntitySponsorshipPricingPresenter,
@@ -267,7 +302,7 @@ export const SponsorProviders: Provider[] = [
) => { ) => {
return new GetSponsorBillingUseCase(paymentRepo, seasonSponsorshipRepo); return new GetSponsorBillingUseCase(paymentRepo, seasonSponsorshipRepo);
}, },
inject: ['IPaymentRepository', SEASON_SPONSORSHIP_REPOSITORY_TOKEN], inject: [PAYMENT_REPOSITORY_TOKEN, SEASON_SPONSORSHIP_REPOSITORY_TOKEN],
}, },
{ {
provide: GET_ENTITY_SPONSORSHIP_PRICING_USE_CASE_TOKEN, provide: GET_ENTITY_SPONSORSHIP_PRICING_USE_CASE_TOKEN,
@@ -330,9 +365,9 @@ export const SponsorProviders: Provider[] = [
SPONSORSHIP_REQUEST_REPOSITORY_TOKEN, SPONSORSHIP_REQUEST_REPOSITORY_TOKEN,
SEASON_SPONSORSHIP_REPOSITORY_TOKEN, SEASON_SPONSORSHIP_REPOSITORY_TOKEN,
SEASON_REPOSITORY_TOKEN, SEASON_REPOSITORY_TOKEN,
'INotificationService', NOTIFICATION_SERVICE_TOKEN,
'IWalletRepository', WALLET_REPOSITORY_TOKEN,
'ILeagueWalletRepository', LEAGUE_WALLET_REPOSITORY_TOKEN,
LOGGER_TOKEN, LOGGER_TOKEN,
ACCEPT_SPONSORSHIP_REQUEST_OUTPUT_PORT_TOKEN, ACCEPT_SPONSORSHIP_REQUEST_OUTPUT_PORT_TOKEN,
], ],

View File

@@ -65,19 +65,9 @@ import {
GET_PENDING_SPONSORSHIP_REQUESTS_USE_CASE_TOKEN, GET_PENDING_SPONSORSHIP_REQUESTS_USE_CASE_TOKEN,
ACCEPT_SPONSORSHIP_REQUEST_USE_CASE_TOKEN, ACCEPT_SPONSORSHIP_REQUEST_USE_CASE_TOKEN,
REJECT_SPONSORSHIP_REQUEST_USE_CASE_TOKEN, REJECT_SPONSORSHIP_REQUEST_USE_CASE_TOKEN,
LOGGER_TOKEN,
GET_ENTITY_SPONSORSHIP_PRICING_PRESENTER_TOKEN,
GET_SPONSORS_PRESENTER_TOKEN,
CREATE_SPONSOR_PRESENTER_TOKEN,
GET_SPONSOR_DASHBOARD_PRESENTER_TOKEN,
GET_SPONSOR_SPONSORSHIPS_PRESENTER_TOKEN,
GET_SPONSOR_PRESENTER_TOKEN,
GET_PENDING_SPONSORSHIP_REQUESTS_PRESENTER_TOKEN,
ACCEPT_SPONSORSHIP_REQUEST_PRESENTER_TOKEN,
REJECT_SPONSORSHIP_REQUEST_PRESENTER_TOKEN,
GET_SPONSOR_BILLING_PRESENTER_TOKEN,
GET_SPONSOR_BILLING_USE_CASE_TOKEN, GET_SPONSOR_BILLING_USE_CASE_TOKEN,
} from './SponsorProviders'; LOGGER_TOKEN,
} from './SponsorTokens';
@Injectable() @Injectable()
export class SponsorService { export class SponsorService {
@@ -105,25 +95,15 @@ export class SponsorService {
@Inject(LOGGER_TOKEN) @Inject(LOGGER_TOKEN)
private readonly logger: Logger, private readonly logger: Logger,
// Injected presenters // Injected presenters
@Inject(GET_ENTITY_SPONSORSHIP_PRICING_PRESENTER_TOKEN)
private readonly getEntitySponsorshipPricingPresenter: GetEntitySponsorshipPricingPresenter, private readonly getEntitySponsorshipPricingPresenter: GetEntitySponsorshipPricingPresenter,
@Inject(GET_SPONSORS_PRESENTER_TOKEN)
private readonly getSponsorsPresenter: GetSponsorsPresenter, private readonly getSponsorsPresenter: GetSponsorsPresenter,
@Inject(CREATE_SPONSOR_PRESENTER_TOKEN)
private readonly createSponsorPresenter: CreateSponsorPresenter, private readonly createSponsorPresenter: CreateSponsorPresenter,
@Inject(GET_SPONSOR_DASHBOARD_PRESENTER_TOKEN)
private readonly getSponsorDashboardPresenter: GetSponsorDashboardPresenter, private readonly getSponsorDashboardPresenter: GetSponsorDashboardPresenter,
@Inject(GET_SPONSOR_SPONSORSHIPS_PRESENTER_TOKEN)
private readonly getSponsorSponsorshipsPresenter: GetSponsorSponsorshipsPresenter, private readonly getSponsorSponsorshipsPresenter: GetSponsorSponsorshipsPresenter,
@Inject(GET_SPONSOR_PRESENTER_TOKEN)
private readonly getSponsorPresenter: GetSponsorPresenter, private readonly getSponsorPresenter: GetSponsorPresenter,
@Inject(GET_PENDING_SPONSORSHIP_REQUESTS_PRESENTER_TOKEN)
private readonly getPendingSponsorshipRequestsPresenter: GetPendingSponsorshipRequestsPresenter, private readonly getPendingSponsorshipRequestsPresenter: GetPendingSponsorshipRequestsPresenter,
@Inject(ACCEPT_SPONSORSHIP_REQUEST_PRESENTER_TOKEN)
private readonly acceptSponsorshipRequestPresenter: AcceptSponsorshipRequestPresenter, private readonly acceptSponsorshipRequestPresenter: AcceptSponsorshipRequestPresenter,
@Inject(REJECT_SPONSORSHIP_REQUEST_PRESENTER_TOKEN)
private readonly rejectSponsorshipRequestPresenter: RejectSponsorshipRequestPresenter, private readonly rejectSponsorshipRequestPresenter: RejectSponsorshipRequestPresenter,
@Inject(GET_SPONSOR_BILLING_PRESENTER_TOKEN)
private readonly sponsorBillingPresenter: SponsorBillingPresenter, private readonly sponsorBillingPresenter: SponsorBillingPresenter,
) {} ) {}

View File

@@ -0,0 +1,47 @@
export const SPONSOR_REPOSITORY_TOKEN = 'ISponsorRepository';
export const SEASON_SPONSORSHIP_REPOSITORY_TOKEN = 'ISeasonSponsorshipRepository';
export const SEASON_REPOSITORY_TOKEN = 'ISeasonRepository';
export const LEAGUE_REPOSITORY_TOKEN = 'ILeagueRepository';
export const LEAGUE_MEMBERSHIP_REPOSITORY_TOKEN = 'ILeagueMembershipRepository';
export const RACE_REPOSITORY_TOKEN = 'IRaceRepository';
export const SPONSORSHIP_PRICING_REPOSITORY_TOKEN = 'ISponsorshipPricingRepository';
export const SPONSORSHIP_REQUEST_REPOSITORY_TOKEN = 'ISponsorshipRequestRepository';
export const LOGGER_TOKEN = 'Logger';
// Presenter tokens
export const GET_ENTITY_SPONSORSHIP_PRICING_PRESENTER_TOKEN = 'GetEntitySponsorshipPricingPresenter';
export const GET_SPONSORS_PRESENTER_TOKEN = 'GetSponsorsPresenter';
export const CREATE_SPONSOR_PRESENTER_TOKEN = 'CreateSponsorPresenter';
export const GET_SPONSOR_DASHBOARD_PRESENTER_TOKEN = 'GetSponsorDashboardPresenter';
export const GET_SPONSOR_SPONSORSHIPS_PRESENTER_TOKEN = 'GetSponsorSponsorshipsPresenter';
export const GET_SPONSOR_PRESENTER_TOKEN = 'GetSponsorPresenter';
export const GET_PENDING_SPONSORSHIP_REQUESTS_PRESENTER_TOKEN = 'GetPendingSponsorshipRequestsPresenter';
export const ACCEPT_SPONSORSHIP_REQUEST_PRESENTER_TOKEN = 'AcceptSponsorshipRequestPresenter';
export const REJECT_SPONSORSHIP_REQUEST_PRESENTER_TOKEN = 'RejectSponsorshipRequestPresenter';
export const GET_SPONSOR_BILLING_PRESENTER_TOKEN = 'SponsorBillingPresenter';
// Use case / application service tokens
export const GET_SPONSORSHIP_PRICING_USE_CASE_TOKEN = 'GetSponsorshipPricingUseCase';
export const GET_SPONSORS_USE_CASE_TOKEN = 'GetSponsorsUseCase';
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 GET_SPONSOR_BILLING_USE_CASE_TOKEN = 'GetSponsorBillingUseCase';
// Output port tokens
export const GET_SPONSORSHIP_PRICING_OUTPUT_PORT_TOKEN = 'GetSponsorshipPricingOutputPort_TOKEN';
export const GET_SPONSORS_OUTPUT_PORT_TOKEN = 'GetSponsorsOutputPort_TOKEN';
export const CREATE_SPONSOR_OUTPUT_PORT_TOKEN = 'CreateSponsorOutputPort_TOKEN';
export const GET_SPONSOR_DASHBOARD_OUTPUT_PORT_TOKEN = 'GetSponsorDashboardOutputPort_TOKEN';
export const GET_SPONSOR_SPONSORSHIPS_OUTPUT_PORT_TOKEN = 'GetSponsorSponsorshipsOutputPort_TOKEN';
export const GET_ENTITY_SPONSORSHIP_PRICING_OUTPUT_PORT_TOKEN = 'GetEntitySponsorshipPricingOutputPort_TOKEN';
export const GET_SPONSOR_OUTPUT_PORT_TOKEN = 'GetSponsorOutputPort_TOKEN';
export const GET_PENDING_SPONSORSHIP_REQUESTS_OUTPUT_PORT_TOKEN = 'GetPendingSponsorshipRequestsOutputPort_TOKEN';
export const ACCEPT_SPONSORSHIP_REQUEST_OUTPUT_PORT_TOKEN = 'AcceptSponsorshipRequestOutputPort_TOKEN';
export const REJECT_SPONSORSHIP_REQUEST_OUTPUT_PORT_TOKEN = 'RejectSponsorshipRequestOutputPort_TOKEN';
export const GET_SPONSOR_BILLING_OUTPUT_PORT_TOKEN = 'GetSponsorBillingOutputPort_TOKEN';

View File

@@ -5,15 +5,16 @@ WORKDIR /app
# Install bash for better shell capabilities # Install bash for better shell capabilities
RUN apk add --no-cache bash RUN apk add --no-cache bash
# Copy root package.json and install dependencies # Copy package manifests and install dependencies (incl. workspaces)
COPY package.json package-lock.json ./ COPY package.json package-lock.json ./
RUN npm ci COPY apps/website/package.json apps/website/package.json
RUN npm ci --workspaces --include-workspace-root
RUN find ./node_modules -name "next" -print || true # Debugging line RUN find ./node_modules -name "next" -print || true # Debugging line
# Copy apps/website and packages for development # Copy sources for development (monorepo)
COPY apps/website apps/website/ COPY apps/website apps/website/
COPY packages core/ COPY core core/
COPY apps/website/tsconfig.json apps/website/ COPY adapters adapters/
COPY scripts scripts/ COPY scripts scripts/
COPY tsconfig.base.json ./ COPY tsconfig.base.json ./

View File

@@ -2,21 +2,21 @@ FROM node:20-alpine AS builder
WORKDIR /app WORKDIR /app
# Copy package files and install dependencies # Copy package manifests and install dependencies (incl. workspaces)
COPY package.json package-lock.json ./ COPY package.json package-lock.json ./
RUN npm ci COPY apps/website/package.json apps/website/package.json
RUN npm ci --workspaces --include-workspace-root
# Copy apps/website, packages, and config for building # Copy sources and config for building (monorepo)
COPY apps/website apps/website/ COPY apps/website apps/website/
COPY packages core/ COPY core core/
COPY apps/website/tsconfig.json apps/website/ COPY adapters adapters/
COPY scripts scripts/ COPY scripts scripts/
COPY tsconfig.base.json ./ COPY tsconfig.base.json ./
# Build the Next.js application # Build the Next.js application from the workspace
# Run from the root workspace context RUN npm run env:website:merge && npm run build --workspace=@gridpilot/website
RUN node ./node_modules/next/dist/bin/next build
# Production stage: slim image with only production dependencies and built files # Production stage: slim image with only production dependencies and built files
@@ -28,10 +28,11 @@ WORKDIR /app
RUN apk add --no-cache wget RUN apk add --no-cache wget
# Copy package files and install production dependencies only # Copy package files and install production dependencies (incl. workspaces)
COPY --from=builder /app/package.json ./ COPY --from=builder /app/package.json ./
COPY --from=builder /app/package-lock.json ./ COPY --from=builder /app/package-lock.json ./
RUN npm ci --omit=dev COPY --from=builder /app/apps/website/package.json ./apps/website/package.json
RUN npm ci --omit=dev --workspaces --include-workspace-root
# Copy built Next.js application # Copy built Next.js application
COPY --from=builder /app/apps/website/.next ./apps/website/.next COPY --from=builder /app/apps/website/.next ./apps/website/.next
@@ -39,10 +40,8 @@ COPY --from=builder /app/apps/website/public ./apps/website/public
COPY --from=builder /app/apps/website/package.json ./apps/website/package.json COPY --from=builder /app/apps/website/package.json ./apps/website/package.json
COPY --from=builder /app/apps/website/next.config.mjs ./apps/website/next.config.mjs COPY --from=builder /app/apps/website/next.config.mjs ./apps/website/next.config.mjs
# Copy packages (needed for runtime dependencies)
COPY --from=builder /app/packages ./packages
ENV NODE_ENV=production ENV NODE_ENV=production
ENV NEXT_TELEMETRY_DISABLED=1 ENV NEXT_TELEMETRY_DISABLED=1
# Run Next.js in production mode from the root workspace context # Run Next.js in production mode (workspace context)
CMD ["node", "./node_modules/next/dist/bin/next", "start"] CMD ["npm", "run", "start", "--workspace=@gridpilot/website"]

View File

@@ -1,9 +1,14 @@
/** @type {import('next').NextConfig} */ /** @type {import('next').NextConfig} */
import path from 'path';
import { fileURLToPath } from 'url';
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const nextConfig = { const nextConfig = {
reactStrictMode: true, reactStrictMode: true,
// Fix for Next.js 13+ Turbopack in monorepos to correctly identify the workspace root // Fix for monorepos: point tracing to repo root (portable across machines/containers)
outputFileTracingRoot: '/Users/marcmintel/Projects/gridpilot', outputFileTracingRoot: path.join(__dirname, '../..'),
images: { images: {
remotePatterns: [ remotePatterns: [
{ {

View File

@@ -1,5 +1,3 @@
version: '3.8'
services: services:
api: api:
build: build:
@@ -12,6 +10,11 @@ services:
ports: ports:
- "3000:3000" - "3000:3000"
- "9229:9229" - "9229:9229"
volumes:
- ./apps/api:/app/apps/api
- ./core:/app/core
- ./adapters:/app/adapters
- ./tsconfig.base.json:/app/tsconfig.base.json:ro
depends_on: depends_on:
db: db:
condition: service_healthy condition: service_healthy
@@ -29,6 +32,12 @@ services:
- NEXT_TELEMETRY_DISABLED=1 - NEXT_TELEMETRY_DISABLED=1
ports: ports:
- "3001:3000" - "3001:3000"
volumes:
- ./apps/website:/app/apps/website
- ./core:/app/core
- ./adapters:/app/adapters
- ./scripts:/app/scripts
- ./tsconfig.base.json:/app/tsconfig.base.json:ro
networks: networks:
- gridpilot-network - gridpilot-network
restart: unless-stopped restart: unless-stopped
@@ -36,10 +45,8 @@ services:
db: db:
image: postgres:15-alpine image: postgres:15-alpine
restart: unless-stopped restart: unless-stopped
environment: env_file:
- POSTGRES_DB=${POSTGRES_DB:-gridpilot_db} - .env.development
- POSTGRES_USER=${POSTGRES_USER:-user}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-password}
ports: ports:
- "5432:5432" - "5432:5432"
volumes: volumes:
@@ -47,7 +54,7 @@ services:
networks: networks:
- gridpilot-network - gridpilot-network
healthcheck: healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-user} -d ${POSTGRES_DB:-gridpilot_db}"] test: ["CMD-SHELL", "pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB"]
interval: 5s interval: 5s
timeout: 5s timeout: 5s
retries: 5 retries: 5

View File

@@ -1,6 +1,4 @@
version: '3.8'
services: services:
api: api:
build: build:
@@ -151,7 +149,7 @@ services:
cpus: '0.25' cpus: '0.25'
memory: 256M memory: 256M
healthcheck: healthcheck:
test: ["CMD", "redis-cli", "--raw", "incr", "ping"] test: ["CMD-SHELL", "redis-cli -a \"$${REDIS_PASSWORD:-CHANGE_ME_IN_PRODUCTION}\" ping"]
interval: 10s interval: 10s
timeout: 3s timeout: 3s
retries: 5 retries: 5