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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user