Доработка методов, userId в токене, инфа в сваггере

This commit is contained in:
Sergey Bolshakov 2025-12-15 17:02:27 +03:00
parent 7895352e76
commit 81a5a829a9
9 changed files with 235 additions and 24 deletions

View File

@ -24,9 +24,13 @@ export class AuthService {
return null; return null;
} }
async login(user: { email: string; password: string }) { login(user: Omit<User, 'password'>) {
this.logger.log('LOG'); this.logger.log('LOG');
const payload = { username: user.email, sub: user.password }; const payload = {
username: user.email,
sub: user.userId,
userId: user.userId,
};
return { return {
access_token: this.jwtService.sign(payload), access_token: this.jwtService.sign(payload),
}; };

View File

@ -1,4 +1,4 @@
import { Controller, Get, Query, Param } from '@nestjs/common'; import { Controller, Get, Query, Param, Post, Body, HttpCode, HttpStatus } from '@nestjs/common';
import { CatalogService } from './catalog.service'; import { CatalogService } from './catalog.service';
import { CatalogResponseDto } from './dto/catalog-response.dto'; import { CatalogResponseDto } from './dto/catalog-response.dto';
import { CatalogFiltersDto } from './dto/catalog-filters.dto'; import { CatalogFiltersDto } from './dto/catalog-filters.dto';
@ -11,9 +11,13 @@ import {
ApiResponse, ApiResponse,
ApiOperation, ApiOperation,
ApiProperty, ApiProperty,
ApiBody,
ApiTags,
} from '@nestjs/swagger'; } from '@nestjs/swagger';
import { MainPageCatalogResponseDto } from './dto/main-page-catalog-response.dto'; import { MainPageCatalogResponseDto } from './dto/main-page-catalog-response.dto';
import { CreateYachtDto } from './dto/create-yacht.dto';
@ApiTags('catalog')
@Controller('catalog') @Controller('catalog')
export class CatalogController { export class CatalogController {
constructor(private readonly catalogService: CatalogService) {} constructor(private readonly catalogService: CatalogService) {}
@ -64,6 +68,19 @@ export class CatalogController {
return this.catalogService.getMainPageCatalog(); return this.catalogService.getMainPageCatalog();
} }
@Get('user/:userId')
@ApiOperation({ summary: 'Get catalog items by user ID' })
@ApiResponse({
status: 200,
description: 'Catalog items for the specified user',
type: [CatalogItemShortDto],
})
async getCatalogByUserId(
@Param('userId') userId: string,
): Promise<CatalogItemShortDto[]> {
return this.catalogService.getCatalogByUserId(Number(userId));
}
@Get(':id') @Get(':id')
@ApiOperation({ summary: 'Get catalog item by ID with full details' }) @ApiOperation({ summary: 'Get catalog item by ID with full details' })
@ApiResponse({ @ApiResponse({
@ -76,4 +93,21 @@ export class CatalogController {
): Promise<CatalogItemLongDto | null> { ): Promise<CatalogItemLongDto | null> {
return this.catalogService.getCatalogItemById(Number(id)); return this.catalogService.getCatalogItemById(Number(id));
} }
@Post()
@HttpCode(HttpStatus.CREATED)
@ApiOperation({ summary: 'Create a new yacht in catalog' })
@ApiBody({ type: CreateYachtDto })
@ApiResponse({
status: 201,
description: 'Yacht successfully created',
type: CatalogItemLongDto,
})
@ApiResponse({
status: 400,
description: 'Bad request',
})
async createYacht(@Body() createYachtDto: CreateYachtDto): Promise<CatalogItemLongDto> {
return this.catalogService.createYacht(createYachtDto);
}
} }

View File

@ -1,4 +1,4 @@
import { Module } from '@nestjs/common'; import { Module, forwardRef } from '@nestjs/common';
import { CatalogService } from './catalog.service'; import { CatalogService } from './catalog.service';
import { CatalogController } from './catalog.controller'; import { CatalogController } from './catalog.controller';
import { UsersModule } from '../users/users.module'; import { UsersModule } from '../users/users.module';
@ -8,10 +8,11 @@ import { ReviewsModule } from '../reviews/reviews.module';
@Module({ @Module({
imports: [ imports: [
UsersModule, // This provides UsersService UsersModule, // This provides UsersService
ReservationsModule, // This provides ReservationsService forwardRef(() => ReservationsModule), // This provides ReservationsService
ReviewsModule, // This provides ReviewsService ReviewsModule, // This provides ReviewsService
], ],
controllers: [CatalogController], controllers: [CatalogController],
providers: [CatalogService], providers: [CatalogService],
exports: [CatalogService], // Export for other modules to use
}) })
export class CatalogModule {} export class CatalogModule {}

View File

@ -1,4 +1,4 @@
import { Injectable } from '@nestjs/common'; import { Injectable, Inject, forwardRef } from '@nestjs/common';
import { UsersService } from '../users/users.service'; import { UsersService } from '../users/users.service';
import { ReservationsService } from '../reservations/reservations.service'; import { ReservationsService } from '../reservations/reservations.service';
import { ReviewsService } from '../reviews/reviews.service'; import { ReviewsService } from '../reviews/reviews.service';
@ -10,11 +10,13 @@ import { CatalogParamsDto } from './dto/catalog-params.dto';
import { CatalogResponseDto } from './dto/catalog-response.dto'; import { CatalogResponseDto } from './dto/catalog-response.dto';
import { MainPageCatalogResponseDto } from './dto/main-page-catalog-response.dto'; import { MainPageCatalogResponseDto } from './dto/main-page-catalog-response.dto';
import { CatalogFiltersDto } from './dto/catalog-filters.dto'; import { CatalogFiltersDto } from './dto/catalog-filters.dto';
import { CreateYachtDto } from './dto/create-yacht.dto';
@Injectable() @Injectable()
export class CatalogService { export class CatalogService {
constructor( constructor(
private readonly usersService: UsersService, private readonly usersService: UsersService,
@Inject(forwardRef(() => ReservationsService))
private readonly reservationsService: ReservationsService, private readonly reservationsService: ReservationsService,
private readonly reviewsService: ReviewsService, private readonly reviewsService: ReviewsService,
) {} ) {}
@ -49,7 +51,7 @@ export class CatalogService {
power: 1200, power: 1200,
description: description:
'Роскошная моторная яхта Азимут 55 - это воплощение итальянского стиля и российского качества. Идеально подходит для прогулок по Финскому заливу, корпоративных мероприятий и романтических свиданий. На борту: три комфортабельные каюты, просторный салон с панорамным остеклением, полностью оборудованная кухня и две ванные комнаты. Максимальная скорость 32 узла позволяет быстро добраться до самых живописных мест Карельского перешейка.', 'Роскошная моторная яхта Азимут 55 - это воплощение итальянского стиля и российского качества. Идеально подходит для прогулок по Финскому заливу, корпоративных мероприятий и романтических свиданий. На борту: три комфортабельные каюты, просторный салон с панорамным остеклением, полностью оборудованная кухня и две ванные комнаты. Максимальная скорость 32 узла позволяет быстро добраться до самых живописных мест Карельского перешейка.',
owner: null as any, owner: { userId: 1 } as any,
reviews: [], reviews: [],
reservations: [], reservations: [],
}, },
@ -83,7 +85,7 @@ export class CatalogService {
power: 1400, power: 1400,
description: description:
'Британский шик и русская душа в одной яхте! Сансикер Манхэттен 52 - выбор настоящих ценителей морских путешествий. Просторный кокпит с мягкими диванами, бар на 8 персон, система мультимедиа премиум-класса. Идеальна для празднования дня рождения на воде или деловой встречи с партнерами. Отличная маневренность позволяет заходить в марины Санкт-Петербурга и Кронштадта.', 'Британский шик и русская душа в одной яхте! Сансикер Манхэттен 52 - выбор настоящих ценителей морских путешествий. Просторный кокпит с мягкими диванами, бар на 8 персон, система мультимедиа премиум-класса. Идеальна для празднования дня рождения на воде или деловой встречи с партнерами. Отличная маневренность позволяет заходить в марины Санкт-Петербурга и Кронштадта.',
owner: null as any, owner: { userId: 2 } as any,
reviews: [], reviews: [],
reservations: [], reservations: [],
}, },
@ -117,7 +119,7 @@ export class CatalogService {
power: 1100, power: 1100,
description: description:
'Принцесс V55 - королева российских вод! Эта яхта создана для тех, кто ценит комфорт и элегантность. Четыре уютные каюты с кондиционером, гальюн с душем, полностью оборудованная камбузная зона. Особенность - огромный платц с гидравлическим трапом для купания в Ладожском озере. Отличный выбор для семейного отдыха или рыбалки с друзьями.', 'Принцесс V55 - королева российских вод! Эта яхта создана для тех, кто ценит комфорт и элегантность. Четыре уютные каюты с кондиционером, гальюн с душем, полностью оборудованная камбузная зона. Особенность - огромный платц с гидравлическим трапом для купания в Ладожском озере. Отличный выбор для семейного отдыха или рыбалки с друзьями.',
owner: null as any, owner: { userId: 1 } as any,
reviews: [], reviews: [],
reservations: [], reservations: [],
}, },
@ -151,7 +153,7 @@ export class CatalogService {
power: 900, power: 900,
description: description:
'Итальянская страсть в русской стихии! Ферретти 500 сочетает в себе средиземноморский шарм и надежность для суровых условий Балтики. Просторный салон с панорамными окнами, обеденная зона на 6 человек, современная навигационная система. Идеально подходит для фотосессий на фоне разводных мостов Петербурга или романтического ужина под звуки волн.', 'Итальянская страсть в русской стихии! Ферретти 500 сочетает в себе средиземноморский шарм и надежность для суровых условий Балтики. Просторный салон с панорамными окнами, обеденная зона на 6 человек, современная навигационная система. Идеально подходит для фотосессий на фоне разводных мостов Петербурга или романтического ужина под звуки волн.',
owner: null as any, owner: { userId: 2 } as any,
reviews: [], reviews: [],
reservations: [], reservations: [],
}, },
@ -184,7 +186,7 @@ export class CatalogService {
power: 1300, power: 1300,
description: description:
'Американская мощь для русского моря! Си Рей 510 Сандансер - самая быстрая яхта в нашем флоте. Развивает скорость до 35 узлов, что позволяет за день обогнуть весь Финский залив. Три комфортабельные каюты, система стабилизации на стоянке, мощная аудиосистема с сабвуфером. Отличный выбор для любителей острых ощущений и скоростных прогулок.', 'Американская мощь для русского моря! Си Рей 510 Сандансер - самая быстрая яхта в нашем флоте. Развивает скорость до 35 узлов, что позволяет за день обогнуть весь Финский залив. Три комфортабельные каюты, система стабилизации на стоянке, мощная аудиосистема с сабвуфером. Отличный выбор для любителей острых ощущений и скоростных прогулок.',
owner: null as any, owner: { userId: 1 } as any,
reviews: [], reviews: [],
reservations: [], reservations: [],
}, },
@ -217,7 +219,7 @@ export class CatalogService {
power: 320, power: 320,
description: description:
'Немецкое качество для русского характера! Бавария SR41 - надежная и экономичная яхта для спокойных прогулок по Ладоге. Две уютные каюты, просторный кокпит с тентом от дождя, лебедка для подъема парусов. Идеальный выбор для начинающих яхтсменов или семейного отдыха с детьми. Расход топлива всего 15 литров в час!', 'Немецкое качество для русского характера! Бавария SR41 - надежная и экономичная яхта для спокойных прогулок по Ладоге. Две уютные каюты, просторный кокпит с тентом от дождя, лебедка для подъема парусов. Идеальный выбор для начинающих яхтсменов или семейного отдыха с детьми. Расход топлива всего 15 литров в час!',
owner: null as any, owner: { userId: 2 } as any,
reviews: [], reviews: [],
reservations: [], reservations: [],
}, },
@ -250,7 +252,7 @@ export class CatalogService {
power: 250, power: 250,
description: description:
'Французская элегантность для русского простора! Жанно Мери Фишер 895 - компактная, но вместительная яхта для рыбалки и пикников. Одна просторная каюта, открытый кокпит, столик для барбекю. Отлично подходит для выездов на природу, ночевки в бухтах или обучения детей управлению яхтой. Самый экономичный вариант в нашем флоте!', 'Французская элегантность для русского простора! Жанно Мери Фишер 895 - компактная, но вместительная яхта для рыбалки и пикников. Одна просторная каюта, открытый кокпит, столик для барбекю. Отлично подходит для выездов на природу, ночевки в бухтах или обучения детей управлению яхтой. Самый экономичный вариант в нашем флоте!',
owner: null as any, owner: { userId: 1 } as any,
reviews: [], reviews: [],
reservations: [], reservations: [],
}, },
@ -283,7 +285,7 @@ export class CatalogService {
power: 425, power: 425,
description: description:
'Французский траулер для русского севера! Бенето Свифт Троулер 41 создан для длительных путешествий по Белому морю. Экономичный дизельный двигатель, большой запас топлива, система опреснения воды. Две комфортабельные каюты с подогревом пола. Идеальный выбор для экспедиций или многодневных круизов по северным островам.', 'Французский траулер для русского севера! Бенето Свифт Троулер 41 создан для длительных путешествий по Белому морю. Экономичный дизельный двигатель, большой запас топлива, система опреснения воды. Две комфортабельные каюты с подогревом пола. Идеальный выбор для экспедиций или многодневных круизов по северным островам.',
owner: null as any, owner: { userId: 2 } as any,
reviews: [], reviews: [],
reservations: [], reservations: [],
}, },
@ -316,7 +318,7 @@ export class CatalogService {
power: 90, power: 90,
description: description:
'Французский катамаран для русского размаха! Лагун 450 - невероятно устойчивая и просторная яхта. Четыре отдельные каюты с санузлами, огромный салон-трансформер, две кухни. Идеально подходит для больших компаний, свадебных церемоний на воде или длительных круизов всей семьей. Не кренится даже в шторм!', 'Французский катамаран для русского размаха! Лагун 450 - невероятно устойчивая и просторная яхта. Четыре отдельные каюты с санузлами, огромный салон-трансформер, две кухни. Идеально подходит для больших компаний, свадебных церемоний на воде или длительных круизов всей семьей. Не кренится даже в шторм!',
owner: null as any, owner: { userId: 1 } as any,
reviews: [], reviews: [],
reservations: [], reservations: [],
}, },
@ -349,7 +351,7 @@ export class CatalogService {
power: 80, power: 80,
description: description:
'Французский катамаран класса люкс! Фонтен Пажо Люсия 40 - это плавающий пятизвездочный отель. Четыре каюты-люкс с джакузи, салон с камином, профессиональная кухня с шеф-поваром. Система стабилизации на якоре, гидромассажный бассейн на палубе. Выбор настоящих ценителей роскоши и комфорта на воде.', 'Французский катамаран класса люкс! Фонтен Пажо Люсия 40 - это плавающий пятизвездочный отель. Четыре каюты-люкс с джакузи, салон с камином, профессиональная кухня с шеф-поваром. Система стабилизации на якоре, гидромассажный бассейн на палубе. Выбор настоящих ценителей роскоши и комфорта на воде.',
owner: null as any, owner: { userId: 2 } as any,
reviews: [], reviews: [],
reservations: [], reservations: [],
}, },
@ -382,7 +384,7 @@ export class CatalogService {
power: 380, power: 380,
description: description:
'Французская парусная яхта для русского ветра! Дюфур 460 - мечта любого яхтсмена. Три просторные каюты, кокпит с мягкими сиденьями, современное парусное вооружение. Идеально сбалансированная, легко управляется даже новичками. Отличный выбор для регат, обучения парусному спорту или романтических круизов под парусами.', 'Французская парусная яхта для русского ветра! Дюфур 460 - мечта любого яхтсмена. Три просторные каюты, кокпит с мягкими сиденьями, современное парусное вооружение. Идеально сбалансированная, легко управляется даже новичками. Отличный выбор для регат, обучения парусному спорту или романтических круизов под парусами.',
owner: null as any, owner: { userId: 1 } as any,
reviews: [], reviews: [],
reservations: [], reservations: [],
}, },
@ -415,7 +417,7 @@ export class CatalogService {
power: 1600, power: 1600,
description: description:
'Американская легенда для русского океана! Гранд Бэнкс 60 - экспедиционная яхта для самых смелых путешествий. Три каюты-люкс, салон с библиотекой, зимний сад, сауна. Автономность плавания - 30 дней! Способна пересечь Баренцево море и дойти до Шпицбергена. Выбор для настоящих морских волков и исследователей Арктики.', 'Американская легенда для русского океана! Гранд Бэнкс 60 - экспедиционная яхта для самых смелых путешествий. Три каюты-люкс, салон с библиотекой, зимний сад, сауна. Автономность плавания - 30 дней! Способна пересечь Баренцево море и дойти до Шпицбергена. Выбор для настоящих морских волков и исследователей Арктики.',
owner: null as any, owner: { userId: 2 } as any,
reviews: [], reviews: [],
reservations: [], reservations: [],
}, },
@ -610,4 +612,44 @@ export class CatalogService {
async getAllCatalogItems(): Promise<CatalogItemShortDto[]> { async getAllCatalogItems(): Promise<CatalogItemShortDto[]> {
return this.catalogItems.map((item) => this.toShortDto(item)); return this.catalogItems.map((item) => this.toShortDto(item));
} }
async getCatalogByUserId(userId: number): Promise<CatalogItemShortDto[]> {
// Логика определения ownerId: нечетные id -> ownerId=1, четные id -> ownerId=2
const filteredItems = this.catalogItems.filter((item) => {
return item.owner?.userId === userId;
});
return filteredItems.map((item) => this.toShortDto(item));
}
async createYacht(createYachtDto: CreateYachtDto): Promise<CatalogItemLongDto> {
const newId = Math.max(...this.catalogItems.map((item) => item.id || 0), 0) + 1;
const owner = await this.usersService.findById(createYachtDto.userId);
const newYacht: CatalogItemLongDto = {
id: newId,
name: createYachtDto.name,
length: createYachtDto.length,
speed: createYachtDto.speed,
minCost: createYachtDto.minCost,
mainImageUrl: createYachtDto.mainImageUrl,
galleryUrls: createYachtDto.galleryUrls,
hasQuickRent: createYachtDto.hasQuickRent,
isFeatured: createYachtDto.isFeatured,
year: createYachtDto.year,
comfortCapacity: createYachtDto.comfortCapacity,
maxCapacity: createYachtDto.maxCapacity,
width: createYachtDto.width,
cabinsCount: createYachtDto.cabinsCount,
matherial: createYachtDto.matherial,
power: createYachtDto.power,
description: createYachtDto.description,
owner: owner || ({ userId: createYachtDto.userId } as any),
reviews: [],
reservations: [],
topText: createYachtDto.topText,
};
this.catalogItems.push(newYacht);
return newYacht;
}
} }

