diff --git a/app/controllers/colles_controller.ts b/app/controllers/colles_controller.ts index e9bf3a6..5095459 100644 --- a/app/controllers/colles_controller.ts +++ b/app/controllers/colles_controller.ts @@ -3,6 +3,7 @@ import { ColleService } from '#services/colle_service' import { createColleValidator, createUpcomingCollesValidator } from '#validators/colle' import { inject } from '@adonisjs/core' import type { HttpContext } from '@adonisjs/core/http' +import redis from '@adonisjs/redis/services/main' import { DateTime } from 'luxon' @inject() @@ -42,6 +43,7 @@ export default class CollesController { .preload('examiner') .preload('subject') .preload('room') + .preload('attachments') .first() if (!colle) { return response.notFound({ message: 'Colle not found' }) @@ -57,6 +59,39 @@ export default class CollesController { } } + async refresh({ params, response, auth }: HttpContext) { + const colleId = parseInt(params.colleId) + if (isNaN(colleId)) { + return response.badRequest({ message: 'Invalid colle ID' }) + } + + // Retrieve the colle by ID + const colle = await Colle.query() + .where('id', colleId) + .whereHas('student', (query) => { + query.where('className', auth.user!.className) + }) + .first() + if (!colle) { + return response.notFound({ message: 'Colle not found' }) + } + + // Post Redis message to refresh the colle + await redis.publish( + 'jobs_queue', + JSON.stringify({ + type: 0, // Refresh colle + colle_id: colle.bjid, + colle_secret: colle.bjsecret, + class_name: auth.user!.className, + }) + ) + return response.ok({ + success: true, + message: `Colle ${colleId} refresh request sent`, + }) + } + async create({ request, response }: HttpContext) { const { colle: payload, className } = await request.validateUsing(createColleValidator) @@ -93,19 +128,54 @@ export default class CollesController { } // Check if the colle already exists - const colle = await Colle.query() + const existing = await Colle.query() .where('studentId', student.id) .where('subjectId', subject.id) .where('date', date.toISO()) .first() // If it exists, update the existing colle - if (colle) { - Object.assign(colle, colleData) - return colle.save() + if (existing) { + // Merge the new data with the existing colle + Object.assign(existing, colleData) + + // Handle attachments if any + if (payload.attachments && payload.attachments.length > 0) { + // Retrieve existing attachments + const existingAttachments = await existing.related('attachments').query() + // Remove attachments that are not in the new payload + const existingAttachmentUrls = new Set(existingAttachments.map((a) => a.path)) + for (const attachment of payload.attachments) { + if (!existingAttachmentUrls.has(attachment.url)) { + await existing.related('attachments').create({ + name: attachment.name, + path: attachment.url, + }) + } + } + // Remove attachments that are not in the new payload + for (const attachment of existingAttachments) { + if (!payload.attachments.some((a) => a.url === attachment.path)) { + await attachment.delete() + } + } + } + + return existing.save() } - // Create the colle - return Colle.create(colleData) + const colle = await Colle.create(colleData) + + // Handle attachments if any + if (payload.attachments && payload.attachments.length > 0) { + for (const attachment of payload.attachments) { + await colle.related('attachments').create({ + path: attachment.url, + name: attachment.name, + }) + } + } + + return colle } async createUpcoming({ request }: HttpContext) { diff --git a/app/models/colle_attachment.ts b/app/models/colle_attachment.ts index 7ebf60d..e454cad 100644 --- a/app/models/colle_attachment.ts +++ b/app/models/colle_attachment.ts @@ -4,6 +4,9 @@ export default class ColleAttachment extends BaseModel { @column({ isPrimary: true }) declare id: number + @column() + declare colleId: number + @column() declare name: string diff --git a/app/services/colle_service.ts b/app/services/colle_service.ts index 089a509..d87d863 100644 --- a/app/services/colle_service.ts +++ b/app/services/colle_service.ts @@ -75,6 +75,7 @@ export class ColleService { .preload('examiner') .preload('subject') .preload('room') + .preload('attachments') .where('date', '>=', startDate) .where('date', '<=', endDate) .whereHas('student', (query) => { @@ -85,10 +86,11 @@ export class ColleService { .orderBy('date', 'asc') const studentColles = await Colle.query() + .preload('student') .preload('examiner') .preload('subject') .preload('room') - .preload('student') + .preload('attachments') .where('date', '>=', startDate) .where('date', '<=', endDate) .where('studentId', student.id) diff --git a/app/validators/colle.ts b/app/validators/colle.ts index 2a077fc..bbc5c57 100644 --- a/app/validators/colle.ts +++ b/app/validators/colle.ts @@ -11,7 +11,12 @@ const colle = vine.object({ date: vine.date({ formats: ['iso8601'] }), bjsecret: vine.string().optional(), bjid: vine.string().optional(), - // TODO: Add attachments validation + attachments: vine.array( + vine.object({ + url: vine.string(), + name: vine.string().maxLength(255), + }) + ).optional(), }) const className = vine.string() diff --git a/start/routes.ts b/start/routes.ts index 0b8b2e1..586e43d 100644 --- a/start/routes.ts +++ b/start/routes.ts @@ -36,24 +36,12 @@ router.post('/users/@me', [UserController, 'update']).use(middleware.auth()) const SubjectsController = () => import('#controllers/subjects_controller') router.get('/subjects', [SubjectsController, 'index']).use(middleware.auth()) -// TEST ROUTE -// import redis from '@adonisjs/redis/services/main' - -// router.get('/', async () => { -// await redis.publish("jobs_queue", JSON.stringify({ -// type: 1, -// date: "20/09/2019", -// class_name: "MPSI 2", -// })) -// return { message: 'Hello, world!' } -// }) -// END TEST ROUTE - const CollesController = () => import('#controllers/colles_controller') router.group(() => { // TODO: PRIVATE ROUTES router.post('/', [CollesController, 'create']) router.post('/upcoming', [CollesController, 'createUpcoming']) + router.post('/:colleId/refresh', [CollesController, 'refresh']).use(middleware.auth()) router.get('/', [CollesController, 'index']).use(middleware.auth()) router.get('/:colleId', [CollesController, 'show']).use(middleware.auth()) }