Skip to content

Commit

Permalink
Merge pull request #10 from skudinva/module7-task2
Browse files Browse the repository at this point in the history
  • Loading branch information
keksobot authored Oct 16, 2024
2 parents 8dbd898 + da4bbb4 commit ea9e895
Show file tree
Hide file tree
Showing 7 changed files with 46 additions and 21 deletions.
File renamed without changes.
4 changes: 2 additions & 2 deletions TODO
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Todo:
☐ В *service отлавливать ошибки через try catch
☐ SALT из контроллера передается в сервис параметром. Для чего? Почему соль нельзя в сервисе считать из конфига? Нарушение паттерна? Можно перетащить в сервис!!!
В DTO добавить валидацию
кол-во коментов динамически https://stackoverflow.com/questions/48389112/mongodb-best-practice-to-count-related-documents
В DTO добавить валидацию @done(24-10-12 13:12)
кол-во коментов динамически https://stackoverflow.com/questions/48389112/mongodb-best-practice-to-count-related-documents @done(24-10-12 13:12)
32 changes: 20 additions & 12 deletions src/shared/modules/offer/default-offer-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,21 @@ export class DefaultOfferService implements OfferService {
}

async findById(offerId: string): Promise<OfferEntityDocument | null> {
return await this.offerModel.findById(offerId).populate(['userId']).exec();
const [reviews] = await this.reviewModel.aggregate([
{ $match: { offerId } },
{ $count: 'reviewsCount' },
]);

const result = await this.offerModel
.findById(offerId)
.populate(['userId'])
.exec();

if (result) {
Object.assign(result, { reviewsCount: reviews.reviewsCount });
}

return result;
}

async findPremiumByCity(
Expand Down Expand Up @@ -119,16 +133,10 @@ export class DefaultOfferService implements OfferService {
.exec();
}

async updateRating(offerId: string): Promise<OfferEntityDocument | null> {
///// Очень сомневаюсь в правильности
const [{ averageRating }] = await this.reviewModel.aggregate([
{ $match: { offerId } },
{ $group: { _id: null, averageRating: { $avg: '$rating' } } },
]);

return this.offerModel
.findByIdAndUpdate(offerId, [{ rating: averageRating }], { new: true })
.populate(['userId'])
.exec();
async updateRating(
offerId: string,
rating: number
): Promise<OfferEntityDocument | null> {
return this.offerModel.findByIdAndUpdate(offerId, { rating }).exec();
}
}
5 changes: 4 additions & 1 deletion src/shared/modules/offer/offer-service.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ export interface OfferService extends DocumentExists {
offerId: string,
isFavorite: number
): Promise<OfferEntityDocument | null>;
updateRating(offerId: string): Promise<OfferEntityDocument | null>;
updateRating(
offerId: string,
rating: number
): Promise<OfferEntityDocument | null>;
findFavorites(): Promise<OfferEntityDocument[]>;
}
2 changes: 1 addition & 1 deletion src/shared/modules/offer/offer.http
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ GET http://localhost:4000/offers HTTP/1.1


###
GET http://localhost:4000/offers/67069067990eba53b6c2b130 HTTP/1.1
GET http://localhost:4000/offers/670530d901266b562fbdc0ef HTTP/1.1

###
POST http://localhost:4000/offers/ HTTP/1.1
Expand Down
20 changes: 17 additions & 3 deletions src/shared/modules/review/default-review-service.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { Logger } from '#libs/logger/logger.interface.js';
import { OfferService } from '#modules/offer/offer-service.interface.js';
import { Component } from '#types/component.enum.js';
import { types } from '@typegoose/typegoose';
import { inject, injectable } from 'inversify';
import mongoose from 'mongoose';
import { CreateReviewDto } from './dto/create-review-dto.js';
import { ReviewEntity } from './review-entity.js';
import {
Expand All @@ -14,17 +16,29 @@ export class DefaultReviewService implements ReviewService {
constructor(
@inject(Component.Logger) private readonly logger: Logger,
@inject(Component.ReviewModel)
private readonly reviewModel: types.ModelType<ReviewEntity>
private readonly reviewModel: types.ModelType<ReviewEntity>,
@inject(Component.OfferService)
private readonly offerService: OfferService
) {}

async calculateAverageRating(offerId: string): Promise<number> {
const [review] = await this.reviewModel.aggregate<Record<string, number>>([
{ $match: { offerId: new mongoose.Types.ObjectId(offerId) } },
{ $group: { _id: null, averageRating: { $avg: '$rating' } } },
]);
return +review.averageRating.toFixed(1);
}

async create(
offerId: string,
dto: CreateReviewDto
): Promise<ReviewEntityDocument> {
const result = await this.reviewModel.create({ ...dto, offerId });
this.logger.info('New review created');
const averageRating = await this.calculateAverageRating(offerId);

return result;
this.offerService.updateRating(offerId, averageRating);
this.logger.info('New review created');
return result.populate('userId');
}

async findByOfferId(offerId: string): Promise<ReviewEntityDocument[] | null> {
Expand Down
4 changes: 2 additions & 2 deletions src/shared/modules/review/review.http
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ POST http://localhost:4000/reviews/670530d901266b562fbdc0ef HTTP/1.1
Content-Type: application/json

{
"offerId": "67069067990eba53b6c2b130",
"offerId": "670530d901266b562fbdc0ef",
"date": "2024-08-10T08:11:23.283Z",
"userId": "6704f9003df41d32ec047a0e",
"comment": "test sdhfskdhfks",
"rating": 4
"rating": 1.3
}

0 comments on commit ea9e895

Please sign in to comment.