Skip to content

BFF Service

bff-service owns frontend-specific screen aggregation for HocTapAZ. It shapes web/admin dashboard and shell responses from owner-service APIs or health snapshots, but it does not own business data and does not replace API Gateway route compatibility.

Public browser traffic still goes through API Gateway. Native BFF /v1/* routes are for gateway-approved adapters, service tests, and migration rehearsals. The first non-default public rehearsal maps only GET /api/admin/overview to GET /v1/bff/admin/overview; all other broad admin and BFF-facing routes stay on existing gateway/legacy behavior.

admin-web may opt into this single rehearsal with ?adminOverviewGateway=native and an existing ADMIN Gateway session. Its client reads source status only, retains fixture totals, and falls back to those fixtures for missing session, timeout, HTTP, or malformed-envelope failures. This client candidate does not activate deploy/gateway/routes.json or assert full dashboard parity.

Boundary

Owns:

  • Screen-shaped aggregation for admin, teacher, student, parent, and public app shells.
  • Source-service status and traceability for every dashboard section.
  • Frontend route metadata that points back to owner service boundaries.
  • Service-local composition previews that call owner-service APIs without owning their domain data.

Does not own:

  • IAM credentials, sessions, roles, or permission source of truth.
  • Profile, organization, classroom, course, question, exam, import, file, AI, wallet, payment, billing, usage, notification, search, audit, or admin domain writes.
  • Direct reads from service databases.
  • Public /api/* compatibility until API Gateway route evidence exists.

Native Routes

MethodPathPurpose
GET/v1/bff/admin/overviewAdmin dashboard shell over owner-service source status.
GET/v1/bff/admin/operations/summaryAdmin operations summary shell with legacy queue names and source status.
GET/v1/bff/teacher/dashboardTeacher dashboard shell scoped by organization.
GET/v1/bff/teacher/operationsTeacher operations summary shell scoped by organization.
POST/v1/bff/teacher/exam-blueprintsCreate a persistent exam matrix through exam-service.
GET/v1/bff/teacher/exam-blueprintsList visible teacher/system matrices through exam-service.
GET/v1/bff/teacher/exam-blueprints/{blueprintId}Read one visible matrix through exam-service.
PATCH/v1/bff/teacher/exam-blueprints/{blueprintId}Replace matrix rules through exam-service.
DELETE/v1/bff/teacher/exam-blueprints/{blueprintId}Delete an unreferenced matrix through exam-service.
POST/v1/bff/teacher/exam-blueprints/{blueprintId}/generateGenerate an owner-scoped online or offline draft through exam-service.
POST/v1/bff/teacher/exam-print-templatesCreate an actor-owned Word print template through exam-service.
GET/v1/bff/teacher/exam-print-templatesList actor-owned Word print templates from exam-service.
PATCH/v1/bff/teacher/exam-print-templates/{templateId}Replace an actor-owned Word print template configuration through exam-service.
POST/v1/bff/teacher/exams/{examId}/print-exportsCreate an actor-owned durable DOCX export through exam-service.
GET/v1/bff/teacher/exams/{examId}/print-exportsList actor-owned durable DOCX export records from exam-service.
GET/v1/bff/teacher/exams/{examId}/print-exports/{exportId}/contentVerify export ownership through exam-service, then stream its DOCX from document-service.
POST/v1/bff/teacher/weak-topic-alert-dispatches/previewInternal weak-topic alert dispatch preview over analytics intent metadata, profile parent-recipient resolution, and notification weak-topic event fanout.
GET/v1/bff/frontend-shellRole-based navigation/shell metadata for frontend apps.

Admin Owner Sources

GET /v1/bff/admin/overview and GET /v1/bff/admin/operations/summary include optional ownerSources metadata when BFF can call admin-service GET /v1/admin/operations/source-map. This is traceability data for dashboard sections: each item names the owner service, owner API, source type, and current route status for operations such as identity counts, import queues, wallet reviews, support queues, and audit history.

BFF also reads admin-service GET /v1/admin/operations/source-snapshots when configured and returns it as optional ownerSourceSnapshots metadata. Snapshot items report owner endpoint probe status such as ok, degraded, unavailable, or unconfigured; they are not dashboard totals.

The BFF runs source health checks, source-map, and source-snapshot reads in parallel. Each optional owner read preserves its independent degraded result, so a slow source-map response does not add its latency to the snapshot read. Health checks use BFF_UPSTREAM_TIMEOUT_MS (default 750ms); optional admin source-map and source-snapshot reads use the shorter independent BFF_ADMIN_SOURCE_TIMEOUT_MS budget (default 500ms).

The reads are non-authoritative for BFF. If admin-service is unavailable, BFF returns the normal screen shell and marks the affected metadata status as degraded with the upstream error. BFF still must not synthesize domain metrics, read owner databases, or promote default /api/admin/* routes from this service-local metadata alone.

Weak-Topic Alert Dispatch Preview

POST /v1/bff/teacher/weak-topic-alert-dispatches/preview is a bounded service-local route for the weak-topic parent alert handoff. It requires ADMIN or TEACHER plus X-Organization-Id.

The request body supplies one or more analytics weak-topic alert intents with the resolved studentId needed for recipient lookup. BFF then calls profile-service POST /v1/internal/profiles/parent-recipients/resolve with:

json
{
  "studentIds": ["student_1"],
  "organizationId": "org_1",
  "purpose": "WEAK_TOPIC_ALERT"
}

For each intent with parent recipients, BFF posts notification-service POST /v1/events/weak-topic-alert using the analytics replay metadata (sourceService, sourceEventId, topic) and already-resolved parentIds. Intents with no parent recipients are skipped and reported as skipped_no_recipient; notification adapter errors are reported per intent. If profile recipient resolution cannot evaluate the batch, BFF returns a BFF_UPSTREAM error.

This route is not present in gateway route tables and must not be treated as a public /api/* cutover.

Teacher Word Template And DOCX Rehearsal

The three /v1/bff/teacher/exam-print-templates routes and three /v1/bff/teacher/exams/{examId}/print-exports routes are bounded frontend adapters over the owner services. They require gateway-injected X-User-Id, X-User-Role (ADMIN or TEACHER), and X-Organization-Id.

For template create, list, and update, BFF forwards that actor scope only to exam-service. exam-service retains ownership of template validation, versioning, tenant/owner scope, and quota. For export create and list it retains ownership of snapshots, export records, and the immutable template config/version pinned on each export. It writes the DOCX artifact through document-service; BFF never reaches object storage or either owner database.

The BFF forwards template config unchanged. The native renderer currently recognizes includeAnswerSheet and answerSheetMode (after-questions or separate-page) for its generic answer-sheet layout; legacy answer-sheet variants remain an Exam Service renderer parity task.

For download, BFF first lists the exports for the exact actor and exam, finds the requested exportId, and only then streams the record's documentAssetId from document-service. The frontend never supplies a raw document asset id, so it cannot turn this route into a cross-tenant document reader. The response is a private no-store DOCX attachment.

The non-default route tables deploy/gateway/routes.teacher-print-export-bff-native-example.json and deploy/gateway/routes.teacher-print-export-bff-native-localhost-example.json map only the compatible /api/teacher/... paths through Gateway to these BFF routes. deploy/gateway/routes.json remains unchanged. The rehearsal has route coverage and hermetic Gateway auth/scope proof, but public promotion still needs an authenticated browser download and explicit rollback evidence.

Teacher Exam Blueprint Rehearsal

The five /v1/bff/teacher/exam-blueprints routes are a narrow teacher adapter over exam-service. BFF forwards only the authenticated actor and organization scope; it does not own matrices, rules, canonical questions, question selection, or generation jobs. A PATCH forwards the exact changed field set so rules can replace the owner-service matrix atomically.

The non-default route tables deploy/gateway/routes.teacher-exam-blueprint-bff-native-*.json map only the compatible /api/teacher/exam-blueprints* calls to BFF. The default deploy/gateway/routes.json is unchanged. Route, BFF owner-source, and local PostgreSQL evidence are recorded in Teacher Exam Blueprint BFF Route Rehearsal.

POST /v1/bff/teacher/exam-blueprints/{blueprintId}/generate is the sixth adapter in this bounded group. It forwards the authenticated actor scope and delivery mode only. Question Bank selects canonical questions, exam-service owns snapshots and the draft, and BFF owns neither database.

Legacy Evidence

Legacy GET /api/admin/overview composes organization, active-user, classroom, exam, teaching-document, import-job, outbox, queue, and health signals in one admin dashboard payload. Legacy admin operations uses queue names exam-import-algorithm, question-classification, grading, and exports. Legacy GET /api/dashboard/teacher and GET /api/dashboard/teacher/operations are tenant-scoped teacher dashboard routes. The native BFF overview route now includes admin-service owner-source trace and source-snapshot metadata, but it is still not full legacy dashboard parity; additional owner-service read adapters and browser proof are required before default route promotion.

The bounded owner-source and gateway proof is recorded in docs/qa/bff-admin-overview-owner-source-proof.md. The proof uses the named admin-service source-map/source-snapshot APIs and does not promote the default gateway route.

Gateway Rehearsal

Non-default route tables:

  • deploy/gateway/routes.bff-admin-overview-native-example.json
  • deploy/gateway/routes.bff-admin-overview-native-localhost-example.json

These exact tables route only GET /api/admin/overview to /v1/bff/admin/overview, require gateway auth with role ADMIN, and do not require X-Organization-Id. Broad /api/admin, POST /api/admin/overview, GET /api/admin/overview/export, admin operations, teacher dashboard, frontend shell routes, weak-topic alert dispatch preview, and fallback stay legacy-proxied. Rollback is returning GATEWAY_ROUTE_TABLE to deploy/gateway/routes.json or deleting the non-default BFF route entry.

Verification

bash
GOTOOLCHAIN=go1.25.11 go test ./services/bff-service/... -count=1
make test-bff-routes

Go-platform documentation is generated from repository Markdown.