Appearance
Student Course Route Proof
Status: accepted-bounded-local-live-browser-proof-not-promoted.
This proof closes the SVC-007-student-course-route-proof implementation slice without approving the default student route promotion.
Evidence
| Requirement | Evidence | Result |
|---|---|---|
| Student course route guard proof | make test-student-course-routes, make test-student-course-progress-routes, and TestGatewayStudentCourseNativeRoutesOnlyCaptureReadSurface keep native routes limited to authenticated STUDENT reads/progress examples while broad/default routes stay legacy. | Passed |
| Student projection workflow | TestStudentCourseRouteGuardEnforcesEnrollmentAndPublishedProjection proves enrollment-gated list/detail, published lesson/material filtering, progress writes, cross-organization denial, and non-student denial. | Passed |
| Browser proof | Local rehearsal on 2026-07-13 ran the real student-web at http://127.0.0.1:5213, api-gateway with routes.student-courses-read-native-localhost-example.json at :18085, and course-service at :8086. It used an active-enrollment fixture and a signed STUDENT token. | Passed: browser observed student-courses-list and student-courses-detail, both native_read; artifacts are in output/playwright/student-course-browser-proof-20260713/ |
| Progress and material workflow | Local rehearsal on 2026-07-13 used routes.student-course-workflow-native-localhost-example.json, active enrollment, and the real student course detail UI. | Passed: POST .../lessons/{lessonId}/progress returned student-course-lesson-progress/native_write, refreshed the owner projection to 100%, and POST .../materials/{materialId}/view returned student-course-material-view/native_write; responsive artifacts are in output/playwright/student-course-workflow-proof-20260713/ |
| Default rollback notes | deploy/gateway/routes.json remains active and student course routes are not promoted there. | Passed |
Ownership Boundary
course-serviceowns course, lesson, material metadata, enrollment, and student progress state.- File bytes remain owned by file/document-service; question and exam state remains owned by question-service/exam-service.
- Student routes require
STUDENTactor identity and organization scope; the student must have an active enrollment for detail and progress workflows. - Draft lessons and materials attached to draft lessons are excluded from the student projection.
- Wallet purchase and paid-access decisions remain outside course-service.
Verification
bash
GOTOOLCHAIN=go1.25.11 go test ./services/course-service/... -count=1
GOTOOLCHAIN=go1.25.11 go test ./services/api-gateway/internal/gateway -run 'TestGatewayStudentCourse' -count=1
make test-student-course-routes test-student-course-progress-routes
make test-student-course-workflow-routes
STUDENT_COURSE_BROWSER_SELF_TEST=1 make test-student-course-browserAll listed static, service, gateway, and browser self-test commands passed. The browser runner itself defaults to /student/courses?studentCourseGateway=native and forwards that opt-in query to its detail URL; its self-test rejects a regression that would silently exercise fixture/default data instead of the native candidate. The local live/browser rehearsal additionally passed with STUDENT_COURSE_BROWSER_DETAIL_ID=auto and captured the list/detail response headers and pages. Its preflight response permits X-Organization-Id, which the authenticated student frontend sends for organization-scoped reads.
Live/Browser Gate
The local live/browser proof is complete for the dedicated non-default read and workflow route tables. It uses only an in-memory disposable course-service fixture and does not prove a deployed environment, data migration, or default-route parity.
A complete default-route promotion bundle still needs production-like owner data, rollout verification, browser proof against the candidate deployment, and rollback-after-live evidence.
Route State And Rollback
- Default
/api/student/courses*,/api/courses*, public catalog, and fallback routes remain legacy-proxied indeploy/gateway/routes.json. - Non-default route examples cover native student list/detail and progress targets only.
routes.student-course-workflow-native-*.jsoncombines those exact reads and writes for browser rehearsal without broadening the fallback. - Rollback is switching the gateway back to
GATEWAY_ROUTE_TABLE=deploy/gateway/routes.json, then rerunning the two static route guards. - No default route promotion is part of this handoff.