View File

@ -0,0 +1,71 @@
import { ApiProperty } from '@nestjs/swagger';
export class CreateYachtDto {
@ApiProperty({ example: 'Азимут 55', description: 'Название яхты' })
name: string;
@ApiProperty({ example: 16.7, description: 'Длина яхты в метрах' })
length: number;
@ApiProperty({ example: 32, description: 'Скорость в узлах' })
speed: number;
@ApiProperty({ example: 85000, description: 'Минимальная стоимость аренды' })
minCost: number;
@ApiProperty({
example: 'api/uploads/1765727362318-238005198.jpg',
description: 'URL главного изображения',
})
mainImageUrl: string;
@ApiProperty({
type: [String],
example: ['api/uploads/1765727362318-238005198.jpg'],
description: 'URL галереи изображений',
})
galleryUrls: string[];
@ApiProperty({ example: true, description: 'Доступна быстрая аренда' })
hasQuickRent: boolean;
@ApiProperty({ example: false, description: 'Рекомендуемая яхта' })
isFeatured: boolean;
@ApiProperty({ example: 2022, description: 'Год выпуска' })
year: number;
@ApiProperty({ example: 8, description: 'Комфортная вместимость' })
comfortCapacity: number;
@ApiProperty({ example: 12, description: 'Максимальная вместимость' })
maxCapacity: number;
@ApiProperty({ example: 4.8, description: 'Ширина в метрах' })
width: number;
@ApiProperty({ example: 3, description: 'Количество кают' })
cabinsCount: number;
@ApiProperty({ example: 'Стеклопластик', description: 'Материал корпуса' })
matherial: string;
@ApiProperty({ example: 1200, description: 'Мощность двигателя' })
power: number;
@ApiProperty({
example: 'Роскошная моторная яхта...',
description: 'Описание яхты',
})
description: string;
@ApiProperty({ example: 1, description: 'ID владельца яхты' })
userId: number;
@ApiProperty({
required: false,
example: '🔥 Лучшее предложение',
description: 'Текст для отображения сверху',
})
topText?: string;
}

