How learninglocker/xapi-service works
Purpose and runtime entry points
This TypeScript/Node.js service implements an xAPI Learning Record Store API. It exposes four API domains: Statements, Agent Profiles, Activity Profiles, and State. The process is started through src/server.ts; application composition is centered in src/apps/app.ts, with domain Express apps in src/apps/statements/app.ts, src/apps/agents/app.ts, src/apps/activities/app.ts, and src/apps/states/app.ts. src/conformanceServer.ts appears to provide a separate conformance-oriented server entry point.
HTTP presentation boundary
Each domain has an Express presenter that parses xAPI HTTP requests, validates protocol headers/content types, invokes services, and maps domain errors to HTTP responses. Statements support GET/POST/PUT, multipart statement/attachment handling, About, and full-activity routes in src/apps/statements/expressPresenter/index.ts and src/apps/statements/expressPresenter/postStatements/index.ts. Profile/state endpoints use analogous presenters, e.g. src/apps/agents/expressPresenter/index.ts, src/apps/activities/expressPresenter/index.ts, and src/apps/states/expressPresenter/index.ts.
Statement ingestion pipeline
Statement writes follow a staged service pipeline: normalize incoming models, validate statements and signatures, resolve duplicate/voiding/reference rules, persist attachments and statements, derive queryable indexes, update full activities, and emit events. The orchestration is src/apps/statements/service/storeStatements/index.ts; its validation/setup stages live under src/apps/statements/service/storeStatements/preValidationSetup/ and src/apps/statements/service/storeStatements/postValidationSetup/; persistence/reference updates are under src/apps/statements/service/storeStatements/createStatements.ts and src/apps/statements/service/storeStatements/updateReferences/.
Statement query and representation flow
Read services retrieve statements, references, activities, and attachments, then apply xAPI result formatting (canonical or IDs formats) and pagination/multipart response assembly. Key boundaries are src/apps/statements/service/getStatements.ts, src/apps/statements/repo/modelsRepo/getStatements/mongo/index.ts, and src/apps/statements/service/utils/getStatementsResult.ts. The presenter owns request parameter parsing and HTTP/multipart streaming in src/apps/statements/expressPresenter/utils/getStatements/.
Profiles and state domains
Agents and activities each manage profile documents plus externally stored profile content; states manage activity-agent-registration scoped state content. Their services enforce client trust, organization/store isolation, read/write scopes, content semantics, conditional ETag updates where applicable, and patch/overwrite/delete behavior. Representative orchestration paths are src/apps/agents/service/index.ts, src/apps/activities/service/index.ts, and src/apps/states/service/index.ts. These domains share a repeated layered pattern: presenter → service → repository contracts/factories → Mongo metadata and blob storage.
Repository abstraction and infrastructure
Factories decouple domain logic from backing providers. Statements compose auth, Mongo models, attachments storage, and event repositories via src/apps/statements/repo/factory.ts and src/apps/statements/repo/facade.ts. Profile/state domains expose equivalent contracts and select implementations through paths such as src/apps/agents/repo/factory.ts, src/apps/activities/repoFactory/index.ts, and src/apps/states/repo/factory.ts.
MongoDB is the primary metadata/statement store; Redis supports statement event/queue behavior. Attachments and profile/state bodies can use local disk, AWS S3, Google Cloud Storage, or Azure Blob Storage. Statement events can use Redis or AWS SQS, as indicated by src/apps/statements/repo/eventsRepo/emitNewStatements/redis.ts, src/apps/statements/repo/eventsRepo/emitNewStatements/sqs.ts, and src/utils/connectToSQS.ts.
Deployment and operational boundaries
Runtime configuration is centralized in src/config.ts, with logging and telemetry-related modules at src/logger.ts and src/tracker.ts. Local development infrastructure is MongoDB and Redis via docker-compose.yml; production packaging is provided by Dockerfile and PM2 configuration under pm2/xapi.json.
Main entry points: app.ts Application composition · facade.ts Statement repository facade · factory.ts Profile/state repositories · index.ts Statements API
Components 19
Runtime
- Main server
src/server.ts - Conformance server · Separate conformance-oriented runtime.
src/conformanceServer.ts - Application composition
src/apps/app.ts
HTTP domains
- Statements API · Handles statement, About, and full-activity HTTP routes.
src/apps/statements/expressPresenter/index.ts - Agent Profiles API
src/apps/agents/expressPresenter/index.ts - Activity Profiles API
src/apps/activities/expressPresenter/index.ts - State API
src/apps/states/expressPresenter/index.ts
Statements pipeline
- Store statements · Coordinates normalization, validation, persistence, indexing, and events.
src/apps/statements/service/storeStatements/index.ts - Validation and setup · Applies validation, signatures, duplicate, voiding, and reference rules.
- Statement persistence · Creates statements and updates references.
src/apps/statements/service/storeStatements/createStatements.ts - Get statements · Retrieves records and formats xAPI result representations.
src/apps/statements/service/getStatements.ts - Statement repository facade · Composes auth, models, attachments, and event providers.
src/apps/statements/repo/facade.ts
Profiles and state
- Profile services · Agent and activity profiles enforce trust, scope, ETags, and content semantics.
src/apps/agents/service/index.ts - State service · Manages activity-agent-registration scoped state content.
src/apps/states/service/index.ts - Profile/state repositories · Select metadata and content-storage implementations.
src/apps/states/repo/factory.ts
Infrastructure
- MongoDB · Primary statement and document metadata store.
docker-compose.yml - Blob storage · Local disk or cloud storage for attachments and profile/state bodies.
- Statement events · Redis or SQS publication for new statements.
src/apps/statements/repo/eventsRepo/emitNewStatements/redis.ts - Redis · Supports local statement event and queue behavior.
docker-compose.yml
Connections 23
- Main server → Application composition: starts
- Conformance server → Application composition: serves
- Application composition → Statements API: mounts
- Application composition → Agent Profiles API: mounts
- Application composition → Activity Profiles API: mounts
- Application composition → State API: mounts
- Statements API → Store statements: writes
- Statements API → Get statements: reads
- Store statements → Validation and setup: validates
- Validation and setup → Statement persistence: authorizes write
- Statement persistence → Statement repository facade: persists through
- Get statements → Statement repository facade: queries through
- Statement repository facade → MongoDB: stores statements and indexes
- Statement repository facade → Blob storage: stores attachments
- Statement repository facade → Statement events: emits new statements
- Statement events → Redis: Redis option
- Agent Profiles API → Profile services: invokes
- Activity Profiles API → Profile services: invokes
- State API → State service: invokes
- Profile services → Profile/state repositories: uses
- State service → Profile/state repositories: uses
- Profile/state repositories → MongoDB: stores metadata
- Profile/state repositories → Blob storage: stores bodies