# classroomController.js split plan **Source:** `backend/src/controllers/classroomController.js` — 1618 lines, 70 functions **Target:** `backend/src/controllers/classroom/` — 8 files **Strategy:** pure mechanical split, no behaviour changes, facade preserves compatibility --- ## Target structure ``` backend/src/controllers/ classroomController.js ← 8-line re-export facade (unchanged public API) classroom/ _shared.js ← shared helpers used by multiple files sessions.js ← session lifecycle + guest tokens strokes.js ← whiteboard strokes + cursor preview pages.js ← page CRUD + templates + board theme chat.js ← chat messages, reactions, attachments, export permissions.js ← draw permissions, hand-raise, mute, screen, attendance sim.js ← simulation relay (simOpen/State/Mode/Annotate/Close) admin.js ← history, notes, templates, admin views ``` --- ## File mapping ### `classroom/_shared.js` Helpers used by 2+ files. Exports: `{ GUEST_EVENTS, emitToSession, hasAccess, canDraw }` | Symbol | Lines | Used by | |--------|-------|---------| | `GUEST_EVENTS` | 21–27 | sessions, strokes, pages, permissions, sim | | `emitToSession` | 31–34 | sessions, strokes, pages, chat, permissions, sim | | `hasAccess` | 37–48 | sessions, strokes, pages, chat, permissions, admin | | `canDraw` | 13–18 | strokes | Imports: `db`, `broadcastToSession` from `ws-server` --- ### `classroom/sessions.js` Session lifecycle, signal (WebRTC), guest tokens. | Function | Lines | |----------|-------| | `createSession` | 51–105 | | `getSession` | 106–128 | | `endSession` | 129–145 | | `getActiveSession` | 146–163 | | `getMyActive` | 164–177 | | `joinSession` | 178–210 | | `leaveSession` | 211–231 | | `getMySession` | 385–433 | | `signal` | 359–384 | | `generateGuestToken` | 1520–1531 | | `revokeGuestToken` | 1532–1542 | | `getGuestToken` | 1543–end | Imports: `db`, `crypto`, `invalidateSession`, `emitToUser` (from `ws-server`), `_shared` --- ### `classroom/strokes.js` Whiteboard stroke CRUD + live cursor/preview broadcast. | Function | Lines | |----------|-------| | `postStrokes` | 568–608 | | `getStrokes` | 609–635 | | `updateStroke` | 636–662 | | `deleteStroke` | 663–686 | | `clearPage` | 687–700 | | `previewStroke` | 815–840 | | `broadcastCursor` | 901–918 | Imports: `db`, `_shared` --- ### `classroom/pages.js` Page CRUD, templates, board theme. | Function | Lines | |----------|-------| | `getPages` | 701–723 | | `addPage` | 449–472 | | `changePage` | 473–488 | | `updatePageTemplate` | 489–503 | | `updateBoardTheme` | 504–518 | | `renamePage` | 724–740 | | `duplicatePage` | 741–769 | | `deletePage` | 770–799 | Imports: `db`, `_shared` --- ### `classroom/chat.js` Chat messages, reactions, file attachments, export, CHAT_UPLOADS_DIR setup. | Symbol | Lines | |--------|-------| | `CHAT_UPLOADS_DIR` | 9–10 | | `ALLOWED_REACTIONS` | 1027 | | `sendChat` | 232–268 | | `getChat` | 269–320 | | `pinMessage` | 841–864 | | `reactToMessage` | 1028–1074 | | `uploadChatAttachment` | 1019–1026 | | `exportChat` | 1244–1275 | Imports: `db`, `path`, `fs`, `crypto`, `emitToUser` (from `ws-server`), `_shared` --- ### `classroom/permissions.js` Draw permits, hand-raise, mute, screen share, online students. | Function | Lines | |----------|-------| | `getParticipants` | 321–340 | | `getAttendance` | 341–358 | | `getOnlineStudents` | 434–448 | | `raiseHand` | 519–537 | | `lowerHand` | 538–550 | | `getHands` | 551–567 | | `allowDraw` | 865–882 | | `revokeDraw` | 883–900 | | `mutePeer` | 800–814 | | `screenStart` | 919–930 | | `screenStop` | 931–941 | Imports: `db`, `emitToUser`, `invalidateDrawCache` (from `ws-server`), `getOnlineUserIds` (from `sse`), `_shared` --- ### `classroom/sim.js` Simulation relay — teacher broadcasts sim events to students. | Function | Lines | |----------|-------| | `simOpen` | 945–958 | | `simState` | 961–976 | | `simMode` | 979–991 | | `simAnnotate` | 994–1004 | | `simClose` | 1007–1018 | Imports: `db`, `_shared` --- ### `classroom/admin.js` History, notes, board templates, admin dashboards. | Function | Lines | |----------|-------| | `getNotes` | 1075–1082 | | `saveNotes` | 1083–1097 | | `getClassHistory` | 1098–1140 | | `getMyHistory` | 1141–1188 | | `getSessionSummary` | 1189–1243 | | `getAllNotes` | 1276–1294 | | `deleteHistorySession` | 1295–1320 | | `adminGetActiveSessions` | 1321–1341 | | `adminGetAllSessions` | 1342–1422 | | `adminGetTeachersList` | 1423–1434 | | `getTemplates` | 1435–1441 | | `saveTemplate` | 1442–1473 | | `deleteTemplate` | 1474–1479 | | `loadTemplate` | 1480–1519 | Imports: `db`, `_shared` --- ## Facade (`classroomController.js` after split) ```js module.exports = { ...require('./classroom/sessions'), ...require('./classroom/strokes'), ...require('./classroom/pages'), ...require('./classroom/chat'), ...require('./classroom/permissions'), ...require('./classroom/sim'), ...require('./classroom/admin'), }; ``` `routes/classroom.js` imports from `'../controllers/classroomController'` — unchanged. --- ## What does NOT change - All function names — unchanged - All route bindings in `routes/classroom.js` — unchanged - All public exports from `classroomController.js` — same set - DB queries — moved verbatim, not rewritten - Error responses — unchanged ## Risks - `simClose` (line 1007) references `emitToSession` — must be imported from `_shared` - `sendChat` builds URLs with `req.protocol + '://' + req.get('host')` — needs no extra imports - `getSessionSummary` (line 1189) is 54 lines — complex, move carefully