refactor food service

This commit is contained in:
2025-12-20 19:43:29 +03:30
parent 4e117ad42c
commit f0b2b6ce17
+56 -40
View File
@@ -110,59 +110,75 @@ export class FoodService {
return food;
}
/**
* Find active foods for a restaurant based on current week day and meal type in Iran timezone.
* @param slug - Restaurant slug identifier
* @returns Array of active foods matching current day and meal time
*/
async findByWeekDateAndMealType(slug: string): Promise<Food[]> {
// const cacheKey = `${this.FOODS_BY_RESTAURANT_CACHE_KEY_PREFIX}${slug}`;
// Try to get from cache first
// const cachedFoods = await this.cacheService.get<string>(cacheKey);
// if (cachedFoods) {
// try {
// const parsed: unknown = JSON.parse(cachedFoods);
// if (Array.isArray(parsed)) {
// return parsed as Food[];
// }
// } catch {
// // If parsing fails, continue to fetch from DB
// }
// }
// If not in cache, fetch from database
const restaurant = await this.restRepository.findOne({ slug });
if (!restaurant) {
throw new NotFoundException(RestMessage.NOT_FOUND);
}
const nowInIran = new Date(new Date().toLocaleString('en-US', { timeZone: 'Asia/Tehran' }));
const { iranWeekDay, mealType } = this.getCurrentIranTimeContext();
const queryFilter: FilterQuery<Food> = {
restaurant: { slug },
isActive: true,
weekDays: { $contains: iranWeekDay },
...(mealType ? { mealTypes: { $contains: mealType } } : {}),
} as unknown as FilterQuery<Food>;
return this.foodRepository.find(queryFilter, { populate: ['category'] });
}
/**
* Get current Iran timezone context (weekday and meal type).
* @returns Object containing Iran weekday (0-6, where 0=Saturday) and current meal type
*/
private getCurrentIranTimeContext(): { iranWeekDay: number; mealType: MealType | null } {
const nowInIran = new Date(new Date().toLocaleString('en-US', { timeZone: 'Asia/Tehran' }));
const weekDay = nowInIran.getDay(); // 0 = Sunday, 6 = Saturday
const currentHour = nowInIran.getHours();
// Convert to Iran weekday: Saturday=0, Sunday=1, ..., Friday=6
// JavaScript: Sunday=0, Monday=1, ..., Saturday=6
// Iran week: Saturday=0, Sunday=1, ..., Friday=6
const iranWeekDay = (weekDay + 1) % 7;
let mealType: string | null = null;
if (currentHour >= 6 && currentHour < 11) {
mealType = MealType.BREAKFAST;
} else if (currentHour >= 11 && currentHour < 15) {
mealType = MealType.LUNCH;
} else if (currentHour >= 15 && currentHour < 19) {
mealType = MealType.SNACK;
} else if (currentHour >= 19 && currentHour < 24) {
mealType = MealType.DINNER;
const mealType = this.getMealTypeByHour(currentHour);
return { iranWeekDay, mealType };
}
/**
* Determine meal type based on current hour in Iran timezone.
* @param hour - Current hour (0-23)
* @returns Meal type or null if outside meal hours
*/
private getMealTypeByHour(hour: number): MealType | null {
const MEAL_TIME_RANGES = {
BREAKFAST: { start: 6, end: 11 },
LUNCH: { start: 11, end: 15 },
SNACK: { start: 15, end: 19 },
DINNER: { start: 19, end: 24 },
} as const;
if (hour >= MEAL_TIME_RANGES.BREAKFAST.start && hour < MEAL_TIME_RANGES.BREAKFAST.end) {
return MealType.BREAKFAST;
}
if (hour >= MEAL_TIME_RANGES.LUNCH.start && hour < MEAL_TIME_RANGES.LUNCH.end) {
return MealType.LUNCH;
}
if (hour >= MEAL_TIME_RANGES.SNACK.start && hour < MEAL_TIME_RANGES.SNACK.end) {
return MealType.SNACK;
}
if (hour >= MEAL_TIME_RANGES.DINNER.start && hour < MEAL_TIME_RANGES.DINNER.end) {
return MealType.DINNER;
}
const foods = await this.foodRepository.find(
// cast to FilterQuery<Food> because MikroORM types don't accept a numeric $contains value for jsonb number[]
{
restaurant: { slug },
isActive: true,
...(mealType ? { mealTypes: { $contains: mealType } } : {}),
weekDays: { $contains: iranWeekDay },
} as unknown as FilterQuery<Food>,
{ populate: ['category'] },
);
// Cache the result
// await this.cacheService.set(cacheKey, JSON.stringify(foods), this.FOODS_CACHE_TTL);
return foods;
return null;
}
async update(restId: string, id: string, dto: Partial<CreateFoodDto>): Promise<Food> {