Compare commits

..

2 commits

Author SHA1 Message Date
Nathan Lamy
cc817cf9a7 feat: show past colles 2026-02-25 00:31:50 +01:00
Nathan Lamy
77213340b6 feat: improve user serialization 2026-02-25 00:29:27 +01:00
3 changed files with 77 additions and 54 deletions

View file

@ -1,4 +1,5 @@
import Colle from '#models/colle' import Colle from '#models/colle'
import User from '#models/user'
import { ColleService } from '#services/colle_service' import { ColleService } from '#services/colle_service'
import { NotificationService } from '#services/notification_service' import { NotificationService } from '#services/notification_service'
import { createColleValidator, createUpcomingCollesValidator } from '#validators/colle' import { createColleValidator, createUpcomingCollesValidator } from '#validators/colle'
@ -38,7 +39,7 @@ export default class CollesController {
return response.badRequest({ message: 'Invalid colle ID' }) return response.badRequest({ message: 'Invalid colle ID' })
} }
// Retrieve the colle by ID // Retrieve the colle by ID
const colle = await Colle.query() let colle = await Colle.query()
.where('id', colleId) .where('id', colleId)
.whereHas('student', (query) => { .whereHas('student', (query) => {
query.where('className', auth.user!.className) query.where('className', auth.user!.className)
@ -49,6 +50,28 @@ export default class CollesController {
.preload('room') .preload('room')
.preload('attachments') .preload('attachments')
.first() .first()
let className = auth.user!.className
// If colle not found and user has a past student ID, try with the past student's class
if (!colle && auth.user!.pastStudentId) {
const pastUser = await User.find(auth.user!.pastStudentId)
if (pastUser) {
className = pastUser.className
colle = await Colle.query()
.where('id', colleId)
.whereHas('student', (query) => {
query.where('className', pastUser.className)
})
.preload('student')
.preload('examiner')
.preload('subject')
.preload('room')
.preload('attachments')
.first()
}
}
if (!colle) { if (!colle) {
return response.notFound({ message: 'Colle not found' }) return response.notFound({ message: 'Colle not found' })
} }
@ -59,7 +82,7 @@ export default class CollesController {
.where('id', '!=', colle.id) // Exclude the current colle .where('id', '!=', colle.id) // Exclude the current colle
.where('examinerId', colle.examinerId) .where('examinerId', colle.examinerId)
.whereHas('student', (query) => { .whereHas('student', (query) => {
query.where('className', auth.user!.className) query.where('className', className)
}) })
.preload('student') .preload('student')
@ -81,12 +104,28 @@ export default class CollesController {
} }
// Retrieve the colle by ID // Retrieve the colle by ID
const colle = await Colle.query() let colle = await Colle.query()
.where('id', colleId) .where('id', colleId)
.whereHas('student', (query) => { .whereHas('student', (query) => {
query.where('className', auth.user!.className) query.where('className', auth.user!.className)
}) })
.first() .first()
let className = auth.user!.className
if (!colle && auth.user!.pastStudentId) {
const pastUser = await User.find(auth.user!.pastStudentId)
if (pastUser) {
className = pastUser.className
colle = await Colle.query()
.where('id', colleId)
.whereHas('student', (query) => {
query.where('className', pastUser.className)
})
.first()
}
}
if (!colle) { if (!colle) {
return response.notFound({ message: 'Colle not found' }) return response.notFound({ message: 'Colle not found' })
} }
@ -99,7 +138,7 @@ export default class CollesController {
type: 0, // Refresh colle type: 0, // Refresh colle
colle_id: colle.bjid, colle_id: colle.bjid,
colle_secret: colle.bjsecret, colle_secret: colle.bjsecret,
class_name: auth.user!.className, class_name: className,
}) })
) )
} else { } else {
@ -109,7 +148,7 @@ export default class CollesController {
JSON.stringify({ JSON.stringify({
type: 1, // Search for colles on a specific day type: 1, // Search for colles on a specific day
date: colle.date.toFormat('dd/MM/yyyy'), date: colle.date.toFormat('dd/MM/yyyy'),
class_name: auth.user!.className, class_name: className,
}) })
) )
} }

