const express = require('express'); const router = express.Router(); const multer = require('multer'); const path = require('path'); const fs = require('fs'); const crypto = require('crypto'); const fc = require('../controllers/flashcardController'); const { authMiddleware, requireRole, requirePermission, requirePermissionForStudents } = require('../middleware/auth'); const { requireOwnership } = require('../middleware/ownership'); /* ── multer для картинок карточек ─────────────────────────────────────── Файлы складываем в backend/uploads/flashcards, отдаём статикой через /uploads/flashcards (см. server.js). Имя — случайный hex, расширение из оригинала (нормализованное). Только изображения, до 5 МБ. */ const _fcUploadsDir = path.join(__dirname, '../../uploads/flashcards'); if (!fs.existsSync(_fcUploadsDir)) fs.mkdirSync(_fcUploadsDir, { recursive: true }); const _fcStorage = multer.diskStorage({ destination: (req, file, cb) => cb(null, _fcUploadsDir), filename: (req, file, cb) => { const ext = path.extname(file.originalname).toLowerCase().replace(/[^.a-z0-9]/g, ''); cb(null, crypto.randomBytes(14).toString('hex') + (ext || '.png')); }, }); const fcUpload = multer({ storage: _fcStorage, limits: { fileSize: 5 * 1024 * 1024 }, fileFilter: (req, file, cb) => cb(null, ['image/jpeg','image/png','image/gif','image/webp'].includes(file.mimetype)), }); router.use(authMiddleware); // Ролевой доступ к разделу флеш-карт: ученик без права flashcards.access закрыт; // учитель/админ проходят всегда (создают и раздают колоды). router.use(requirePermissionForStudents('flashcards.access')); router.post ('/upload', fcUpload.single('file'), fc.uploadImage); router.post ('/quick', fc.quickAdd); router.get ('/random', fc.getRandom); router.get ('/decks', fc.listDecks); router.post ('/decks', fc.createDeck); router.put ('/decks/:id', fc.updateDeck); router.delete('/decks/:id', fc.deleteDeck); router.get ('/decks/:id/cards', fc.getCards); router.post ('/decks/:id/cards', fc.addCard); router.post ('/decks/:id/cards/bulk', fc.addCardsBulk); router.put ('/decks/:id/reorder', requireOwnership({ table: 'flashcard_decks', ownerField: 'user_id' }), fc.reorderCards); // Шаринг колоды (назначение классу/ученику) — только владелец/админ (проверка в хендлере). router.get ('/decks/:id/shares', fc.listShares); router.post ('/decks/:id/share', requireRole('teacher','admin'), requirePermission('flashcards.manage'), fc.addShare); router.delete('/decks/:id/share', requireRole('teacher','admin'), requirePermission('flashcards.manage'), fc.removeShare); router.get ('/decks/:id/study', fc.getStudySession); router.put ('/cards/:id', fc.updateCard); router.delete('/cards/:id', fc.deleteCard); router.post ('/cards/:id/review', fc.submitReview); router.get ('/stats', fc.getStats); module.exports = router;