Skip to main content

Module analytics_schema_registry

Module analytics_schema_registry 

Source
Expand description

Issue #577 — Analytics slice 2: AnalyticsSchemaRegistry. Issue #581 — Analytics slice 3: additive schema evolution + breaking-change rejection.

Owns (event_name, version) → schema_json mappings persisted in red_config, validates payloads at insert time, and exposes the registered set for the red.schema_registry virtual table.

Re-registering an existing event_name is allowed iff the change is additive: new optional fields only (with or without default), widening string maxLength. Anything else — rename, retype, drop, optional→required, brand-new required field — is rejected with a typed SchemaError::BreakingChange { offenders } whose offenders list names every offending field together with the kind of break, so the caller can pick a new event_name rather than smuggle the incompatible change through the same one.

Persistence shape: a single JSON document stored under red.analytics.schema_registry.entries_json as a Text value. It contains an array of entries {event_name, version, schema_json, registered_at_ms}. red_config is append-only, so we read by scanning that collection and keeping the row with the largest engine-assigned EntityId (most recent write) — same trick signed_writes_kind uses.

The schema language is a minimal JSON Schema subset:

{ "type": "object",
  "properties": { "url": { "type": "string" } },
  "required": ["url"] }

Validation rules (v1):

  • payload must parse to a JSON object,
  • every key in required must be present,
  • every key in the payload must appear in properties (unknown field rejected — strict mode),
  • for keys present in both, the type tag must match.

Structs§

SchemaEntry
One registered schema row.

Enums§

BreakingChange
One reason why a candidate schema is not an additive successor of the previous version. Used inside SchemaError::BreakingChange.
SchemaError
ValidationError

Functions§

latest
Return (version, schema_json) for the latest registered schema of event_name, or None if nothing is registered. Since slice 2 only allows version 1 per event, “latest” == “the one row that exists”. Once evolution lands, the resolver will keep the max-version row per event_name.
list
Snapshot every registered schema. Used by the red.schema_registry virtual table.
register
Register a schema for event_name.
validate
Validate payload (a JSON string) against the latest schema registered for event_name. Returns Ok(()) if the payload matches; Err(ValidationError) with a typed reason otherwise.
validation_error_to_reddb
Map a ValidationError onto a [RedDBError] with a marker prefix the transport layer can pattern-match for status codes. The exact HTTP mapping is wired up alongside the broader analytics transport work; here we keep the body shape stable so callers can already parse it.