3.8 KiB
3.8 KiB
My Class Integration
Purpose
/my-class gives class-scoped staff a roster view for their assigned class and lets higher-scope
users view a classroom roster after drilling into a class from the scope switcher. The page lists
students, linked guardians, and assigned class staff. Users with the required user-management
permissions can add and edit student user accounts directly from the Students section, including
linked guardian accounts for each student.
Slice Files
- Page:
frontend/src/pages/modules/MyClassPage.tsx - Business API re-exports:
frontend/src/business/my-class/api.ts - Business selectors:
frontend/src/business/my-class/selectors.ts - Shared APIs reused from User Admin:
frontend/src/shared/api/users.ts,frontend/src/shared/api/roles.ts - Shared UI reused from User Admin:
ImageUpload,UserAvatar, common inputs/selects/buttons
Behavior
- The page resolves the current class from the selected effective scope first. If the selected scope
is a classroom, that classroom is used; otherwise the signed-in user's own
classIdis used for class-scoped staff. - Higher-scope users must drill into a classroom before
/my-classcan show a roster. Class-scoped users without an assigned class see the unassigned-class message. - The Students section lists class-scoped student users from
GET /api/users?classId=<classId>. Backend listing includes both directusers.classIdmatches and students linked throughclass_enrollments, which is how the seeded class roster is represented. - The add/edit form is collapsible. It is fixed to the current class, the seeded
studentrole id, and the seededguardianrole id. It does not show arbitrary role, tenant, or custom-permission controls. - Form fields mirror the reusable User Admin identity fields: avatar, title, first name, last name, email, and phone number.
- Creating a student calls
POST /api/userswithapp_role=<student role id>and the currentclassId; editing callsPUT /api/users/:idwith the same fixed role and class scope. - When the backend returns
temporaryPasswordbecause the mailer is not configured, the form stays open and shows the generated password once with copy instructions. Teachers must copy the student or guardian password before leaving the form and deliver it manually. - The same form includes a repeatable Guardians section with photo upload. When guardian fields are
entered, the UI creates or updates each
guardianuser through the shared user API, then callsPOST /api/guardian_studentsto link that guardian to the student. The link endpoint is idempotent. - On edit, all existing guardian links for the student are loaded into the Guardians section. The teacher can add additional unsaved guardian rows from the same form.
- The UI enables create/edit controls only when the current user has
CREATE_USERSorUPDATE_USERS, a currentclassId, and thestudent/guardianrole ids have loaded. - Backend user service guards remain authoritative: class-scoped users can only manage student
accounts in their own class and guardian accounts linked to students in their own class. Direct
users.classIdandclass_enrollmentsmembership both count as own-class membership, so seeded enrollment-backed students can be edited from/my-class. The guardian-student link service also verifies that class-scoped links connect aguardianuser to astudentuser in the teacher's own class. Class-scoped user management cannot add custom permissions or permission exclusions.
Tests
frontend/src/business/my-class/selectors.test.tscovers payload normalization and permission / class / role gating.- Backend coverage lives in
backend/src/services/users.test.ts,backend/src/services/guardian_students.test.ts,backend/src/services/shared/role-policy.test.ts, andbackend/src/db/seeders/user-roles.test.ts.