Skip to main content

Events

:::info Source Sourced from services/analytics-service/EVENT_SCHEMAS.md in the documentation repo. :::

1. Envelope

Standard platform envelope; retentionClass = operational or analytics (custom class: 13 months hot + 5 years cold).

2. Events Published

2.1 analytics.export.completed.v1

interface ExportCompletedV1 { exportJobId: ULID; tenantId: TenantId; requestedBy: UserId; format: string; rowCount: number; outputUrl: string; completedAt: ISODate; }

2.2 analytics.export.failed.v1

interface ExportFailedV1 { exportJobId: ULID; tenantId: TenantId; reason: string; failedAt: ISODate; }

2.3 analytics.alert.triggered.v1

interface AlertTriggeredV1 { alertId: ULID; tenantId: TenantId; metricId: ULID; threshold: number; observed: number; severity: 'info' | 'warning' | 'critical'; triggeredAt: ISODate; confidence?: number; aiProvenance?: AIProvenance; }

2.4 analytics.cohort.evaluated.v1

interface CohortEvaluatedV1 { cohortId: ULID; tenantId: TenantId; memberCount: number; evaluatedAt: ISODate; }

2.5 analytics.report.generated.v1 (US-58)

interface ReportGeneratedV1 {
reportId: ULID;
runId: ULID;
tenantId: TenantId;
requestedBy: UserId;
pdfExportJobId: ULID;
csvExportJobId: ULID;
pdfUrl: string;
csvUrl: string;
generatedAt: ISODate;
aiSummaryBullets: string[];
}

2.6 analytics.insight.generated.v1 (EP-15 US-75 / US-76)

interface InsightGeneratedV1 {
insightId: ULID;
kind: 'at_risk' | 'board_summary';
tenantId: TenantId;
requestedBy: UserId;
generatedAt: ISODate;
orgUnitId?: string | null;
asOf?: string | null;
from?: string | null;
to?: string | null;
region?: string | null;
learnerCount?: number;
}

2.7 analytics.report.rendered.v1 (legacy alias / older drafts)

interface ReportRenderedV1 { reportId: ULID; tenantId: TenantId; outputUrl: string; renderedAt: ISODate; }

2.7 audit.merkle.anchored.v1 (US-106)

Emitted when a daily Merkle anchor row is committed. Payload is JSON (not necessarily ULID-branded ids):

interface AuditMerkleAnchoredV1 {
anchorDate: string; // YYYY-MM-DD (UTC)
rootHash: string;
leafCount: number;
chainPrevHash: string | null;
}

3. Events Consumed (firehose — partial list)

  • identity.*, tenant.*, authoring.*, content.*, catalog.*, marketplace.*, billing.*, enrollment.*, assignment.*, delivery.*, progress.*, assessment.*, certification.*, notification.*, media.*, search.*, ai.*, sync.*.

All events flow into the raw events table via firehose; tenant isolation preserved on Kafka topic and ClickHouse partition.

4. Versioning

Analytics consumers tolerate unknown fields gracefully; new events auto-ingested with schema inference plus registered schema override.

5. Idempotency

  • Raw events table: eventId PK dedups.
  • Materialized views recomputed idempotently.

6. Outbox / Inbox

Standard outbox for analytics-published events.

7. Partition Key

Analytics-internal events: partitionKey = tenantId.

8. DLQ

analytics.dlq. Poison events logged; manual investigation tool.