Add lessons Phase 5: grading scales with nested levels
Custom grading scales with ordered levels (value, label, numeric score, color). Supports one-default-per-store constraint, deep create with nested levels, lookup endpoint for dropdowns, and search/pagination. 12 new tests (76 total lessons tests).
This commit is contained in:
@@ -13,8 +13,10 @@ import {
|
||||
LessonSessionStatusUpdateSchema,
|
||||
LessonSessionNotesSchema,
|
||||
LessonSessionUpdateSchema,
|
||||
GradingScaleCreateSchema,
|
||||
GradingScaleUpdateSchema,
|
||||
} from '@lunarfront/shared/schemas'
|
||||
import { InstructorService, LessonTypeService, ScheduleSlotService, EnrollmentService, LessonSessionService } from '../../services/lesson.service.js'
|
||||
import { InstructorService, LessonTypeService, ScheduleSlotService, EnrollmentService, LessonSessionService, GradingScaleService } from '../../services/lesson.service.js'
|
||||
|
||||
export const lessonRoutes: FastifyPluginAsync = async (app) => {
|
||||
// --- Instructors ---
|
||||
@@ -273,4 +275,51 @@ export const lessonRoutes: FastifyPluginAsync = async (app) => {
|
||||
if (!session) return reply.status(404).send({ error: { message: 'Lesson session not found', statusCode: 404 } })
|
||||
return reply.send(session)
|
||||
})
|
||||
|
||||
// --- Grading Scales ---
|
||||
|
||||
app.post('/grading-scales', { preHandler: [app.authenticate, app.requirePermission('lessons.admin')] }, async (request, reply) => {
|
||||
const parsed = GradingScaleCreateSchema.safeParse(request.body)
|
||||
if (!parsed.success) {
|
||||
return reply.status(400).send({ error: { message: 'Validation failed', details: parsed.error.flatten(), statusCode: 400 } })
|
||||
}
|
||||
const scale = await GradingScaleService.create(app.db, parsed.data, request.user.id)
|
||||
return reply.status(201).send(scale)
|
||||
})
|
||||
|
||||
app.get('/grading-scales', { preHandler: [app.authenticate, app.requirePermission('lessons.view')] }, async (request, reply) => {
|
||||
const params = PaginationSchema.parse(request.query)
|
||||
const result = await GradingScaleService.list(app.db, params)
|
||||
return reply.send(result)
|
||||
})
|
||||
|
||||
app.get('/grading-scales/all', { preHandler: [app.authenticate, app.requirePermission('lessons.view')] }, async (_request, reply) => {
|
||||
const scales = await GradingScaleService.listAll(app.db)
|
||||
return reply.send(scales)
|
||||
})
|
||||
|
||||
app.get('/grading-scales/:id', { preHandler: [app.authenticate, app.requirePermission('lessons.view')] }, async (request, reply) => {
|
||||
const { id } = request.params as { id: string }
|
||||
const scale = await GradingScaleService.getById(app.db, id)
|
||||
if (!scale) return reply.status(404).send({ error: { message: 'Grading scale not found', statusCode: 404 } })
|
||||
return reply.send(scale)
|
||||
})
|
||||
|
||||
app.patch('/grading-scales/:id', { preHandler: [app.authenticate, app.requirePermission('lessons.admin')] }, async (request, reply) => {
|
||||
const { id } = request.params as { id: string }
|
||||
const parsed = GradingScaleUpdateSchema.safeParse(request.body)
|
||||
if (!parsed.success) {
|
||||
return reply.status(400).send({ error: { message: 'Validation failed', details: parsed.error.flatten(), statusCode: 400 } })
|
||||
}
|
||||
const scale = await GradingScaleService.update(app.db, id, parsed.data)
|
||||
if (!scale) return reply.status(404).send({ error: { message: 'Grading scale not found', statusCode: 404 } })
|
||||
return reply.send(scale)
|
||||
})
|
||||
|
||||
app.delete('/grading-scales/:id', { preHandler: [app.authenticate, app.requirePermission('lessons.admin')] }, async (request, reply) => {
|
||||
const { id } = request.params as { id: string }
|
||||
const scale = await GradingScaleService.delete(app.db, id)
|
||||
if (!scale) return reply.status(404).send({ error: { message: 'Grading scale not found', statusCode: 404 } })
|
||||
return reply.send(scale)
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user