Skip to content

Question Write Route Rehearsals

Status: non-default proof gate for question-service editor save/reload write parity.

This page covers the named route, live, and browser checks required before any public /api/questions*, /api/question-folders*, or /api/question-groups* write route can move from legacy to question-bank-service.

It does not approve default route promotion. The default deploy/gateway/routes.json keeps broad question write routes on legacy_proxy until route proof, live/browser evidence, and rollback notes are attached to the cutover handoff.

Route Tables

Use these non-default route tables only for rehearsal:

  • deploy/gateway/routes.questions-write-native-example.json
  • deploy/gateway/routes.questions-write-native-localhost-example.json

The route tables carve out:

  • GET /api/questions and GET /api/questions/:id as native read reload paths through /v1/legacy/questions.
  • POST /api/questions as questions-create.
  • PATCH /api/questions/:id as questions-update.
  • DELETE /api/questions/:id as questions-delete.
  • PATCH /api/questions/bulk-status as questions-bulk-status.
  • GET/POST/PATCH/DELETE /api/question-folders* through question-service folder APIs.
  • GET/POST /api/question-groups* through question-service group APIs.

Unlisted nested question routes and the broad fallbacks remain legacy.

Verification

Static route coverage:

bash
make test-question-write-routes

Hermetic live-smoke self-test:

bash
QUESTION_WRITE_SELF_TEST=1 make test-question-write-live

Live gateway write smoke:

bash
QUESTION_WRITE_LIVE_CONFIRM=write-native \
QUESTION_WRITE_AUTHORIZATION='Bearer <token>' \
QUESTION_WRITE_ORGANIZATION_ID=<org-id> \
GATEWAY_BASE_URL=http://localhost:8085 \
make test-question-write-live

Browser smoke self-test:

bash
QUESTION_WRITE_BROWSER_SELF_TEST=1 make test-question-write-browser

Chromium API-shell proof uses a browser page plus a seeded editable question and teacher/admin token. It can load a same-origin health page when an actual frontend is not part of the proof:

bash
QUESTION_WRITE_BROWSER_AUTHORIZATION='Bearer <token>' \
QUESTION_WRITE_BROWSER_ORGANIZATION_ID=<org-id> \
QUESTION_WRITE_BROWSER_QUESTION_ID=<question-id> \
WEB_BASE_URL=http://localhost:8085 \
GATEWAY_BASE_URL=http://localhost:8085 \
QUESTION_WRITE_BROWSER_PATH=/healthz \
make test-question-write-browser

This API-shell proof must observe both:

  • reload through questions-detail / native_read
  • save through questions-update / native_write; the smoke writes a unique browser-smoke content marker through the browser context, reloads the page, and fails unless the reloaded questions-detail payload still contains that marker.

The API-shell runner does not by itself prove the teacher editor's visible save button. The current editor now calls the Gateway when a valid teacher Gateway session exists. The local candidate proof at output/playwright/question-editor-gateway-ui-proof-20260713/ exercised its create/reload/publish/reload workflow. The default route table still rejects the write through legacy_proxy, so promotion evidence remains open until a candidate deployment has populated-target parity and rollback-after-live proof.

The editor's write and reload share one 25-second client deadline. A successful latency event records writeDurationMs and reloadDurationMs; an exhausted budget records deadlineExceeded=true instead of allowing the two phases to wait for separate 25-second timeouts.

Rollback

Rollback is setting GATEWAY_ROUTE_TABLE=deploy/gateway/routes.json or deleting the questions-*, question-folders-*, and question-groups-* native carve outs from the non-default route table. The broad questions, question-folders, question-groups, and fallback routes stay legacy_proxy in the rehearsal examples.

Go-platform documentation is generated from repository Markdown.