import type { FastifyPluginAsync } from 'fastify' import { PaginationSchema, InstructorCreateSchema, InstructorUpdateSchema, LessonTypeCreateSchema, LessonTypeUpdateSchema, ScheduleSlotCreateSchema, ScheduleSlotUpdateSchema, EnrollmentCreateSchema, EnrollmentUpdateSchema, EnrollmentStatusUpdateSchema, LessonSessionStatusUpdateSchema, LessonSessionNotesSchema, LessonSessionUpdateSchema, GradingScaleCreateSchema, GradingScaleUpdateSchema, LessonPlanCreateSchema, LessonPlanUpdateSchema, LessonPlanItemUpdateSchema, GradeCreateSchema, SessionPlanItemsSchema, LessonPlanTemplateCreateSchema, LessonPlanTemplateUpdateSchema, TemplateInstantiateSchema, InstructorBlockedDateCreateSchema, StoreClosureCreateSchema, } from '@lunarfront/shared/schemas' import { InstructorService, LessonTypeService, ScheduleSlotService, EnrollmentService, LessonSessionService, GradingScaleService, LessonPlanService, LessonPlanItemService, LessonPlanTemplateService, GradeHistoryService, SessionPlanItemService, InstructorBlockedDateService, StoreClosureService } from '../../services/lesson.service.js' export const lessonRoutes: FastifyPluginAsync = async (app) => { // --- Instructors --- app.post('/instructors', { preHandler: [app.authenticate, app.requirePermission('lessons.admin')] }, async (request, reply) => { const parsed = InstructorCreateSchema.safeParse(request.body) if (!parsed.success) { return reply.status(400).send({ error: { message: 'Validation failed', details: parsed.error.flatten(), statusCode: 400 } }) } const instructor = await InstructorService.create(app.db, parsed.data) return reply.status(201).send(instructor) }) app.get('/instructors', { preHandler: [app.authenticate, app.requirePermission('lessons.view')] }, async (request, reply) => { const params = PaginationSchema.parse(request.query) const result = await InstructorService.list(app.db, params) return reply.send(result) }) app.get('/instructors/:id', { preHandler: [app.authenticate, app.requirePermission('lessons.view')] }, async (request, reply) => { const { id } = request.params as { id: string } const instructor = await InstructorService.getById(app.db, id) if (!instructor) return reply.status(404).send({ error: { message: 'Instructor not found', statusCode: 404 } }) return reply.send(instructor) }) app.patch('/instructors/:id', { preHandler: [app.authenticate, app.requirePermission('lessons.admin')] }, async (request, reply) => { const { id } = request.params as { id: string } const parsed = InstructorUpdateSchema.safeParse(request.body) if (!parsed.success) { return reply.status(400).send({ error: { message: 'Validation failed', details: parsed.error.flatten(), statusCode: 400 } }) } const instructor = await InstructorService.update(app.db, id, parsed.data) if (!instructor) return reply.status(404).send({ error: { message: 'Instructor not found', statusCode: 404 } }) return reply.send(instructor) }) app.delete('/instructors/:id', { preHandler: [app.authenticate, app.requirePermission('lessons.admin')] }, async (request, reply) => { const { id } = request.params as { id: string } const instructor = await InstructorService.delete(app.db, id) if (!instructor) return reply.status(404).send({ error: { message: 'Instructor not found', statusCode: 404 } }) return reply.send(instructor) }) // --- Lesson Types --- app.post('/lesson-types', { preHandler: [app.authenticate, app.requirePermission('lessons.admin')] }, async (request, reply) => { const parsed = LessonTypeCreateSchema.safeParse(request.body) if (!parsed.success) { return reply.status(400).send({ error: { message: 'Validation failed', details: parsed.error.flatten(), statusCode: 400 } }) } const lessonType = await LessonTypeService.create(app.db, parsed.data) return reply.status(201).send(lessonType) }) app.get('/lesson-types', { preHandler: [app.authenticate, app.requirePermission('lessons.view')] }, async (request, reply) => { const params = PaginationSchema.parse(request.query) const result = await LessonTypeService.list(app.db, params) return reply.send(result) }) app.get('/lesson-types/:id', { preHandler: [app.authenticate, app.requirePermission('lessons.view')] }, async (request, reply) => { const { id } = request.params as { id: string } const lessonType = await LessonTypeService.getById(app.db, id) if (!lessonType) return reply.status(404).send({ error: { message: 'Lesson type not found', statusCode: 404 } }) return reply.send(lessonType) }) app.patch('/lesson-types/:id', { preHandler: [app.authenticate, app.requirePermission('lessons.admin')] }, async (request, reply) => { const { id } = request.params as { id: string } const parsed = LessonTypeUpdateSchema.safeParse(request.body) if (!parsed.success) { return reply.status(400).send({ error: { message: 'Validation failed', details: parsed.error.flatten(), statusCode: 400 } }) } const lessonType = await LessonTypeService.update(app.db, id, parsed.data) if (!lessonType) return reply.status(404).send({ error: { message: 'Lesson type not found', statusCode: 404 } }) return reply.send(lessonType) }) app.delete('/lesson-types/:id', { preHandler: [app.authenticate, app.requirePermission('lessons.admin')] }, async (request, reply) => { const { id } = request.params as { id: string } const lessonType = await LessonTypeService.delete(app.db, id) if (!lessonType) return reply.status(404).send({ error: { message: 'Lesson type not found', statusCode: 404 } }) return reply.send(lessonType) }) // --- Schedule Slots --- app.post('/schedule-slots', { preHandler: [app.authenticate, app.requirePermission('lessons.admin')] }, async (request, reply) => { const parsed = ScheduleSlotCreateSchema.safeParse(request.body) if (!parsed.success) { return reply.status(400).send({ error: { message: 'Validation failed', details: parsed.error.flatten(), statusCode: 400 } }) } const result = await ScheduleSlotService.create(app.db, parsed.data) if ('error' in result) { return reply.status(409).send({ error: { message: result.error, statusCode: 409 } }) } return reply.status(201).send(result) }) app.get('/schedule-slots', { preHandler: [app.authenticate, app.requirePermission('lessons.view')] }, async (request, reply) => { const query = request.query as Record const params = PaginationSchema.parse(query) const filters = { instructorId: query.instructorId, dayOfWeek: query.dayOfWeek !== undefined ? Number(query.dayOfWeek) : undefined, } const result = await ScheduleSlotService.list(app.db, params, filters) return reply.send(result) }) app.get('/schedule-slots/:id', { preHandler: [app.authenticate, app.requirePermission('lessons.view')] }, async (request, reply) => { const { id } = request.params as { id: string } const slot = await ScheduleSlotService.getById(app.db, id) if (!slot) return reply.status(404).send({ error: { message: 'Schedule slot not found', statusCode: 404 } }) return reply.send(slot) }) app.patch('/schedule-slots/:id', { preHandler: [app.authenticate, app.requirePermission('lessons.admin')] }, async (request, reply) => { const { id } = request.params as { id: string } const parsed = ScheduleSlotUpdateSchema.safeParse(request.body) if (!parsed.success) { return reply.status(400).send({ error: { message: 'Validation failed', details: parsed.error.flatten(), statusCode: 400 } }) } const result = await ScheduleSlotService.update(app.db, id, parsed.data) if (!result) return reply.status(404).send({ error: { message: 'Schedule slot not found', statusCode: 404 } }) if ('error' in result) { return reply.status(409).send({ error: { message: result.error, statusCode: 409 } }) } return reply.send(result) }) app.delete('/schedule-slots/:id', { preHandler: [app.authenticate, app.requirePermission('lessons.admin')] }, async (request, reply) => { const { id } = request.params as { id: string } const slot = await ScheduleSlotService.delete(app.db, id) if (!slot) return reply.status(404).send({ error: { message: 'Schedule slot not found', statusCode: 404 } }) return reply.send(slot) }) // --- Enrollments --- app.post('/enrollments', { preHandler: [app.authenticate, app.requirePermission('lessons.edit')] }, async (request, reply) => { const parsed = EnrollmentCreateSchema.safeParse(request.body) if (!parsed.success) { return reply.status(400).send({ error: { message: 'Validation failed', details: parsed.error.flatten(), statusCode: 400 } }) } const result = await EnrollmentService.create(app.db, parsed.data) if ('error' in result) { return reply.status(409).send({ error: { message: result.error, statusCode: 409 } }) } return reply.status(201).send(result) }) app.get('/enrollments', { preHandler: [app.authenticate, app.requirePermission('lessons.view')] }, async (request, reply) => { const query = request.query as Record const params = PaginationSchema.parse(query) const filters = { memberId: query.memberId, accountId: query.accountId, instructorId: query.instructorId, status: query.status?.split(',').filter(Boolean), } const result = await EnrollmentService.list(app.db, params, filters) return reply.send(result) }) app.get('/enrollments/:id', { preHandler: [app.authenticate, app.requirePermission('lessons.view')] }, async (request, reply) => { const { id } = request.params as { id: string } const enrollment = await EnrollmentService.getById(app.db, id) if (!enrollment) return reply.status(404).send({ error: { message: 'Enrollment not found', statusCode: 404 } }) return reply.send(enrollment) }) app.patch('/enrollments/:id', { preHandler: [app.authenticate, app.requirePermission('lessons.edit')] }, async (request, reply) => { const { id } = request.params as { id: string } const parsed = EnrollmentUpdateSchema.safeParse(request.body) if (!parsed.success) { return reply.status(400).send({ error: { message: 'Validation failed', details: parsed.error.flatten(), statusCode: 400 } }) } const enrollment = await EnrollmentService.update(app.db, id, parsed.data) if (!enrollment) return reply.status(404).send({ error: { message: 'Enrollment not found', statusCode: 404 } }) return reply.send(enrollment) }) app.post('/enrollments/:id/status', { preHandler: [app.authenticate, app.requirePermission('lessons.edit')] }, async (request, reply) => { const { id } = request.params as { id: string } const parsed = EnrollmentStatusUpdateSchema.safeParse(request.body) if (!parsed.success) { return reply.status(400).send({ error: { message: 'Validation failed', details: parsed.error.flatten(), statusCode: 400 } }) } const enrollment = await EnrollmentService.updateStatus(app.db, id, parsed.data.status) if (!enrollment) return reply.status(404).send({ error: { message: 'Enrollment not found', statusCode: 404 } }) return reply.send(enrollment) }) app.post('/enrollments/:id/generate-sessions', { preHandler: [app.authenticate, app.requirePermission('lessons.edit')] }, async (request, reply) => { const { id } = request.params as { id: string } const query = request.query as Record const weeks = query.weeks ? Number(query.weeks) : 4 const sessions = await LessonSessionService.generateSessions(app.db, id, weeks) return reply.send({ generated: sessions.length, sessions }) }) // --- Lesson Sessions --- app.get('/lesson-sessions', { preHandler: [app.authenticate, app.requirePermission('lessons.view')] }, async (request, reply) => { const query = request.query as Record const params = PaginationSchema.parse(query) const filters = { enrollmentId: query.enrollmentId, instructorId: query.instructorId, status: query.status?.split(',').filter(Boolean), dateFrom: query.dateFrom, dateTo: query.dateTo, } const result = await LessonSessionService.list(app.db, params, filters) return reply.send(result) }) app.get('/lesson-sessions/:id', { preHandler: [app.authenticate, app.requirePermission('lessons.view')] }, async (request, reply) => { const { id } = request.params as { id: string } const session = await LessonSessionService.getById(app.db, id) if (!session) return reply.status(404).send({ error: { message: 'Lesson session not found', statusCode: 404 } }) return reply.send(session) }) app.patch('/lesson-sessions/:id', { preHandler: [app.authenticate, app.requirePermission('lessons.edit')] }, async (request, reply) => { const { id } = request.params as { id: string } const parsed = LessonSessionUpdateSchema.safeParse(request.body) if (!parsed.success) { return reply.status(400).send({ error: { message: 'Validation failed', details: parsed.error.flatten(), statusCode: 400 } }) } const result = await LessonSessionService.update(app.db, id, parsed.data) if (!result) return reply.status(404).send({ error: { message: 'Lesson session not found', statusCode: 404 } }) if ('error' in result) return reply.status(409).send({ error: { message: result.error, statusCode: 409 } }) return reply.send(result) }) app.post('/lesson-sessions/:id/status', { preHandler: [app.authenticate, app.requirePermission('lessons.edit')] }, async (request, reply) => { const { id } = request.params as { id: string } const parsed = LessonSessionStatusUpdateSchema.safeParse(request.body) if (!parsed.success) { return reply.status(400).send({ error: { message: 'Validation failed', details: parsed.error.flatten(), statusCode: 400 } }) } const session = await LessonSessionService.updateStatus(app.db, id, parsed.data.status) if (!session) return reply.status(404).send({ error: { message: 'Lesson session not found', statusCode: 404 } }) return reply.send(session) }) app.post('/lesson-sessions/:id/notes', { preHandler: [app.authenticate, app.requirePermission('lessons.edit')] }, async (request, reply) => { const { id } = request.params as { id: string } const parsed = LessonSessionNotesSchema.safeParse(request.body) if (!parsed.success) { return reply.status(400).send({ error: { message: 'Validation failed', details: parsed.error.flatten(), statusCode: 400 } }) } const session = await LessonSessionService.updateNotes(app.db, id, parsed.data) 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) }) // --- Lesson Plans --- app.post('/lesson-plans', { preHandler: [app.authenticate, app.requirePermission('lessons.edit')] }, async (request, reply) => { const parsed = LessonPlanCreateSchema.safeParse(request.body) if (!parsed.success) { return reply.status(400).send({ error: { message: 'Validation failed', details: parsed.error.flatten(), statusCode: 400 } }) } const plan = await LessonPlanService.create(app.db, parsed.data, request.user.id) return reply.status(201).send(plan) }) app.get('/lesson-plans', { preHandler: [app.authenticate, app.requirePermission('lessons.view')] }, async (request, reply) => { const query = request.query as Record const params = PaginationSchema.parse(query) const filters = { enrollmentId: query.enrollmentId, memberId: query.memberId, isActive: query.isActive === 'true' ? true : query.isActive === 'false' ? false : undefined, } const result = await LessonPlanService.list(app.db, params, filters) return reply.send(result) }) app.get('/lesson-plans/:id', { preHandler: [app.authenticate, app.requirePermission('lessons.view')] }, async (request, reply) => { const { id } = request.params as { id: string } const plan = await LessonPlanService.getById(app.db, id) if (!plan) return reply.status(404).send({ error: { message: 'Lesson plan not found', statusCode: 404 } }) return reply.send(plan) }) app.patch('/lesson-plans/:id', { preHandler: [app.authenticate, app.requirePermission('lessons.edit')] }, async (request, reply) => { const { id } = request.params as { id: string } const parsed = LessonPlanUpdateSchema.safeParse(request.body) if (!parsed.success) { return reply.status(400).send({ error: { message: 'Validation failed', details: parsed.error.flatten(), statusCode: 400 } }) } const plan = await LessonPlanService.update(app.db, id, parsed.data) if (!plan) return reply.status(404).send({ error: { message: 'Lesson plan not found', statusCode: 404 } }) return reply.send(plan) }) // --- Lesson Plan Items --- app.patch('/lesson-plan-items/:id', { preHandler: [app.authenticate, app.requirePermission('lessons.edit')] }, async (request, reply) => { const { id } = request.params as { id: string } const parsed = LessonPlanItemUpdateSchema.safeParse(request.body) if (!parsed.success) { return reply.status(400).send({ error: { message: 'Validation failed', details: parsed.error.flatten(), statusCode: 400 } }) } const item = await LessonPlanItemService.update(app.db, id, parsed.data) if (!item) return reply.status(404).send({ error: { message: 'Lesson plan item not found', statusCode: 404 } }) return reply.send(item) }) // --- Lesson Plan Templates --- app.post('/lesson-plan-templates', { preHandler: [app.authenticate, app.requirePermission('lessons.admin')] }, async (request, reply) => { const parsed = LessonPlanTemplateCreateSchema.safeParse(request.body) if (!parsed.success) { return reply.status(400).send({ error: { message: 'Validation failed', details: parsed.error.flatten(), statusCode: 400 } }) } const template = await LessonPlanTemplateService.create(app.db, parsed.data, request.user.id) return reply.status(201).send(template) }) app.get('/lesson-plan-templates', { preHandler: [app.authenticate, app.requirePermission('lessons.view')] }, async (request, reply) => { const query = request.query as Record const params = PaginationSchema.parse(query) const filters = { instrument: query.instrument, skillLevel: query.skillLevel, } const result = await LessonPlanTemplateService.list(app.db, params, filters) return reply.send(result) }) app.get('/lesson-plan-templates/:id', { preHandler: [app.authenticate, app.requirePermission('lessons.view')] }, async (request, reply) => { const { id } = request.params as { id: string } const template = await LessonPlanTemplateService.getById(app.db, id) if (!template) return reply.status(404).send({ error: { message: 'Template not found', statusCode: 404 } }) return reply.send(template) }) app.patch('/lesson-plan-templates/:id', { preHandler: [app.authenticate, app.requirePermission('lessons.admin')] }, async (request, reply) => { const { id } = request.params as { id: string } const parsed = LessonPlanTemplateUpdateSchema.safeParse(request.body) if (!parsed.success) { return reply.status(400).send({ error: { message: 'Validation failed', details: parsed.error.flatten(), statusCode: 400 } }) } const template = await LessonPlanTemplateService.update(app.db, id, parsed.data) if (!template) return reply.status(404).send({ error: { message: 'Template not found', statusCode: 404 } }) return reply.send(template) }) app.delete('/lesson-plan-templates/:id', { preHandler: [app.authenticate, app.requirePermission('lessons.admin')] }, async (request, reply) => { const { id } = request.params as { id: string } const template = await LessonPlanTemplateService.delete(app.db, id) if (!template) return reply.status(404).send({ error: { message: 'Template not found', statusCode: 404 } }) return reply.send(template) }) app.post('/lesson-plan-templates/:id/create-plan', { preHandler: [app.authenticate, app.requirePermission('lessons.edit')] }, async (request, reply) => { const { id } = request.params as { id: string } const parsed = TemplateInstantiateSchema.safeParse(request.body) if (!parsed.success) { return reply.status(400).send({ error: { message: 'Validation failed', details: parsed.error.flatten(), statusCode: 400 } }) } const plan = await LessonPlanTemplateService.instantiate(app.db, id, parsed.data, request.user.id) if (!plan) return reply.status(404).send({ error: { message: 'Template not found', statusCode: 404 } }) return reply.status(201).send(plan) }) // --- Grade History --- app.post('/lesson-plan-items/:id/grades', { preHandler: [app.authenticate, app.requirePermission('lessons.edit')] }, async (request, reply) => { const { id } = request.params as { id: string } const parsed = GradeCreateSchema.safeParse(request.body) if (!parsed.success) { return reply.status(400).send({ error: { message: 'Validation failed', details: parsed.error.flatten(), statusCode: 400 } }) } const result = await GradeHistoryService.create(app.db, id, parsed.data, request.user.id) if (!result) return reply.status(404).send({ error: { message: 'Lesson plan item not found', statusCode: 404 } }) return reply.status(201).send(result) }) app.get('/lesson-plan-items/:id/grade-history', { preHandler: [app.authenticate, app.requirePermission('lessons.view')] }, async (request, reply) => { const { id } = request.params as { id: string } const history = await GradeHistoryService.list(app.db, id) return reply.send(history) }) // --- Session Plan Items --- app.post('/lesson-sessions/:id/plan-items', { preHandler: [app.authenticate, app.requirePermission('lessons.edit')] }, async (request, reply) => { const { id } = request.params as { id: string } const parsed = SessionPlanItemsSchema.safeParse(request.body) if (!parsed.success) { return reply.status(400).send({ error: { message: 'Validation failed', details: parsed.error.flatten(), statusCode: 400 } }) } const result = await SessionPlanItemService.linkItems(app.db, id, parsed.data) if (result === null) return reply.status(404).send({ error: { message: 'Lesson session not found', statusCode: 404 } }) return reply.status(201).send({ linked: result.length, items: result }) }) app.get('/lesson-sessions/:id/plan-items', { preHandler: [app.authenticate, app.requirePermission('lessons.view')] }, async (request, reply) => { const { id } = request.params as { id: string } const items = await SessionPlanItemService.listForSession(app.db, id) return reply.send(items) }) // --- Instructor Blocked Dates --- app.post('/instructors/:id/blocked-dates', { preHandler: [app.authenticate, app.requirePermission('lessons.admin')] }, async (request, reply) => { const { id } = request.params as { id: string } const parsed = InstructorBlockedDateCreateSchema.safeParse(request.body) if (!parsed.success) { return reply.status(400).send({ error: { message: 'Validation failed', details: parsed.error.flatten(), statusCode: 400 } }) } const instructor = await InstructorService.getById(app.db, id) if (!instructor) return reply.status(404).send({ error: { message: 'Instructor not found', statusCode: 404 } }) const result = await InstructorBlockedDateService.create(app.db, id, parsed.data) if ('error' in result) return reply.status(409).send({ error: { message: result.error, statusCode: 409 } }) return reply.status(201).send(result) }) app.get('/instructors/:id/blocked-dates', { preHandler: [app.authenticate, app.requirePermission('lessons.view')] }, async (request, reply) => { const { id } = request.params as { id: string } const instructor = await InstructorService.getById(app.db, id) if (!instructor) return reply.status(404).send({ error: { message: 'Instructor not found', statusCode: 404 } }) const dates = await InstructorBlockedDateService.list(app.db, id) return reply.send(dates) }) app.delete('/instructors/:instructorId/blocked-dates/:id', { preHandler: [app.authenticate, app.requirePermission('lessons.admin')] }, async (request, reply) => { const { instructorId, id } = request.params as { instructorId: string; id: string } const row = await InstructorBlockedDateService.delete(app.db, id, instructorId) if (!row) return reply.status(404).send({ error: { message: 'Blocked date not found', statusCode: 404 } }) return reply.send(row) }) // --- Store Closures --- app.post('/store-closures', { preHandler: [app.authenticate, app.requirePermission('lessons.admin')] }, async (request, reply) => { const parsed = StoreClosureCreateSchema.safeParse(request.body) if (!parsed.success) { return reply.status(400).send({ error: { message: 'Validation failed', details: parsed.error.flatten(), statusCode: 400 } }) } const result = await StoreClosureService.create(app.db, parsed.data) if ('error' in result) return reply.status(409).send({ error: { message: result.error, statusCode: 409 } }) return reply.status(201).send(result) }) app.get('/store-closures', { preHandler: [app.authenticate, app.requirePermission('lessons.view')] }, async (_request, reply) => { const closures = await StoreClosureService.list(app.db) return reply.send(closures) }) app.delete('/store-closures/:id', { preHandler: [app.authenticate, app.requirePermission('lessons.admin')] }, async (request, reply) => { const { id } = request.params as { id: string } const row = await StoreClosureService.delete(app.db, id) if (!row) return reply.status(404).send({ error: { message: 'Store closure not found', statusCode: 404 } }) return reply.send(row) }) }