Skip to content

Handoff: SVC-008-question-save-reload-route-proof

Scope

  • Dispatch ID: SVC-008
  • Service: question-service (services/question-bank-service)
  • Task pack: docs/agents/service-tasks/question-service.md
  • Next task: SVC-008-question-save-reload-route-proof
  • Goal: prove question read/write/type save-reload behavior with live/browser and rollback evidence before default promotion.
  • Status: accepted bounded slice, not service completion.

Docs Read

  • docs/agents/service-agent-next-slice-queue.json
  • docs/agents/service-agent-next-slice-closeout-ledger.json
  • docs/agents/service-tasks/question-service.md
  • docs/agents/handoff-phase-6-question-editor-projection-smoke.md
  • docs/qa/question-write-route-rehearsals.md
  • docs/qa/question-save-reload-route-proof.md
  • docs/qa/question-write-route-rehearsals.md
  • docs/qa/question-editor-gateway-ui-proof.md
  • scripts/test/question-write-browser-smoke.mjs
  • packages/ui/src/modules/teacher/teacher-question-editor-api.ts
  • packages/ui/src/modules/teacher/panels/question-editor-panel.tsx
  • packages/ui/src/modules/teacher/teacher-workspace.test.tsx
  • docs/api/question-bank-service.md

Legacy Evidence Read

  • /Users/velikho/Desktop/WORKING/HOCTAPAZ/node-platform/apps/api/src/modules/questions/questions.controller.ts
  • /Users/velikho/Desktop/WORKING/HOCTAPAZ/node-platform/apps/api/src/modules/questions/question-permanent-delete.queue.ts
  • /Users/velikho/Desktop/WORKING/HOCTAPAZ/node-platform/apps/api/src/modules/questions/question-permanent-delete.worker.ts
  • /Users/velikho/Desktop/WORKING/HOCTAPAZ/node-platform/apps/api/src/modules/app-data/app-data.questions-write.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/question-bank-service/internal/http/server_test.go
  • docs/qa/question-save-reload-route-proof.md
  • docs/agents/handoffs/SVC-008-question-save-reload-route-proof.md
  • docs/agents/service-agent-next-slice-closeout-ledger.json
  • docs/agents/service-agent-next-slice-closeout-ledger.md
  • docs/agents/service-agent-accepted-handoffs.md
  • docs/agents/service-tasks/question-service.md
  • docs/api/question-bank-service.md
  • docs/index.md
  • docs/.vitepress/config.ts
  • docs/qa/service-agent-goal-completion-audit.md
  • docs/qa/service-agent-readiness-smoke.md

Behavior Implemented

  • Extended the question HTTP update workflow to reload the question after PATCH and verify persisted replacement version, content, options, tags, and omitted-field preservation.
  • Revalidated permanent-delete job/impact ownership boundaries: only question-bank-owned rows are deleted; exam/attempt/course data is not.
  • Revalidated native read/write route examples and legacy fallbacks without changing the default gateway table.
  • Ran an isolated in-memory question-bank-service behind the non-default question-write Gateway table. A teacher-scoped fixture was created, patched, reloaded, updated from Chromium, reloaded again, and deleted.
  • Updated the Chromium runner to use the installed @playwright/test runtime and issue the read/write/reload requests from the browser context. It is an API-shell proof retained alongside the teacher-editor workflow below.
  • Wired the authenticated teacher question editor to Gateway-only POST/PATCH /api/questions writes followed by GET ...?view=editor reloads. Unauthenticated editor sessions preserve the existing local-draft behavior.
  • Bound the teacher editor's write and persistence reload to one 25-second deadline. Successful latency events include writeDurationMs and reloadDurationMs; a timed-out budget records deadlineExceeded=true.

Required Evidence

  • save/reload proof: PATCH /v1/questions/{id} followed by GET /v1/questions/{id} preserves the replacement version and refs.
  • live/browser proof: live save/reload passed through the non-default Gateway at output/qa/question-save-reload-route-proof-20260713/gateway-live/. Chromium then observed questions-detail, questions-update, and a reloaded questions-detail from its page context at output/playwright/question-save-reload-route-proof-20260713/.
  • teacher-editor browser proof: the real teacher-web editor at http://127.0.0.1:5214/teacher/questions/new created a question, reloaded it, published it with PATCH, and reloaded it again through the candidate Gateway. Route/header evidence and screenshots are in output/playwright/question-editor-gateway-ui-proof-20260713/.
  • rollback evidence: after the candidate Gateway stopped, the unmodified default deploy/gateway/routes.json returned 502 with questions/legacy_proxy for both read and update. Headers and bodies are retained under output/qa/question-save-reload-route-proof-20260713/rollback-default/.

Tests And Verification

  • gofmt -w services/question-bank-service/internal/http/server_test.go
  • GOTOOLCHAIN=go1.25.11 go test ./services/question-bank-service/... -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
  • Isolated live Gateway smoke passed with a real teacher JWT and a temporary in-memory question-service fixture.
  • Chromium API-shell save/reload passed against that fixture, followed by a native delete cleanup. The temporary :8089 question-service and :18085 Gateway listeners were stopped and verified absent.
  • pnpm exec vitest run packages/ui/src/modules/teacher/teacher-workspace.test.tsx, pnpm --filter @hoctapaz/ui typecheck, and pnpm frontend:typecheck passed.
  • pnpm vitest run packages/ui/src/modules/teacher/teacher-question-editor-api.test.ts passed. It verifies the POST/PATCH and reload share one abort signal and the deadline rejects before a stalled write can consume a second 25-second wait.
  • The real editor browser proof also verified that default-table rollback returns 502/questions/legacy_proxy and surfaces the Gateway error in the editor instead of reporting a local save.
  • Permanent-delete usecase and HTTP tests passed for scoped rows, impact, and job lifecycle.

Route State

  • Route/default state: question write route promotion requires save/reload, live/browser, and rollback evidence.
  • Default question, folder, group, and fallback routes remain legacy_proxy.
  • Candidate proof used only deploy/gateway/routes.questions-write-native-localhost-example.json; it did not edit or promote deploy/gateway/routes.json.
  • Native question write route tables remain non-default rehearsals.

Data Notes

  • Question-service owns question-bank rows and copied reference projections.
  • It intentionally does not delete exam, attempt, course, file bytes, or search index source data.
  • Permanent-delete job processing is service-local and still requires durable broker/worker parity as a separate risk.

Risks / Blockers

  • The real teacher-editor save/reload proof is local-candidate evidence only. It uses an in-memory Question Bank, a disposable teacher token, and a non-default Gateway route table; it is not a deployed or populated-target proof.
  • Durable broker/worker parity remains separate from this route proof.
  • Default question write promotion remains blocked pending candidate deployment validation, populated-target response parity, and rollback-after-live evidence, despite the completed local browser-visible editor proof.

Rollback Notes

These are the rollback notes for the accepted bounded slice:

  • Set GATEWAY_ROUTE_TABLE=deploy/gateway/routes.json.
  • Disable native question write rehearsal callers.
  • Rerun make test-question-write-routes and confirm broad question routes are legacy-proxied.

Next Step

Run the now Gateway-backed editor against a candidate deployment with production-like question ownership data, then attach rollback-after-live evidence before any default promotion review.

Go-platform documentation is generated from repository Markdown.