Appearance
Handoff: SVC-007-student-course-route-proof
Scope
- Dispatch ID:
SVC-007 - Service:
course-service - Task pack:
docs/agents/service-tasks/course-service.md - Next task:
SVC-007-student-course-route-proof - Goal: prove student course route guards with live/browser evidence and rollback notes before default route promotion.
- Status: accepted bounded slice, not service completion.
Docs Read
docs/agents/service-agent-next-slice-queue.jsondocs/agents/service-agent-next-slice-closeout-ledger.jsondocs/agents/service-tasks/course-service.mddocs/agents/handoff-phase-8-course-foundation.mddocs/qa/student-course-route-rehearsals.mddocs/qa/student-course-route-proof.mddocs/api/course-service.md
Legacy Evidence Read
/Users/velikho/Desktop/WORKING/HOCTAPAZ/node-platform/apps/api/src/modules/courses/courses.service.ts/Users/velikho/Desktop/WORKING/HOCTAPAZ/node-platform/apps/api/src/modules/courses/courses.controller.ts/Users/velikho/Desktop/WORKING/HOCTAPAZ/node-platform/apps/api/src/modules/courses/courses.spec.ts/Users/velikho/Desktop/WORKING/HOCTAPAZ/node-platform/apps/api/src/modules/app-data/app-data.courses-catalog.ts/Users/velikho/Desktop/WORKING/HOCTAPAZ/node-platform/apps/api/src/modules/app-data/app-data.courses-support.ts/Users/velikho/Desktop/WORKING/HOCTAPAZ/node-platform/apps/api/prisma/schema.prisma
Legacy source was read-only evidence. No file under /Users/velikho/Desktop/WORKING/HOCTAPAZ/ was changed.
Files Changed
services/course-service/internal/http/student_route_guard_test.godocs/qa/student-course-route-proof.mddocs/agents/handoffs/SVC-007-student-course-route-proof.mddocs/agents/service-agent-next-slice-closeout-ledger.jsondocs/agents/service-agent-next-slice-closeout-ledger.mddocs/agents/service-agent-accepted-handoffs.mddocs/agents/service-tasks/course-service.mddocs/api/course-service.mddocs/index.mddocs/.vitepress/config.tsdocs/qa/service-agent-goal-completion-audit.mddocs/qa/service-agent-readiness-smoke.md
Behavior Implemented
- Added direct HTTP workflow coverage for student course list/detail and progress routes.
- Student detail returns only active-enrollment content with published lessons and materials attached to published lessons.
- Student progress writes require the student actor, matching organization, active enrollment, and published lesson.
- Revoked and expired enrollments are covered at the HTTP boundary: they are omitted from the student list and denied on detail and progress routes.
- Non-student actors and cross-organization actors are denied.
- Existing gateway route examples and guards remain non-default; no public default route was changed.
Required Evidence
- student course route guard proof: static read/progress route guards and the gateway native-route integration tests passed.
- inactive enrollment proof:
TestStudentCourseRouteGuardRejectsInactiveEnrollmentcovers revoked and expired enrollment behavior for list, detail, and progress at the course-service HTTP boundary. - live/browser proof: a local 2026-07-13 rehearsal used an active-enrollment fixture, signed STUDENT session, course-service
:8086, non-default Gateway table:18085, and real student-web:5213. It capturedstudent-courses-list/native_readandstudent-courses-detail/native_readheaders and pages underoutput/playwright/student-course-browser-proof-20260713/. - workflow write proof: the historical local workflow table captured
student-course-lesson-progress/native_writeand an owner detail refresh at 100%, plusstudent-course-material-view/native_writefrom the real student UI. The current opt-in frontend removes that post-write detail refresh; its unit/browser regression verifies the settled detail-read count stays unchanged after the progress write. Historical artifacts are underoutput/playwright/student-course-workflow-proof-20260713/. - default rollback notes: keep
deploy/gateway/routes.jsonactive and switch any rehearsal gateway back to it before promotion review.
Tests And Verification
gofmt -w services/course-service/internal/http/student_route_guard_test.goGOTOOLCHAIN=go1.25.11 go test ./services/course-service/... -count=1GOTOOLCHAIN=go1.25.11 go test ./services/api-gateway/internal/gateway -run 'TestGatewayStudentCourse' -count=1make test-student-course-routes test-student-course-progress-routesSTUDENT_COURSE_BROWSER_SELF_TEST=1 make test-student-course-browser- local live browser smoke with the non-default localhost read table and
STUDENT_COURSE_BROWSER_DETAIL_ID=auto make test-student-course-workflow-routes
All commands passed. The local browser smoke is a non-default owner-service rehearsal, not default-route or deployed-environment promotion evidence.
Route State
- Route/default state: student route promotion blocked until live/browser proof and rollback notes are attached.
- Default
/api/student/courses*,/api/courses*, public catalog, and fallback routes remain legacy-proxied. - Native list/detail/progress route examples remain non-default rehearsal tables.
Data Notes
- Course-service owns course/lesson/material metadata, enrollment, and progress rows only.
- File storage, question source of truth, exam state, wallet purchase, and paid-access entitlement remain outside this slice.
- The student projection excludes unpublished lessons and materials attached to unpublished lessons.
Risks / Blockers
- The local live/browser proof is complete for the dedicated localhost table.
- Default route promotion remains blocked until deployed gateway/frontend and rollback-after-live evidence are attached.
- Question/exam integration, paid access, and broader mastery projections are separate owner slices.
Rollback Notes
These are the default rollback notes for the accepted bounded slice:
- Set
GATEWAY_ROUTE_TABLE=deploy/gateway/routes.json. - Disable native student-course rehearsal callers.
- Rerun
make test-student-course-routes test-student-course-progress-routesand confirm default routes remain legacy-proxied.
Next Step
Obtain production-like owner data, candidate deployment browser proof, and rollback-after-live evidence before considering student route promotion.