View File

@ -1,6 +1,28 @@
import { ApiProperty } from '@nestjs/swagger';
import { CatalogItemLongDto } from '../catalog/dto/catalog-item.dto';
export class ReservationItemDto { export class ReservationItemDto {
@ApiProperty({ example: 1, description: 'ID яхты' })
yachtId: number; yachtId: number;
@ApiProperty({ example: 1, description: 'ID резерватора' })
reservatorId: number; reservatorId: number;
@ApiProperty({ example: 1733097600, description: 'Начало резервации (Unix timestamp в UTC)' })
startUtc: number; startUtc: number;
@ApiProperty({ example: 1733133600, description: 'Конец резервации (Unix timestamp в UTC)' })
endUtc: number; endUtc: number;
} }
export class ReservationWithYachtDto extends ReservationItemDto {
@ApiProperty({ example: 1, description: 'ID резервации' })
id: number;
@ApiProperty({
type: CatalogItemLongDto,
required: false,
description: 'Данные о яхте',
})
yacht?: CatalogItemLongDto;
}

View File

@ -1,18 +1,29 @@
import { Controller, Get, Post, Body, Param } from '@nestjs/common'; import { Controller, Get, Post, Body, Param } from '@nestjs/common';
import { ApiOperation, ApiResponse, ApiBody, ApiParam } from '@nestjs/swagger';
import { ReservationsService } from './reservations.service'; import { ReservationsService } from './reservations.service';
import { ReservationItemDto } from './reservation-item.dto'; import { ReservationItemDto, ReservationWithYachtDto } from './reservation-item.dto';
@Controller('reservations') @Controller('reservations')
export class ReservationsController { export class ReservationsController {
constructor(private readonly reservationsService: ReservationsService) {} constructor(private readonly reservationsService: ReservationsService) {}
@Post() @Post()
@ApiOperation({ summary: 'Создать новую резервацию' })
@ApiBody({ type: ReservationItemDto })
@ApiResponse({ status: 201, description: 'Резервация успешно создана' })
create(@Body() dto: ReservationItemDto) { create(@Body() dto: ReservationItemDto) {
return this.reservationsService.createReservation(dto); return this.reservationsService.createReservation(dto);
} }
@Get('user/:userId') @Get('user/:userId')
findByUserId(@Param('userId') userId: string) { @ApiOperation({ summary: 'Получить резервации по ID пользователя' })
@ApiParam({ name: 'userId', description: 'ID пользователя', type: Number })
@ApiResponse({
status: 200,
description: 'Список резерваций пользователя с данными о яхтах',
type: [ReservationWithYachtDto],
})
async findByUserId(@Param('userId') userId: string) {
return this.reservationsService.getReservationsByUserId(Number(userId)); return this.reservationsService.getReservationsByUserId(Number(userId));
} }

View File

@ -1,8 +1,10 @@
import { Module } from '@nestjs/common'; import { Module, forwardRef } from '@nestjs/common';
import { ReservationsService } from './reservations.service'; import { ReservationsService } from './reservations.service';
import { ReservationsController } from './reservations.controller'; import { ReservationsController } from './reservations.controller';
import { CatalogModule } from '../catalog/catalog.module';
@Module({ @Module({
imports: [forwardRef(() => CatalogModule)],
controllers: [ReservationsController], controllers: [ReservationsController],
providers: [ReservationsService], providers: [ReservationsService],
exports: [ReservationsService], // Export for other modules to use exports: [ReservationsService], // Export for other modules to use

View File

@ -1,12 +1,23 @@
import { Injectable } from '@nestjs/common'; import { Injectable, Inject, forwardRef } from '@nestjs/common';
import { ReservationItemDto } from './reservation-item.dto'; import { ReservationItemDto } from './reservation-item.dto';
import { CatalogService } from '../catalog/catalog.service';
import { CatalogItemLongDto } from '../catalog/dto/catalog-item.dto';
export interface Reservation extends ReservationItemDto { export interface Reservation extends ReservationItemDto {
id: number; id: number;
} }
export interface ReservationWithYacht extends Reservation {
yacht?: CatalogItemLongDto;
}
@Injectable() @Injectable()
export class ReservationsService { export class ReservationsService {
constructor(
@Inject(forwardRef(() => CatalogService))
private readonly catalogService: CatalogService,
) {}
private reservations: Reservation[] = [ private reservations: Reservation[] = [
{ {
id: 1, id: 1,
@ -70,8 +81,21 @@ export class ReservationsService {
return reservation; return reservation;
} }
getReservationsByUserId(userId: number): Reservation[] { async getReservationsByUserId(userId: number): Promise<ReservationWithYacht[]> {
return this.reservations.filter((r) => r.reservatorId === userId); const reservations = this.reservations.filter((r) => r.reservatorId === userId);
// Populate данные по яхте для каждой резервации
const reservationsWithYacht = await Promise.all(
reservations.map(async (reservation) => {
const yacht = await this.catalogService.getCatalogItemById(reservation.yachtId);
return {
...reservation,
yacht: yacht || undefined,
};
})
);
return reservationsWithYacht;
} }
getReservationsByYachtId(yachtId: number): Reservation[] { getReservationsByYachtId(yachtId: number): Reservation[] {