crone
This commit is contained in:
@@ -0,0 +1,79 @@
|
|||||||
|
import { Injectable, Logger } from '@nestjs/common';
|
||||||
|
import { Cron } from '@nestjs/schedule';
|
||||||
|
import { EntityManager } from '@mikro-orm/postgresql';
|
||||||
|
import { FoodRepository } from '../../foods/repositories/food.repository';
|
||||||
|
import { ReviewRepository } from '../repositories/review.repository';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class FoodRatingCronService {
|
||||||
|
private readonly logger = new Logger(FoodRatingCronService.name);
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private readonly em: EntityManager,
|
||||||
|
private readonly foodRepository: FoodRepository,
|
||||||
|
private readonly reviewRepository: ReviewRepository,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cron job that runs at midnight every day (00:00:00 UTC)
|
||||||
|
* Calculates and updates the average rating for each restaurant food
|
||||||
|
*/
|
||||||
|
@Cron('0 0 * * *', {
|
||||||
|
name: 'calculateFoodRatings',
|
||||||
|
timeZone: 'UTC',
|
||||||
|
})
|
||||||
|
async handleCron() {
|
||||||
|
this.logger.log('Starting daily food rating calculation cron job...');
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Get all foods from all restaurants
|
||||||
|
const foods = await this.foodRepository.find({});
|
||||||
|
|
||||||
|
this.logger.log(`Found ${foods.length} foods to process`);
|
||||||
|
|
||||||
|
let updatedCount = 0;
|
||||||
|
let errorCount = 0;
|
||||||
|
|
||||||
|
// Process each food item
|
||||||
|
for (const food of foods) {
|
||||||
|
try {
|
||||||
|
// Get all approved reviews for this food that are not deleted
|
||||||
|
const reviews = await this.reviewRepository.find(
|
||||||
|
{
|
||||||
|
food: { id: food.id },
|
||||||
|
isApproved: true,
|
||||||
|
deletedAt: null,
|
||||||
|
},
|
||||||
|
{ fields: ['rating'] },
|
||||||
|
);
|
||||||
|
|
||||||
|
// Calculate average rating
|
||||||
|
let averageRating = 0;
|
||||||
|
if (reviews.length > 0) {
|
||||||
|
const sum = reviews.reduce((acc, review) => acc + review.rating, 0);
|
||||||
|
averageRating = sum / reviews.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update food rate
|
||||||
|
food.rate = parseFloat(averageRating.toFixed(2));
|
||||||
|
this.em.persist(food);
|
||||||
|
|
||||||
|
updatedCount++;
|
||||||
|
} catch (error) {
|
||||||
|
this.logger.error(`Error processing food ${food.id}: ${error.message}`, error.stack);
|
||||||
|
errorCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Flush all updates at once for better performance
|
||||||
|
await this.em.flush();
|
||||||
|
|
||||||
|
this.logger.log(
|
||||||
|
`Food rating calculation completed. Updated: ${updatedCount}, Errors: ${errorCount}`,
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
this.logger.error(`Error in food rating cron job: ${error.message}`, error.stack);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -2,6 +2,7 @@ import { Module } from '@nestjs/common';
|
|||||||
import { ReviewService } from './providers/review.service';
|
import { ReviewService } from './providers/review.service';
|
||||||
import { ReviewController } from './controllers/review.controller';
|
import { ReviewController } from './controllers/review.controller';
|
||||||
import { ReviewRepository } from './repositories/review.repository';
|
import { ReviewRepository } from './repositories/review.repository';
|
||||||
|
import { FoodRatingCronService } from './providers/food-rating-cron.service';
|
||||||
import { MikroOrmModule } from '@mikro-orm/nestjs';
|
import { MikroOrmModule } from '@mikro-orm/nestjs';
|
||||||
import { Review } from './entities/review.entity';
|
import { Review } from './entities/review.entity';
|
||||||
import { FoodModule } from '../foods/food.module';
|
import { FoodModule } from '../foods/food.module';
|
||||||
@@ -18,7 +19,7 @@ import { JwtModule } from '@nestjs/jwt';
|
|||||||
JwtModule,
|
JwtModule,
|
||||||
],
|
],
|
||||||
controllers: [ReviewController],
|
controllers: [ReviewController],
|
||||||
providers: [ReviewService, ReviewRepository],
|
providers: [ReviewService, ReviewRepository, FoodRatingCronService],
|
||||||
exports: [ReviewRepository],
|
exports: [ReviewRepository],
|
||||||
})
|
})
|
||||||
export class ReviewModule {}
|
export class ReviewModule {}
|
||||||
|
|||||||
Reference in New Issue
Block a user