Skip to content

feat: Schema Migration System for ZIO Blocks#1260

Open
tanishqshah2 wants to merge 3 commits intozio:mainfrom
tanishqshah2:feature/schema-migration-system-519
Open

feat: Schema Migration System for ZIO Blocks#1260
tanishqshah2 wants to merge 3 commits intozio:mainfrom
tanishqshah2:feature/schema-migration-system-519

Conversation

@tanishqshah2
Copy link

@tanishqshah2 tanishqshah2 commented Mar 22, 2026

Demo

Schema Migration System Demo

Closes #519

/claim #519

Summary

Implements a complete, algebraic, serializable Schema Migration System for ZIO Blocks, resolving issue #519.

Architecture

Two-layer design mirroring the existing DynamicPatch / Patch[A] pattern:

DynamicMigration - untyped, pure data, fully serializable

  • actions: Vector[MigrationAction] - a sequence of named operations applied in order
  • apply(DynamicValue): Either[MigrationError, DynamicValue]
  • reverse: DynamicMigration - structural inverse of all actions
  • ++ composition, isEmpty

Migration[A, B] - typed wrapper

  • Converts A to DynamicValue via sourceSchema, applies DynamicMigration, converts back to B via targetSchema
  • reverse: Migration[B, A]
  • ++[C](that: Migration[B, C]): Migration[A, C]

MigrationAction ADT

All actions carry at: DynamicOptic for precise path addressing:

  • AddField(at, default) - Add a field with a default value
  • DropField(at, defaultForReverse) - Remove a field
  • Rename(at, to) - Rename a field
  • TransformValue(at, expr) - Transform a value using a DynamicMigrationExpr
  • Mandate(at, default) - Make optional field mandatory
  • Optionalize(at) - Wrap mandatory field in Some
  • RenameCase(at, from, to) - Rename an enum variant
  • TransformCase(at, caseName, actions) - Apply nested migrations to a variant payload
  • TransformElements(at, expr) - Map over sequence elements
  • TransformKeys(at, expr) - Map over map keys
  • TransformValues(at, expr) - Map over map values

DynamicMigrationExpr

Serializable expression ADT: Identity, Constant, IntToLong/LongToInt, IntToString/StringToInt, LongToString/StringToLong, DoubleToString/StringToDouble, FloatToDouble/DoubleToFloat, BooleanToString/StringToBoolean, ConcatFields, Compose

MigrationBuilder DSL

val migration = Migration.newBuilder[PersonV1, PersonV2]
  .renameField("name", "fullName")
  .addField("country", Schema[String], "Unknown")
  .build

.build validates paths, .buildPartial skips validation

Laws

  • Identity: Migration.identity[A].apply(a) == Right(a)
  • Associativity: (m1 ++ m2) ++ m3 == m1 ++ (m2 ++ m3)
  • Reverse: m.reverse.reverse has structurally equal actions to m

Files Added

  • migration/MigrationError.scala
  • migration/DynamicMigrationExpr.scala
  • migration/MigrationAction.scala
  • migration/DynamicMigration.scala
  • migration/Migration.scala
  • migration/MigrationBuilder.scala
  • migration/DynamicMigrationSpec.scala (tests)
  • migration/MigrationSpec.scala (tests)

Implements a complete, algebraic, serializable schema migration engine
with both untyped (DynamicMigration) and typed (Migration[A,B]) layers.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@CLAassistant
Copy link

CLAassistant commented Mar 22, 2026

CLA assistant check
All committers have signed the CLA.

tanishqshah2 and others added 2 commits March 22, 2026 14:37
…rload, scalafmt

- Remove unused fullPath parameter from navigateOneLevel (Scala 2.13 error)
- Remove unused SchemaError import from Migration.scala
- Remove unused PrimitiveValue import from MigrationBuilder.scala
- Remove duplicate MigrationBuilder.empty overload that caused JVM erasure
  conflict in both Scala 2.13 and Scala 3.x
- Run scalafmt on all migration source and test files

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Migration[PersonV1, PersonV1] with rename cannot round-trip through
fromDynamicValue because the renamed DynamicValue has a different field
name than PersonV1 expects. Test the round-trip at the DynamicMigration
level where schemas are not involved.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Schema Migration System for ZIO Schema 2

2 participants