View file

@ -10,11 +10,16 @@ export default class UserController {
// GET /users/@me // GET /users/@me
async me({ auth }: HttpContext) { async me({ auth }: HttpContext) {
const user = auth.user!
return { return {
success: true, success: true,
data: { data: {
...auth.user?.serialize(), ...user.serialize(),
email: auth.user!.email || '', firstName: user.firstName,
lastName: user.lastName,
email: user.email,
preferences: user.preferences,
pastStudentId: user.pastStudentId,
}, },
} }
} }
@ -52,7 +57,14 @@ export default class UserController {
await user.save() await user.save()
return { return {
success: true, success: true,
data: user, data: {
...user.serialize(),
firstName: user.firstName,
lastName: user.lastName,
email: user.email,
preferences: user.preferences,
pastStudentId: user.pastStudentId,
},
} }
} }
@ -70,7 +82,14 @@ export default class UserController {
return response.notFound({ message: 'User not found' }) return response.notFound({ message: 'User not found' })
} }
return { success: true, data: user } return {
success: true,
data: {
...user.serialize(),
preferences: user.preferences,
pastStudentId: user.pastStudentId,
},
}
} }
// POST /merge-student // POST /merge-student
@ -81,6 +100,13 @@ export default class UserController {
user.pastStudentId = pastStudentId user.pastStudentId = pastStudentId
await user.save() await user.save()
return { success: true, data: user } return {
success: true,
data: {
...user.serialize(),
preferences: user.preferences,
pastStudentId: user.pastStudentId,
},
}
} }
} }

View file

@ -1,55 +1,14 @@
import { DateTime } from 'luxon' import { DateTime } from 'luxon'
import { BaseModel, column, computed } from '@adonisjs/lucid/orm' import { BaseModel, column, computed } from '@adonisjs/lucid/orm'
import { DbRememberMeTokensProvider } from '@adonisjs/auth/session' import { DbRememberMeTokensProvider } from '@adonisjs/auth/session'
import { HttpContext } from '@adonisjs/core/http'
export default class User extends BaseModel { export default class User extends BaseModel {
serializeExtras = true
serialize() {
const ctx = HttpContext.get()
if (!ctx) {
this.serializeExtras = false
const serialized = super.serialize()
delete serialized.pastStudentId
delete serialized.extras
return serialized
}
const requestUrl = ctx.request.url()
const isUsersRoute = requestUrl.startsWith('/users')
const isMeRoute = requestUrl.includes('/users/@me')
this.serializeExtras = isUsersRoute
const serialized = super.serialize()
if (!isUsersRoute) {
delete serialized.pastStudentId
delete serialized.extras
}
if (isMeRoute) {
console.log('Serializing full name for /users/@me route')
serialized.firstName = this.firstName
serialized.lastName = this.lastName
}
if (this.serializeExtras) {
serialized.preferences = this.preferences
} else {
delete serialized.preferences
}
return serialized
}
static rememberMeTokens = DbRememberMeTokensProvider.forModel(User) static rememberMeTokens = DbRememberMeTokensProvider.forModel(User)
@column({ isPrimary: true }) @column({ isPrimary: true })
declare id: number declare id: number
@column() @column({ serializeAs: null })
declare pastStudentId: number | null declare pastStudentId: number | null
@column() @column()
@ -72,9 +31,8 @@ export default class User extends BaseModel {
@column({ serializeAs: null }) @column({ serializeAs: null })
declare extras: Record<string, any> declare extras: Record<string, any>
@computed() @computed({ serializeAs: null })
get preferences(): { name: string; emoji: string; color: string }[] { get preferences(): { name: string; emoji: string; color: string }[] {
if (!this.serializeExtras) return []
return this.extras?.preferences || [] return this.extras?.preferences || []
} }