Events
:::info Source
Sourced from services/enrollment-service/EVENT_SCHEMAS.md in the documentation repo.
:::
1. Envelope
Standard. retentionClass = operational.
2. Published
2.0 EP-6 — Marketplace commerce (Ghasi-EdTech, 2026-04)
These marketplace.* types are written to enrollment-service outbox (same EventEnvelope as other services). IDs are string prefixes (lcn_, enr_, ssa_, ord_).
| Wire type | When |
|---|---|
marketplace.license.granted.v1 | License row created after paid order (all plan kinds). |
enrollment.created.v1 | Learner enrollment row created (buyer or assignee). |
marketplace.license.assigned.v1 | Org admin assigns a seat from a seat-pack license. |
marketplace.license.revoked.v1 | Refund saga revokes license (aggregate). |
enrollment.revoked.v1 | Bulk revoke enrollments for an orderId (refund). |
marketplace.license.granted.v1 (payload)
interface MarketplaceLicenseGrantedV1Payload {
licenseId: string;
orderId: string;
courseId: string;
listingId: string;
buyerUserId: string;
seatTotal?: number;
}
marketplace.license.assigned.v1 (payload)
interface MarketplaceLicenseAssignedV1Payload {
licenseId: string;
assigneeUserId: string;
seatAssignmentId: string;
orderId: string;
}
enrollment.revoked.v1 (payload)
interface EnrollmentRevokedV1PayloadEp6 {
orderId: string;
revokedCount: number;
}
marketplace.license.revoked.v1 (payload)
interface MarketplaceLicenseRevokedV1Payload {
licenseId: string;
orderId: string;
reason: string;
}
(Older doc shape for admin/compliance revoke may still apply for non-commerce paths.)
2.1 enrollment.created.v1
EP-6 commerce payload (subset): enrollmentId, licenseId, orderId, courseId, userId.
interface EnrollmentCreatedV1 { enrollmentId: EnrollmentId; tenantId: TenantId; userId: UserId; courseId: CourseId; courseVersionId: CourseVersionId; source: { kind: string; ref: string }; enrolledAt: ISODate; expiresAt?: ISODate; }
2.2 enrollment.completed.v1
interface EnrollmentCompletedV1 { enrollmentId: EnrollmentId; tenantId: TenantId; userId: UserId; courseId: CourseId; completedAt: ISODate; completionRecordId: string; }
2.3 enrollment.expired.v1
interface EnrollmentExpiredV1 { enrollmentId: EnrollmentId; tenantId: TenantId; userId: UserId; expiredAt: ISODate; }
2.4 enrollment.revoked.v1
interface EnrollmentRevokedV1 { enrollmentId: EnrollmentId; tenantId: TenantId; userId: UserId; reason: 'license_revoked' | 'admin' | 'compliance'; revokedAt: ISODate; }
EP-6 refund path: may emit an aggregate event with orderId + revokedCount (see §2.0).
2.5 enrollment.accessed.v1
interface EnrollmentAccessedV1 { enrollmentId: EnrollmentId; tenantId: TenantId; userId: UserId; accessedAt: ISODate; attemptNumber: number; }
3. Consumed
marketplace.license.granted.v1→ optional consumer path; current EP-6 slice creates enrollments synchronously from billing handoff + also emits this event for downstream analytics.marketplace.license.revoked.v1→ revoke enrollments (future consumer; today revoke is driven by internal HTTP from billing).assignment.window.opened.v1→ deferred enrollment on first play.progress.completion.recorded.v1→ complete enrollment.delivery.play_session.started.v1→ accessed + create if assignment-deferred.gdpr.subject_request.received.v1→ erase user enrollments.
4. Versioning
v1 additive.
5. Idempotency
Inbox dedups. Creation idempotent on (tenantId, userId, courseId, source.ref).
6. Outbox/Inbox
Standard.
7. Partition Key
partitionKey = userId for per-learner ordering.
8. DLQ
enrollment.dlq.