feat(teacher-workflow): add multi-class student management, diagnostics, performance dashboard and evaluation reports - #74
Open
sreeja37 wants to merge 9 commits into
Conversation
added 9 commits
July 18, 2026 03:45
…le dev-token authentication bypass
Bug 6 (Student Profile mock fallback) and Bug 7 (class/section
selectors) were already landed on this branch in earlier sessions.
This commit bundles them with the new Edit Personal Details feature.
Backend:
- Add PATCH /api/students/:id (repo + service + controller + route).
- extend IStudent + Student schema with 11 optional personal/contact
fields: dateOfBirth, gender, bloodGroup, disabilityStatus,
guardianName, guardianRelation, contactNumber, residentialAddress,
midDayMeal, busRoute, enrollmentDate.
- updateStudent: editable whitelist (12 fields), validation
(name required, age 3-25, contact 7-15 digits, dob valid date),
school-scope (superadmin bypass), 404 on miss, 400 on empty patch,
role-based Aadhar masking at response edge (superadmin sees raw,
others see XXXX-XXXX-1234).
- Extend IStudentProfile + GET /api/students/:id so the Dashboard
View Profile modal surfaces the same fields the Student Profile
page can edit.
Frontend:
- Student type extended with the 11 new optional fields.
- studentService: UpdateStudentPayload + updateStudent(id, payload).
- useUpdateStudent hook: useMutation + invalidateQueries([students])
on success (same pattern as useCreateStudent). Every consumer of
the [students] cache (Dashboard roster, Registration selector,
Student List, Student Profile) auto-refreshes after a save.
- PanelViews.tsx Personal Information card: full Edit / Save / Cancel
UI with inline validation, success/error toast, Loader2 spinner,
disabled inputs during save, read-only fields preserved as a
separate section (Aadhar, Class, Section, School, School ID).
- Diff-only payload: snapshot personalOriginal at Edit-click; send
only keys whose draft value differs.
- Unsaved-changes guard: trySwitchStudent / trySwitchTab /
trySwitchScope intercept navigation; confirmUnsavedSave /
confirmUnsavedDiscard / cancelUnsavedPrompt handle the 3-way
dialog.
- Migrate Quick Info, Additional Info, Guardian & Contact cards
(and the enrollmentTimestamp calc) off the legacy
profile = {} placeholder; remove the placeholder declaration.
- RoleDashboards.tsx StudentProfileModal: extend ProfileState type
with the 9 new fields; add 9 new dt/dd rows using the existing
renderValue / renderMissingChip pair; add caption noting the
modal reflects the latest PATCH edits.
Verification:
- npx tsc --noEmit (frontend): 0 errors.
- npx tsc --noEmit (backend): only pre-existing errors (db.ts,
paperGenerator.ts, student.service.ts:103/174 - not from this
work).
- npm run build (frontend vite build): success.
- npm run build (backend esbuild): success.
- curl PATCH + GET round-trip: confirms all 9 new fields surface
through GET /api/students/:id, list endpoint reflects changes,
revert to null works, invalid input rejected (400/404).
Bug found in user verification: PATCH /api/students/:id persisted gender fine, but the Dashboard "View Profile" modal still showed "Not Available" because getStudentProfile() was hardcoding "gender: null" (and "enrollmentDate: null") instead of reading from the stored document. The seeded-students comment from before Phase 3 (when neither field was editable) became a real footgun once PATCH made gender editable. Fix: getStudentProfile() now reads student.gender ?? null, the same pattern used for the Phase 3 personal / contact fields just below it. "enrollmentDate" is intentionally NOT yet changed because it is not on the updateStudent whitelist and remains read-only. The inline comment in the service explains how to fix it when that field becomes editable. Verified end-to-end via curl on s_AP_GNT_GNT_01_01_C2_03: GET before: gender "Female" (left over from prior session) PATCH gender=Female: 200, body.gender "Female" GET after Female: "Female" (bug fixed) PATCH gender=Male: 200 GET after Male: "Male" PATCH gender=null: 200, body.gender null GET after null: null (revert works) Backend tsc --noEmit unchanged (same 6 pre-existing errors, none from this fix). The Dashboard modal reads /api/students/:id via direct fetch (not React Query), so the next modal open after a PATCH will now show the freshly-saved gender value.
…tion/student)
Mirror the Student Profile's class+section selector pattern in the
Performance panel, and add a per-student focus dropdown so teachers can
drill from class-level aggregates into a single student's progress
without leaving the page.
Scope:
- New component-level state: perfScopeClassGroup, perfScopeSection,
perfSelectedStudentId. Independent from the Student Profile scope so
changing one doesn't disturb the other.
- Two new useEffects: one to snap perf scope to first available
class+section when the roster arrives, and one to clear
perfSelectedStudentId when the focused student falls out of scope.
- Performance panel rewritten end-to-end:
- Filter row: Class + Section dropdowns (mirrors the existing
profile-block selectors) + a Focus Student dropdown with an
"Aggregate view (whole class)" no-focus option.
- Metric cards react to the filtered scope: Students in Scope, Avg
Level, Certified (L5+), Pending Diagnostic (with active/awaiting
breakdown).
- Per-student detail card when a student is focused: name + ID +
Placed/Pending chip, target/streak, current level big-readout,
progress bar to target level, recent level history (last 8 events,
newest first).
- Level Distribution histogram (L1..L4 + L5+) for the active scope.
- Top Performers list (sorted by currentLevel, filtered to scope),
click-to-focus on each row.
- Zero mock data, zero REPORTS_MOCK references in this panel — every
field is derived from the live useStudents() roster.
Verification:
- npx tsc --noEmit frontend: 0 errors
- npx tsc --noEmit backend: 6 pre-existing errors only (db.ts,
paperGenerator.ts, student.service.ts:103/174)
- npm run build: success in 16.07s (vite + esbuild)
- Live probe: 75 students across 5 classes/sections returned from
GET /api/students; all carry levelHistory[], targetLevel, streak
- Brace balance: 103 opens / 103 closes in the perf block
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR enhances the Teacher Workflow by replacing mock implementations with dynamic backend-driven functionality and improving student management, diagnostics, performance tracking, and evaluation reporting.
Features Implemented
Student Registration
Multi-Class & Multi-Section Support
Student List
Student Profile
Editable Personal Details
Diagnostic Workflow
Performance Dashboard
Evaluation Reports
Backend
Frontend
Verification