feat: Teacher Classroom Management — create, enroll students, track attendance, and visualize seating in 3D#266
Conversation
- app.css : reorganisation, suppression doublons, design system complet - UserMessage : bulle dégradé bleu/cyan avec shimmer hover - ResponseMessage : bulle AI avec accent bar et animations - Chat : glassmorphism navbar, input floating, loading motivant - MessageInput : amélioration zone de saisie - Sidebar, RightBar, ConfirmDialog : améliorations visuelles
…ments, 3D seating chart) Builds out the full teacher classroom workflow end to end: - Classroom CRUD with student enrollment via manual add, CSV import, a persistent join code, and ad-hoc invite codes - Live attendance: sessions default students to absent, students self check in via /join, teachers can end a session to stop check-ins - Classroom announcements (stream) so teachers can post updates that enrolled students see on their dashboard - A Three.js 3D seating chart; clicking a student's avatar opens their info with live presence/absence percentages - Shared teacher dashboard shell (sidebar + navbar) reused from the student UI, plus a student-facing "My Classrooms" + join flow
…shots to docs - Add rate limiting (slowapi) on login, signup, invite redeem, and session join - Add pagination (limit/offset) to classroom and student list endpoints - Add security headers middleware (CSP, X-Frame-Options, nosniff, Referrer-Policy) - Reject CSV imports larger than 5 MB or exceeding 2 000 rows - Replace hardcoded JWT dev secret with a random token (secrets.token_hex) - Guard against CORS wildcard + allow_credentials combination in production - Add max_length/ge field bounds to all free-text and numeric schema fields - Increase invite code entropy from 48 bits (hex[:12]) to 64 bits (hex[:16]) - Disable sourcemaps in production Vite build - Update teacher classroom management user guide with annotated screenshots
…nouncements, 3D seating chart, security fixes, and docs
|
Hi @hasnaa88 Missing steps in the user guide (features exist in the code/API but aren't shown):
Language: a few French words appear in the user guide ("Présences tab", "Démarrer une séance") and the entire .Rhistory appears to be an unrelated local file (R language) - please Reminder: could you add a "Why" section and a changelog entry to the PR Please address the missing guide sections and the language fix before approval. |
|
Can we use the existing 3D classroom for the students organization ? |
|
Hi Mr. @TarekAi The current component already renders students on desks in 3D and detects clicks on avatars. What's missing is the ability to drag a student from one seat to another and save that arrangement. It's doable as a next step on top of what's already there. |
|
Salam @hasnaa88 |
|
Salam @hasnaa88 1. The new Alembic migrations aren't actually run anywhere This PR adds 4 real migration files (create classrooms table, add 2. Self-check-in is rate-limited by IP, which will misfire for a whole classroom The limiter's key is Also noticed (not blocking): ownership checks use built-in Heads-up, not this PR's fault: #274 will conflict hard with this one if both land — both add teacher classroom-management backend code, and both independently created |
There was a problem hiding this comment.
Pull request overview
This PR introduces an end-to-end “Teacher Classroom Management” feature spanning UI (SvelteKit), API (FastAPI), database models/migrations (SQLAlchemy/Alembic), and tests (Vitest/Cypress/Pytest), enabling teachers to manage classrooms, enroll students, run attendance sessions, and post announcements.
Changes:
- Adds classroom CRUD UI (wizard + dashboard), student enrollment flows (invite codes, CSV import), and attendance + announcements UIs.
- Implements corresponding API routes/services/repositories, new domain models, and Alembic migrations.
- Adds rate limiting + security headers middleware, and expands unit/integration/e2e test coverage.
Reviewed changes
Copilot reviewed 113 out of 160 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| ui/vitest.config.js | Adjusts Vitest config to define Vite globals and force browser resolution conditions. |
| ui/vite.config.ts | Updates Vite build sourcemap behavior (intended prod change). |
| ui/src/tests/teacherShell.test.ts | Adds unit tests for teacher shell navbar/redirect behavior. |
| ui/src/tests/studentInfoModal.test.ts | Adds tests for student info modal + history loading/error cases. |
| ui/src/tests/studentClassrooms.test.ts | Adds tests for student classrooms page behaviors (live session/join/invite). |
| ui/src/tests/studentAvatar.test.ts | Adds tests for avatar photo/initials fallback logic. |
| ui/src/tests/editClassroom.test.ts | Adds tests for edit-classroom page prefill/save/error handling. |
| ui/src/tests/createClassroom.test.ts | Adds tests for create-classroom wizard navigation/validation/submit. |
| ui/src/tests/classroomSeatingChart.test.ts | Adds tests for seating chart empty/WebGL-unavailable/layout controls. |
| ui/src/tests/classroomsApi.test.ts | Adds MSW-based tests for classrooms + sessions API clients. |
| ui/src/tests/classrooms.test.ts | Adds tests for “My Classrooms” dashboard UI and filtering/navigation. |
| ui/src/tests/announcementsFeed.test.ts | Adds tests for announcements list/post/delete/error states. |
| ui/src/routes/teacher/+layout.svelte | Introduces teacher route layout shell wrapper. |
| ui/src/routes/classrooms/new/+page.svelte | Adds 6-step classroom creation wizard page. |
| ui/src/routes/classrooms/+page.svelte | Adds “My Classrooms” list page with search + empty/loading states. |
| ui/src/routes/classrooms/+layout.svelte | Wraps classrooms routes with teacher shell layout. |
| ui/src/lib/types/classroom.ts | Adds TS types for classrooms, enrollment, sessions, attendance, announcements. |
| ui/src/lib/components/wizard/StepSubject.svelte | Wizard step: name/description/subject inputs. |
| ui/src/lib/components/wizard/StepReview.svelte | Wizard step: review table + submit + inline errors. |
| ui/src/lib/components/wizard/StepObjectives.svelte | Wizard step: objectives input. |
| ui/src/lib/components/wizard/StepLevel.svelte | Wizard step: level selection. |
| ui/src/lib/components/wizard/StepDetails.svelte | Wizard step: duration/language inputs. |
| ui/src/lib/components/wizard/StepCourse.svelte | Wizard step: course name input. |
| ui/src/lib/components/teacher/TeacherShell.svelte | Adds shared teacher chrome + auth guard around teacher/classrooms routes. |
| ui/src/lib/components/StudentInfoModal.svelte | Adds modal showing student details and attendance history panel. |
| ui/src/lib/components/StudentAvatar.svelte | Adds avatar component with deterministic color + photo fallback. |
| ui/src/lib/components/student/pages/Dashboard.svelte | Replaces placeholder join-course logic with real invite redemption. |
| ui/src/lib/components/student/elements/Sidebar.svelte | Adds forced role + href support; maps /classrooms/* to nav highlighting. |
| ui/src/lib/components/student/elements/RightBar.svelte | Refactors progress card UI structure. |
| ui/src/lib/components/StartSessionModal.svelte | Adds start-session modal with success state and error handling. |
| ui/src/lib/components/icons/StopCircle.svelte | Adds stop-circle icon for ending sessions. |
| ui/src/lib/components/DeleteClassroomModal.svelte | Adds delete confirmation modal with consequences list. |
| ui/src/lib/components/CreateStudentModal.svelte | Adds UI to create a student account and enroll into classroom. |
| ui/src/lib/components/ClassroomCard.svelte | Adds classroom card UI with options menu + delete integration. |
| ui/src/lib/components/chat/Messages/UserMessage.svelte | Updates user message styling. |
| ui/src/lib/components/chat/Messages/ResponseMessage.svelte | Tweaks SVG stroke color in response message UI. |
| ui/src/lib/components/chat/MessageInput.svelte | Minor whitespace change. |
| ui/src/lib/components/attendance/StudentHistoryPanel.svelte | Adds student attendance history visualization panel. |
| ui/src/lib/components/attendance/SessionList.svelte | Adds session list UI with end/delete controls. |
| ui/src/lib/components/attendance/SessionDetail.svelte | Adds session detail table of presences + student selection. |
| ui/src/lib/components/attendance/PresenceStatusBadge.svelte | Adds status badge component for presence state. |
| ui/src/lib/components/attendance/AttendanceKPICards.svelte | Adds attendance KPI cards component. |
| ui/src/lib/components/attendance/AttendanceDonut.svelte | Adds donut chart component for attendance breakdown. |
| ui/src/lib/components/AnnouncementsFeed.svelte | Adds announcement stream UI (list/post/delete, permission-gated). |
| ui/src/lib/apis/sessions/index.ts | Adds sessions/attendance API client. |
| ui/src/lib/apis/errors.ts | Adds shared API error types (Forbidden/NotFound). |
| ui/src/lib/apis/classrooms/index.ts | Adds classrooms API client incl. students/import/invites/enrolled list. |
| ui/src/lib/apis/announcements/index.ts | Adds announcements API client. |
| ui/src/app.css | Minor whitespace change. |
| ui/package.json | Adds MSW + Vitest coverage dependency ordering updates. |
| ui/cypress/e2e/classrooms.cy.ts | Adds Cypress e2e coverage for classroom workflows + access control. |
| tests/test_classrooms_import_invites.py | Adds integration tests for CSV import, invites, join code persistence, rate limiting. |
| tests/test_auth.py | Adds integration test for signin rate limiting. |
| tests/test_announcements.py | Adds unit + integration coverage for announcements service and endpoints. |
| tests/fixtures/sample_students.csv | Adds sample CSV fixture for student import scenarios. |
| tests/conftest.py | Adds autouse fixture to reset rate limiter between tests. |
| requirements.txt | Adds slowapi + pytest-mock dependency. |
| requirements-ci.txt | Adds slowapi + pytest-mock to CI dependencies. |
| pytest.ini | Introduces unit/integration markers. |
| pyproject.toml | Adds pytest-mock to project dependencies list. |
| Makefile | Adds feature-specific test targets for classrooms UI/API and e2e runs. |
| learning/sessions/schemas.py | Adds Pydantic schemas for sessions/presences/stats/history. |
| learning/classrooms/schemas.py | Adds classroom/enrollment/invite Pydantic schemas and validation bounds. |
| learning/classrooms/repository.py | Adds classroom repository operations incl. invites and enrollment queries. |
| learning/attendance/repository.py | Adds attendance repository for sessions/presences operations. |
| learning/attendance/init.py | Declares attendance domain boundary. |
| learning/announcements/service.py | Adds announcements service with access checks and CRUD logic. |
| learning/announcements/schemas.py | Adds Pydantic schemas for announcements. |
| learning/announcements/repository.py | Adds announcements repository CRUD. |
| learning/announcements/init.py | Declares announcements domain boundary. |
| gateway/http/routers/sessions.py | Adds attendance/session routes incl. join rate limiting. |
| gateway/http/routers/auth.py | Adds rate limiting to auth endpoints + role allowlist for self-signup. |
| gateway/http/routers/announcements.py | Adds announcements routes for classroom stream. |
| gateway/http/rate_limit.py | Introduces shared SlowAPI limiter module. |
| gateway/http/app.py | Registers new routers, adds security headers middleware, adds rate limit handler. |
| docs/teacher_space/teacher-classroom-management-user-guide.md | Adds user guide documentation for the feature. |
| docs/teacher_space/sequence-diagram.md | Adds mermaid sequence diagrams for core flows. |
| docs/teacher_space/class-diagram.md | Adds mermaid class diagram for new domain entities. |
| data/models/user.py | Adds relationships for classrooms/enrollments/presences. |
| data/models/session.py | Adds ClassSession SQLAlchemy model. |
| data/models/presence.py | Adds Presence SQLAlchemy model + PresenceStatus enum. |
| data/models/invite.py | Adds Invite SQLAlchemy model. |
| data/models/enrollment.py | Adds Enrollment SQLAlchemy model. |
| data/models/classroom.py | Adds Classroom SQLAlchemy model + relationships. |
| data/models/announcement.py | Adds Announcement SQLAlchemy model. |
| data/models/init.py | Exports new models/enums. |
| config/settings.py | Replaces dev JWT secret behavior and adds CORS+credentials safety guard. |
| alembic/versions/d020e02dee83_add_ended_at_to_class_sessions.py | Adds ended_at column migration for class_sessions. |
| alembic/versions/96394a73af7d_add_objectives_to_class_sessions.py | Adds objectives column migration for class_sessions. |
| alembic/versions/3aabdff2eab4_teacher_classroom_management.py | Adds initial migrations for classrooms/enrollments/sessions/presences tables. |
| alembic/versions/25d47d6be6ea_add_invite_is_primary_and_announcements.py | Adds invite primary flag + announcements table migration. |
| alembic/script.py.mako | Adds Alembic revision template. |
| alembic/README | Adds Alembic readme stub. |
| alembic/env.py | Adds Alembic env configuration wiring Base metadata. |
| alembic.ini | Adds Alembic configuration. |
| accounts/users/service.py | Adjusts create_user role handling for optional role input. |
| .gitignore | Adds .Rhistory ignore. |
Files not reviewed (1)
- ui/package-lock.json: Generated file
| fill="none" | ||
| stroke={arc.color} | ||
| stroke-width={STROKE} | ||
| stroke-dasharray="{arc.length} {CIRCUMFERENCE - arc.length}" |
| const isDarkMode = derived(theme, ($theme) => { | ||
| return ( | ||
| $theme === 'dark' || | ||
| ($theme === 'system' && window.matchMedia('(prefers-color-scheme: dark)').matches) | ||
| ); | ||
| }); | ||
|
|
||
| let currentIsDarkMode = false; | ||
| isDarkMode.subscribe((value) => { | ||
| currentIsDarkMode = value; | ||
| document.documentElement.classList.toggle('dark', value); | ||
| }); |
| if (pathname.startsWith('/classrooms')) { | ||
| pageFromUrl = 'classrooms'; | ||
| } else { | ||
| const pathSegments = pathname.split('/'); | ||
| if (pathSegments.length >= 3) { | ||
| pageFromUrl = pathSegments[2]; // student/dashboard -> "dashboard" |
| <span class="progress-badge"> | ||
| {courseCompletion < 50 ? "In Progress" : "Almost Done"} | ||
| </span> | ||
| </div> |
| <p class="text-center text-sm text-gray-500 dark:text-gray-400 mt-3"> | ||
| {courseCompletion < 50 | ||
| ? "Keep going 💪" | ||
| : "You're doing great 🚀"} | ||
| </p> |
| build: { | ||
| sourcemap: true | ||
| sourcemap: process.env.NODE_ENV !== 'production' | ||
| }, |
Why
Open TutorAI CE lacked any classroom management workflow for teachers.
This PR introduces the full end-to-end feature so that teachers can
organize students into classrooms, track attendance in real time, and
communicate through announcements — without relying on external tools.
Changelog
Added
limit/offset).csvextension check)Changed
secrets.token_hex(32)(no more static string)Summary
This PR delivers the full teacher classroom management workflow end to end:
teachers can create and manage classrooms, enroll students, run live attendance
sessions, post announcements, and visualize the class in a 3D seating chart.
Students can join classrooms with a code, self check-in during live sessions,
and read class announcements.
Teacher Dashboard & Classrooms
Teacher Dashboard

My Classrooms

Create a Classroom
A 6-step wizard guides the teacher through name, subject, course, objectives,
level, and a final review before creation.
Create Classroom — Step 1

Create Classroom — Review

Edit & Delete a Classroom
Edit Classroom

Delete Classroom

Student Enrollment
Students can be added by email, imported via CSV, or enrolled with a join code.
Students Tab — empty

Students Tab — list view

3D Seating Chart
Three switchable layouts: rows, U-shape, and islands (groups of 4).
Hover to see a student's name; click to open their info card.
3D Chart — Islands

3D Chart — Rows

3D Chart — U-shape

Live Attendance Sessions
When the teacher starts a session, all enrolled students are marked Absent by
default. Students join from their portal and are automatically marked Present.
Attendance Tab — empty

Start Session modal

Session started confirmation

Attendance list + Student History

Student Portal
Students see a Live badge on open sessions and can join with one click.
Student My Classrooms

Student — You are present ✓

Test plan
pytest -q→ 272 passed, 0 failed