feat: add attachments

This commit is contained in:
Nathan Lamy 2025-08-19 20:07:38 +02:00
parent 12241d52b9
commit 06fc137057
5 changed files with 89 additions and 21 deletions

View file

@ -3,6 +3,7 @@ import { ColleService } from '#services/colle_service'
import { createColleValidator, createUpcomingCollesValidator } from '#validators/colle' import { createColleValidator, createUpcomingCollesValidator } from '#validators/colle'
import { inject } from '@adonisjs/core' import { inject } from '@adonisjs/core'
import type { HttpContext } from '@adonisjs/core/http' import type { HttpContext } from '@adonisjs/core/http'
import redis from '@adonisjs/redis/services/main'
import { DateTime } from 'luxon' import { DateTime } from 'luxon'
@inject() @inject()
@ -42,6 +43,7 @@ export default class CollesController {
.preload('examiner') .preload('examiner')
.preload('subject') .preload('subject')
.preload('room') .preload('room')
.preload('attachments')
.first() .first()
if (!colle) { if (!colle) {
return response.notFound({ message: 'Colle not found' }) 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) { async create({ request, response }: HttpContext) {
const { colle: payload, className } = await request.validateUsing(createColleValidator) const { colle: payload, className } = await request.validateUsing(createColleValidator)
@ -93,19 +128,54 @@ export default class CollesController {
} }
// Check if the colle already exists // Check if the colle already exists
const colle = await Colle.query() const existing = await Colle.query()
.where('studentId', student.id) .where('studentId', student.id)
.where('subjectId', subject.id) .where('subjectId', subject.id)
.where('date', date.toISO()) .where('date', date.toISO())
.first() .first()
// If it exists, update the existing colle // If it exists, update the existing colle
if (colle) { if (existing) {
Object.assign(colle, colleData) // Merge the new data with the existing colle
return colle.save() 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,
})
} }
// Create the colle }
return Colle.create(colleData) // 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()
}
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) { async createUpcoming({ request }: HttpContext) {

View file

@ -4,6 +4,9 @@ export default class ColleAttachment extends BaseModel {
@column({ isPrimary: true }) @column({ isPrimary: true })
declare id: number declare id: number
@column()
declare colleId: number
@column() @column()
declare name: string declare name: string

View file

@ -75,6 +75,7 @@ export class ColleService {
.preload('examiner') .preload('examiner')
.preload('subject') .preload('subject')
.preload('room') .preload('room')
.preload('attachments')
.where('date', '>=', startDate) .where('date', '>=', startDate)
.where('date', '<=', endDate) .where('date', '<=', endDate)
.whereHas('student', (query) => { .whereHas('student', (query) => {
@ -85,10 +86,11 @@ export class ColleService {
.orderBy('date', 'asc') .orderBy('date', 'asc')
const studentColles = await Colle.query() const studentColles = await Colle.query()
.preload('student')
.preload('examiner') .preload('examiner')
.preload('subject') .preload('subject')
.preload('room') .preload('room')
.preload('student') .preload('attachments')
.where('date', '>=', startDate) .where('date', '>=', startDate)
.where('date', '<=', endDate) .where('date', '<=', endDate)
.where('studentId', student.id) .where('studentId', student.id)

View file

@ -11,7 +11,12 @@ const colle = vine.object({
date: vine.date({ formats: ['iso8601'] }), date: vine.date({ formats: ['iso8601'] }),
bjsecret: vine.string().optional(), bjsecret: vine.string().optional(),
bjid: 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() const className = vine.string()

View file

@ -36,24 +36,12 @@ router.post('/users/@me', [UserController, 'update']).use(middleware.auth())
const SubjectsController = () => import('#controllers/subjects_controller') const SubjectsController = () => import('#controllers/subjects_controller')
router.get('/subjects', [SubjectsController, 'index']).use(middleware.auth()) 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') const CollesController = () => import('#controllers/colles_controller')
router.group(() => { router.group(() => {
// TODO: PRIVATE ROUTES // TODO: PRIVATE ROUTES
router.post('/', [CollesController, 'create']) router.post('/', [CollesController, 'create'])
router.post('/upcoming', [CollesController, 'createUpcoming']) router.post('/upcoming', [CollesController, 'createUpcoming'])
router.post('/:colleId/refresh', [CollesController, 'refresh']).use(middleware.auth())
router.get('/', [CollesController, 'index']).use(middleware.auth()) router.get('/', [CollesController, 'index']).use(middleware.auth())
router.get('/:colleId', [CollesController, 'show']).use(middleware.auth()) router.get('/:colleId', [CollesController, 'show']).use(middleware.auth())
} }