feat: send notifications on update

This commit is contained in:
Nathan Lamy 2025-08-21 10:49:56 +02:00
parent 7093b344ed
commit 169df9715e
2 changed files with 63 additions and 17 deletions

View file

@ -1,5 +1,6 @@
import Colle from '#models/colle' import Colle from '#models/colle'
import { ColleService } from '#services/colle_service' import { ColleService } from '#services/colle_service'
import { NotificationService } from '#services/notification_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'
@ -8,7 +9,10 @@ import { DateTime } from 'luxon'
@inject() @inject()
export default class CollesController { export default class CollesController {
constructor(private service: ColleService) {} constructor(
private service: ColleService,
private notificationService: NotificationService
) {}
async index({ request, response, auth }: HttpContext) { async index({ request, response, auth }: HttpContext) {
const { startDate: rawStartDate } = request.qs() const { startDate: rawStartDate } = request.qs()
@ -137,6 +141,7 @@ export default class CollesController {
// If it exists, update the existing colle // If it exists, update the existing colle
if (existing) { if (existing) {
// Merge the new data with the existing colle // Merge the new data with the existing colle
const beforeColle = existing.serialize()
Object.assign(existing, colleData) Object.assign(existing, colleData)
// Handle attachments if any // Handle attachments if any
@ -161,6 +166,19 @@ export default class CollesController {
} }
} }
const afterColle = existing.serialize()
if (!beforeColle.grade && afterColle.grade) {
await this.notificationService.sendNotification('GRADE_ADDED', existing)
} else if (parseFloat(beforeColle.grade) !== afterColle.grade) {
await this.notificationService.sendNotification(
'GRADE_UPDATED',
existing,
parseFloat(beforeColle.grade)
)
}
if (!deepEqual(beforeColle, afterColle)) {
await this.notificationService.sendNotification('COLLE_UPDATED', existing)
}
return existing.save() return existing.save()
} }
const colle = await Colle.create(colleData) const colle = await Colle.create(colleData)
@ -226,25 +244,49 @@ export default class CollesController {
// Create a new colle if it doesn't exist // Create a new colle if it doesn't exist
if (!oldColle) { if (!oldColle) {
await Colle.create(updatedColle) const colle = await Colle.create(updatedColle)
await this.notificationService.sendNotification('COLLE_ADDED', colle)
continue continue
} }
// Update the colle with the new data // Update the colle with the new data
// and remove it from the list // and remove it from the list
const beforeColle = oldColle.serialize()
Object.assign(oldColle, updatedColle) Object.assign(oldColle, updatedColle)
await oldColle.save() await oldColle.save()
const afterColle = oldColle.serialize()
upcomingCollesIds.delete(oldColle.id) upcomingCollesIds.delete(oldColle.id)
if (beforeColle.room !== afterColle.room) {
await this.notificationService.sendNotification('ROOM_UPDATED', oldColle)
} else if (!deepEqual(beforeColle, afterColle)) {
await this.notificationService.sendNotification('COLLE_UPDATED', oldColle)
}
} }
// Delete the colles that were not updated // Delete the colles that were not updated
const deleted = await Colle.query() const collesToDelete = await Promise.all(
Array.from(upcomingCollesIds).map((id) => {
return Colle.query()
.where('id', id)
.whereHas('student', (query) => { .whereHas('student', (query) => {
query.where('className', payload.className) query.where('className', payload.className)
}) })
.whereIn('id', Array.from(upcomingCollesIds)) .first()
.delete() })
)
for (const colle of collesToDelete) {
if (colle) {
await this.notificationService.sendNotification('COLLE_REMOVED', colle)
await colle.delete()
}
}
console.log(`Deleted ${deleted} upcoming colles that were not updated`) console.log(`Deleted ${collesToDelete.length} upcoming colles that were not updated`)
} }
} }
function deepEqual(a: any, b: any) {
return JSON.stringify(a) === JSON.stringify(b)
}

View file

@ -45,8 +45,12 @@ export class NotificationService {
}) })
} }
public async sendNotification(notificationId: NotificationId, colle: Colle) { public async sendNotification(notificationId: NotificationId, colle: Colle, args?: any) {
const payload = Object.assign(DEFAULT_NOTIFICATION, NOTIFICATIONS[notificationId](colle)) await colle.load('subject')
if (notificationId === 'ROOM_UPDATED') {
await colle.load('room')
}
const payload = Object.assign(DEFAULT_NOTIFICATION, NOTIFICATIONS[notificationId](colle, args))
const subscriptions = await Subscription.query() const subscriptions = await Subscription.query()
.where('enabled', true) .where('enabled', true)
@ -92,7 +96,7 @@ export class NotificationService {
const NOTIFICATIONS = { const NOTIFICATIONS = {
COLLE_ADDED: (colle: Colle) => ({ COLLE_ADDED: (colle: Colle) => ({
title: 'Nouvelle colle', title: 'Nouvelle colle',
body: `Colle de ${colle.subject} ajoutée le ${formatDate(colle.date)}.`, body: `Colle de ${colle.subject.name} ajoutée le ${formatDate(colle.date)}.`,
data: { data: {
id: colle.id, id: colle.id,
}, },
@ -100,12 +104,12 @@ const NOTIFICATIONS = {
}), }),
COLLE_REMOVED: (colle: Colle) => ({ COLLE_REMOVED: (colle: Colle) => ({
title: 'Colle supprimée', title: 'Colle supprimée',
body: `Votre colle de ${colle.subject}, le ${formatDate(colle.date)} a été supprimée.`, body: `Votre colle de ${colle.subject.name}, le ${formatDate(colle.date)} a été supprimée.`,
actions: [HOME_ACTION], actions: [HOME_ACTION],
}), }),
COLLE_UPDATED: (colle: Colle) => ({ COLLE_UPDATED: (colle: Colle) => ({
title: 'Colle modifiée', title: 'Colle modifiée',
body: `Votre colle de ${colle.subject} du ${formatDate(colle.date)} a été modifiée.`, body: `Votre colle de ${colle.subject.name} du ${formatDate(colle.date)} a été modifiée.`,
data: { data: {
id: colle.id, id: colle.id,
}, },
@ -114,15 +118,15 @@ const NOTIFICATIONS = {
GRADE_ADDED: (colle: Colle) => ({ GRADE_ADDED: (colle: Colle) => ({
title: 'Nouvelle note', title: 'Nouvelle note',
body: `Colle de ${colle.subject} : ${colle.grade}/20`, body: `Colle de ${colle.subject.name} : ${colle.grade}/20`,
data: { data: {
id: colle.id, id: colle.id,
}, },
actions: [OPEN_ACION, HOME_ACTION], actions: [OPEN_ACION, HOME_ACTION],
}), }),
GRADE_UPDATED: (colle: Colle) => ({ GRADE_UPDATED: (colle: Colle, oldGrade: number) => ({
title: 'Note modifiée', title: 'Note modifiée',
body: `Colle de ${colle.subject} : ${colle.grade}/20`, body: `Colle de ${colle.subject.name} : ${oldGrade}/20 --> ${colle.grade}/20`,
data: { data: {
id: colle.id, id: colle.id,
}, },
@ -131,7 +135,7 @@ const NOTIFICATIONS = {
ROOM_UPDATED: (colle: Colle) => ({ ROOM_UPDATED: (colle: Colle) => ({
title: 'Salle modifiée', title: 'Salle modifiée',
body: `Colle de ${colle.subject} en ${colle.room}.`, body: `Colle de ${colle.subject.name} en ${colle.room.name}.`,
data: { data: {
id: colle.id, id: colle.id,
}, },