type User = {
    name: String,
    email: String,
}

let v1_user = Schema.versioned("User", 1, { name: "Alice" })

let v1_version = Schema.getVersion(v1_user)

let v2_user = Schema.migrate(v1_user, 2)

let v2_version = Schema.getVersion(v2_user)

let config1 = Schema.versioned("Config", 1, "debug")

let config2 = Schema.versioned("Config", 2, "release")

let c1 = Schema.getVersion(config1)

let c2 = Schema.getVersion(config2)

let upgradedConfig = Schema.migrate(config1, 2)

let upgradedConfigVersion = Schema.getVersion(upgradedConfig)

fn createResponseV1(data: String): { version: Int, payload: String } = { version: 1, payload: data }

fn createResponseV2(data: String, timestamp: Int): { version: Int, payload: String, meta: { ts: Int } } = { version: 2, payload: data, meta: { ts: timestamp } }

fn getPayload(response: { version: Int, payload: String }): String = response.payload

let resp1 = createResponseV1("Hello")

let resp2 = createResponseV2("World", 1234567890)

let payload1 = getPayload(resp1)

let payload2 = resp2.payload

fn main(): Unit with {Console} = {
    Console.print("=== Schema Evolution Demo ===")
    Console.print("")
    Console.print("Part 1: Type-declared migrations")
    Console.print("  User before migration: v" + toString(v1_version))
    Console.print("  User after migration: v" + toString(v2_version))
    Console.print("")
    Console.print("Part 2: Runtime schema operations")
    Console.print("  Config v1 version: " + toString(c1))
    Console.print("  Config v2 version: " + toString(c2))
    Console.print("  After upgrade: " + toString(upgradedConfigVersion))
    Console.print("")
    Console.print("Part 3: API versioning")
    Console.print("  Response v1 payload: " + payload1)
    Console.print("  Response v2 payload: " + payload2)
}

let output = run main() with {}
