Appearance
classroom-service Agent Tasks
Agent workflow: follow README.md for Audit -> Investigate -> Code -> Test -> Fix; keep this pack's writable scope and verification commands authoritative.
Dispatch type: per-service
Dispatch ID: SVC-006
Owns: services/classroom-service.
Must read:
docs/agents/handoff-phase-8-classroom-foundation.md- legacy classroom/class member modules:
/Users/velikho/Desktop/WORKING/HOCTAPAZ/node-platform/apps/api/src/modules/classrooms/classroom.service.ts,/Users/velikho/Desktop/WORKING/HOCTAPAZ/node-platform/apps/api/src/modules/classrooms/classrooms.controller.ts,/Users/velikho/Desktop/WORKING/HOCTAPAZ/node-platform/apps/api/src/modules/classrooms/classroom-workspace.spec.ts.
Legacy source evidence:
/Users/velikho/Desktop/WORKING/HOCTAPAZ/node-platform/apps/api/src/modules/classrooms/**- Prisma classroom/member models in
/Users/velikho/Desktop/WORKING/HOCTAPAZ/node-platform/apps/api/prisma/schema.prisma.
Writable files:
services/classroom-service/**contracts/openapi/services/classroom-service.yamldocs/api/classroom-service.md
Orchestrator-owned files:
- profile/IAM/school boundary decisions, shared gateway route tables, and shared deploy manifests unless explicitly delegated.
Delegated gateway verification scope:
- Only when the orchestrator assigns a classroom route/live/browser proof subtask, this service agent may update non-default
deploy/gateway/routes.classroom*.jsonexamples,scripts/test/classroom-*.sh,docs/qa/classroom-*.md, and rootMakefiletest-classroom-*targets. - The default gateway route table, profile/IAM/school ownership decisions, frontend classroom UI, and shared deploy manifests remain orchestrator-owned. Public classroom route promotion still requires route-specific runtime or browser proof and rollback notes.
Initial tasks:
- Complete teacher assignment and student membership workflow coverage.
- Add tests for join code, delete impact, purge, and progress summary boundaries. Current coverage includes join, archive, member removal, hard delete, snapshot delete-impact counters, purge with post-purge 404, and progress placeholder boundaries.
- Done: native membership mutations best-effort publish
classroom.membership.snapshot.v1to analytics-service with replay metadata, post-mutation member refs, and no profile PII. Delivery is disabled unlessANALYTICS_SERVICE_URLorANALYTICS_SERVICE_BASE_URLis configured and publisher failures do not block classroom writes. - Done: native quick classroom notifications are available at internal
POST /v1/classrooms/{classroomId}/notifications. The command requires a caller-suppliedclientRequestId, reads currentSTUDENTmembers from classroom-service owned roster state, and best-effort publishesclassroom.notification.sent.v1to notification-service withsourceEventId=classroom:{classroomId}:notification:{clientRequestId}. WhenPROFILE_SERVICE_URLorPROFILE_SERVICE_BASE_URLis configured, it resolves parent recipients through profile-service/v1/internal/profiles/parent-recipients/resolveand publishesclassroom.notification.parent.sent.v1withsourceEventId=classroom:{classroomId}:notification:{clientRequestId}:parents. - Done: add a read-only admin classroom summary owner API at
GET /v1/admin/classrooms/summary. It reports classroom status/visibility counts and classroom-member role rows for admin dashboard/source-map adapters without hydrating profile data or reading organization, exam, attempt, or IAM stores. - Done: add
SVC-006-public-route-guard-proof. Non-admin list/detail scope is pinned to the actor organization so query/header values cannot widen tenant access. Focused HTTP coverage proves owner-local ids, gateway identity-header compatibility, cross-tenant denial, PARENT denial, and no profile/org display field hydration. - Done: add a named, non-default
GET /api/classroomsandGET /api/classrooms/{classroomId}candidate forADMIN/TEACHERreads. Its disposable runtime proof starts memory-backed Classroom and Gateway processes, verifies tenant query override resistance, cross-tenant detail denial, Gateway role enforcement, owner-local response fields, and a local latency sanity value. The opt-in Admin Vite browser harness additionally verifies canonical nested-session tenant propagation, one Gateway request, credentialed CORS/native route headers, and read-only tenant rendering. The default route table and writes remain unchanged. - Identify lessons/materials/tuition routes that remain legacy-proxied.
Acceptance:
- Classroom stores public IDs for organization/profile/document references only.
- Classroom membership is classroom-local roster state. It may reference IAM, profile, and organization identifiers, but it must not mutate IAM roles, permission-bearing organization membership, profile PII, or organization metadata by side effect.
- No question/exam grading logic enters classroom-service.
- Membership operations preserve last-owner/manager safety rules when applicable.
Verification:
GOTOOLCHAIN=go1.25.11 go test ./services/classroom-service/...make test-classroom-route-guardmake test-classroom-read-routesCLASSROOM_READ_RUNTIME_SMOKE_CONFIRM=disposable-runtime make test-classroom-read-runtimeCLASSROOM_READ_RUNTIME_SMOKE_CONFIRM=disposable-runtime CLASSROOM_READ_RUNTIME_SMOKE_ADMIN_BROWSER=1 make test-classroom-read-runtimeGOTOOLCHAIN=go1.25.11 go test ./services/classroom-service/... ./services/analytics-service/... -count=1when changing analytics producer contracts.- Add a named route/live target before any public classroom purge/progress route promotion; do not rely on manual smoke notes.