# 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
