Evaluating Schema Evolution Strategies
An additive-only approach is insufficient for complex permission refactoring. While additive changes (adding new relationship types or permissions) ensure that older application versions can still function, they cannot handle the removal of obsolete logic or the renaming of relationship types without leaving the system in an inconsistent state.
For destructive changes, a multi-phase migration is required to maintain rollback safety. Because removing a relationship type from the schema does not purge the underlying tuples, a rollback to a previous schema version will simply make those existing tuples "visible" and active again, potentially triggering legacy permission logic that the application no longer intends to support.
Recommended Multi-Phase Migration Workflow
To safely transition schema states while allowing for code rollbacks, follow these phases:
- Additive Phase: Introduce the new relationship types or permissions to the schema. Update the application to write to both the old and new relationships (dual-writing) but continue reading from the old ones.
- Transition Phase: Update the application to read from the new relationship types. Maintain dual-writing to ensure that a code rollback to the previous version still finds current data in the old relationship types.
- Cleanup Phase: Once the new version is verified as stable, remove the old relationship types from the schema.
Handling Orphaned Tuples During Rollback
If a migration is rolled back after the cleanup phase has begun, the orphaned tuples (data associated with the deleted relationship types) remain in the database. The recommended mechanism for handling this is:
- Schema Re-activation: Re-apply the previous schema definition. Since the tuples were never purged, the permissions are instantly restored to their state prior to the cleanup phase.
- Targeted Purging: If the migration failed due to data corruption in the new relationship types, use a scoped delete command to remove only the tuples created during the migration window before reverting the schema.
Verification and Safety
Before executing a destructive cleanup, verify the state of your tuples using a read-only check to ensure no critical permissions are missing in the new schema:
# Example: Verify existence of new relationship tuples before deleting old ones
zed read --relationship-type=new_permission_type
Missing Diagnostic: Are you utilizing a versioned schema migration tool or applying changes via direct API calls? This determines whether rollback is a simple API request or requires a coordinated state synchronization across environments.