Skip to content

Service Workflow Test Matrix

Status: orchestrator-owned dispatch aid for service agents.

Use this with docs/architecture/service-responsibility-matrix.md, docs/agents/agent-task-matrix.md, and the assigned service task pack. It does not replace any task pack; it gives each agent a quick workflow and test target before they audit, code, test, and fix one vertical slice.

Dispatch Invariants

  • Work stays inside go-platform/; legacy paths are read-only evidence.
  • Frontend callers go through api-gateway or an approved BFF.
  • One agent owns one implementation directory per active slice.
  • Alias services use the current implementation directory from the matrix; do not create duplicate directories such as services/question-service.
  • Default gateway promotion needs browser/runtime proof and rollback evidence.
  • Shared files such as root Makefile, Compose, Helm, VitePress navigation, and default route tables are orchestrator-owned unless explicitly delegated.

Core Service Workflows

Dispatch IDServiceCurrent implementationNext workflow sliceFocused verification
SVC-001api-gatewayservices/api-gatewayProtected route rehearsal with IAM RS256/JWKS, HS256 fallback, role/org guards, rollback route table, and route-specific adapters such as exam_start_adapter.GOTOOLCHAIN=go1.25.11 go test ./services/api-gateway/... plus named route targets for touched surfaces such as make test-auth-routes test-auth-routes-live test-auth-routes-browser test-auth-routes-session-browser test-profile-routes test-organization-routes test-attempt-routes test-bff-routes test-teacher-ai-preview-routes; exam_start_adapter slices also require the opt-in make test-attempt-live and make test-attempt-browser proof hooks before any public promotion. DOCX_PHYSICS_GATEWAY_ATTEMPT_LOCAL_POSTGRES_CONFIRM=local-postgres make test-docx-physics-attempt-local-postgres is the isolated end-to-end candidate that verifies its dynamic served route table, real IAM/Exam/Attempt owner path, and Student Web browser start -> answer-save -> submit -> result-read journey, without default promotion.
SVC-002bff-serviceservices/bff-serviceScreen aggregation and bounded owner-service composition previews without primary business DB or hidden writes.GOTOOLCHAIN=go1.25.11 go test ./services/bff-service/..., make test-bff-routes, and BFF_ADMIN_OVERVIEW_ISOLATED_CONFIRM=bff-admin-overview-isolated make test-bff-admin-overview-isolated for the direct owner/BFF runtime. BFF_ADMIN_OVERVIEW_ISOLATED_CONFIRM=bff-admin-overview-isolated make test-bff-admin-overview-browser additionally runs Admin Vite -> temporary authenticated Gateway -> BFF -> admin-service/AI with one browser request, native route headers, rendered source state, and a local latency ceiling. Both are disposable/non-default and do not promote broad /api/admin.
SVC-003iam-serviceservices/iam-serviceCredentials, sessions, JWKS, management guards, access scopes, invites, and IAM-owned organization membership.GOTOOLCHAIN=go1.25.11 go test ./services/iam-service/..., make test-auth-routes, AUTH_ROUTE_LIVE_SELF_TEST=1 make test-auth-routes-live, AUTH_ROUTE_BROWSER_SELF_TEST=1 make test-auth-routes-browser, AUTH_SESSION_BROWSER_SELF_TEST=1 make test-auth-routes-session-browser, make test-organization-routes, and ORGANIZATION_MEMBERSHIP_WRITE_SELF_TEST=1 make test-organization-membership-write-live when membership routes change.
SVC-004profile-serviceservices/profile-serviceEducation profile, contacts, parent-child read models, parent-recipient resolution, safe teacher KYC self-service/admin review, redacted audit projection, and current-user profile route proof through api-gateway.GOTOOLCHAIN=go1.25.11 go test ./services/profile-service/..., make test-profile-routes test-profile-kyc-routes test-profile-admin-kyc-routes, PROFILE_ROUTE_LIVE_SELF_TEST=1 make test-profile-routes-live, and PROFILE_ROUTE_BROWSER_SELF_TEST=1 make test-profile-routes-browser; live/browser profile promotion still requires orchestrator approval and default-route rollback evidence.
SVC-005organization-serviceservices/school-service aliasSchool/center/campus/org-unit and academic-year metadata plus IAM-synchronized membership read model for tenant validation.GOTOOLCHAIN=go1.25.11 go test ./services/school-service/..., make test-organization-routes, make test-academic-year-routes, make test-academic-year-route-runtime, make test-academic-year-postgres, and make test-academic-year-browser. The browser target starts fresh PostgreSQL, temporary school/Gateway/Admin Vite processes, and proves list/draft/activate only through the opt-in candidate; all academic-year evidence remains disposable/non-default and broad organization routes stay legacy-backed.
SVC-006classroom-serviceservices/classroom-serviceClassroom-local class/member/teacher-assignment workflows using profile/org references only.GOTOOLCHAIN=go1.25.11 go test ./services/classroom-service/... and make test-classroom-route-guard.
SVC-007course-serviceservices/course-serviceCourse/module/lesson/material metadata, enrollment, progress, visibility, owner catalog snapshots, and public/student route rehearsal.GOTOOLCHAIN=go1.25.11 go test ./services/course-service/..., COURSE_SEARCH_PROJECTION_OUTBOX_POSTGRES_CONFIRM=disposable-postgres make test-course-learning-catalog-delivery-postgres test-course-learning-progress-delivery-postgres, and COURSE_LEARNING_ANALYTICS_RUNTIME_CONFIRM=local-postgres make test-course-learning-analytics-runtime for native Course -> Analytics catalog/progress delivery and mastery read with separate fresh owner databases. Also run make test-student-course-routes test-student-course-progress-routes and STUDENT_COURSE_BROWSER_SELF_TEST=1 make test-student-course-browser; all outbox/runtime targets are local/disposable and do not promote a route. docs/qa/student-course-route-rehearsals.md keeps live/browser proof required before student route promotion.
SVC-008question-serviceservices/question-bank-service aliasQuestion CRUD/read projections, type definitions, taxonomy, AI context, import ingest handoff, and editor write save/reload proof.GOTOOLCHAIN=go1.25.11 go test ./services/question-bank-service/... plus make test-question-read-routes test-question-types-routes test-question-classification-apply-routes, make 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, make test-question-types-live test-question-types-browser, and make test-question-read-browser test-question-read-browser-admin for read/type/apply/write route slices.
SVC-009exam-serviceservices/exam-serviceExam authoring, persistent matrix blueprints/rules, publish snapshots, native assignment/result-release, access decision API, and next share-link/export contracts.GOTOOLCHAIN=go1.25.11 go test ./services/exam-service/..., ATTEMPT_RESULT_RELEASE_NOTIFICATION_SELF_TEST=1 make test-attempt-result-release-notification-workflow, EXAM_RESULT_RELEASE_POSTGRES_CONFIRM=disposable-postgres make test-exam-result-release-postgres, make test-exam-result-release-deploy, and EXAM_RESULT_RELEASE_RUNTIME_CONFIRM=exam-result-release-isolated make test-exam-result-release-runtime, plus make test-exam-authoring-routes test-teacher-exam-blueprint-bff-routes. The result-release workflow proves the exam-owned durable relay before attempt-service's notification outbox; the disposable Postgres proof verifies owner migration, transaction rollback, and restart recovery; the runtime proof verifies the authenticated relay opens an actual hidden submitted attempt; and the deployment guard keeps its target/auth/worker configuration present. All remain disposable/non-default, not shared/live or public Gateway promotion. Run DOCX_PHYSICS_EXAM_BLUEPRINT_ISOLATED_CONFIRM=docx-physics-exam-blueprint-isolated make test-docx-physics-exam-blueprint-isolated for a fresh Compose proof of a real 28-question DOCX matrix through BFF, including source-solution parity in Question Bank, 16 ordered true/false statements in online/offline snapshots and Word, embedded snapshot images, and every formula as OMML or a visible fallback. Matrix rehearsal remains non-default until browser/rollback proof, while start adapter slices also require make test-attempt-routes, make test-attempt-live, and make test-attempt-browser.
SVC-010attempt-serviceservices/attempt-serviceAttempt sessions, copied snapshots, answers, grading, events, results, exam result-release propagation, and public attempt surfaces.GOTOOLCHAIN=go1.25.11 go test ./services/attempt-service/... plus make test-attempt-routes, make test-attempt-live, and make test-attempt-browser; gateway/BFF adapter tests are required before public route promotion. ATTEMPT_RESULT_RELEASE_NOTIFICATION_SELF_TEST=1 make test-attempt-result-release-notification-workflow covers result visibility, retry, and two-dispatcher lease claiming before notification-service publish. DOCX_PHYSICS_GATEWAY_ATTEMPT_LOCAL_POSTGRES_CONFIRM=local-postgres make test-docx-physics-attempt-local-postgres proves a Physics-backed Student Web browser start -> save -> submit -> result-read -> GRADED attempt with fresh IAM/Exam/Attempt databases and no shared runtime or default route.
SVC-011file-serviceservices/document-service aliasFile/media metadata, signed reads, teaching documents, and owner projection for search.GOTOOLCHAIN=go1.25.11 go test ./services/document-service/... plus make test-storage-media-parity when upload/download behavior changes; docs/qa/storage-media-parity-smoke.md keeps browser proof required before public storage promotion.
SVC-012import-serviceservices/docx-import-service aliasImport jobs, parser orchestration, review save, approval saga, SSE/status/download, direct Mistral OCR, formula provenance bridge, direct and durable MathType-to-OMML conversion, and draft handoff to question/exam.GOTOOLCHAIN=go1.25.11 go test ./services/docx-import-service/... plus make test-import-create-routes test-import-status-routes test-import-approval-routes test-import-review-roundtrip-routes, make test-import-pdf-ocr-workflow, and the matching live/browser smoke target for changed workflows. make test-docx-corpus reads all four local fixtures, then runs a real in-process Import approval against an isolated Question Bank HTTP boundary: complete Physics payloads forward unchanged, while untouched Math, English, and DGNL remain blocked before any owner write. It then saves review-safe source-evidence subsets (Math 13, English 34, DGNL 37), asserts exact owner payload plus recomputed review stats, and verifies canonical type plus source-label-to-option-ID, numeric-value, and Physics true/false statement mappings; no missing or nonnumeric placeholder answer is inferred. `GOTOOLCHAIN=go1.25.11 go test ./services/docx-import-service/internal/usecase ./services/docx-import-service/internal/http -run 'TestHTTPApprovalUsage
SVC-013formula-docx-servicesource-controlled runtimes/go-formula-docx runtime behind import adaptersParser determinism, MathType/OMML/OLE/table conversion, per-question formula provenance, metrics, and corpus evidence through docx-import-service adapter tests.sh scripts/test/go-formula-runtime-coverage.sh, make test-docx-corpus, DOCX_FORMULA_DETERMINISM_CONFIRM=read-only-formula-runtime make test-docx-formula-determinism, and GOTOOLCHAIN=go1.25.11 go test ./services/docx-import-service/internal/parser/docx -count=1 when parser behavior changes. The determinism target repeats Math (22/125, 117 MTEF-OLE plus 8 OMML) and Physics (28/84 MTEF-OLE) against the external runtime, then has the real Go adapter require byte-identical import-visible JSON after latency_ms is cleared. Raw OLE/WMF diagnostic asset paths remain filtered non-display provenance, not persisted browser media.
SVC-014search-serviceservices/search-serviceRebuildable owner-service indexes, sync checkpoints, filters, and source projection pulls; /api/public/catalog* remains course-service-owned until an explicit legacy route mapping selects search-service.GOTOOLCHAIN=go1.25.11 go test ./services/search-service/... -count=1, make test-search-rebuild, make test-search-routes, and make test-search-projection-freshness-latency; SEARCH_PROJECTION_PULL_WORKER_POSTGRES_CONFIRM=disposable-postgres make test-search-projection-pull-worker-postgres runs the real binary against fresh PostgreSQL, proves one-page PARTIAL checkpoints resume to SYNCED after process restart, and verifies native search/sync reads. All are local/disposable only; route rehearsals must cite the exact legacy controller/owner mapping first.
SVC-015ai-serviceservices/ai-classifier-service aliasProvider adapters, AI jobs, AI-owned non-secret default provider runtime selection, prompt context, generate/explain/grade contracts, and usage/wallet integration points only through explicit APIs; AI must not own quota checks or credit movement.GOTOOLCHAIN=go1.25.11 go test ./services/ai-classifier-service/..., make test-ai-provider-settings, make test-ai-classification-job-route-guard test-teacher-ai-preview-routes, AI_CLASSIFICATION_JOB_SELF_TEST=1 make test-ai-classification-job-live, and make test-question-classification-apply-routes; AI_GENERATION_SETTLEMENT_LOCAL_POSTGRES_CONFIRM=local-postgres make test-ai-generation-settlement-local-postgres uses a fresh initdb cluster, seeds only an AI-owned non-secret mock provider_settings selection, and asserts both native binary starts report configurationSource=database before its separate usage/wallet settlement restart proof. The explicitly isolated make test-docx-physics-exam-blueprint-isolated also proves mock similar/explanation previews from an imported Question Bank reference stay no-write until the teacher-reviewed Question Bank draft/version APIs run idempotently. Run make test-monetization-event-chain when touching usage/wallet handoff contracts, and use make test-question-classification-apply-live only for explicit live write smoke.
SVC-016billing-serviceservices/billing-servicePlan catalog, subscription lifecycle, invoices, entitlement events, renewal/proration policy.GOTOOLCHAIN=go1.25.11 go test ./services/billing-service/... plus make test-monetization-event-chain and make test-monetization-broker-transport when emitting to usage/wallet.
SVC-017wallet-serviceservices/wallet-serviceAZ Credits balance, immutable ledger, top-up/withdrawal admin review, grants/debits/refunds, event consumers, and first legacy-compatible wallet/admin adapter rehearsal.GOTOOLCHAIN=go1.25.11 go test ./services/wallet-service/... plus make test-monetization-event-chain test-monetization-routes test-monetization-broker-transport for replay/idempotency, route guards, and broker transport.
SVC-018usage-serviceservices/usage-serviceFeature gates, quotas, counters, check/consume/reset, entitlement sync, and limit overrides.GOTOOLCHAIN=go1.25.11 go test ./services/usage-service/... plus make test-monetization-event-chain and make test-monetization-broker-transport for billing entitlement replay and broker transport.
SVC-019payment-serviceservices/payment-servicePayment orders, provider webhooks, idempotency, reconcile, and paid-event outbox.GOTOOLCHAIN=go1.25.11 go test ./services/payment-service/... plus make test-monetization-event-chain test-monetization-routes test-monetization-broker-transport before public hook cutover. `PAYMENT_SERVICE_POSTGRES_TEST_DATABASE_URL='payment-test-dsn' GOTOOLCHAIN=go1.25.11 go test ./services/payment-service/internal/repository -run 'TestPostgresPaymentWebhookReplayIntegration
SVC-020notification-serviceservices/notification-serviceInbox, preferences, read/delete state, parent alerts, fanout consumers, and delivery metadata. attempt-service is a bounded grade-release producer dependency, including delayed MANUAL/pre-close AFTER_CLOSE result release, not an implementation owner.GOTOOLCHAIN=go1.25.11 go test ./services/notification-service/... plus GOTOOLCHAIN=go1.25.11 go test ./services/attempt-service/..., ATTEMPT_RESULT_RELEASE_NOTIFICATION_SELF_TEST=1 make test-attempt-result-release-notification-workflow, make test-notification-routes test-parent-alert-routes test-attempt-routes, NOTIFICATION_EVENT_FANOUT_POSTGRES_CONFIRM=disposable-postgres make test-notification-event-fanout-postgres, and make test-student-notification-browser. The fanout and browser targets use disposable owner storage or memory-only candidate processes and do not promote the default route.
SVC-021audit-serviceservices/audit-serviceAppend-only audit/security events, replay/idempotency, retention/legal-hold scans, producer projections, and compatibility backfill target.GOTOOLCHAIN=go1.25.11 go test ./services/audit-service/..., make test-audit-admin-compat-routes, AUDIT_REPLAY_RETENTION_POSTGRES_CONFIRM=disposable-postgres make test-audit-replay-retention-postgres, make test-admin-audit-owner-browser, plus producer contract tests for IAM/payment/billing/wallet/admin/gateway. The Postgres and Admin browser targets are disposable/non-default evidence; they do not establish legacy backfill parity or promote the default route.
SVC-022analytics-serviceservices/analytics-serviceDashboard/result/progress/mastery projections and weak-topic rollups from owner events.GOTOOLCHAIN=go1.25.11 go test ./services/analytics-service/..., ANALYTICS_POSTGRES_REBUILD_CONFIRM=disposable-postgres make test-analytics-course-learning-projection-outbox-postgres, make test-analytics-course-learning-projection-worker-config, and COURSE_LEARNING_ANALYTICS_RUNTIME_CONFIRM=local-postgres make test-course-learning-analytics-runtime for the native two-service handoff. Also run make test-analytics-routes and event projection fixtures for changed producers. The Course outboxes and Analytics 000008 worker remain opt-in/local only and never add a Gateway route.
SVC-023admin-serviceservices/admin-serviceAdmin read models, feature maintenance guard decisions, moderation/support workflows, and owner-service adapters; dashboards must use owner APIs/source snapshots instead of synthesizing source-service totals.GOTOOLCHAIN=go1.25.11 go test ./services/admin-service/... plus owner-source/source-snapshot tests, make test-feature-maintenance-routes test-admin-audit-routes test-admin-owner-source-routes, and make test-admin-owner-source-browser. The browser target uses memory-only Admin storage, a disposable owner fixture, temporary Gateway/Vite processes, and default legacy rollback; it does not prove dashboard parity or promote a route.

