website refactor

This commit is contained in:
2026-01-16 21:44:26 +01:00
parent 2d322b42e1
commit 83a9092c50
327 changed files with 1086 additions and 1088 deletions

View File

@@ -1,5 +1,6 @@
import { MiddlewareConsumer, Module, type NestModule } from '@nestjs/common';
import { AdminModule } from './domain/admin/AdminModule';
import { AnalyticsModule } from './domain/analytics/AnalyticsModule';
import { AuthModule } from './domain/auth/AuthModule';
import { BootstrapModule } from './domain/bootstrap/BootstrapModule';
@@ -12,7 +13,6 @@ import { LoggingModule } from './domain/logging/LoggingModule';
import { MediaModule } from './domain/media/MediaModule';
import { NotificationsModule } from './domain/notifications/NotificationsModule';
import { PaymentsModule } from './domain/payments/PaymentsModule';
import { AdminModule } from './domain/admin/AdminModule';
import { PolicyModule } from './domain/policy/PolicyModule';
import { ProtestsModule } from './domain/protests/ProtestsModule';
import { RaceModule } from './domain/race/RaceModule';

View File

@@ -4,8 +4,8 @@
* Run with: npm test -- feature-loader.test.ts
*/
import { describe, it, expect, beforeEach } from 'vitest';
import { loadFeatureConfig, isFeatureEnabled, getFeatureState, getAllFeatures } from './feature-loader';
import { beforeEach, describe, expect, it } from 'vitest';
import { getAllFeatures, getFeatureState, isFeatureEnabled, loadFeatureConfig } from './feature-loader';
import { FlattenedFeatures } from './feature-types';
describe('Feature Flag Configuration', () => {

View File

@@ -1,10 +1,10 @@
import { featureConfig } from './features.config';
import {
FeatureFlagConfig,
FlattenedFeatures,
ConfigLoadResult,
FeatureState
import {
ConfigLoadResult,
FeatureFlagConfig,
FeatureState,
FlattenedFeatures
} from './feature-types';
import { featureConfig } from './features.config';
/**
* Default configuration path relative to project root

View File

@@ -2,8 +2,8 @@
* Integration test to verify the feature flag system works end-to-end
*/
import { describe, it, expect } from 'vitest';
import { loadFeatureConfig, isFeatureEnabled, getFeatureState } from './feature-loader';
import { describe, expect, it } from 'vitest';
import { getFeatureState, isFeatureEnabled, loadFeatureConfig } from './feature-loader';
describe('Feature Flag Integration Test', () => {
it('should load config and provide correct feature states', async () => {

View File

@@ -1,6 +1,6 @@
import 'reflect-metadata';
import { ValidationPipe, INestApplication } from '@nestjs/common';
import { INestApplication, ValidationPipe } from '@nestjs/common';
import { Reflector } from '@nestjs/core';
import { Test } from '@nestjs/testing';
import request from 'supertest';

View File

@@ -1,8 +1,8 @@
import { describe, it, expect, vi } from 'vitest';
import { describe, expect, it, vi } from 'vitest';
import { AdminController } from './AdminController';
import { DashboardStatsResponseDto } from './dto/DashboardStatsResponseDto';
import { ListUsersRequestDto } from './dtos/ListUsersRequestDto';
import { UserListResponseDto, UserResponseDto } from './dtos/UserResponseDto';
import { DashboardStatsResponseDto } from './dto/DashboardStatsResponseDto';
describe('AdminController', () => {
let controller: AdminController;

View File

@@ -1,14 +1,14 @@
import type { ListUsersInput } from '@core/admin/application/use-cases/ListUsersUseCase';
import { Controller, Get, Inject, Query, Req, UseGuards } from '@nestjs/common';
import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
import { AdminService } from './AdminService';
import { ListUsersRequestDto } from './dtos/ListUsersRequestDto';
import { UserListResponseDto } from './dtos/UserResponseDto';
import { DashboardStatsResponseDto } from './dto/DashboardStatsResponseDto';
import type { Request } from 'express';
import { AuthorizationGuard } from '../auth/AuthorizationGuard';
import { RequireAuthenticatedUser } from '../auth/RequireAuthenticatedUser';
import { RequireRoles } from '../auth/RequireRoles';
import { AuthorizationGuard } from '../auth/AuthorizationGuard';
import type { Request } from 'express';
import type { ListUsersInput } from '@core/admin/application/use-cases/ListUsersUseCase';
import { AdminService } from './AdminService';
import { DashboardStatsResponseDto } from './dto/DashboardStatsResponseDto';
import { ListUsersRequestDto } from './dtos/ListUsersRequestDto';
import { UserListResponseDto } from './dtos/UserResponseDto';
@ApiTags('admin')
@Controller('admin')

View File

@@ -1,13 +1,13 @@
import { ListUsersUseCase } from '@core/admin/application/use-cases/ListUsersUseCase';
import type { IAdminUserRepository } from '@core/admin/domain/repositories/AdminUserRepository';
import type { Provider } from '@nestjs/common';
import { Module } from '@nestjs/common';
import { InMemoryAdminPersistenceModule } from '../../persistence/inmemory/InMemoryAdminPersistenceModule';
import { AdminService } from './AdminService';
import { AdminController } from './AdminController';
import { AuthModule } from '../auth/AuthModule';
import { ListUsersUseCase } from '@core/admin/application/use-cases/ListUsersUseCase';
import { GetDashboardStatsUseCase } from './use-cases/GetDashboardStatsUseCase';
import { InitializationLogger } from '../../shared/logging/InitializationLogger';
import type { IAdminUserRepository } from '@core/admin/domain/repositories/AdminUserRepository';
import { AuthModule } from '../auth/AuthModule';
import { AdminController } from './AdminController';
import { AdminService } from './AdminService';
import { GetDashboardStatsUseCase } from './use-cases/GetDashboardStatsUseCase';
export const ADMIN_USER_REPOSITORY_TOKEN = 'IAdminUserRepository';

View File

@@ -1,7 +1,7 @@
import { AdminService } from './AdminService';
import { AdminUser } from '@core/admin/domain/entities/AdminUser';
import { Result } from '@core/shared/domain/Result';
import { vi, describe, it, expect, beforeEach } from 'vitest';
import { beforeEach, describe, expect, it, vi } from 'vitest';
import { AdminService } from './AdminService';
// Mock use cases
const mockListUsersUseCase = {

View File

@@ -1,9 +1,9 @@
import { Injectable } from '@nestjs/common';
import { ListUsersUseCase, ListUsersInput, ListUsersResult } from '@core/admin/application/use-cases/ListUsersUseCase';
import { GetDashboardStatsUseCase, GetDashboardStatsInput } from './use-cases/GetDashboardStatsUseCase';
import { UserListResponseDto, UserResponseDto } from './dtos/UserResponseDto';
import { DashboardStatsResponseDto } from './dto/DashboardStatsResponseDto';
import { ListUsersInput, ListUsersResult, ListUsersUseCase } from '@core/admin/application/use-cases/ListUsersUseCase';
import type { AdminUser } from '@core/admin/domain/entities/AdminUser';
import { Injectable } from '@nestjs/common';
import { DashboardStatsResponseDto } from './dto/DashboardStatsResponseDto';
import { UserListResponseDto, UserResponseDto } from './dtos/UserResponseDto';
import { GetDashboardStatsInput, GetDashboardStatsUseCase } from './use-cases/GetDashboardStatsUseCase';
@Injectable()
export class AdminService {

View File

@@ -1,5 +1,5 @@
import { ApiPropertyOptional } from '@nestjs/swagger';
import { IsOptional, IsString, IsNumber, Min, Max } from 'class-validator';
import { IsNumber, IsOptional, IsString, Max, Min } from 'class-validator';
export class ListUsersRequestDto {
@ApiPropertyOptional({

View File

@@ -1,6 +1,6 @@
import { ListUsersPresenter } from './ListUsersPresenter';
import { ListUsersResult } from '@core/admin/application/use-cases/ListUsersUseCase';
import { AdminUser } from '@core/admin/domain/entities/AdminUser';
import { ListUsersPresenter } from './ListUsersPresenter';
describe('ListUsersPresenter', () => {
describe('TDD - Test First', () => {

View File

@@ -1,7 +1,7 @@
import { UseCaseOutputPort } from '@core/shared/application/UseCaseOutputPort';
import { ListUsersResult } from '@core/admin/application/use-cases/ListUsersUseCase';
import { UserListResponseDto, UserResponseDto } from '../dtos/UserResponseDto';
import type { AdminUser } from '@core/admin/domain/entities/AdminUser';
import { UseCaseOutputPort } from '@core/shared/application/UseCaseOutputPort';
import { UserListResponseDto, UserResponseDto } from '../dtos/UserResponseDto';
export type ListUsersViewModel = UserListResponseDto;

View File

@@ -1,8 +1,8 @@
import { Result } from '@core/shared/domain/Result';
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
import type { IAdminUserRepository } from '@core/admin/domain/repositories/AdminUserRepository';
import { AuthorizationService } from '@core/admin/domain/services/AuthorizationService';
import { UserId } from '@core/admin/domain/value-objects/UserId';
import { Result } from '@core/shared/domain/Result';
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
export interface DashboardStatsResult {
totalUsers: number;

View File

@@ -1,21 +1,21 @@
import 'reflect-metadata';
import { EngagementAction, EngagementEntityType } from '@core/analytics/domain/types/EngagementEvent';
import { EntityType, VisitorType } from '@core/analytics/domain/types/PageView';
import { Reflector } from '@nestjs/core';
import { Test } from '@nestjs/testing';
import type { Response } from 'express';
import request from 'supertest';
import { vi } from 'vitest';
import { AnalyticsController } from './AnalyticsController';
import { AnalyticsService } from './AnalyticsService';
import type { Response } from 'express';
import { EntityType, VisitorType } from '@core/analytics/domain/types/PageView';
import { EngagementAction, EngagementEntityType } from '@core/analytics/domain/types/EngagementEvent';
import type { RecordEngagementOutputDTO } from './dtos/RecordEngagementOutputDTO';
import type { RecordPageViewOutputDTO } from './dtos/RecordPageViewOutputDTO';
import { AuthenticationGuard } from '../auth/AuthenticationGuard';
import { AuthorizationGuard } from '../auth/AuthorizationGuard';
import type { AuthorizationService } from '../auth/AuthorizationService';
import { FeatureAvailabilityGuard } from '../policy/FeatureAvailabilityGuard';
import type { PolicyService, PolicySnapshot } from '../policy/PolicyService';
import { AnalyticsController } from './AnalyticsController';
import { AnalyticsService } from './AnalyticsService';
import type { RecordEngagementOutputDTO } from './dtos/RecordEngagementOutputDTO';
import type { RecordPageViewOutputDTO } from './dtos/RecordPageViewOutputDTO';
describe('AnalyticsController', () => {
let controller: AnalyticsController;

View File

@@ -1,14 +1,14 @@
import { Controller, Get, Post, Body, Res, HttpStatus, Inject } from '@nestjs/common';
import { ApiTags, ApiOperation, ApiBody, ApiResponse } from '@nestjs/swagger';
import { Body, Controller, Get, HttpStatus, Inject, Post, Res } from '@nestjs/common';
import { ApiBody, ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
import type { Response } from 'express';
import { Public } from '../auth/Public';
import { RecordPageViewInputDTO } from './dtos/RecordPageViewInputDTO';
import { RecordPageViewOutputDTO } from './dtos/RecordPageViewOutputDTO';
import { AnalyticsService } from './AnalyticsService';
import { GetAnalyticsMetricsOutputDTO } from './dtos/GetAnalyticsMetricsOutputDTO';
import { GetDashboardDataOutputDTO } from './dtos/GetDashboardDataOutputDTO';
import { RecordEngagementInputDTO } from './dtos/RecordEngagementInputDTO';
import { RecordEngagementOutputDTO } from './dtos/RecordEngagementOutputDTO';
import { GetDashboardDataOutputDTO } from './dtos/GetDashboardDataOutputDTO';
import { GetAnalyticsMetricsOutputDTO } from './dtos/GetAnalyticsMetricsOutputDTO';
import { AnalyticsService } from './AnalyticsService';
import { RecordPageViewInputDTO } from './dtos/RecordPageViewInputDTO';
import { RecordPageViewOutputDTO } from './dtos/RecordPageViewOutputDTO';
type RecordPageViewInput = RecordPageViewInputDTO;
type RecordEngagementInput = RecordEngagementInputDTO;

View File

@@ -1,6 +1,6 @@
import { Test, TestingModule } from '@nestjs/testing';
import { AnalyticsModule } from './AnalyticsModule';
import { AnalyticsController } from './AnalyticsController';
import { AnalyticsModule } from './AnalyticsModule';
import { AnalyticsService } from './AnalyticsService';
describe('AnalyticsModule', () => {

View File

@@ -2,8 +2,8 @@ import { Module } from '@nestjs/common';
import { AnalyticsPersistenceModule } from '../../persistence/analytics/AnalyticsPersistenceModule';
import { AnalyticsController } from './AnalyticsController';
import { AnalyticsService } from './AnalyticsService';
import { AnalyticsProviders } from './AnalyticsProviders';
import { AnalyticsService } from './AnalyticsService';
@Module({
imports: [AnalyticsPersistenceModule],

View File

@@ -1,10 +1,10 @@
import { describe, expect, it, vi } from 'vitest';
import { Result } from '@core/shared/domain/Result';
import { describe, expect, it, vi } from 'vitest';
import { AnalyticsService } from './AnalyticsService';
import { RecordPageViewPresenter } from './presenters/RecordPageViewPresenter';
import { RecordEngagementPresenter } from './presenters/RecordEngagementPresenter';
import { GetDashboardDataPresenter } from './presenters/GetDashboardDataPresenter';
import { GetAnalyticsMetricsPresenter } from './presenters/GetAnalyticsMetricsPresenter';
import { GetDashboardDataPresenter } from './presenters/GetDashboardDataPresenter';
import { RecordEngagementPresenter } from './presenters/RecordEngagementPresenter';
import { RecordPageViewPresenter } from './presenters/RecordPageViewPresenter';
describe('AnalyticsService', () => {
it('recordPageView returns presenter response on success', async () => {

View File

@@ -1,6 +1,6 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsString, IsOptional, IsEnum, IsObject } from 'class-validator';
import { EngagementAction, EngagementEntityType } from '@core/analytics/domain/types/EngagementEvent';
import { ApiProperty } from '@nestjs/swagger';
import { IsEnum, IsObject, IsOptional, IsString } from 'class-validator';
export class RecordEngagementInputDTO {
@ApiProperty({ enum: EngagementAction })

View File

@@ -1,5 +1,5 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsString, IsNumber } from 'class-validator';
import { IsNumber, IsString } from 'class-validator';
export class RecordEngagementOutputDTO {
@ApiProperty()

View File

@@ -1,6 +1,6 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsString, IsOptional, IsEnum } from 'class-validator';
import { EntityType, VisitorType } from '@core/analytics/domain/types/PageView';
import { ApiProperty } from '@nestjs/swagger';
import { IsEnum, IsOptional, IsString } from 'class-validator';
export class RecordPageViewInputDTO {
@ApiProperty({ enum: EntityType })

View File

@@ -1,6 +1,6 @@
import { describe, it, expect, beforeEach } from 'vitest';
import { GetAnalyticsMetricsPresenter } from './GetAnalyticsMetricsPresenter';
import type { GetAnalyticsMetricsOutput } from '@core/analytics/application/use-cases/GetAnalyticsMetricsUseCase';
import { beforeEach, describe, expect, it } from 'vitest';
import { GetAnalyticsMetricsPresenter } from './GetAnalyticsMetricsPresenter';
describe('GetAnalyticsMetricsPresenter', () => {
let presenter: GetAnalyticsMetricsPresenter;

View File

@@ -1,6 +1,6 @@
import { describe, it, expect, beforeEach } from 'vitest';
import { GetDashboardDataPresenter } from './GetDashboardDataPresenter';
import type { GetDashboardDataOutput } from '@core/analytics/application/use-cases/GetDashboardDataUseCase';
import { beforeEach, describe, expect, it } from 'vitest';
import { GetDashboardDataPresenter } from './GetDashboardDataPresenter';
describe('GetDashboardDataPresenter', () => {
let presenter: GetDashboardDataPresenter;

View File

@@ -1,6 +1,6 @@
import { describe, it, expect, beforeEach } from 'vitest';
import { RecordEngagementPresenter } from './RecordEngagementPresenter';
import type { RecordEngagementOutput } from '@core/analytics/application/use-cases/RecordEngagementUseCase';
import { beforeEach, describe, expect, it } from 'vitest';
import { RecordEngagementPresenter } from './RecordEngagementPresenter';
describe('RecordEngagementPresenter', () => {
let presenter: RecordEngagementPresenter;

View File

@@ -1,6 +1,6 @@
import { describe, it, expect, beforeEach } from 'vitest';
import { RecordPageViewPresenter } from './RecordPageViewPresenter';
import type { RecordPageViewOutput } from '@core/analytics/application/use-cases/RecordPageViewUseCase';
import { beforeEach, describe, expect, it } from 'vitest';
import { RecordPageViewPresenter } from './RecordPageViewPresenter';
describe('RecordPageViewPresenter', () => {
let presenter: RecordPageViewPresenter;

View File

@@ -1,8 +1,8 @@
import { describe, expect, it, vi } from 'vitest';
import { requestContextMiddleware } from '@adapters/http/RequestContext';
import { Result } from '@core/shared/domain/Result';
import { getActorFromRequestContext } from './getActorFromRequestContext';
import { describe, expect, it, vi } from 'vitest';
import { requireLeagueAdminOrOwner } from '../league/LeagueAuthorization';
import { getActorFromRequestContext } from './getActorFromRequestContext';
async function withRequestContext<T>(req: Record<string, unknown>, fn: () => Promise<T>): Promise<T> {
const res = {};

View File

@@ -4,15 +4,15 @@ import { Reflector } from '@nestjs/core';
import { Test } from '@nestjs/testing';
import request from 'supertest';
import { Mock, vi } from 'vitest';
import { FeatureAvailabilityGuard } from '../policy/FeatureAvailabilityGuard';
import type { PolicyService, PolicySnapshot } from '../policy/PolicyService';
import { AuthController } from './AuthController';
import { AuthService } from './AuthService';
import { AuthSessionDTO, LoginParamsDTO, SignupParamsDTO, SignupSponsorParamsDTO } from './dtos/AuthDto';
import type { CommandResultDTO } from './presenters/CommandResultPresenter';
import { AuthenticationGuard } from './AuthenticationGuard';
import { AuthorizationGuard } from './AuthorizationGuard';
import type { AuthorizationService } from './AuthorizationService';
import { FeatureAvailabilityGuard } from '../policy/FeatureAvailabilityGuard';
import type { PolicyService, PolicySnapshot } from '../policy/PolicyService';
import { AuthService } from './AuthService';
import { AuthSessionDTO, LoginParamsDTO, SignupParamsDTO, SignupSponsorParamsDTO } from './dtos/AuthDto';
import type { CommandResultDTO } from './presenters/CommandResultPresenter';
describe('AuthController', () => {
let controller: AuthController;

View File

@@ -1,9 +1,9 @@
import { Controller, Get, Post, Body, Query, Inject, Res, BadRequestException, UnauthorizedException } from '@nestjs/common';
import { Public } from './Public';
import { AuthService } from './AuthService';
import { LoginParamsDTO, SignupParamsDTO, SignupSponsorParamsDTO, AuthSessionDTO, ForgotPasswordDTO, ResetPasswordDTO } from './dtos/AuthDto';
import type { CommandResultDTO } from './presenters/CommandResultPresenter';
import { BadRequestException, Body, Controller, Get, Inject, Post, Query, Res, UnauthorizedException } from '@nestjs/common';
import type { Response } from 'express';
import { AuthService } from './AuthService';
import { AuthSessionDTO, ForgotPasswordDTO, LoginParamsDTO, ResetPasswordDTO, SignupParamsDTO, SignupSponsorParamsDTO } from './dtos/AuthDto';
import type { CommandResultDTO } from './presenters/CommandResultPresenter';
import { Public } from './Public';
@Public()
@Controller('auth')

View File

@@ -5,14 +5,14 @@ import { Reflector } from '@nestjs/core';
import { Test } from '@nestjs/testing';
import request from 'supertest';
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
import { FeatureAvailabilityGuard } from '../policy/FeatureAvailabilityGuard';
import { PolicyService, type PolicySnapshot } from '../policy/PolicyService';
import { RequireCapability } from '../policy/RequireCapability';
import { AuthenticationGuard } from './AuthenticationGuard';
import { AuthorizationGuard } from './AuthorizationGuard';
import { AuthorizationService } from './AuthorizationService';
import { Public } from './Public';
import { RequireRoles } from './RequireRoles';
import { FeatureAvailabilityGuard } from '../policy/FeatureAvailabilityGuard';
import { PolicyService, type PolicySnapshot } from '../policy/PolicyService';
import { RequireCapability } from '../policy/RequireCapability';
@Controller('authz-test')
class AuthzTestController {

View File

@@ -1,6 +1,6 @@
import { Test, TestingModule } from '@nestjs/testing';
import { AuthModule } from './AuthModule';
import { AuthController } from './AuthController';
import { AuthModule } from './AuthModule';
import { AuthService } from './AuthService';
describe('AuthModule', () => {

View File

@@ -1,9 +1,9 @@
import { Module } from '@nestjs/common';
import { IdentityPersistenceModule } from '../../persistence/identity/IdentityPersistenceModule';
import { InMemoryAdminPersistenceModule } from '../../persistence/inmemory/InMemoryAdminPersistenceModule';
import { AuthService } from './AuthService';
import { AuthController } from './AuthController';
import { AuthProviders } from './AuthProviders';
import { AuthService } from './AuthService';
import { AuthenticationGuard } from './AuthenticationGuard';
import { AuthorizationGuard } from './AuthorizationGuard';
import { AuthorizationService } from './AuthorizationService';

View File

@@ -1,5 +1,5 @@
import { describe, expect, it, vi } from 'vitest';
import { Result } from '@core/shared/domain/Result';
import { describe, expect, it, vi } from 'vitest';
import { AuthService } from './AuthService';
class FakeAuthSessionPresenter {

View File

@@ -1,5 +1,5 @@
import { CanActivate, ExecutionContext, Inject, Injectable } from '@nestjs/common';
import type { IdentitySessionPort } from '@core/identity/application/ports/IdentitySessionPort';
import { CanActivate, ExecutionContext, Inject, Injectable } from '@nestjs/common';
import { IDENTITY_SESSION_PORT_TOKEN } from './AuthProviders';
type AuthenticatedRequest = {

View File

@@ -1,5 +1,5 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsEmail, IsString, MinLength, IsOptional } from 'class-validator';
import { IsEmail, IsOptional, IsString, MinLength } from 'class-validator';
export class AuthenticatedUserDTO {
@ApiProperty()

View File

@@ -1,8 +1,8 @@
import { describe, it, expect, beforeEach } from 'vitest';
import { AuthSessionPresenter } from './AuthSessionPresenter';
import { User } from '@core/identity/domain/entities/User';
import { UserId } from '@core/identity/domain/value-objects/UserId';
import { PasswordHash } from '@core/identity/domain/value-objects/PasswordHash';
import { UserId } from '@core/identity/domain/value-objects/UserId';
import { beforeEach, describe, expect, it } from 'vitest';
import { AuthSessionPresenter } from './AuthSessionPresenter';
describe('AuthSessionPresenter', () => {
let presenter: AuthSessionPresenter;

View File

@@ -1,8 +1,8 @@
import type { LoginResult } from '@core/identity/application/use-cases/LoginUseCase';
import type { SignupSponsorResult } from '@core/identity/application/use-cases/SignupSponsorUseCase';
import type { SignupResult } from '@core/identity/application/use-cases/SignupUseCase';
import type { UseCaseOutputPort } from '@core/shared/application/UseCaseOutputPort';
import { AuthenticatedUserDTO } from '../dtos/AuthDto';
import type { LoginResult } from '@core/identity/application/use-cases/LoginUseCase';
import type { SignupResult } from '@core/identity/application/use-cases/SignupUseCase';
import type { SignupSponsorResult } from '@core/identity/application/use-cases/SignupSponsorUseCase';
type AuthSessionResult = LoginResult | SignupResult | SignupSponsorResult;

View File

@@ -1,4 +1,4 @@
import { describe, it, expect, beforeEach } from 'vitest';
import { beforeEach, describe, expect, it } from 'vitest';
import { CommandResultPresenter } from './CommandResultPresenter';
describe('CommandResultPresenter', () => {

View File

@@ -1,5 +1,5 @@
import type { UseCaseOutputPort } from '@core/shared/application/UseCaseOutputPort';
import type { LogoutResult } from '@core/identity/application/use-cases/LogoutUseCase';
import type { UseCaseOutputPort } from '@core/shared/application/UseCaseOutputPort';
export interface CommandResultDTO {
success: boolean;

View File

@@ -1,6 +1,6 @@
import { Injectable } from '@nestjs/common';
import { UseCaseOutputPort } from '@core/shared/application';
import { ForgotPasswordResult } from '@core/identity/application/use-cases/ForgotPasswordUseCase';
import { UseCaseOutputPort } from '@core/shared/application';
import { Injectable } from '@nestjs/common';
@Injectable()
export class ForgotPasswordPresenter implements UseCaseOutputPort<ForgotPasswordResult> {

View File

@@ -1,6 +1,6 @@
import { Injectable } from '@nestjs/common';
import { UseCaseOutputPort } from '@core/shared/application';
import { ResetPasswordResult } from '@core/identity/application/use-cases/ResetPasswordUseCase';
import { UseCaseOutputPort } from '@core/shared/application';
import { Injectable } from '@nestjs/common';
@Injectable()
export class ResetPasswordPresenter implements UseCaseOutputPort<ResetPasswordResult> {

View File

@@ -1,7 +1,7 @@
import 'reflect-metadata';
import { Test } from '@nestjs/testing';
import type { TestingModule } from '@nestjs/testing';
import { Test } from '@nestjs/testing';
import request from 'supertest';
import { afterAll, beforeAll, describe, expect, it, vi } from 'vitest';

View File

@@ -1,5 +1,5 @@
import { describe, expect, it } from 'vitest';
import { createRacingSeed } from '@adapters/bootstrap/racing/RacingSeed';
import { describe, expect, it } from 'vitest';
describe('Racing seed (bootstrap)', () => {
it('creates a large, internally consistent seed', () => {

View File

@@ -4,14 +4,14 @@ import { Reflector } from '@nestjs/core';
import { Test } from '@nestjs/testing';
import request from 'supertest';
import { vi } from 'vitest';
import { DashboardController } from './DashboardController';
import { DashboardOverviewDTO } from './dtos/DashboardOverviewDTO';
import { AuthenticationGuard } from '../auth/AuthenticationGuard';
import { AuthorizationGuard } from '../auth/AuthorizationGuard';
import type { AuthorizationService } from '../auth/AuthorizationService';
import { FeatureAvailabilityGuard } from '../policy/FeatureAvailabilityGuard';
import type { PolicyService, PolicySnapshot } from '../policy/PolicyService';
import { DashboardController } from './DashboardController';
import { DashboardService } from './DashboardService';
import { DashboardOverviewDTO } from './dtos/DashboardOverviewDTO';
describe('DashboardController', () => {
let controller: DashboardController;

View File

@@ -1,5 +1,5 @@
import { Controller, Get, Query, Req, UnauthorizedException, Inject } from '@nestjs/common';
import { ApiTags, ApiResponse, ApiOperation, ApiQuery } from '@nestjs/swagger';
import { Controller, Get, Inject, Query, Req, UnauthorizedException } from '@nestjs/common';
import { ApiOperation, ApiQuery, ApiResponse, ApiTags } from '@nestjs/swagger';
import { DashboardService } from './DashboardService';
import { DashboardOverviewDTO } from './dtos/DashboardOverviewDTO';

View File

@@ -1,6 +1,6 @@
import { Test, TestingModule } from '@nestjs/testing';
import { DashboardModule } from './DashboardModule';
import { DashboardController } from './DashboardController';
import { DashboardModule } from './DashboardModule';
import { DashboardService } from './DashboardService';
import { DashboardOverviewPresenter } from './presenters/DashboardOverviewPresenter';

View File

@@ -1,9 +1,9 @@
import { Module } from '@nestjs/common';
import { RacingPersistenceModule } from '../../persistence/racing/RacingPersistenceModule';
import { SocialPersistenceModule } from '../../persistence/social/SocialPersistenceModule';
import { DashboardService } from './DashboardService';
import { DashboardController } from './DashboardController';
import { DashboardProviders } from './DashboardProviders';
import { DashboardService } from './DashboardService';
@Module({
imports: [RacingPersistenceModule, SocialPersistenceModule],

View File

@@ -1,50 +1,50 @@
import { Provider } from '@nestjs/common';
// Import core interfaces
import type { Logger } from '@core/shared/application/Logger';
import { IDriverRepository } from '@core/racing/domain/repositories/DriverRepository';
import { ILeagueMembershipRepository } from '@core/racing/domain/repositories/LeagueMembershipRepository';
import { ILeagueRepository } from '@core/racing/domain/repositories/LeagueRepository';
import { IRaceRegistrationRepository } from '@core/racing/domain/repositories/RaceRegistrationRepository';
import { IRaceRepository } from '@core/racing/domain/repositories/RaceRepository';
import { IResultRepository } from '@core/racing/domain/repositories/ResultRepository';
import { ILeagueRepository } from '@core/racing/domain/repositories/LeagueRepository';
import { IStandingRepository } from '@core/racing/domain/repositories/StandingRepository';
import { ILeagueMembershipRepository } from '@core/racing/domain/repositories/LeagueMembershipRepository';
import { IRaceRegistrationRepository } from '@core/racing/domain/repositories/RaceRegistrationRepository';
import type { Logger } from '@core/shared/application/Logger';
import { IFeedRepository } from '@core/social/domain/repositories/FeedRepository';
import { ISocialGraphRepository } from '@core/social/domain/repositories/SocialGraphRepository';
import { SOCIAL_FEED_REPOSITORY_TOKEN, SOCIAL_GRAPH_REPOSITORY_TOKEN } from '../../persistence/social/SocialPersistenceTokens';
import { ImageServicePort } from '@core/media/application/ports/ImageServicePort';
import { DashboardOverviewUseCase } from '@core/racing/application/use-cases/DashboardOverviewUseCase';
import { SOCIAL_FEED_REPOSITORY_TOKEN, SOCIAL_GRAPH_REPOSITORY_TOKEN } from '../../persistence/social/SocialPersistenceTokens';
// Import concrete implementations
import { ConsoleLogger } from '@adapters/logging/ConsoleLogger';
import { InMemoryImageServiceAdapter } from '@adapters/media/ports/InMemoryImageServiceAdapter';
import { DashboardOverviewPresenter } from './presenters/DashboardOverviewPresenter';
import {
DASHBOARD_OVERVIEW_USE_CASE_TOKEN,
DRIVER_REPOSITORY_TOKEN,
IMAGE_SERVICE_TOKEN,
LEAGUE_MEMBERSHIP_REPOSITORY_TOKEN,
LEAGUE_REPOSITORY_TOKEN,
LOGGER_TOKEN,
RACE_REGISTRATION_REPOSITORY_TOKEN,
RACE_REPOSITORY_TOKEN,
RESULT_REPOSITORY_TOKEN,
STANDING_REPOSITORY_TOKEN,
DASHBOARD_OVERVIEW_USE_CASE_TOKEN,
DRIVER_REPOSITORY_TOKEN,
IMAGE_SERVICE_TOKEN,
LEAGUE_MEMBERSHIP_REPOSITORY_TOKEN,
LEAGUE_REPOSITORY_TOKEN,
LOGGER_TOKEN,
RACE_REGISTRATION_REPOSITORY_TOKEN,
RACE_REPOSITORY_TOKEN,
RESULT_REPOSITORY_TOKEN,
STANDING_REPOSITORY_TOKEN,
} from './DashboardTokens';
import { DashboardOverviewPresenter } from './presenters/DashboardOverviewPresenter';
// Re-export tokens for convenience (legacy imports)
export {
DASHBOARD_OVERVIEW_USE_CASE_TOKEN,
DRIVER_REPOSITORY_TOKEN,
IMAGE_SERVICE_TOKEN,
LEAGUE_MEMBERSHIP_REPOSITORY_TOKEN,
LEAGUE_REPOSITORY_TOKEN,
LOGGER_TOKEN,
RACE_REGISTRATION_REPOSITORY_TOKEN,
RACE_REPOSITORY_TOKEN,
RESULT_REPOSITORY_TOKEN,
STANDING_REPOSITORY_TOKEN,
DASHBOARD_OVERVIEW_USE_CASE_TOKEN,
DRIVER_REPOSITORY_TOKEN,
IMAGE_SERVICE_TOKEN,
LEAGUE_MEMBERSHIP_REPOSITORY_TOKEN,
LEAGUE_REPOSITORY_TOKEN,
LOGGER_TOKEN,
RACE_REGISTRATION_REPOSITORY_TOKEN,
RACE_REPOSITORY_TOKEN,
RESULT_REPOSITORY_TOKEN,
STANDING_REPOSITORY_TOKEN
} from './DashboardTokens';
export const DashboardProviders: Provider[] = [

View File

@@ -1,5 +1,5 @@
import { describe, expect, it, vi } from 'vitest';
import { Result } from '@core/shared/domain/Result';
import { describe, expect, it, vi } from 'vitest';
import { DashboardService } from './DashboardService';
describe('DashboardService', () => {

View File

@@ -8,8 +8,8 @@ import type { Logger } from '@core/shared/application/Logger';
// Tokens (standalone to avoid circular imports)
import {
DASHBOARD_OVERVIEW_USE_CASE_TOKEN,
LOGGER_TOKEN,
DASHBOARD_OVERVIEW_USE_CASE_TOKEN,
LOGGER_TOKEN,
} from './DashboardTokens';
@Injectable()

View File

@@ -1,5 +1,5 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsString, IsNumber, IsOptional } from 'class-validator';
import { IsNumber, IsOptional, IsString } from 'class-validator';
export class DashboardDriverSummaryDTO {
@ApiProperty()

View File

@@ -1,5 +1,5 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsString, IsOptional } from 'class-validator';
import { IsOptional, IsString } from 'class-validator';
export type DashboardFeedItemType =
| 'friend-joined-league'

View File

@@ -1,5 +1,5 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsString, IsNumber } from 'class-validator';
import { IsNumber, IsString } from 'class-validator';
export class DashboardLeagueStandingSummaryDTO {
@ApiProperty()

View File

@@ -1,6 +1,6 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsString, IsNumber, IsOptional, IsBoolean, IsArray, ValidateNested } from 'class-validator';
import { Type } from 'class-transformer';
import { IsArray, IsBoolean, IsNumber, IsOptional, IsString, ValidateNested } from 'class-validator';
export class DashboardDriverSummaryDTO {
@ApiProperty()

View File

@@ -1,5 +1,5 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsString, IsBoolean } from 'class-validator';
import { IsBoolean, IsString } from 'class-validator';
export class DashboardRaceSummaryDTO {
@ApiProperty()

View File

@@ -1,5 +1,5 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsString, IsNumber } from 'class-validator';
import { IsNumber, IsString } from 'class-validator';
export class DashboardRecentResultDTO {
@ApiProperty()

View File

@@ -1,15 +1,15 @@
import type {
DashboardOverviewResult,
DashboardOverviewResult,
} from '@core/racing/application/use-cases/DashboardOverviewUseCase';
import {
DashboardOverviewDTO,
DashboardDriverSummaryDTO,
DashboardRaceSummaryDTO,
DashboardRecentResultDTO,
DashboardLeagueStandingSummaryDTO,
DashboardFeedSummaryDTO,
DashboardFeedItemSummaryDTO,
DashboardFriendSummaryDTO,
DashboardDriverSummaryDTO,
DashboardFeedItemSummaryDTO,
DashboardFeedSummaryDTO,
DashboardFriendSummaryDTO,
DashboardLeagueStandingSummaryDTO,
DashboardOverviewDTO,
DashboardRaceSummaryDTO,
DashboardRecentResultDTO,
} from '../dtos/DashboardOverviewDTO';
export class DashboardOverviewPresenter {

View File

@@ -2,28 +2,28 @@ import 'reflect-metadata';
import { Reflector } from '@nestjs/core';
import { Test, TestingModule } from '@nestjs/testing';
import type { Request } from 'express';
import request from 'supertest';
import { vi } from 'vitest';
import { DriverController } from './DriverController';
import { DriverService } from './DriverService';
import type { Request } from 'express';
import { AuthenticationGuard } from '../auth/AuthenticationGuard';
import { AuthorizationGuard } from '../auth/AuthorizationGuard';
import type { AuthorizationService } from '../auth/AuthorizationService';
import { FeatureAvailabilityGuard } from '../policy/FeatureAvailabilityGuard';
import type { PolicyService, PolicySnapshot } from '../policy/PolicyService';
interface AuthenticatedRequest extends Request {
user?: { userId: string };
}
import { DriverController } from './DriverController';
import { DriverService } from './DriverService';
import { CompleteOnboardingInputDTO } from './dtos/CompleteOnboardingInputDTO';
import { CompleteOnboardingOutputDTO } from './dtos/CompleteOnboardingOutputDTO';
import { DriverRegistrationStatusDTO } from './dtos/DriverRegistrationStatusDTO';
import { DriversLeaderboardDTO } from './dtos/DriversLeaderboardDTO';
import { DriverStatsDTO } from './dtos/DriverStatsDTO';
import { GetDriverLiveriesOutputDTO } from './dtos/GetDriverLiveriesOutputDTO';
import { GetDriverOutputDTO } from './dtos/GetDriverOutputDTO';
import { GetDriverProfileOutputDTO } from './dtos/GetDriverProfileOutputDTO';
import { DriverRegistrationStatusDTO } from './dtos/DriverRegistrationStatusDTO';
interface AuthenticatedRequest extends Request {
user?: { userId: string };
}
describe('DriverController', () => {
let controller: DriverController;

View File

@@ -1,13 +1,9 @@
import { Body, Controller, Get, Param, Post, Put, Req, Inject, NotFoundException } from '@nestjs/common';
import { Body, Controller, Get, Inject, NotFoundException, Param, Post, Put, Req } from '@nestjs/common';
import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
import { Public } from '../auth/Public';
import { DriverService } from './DriverService';
import { CompleteOnboardingInputDTO } from './dtos/CompleteOnboardingInputDTO';
type AuthenticatedRequest = {
user?: { userId: string };
};
import { CompleteOnboardingOutputDTO } from './dtos/CompleteOnboardingOutputDTO';
import { DriverRegistrationStatusDTO } from './dtos/DriverRegistrationStatusDTO';
import { DriversLeaderboardDTO } from './dtos/DriversLeaderboardDTO';
@@ -16,6 +12,10 @@ import { GetDriverLiveriesOutputDTO } from './dtos/GetDriverLiveriesOutputDTO';
import { GetDriverOutputDTO } from './dtos/GetDriverOutputDTO';
import { GetDriverProfileOutputDTO } from './dtos/GetDriverProfileOutputDTO';
type AuthenticatedRequest = {
user?: { userId: string };
};
@ApiTags('drivers')
@Controller('drivers')

View File

@@ -1,6 +1,6 @@
import { Test, TestingModule } from '@nestjs/testing';
import { DriverModule } from './DriverModule';
import { DriverController } from './DriverController';
import { DriverModule } from './DriverModule';
import { DriverService } from './DriverService';
describe('DriverModule', () => {

View File

@@ -1,9 +1,9 @@
import { Module } from '@nestjs/common';
import { RacingPersistenceModule } from '../../persistence/racing/RacingPersistenceModule';
import { SocialPersistenceModule } from '../../persistence/social/SocialPersistenceModule';
import { DriverService } from './DriverService';
import { DriverController } from './DriverController';
import { DriverProviders } from './DriverProviders';
import { DriverService } from './DriverService';
@Module({
imports: [RacingPersistenceModule, SocialPersistenceModule],

View File

@@ -1,6 +1,6 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { describe, expect, it, vi, beforeEach } from 'vitest';
import { Result } from '@core/shared/domain/Result';
import { beforeEach, describe, expect, it, vi } from 'vitest';
import { DriverService } from './DriverService';
describe('DriverService', () => {

View File

@@ -1,5 +1,5 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsString, IsNotEmpty, IsOptional } from 'class-validator';
import { IsNotEmpty, IsOptional, IsString } from 'class-validator';
export class CompleteOnboardingInputDTO {
@ApiProperty()

View File

@@ -1,11 +1,11 @@
import { ApiProperty } from '@nestjs/swagger';
import { DriverProfileDriverSummaryDTO } from './DriverProfileDriverSummaryDTO';
import { DriverProfileStatsDTO } from './DriverProfileStatsDTO';
import { DriverProfileFinishDistributionDTO } from './DriverProfileFinishDistributionDTO';
import { DriverProfileTeamMembershipDTO } from './DriverProfileTeamMembershipDTO';
import { DriverProfileSocialSummaryDTO } from './DriverProfileSocialSummaryDTO';
import { DriverProfileExtendedProfileDTO } from './DriverProfileExtendedProfileDTO';
import { DriverProfileFinishDistributionDTO } from './DriverProfileFinishDistributionDTO';
import { DriverProfileSocialSummaryDTO } from './DriverProfileSocialSummaryDTO';
import { DriverProfileStatsDTO } from './DriverProfileStatsDTO';
import { DriverProfileTeamMembershipDTO } from './DriverProfileTeamMembershipDTO';
export class GetDriverProfileOutputDTO {
@ApiProperty({ type: DriverProfileDriverSummaryDTO, nullable: true })

View File

@@ -1,5 +1,5 @@
import type { CompleteOnboardingOutputDTO } from '../dtos/CompleteOnboardingOutputDTO';
import type { CompleteDriverOnboardingResult } from '@core/racing/application/use-cases/CompleteDriverOnboardingUseCase';
import type { CompleteOnboardingOutputDTO } from '../dtos/CompleteOnboardingOutputDTO';
export class CompleteOnboardingPresenter {
private responseModel: CompleteOnboardingOutputDTO | null = null;

View File

@@ -1,9 +1,9 @@
import { Result } from '@core/shared/domain/Result';
import type { Driver } from '@core/racing/domain/entities/Driver';
import type { GetDriverOutputDTO } from '../dtos/GetDriverOutputDTO';
import type { IDriverStatsRepository } from '@core/racing/domain/repositories/DriverStatsRepository';
import type { MediaResolverPort } from '@core/ports/media/MediaResolverPort';
import { MediaReference } from '@core/domain/media/MediaReference';
import type { MediaResolverPort } from '@core/ports/media/MediaResolverPort';
import type { Driver } from '@core/racing/domain/entities/Driver';
import type { IDriverStatsRepository } from '@core/racing/domain/repositories/DriverStatsRepository';
import { Result } from '@core/shared/domain/Result';
import type { GetDriverOutputDTO } from '../dtos/GetDriverOutputDTO';
export class DriverPresenter {
private responseModel: GetDriverOutputDTO | null = null;

View File

@@ -1,10 +1,10 @@
import type {
GetProfileOverviewResult,
} from '@core/racing/application/use-cases/GetProfileOverviewUseCase';
import type { GetDriverProfileOutputDTO } from '../dtos/GetDriverProfileOutputDTO';
import type { DriverProfileExtendedProfileDTO } from '../dtos/DriverProfileExtendedProfileDTO';
import type { MediaResolverPort } from '@core/ports/media/MediaResolverPort';
import { MediaReference } from '@core/domain/media/MediaReference';
import type { MediaResolverPort } from '@core/ports/media/MediaResolverPort';
import type {
GetProfileOverviewResult,
} from '@core/racing/application/use-cases/GetProfileOverviewUseCase';
import type { DriverProfileExtendedProfileDTO } from '../dtos/DriverProfileExtendedProfileDTO';
import type { GetDriverProfileOutputDTO } from '../dtos/GetDriverProfileOutputDTO';
export class DriverProfilePresenter {
private responseModel: GetDriverProfileOutputDTO | null = null;

View File

@@ -1,4 +1,4 @@
import { describe, it, expect, beforeEach } from 'vitest';
import { beforeEach, describe, expect, it } from 'vitest';
import { DriverRegistrationStatusPresenter } from './DriverRegistrationStatusPresenter';
describe('DriverRegistrationStatusPresenter', () => {

View File

@@ -1,5 +1,5 @@
import type {
IsDriverRegisteredForRaceResult,
IsDriverRegisteredForRaceResult,
} from '@core/racing/application/use-cases/IsDriverRegisteredForRaceUseCase';
import { DriverRegistrationStatusDTO } from '../dtos/DriverRegistrationStatusDTO';

View File

@@ -1,6 +1,6 @@
import { describe, it, expect, beforeEach } from 'vitest';
import { DriverStatsPresenter } from './DriverStatsPresenter';
import type { GetTotalDriversResult } from '@core/racing/application/use-cases/GetTotalDriversUseCase';
import { beforeEach, describe, expect, it } from 'vitest';
import { DriverStatsPresenter } from './DriverStatsPresenter';
describe('DriverStatsPresenter', () => {
let presenter: DriverStatsPresenter;

View File

@@ -1,7 +1,7 @@
import { DriverStatsDTO } from '../dtos/DriverStatsDTO';
import type {
GetTotalDriversResult,
GetTotalDriversResult,
} from '@core/racing/application/use-cases/GetTotalDriversUseCase';
import { DriverStatsDTO } from '../dtos/DriverStatsDTO';
export class DriverStatsPresenter {
private responseModel: DriverStatsDTO | null = null;

View File

@@ -1,10 +1,10 @@
import { GetDriversLeaderboardResult } from '@core/racing/application/use-cases/GetDriversLeaderboardUseCase';
import { beforeEach, describe, expect, it, vi } from 'vitest';
import { DriversLeaderboardPresenter } from './DriversLeaderboardPresenter';
import type { Driver } from '@core/racing/domain/entities/Driver';
import type { SkillLevel } from '@core/racing/domain/services/SkillLevelService';
import { MediaReference } from '@core/domain/media/MediaReference';
import type { MediaResolverPort } from '@core/ports/media/MediaResolverPort';
import { GetDriversLeaderboardResult } from '@core/racing/application/use-cases/GetDriversLeaderboardUseCase';
import type { Driver } from '@core/racing/domain/entities/Driver';
import type { SkillLevel } from '@core/racing/domain/services/SkillLevelService';
import { beforeEach, describe, expect, it, vi } from 'vitest';
import { DriversLeaderboardPresenter } from './DriversLeaderboardPresenter';
describe('DriversLeaderboardPresenter', () => {
let presenter: DriversLeaderboardPresenter;

View File

@@ -1,9 +1,9 @@
import { DriversLeaderboardDTO } from '../dtos/DriversLeaderboardDTO';
import type {
GetDriversLeaderboardResult,
} from '@core/racing/application/use-cases/GetDriversLeaderboardUseCase';
import type { MediaResolverPort } from '@core/ports/media/MediaResolverPort';
import { MediaReference } from '@core/domain/media/MediaReference';
import type { MediaResolverPort } from '@core/ports/media/MediaResolverPort';
import type {
GetDriversLeaderboardResult,
} from '@core/racing/application/use-cases/GetDriversLeaderboardUseCase';
import { DriversLeaderboardDTO } from '../dtos/DriversLeaderboardDTO';
export class DriversLeaderboardPresenter {
private responseModel: DriversLeaderboardDTO | null = null;

View File

@@ -1,7 +1,7 @@
import { describe, it, expect, beforeEach } from 'vitest';
import { Result } from '@core/shared/domain/Result';
import { GetDriverLiveriesPresenter } from './GetDriverLiveriesPresenter';
import { DriverLivery } from '@core/racing/domain/entities/DriverLivery';
import { Result } from '@core/shared/domain/Result';
import { beforeEach, describe, expect, it } from 'vitest';
import { GetDriverLiveriesPresenter } from './GetDriverLiveriesPresenter';
describe('GetDriverLiveriesPresenter', () => {
let presenter: GetDriverLiveriesPresenter;

View File

@@ -1,5 +1,5 @@
import { Result } from '@core/shared/domain/Result';
import type { DriverLivery } from '@core/racing/domain/entities/DriverLivery';
import { Result } from '@core/shared/domain/Result';
import type { GetDriverLiveriesOutputDTO } from '../dtos/GetDriverLiveriesOutputDTO';
export class GetDriverLiveriesPresenter {

View File

@@ -1,4 +1,4 @@
import { describe, it, expect, vi } from 'vitest';
import { describe, expect, it, vi } from 'vitest';
import { HelloController } from './HelloController';
describe('HelloController', () => {

View File

@@ -1,6 +1,6 @@
import type { GetLeagueAdminPermissionsUseCase } from '@core/racing/application/use-cases/GetLeagueAdminPermissionsUseCase';
import { ForbiddenException } from '@nestjs/common';
import { getActorFromRequestContext } from '../auth/getActorFromRequestContext';
import type { GetLeagueAdminPermissionsUseCase } from '@core/racing/application/use-cases/GetLeagueAdminPermissionsUseCase';
type GetLeagueAdminPermissionsUseCaseLike = Pick<GetLeagueAdminPermissionsUseCase, 'execute'>;

View File

@@ -4,13 +4,13 @@ import { Reflector } from '@nestjs/core';
import { Test, TestingModule } from '@nestjs/testing';
import request from 'supertest';
import { vi } from 'vitest';
import { LeagueController } from './LeagueController';
import { LeagueService } from './LeagueService';
import { AuthenticationGuard } from '../auth/AuthenticationGuard';
import { AuthorizationGuard } from '../auth/AuthorizationGuard';
import type { AuthorizationService } from '../auth/AuthorizationService';
import { FeatureAvailabilityGuard } from '../policy/FeatureAvailabilityGuard';
import type { PolicyService, PolicySnapshot } from '../policy/PolicyService';
import { LeagueController } from './LeagueController';
import { LeagueService } from './LeagueService';
describe('LeagueController', () => {
let controller: LeagueController;

View File

@@ -1,14 +1,20 @@
import { Body, Controller, Delete, Get, HttpCode, Param, Patch, Post, Inject, ValidationPipe, Query, NotFoundException, UnauthorizedException, BadRequestException } from '@nestjs/common';
import { BadRequestException, Body, Controller, Delete, Get, HttpCode, Inject, NotFoundException, Param, Patch, Post, Query, UnauthorizedException, ValidationPipe } from '@nestjs/common';
import { ApiBody, ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
import { Public } from '../auth/Public';
import { LeagueService } from './LeagueService';
import { AllLeaguesWithCapacityDTO } from './dtos/AllLeaguesWithCapacityDTO';
import { AllLeaguesWithCapacityAndScoringDTO } from './dtos/AllLeaguesWithCapacityAndScoringDTO';
import { AllLeaguesWithCapacityDTO } from './dtos/AllLeaguesWithCapacityDTO';
import { ApproveJoinRequestInputDTO } from './dtos/ApproveJoinRequestInputDTO';
import { ApproveJoinRequestOutputDTO } from './dtos/ApproveJoinRequestOutputDTO';
import { CreateLeagueInputDTO } from './dtos/CreateLeagueInputDTO';
import { CreateLeagueOutputDTO } from './dtos/CreateLeagueOutputDTO';
import { GetLeagueAdminConfigQueryDTO } from './dtos/GetLeagueAdminConfigQueryDTO';
import { GetLeagueOwnerSummaryQueryDTO } from './dtos/GetLeagueOwnerSummaryQueryDTO';
import { GetLeagueProtestsQueryDTO } from './dtos/GetLeagueProtestsQueryDTO';
import { GetLeagueRacesOutputDTO } from './dtos/GetLeagueRacesOutputDTO';
import { GetLeagueScheduleQueryDTO } from './dtos/GetLeagueScheduleQueryDTO';
import { GetLeagueSeasonsQueryDTO } from './dtos/GetLeagueSeasonsQueryDTO';
import { GetLeagueWalletOutputDTO } from './dtos/GetLeagueWalletOutputDTO';
import { GetSeasonSponsorshipsOutputDTO } from './dtos/GetSeasonSponsorshipsOutputDTO';
import { LeagueAdminDTO } from './dtos/LeagueAdminDTO';
import { LeagueAdminPermissionsDTO } from './dtos/LeagueAdminPermissionsDTO';
@@ -16,39 +22,33 @@ import { LeagueAdminProtestsDTO } from './dtos/LeagueAdminProtestsDTO';
import { LeagueConfigFormModelDTO } from './dtos/LeagueConfigFormModelDTO';
import { LeagueJoinRequestDTO } from './dtos/LeagueJoinRequestDTO';
import { LeagueMembershipsDTO } from './dtos/LeagueMembershipsDTO';
import { LeagueOwnerSummaryDTO } from './dtos/LeagueOwnerSummaryDTO';
import { LeagueRosterJoinRequestDTO } from './dtos/LeagueRosterJoinRequestDTO';
import { LeagueRosterMemberDTO } from './dtos/LeagueRosterMemberDTO';
import { LeagueOwnerSummaryDTO } from './dtos/LeagueOwnerSummaryDTO';
import { LeagueScheduleDTO } from './dtos/LeagueScheduleDTO';
import {
LeagueSeasonSchedulePublishInputDTO,
LeagueSeasonSchedulePublishOutputDTO,
} from './dtos/LeagueSeasonSchedulePublishDTO';
import {
CreateLeagueScheduleRaceInputDTO,
CreateLeagueScheduleRaceOutputDTO,
LeagueScheduleRaceMutationSuccessDTO,
UpdateLeagueScheduleRaceInputDTO,
CreateLeagueScheduleRaceInputDTO,
CreateLeagueScheduleRaceOutputDTO,
LeagueScheduleRaceMutationSuccessDTO,
UpdateLeagueScheduleRaceInputDTO,
} from './dtos/LeagueScheduleRaceAdminDTO';
import { LeagueScoringPresetsDTO } from './dtos/LeagueScoringPresetsDTO';
import {
LeagueSeasonSchedulePublishInputDTO,
LeagueSeasonSchedulePublishOutputDTO,
} from './dtos/LeagueSeasonSchedulePublishDTO';
import { LeagueSeasonSummaryDTO } from './dtos/LeagueSeasonSummaryDTO';
import { LeagueStandingsDTO } from './dtos/LeagueStandingsDTO';
import { LeagueStatsDTO } from './dtos/LeagueStatsDTO';
import { RejectJoinRequestInputDTO } from './dtos/RejectJoinRequestInputDTO';
import { RejectJoinRequestOutputDTO } from './dtos/RejectJoinRequestOutputDTO';
import { RemoveLeagueMemberOutputDTO } from './dtos/RemoveLeagueMemberOutputDTO';
import { TotalLeaguesDTO } from './dtos/TotalLeaguesDTO';
import { TransferLeagueOwnershipInputDTO } from './dtos/TransferLeagueOwnershipInputDTO';
import { UpdateLeagueMemberRoleInputDTO } from './dtos/UpdateLeagueMemberRoleInputDTO';
import { UpdateLeagueMemberRoleOutputDTO } from './dtos/UpdateLeagueMemberRoleOutputDTO';
import { GetLeagueOwnerSummaryQueryDTO } from './dtos/GetLeagueOwnerSummaryQueryDTO';
import { GetLeagueAdminConfigQueryDTO } from './dtos/GetLeagueAdminConfigQueryDTO';
import { GetLeagueProtestsQueryDTO } from './dtos/GetLeagueProtestsQueryDTO';
import { GetLeagueSeasonsQueryDTO } from './dtos/GetLeagueSeasonsQueryDTO';
import { GetLeagueWalletOutputDTO } from './dtos/GetLeagueWalletOutputDTO';
import { TotalLeaguesDTO } from './dtos/TotalLeaguesDTO';
import { GetLeagueScheduleQueryDTO } from './dtos/GetLeagueScheduleQueryDTO';
import { WithdrawFromLeagueWalletInputDTO } from './dtos/WithdrawFromLeagueWalletInputDTO';
import { WithdrawFromLeagueWalletOutputDTO } from './dtos/WithdrawFromLeagueWalletOutputDTO';
import { LeagueScoringPresetsDTO } from './dtos/LeagueScoringPresetsDTO';
import { TransferLeagueOwnershipInputDTO } from './dtos/TransferLeagueOwnershipInputDTO';
@ApiTags('leagues')
@Controller('leagues')

View File

@@ -1,8 +1,8 @@
import { Module } from '@nestjs/common';
import { RacingPersistenceModule } from '../../persistence/racing/RacingPersistenceModule';
import { LeagueService } from './LeagueService';
import { LeagueController } from './LeagueController';
import { LeagueProviders } from './LeagueProviders';
import { LeagueService } from './LeagueService';
@Module({
imports: [RacingPersistenceModule],

View File

@@ -4,6 +4,7 @@ import { LeagueService } from './LeagueService';
import * as LeagueTokens from './LeagueTokens';
// Import core interfaces
import type { MediaResolverPort } from '@core/ports/media/MediaResolverPort';
import type { IDriverRepository } from '@core/racing/domain/repositories/DriverRepository';
import type { ILeagueMembershipRepository } from '@core/racing/domain/repositories/LeagueMembershipRepository';
import type { ILeagueRepository } from '@core/racing/domain/repositories/LeagueRepository';
@@ -13,29 +14,28 @@ import type { ISeasonRepository } from '@core/racing/domain/repositories/SeasonR
import type { ISeasonSponsorshipRepository } from '@core/racing/domain/repositories/SeasonSponsorshipRepository';
import type { IStandingRepository } from '@core/racing/domain/repositories/StandingRepository';
import type { Logger } from '@core/shared/application/Logger';
import type { MediaResolverPort } from '@core/ports/media/MediaResolverPort';
// Import concrete in-memory implementations
import type { ILeagueWalletRepository } from "@core/racing/domain/repositories/LeagueWalletRepository";
import type { ITransactionRepository } from "@core/racing/domain/repositories/TransactionRepository";
import { getLeagueScoringPresetById, listLeagueScoringPresets } from '@adapters/bootstrap/LeagueScoringPresets';
import { ConsoleLogger } from '@adapters/logging/ConsoleLogger';
import { InMemoryLeagueStandingsRepository } from '@adapters/racing/persistence/inmemory/InMemoryLeagueStandingsRepository';
import { MediaResolverAdapter } from '@adapters/media/MediaResolverAdapter';
import { InMemoryLeagueStandingsRepository } from '@adapters/racing/persistence/inmemory/InMemoryLeagueStandingsRepository';
import type { ILeagueWalletRepository } from "@core/racing/domain/repositories/LeagueWalletRepository";
import type { ITransactionRepository } from "@core/racing/domain/repositories/TransactionRepository";
// Import use cases
import { ApproveLeagueJoinRequestUseCase } from '@core/racing/application/use-cases/ApproveLeagueJoinRequestUseCase';
import { CreateLeagueWithSeasonAndScoringUseCase } from '@core/racing/application/use-cases/CreateLeagueWithSeasonAndScoringUseCase';
import { GetAllLeaguesWithCapacityUseCase } from '@core/racing/application/use-cases/GetAllLeaguesWithCapacityUseCase';
import { GetAllLeaguesWithCapacityAndScoringUseCase } from '@core/racing/application/use-cases/GetAllLeaguesWithCapacityAndScoringUseCase';
import { GetAllLeaguesWithCapacityUseCase } from '@core/racing/application/use-cases/GetAllLeaguesWithCapacityUseCase';
import { GetLeagueAdminPermissionsUseCase } from '@core/racing/application/use-cases/GetLeagueAdminPermissionsUseCase';
import { GetLeagueFullConfigUseCase } from '@core/racing/application/use-cases/GetLeagueFullConfigUseCase';
import { GetLeagueJoinRequestsUseCase } from '@core/racing/application/use-cases/GetLeagueJoinRequestsUseCase';
import { GetLeagueMembershipsUseCase } from '@core/racing/application/use-cases/GetLeagueMembershipsUseCase';
import { GetLeagueRosterMembersUseCase } from '@core/racing/application/use-cases/GetLeagueRosterMembersUseCase';
import { GetLeagueRosterJoinRequestsUseCase } from '@core/racing/application/use-cases/GetLeagueRosterJoinRequestsUseCase';
import { GetLeagueOwnerSummaryUseCase } from '@core/racing/application/use-cases/GetLeagueOwnerSummaryUseCase';
import { GetLeagueProtestsUseCase } from '@core/racing/application/use-cases/GetLeagueProtestsUseCase';
import { GetLeagueRosterJoinRequestsUseCase } from '@core/racing/application/use-cases/GetLeagueRosterJoinRequestsUseCase';
import { GetLeagueRosterMembersUseCase } from '@core/racing/application/use-cases/GetLeagueRosterMembersUseCase';
import { GetLeagueScheduleUseCase } from '@core/racing/application/use-cases/GetLeagueScheduleUseCase';
import { GetLeagueScoringConfigUseCase } from '@core/racing/application/use-cases/GetLeagueScoringConfigUseCase';
import { GetLeagueSeasonsUseCase } from '@core/racing/application/use-cases/GetLeagueSeasonsUseCase';
@@ -55,22 +55,18 @@ import { WithdrawFromLeagueWalletUseCase } from '@core/racing/application/use-ca
// Schedule mutation use cases
import { CreateLeagueSeasonScheduleRaceUseCase } from '@core/racing/application/use-cases/CreateLeagueSeasonScheduleRaceUseCase';
import { UpdateLeagueSeasonScheduleRaceUseCase } from '@core/racing/application/use-cases/UpdateLeagueSeasonScheduleRaceUseCase';
import { DeleteLeagueSeasonScheduleRaceUseCase } from '@core/racing/application/use-cases/DeleteLeagueSeasonScheduleRaceUseCase';
import { PublishLeagueSeasonScheduleUseCase } from '@core/racing/application/use-cases/PublishLeagueSeasonScheduleUseCase';
import { UnpublishLeagueSeasonScheduleUseCase } from '@core/racing/application/use-cases/UnpublishLeagueSeasonScheduleUseCase';
import { UpdateLeagueSeasonScheduleRaceUseCase } from '@core/racing/application/use-cases/UpdateLeagueSeasonScheduleRaceUseCase';
// Import presenters
import { AllLeaguesWithCapacityPresenter } from './presenters/AllLeaguesWithCapacityPresenter';
import { AllLeaguesWithCapacityAndScoringPresenter } from './presenters/AllLeaguesWithCapacityAndScoringPresenter';
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 {
GetLeagueRosterJoinRequestsPresenter,
GetLeagueRosterMembersPresenter,
} from './presenters/LeagueRosterAdminReadPresenters';
import { GetLeagueOwnerSummaryPresenter } from './presenters/GetLeagueOwnerSummaryPresenter';
import { GetLeagueProtestsPresenter } from './presenters/GetLeagueProtestsPresenter';
import { GetLeagueSeasonsPresenter } from './presenters/GetLeagueSeasonsPresenter';
@@ -79,7 +75,11 @@ import { GetSeasonSponsorshipsPresenter } from './presenters/GetSeasonSponsorshi
import { JoinLeaguePresenter } from './presenters/JoinLeaguePresenter';
import { LeagueConfigPresenter } from './presenters/LeagueConfigPresenter';
import { LeagueJoinRequestsPresenter } from './presenters/LeagueJoinRequestsPresenter';
import { LeagueSchedulePresenter, LeagueRacesPresenter } from './presenters/LeagueSchedulePresenter';
import {
GetLeagueRosterJoinRequestsPresenter,
GetLeagueRosterMembersPresenter,
} from './presenters/LeagueRosterAdminReadPresenters';
import { LeagueRacesPresenter, LeagueSchedulePresenter } from './presenters/LeagueSchedulePresenter';
import { LeagueScoringConfigPresenter } from './presenters/LeagueScoringConfigPresenter';
import { LeagueScoringPresetsPresenter } from './presenters/LeagueScoringPresetsPresenter';
import { LeagueStandingsPresenter } from './presenters/LeagueStandingsPresenter';
@@ -92,11 +92,11 @@ import { UpdateLeagueMemberRolePresenter } from './presenters/UpdateLeagueMember
import { WithdrawFromLeagueWalletPresenter } from './presenters/WithdrawFromLeagueWalletPresenter';
import {
CreateLeagueSeasonScheduleRacePresenter,
DeleteLeagueSeasonScheduleRacePresenter,
PublishLeagueSeasonSchedulePresenter,
UnpublishLeagueSeasonSchedulePresenter,
UpdateLeagueSeasonScheduleRacePresenter,
CreateLeagueSeasonScheduleRacePresenter,
DeleteLeagueSeasonScheduleRacePresenter,
PublishLeagueSeasonSchedulePresenter,
UnpublishLeagueSeasonSchedulePresenter,
UpdateLeagueSeasonScheduleRacePresenter,
} from './presenters/LeagueSeasonScheduleMutationPresenters';
export const LEAGUE_REPOSITORY_TOKEN = 'ILeagueRepository';

View File

@@ -1,27 +1,27 @@
import 'reflect-metadata';
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
import { Test } from '@nestjs/testing';
import { Reflector } from '@nestjs/core';
import request from 'supertest';
import { ValidationPipe } from '@nestjs/common';
import { Reflector } from '@nestjs/core';
import { Test } from '@nestjs/testing';
import request from 'supertest';
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
import { LeagueModule } from './LeagueModule';
import { AuthenticationGuard } from '../auth/AuthenticationGuard';
import { AuthorizationGuard } from '../auth/AuthorizationGuard';
import type { AuthorizationService } from '../auth/AuthorizationService';
import { LeagueModule } from './LeagueModule';
import { requestContextMiddleware } from '@adapters/http/RequestContext';
import {
DRIVER_REPOSITORY_TOKEN,
LEAGUE_MEMBERSHIP_REPOSITORY_TOKEN,
LEAGUE_REPOSITORY_TOKEN,
DRIVER_REPOSITORY_TOKEN,
LEAGUE_MEMBERSHIP_REPOSITORY_TOKEN,
LEAGUE_REPOSITORY_TOKEN,
} from '../../persistence/inmemory/InMemoryRacingPersistenceModule';
import { League } from '@core/racing/domain/entities/League';
import { Driver } from '@core/racing/domain/entities/Driver';
import { JoinRequest } from '@core/racing/domain/entities/JoinRequest';
import { League } from '@core/racing/domain/entities/League';
import { LeagueMembership } from '@core/racing/domain/entities/LeagueMembership';
describe('League roster join request mutations (HTTP)', () => {

View File

@@ -1,26 +1,26 @@
import 'reflect-metadata';
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
import { Test } from '@nestjs/testing';
import { Reflector } from '@nestjs/core';
import request from 'supertest';
import { ValidationPipe } from '@nestjs/common';
import { Reflector } from '@nestjs/core';
import { Test } from '@nestjs/testing';
import request from 'supertest';
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
import { LeagueModule } from './LeagueModule';
import { AuthenticationGuard } from '../auth/AuthenticationGuard';
import { AuthorizationGuard } from '../auth/AuthorizationGuard';
import type { AuthorizationService } from '../auth/AuthorizationService';
import { LeagueModule } from './LeagueModule';
import { requestContextMiddleware } from '@adapters/http/RequestContext';
import {
DRIVER_REPOSITORY_TOKEN,
LEAGUE_MEMBERSHIP_REPOSITORY_TOKEN,
LEAGUE_REPOSITORY_TOKEN,
DRIVER_REPOSITORY_TOKEN,
LEAGUE_MEMBERSHIP_REPOSITORY_TOKEN,
LEAGUE_REPOSITORY_TOKEN,
} from '../../persistence/inmemory/InMemoryRacingPersistenceModule';
import { League } from '@core/racing/domain/entities/League';
import { Driver } from '@core/racing/domain/entities/Driver';
import { League } from '@core/racing/domain/entities/League';
import { LeagueMembership } from '@core/racing/domain/entities/LeagueMembership';
describe('League roster member mutations (HTTP)', () => {

View File

@@ -1,6 +1,6 @@
import { describe, expect, it, vi } from 'vitest';
import { Result } from '@core/shared/domain/Result';
import { requestContextMiddleware } from '@adapters/http/RequestContext';
import { Result } from '@core/shared/domain/Result';
import { describe, expect, it, vi } from 'vitest';
import { LeagueService } from './LeagueService';
async function withUserId<T>(userId: string, fn: () => Promise<T>): Promise<T> {

View File

@@ -1,5 +1,5 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsString, IsBoolean } from 'class-validator';
import { IsBoolean, IsString } from 'class-validator';
export class ApproveJoinRequestOutputDTO {
@ApiProperty()

View File

@@ -1,5 +1,5 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsString, IsEnum } from 'class-validator';
import { IsEnum, IsString } from 'class-validator';
export class CreateLeagueInputDTO {
@ApiProperty()

View File

@@ -1,5 +1,5 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsString, IsBoolean } from 'class-validator';
import { IsBoolean, IsString } from 'class-validator';
export class CreateLeagueOutputDTO {
@ApiProperty()

View File

@@ -1,6 +1,6 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsOptional, ValidateNested } from 'class-validator';
import { Type } from 'class-transformer';
import { IsOptional, ValidateNested } from 'class-validator';
import { LeagueConfigFormModelDTO } from './LeagueConfigFormModelDTO';
export class GetLeagueAdminConfigOutputDTO {

View File

@@ -1,6 +1,6 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsOptional, ValidateNested } from 'class-validator';
import { Type } from 'class-transformer';
import { IsOptional, ValidateNested } from 'class-validator';
import { LeagueConfigFormModelDTO } from './LeagueConfigFormModelDTO';
export class LeagueAdminConfigDTO {

View File

@@ -1,10 +1,10 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsOptional, IsArray, ValidateNested } from 'class-validator';
import { Type } from 'class-transformer';
import { LeagueJoinRequestDTO } from './LeagueJoinRequestDTO';
import { LeagueOwnerSummaryDTO } from './LeagueOwnerSummaryDTO';
import { IsArray, IsOptional, ValidateNested } from 'class-validator';
import { LeagueAdminConfigDTO } from './LeagueAdminConfigDTO';
import { LeagueAdminProtestsDTO } from './LeagueAdminProtestsDTO';
import { LeagueJoinRequestDTO } from './LeagueJoinRequestDTO';
import { LeagueOwnerSummaryDTO } from './LeagueOwnerSummaryDTO';
import { LeagueSeasonSummaryDTO } from './LeagueSeasonSummaryDTO';
export class LeagueAdminDTO {

View File

@@ -1,6 +1,6 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsArray, ValidateNested, IsObject } from 'class-validator';
import { Type } from 'class-transformer';
import { IsArray, IsObject, ValidateNested } from 'class-validator';
import { DriverDTO } from '../../driver/dtos/DriverDTO';
import { RaceDTO } from '../../race/dtos/RaceDTO';
import { ProtestDTO } from './ProtestDTO';

View File

@@ -1,5 +1,5 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsString, IsEnum } from 'class-validator';
import { IsEnum, IsString } from 'class-validator';
export class LeagueConfigFormModelBasicsDTO {
@ApiProperty()

View File

@@ -1,11 +1,11 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsString, IsArray, ValidateNested } from 'class-validator';
import { Type } from 'class-transformer';
import { IsArray, IsString, ValidateNested } from 'class-validator';
import { LeagueConfigFormModelBasicsDTO } from './LeagueConfigFormModelBasicsDTO';
import { LeagueConfigFormModelStructureDTO } from './LeagueConfigFormModelStructureDTO';
import { LeagueConfigFormModelScoringDTO } from './LeagueConfigFormModelScoringDTO';
import { LeagueConfigFormModelDropPolicyDTO } from './LeagueConfigFormModelDropPolicyDTO';
import { LeagueConfigFormModelScoringDTO } from './LeagueConfigFormModelScoringDTO';
import { LeagueConfigFormModelStewardingDTO } from './LeagueConfigFormModelStewardingDTO';
import { LeagueConfigFormModelStructureDTO } from './LeagueConfigFormModelStructureDTO';
import { LeagueConfigFormModelTimingsDTO } from './LeagueConfigFormModelTimingsDTO';
export class LeagueConfigFormModelDTO {

View File

@@ -1,5 +1,5 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsNumber, IsOptional, IsEnum } from 'class-validator';
import { IsEnum, IsNumber, IsOptional } from 'class-validator';
export class LeagueConfigFormModelDropPolicyDTO {
@ApiProperty({ enum: ['none', 'worst_n'] })

View File

@@ -1,5 +1,5 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsString, IsNumber } from 'class-validator';
import { IsNumber, IsString } from 'class-validator';
export class LeagueConfigFormModelScoringDTO {
@ApiProperty()

View File

@@ -1,5 +1,5 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsNumber, IsBoolean, IsOptional, IsEnum } from 'class-validator';
import { IsBoolean, IsEnum, IsNumber, IsOptional } from 'class-validator';
export class LeagueConfigFormModelStewardingDTO {
@ApiProperty({ enum: ['single_steward', 'committee_vote'] })

View File

@@ -1,5 +1,5 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsString, IsEnum } from 'class-validator';
import { IsEnum, IsString } from 'class-validator';
export class LeagueConfigFormModelStructureDTO {
@ApiProperty()

View File

@@ -1,5 +1,5 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsString, IsNumber } from 'class-validator';
import { IsNumber, IsString } from 'class-validator';
export class LeagueConfigFormModelTimingsDTO {
@ApiProperty()

View File

@@ -1,6 +1,6 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsString, IsDate, IsOptional } from 'class-validator';
import { Type } from 'class-transformer';
import { IsDate, IsOptional, IsString } from 'class-validator';
export interface DriverInfo {
id: string;

View File

@@ -1,6 +1,6 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsEnum, IsString, ValidateNested } from 'class-validator';
import { Type } from 'class-transformer';
import { IsEnum, IsString, ValidateNested } from 'class-validator';
import { DriverDTO } from '../../driver/dtos/DriverDTO';
export class LeagueMemberDTO {

Some files were not shown because too many files have changed in this diff Show More