# Migration System Quick Reference ## TL;DR **Default**: Migrations sind forward-only (nur `up()` Methode). **Optional**: Implementiere `SafelyReversible` nur wenn Rollback OHNE Datenverlust möglich ist. ## Quick Decision Tree ``` Is rollback safe (no data loss)? │ ├─ YES (e.g., create table, add nullable column, create index) │ └─ Implement: Migration, SafelyReversible │ └─ NO (e.g., drop column, transform data, delete data) └─ Implement: Migration only ``` ## Code Templates ### Forward-Only Migration (Default) ```php use App\Framework\Database\Migration\Migration; use App\Framework\Database\Migration\MigrationVersion; use App\Framework\Database\ConnectionInterface; use App\Framework\Database\Schema\Schema; final readonly class YourMigration implements Migration { public function up(ConnectionInterface $connection): void { $schema = new Schema($connection); // Your migration logic $schema->execute(); } public function getVersion(): MigrationVersion { return MigrationVersion::fromTimestamp("2024_12_20_100000"); } public function getDescription(): string { return 'Description of what this migration does'; } public function getDomain(): string { return "YourDomain"; } } ``` ### Safe Rollback Migration ```php use App\Framework\Database\Migration\{Migration, SafelyReversible}; use App\Framework\Database\Migration\MigrationVersion; use App\Framework\Database\ConnectionInterface; use App\Framework\Database\Schema\Schema; /** * This migration is safely reversible because: * - [Explain why rollback is safe, e.g., "Creates new empty table"] */ final readonly class YourSafeMigration implements Migration, SafelyReversible { public function up(ConnectionInterface $connection): void { $schema = new Schema($connection); // Your migration logic $schema->execute(); } public function down(ConnectionInterface $connection): void { $schema = new Schema($connection); // Reverse the changes safely $schema->execute(); } public function getVersion(): MigrationVersion { return MigrationVersion::fromTimestamp("2024_12_20_100000"); } public function getDescription(): string { return 'Description of what this migration does'; } public function getDomain(): string { return "YourDomain"; } } ``` ## Common Operations ### Create Migration ```bash php console.php make:migration CreateYourTable ``` ### Run Migrations ```bash php console.php db:migrate ``` ### Rollback (Only SafelyReversible) ```bash # Rollback last migration php console.php db:rollback # Rollback last 3 migrations php console.php db:rollback 3 ``` ### Check Status ```bash php console.php db:status ``` ## Safe vs Unsafe Cheatsheet | Operation | Safe? | Implements | |-----------|-------|------------| | Create table | ✅ | Migration, SafelyReversible | | Drop table (empty) | ✅ | Migration, SafelyReversible | | Drop table (with data) | ❌ | Migration only | | Add nullable column | ✅ | Migration, SafelyReversible | | Add NOT NULL column (with default) | ⚠️ | Case by case | | Drop column (empty) | ✅ | Migration, SafelyReversible | | Drop column (with data) | ❌ | Migration only | | Rename column | ✅ | Migration, SafelyReversible | | Change column type | ❌ | Migration only | | Create index | ✅ | Migration, SafelyReversible | | Drop index | ✅ | Migration, SafelyReversible | | Add foreign key | ✅ | Migration, SafelyReversible | | Drop foreign key | ✅ | Migration, SafelyReversible | | Transform data | ❌ | Migration only | | Delete data | ❌ | Migration only | | Merge tables | ❌ | Migration only | ## Error Handling ### Rollback Failed (Not SafelyReversible) ```bash ❌ Rollback failed: Migration 2024_12_20_100000 does not support safe rollback 💡 Recommendation: Create a new forward migration to undo the changes instead: php console.php make:migration FixYourChanges ``` ### What to do: 1. Create new forward migration 2. Implement reverse logic in `up()` method 3. Run `php console.php db:migrate` ## Testing Rollback ```bash # Test cycle in development php console.php db:migrate php console.php db:rollback 1 php console.php db:migrate # Should succeed again ``` ## Best Practices 1. ✅ **Document why safe**: Always comment why a migration is SafelyReversible 2. ✅ **Test rollback cycle**: Test `up() → down() → up()` in development 3. ✅ **Default to forward-only**: Only add SafelyReversible if certain 4. ❌ **Never rollback in production**: Even "safe" rollbacks should be avoided 5. ✅ **Use fix-forward**: Prefer new migrations over rollback 6. ✅ **Backup before rollback**: Always backup database before rolling back 7. ✅ **Check for data**: Verify column is empty before making it SafelyReversible ## Links - **Full Examples**: `docs/claude/examples/migrations/SafeVsUnsafeMigrations.md` - **Database Patterns**: `docs/claude/database-patterns.md` - **Migration Interface**: `src/Framework/Database/Migration/Migration.php` - **SafelyReversible Interface**: `src/Framework/Database/Migration/SafelyReversible.php` ## Framework Compliance ✅ Readonly classes: `final readonly class` ✅ Composition over inheritance: Interface-based ✅ Explicit contracts: `SafelyReversible` is opt-in ✅ Type safety: Strong typing throughout ✅ No primitive obsession: Uses Value Objects (MigrationVersion)