Skip to content

Student Exam Room Gateway Candidate

Scope

student-web now has an opt-in native exam-room client for the non-default attempt Gateway rehearsal. It owns browser-side request shaping only; exam runtime access remains exam-service, while attempt snapshots, answers, submission, and result policy remain attempt-service ownership.

The default deploy/gateway/routes.json remains unchanged and legacy-proxied. Normal /student/exams/:examId/take navigation therefore keeps the existing preview. The native candidate is enabled explicitly with:

text
/student/exams/:examId/take?attemptGateway=native

Use that URL only with a Gateway process configured with deploy/gateway/routes.attempt-native-localhost-example.json or the Compose equivalent. It must not be treated as default-route promotion.

Browser Contract

With a stored student access token and organization id, the candidate calls the configured Gateway base URL only:

  1. POST /api/exams/:examId/start with a stable browser-session X-Correlation-Id. This is an allowed CORS header and is accepted by the Gateway start adapter as the replay key.
  2. POST /api/attempts/:attemptId/answers with the attempt-owned questionId, clientVersion, and browser tab id.
  3. POST /api/attempts/:attemptId/submit only after the user chooses to submit.

The client maps the returned attempt-owned question snapshots and saved answer versions into the room. It does not call an owner service directly, inspect a service database, send a caller-supplied start snapshot, or manufacture an initial answer.

Local Verification (2026-07-13)

bash
pnpm --filter @hoctapaz/ui typecheck
pnpm --filter @hoctapaz/ui test -- student-dashboard.test.tsx
make test-attempt-routes

The focused UI test covers an opt-in browser component flow for start, answer save, and submit. It checks the Gateway URL, bearer/org headers, correlation header, and answer version body. It also changes the dashboard query and status filters after the room loads and asserts that the native start request remains single-shot, avoiding a redundant round trip and loading reset. The default route test asserts that the candidate is not called without attemptGateway=native.

Remaining Proof

This is component-level browser evidence with mocked Gateway responses. It is not a deployed student-web browser run against an IAM/classroom-backed Gateway, and it does not prove score, leaderboard, or review-page parity. Before any default route promotion, capture an authenticated student application browser run with the non-default table, then complete the existing live, browser, and rollback gates in docs/qa/attempt-live-smoke.md and docs/qa/attempt-browser-smoke.md.

Rollback

Keep normal routes free of attemptGateway=native, or remove the opt-in client when the rehearsal is no longer needed. The Gateway rollback remains restoring GATEWAY_ROUTE_TABLE=deploy/gateway/routes.json and rerunning make test-attempt-routes.

Go-platform documentation is generated from repository Markdown.