Overview
:::info Source
Sourced from services/delivery-service/SERVICE_OVERVIEW.md in the documentation repo.
:::
Companion: 03 delivery-service · 02 DDD · 11 LMS Runtime Player · 13 Security
1. Purpose
The delivery-service is the runtime learner experience engine for the Ghasi-edTech platform. It owns the full lifecycle of PlaySession aggregates — from start through navigation, AI tutor interaction, offline mount/unmount, pause, completion, and abandonment. It is the server-side counterpart of the LMS runtime player defined in doc 11.
2. Bounded Context
Delivery — classified as Core (competitive differentiator). The Delivery context is where the platform's offline-first, AI-first promise materializes for learners. It consumes PlayPackage projections from Content-Packaging, validates enrollment eligibility, orchestrates the AI tutor, and manages the offline bundle lifecycle.
3. Responsibilities
| Area | What Delivery Owns |
|---|---|
| PlaySession lifecycle | Start, resume, navigate, pause, complete, abandon transitions on the PlaySession state machine |
| Navigation | Cursor management through module/lesson/block trees; branch-path decisions (quiz-gated advancement delegated to assessment-service) |
| AI Tutor orchestration | Streaming SSE-based AI tutor interactions scoped to the current lesson context; RAG over course content |
| Offline mount/unmount | License envelope validation, device binding checks, bundle integrity verification, mount/unmount lifecycle |
| Session telemetry | Emitting navigation and session lifecycle events consumed by progress-service |
| SCORM 2004 runtime | Runtime adapter for SCORM 2004 sequencing (S4 slice) |
4. Non-Responsibilities
| Area | Owner | Why Not Delivery |
|---|---|---|
| Statement storage (LRS) | progress-service | Delivery emits intents; Progress is the authoritative record store |
| Quiz scoring | assessment-service | Delivery delegates quiz presentation and scoring; it only receives pass/fail gates |
| PlayPackage building | content-service | Content-Packaging owns the manifest and bundle creation pipeline |
| Enrollment eligibility | enrollment-service | Delivery checks enrollment status but does not own enrollment records |
| Certificate issuance | certification-service | Triggered downstream from progress completion events |
| AI model management | ai-gateway-service | Delivery calls the AIClient port; model selection and routing are gateway concerns |
5. Dependencies
5.1 Upstream Dependencies
| Dependency | Pattern | Purpose |
|---|---|---|
| content-service | PL (Published Language) | Consumes content.play_package.built.v1 and content.play_package.bundle.published.v1 for PlayPackage manifests and bundles |
| enrollment-service | CS (Customer/Supplier) | Validates enrollment eligibility before session start; consumes enrollment.created.v1 |
| assessment-service | CS | Delegates quiz serving and scoring; consumes assessment.attempt_result.scored.v1 for gated navigation |
| ai-gateway-service | OHS (Open Host Service) | AI tutor inference — cloud for online, local model for offline |
| identity-service | CF (Conformist) | JWT validation and device binding verification |
5.2 Downstream Consumers
| Consumer | Pattern | What They Consume |
|---|---|---|
| progress-service | CS | Consumes delivery.play_session.started.v1, .completed.v1, .navigated.v1 to open attempts and record progress |
| analytics-service | Event consumer | Consumes all delivery events for learning analytics dashboards |
| sync-service | Event consumer | Consumes offline mount/unmount events for sync registration |
| notification-service | Event consumer | Consumes session abandonment events for re-engagement notifications |
5.3 Events Consumed by Delivery
| Event | Producer | Purpose |
|---|---|---|
content.play_package.built.v1 | content-service | Cache the PlayPackage manifest for runtime navigation |
enrollment.created.v1 | enrollment-service | Allow session creation for newly enrolled learners |
content.play_package.bundle.published.v1 | content-service | Mark bundles available for offline mount |
content.bundle.tamper_detected.v1 | content-service | Force-unmount tampered bundles; invalidate sessions |
6. Slice Involvement
| Slice | Scope | Milestone |
|---|---|---|
| S1 — Player MVP + AI tutor + offline | PlaySession CRUD, basic navigation, AI tutor (SSE streaming), offline mount/unmount, bundle validation | M1 |
| S4 — SCORM 2004 runtime | SCORM 2004 sequencing adapter, runtime data model mapping, SCO launch and communication | M3 |
| S5 — Enhanced navigation | Branching paths, prerequisite-gated lessons, adaptive sequencing, bookmarks | M3 |
7. Architectural Freeze Points
| Freeze | What Is Frozen | Frozen By |
|---|---|---|
| F15 | PlayPackage manifest schema — the contract between content-service and delivery-service defining the structure of course runtime data | End of M1 |
| F01 | EventEnvelope schema — all events conform to the envelope in 04 Event-Driven | End of M0 |
After freeze, changes require architectural review and a new version with dual-publish window.
8. Service Readiness Levels
| Level | Description | Target Milestone |
|---|---|---|
| L3 | PlaySession lifecycle operational, AI tutor streaming, offline mount/unmount, contract tests, basic SLO tracking | M1 |
| L4 | SCORM 2004 runtime, enhanced navigation, chaos-tested, full observability, production-grade | M3 |
9. Architecture Diagram
┌───────────────────────────────────────────────┐
│ API Gateway / Edge │
└──────────────────┬────────────────────────────┘
│
┌──────────────────▼────────────────────────────┐
│ delivery-service (NestJS) │
│ │
│ ┌──────────┐ ┌──────────┐ ┌────────────┐ │
│ │PlaySess │ │ AI Tutor │ │ Offline │ │
│ │ Module │ │ Module │ │ Module │ │
│ └────┬─────┘ └────┬─────┘ └─────┬──────┘ │
│ │ │ │ │
│ ┌────▼─────────────▼──────────────▼──────┐ │
│ │ Domain Layer (pure TS) │ │
│ │ PlaySession · NavigationCursor │ │
│ │ AssistantTurn · OfflineMount │ │
│ └────────────────┬───────────────────────┘ │
│ │ │
│ ┌────────────────▼───────────────────────┐ │
│ │ Infrastructure Layer │ │
│ │ Postgres (RLS) · NATS · Redis │ │
│ │ AIClient · EnrollmentClient · SSE │ │
│ │ ContentClient · OutboxRelay │ │
│ └────────────────────────────────────────┘ │
└──────────────────────────────────────────────┘
│
┌──────────────────────────┼──────────────────────────┐
│ │ │
┌──────▼──────┐ ┌───────▼───────┐ ┌──────▼──────┐
│ content- │ │ ai-gateway- │ │ enrollment- │
│ service │ │ service │ │ service │
└─────────────┘ └───────────────┘ └─────────────┘
10. Key Design Decisions
| Decision | Rationale |
|---|---|
| SSE for AI tutor (not WebSocket) | Simpler, unidirectional streaming; aligns with platform API surface conventions; works through CDN/proxies without upgrade negotiation |
| PlaySession as aggregate root | All navigation, tutor interactions, and offline mounts are clustered under session; provides a single consistency boundary for concurrent operations |
| Event-driven progress reporting | Delivery does not write to progress-service directly; emits events consumed asynchronously. This decouples the runtime path from LRS write latency |
| License envelope validation on mount | Prevents unauthorized offline access; device binding ensures content cannot be sideloaded to unregistered devices |
| Local AI inference for offline | Learners in offline mode get AI tutor via on-device model; this fulfills the "AI-first even offline" platform promise |