Appearance
bff-service Agent Tasks
Agent workflow: follow README.md for Audit -> Investigate -> Code -> Test -> Fix; keep this pack's writable scope and verification commands authoritative.
Dispatch type: per-service
Dispatch ID: SVC-002
Current implementation: services/bff-service foundation exists.
Owns: frontend-specific aggregation, screen-shaped response composition, source status snapshots, and role-based frontend shell metadata.
Must read:
docs/architecture/service-responsibility-matrix.mddocs/architecture/api-contract-strategy.md- frontend API client docs under
docs/api/
Legacy source evidence:
- frontend screen callers under
/Users/velikho/Desktop/WORKING/HOCTAPAZ/node-platform/apps/web/app/** - legacy admin/dashboard APIs under
/Users/velikho/Desktop/WORKING/HOCTAPAZ/node-platform/apps/api/src/modules/admin/admin-dashboard.controller.ts - teacher/dashboard source routes under
/Users/velikho/Desktop/WORKING/HOCTAPAZ/node-platform/apps/api/src/modules/analytics/analytics.controller.ts - owner-service docs for each screen source.
Writable files:
services/bff-service/**contracts/openapi/services/bff-service.yamldocs/api/bff-service.md
Orchestrator-owned files:
- default gateway route tables, frontend code, shared deploy manifests, and owner-service API contracts unless explicitly delegated.
Delegated gateway verification scope:
- Agents may maintain only the non-default admin overview rehearsal in
deploy/gateway/routes.bff-admin-overview-native-example.jsonanddeploy/gateway/routes.bff-admin-overview-native-localhost-example.json; broad/api/admin, operations, teacher dashboard, frontend shell, and default gateway routes remain orchestrator-owned. - Route proof must cover
GET /api/admin/overviewto/v1/bff/admin/overviewthroughscripts/test/bff-route-coverage.sh, with QA evidence underdocs/qa/bff-admin-overview-*.md. - Makefile target:
test-bff-routes.
Initial tasks:
- Done: create a separate Go
bff-servicefoundation with no primary DB. - Done: define admin/teacher dashboard and operations shells plus role-based frontend shell metadata.
- Done: add guardrails so BFF reports owner-service source status and does not own fallback domain data.
- Done: add a non-default gateway route-table rehearsal for
GET /api/admin/overview->/v1/bff/admin/overview, guarded bymake test-bff-routes. Broad/api/admin, operations, teacher dashboard, and frontend shell routes remain legacy/gateway controlled. - Done:
admin-webhas a bounded opt-in consumer for the exact BFF admin overview rehearsal. Only an existingADMINGateway session with?adminOverviewGateway=nativereadsdata.sources; fixture totals remain authoritative in the UI, and missing session, timeout, HTTP, or envelope failures stay on fixture data with an accessible fallback status. Its proof isdocs/qa/bff-admin-overview-owner-source-proof.md; it is not default route promotion or full dashboard parity. - Done: add an isolated authenticated Admin browser candidate for that opt-in route. It starts disposable owner/BFF services, temporary Gateway and Vite processes, verifies one
ADMINbrowser request reachesbff-admin-overview/native_read, and preserves the fixture dashboard plus source status. The frontend reuses the in-flight source request so React StrictMode cannot double the Gateway/BFF fan-out. It remains non-default and requires rollback review before public promotion. - Done: add a bounded service-local weak-topic alert dispatch preview at
/v1/bff/teacher/weak-topic-alert-dispatches/preview. The route accepts concrete analytics intent metadata withstudentId, requiresADMINorTEACHERplusX-Organization-Id, resolves parent recipients through profile-service, and posts replay-safe weak-topic events to notification-service. It is not a public/api/*route and does not own recipient discovery or notification storage. - Done: add the first owner-service read adapter for admin dashboard traceability. BFF admin overview and operations summary can call admin-service
GET /v1/admin/operations/source-mapand expose optionalownerSourcesmetadata with owner service/API/route status. Upstream source map failures degrade only that metadata and do not make BFF own fallback domain metrics. - Done: BFF now consumes admin-service
GET /v1/admin/operations/source-snapshotsfor admin overview and admin operations summary when admin-service is configured. It exposes the response as optionalownerSourceSnapshotsmetadata and degrades only that metadata on upstream failure; it does not turn source snapshots into domain metrics. - Done: health checks, owner source-map, and owner source-snapshot reads run in parallel for admin screens. The independent degraded metadata contract stays unchanged while screen latency is bounded by the slowest dependency.
- Done: optional admin trace reads have an independent configurable
BFF_ADMIN_SOURCE_TIMEOUT_MSbudget (default500ms), below the750mshealth-check budget, so trace metadata cannot extend the admin screen past the health-check latency cap. - Done:
owner_source_integration_test.goexercises the BFF admin overview through a real HTTP owner endpoint, verifies actor/role/organization header forwarding and source-map/source-snapshot aggregation, and keeps owner failures as degraded metadata. - Done: the Admin Overview fan-out regression holds
/healthz, owner source-map, and owner source-snapshot responses until all three requests have started. It fails if any independent dependency becomes serial, preserving the slowest-dependency latency bound without changing route or ownership behavior. - Done: an opt-in isolated Compose runner exposes only BFF, admin-service, and ai-classifier-service on temporary host ports while allowing their transitive service-owned dependencies to boot with disposable state. It proves BFF calls the named admin-service owner APIs, admin-service probes the real AI provider-status endpoint, and the complete screen response stays within a bounded local latency budget. It is direct owner/BFF runtime evidence only; it does not authenticate through api-gateway or promote
/api/admin/overview. - Done: BFF now has service-local teacher Word template adapters:
POST/GET /v1/bff/teacher/exam-print-templatesandPATCH .../{templateId}, plus durable DOCX export adapters:POST/GET /v1/bff/teacher/exams/{examId}/print-exportsandGET .../{exportId}/content. It forwards actor scope to exam-service for exact owner-scoped template/export checks, then streams only the verified document-service asset. It has no export database and does not accept raw media asset ids from frontend callers. HTTP integration coverage proves owner-header forwarding and template create/list/update plus export create/list/download composition. Gateway rehearsal remains non-default. - Done: BFF forwards
POST /v1/bff/teacher/exam-blueprints/{id}/generateto exam-service with gateway-injected teacher scope. It has no Question Bank or Exam database access; the owner flow is Question Bank selection -> Exam snapshot draft -> BFF response. The matching Gateway route remains a non-default rehearsal until authenticated browser rollback proof is accepted. - Next: replace remaining health-only source snapshots with additional owner-service read adapters only when those owner APIs have parity evidence.
- Next: if BFF is explicitly delegated the student exam-start adapter, call exam-service
POST /v1/exams/{id}/runtime-accessfirst, forward onlydata.startInputto attempt-service, and do not implement exam access policy or read service databases.
Acceptance:
- BFF has no primary business database.
- BFF does not own IAM, profile, wallet, payment, question, exam, or import state.
- Any BFF route can be traced to owner service APIs and has fallback/rollback behavior.
- Admin overview owner source metadata comes from admin-service
/v1/admin/operations/source-map; BFF must expose upstream failure as degraded metadata instead of synthesizing owner data. - Weak-topic dispatch preview must keep parent-recipient lookup in profile-service, notification creation in notification-service, and public route promotion in gateway-owned route proof.
Verification:
- Current:
GOTOOLCHAIN=go1.25.11 go test ./services/bff-service/... make test-bff-routesBFF_ADMIN_OVERVIEW_ISOLATED_CONFIRM=bff-admin-overview-isolated make test-bff-admin-overview-isolatedBFF_ADMIN_OVERVIEW_ISOLATED_CONFIRM=bff-admin-overview-isolated make test-bff-admin-overview-browserBFF_ADMIN_OVERVIEW_ISOLATED_SELF_TEST=1 make test-bff-admin-overview-isolated- OpenAPI mirror parse for
services/bff-service/api/openapi.yamlandcontracts/openapi/services/bff-service.yaml - Focused gateway behavior:
GOTOOLCHAIN=go1.25.11 go test ./services/api-gateway/internal/gateway -run BFF -count=1 docker compose -f deploy/docker-compose.yml config --quietmake test-teacher-print-export-bff-routesandGOTOOLCHAIN=go1.25.11 go test ./services/api-gateway/internal/gateway -run TeacherPrintExportBFF -count=1make test-teacher-exam-blueprint-bff-routesandGOTOOLCHAIN=go1.25.11 go test ./services/api-gateway/internal/gateway -run TeacherExamBlueprintBFF -count=1- Do not request default
/api/*promotion until authenticated browser and rollback evidence complements the non-default route proof.