const router = require('express').Router(); const { authMiddleware, requireRole, requirePermission } = require('../middleware/auth'); const rateLimit = require('../middleware/rateLimit'); const validate = require('../middleware/validate'); const ctrl = require('../controllers/classController'); const assignCtrl = require('../controllers/assignmentController'); const joinLimiter = rateLimit({ windowMs: 60_000, max: 10, message: 'Слишком много попыток, подождите минуту' }); const createLimiter = rateLimit({ windowMs: 60_000, max: 5, message: 'Слишком много запросов, подождите минуту' }); const joinSchema = { body: { invite_code: { type: 'string', required: true, minLen: 1, maxLen: 20 } } }; const createSchema = { body: { name: { type: 'string', required: true, minLen: 1, maxLen: 200 } } }; const updateSchema = { body: { name: { type: 'string', minLen: 1, maxLen: 200 }, description: { type: 'string', maxLen: 1000 }, }}; const assignmentSchema = { body: { title: { type: 'string', required: true, minLen: 1, maxLen: 200 }, subject_slug: { type: 'string', maxLen: 100 }, mode: { type: 'string', oneOf: ['exam', 'practice', 'repeat', 'ct'] }, count: { type: 'number', min: 1, max: 200 }, deadline: { type: 'string', maxLen: 30 }, }}; router.use(authMiddleware); /* ── Student (must be before /:id to avoid route conflicts) ── */ router.post('/join', requireRole('student','free_student'), joinLimiter, validate(joinSchema), ctrl.joinClass); router.get('/student/my', ctrl.myClasses); router.get('/students', requireRole('teacher','admin'), ctrl.listStudents); /* ── Teacher / Admin ── */ router.get('/', requireRole('teacher','admin'), ctrl.listClasses); router.post('/', requireRole('teacher','admin'), requirePermission('classes.manage'), createLimiter, validate(createSchema), ctrl.createClass); router.get('/:id', requireRole('teacher','admin'), ctrl.getClass); router.patch('/:id', requireRole('teacher','admin'), requirePermission('classes.manage'), validate(updateSchema), ctrl.updateClass); router.delete('/:id', requireRole('teacher','admin'), requirePermission('classes.manage'), ctrl.deleteClass); router.post('/:id/new-code', requireRole('teacher','admin'), requirePermission('classes.manage'), ctrl.regenerateCode); router.get('/:id/journal', requireRole('teacher','admin'), ctrl.classJournal); router.get('/:id/journal/csv', requireRole('teacher','admin'), ctrl.classJournalCsv); router.get('/:id/outstanding', requireRole('teacher','admin'), assignCtrl.classOutstanding); router.post('/:id/members', requireRole('teacher','admin'), ctrl.addMember); router.delete('/:id/members/:uid', requireRole('teacher','admin'), ctrl.kickMember); router.post('/:id/assignments', requireRole('teacher','admin'), validate(assignmentSchema), assignCtrl.createAssignment); router.get('/:id/announcements', requireRole('teacher','admin'), ctrl.getAnnouncements); router.post('/:id/announcements', requireRole('teacher','admin'), requirePermission('announcements.send'), ctrl.createAnnouncement); router.delete('/:id/announcements/:aid', requireRole('teacher','admin'), requirePermission('announcements.send'), ctrl.deleteAnnouncement); router.get('/:id/feed', ctrl.classFeed); module.exports = router;