Cutover And Alias Workflows

PackRouted ownerWorkflow gate
auth-serviceIAM onlyNot a Go-platform service row. /api/auth* and /v1/auth* are compatibility namespaces backed by iam-service; do not create an auth-service task pack, API doc, OpenAPI contract, deployment, or runtime directory.
iam-org-membership-canonicalIAM plus organization coordinationIAM remains the only permission-bearing membership writer; school-service sync routes reject ordinary callers and preserve event ordering/tombstones; non-default gateway write proof uses ORGANIZATION_MEMBERSHIP_WRITE_SELF_TEST=1 make test-organization-membership-write-live before any live bearer-token smoke.
iam-profile-cutover-hardeningOrchestrator with IAM/Profile/Gateway/MigrationUUID/backfill/default-route cutover is not done until make test-iam-profile-backfill-report, browser proof, rollback evidence, UUID migration implementation, and clean-cluster proof exist.
user-service-retirementOrchestrator retirement onlyNo new product work enters services/user-service; removal waits for IAM/Profile route parity and data backfill evidence.
docx-corpus-question-bank-local-postgresImport and Question Bank ownersDOCX_CORPUS_QUESTION_BANK_LOCAL_POSTGRES_CONFIRM=local-postgres make test-docx-corpus-question-bank-local-postgres creates two service-owned temporary databases, applies migration Up blocks, and proves the four-fixture HTTP persistence/read-back flow without Docker or a shared database. It does not promote a Gateway route or cover Exam, AI, or browser behavior.
docx-physics-exam-blueprint-local-postgresDocument, Import, Question Bank, Exam, BFF, and AI ownersDOCX_PHYSICS_EXAM_BLUEPRINT_LOCAL_POSTGRES_CONFIRM=local-postgres make test-docx-physics-exam-blueprint-local-postgres creates five service-owned temporary databases, materializes Physics media through Document, then proves the BFF matrix, online/offline snapshots, Word export, and reviewed mock AI writes. Object bytes are intentionally in-memory and it is not Gateway, browser, OCR-provider, or production evidence.
docx-physics-gateway-attempt-local-postgresGateway, IAM, Classroom, Document, Import, Question Bank, Exam, and Attempt ownersDOCX_PHYSICS_GATEWAY_ATTEMPT_LOCAL_POSTGRES_CONFIRM=local-postgres make test-docx-physics-attempt-local-postgres creates seven service-owned temporary databases, verifies the complete dynamically served candidate table, authenticates isolated teacher/student identities, and persists the Physics 18/6/4 Question Bank -> online Exam -> Attempt GRADED path. It drives the Student Web candidate through one each of start, answer-save, submit, and result-read requests, with the access-link code and bearer header redacted in artifacts. Document bytes stay in-memory; it is not Mistral, default-route, deployed, or production proof.
entitlement-serviceUsage alias onlyDo not spawn a separate service owner unless an ADR renames usage-service.
monetization-scaffold-waveBilling/Wallet/Usage/Payment coordinationMoney, entitlement, wallet ledger, and payment webhook responsibilities stay split by service and verified through replay-safe events.

Agent Closeout Checklist

Every service agent closeout must include:

  • Docs read, including the service task pack and this matrix.
  • Legacy evidence read, with file paths.
  • Files changed, limited to the writable scope.
  • Focused tests and service verification command output.
  • Route/default cutover status and rollback notes if any route changed.
  • Remaining risks and the next recommended task.

Go-platform documentation is generated from repository Markdown.