Skip to content

Question Save/Reload Route Proof

Status: accepted-bounded-next-slice-not-complete.

This proof closes the SVC-008-question-save-reload-route-proof slice without approving default question write promotion.

Evidence

RequirementEvidenceResult
Save/reload proofTestServer_UpdateQuestionCreatesReplacementVersionAndPreservesOmittedFields now performs PATCH then GET reload and verifies replacement version, content, options, tags, subject, and folder survive.Passed
Route guard proofmake test-question-read-routes test-question-types-routes test-question-classification-apply-routes test-question-write-routes validates non-default native carve-outs and legacy fallbacks.Passed
Live/browser proofA real in-memory question-bank-service and candidate Gateway created, patched, and reloaded a teacher-scoped question. Chromium then issued GET -> PATCH -> reload GET from its page context and observed questions-detail / questions-update native headers. The real teacher editor also created, reloaded, published, and reloaded a question through the same candidate Gateway. Evidence: output/qa/question-save-reload-route-proof-20260713/gateway-live/, output/playwright/question-save-reload-route-proof-20260713/, and output/playwright/question-editor-gateway-ui-proof-20260713/.Passed, local candidate scope
Rollback evidenceAfter the candidate Gateway stopped, the unmodified default deploy/gateway/routes.json returned 502 with questions / legacy_proxy for both GET and PATCH. Evidence: output/qa/question-save-reload-route-proof-20260713/rollback-default/.Passed

Ownership Boundary

  • question-bank-service owns canonical questions, versions, options, tags, media/formula references, folders, and taxonomy projections.
  • Exam/attempt/course data is not deleted or joined by question-service.
  • Import drafts become canonical questions only through question-service APIs.
  • File bytes remain owned by document/file service; search indexes remain copied projections owned by search-service.

Verification

bash
GOTOOLCHAIN=go1.25.11 go test ./services/question-bank-service/... -count=1
GOTOOLCHAIN=go1.25.11 go test ./services/api-gateway/internal/gateway -run 'TestGatewayQuestion' -count=1
make test-question-read-routes test-question-types-routes test-question-classification-apply-routes test-question-write-routes
QUESTION_WRITE_SELF_TEST=1 make test-question-write-live
QUESTION_WRITE_BROWSER_SELF_TEST=1 make test-question-write-browser

The direct gateway command is a targeted verification when matching test names exist; all question-service and route/self-test commands passed for this slice.

Current Local Recheck

On 2026-07-15, the running local Gateway at http://127.0.0.1:8085 was confirmed to use the default table and therefore intentionally has no questions-list candidate route. The following static and hermetic checks passed without changing that default table:

bash
make test-question-read-routes test-question-types-routes \
  test-question-classification-apply-routes test-question-write-routes
QUESTION_WRITE_SELF_TEST=1 make test-question-write-live
QUESTION_WRITE_BROWSER_SELF_TEST=1 make test-question-write-browser
QUESTION_TYPES_SELF_TEST=1 make test-question-types-live
QUESTION_TYPES_BROWSER_SELF_TEST=1 make test-question-types-browser
QUESTION_READ_BROWSER_SELF_TEST=1 make test-question-read-browser \
  test-question-read-browser-admin
QUESTION_READ_PARITY_SELF_TEST=1 make test-question-read-shadow
QUESTION_READ_NATIVE_SELF_TEST=1 make test-question-read-native
make test-question-read-rollback

This recheck does not claim a live candidate write/browser proof: that still requires an explicitly started non-default route table, a scoped token, a seeded editable question, and its own rollback-after-live artifact.

Live/Browser Gate

The bounded browser evidence includes both a Chromium API-shell proof and a browser-visible teacher-editor proof. The API shell loaded /healthz and issued authenticated requests from page context. The editor proof loaded /teacher/questions/new in the real teacher-web, seeded an expiring teacher Gateway session, then observed POST create -> GET reload -> PATCH publish -> GET reload on the button workflow. Its screenshots and route evidence are in output/playwright/question-editor-gateway-ui-proof-20260713/.

The proof is still local-candidate only. The default-table browser rollback received 502 with questions / legacy_proxy and showed the editor's Gateway error. Default promotion remains blocked until a candidate deployment has production-like owner data, response-parity review, and rollback-after-live evidence.

Route State And Rollback

  • Default /api/questions*, /api/question-folders*, and /api/question-groups* remain legacy-proxied.
  • Non-default native route tables are rehearsal-only.
  • Rollback is GATEWAY_ROUTE_TABLE=deploy/gateway/routes.json; remove native questions-*, folder, and group carve-outs from any rehearsal table.
  • No default route promotion is part of this handoff.

Go-platform documentation is generated from repository Markdown.