api/app/controllers/internals_controller.ts
2025-08-26 00:26:11 +02:00

90 lines
2.7 KiB
TypeScript

import Meal from '#models/meal'
import MealRegistration from '#models/meal_registration'
import env from '#start/env'
import { updateMealsRegistrationsValidator } from '#validators/meal'
import type { HttpContext } from '@adonisjs/core/http'
import redis from '@adonisjs/redis/services/main'
import { DateTime } from 'luxon'
export default class InternalsController {
// POST /internals/back-fetch
async backFetch({ response, request }: HttpContext) {
const className = request.input('className')
if (!className) {
return response.badRequest({ message: 'className is required' })
}
// Start a new thread to avoid blocking the event loop
response.send({
success: true,
message: `Fetching colles for class ${className}...`,
})
setImmediate(async () => {
await queue(className)
console.log(`Colles fetching for class ${className} completed.`)
})
}
// POST /internals/fetch-meals
async fetchMeals({ response }: HttpContext) {
await redis.publish(
'jobs_queue',
JSON.stringify({
type: 3, // Fetch meals
class_name: env.get('DEFAULT_CLASS_NAME'),
})
)
return response.send({ success: true, message: 'Fetching meals...' })
}
// POST /internals/meals-registrations
async updateMealsRegistrations({ response, request }: HttpContext) {
const { userId, meals } = await request.validateUsing(updateMealsRegistrationsValidator)
// Remove all existing registrations for the user
await MealRegistration.query().where('user_id', userId).delete()
for (const mealData of meals) {
const meal = await Meal.query()
.where({
date: mealData.date,
type: mealData.meal_type === 'lunch' ? 0 : 1,
})
.first()
if (meal) {
// Create a new registration
await MealRegistration.create({
mealId: meal.id,
userId: userId,
})
}
}
return response.send({
success: true,
message: 'Meal registrations updated successfully',
})
}
}
async function queue(className: string) {
// 1er Septembre 2019 début de BJColle
const startDate = DateTime.fromISO('2019-09-01T00:00:00')
const endDate = DateTime.now()
let date = endDate
// Loop through all days from startDate to endDate
while (date >= startDate) {
await redis.publish(
'jobs_queue',
JSON.stringify({
type: 1, // Fetch day colles
// Format DD/MM/YYYY
date: date.toFormat('dd/MM/yyyy'),
class_name: className,
})
)
date = date.minus({ days: 1 })
// Wait for 1 second to avoid overwhelming the queue
await new Promise((resolve) => setTimeout(resolve, 1000))
}
}