Implements the schema migration system described in #519 — a pure, algebraic migration framework for structural schema evolution in ZIO Schema 2.
Note: This supersedes previous PRs #848 and #872, which are closed.
DynamicMigration — Fully serializable untyped core that operates on DynamicValue. Contains no user functions, closures, or runtime code generation — only pure data.
MigrationAction — Sealed trait ADT with 14 action types, all path-based via DynamicOptic:
AddField, DropField, Rename, TransformValue, Mandate, Optionalize, ChangeTypeJoin, Split — multi-field merge/split operationsRenameCase, TransformCase (with nested migration actions)TransformElements, TransformKeys, TransformValuesDynamicSchemaExpr — Pure data expression language (sealed trait of case objects/classes). No functions or closures. All evaluation logic lives in DynamicMigration.evalExpr(). Includes:
Literal, Identity, DefaultValueMigration[A, B] — Typed wrapper with source/target schemas enabling migration(oldValue) to return Either[MigrationError, B]
MigrationBuilder[A, B] — Fluent DSL builder with string-based, typed optic, nested path, enum, and collection APIs
MigrationError — Path-aware error types for diagnostics
DynamicOptic paths (e.g., root.field("age")) rather than as separate string parametersmandateField("src", "tgt", default) emits Mandate + Rename)DynamicSchemaExpr contains zero logic — all evaluation lives in the migration engine, keeping expressions fully serializableMigration.identity[A].apply(a) == Right(a)(m1 ++ m2) ++ m3 produces the same result as m1 ++ (m2 ++ m3)m.reverse.reverse == mm(a) == Right(b) => m.reverse(b) == Right(a) when sufficient information existsDynamicMigration fully serializable (pure data, no functions/closures)DynamicSchemaExpr pure data expression language with reversibilityMigration[A, B] wraps schemas and actionsDynamicOptic with path-encoded field namesoptic(_.field) macro).build validates target fields are covered.buildPartial supported| File | Purpose |
|---|---|
DynamicMigration.scala |
Untyped migration core with action application and expression evaluation |
DynamicSchemaExpr.scala |
Pure data expression language (sealed trait, no functions) |
MigrationAction.scala |
Sealed trait ADT with 14 action types |
MigrationBuilder.scala |
Fluent DSL builder with string, optic, nested, enum, and collection APIs |
Migration.scala |
Typed wrapper with schema integration |
MigrationError.scala |
Path-aware error types |
MigrationSpec.scala |
136 tests across 19 suites |
Closes #519
/claim #519
Solari Systems
@YourMarx13
marianaguzmanguerrero16-dev
@marianaguzmanguerrero16-dev
ZIO
@ZIO