Skip to content

Service Boundaries

Phase: Service boundaries for staged implementation Status: active; native foundations follow these boundaries and public/default cutovers remain proof-gated.

Boundary Rules

  • A service owns its database, migrations, SQL queries, events, and domain invariants.
  • A service may expose read APIs for other services, but consumers must not join across databases.
  • Shared libraries may contain request IDs, auth context structs, OpenAPI helpers, error envelope helpers, and generated clients. They must not contain domain write logic.
  • Legacy source remains a read-only reference. Copying behavior requires an evidence note in the implementing task.
  • New source goes under go-platform/ only.

API Gateway

Owns:

  • Public /api/* route compatibility.
  • Legacy proxy routing.
  • Native service routing.
  • Auth token extraction and basic JWT compatibility.
  • Request/correlation ID propagation.
  • CORS and body limits matching legacy defaults.
  • SSE pass-through.
  • Public health and metrics compatibility.

Does not own:

  • Domain writes.
  • Per-service database migrations.
  • AI/provider credentials beyond route-level policy.
  • Business rules hidden inside gateway adapters.

BFF Service

Owns:

  • Frontend-specific screen aggregation and response shaping for gateway-approved web/admin routes.
  • Source-service status snapshots and route metadata for frontend shells.
  • Read-only composition over owner service APIs.

Current state:

  • services/bff-service foundation exists for native admin overview, admin operations summary, teacher dashboard, teacher operations summary, and role-based frontend shell metadata.
  • It has no primary business database and does not read service databases.
  • Public /api/admin/overview, /api/dashboard/teacher, and frontend shell routes remain legacy/gateway controlled until route-table rehearsal and browser evidence exist.

Does not own:

  • Domain writes or canonical state.
  • IAM credentials, profile, wallet, payment, billing, usage, question, exam, import, search, audit, notification, or admin source data.
  • Auth policy beyond trusting gateway-derived actor headers on native tests.

Canonical Service Naming

Some Go services already existed before the July 2026 responsibility refresh. The canonical product boundary is binding; the current implementation name is kept when renaming would break route tables, deploy manifests, or historical handoffs.

Canonical boundaryCurrent implementationRename status
organization-serviceschool-serviceAlias until a dedicated rename task is approved.
question-servicequestion-bank-serviceAlias; service owns the question bank.
file-servicedocument-serviceAlias; service owns files/media/teaching documents.
import-servicedocx-import-serviceAlias for DOCX/PDF/import workflow foundation.
formula-docx-servicego-formula-docx runtime behind docx-import-serviceRuntime split is internal for now.
ai-serviceai-classifier-serviceCurrent slice covers AI classification/provider work.
user-servicedeprecated compatibility scaffoldDo not add new ownership here; identity/profile work routes to iam-service and profile-service.
audit-serviceservices/audit-service foundation; admin audit route still in admin-serviceCompliance ledger split started; public route cutover is separate.

IAM Service

Owns:

  • Account identity and credential state.
  • Local register/login/refresh/logout/session revocation.
  • Refresh-token persistence and rotation.
  • JWT/JWKS compatibility metadata.
  • Roles, permissions, account-role assignment, permission checks.
  • Organization memberships and invitations when used for access control.
  • Login/security audit records.

Depends on:

  • profile-service for display/profile hydration.
  • school-service/organization-service for organization metadata when needed.

Must preserve:

  • Bearer token and hoctapaz.accessToken cookie compatibility at gateway.
  • Access token type=access.
  • Refresh token type=refresh and jti.

Does not own:

  • Avatar, DOB, educational profile, learning progress.
  • Subscription, AZ Credits, wallet ledger, payment provider state.

Profile Service

Owns:

  • Base educational profile read/write after identity creation.
  • Avatar/display name, phone, date of birth, gender.
  • Student, teacher, parent, and staff profile details.
  • Public profile views and internal full profile views.
  • Parent-student display/read models only when they are profile metadata.

Does not own:

  • Login credentials, password verification, token issuance, session revocation.
  • Role and permission source of truth.
  • Organization membership policy.
  • Subscription, wallet, payment, usage quota.

Organization Service (school-service current implementation)

Owns:

  • Organizations.
  • Organization units.
  • Tenant metadata and tenant validation.
  • IAM-synchronized organization-member read models, including sync ordering and tombstone state required to project a member directory locally.
  • School-scoped roster metadata when imported from roster flows, without becoming the access-control membership authority.

Must preserve:

  • X-Organization-Id behavior.
  • Admin bypass rules only through explicit policy, not implicit DB access.

Does not own:

  • Authoritative organization membership writes, membership policy, invitations, roles, or permissions. Those remain iam-service responsibilities.
  • A second source of truth for a member relationship. school-service accepts trusted IAM synchronization only and must reject ordinary member writes.

Classroom Service

Owns:

  • Classroom records.
  • Classroom members.
  • Announcements.
  • Lessons created inside classrooms.
  • Classroom materials and tuition records.

Phase 8 start:

  • P8-004 implements only classroom records and classroom members.
  • Lesson, material, announcement, tuition, dashboard, leaderboard, and exam-assignment behavior remains legacy-proxied until later slices.
  • Organization, unit, subject, teacher, creator, and student identifiers are stored as public ids; validation and hydration stay behind gateway adapters and owning services.

Depends on:

  • school-service for tenant and membership checks.
  • document-service for media/document references.
  • exam-service for exam assignment references.

Course Service

Owns:

  • Course catalog records.
  • Sections, lessons, materials.
  • Enrollment and progress.
  • Course quizzes as references to exam/question contracts.

Phase 8 start:

  • P8-005 implements course records, sections, lessons, material metadata, enrollments, lesson/video progress, material views, and public course projections.
  • Question links, quizzes, mastery, recommendation, reports, wallet purchase, and file streaming remain legacy-proxied until later adapters.
  • Organization, subject, topic, instructor, creator, student, media, uploader, question, exam, and wallet identifiers are stored as public ids; validation and hydration stay behind gateway adapters and owning services.

Does not own:

  • Question canonical content.
  • Exam attempt grading.

File Service (document-service current implementation)

Owns:

  • Media asset metadata.
  • S3/MinIO object key policy.
  • Presigned upload compatibility.
  • Teaching documents, purchases, shares, and content serving.

Must preserve:

  • Existing object keys where migrated.
  • Formula/image variant serving used by import and question editor.
  • MIME and size policy compatibility until a product change is approved.

Import Service (docx-import-service current implementation)

Owns:

  • DOCX Fast jobs.
  • OCR document conversion jobs.
  • MathType -> Word Equation conversion jobs.
  • Import review draft state.
  • Import question segments and processing events.
  • Import SSE event stream.

Depends on:

  • document-service for object reads/writes and media metadata.
  • question-bank-service for approval into questions.
  • exam-service for approval into draft exams/templates.
  • ai-classifier-service only through explicit classification API/event contracts.

Must preserve:

  • docx-fast, mathtype-equation, ocr-document source values.
  • Vietnamese labels such as Import Đề Thi Nhanh (VIP), MathType -> Word Equation, and OCR Tài Liệu.
  • Manual question-type overrides from review/editor saves.
  • Warning, timing, media, formula, table, and source-location fields.

Formula DOCX Service

Owns:

  • CPU/runtime-heavy DOCX, OMML, MathType/OLE/MTEF, formula and table parsing when separated from import orchestration.
  • Parser latency, warning, and corpus metrics.
  • Deterministic conversion outputs that import-service can store/review.

Current state:

  • Implemented as go-formula-docx runtime behind docx-import-service.
  • Do not expose it directly to frontend.

Does not own:

  • Import approval, question persistence, exam creation, quota charging.

AI Service (ai-classifier-service current implementation)

Owns:

  • AI classify job creation/status/events/cancel/apply workflow.
  • AI provider settings.
  • AI provider usage events.
  • Question solution history if generated by AI.

Depends on:

  • question-bank-service for applying classification or solution output.
  • admin-service for feature maintenance state if centralized there.

Must preserve:

  • Read-only GET bypass behavior for feature maintenance where legacy allowed it.
  • SSE snapshot/heartbeat/job update semantics.

Does not own:

  • Usage entitlement, credit debits, subscription state, or payment reconciliation.

Question Service (question-bank-service current implementation)

Owns:

  • Questions.
  • Question versions.
  • Question options.
  • Question type definitions.
  • Folders, groups, tags.
  • Difficulty and taxonomy references unless centralized later.

Must preserve:

  • Existing question types: SINGLE_CHOICE, MULTIPLE_CHOICE, TRUE_FALSE, TRUE_FALSE_GROUP, SHORT_ANSWER, SHORT_NUMERIC_ANSWER, ESSAY.
  • Rich content JSON compatibility.
  • Scoring rule semantics.
  • Archive-vs-hard-delete behavior until explicitly changed.

Exam Service

Owns:

  • Exam folders.
  • Exam blueprints and generation runs.
  • Exam paper templates and sections.
  • Exam authoring, scheduling, assignments, access links.
  • Exam question snapshots at publish time.

Depends on:

  • question-bank-service for source question reads before snapshot.
  • classroom-service for classroom assignment validation.

Must preserve:

  • Draft-only edit rule.
  • Publish snapshot refresh rule.
  • Access password hash behavior.

Native snapshot boundary:

  • exam-service stores exam question snapshots as its own persisted state.
  • Callers must provide hydrated question payloads through service APIs; exam-service must not join the question-bank database.
  • Snapshot payloads preserve content JSON, options, sub-items, answer keys, scoring rules, media/formula refs, option order, and section/order metadata for later attempt snapshots.

Attempt Service

Owns:

  • Attempt creation.
  • Attempt question snapshots.
  • Answer saves.
  • Optimistic answer versioning.
  • Submission and grading.
  • Attempt events and result visibility.

Depends on:

  • exam-service for published exam snapshot/start policy.

Must preserve:

  • Student-only start rule.
  • Online/open/assigned/link access checks.
  • Attempt snapshots independent from later question edits.
  • clientVersion vs serverVersion conflict semantics.

Notification Service

Owns:

  • Notifications.
  • Notification preferences.
  • Notification event fanout and delivery state.
  • In-app delivery state for already-resolved recipients.

Consumes:

  • Exam published/assigned/submitted events.
  • Import completed/failed events.
  • Admin or support ticket events if retained.

Does not own:

  • User search, role broadcast resolution, or parent/student relationship lookup. These come from iam/profile/school-service adapters.
  • Admin audit logs. Those belong to admin-service.
  • Support ticket storage. That stays legacy-proxied until an admin/support slice owns it.
  • Email/SMS provider delivery in P9-001.

Analytics Service

Owns:

  • Read models for dashboard, weak topics, progress, mastery, and result analytics.
  • Event-derived aggregates.
  • Attempt-result projections ingested from already-hydrated attempt/event payloads.
  • Service-local analytics/audit event capture that is not admin audit history.

Does not own:

  • Canonical exam, attempt, course, or question state.
  • Parent-child relationships or user profile hydration.
  • Classroom membership validation.
  • Notification unread rows used in full parent progress.

Billing Service

Owns:

  • Subscription plans and prices.
  • Billing cycles, invoices, subscription status.
  • Plan entitlements as commercial policy.

Does not own:

  • Payment provider webhook ingestion.
  • Wallet ledger or AZ Credit debits.
  • Login, profile, course, question, exam, or import state.

Current state:

  • services/billing-service foundation exists for plan catalog, plan prices, subscriptions, invoices, payment-outcome activation, cancellation, and entitlement snapshots.
  • Public /api/wallet, package, subscription, and payment routes remain legacy-proxied until payment events, wallet credit grants, usage entitlement sync, gateway adapters, and browser/runtime parity are proven.

Wallet Service

Owns:

  • Wallet balances.
  • Immutable AZ Credit ledger.
  • Credit grants, debits, refunds, and adjustment audit trail.

Does not own:

  • Subscription plan lifecycle.
  • Provider payment webhook reconciliation.
  • Feature quota policy beyond balance checks.

Current state:

  • services/wallet-service foundation exists for wallet ensure/read, immutable ledger entries, debit/credit/adjustment idempotency, and service-owned Postgres storage.
  • Existing wallet/AZ Credit public behavior remains legacy-proxied until top-up/withdrawal/admin-review state machines, payment outcome consumers, gateway adapters, and browser/runtime parity are proven.

Usage Service (entitlement-service alias)

Owns:

  • Feature gates and plan entitlement checks.
  • Usage counters and quota periods.
  • Monthly resets and idempotent consume/check APIs.

Does not own:

  • Money movement, wallet ledger, or payment provider state.
  • AI/import execution or parser state.

Current state:

  • services/usage-service foundation exists for entitlement materialization, feature gates, usage counters, quota periods, limit overrides, check/consume decisions, and service-owned Postgres storage.
  • usage-service is the canonical service name; entitlement-service is an allowed planning alias only. Early services must not implement quota locally except through a documented temporary compatibility adapter.

Payment Service

Owns:

  • Payment orders.
  • Provider transactions.
  • Webhooks, idempotency, reconciliation.

Does not own:

  • Subscription activation rules except by emitting successful payment events.
  • Wallet balance as source of truth.

Current state:

  • services/payment-service foundation exists for payment orders, provider webhook evidence, provider transactions, reconciliation, and idempotent replay handling.
  • Provider webhook and payment routes remain legacy-proxied until SePay auth verification, payment event publishing, billing/wallet consumers, gateway adapters, and browser/runtime parity are proven.

Search Service

Owns:

  • Search indexes and sync checkpoints.
  • Full-text/vector-style query APIs over copied/indexed data.

Does not own:

  • Canonical course/question/exam/document state.

Current state:

  • services/search-service foundation exists for read-only/rebuildable index projections, generic search filters, and source sync checkpoints. Public routes remain legacy-proxied until owner-service backfill/event pipelines and gateway adapters are proven.
  • /api/public/catalog* is currently mapped to course-service, not search-service. Copied course index rows can support discovery, but public catalog route compatibility stays with the owner mapping until a separate route cutover explicitly selects search-service with legacy evidence.

Audit Service

Owns:

  • Compliance-grade append-only audit and security event history.
  • Source-service event idempotency, retention policy metadata, legal hold metadata, and query filters for compliance review.

Current state:

  • services/audit-service foundation exists for native /v1/audit-events and /v1/security-events. It is an internal event sink only.
  • admin-service still owns the public admin audit compatibility foundation for GET /api/admin/operations/audit; future migration must preserve legacy action/entity keys, newest-first ordering, and labels.

Does not own:

  • Domain decisions, source writes, feature maintenance, or admin dashboards.
  • IAM credentials, session policy, or permission checks.
  • Public /api/admin/operations/audit until gateway cutover evidence exists.

Admin Service

Owns:

  • Feature maintenance registry state and public active-feature payloads.
  • Admin audit logs.
  • Admin dashboard and operational controls in later slices.
  • Support/admin workflow storage only after an explicit audited task.

Consumes:

  • Audit events emitted by other native services or gateway adapters.
  • Operational projections produced by service-specific APIs/events.

Does not own:

  • Wallet/AZ Credit ledger or payment rails in P9-003.
  • User credentials, profile, KYC storage, or tenant membership.
  • Queue retry, AI provider settings, support tickets, or admin dashboard aggregation in the feature-maintenance/audit foundation slice.

Must preserve:

  • Exact feature maintenance keys and Vietnamese labels from the legacy shared registry.
  • Public status payload { items, activeFeatureKeys, generatedAt }.
  • Read-only AI classification job GET bypass during maintenance.
  • Audit action/entity keys so the existing Vietnamese admin operation labels keep working through adapters.
  • CSV/XLSX classroom report export in P9-002.

Go-platform documentation is generated from repository Markdown.