From be323a762d45b3833efabc66dc691dbc991754a4 Mon Sep 17 00:00:00 2001 From: BlazyOne Date: Wed, 9 Oct 2024 16:36:36 +0500 Subject: [PATCH 1/3] =?UTF-8?q?Edits=20after=20review=20of=20task=204.10.?= =?UTF-8?q?=20=D0=9F=D0=BE=D0=BA=D0=BE=D1=80=D0=B8=D1=82=D0=B5=D0=BB=D1=8C?= =?UTF-8?q?=20=D0=B1=D0=B0=D0=B7=20=D0=B4=D0=B0=D0=BD=D0=BD=D1=8B=D1=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/rest/rest.application.ts | 6 ++++-- .../libs/database-client/mongo.database-client.ts | 10 +++------- src/shared/modules/offer/default-offer.service.ts | 2 +- src/shared/modules/user/default-user.service.ts | 2 +- 4 files changed, 9 insertions(+), 11 deletions(-) diff --git a/src/rest/rest.application.ts b/src/rest/rest.application.ts index ec6b261..2506899 100644 --- a/src/rest/rest.application.ts +++ b/src/rest/rest.application.ts @@ -15,6 +15,8 @@ export class RestApplication { ) {} private async initDb() { + this.logger.info('Init database…'); + const mongoUri = getMongoURI( this.config.get('DB_USER'), this.config.get('DB_PASSWORD'), @@ -24,14 +26,14 @@ export class RestApplication { ); await this.databaseClient.connect(mongoUri); + + this.logger.info('Init database completed'); } public async init() { this.logger.info('Application initialization'); this.logger.info(`Get value from env $PORT: ${this.config.get('PORT')}`); - this.logger.info('Init database…'); await this.initDb(); - this.logger.info('Init database completed'); } } diff --git a/src/shared/libs/database-client/mongo.database-client.ts b/src/shared/libs/database-client/mongo.database-client.ts index bb0e048..3099e9b 100644 --- a/src/shared/libs/database-client/mongo.database-client.ts +++ b/src/shared/libs/database-client/mongo.database-client.ts @@ -11,17 +11,13 @@ const RETRY_TIMEOUT = 1000; @injectable() export class MongoDatabaseClient implements DatabaseClient { private mongoose: typeof Mongoose; - private isConnected: boolean = false; + private isConnected = false; constructor(@inject(Component.Logger) private readonly logger: Logger) {} - public isConnectedToDatabase() { - return this.isConnected; - } - public async connect(uri: string): Promise { if (this.isConnected) { - throw new Error('MongoDB client is already connected'); + return; } this.logger.info('Trying to connect to MongoDB…'); @@ -50,7 +46,7 @@ export class MongoDatabaseClient implements DatabaseClient { public async disconnect(): Promise { if (!this.isConnected) { - throw new Error('Not connected to the database'); + return; } await this.mongoose.disconnect?.(); diff --git a/src/shared/modules/offer/default-offer.service.ts b/src/shared/modules/offer/default-offer.service.ts index 0714fe7..479e6ea 100644 --- a/src/shared/modules/offer/default-offer.service.ts +++ b/src/shared/modules/offer/default-offer.service.ts @@ -26,6 +26,6 @@ export class DefaultOfferService implements OfferService { public async findById( offerId: string, ): Promise | null> { - return await this.offerModel.findById(offerId).exec(); + return this.offerModel.findById(offerId); } } diff --git a/src/shared/modules/user/default-user.service.ts b/src/shared/modules/user/default-user.service.ts index 87f95b3..3da9c79 100644 --- a/src/shared/modules/user/default-user.service.ts +++ b/src/shared/modules/user/default-user.service.ts @@ -43,6 +43,6 @@ export class DefaultUserService implements UserService { return existingUser; } - return await this.create(dto, salt); + return this.create(dto, salt); } } From a414f3af5a624b1575955264c6a191d7c6d9b7ad Mon Sep 17 00:00:00 2001 From: BlazyOne Date: Thu, 10 Oct 2024 12:14:30 +0500 Subject: [PATCH 2/3] Adds OpenAPI specification for user endpoints and create offer endpoint --- specification/project.spec.yml | 402 +++++++++++++++++++++++++++++++++ 1 file changed, 402 insertions(+) create mode 100644 specification/project.spec.yml diff --git a/specification/project.spec.yml b/specification/project.spec.yml new file mode 100644 index 0000000..44789b3 --- /dev/null +++ b/specification/project.spec.yml @@ -0,0 +1,402 @@ +openapi: 3.0.3 +info: + title: API сервер для проекта «Шесть городов». + description: |- + * Список ресурсов и маршрутов сервера «Шесть городов». + license: + name: MIT + url: https://opensource.org/licenses/MIT + version: 1.0.0 +tags: + - name: offers + description: Действия с предложениями по аренде. + - name: comments + description: Действия с комментариями. + - name: users + description: Действия с пользователем. +paths: + /users/register: + post: + tags: + - users + summary: Регистрация пользователя + description: Регистрирует нового пользователя. + + requestBody: + description: Информация для создания нового пользователя. + content: + application/json: + schema: + $ref: '#/components/schemas/createUser' + required: true + + responses: + '201': + description: Пользователь зарегистрирован. Объект пользователя. + content: + application/json: + schema: + $ref: '#/components/schemas/user' + + '409': + description: Пользователь с таким email уже существует. + + /users/login: + post: + tags: + - users + summary: Аутентификация пользователя + description: Аутентифицирует пользователя на основе логина и пароля + + requestBody: + description: Информация для создания нового пользователя. + content: + application/json: + schema: + $ref: '#/components/schemas/login' + required: true + + responses: + '200': + description: Пользователь аутентифицировался. Тело ответа содержит токен + content: + application/json: + schema: + $ref: '#/components/schemas/token' + + '401': + description: Неверный email или пароль. + + get: + tags: + - users + summary: Проверка состояния пользователя + description: Возвращает информацию по авторизованному пользователю + + responses: + '200': + description: Пользователь аутентифицирован. Тело ответа содержит информацию о пользователе. + content: + application/json: + schema: + $ref: '#/components/schemas/user' + + '401': + description: Пользователь не аутентифицирован. + + /users/logout: + get: + tags: + - users + summary: Логаут пользователя + description: Реализует выход пользователя из приложения + + responses: + '204': + description: Пользователь вышел из приложения. + + /users/{userId}/avatar: + post: + tags: + - users + summary: Загрузить изображение аватара + description: Загружает изображение аватара пользователя. Изображение + аватара должно быть в формате `png` или `jpg`. + + requestBody: + content: + multipart/form-data: + schema: + type: object + properties: + # 'file' will be the field name in this multipart request + file: + type: string + format: binary + + responses: + '201': + description: Аватар пользователя был загружен. + + /offers/add: + post: + tags: + - offers + summary: Создание предложения + description: Создаёт предложение об аренде на основе данных в теле запроса. + + requestBody: + description: Информация для создания нового предложения. + content: + application/json: + schema: + $ref: '#/components/schemas/createOffer' + required: true + + responses: + '201': + description: Предложение об аренде создано. В теле ответа информация о новом предложении. + content: + application/json: + schema: + $ref: '#/components/schemas/offer' + + '400': + description: Отправлены некорректные данные. + +components: + schemas: + createUser: + type: object + required: + - email + - name + - password + + properties: + email: + type: string + example: keks@htmlacademy.ru + + name: + type: string + example: Keks + + password: + type: string + example: 123456 + + user: + type: object + + properties: + id: + type: string + example: 6329c3d6a04ab1061c6425ea + + email: + type: string + example: keks@htmlacademy.ru + + name: + type: string + example: 'Keks' + + login: + type: object + required: + - email + - password + + properties: + email: + type: string + example: keks@htmlacademy.ru + + password: + type: string + example: 123456 + + token: + type: object + properties: + token: + type: string + example: 6329c3d6a04ab1061c6425ea + + createOffer: + type: object + required: + - title + - description + - city + - preview + - photos + - isPremium + - housingType + - roomsNumber + - guestsNumber + - price + - facilities + - latitude + - longitude + + properties: + title: + type: string + example: 'Hotel California' + + description: + type: string + example: 'Such a lovely place' + + city: + $ref: '#/components/schemas/cities' + + preview: + type: string + example: hotel.jpg + + photos: + type: array + items: + type: string + example: + - photo1.jpg + - photo2.jpg + - photo3.jpg + - photo4.jpg + - photo5.jpg + - photo6.jpg + + isPremium: + type: boolean + example: true + + housingType: + $ref: '#/components/schemas/housingType' + + roomsNumber: + type: integer + example: 4 + + guestsNumber: + type: integer + example: 4 + + price: + type: integer + example: 10000 + + facilities: + $ref: '#/components/schemas/facilities' + + offer: + type: object + required: + - title + - description + - createdAt + - city + - preview + - photos + - isPremium + - isFavorite + - rating + - housingType + - roomsNumber + - guestsNumber + - price + - facilities + - latitude + - longitude + - author + - commentsCount + + properties: + title: + type: string + example: 'Hotel California' + + description: + type: string + example: 'Such a lovely place' + + createdAt: + type: string + example: '2022-04-06T08:45:40.283Z' + + city: + $ref: '#/components/schemas/cities' + + preview: + type: string + example: hotel.jpg + + photos: + type: array + items: + type: string + example: + - photo1.jpg + - photo2.jpg + - photo3.jpg + - photo4.jpg + - photo5.jpg + - photo6.jpg + + isPremium: + type: boolean + example: true + + isFavorite: + type: boolean + example: true + + rating: + type: number + example: 4.5 + + housingType: + $ref: '#/components/schemas/housingType' + + roomsNumber: + type: integer + example: 4 + + guestsNumber: + type: integer + example: 4 + + price: + type: integer + example: 10000 + + facilities: + $ref: '#/components/schemas/facilities' + + author: + $ref: '#/components/schemas/user' + + commentsCount: + type: integer + example: 50 + + latitude: + type: number + example: 53.550341 + + longitude: + type: number + example: 10.000654 + + cities: + type: string + enum: + - Paris + - Cologne + - Brussels + - Amsterdam + - Hamburg + - Dusseldorf + + housingType: + type: string + enum: + - Apartment + - House + - Room + - Hotel + + facilities: + type: array + items: + type: string + enum: + - Breakfast + - Air conditioning + - Laptop friendly workspace + - Baby seat + - Washer + - Towels + - Fridge From 996bf7346bb9498ca0fe115cb1f6458817c2917f Mon Sep 17 00:00:00 2001 From: BlazyOne Date: Thu, 10 Oct 2024 12:22:11 +0500 Subject: [PATCH 3/3] Adds id to offer schema in specification --- specification/project.spec.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/specification/project.spec.yml b/specification/project.spec.yml index 44789b3..7ef741c 100644 --- a/specification/project.spec.yml +++ b/specification/project.spec.yml @@ -294,6 +294,10 @@ components: - commentsCount properties: + id: + type: string + example: 6329c3d6a04ab1061c6425ea + title: type: string example: 'Hotel California'