website refactor
This commit is contained in:
@@ -175,6 +175,22 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/drivers/{driverId}/liveries": {
|
||||
"get": {
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "List of driver liveries",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/GetDriverLiveriesOutputDTO"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/drivers/{driverId}/races/{raceId}/registration-status": {
|
||||
"get": {
|
||||
"responses": {
|
||||
|
||||
@@ -20,6 +20,7 @@ import { CompleteOnboardingInputDTO } from './dtos/CompleteOnboardingInputDTO';
|
||||
import { CompleteOnboardingOutputDTO } from './dtos/CompleteOnboardingOutputDTO';
|
||||
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';
|
||||
@@ -43,6 +44,7 @@ describe('DriverController', () => {
|
||||
getDriver: vi.fn(),
|
||||
getDriverProfile: vi.fn(),
|
||||
updateDriverProfile: vi.fn(),
|
||||
getDriverLiveries: vi.fn(),
|
||||
},
|
||||
},
|
||||
],
|
||||
@@ -170,6 +172,19 @@ describe('DriverController', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('getDriverLiveries', () => {
|
||||
it('should return driver liveries', async () => {
|
||||
const driverId = 'driver-123';
|
||||
const liveries: GetDriverLiveriesOutputDTO = { liveries: [] };
|
||||
service.getDriverLiveries.mockResolvedValue(liveries);
|
||||
|
||||
const result = await controller.getDriverLiveries(driverId);
|
||||
|
||||
expect(service.getDriverLiveries).toHaveBeenCalledWith(driverId);
|
||||
expect(result).toEqual(liveries);
|
||||
});
|
||||
});
|
||||
|
||||
describe('auth guards (HTTP)', () => {
|
||||
let app: any;
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ 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';
|
||||
|
||||
@@ -111,5 +112,13 @@ export class DriverController {
|
||||
return await this.driverService.updateDriverProfile(driverId, body.bio, body.country);
|
||||
}
|
||||
|
||||
@Public()
|
||||
@Get(':driverId/liveries')
|
||||
@ApiOperation({ summary: 'Get driver liveries' })
|
||||
@ApiResponse({ status: 200, description: 'List of driver liveries', type: GetDriverLiveriesOutputDTO })
|
||||
async getDriverLiveries(@Param('driverId') driverId: string): Promise<GetDriverLiveriesOutputDTO> {
|
||||
return await this.driverService.getDriverLiveries(driverId);
|
||||
}
|
||||
|
||||
// Add other Driver endpoints here based on other presenters
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ import { Provider } from '@nestjs/common';
|
||||
// Import core interfaces
|
||||
import { DriverExtendedProfileProvider } from '@core/racing/application/ports/DriverExtendedProfileProvider';
|
||||
import { IDriverRepository } from '@core/racing/domain/repositories/IDriverRepository';
|
||||
import { ILiveryRepository } from '@core/racing/domain/repositories/ILiveryRepository';
|
||||
import { IRaceRegistrationRepository } from '@core/racing/domain/repositories/IRaceRegistrationRepository';
|
||||
import type { ITeamMembershipRepository } from '@core/racing/domain/repositories/ITeamMembershipRepository';
|
||||
import type { ITeamRepository } from '@core/racing/domain/repositories/ITeamRepository';
|
||||
@@ -15,6 +16,7 @@ import type { MediaResolverPort } from '@core/ports/media/MediaResolverPort';
|
||||
// Import use cases
|
||||
import { CompleteDriverOnboardingUseCase } from '@core/racing/application/use-cases/CompleteDriverOnboardingUseCase';
|
||||
import { GetDriversLeaderboardUseCase } from '@core/racing/application/use-cases/GetDriversLeaderboardUseCase';
|
||||
import { GetDriverLiveriesUseCase } from '@core/racing/application/use-cases/GetDriverLiveriesUseCase';
|
||||
import { GetProfileOverviewUseCase } from '@core/racing/application/use-cases/GetProfileOverviewUseCase';
|
||||
import { GetTotalDriversUseCase } from '@core/racing/application/use-cases/GetTotalDriversUseCase';
|
||||
import { IsDriverRegisteredForRaceUseCase } from '@core/racing/application/use-cases/IsDriverRegisteredForRaceUseCase';
|
||||
@@ -26,6 +28,7 @@ import { InMemoryImageServiceAdapter } from '@adapters/media/ports/InMemoryImage
|
||||
import { InMemoryNotificationPreferenceRepository } from '@adapters/notifications/persistence/inmemory/InMemoryNotificationPreferenceRepository';
|
||||
import { InMemoryDriverExtendedProfileProvider } from '@adapters/racing/ports/InMemoryDriverExtendedProfileProvider';
|
||||
import { InMemoryDriverRatingProvider } from '@adapters/racing/ports/InMemoryDriverRatingProvider';
|
||||
import { InMemoryLiveryRepository } from '@adapters/racing/persistence/inmemory/InMemoryLiveryRepository';
|
||||
// Import new use cases
|
||||
import { RankingUseCase } from '@core/racing/application/use-cases/RankingUseCase';
|
||||
import { DriverStatsUseCase } from '@core/racing/application/use-cases/DriverStatsUseCase';
|
||||
@@ -47,6 +50,7 @@ import { DriverProfilePresenter } from './presenters/DriverProfilePresenter';
|
||||
import { DriverRegistrationStatusPresenter } from './presenters/DriverRegistrationStatusPresenter';
|
||||
import { DriversLeaderboardPresenter } from './presenters/DriversLeaderboardPresenter';
|
||||
import { DriverStatsPresenter } from './presenters/DriverStatsPresenter';
|
||||
import { GetDriverLiveriesPresenter } from './presenters/GetDriverLiveriesPresenter';
|
||||
|
||||
import {
|
||||
DRIVER_REPOSITORY_TOKEN,
|
||||
@@ -58,9 +62,11 @@ import {
|
||||
TEAM_REPOSITORY_TOKEN,
|
||||
TEAM_MEMBERSHIP_REPOSITORY_TOKEN,
|
||||
SOCIAL_GRAPH_REPOSITORY_TOKEN,
|
||||
LIVERY_REPOSITORY_TOKEN,
|
||||
LOGGER_TOKEN,
|
||||
GET_DRIVERS_LEADERBOARD_USE_CASE_TOKEN,
|
||||
GET_TOTAL_DRIVERS_USE_CASE_TOKEN,
|
||||
GET_DRIVER_LIVERIES_USE_CASE_TOKEN,
|
||||
COMPLETE_DRIVER_ONBOARDING_USE_CASE_TOKEN,
|
||||
IS_DRIVER_REGISTERED_FOR_RACE_USE_CASE_TOKEN,
|
||||
UPDATE_DRIVER_PROFILE_USE_CASE_TOKEN,
|
||||
@@ -112,6 +118,7 @@ export const DriverProviders: Provider[] = createLoggedProviders([
|
||||
},
|
||||
inject: [MEDIA_RESOLVER_TOKEN],
|
||||
},
|
||||
GetDriverLiveriesPresenter,
|
||||
|
||||
// Logger
|
||||
{
|
||||
@@ -189,6 +196,11 @@ export const DriverProviders: Provider[] = createLoggedProviders([
|
||||
useFactory: (logger: Logger) => new InMemoryNotificationPreferenceRepository(logger),
|
||||
inject: [LOGGER_TOKEN],
|
||||
},
|
||||
{
|
||||
provide: LIVERY_REPOSITORY_TOKEN,
|
||||
useFactory: (logger: Logger) => new InMemoryLiveryRepository(logger),
|
||||
inject: [LOGGER_TOKEN],
|
||||
},
|
||||
|
||||
// Use cases
|
||||
{
|
||||
@@ -258,4 +270,10 @@ export const DriverProviders: Provider[] = createLoggedProviders([
|
||||
RANKING_SERVICE_TOKEN,
|
||||
],
|
||||
},
|
||||
{
|
||||
provide: GET_DRIVER_LIVERIES_USE_CASE_TOKEN,
|
||||
useFactory: (liveryRepository: ILiveryRepository, logger: Logger) =>
|
||||
new GetDriverLiveriesUseCase(liveryRepository, logger),
|
||||
inject: [LIVERY_REPOSITORY_TOKEN, LOGGER_TOKEN],
|
||||
},
|
||||
], initLogger);
|
||||
|
||||
@@ -317,4 +317,41 @@ describe('DriverService', () => {
|
||||
expect(getProfileOverviewUseCase.execute).toHaveBeenCalledWith({ driverId: 'd1' });
|
||||
expect(driverProfilePresenter.getResponseModel).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('getDriverLiveries executes use case and returns presenter model', async () => {
|
||||
const getDriverLiveriesUseCase = { execute: vi.fn(async () => Result.ok(undefined)) };
|
||||
const getDriverLiveriesPresenter = {
|
||||
present: vi.fn(),
|
||||
getResponseModel: vi.fn(() => ({ liveries: [] }))
|
||||
};
|
||||
const driverPresenter = {
|
||||
setMediaResolver: vi.fn(),
|
||||
setBaseUrl: vi.fn(),
|
||||
present: vi.fn(),
|
||||
getResponseModel: vi.fn(() => null)
|
||||
};
|
||||
|
||||
const service = new DriverService(
|
||||
{ execute: vi.fn() } as any,
|
||||
{ execute: vi.fn() } as any,
|
||||
getDriverLiveriesUseCase as any,
|
||||
{ execute: vi.fn() } as any,
|
||||
{ execute: vi.fn() } as any,
|
||||
{ execute: vi.fn() } as any,
|
||||
{ findById: vi.fn() } as any,
|
||||
logger as any,
|
||||
{ getResponseModel: vi.fn(() => ({ items: [] })) } as any,
|
||||
{ getResponseModel: vi.fn(() => ({ totalDrivers: 0 })) } as any,
|
||||
{ getResponseModel: vi.fn(() => ({ success: true })) } as any,
|
||||
{ getResponseModel: vi.fn(() => ({ isRegistered: false })) } as any,
|
||||
driverPresenter as any,
|
||||
{ getResponseModel: vi.fn(() => ({ profile: {} })) } as any,
|
||||
getDriverLiveriesPresenter as any,
|
||||
);
|
||||
|
||||
await expect(service.getDriverLiveries('d1')).resolves.toEqual({ liveries: [] });
|
||||
expect(getDriverLiveriesUseCase.execute).toHaveBeenCalledWith({ driverId: 'd1' });
|
||||
expect(getDriverLiveriesPresenter.present).toHaveBeenCalled();
|
||||
expect(getDriverLiveriesPresenter.getResponseModel).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
@@ -6,11 +6,13 @@ import { DriverRegistrationStatusDTO } from './dtos/DriverRegistrationStatusDTO'
|
||||
import { DriversLeaderboardDTO } from './dtos/DriversLeaderboardDTO';
|
||||
import { DriverStatsDTO } from './dtos/DriverStatsDTO';
|
||||
import { GetDriverOutputDTO } from './dtos/GetDriverOutputDTO';
|
||||
import { GetDriverLiveriesOutputDTO } from './dtos/GetDriverLiveriesOutputDTO';
|
||||
import { GetDriverProfileOutputDTO } from './dtos/GetDriverProfileOutputDTO';
|
||||
import { GetDriverRegistrationStatusQueryDTO } from './dtos/GetDriverRegistrationStatusQueryDTO';
|
||||
|
||||
// Use cases
|
||||
import { CompleteDriverOnboardingUseCase } from '@core/racing/application/use-cases/CompleteDriverOnboardingUseCase';
|
||||
import { GetDriverLiveriesUseCase } from '@core/racing/application/use-cases/GetDriverLiveriesUseCase';
|
||||
import { GetDriversLeaderboardUseCase } from '@core/racing/application/use-cases/GetDriversLeaderboardUseCase';
|
||||
import { GetProfileOverviewUseCase } from '@core/racing/application/use-cases/GetProfileOverviewUseCase';
|
||||
import { GetTotalDriversUseCase } from '@core/racing/application/use-cases/GetTotalDriversUseCase';
|
||||
@@ -24,6 +26,7 @@ import { DriverProfilePresenter } from './presenters/DriverProfilePresenter';
|
||||
import { DriverRegistrationStatusPresenter } from './presenters/DriverRegistrationStatusPresenter';
|
||||
import { DriversLeaderboardPresenter } from './presenters/DriversLeaderboardPresenter';
|
||||
import { DriverStatsPresenter } from './presenters/DriverStatsPresenter';
|
||||
import { GetDriverLiveriesPresenter } from './presenters/GetDriverLiveriesPresenter';
|
||||
|
||||
// Tokens
|
||||
import type { IDriverRepository } from '@core/racing/domain/repositories/IDriverRepository';
|
||||
@@ -31,6 +34,7 @@ import type { Logger } from '@core/shared/application';
|
||||
import {
|
||||
COMPLETE_DRIVER_ONBOARDING_USE_CASE_TOKEN,
|
||||
DRIVER_REPOSITORY_TOKEN,
|
||||
GET_DRIVER_LIVERIES_USE_CASE_TOKEN,
|
||||
GET_DRIVERS_LEADERBOARD_USE_CASE_TOKEN,
|
||||
GET_PROFILE_OVERVIEW_USE_CASE_TOKEN,
|
||||
GET_TOTAL_DRIVERS_USE_CASE_TOKEN,
|
||||
@@ -46,6 +50,8 @@ export class DriverService {
|
||||
private readonly getDriversLeaderboardUseCase: GetDriversLeaderboardUseCase,
|
||||
@Inject(GET_TOTAL_DRIVERS_USE_CASE_TOKEN)
|
||||
private readonly getTotalDriversUseCase: GetTotalDriversUseCase,
|
||||
@Inject(GET_DRIVER_LIVERIES_USE_CASE_TOKEN)
|
||||
private readonly getDriverLiveriesUseCase: GetDriverLiveriesUseCase,
|
||||
@Inject(COMPLETE_DRIVER_ONBOARDING_USE_CASE_TOKEN)
|
||||
private readonly completeDriverOnboardingUseCase: CompleteDriverOnboardingUseCase,
|
||||
@Inject(IS_DRIVER_REGISTERED_FOR_RACE_USE_CASE_TOKEN)
|
||||
@@ -65,6 +71,7 @@ export class DriverService {
|
||||
private readonly driverRegistrationStatusPresenter?: DriverRegistrationStatusPresenter,
|
||||
private readonly driverPresenter?: DriverPresenter,
|
||||
private readonly driverProfilePresenter?: DriverProfilePresenter,
|
||||
private readonly getDriverLiveriesPresenter?: GetDriverLiveriesPresenter,
|
||||
) {
|
||||
// Presenters are configured by providers, no need to configure here
|
||||
}
|
||||
@@ -175,4 +182,15 @@ export class DriverService {
|
||||
}
|
||||
return this.driverProfilePresenter!.getResponseModel();
|
||||
}
|
||||
|
||||
async getDriverLiveries(driverId: string): Promise<GetDriverLiveriesOutputDTO> {
|
||||
this.logger.debug(`[DriverService] Fetching driver liveries for driverId: ${driverId}`);
|
||||
|
||||
const result = await this.getDriverLiveriesUseCase.execute({ driverId });
|
||||
if (result.isErr()) {
|
||||
throw new Error(result.unwrapErr().details.message);
|
||||
}
|
||||
await this.getDriverLiveriesPresenter!.present(result);
|
||||
return this.getDriverLiveriesPresenter!.getResponseModel()!;
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,7 @@ import { SOCIAL_GRAPH_REPOSITORY_TOKEN } from '../../persistence/social/SocialPe
|
||||
|
||||
export const TEAM_MEMBERSHIP_REPOSITORY_TOKEN = 'ITeamMembershipRepository';
|
||||
export { SOCIAL_GRAPH_REPOSITORY_TOKEN };
|
||||
export const LIVERY_REPOSITORY_TOKEN = 'ILiveryRepository';
|
||||
export const LOGGER_TOKEN = 'Logger';
|
||||
|
||||
// New tokens for clean architecture
|
||||
@@ -24,10 +25,12 @@ export const COMPLETE_DRIVER_ONBOARDING_USE_CASE_TOKEN = 'CompleteDriverOnboardi
|
||||
export const IS_DRIVER_REGISTERED_FOR_RACE_USE_CASE_TOKEN = 'IsDriverRegisteredForRaceUseCase';
|
||||
export const UPDATE_DRIVER_PROFILE_USE_CASE_TOKEN = 'UpdateDriverProfileUseCase';
|
||||
export const GET_PROFILE_OVERVIEW_USE_CASE_TOKEN = 'GetProfileOverviewUseCase';
|
||||
export const GET_DRIVER_LIVERIES_USE_CASE_TOKEN = 'GetDriverLiveriesUseCase';
|
||||
|
||||
export const GET_DRIVERS_LEADERBOARD_OUTPUT_PORT_TOKEN = 'GetDriversLeaderboardOutputPort_TOKEN';
|
||||
export const GET_TOTAL_DRIVERS_OUTPUT_PORT_TOKEN = 'GetTotalDriversOutputPort_TOKEN';
|
||||
export const COMPLETE_DRIVER_ONBOARDING_OUTPUT_PORT_TOKEN = 'CompleteDriverOnboardingOutputPort_TOKEN';
|
||||
export const IS_DRIVER_REGISTERED_FOR_RACE_OUTPUT_PORT_TOKEN = 'IsDriverRegisteredForRaceOutputPort_TOKEN';
|
||||
export const UPDATE_DRIVER_PROFILE_OUTPUT_PORT_TOKEN = 'UpdateDriverProfileOutputPort_TOKEN';
|
||||
export const GET_PROFILE_OVERVIEW_OUTPUT_PORT_TOKEN = 'GetProfileOverviewOutputPort_TOKEN';
|
||||
export const GET_PROFILE_OVERVIEW_OUTPUT_PORT_TOKEN = 'GetProfileOverviewOutputPort_TOKEN';
|
||||
export const GET_DRIVER_LIVERIES_OUTPUT_PORT_TOKEN = 'GetDriverLiveriesOutputPort_TOKEN';
|
||||
@@ -0,0 +1,23 @@
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
|
||||
class LiveryDTO {
|
||||
@ApiProperty()
|
||||
id!: string;
|
||||
|
||||
@ApiProperty()
|
||||
name!: string;
|
||||
|
||||
@ApiProperty()
|
||||
imageUrl!: string;
|
||||
|
||||
@ApiProperty()
|
||||
createdAt!: string;
|
||||
|
||||
@ApiProperty()
|
||||
isActive!: boolean;
|
||||
}
|
||||
|
||||
export class GetDriverLiveriesOutputDTO {
|
||||
@ApiProperty({ type: [LiveryDTO] })
|
||||
liveries!: LiveryDTO[];
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
import { describe, it, expect, beforeEach } from 'vitest';
|
||||
import { Result } from '@core/shared/application/Result';
|
||||
import { GetDriverLiveriesPresenter } from './GetDriverLiveriesPresenter';
|
||||
import { DriverLivery } from '@core/racing/domain/entities/DriverLivery';
|
||||
|
||||
describe('GetDriverLiveriesPresenter', () => {
|
||||
let presenter: GetDriverLiveriesPresenter;
|
||||
|
||||
beforeEach(() => {
|
||||
presenter = new GetDriverLiveriesPresenter();
|
||||
});
|
||||
|
||||
describe('present', () => {
|
||||
it('should map core result to API response model correctly', () => {
|
||||
const mockLiveries: DriverLivery[] = [
|
||||
DriverLivery.create({
|
||||
id: 'livery1',
|
||||
driverId: 'driver1',
|
||||
gameId: 'game1',
|
||||
carId: 'car1',
|
||||
uploadedImageUrl: 'http://example.com/livery1.png',
|
||||
createdAt: new Date('2023-01-01'),
|
||||
}),
|
||||
DriverLivery.create({
|
||||
id: 'livery2',
|
||||
driverId: 'driver1',
|
||||
gameId: 'game1',
|
||||
carId: 'car2',
|
||||
uploadedImageUrl: 'http://example.com/livery2.png',
|
||||
createdAt: new Date('2023-01-02'),
|
||||
}),
|
||||
];
|
||||
|
||||
const result = Result.ok(mockLiveries);
|
||||
presenter.present(result);
|
||||
|
||||
const response = presenter.getResponseModel();
|
||||
|
||||
expect(response).toEqual({
|
||||
liveries: [
|
||||
{
|
||||
id: 'livery1',
|
||||
name: 'Livery for car1',
|
||||
imageUrl: 'http://example.com/livery1.png',
|
||||
createdAt: '2023-01-01T00:00:00.000Z',
|
||||
isActive: true,
|
||||
},
|
||||
{
|
||||
id: 'livery2',
|
||||
name: 'Livery for car2',
|
||||
imageUrl: 'http://example.com/livery2.png',
|
||||
createdAt: '2023-01-02T00:00:00.000Z',
|
||||
isActive: false,
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
it('should handle empty liveries array', () => {
|
||||
const result = Result.ok([]);
|
||||
presenter.present(result);
|
||||
|
||||
const response = presenter.getResponseModel();
|
||||
|
||||
expect(response).toEqual({
|
||||
liveries: [],
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,33 @@
|
||||
import { Result } from '@core/shared/application/Result';
|
||||
import type { DriverLivery } from '@core/racing/domain/entities/DriverLivery';
|
||||
import type { GetDriverLiveriesOutputDTO } from '../dtos/GetDriverLiveriesOutputDTO';
|
||||
|
||||
export class GetDriverLiveriesPresenter {
|
||||
private responseModel: GetDriverLiveriesOutputDTO | null = null;
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
async present(result: Result<DriverLivery[], any>): Promise<void> {
|
||||
if (result.isErr()) {
|
||||
const error = result.unwrapErr();
|
||||
throw new Error(error.details?.message ?? 'Failed to get driver liveries');
|
||||
}
|
||||
|
||||
const liveries = result.unwrap();
|
||||
|
||||
const dto: GetDriverLiveriesOutputDTO = {
|
||||
liveries: liveries.map((livery, index) => ({
|
||||
id: livery.id,
|
||||
name: `Livery for ${livery.carId.toString()}`, // Simple name generation
|
||||
imageUrl: livery.uploadedImageUrl.toString(),
|
||||
createdAt: livery.createdAt.toISOString(),
|
||||
isActive: index === 0, // First livery is active by default
|
||||
})),
|
||||
};
|
||||
|
||||
this.responseModel = dto;
|
||||
}
|
||||
|
||||
getResponseModel(): GetDriverLiveriesOutputDTO | null {
|
||||
return this.responseModel;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user