Skip to content

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

RequirementEvidenceResult
Student course route guard proofmake 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 workflowTestStudentCourseRouteGuardEnforcesEnrollmentAndPublishedProjection proves enrollment-gated list/detail, published lesson/material filtering, progress writes, cross-organization denial, and non-student denial.Passed
Browser proofLocal 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 workflowLocal 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 notesdeploy/gateway/routes.json remains active and student course routes are not promoted there.Passed

Ownership Boundary

  • course-service owns 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 STUDENT actor 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-browser

All 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 in deploy/gateway/routes.json.
  • Non-default route examples cover native student list/detail and progress targets only. routes.student-course-workflow-native-*.json combines 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.

Go-platform documentation is generated from repository Markdown.