ARCHIVED from builddistributedsystem.com on 2026-04-28 — URL: https://builddistributedsystem.com/tracks/reactor/tasks/task-27-1-3-event-versioning
TASK

Implementation

Event schemas change over time as requirements evolve. A field gets added, renamed, or split. Because old events are immutable, you cannot change them in place — instead you upcast them: transform older versions to the current schema on read.

Implement a node that handles event schema migration through upcasting:

// Upcast a single event from v1 to v2
// v1 UserCreated has: id, name
// v2 UserCreated adds: email (default "")
{ "type": "upcast", "msg_id": 1,
  "event": {"event_type": "UserCreated", "version": 1,
            "event_data": {"id": 1, "name": "John"}},
  "target_version": 2 }
-> { "type": "upcasted", "in_reply_to": 1,
    "event": {"event_type": "UserCreated", "version": 2,
              "event_data": {"id": 1, "name": "John", "email": ""}} }

// Migrate a batch of events to the target version
{ "type": "migrate_batch", "msg_id": 2,
  "events": [
    {"event_type": "UserCreated", "version": 1, "event_data": {"id": 1}}
  ],
  "target_version": 2 }
-> { "type": "migrated", "in_reply_to": 2,
    "count": 1, "target_version": 2 }

Your upcaster must handle multi-step migration (e.g. v1 -> v2 -> v3) by chaining single-version upgrades. Each step adds or defaults the fields introduced in that version.

Sample Test Cases

Upcast event to new versionTimeout: 5000ms
Input
{
  "src": "migrator",
  "dest": "eventstore",
  "body": {
    "type": "upcast",
    "msg_id": 1,
    "event": {
      "event_type": "UserCreated",
      "version": 1,
      "event_data": {
        "id": 1,
        "name": "John"
      }
    },
    "target_version": 2
  }
}
Expected Output
{"type": "upcasted", "in_reply_to": 1, "event": {"event_type": "UserCreated", "version": 2, "event_data": {"id": 1, "name": "John", "email": ""}}}
Migrate batch of eventsTimeout: 5000ms
Input
{
  "src": "migrator",
  "dest": "eventstore",
  "body": {
    "type": "migrate_batch",
    "msg_id": 1,
    "events": [
      {
        "event_type": "UserCreated",
        "version": 1,
        "event_data": {
          "id": 1
        }
      }
    ],
    "target_version": 2
  }
}
Expected Output
{"type": "migrated", "in_reply_to": 1, "count": 1, "target_version": 2}

Hints

Hint 1
Upcasting transforms an old event version to the target version in-place
Hint 2
When upcasting from v1 to v2, fill missing fields with sensible defaults (empty string, 0, etc.)
Hint 3
migrate_batch iterates over the events array and upcasts each one
Hint 4
count in the migrate_batch response is the total number of events processed
Hint 5
Events already at the target version should be returned unchanged
OVERVIEW

Theoretical Hub

Concept overview coming soon

Key Concepts

event versioningschema evolutionupcastingbackward compatibilitymigration
main.py
python
Implement Event Versioning and Migration - The Reactor | Build Distributed Systems