feat(marketplace): command consolidation + 8 new plugins (v8.1.0 → v9.0.0) [BREAKING]
Phase 1b: Rename all ~94 commands across 12 plugins to /<noun> <action> sub-command pattern. Git-flow consolidated from 8→5 commands (commit variants absorbed into --push/--merge/--sync flags). Dispatch files, name: frontmatter, and cross-reference updates for all plugins. Phase 2: Design documents for 8 new plugins in docs/designs/. Phase 3: Scaffold 8 new plugins — saas-api-platform, saas-db-migrate, saas-react-platform, saas-test-pilot, data-seed, ops-release-manager, ops-deploy-pipeline, debug-mcp. Each with plugin.json, commands, agents, skills, README, and claude-md-integration. Marketplace grows from 12→20. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
157
plugins/saas-db-migrate/skills/rollback-patterns.md
Normal file
157
plugins/saas-db-migrate/skills/rollback-patterns.md
Normal file
@@ -0,0 +1,157 @@
|
||||
---
|
||||
name: rollback-patterns
|
||||
description: Standard rollback generation patterns, reverse operations, and data backup strategies
|
||||
---
|
||||
|
||||
# Rollback Patterns
|
||||
|
||||
## Purpose
|
||||
|
||||
Defines patterns for generating safe rollback migrations. This skill is loaded by the `migration-planner` agent when generating migrations (to include downgrade sections) and when creating explicit rollback plans.
|
||||
|
||||
---
|
||||
|
||||
## Reverse Operation Map
|
||||
|
||||
| Forward Operation | Reverse Operation | Data Preserved |
|
||||
|-------------------|-------------------|----------------|
|
||||
| CREATE TABLE | DROP TABLE | No (all data lost) |
|
||||
| DROP TABLE | CREATE TABLE (empty) | No (must restore from backup) |
|
||||
| ADD COLUMN | DROP COLUMN | No (column data lost) |
|
||||
| DROP COLUMN | ADD COLUMN (nullable) | No (must restore from backup) |
|
||||
| RENAME TABLE | RENAME TABLE (back) | Yes |
|
||||
| RENAME COLUMN | RENAME COLUMN (back) | Yes |
|
||||
| ADD INDEX | DROP INDEX | Yes (data unaffected) |
|
||||
| DROP INDEX | CREATE INDEX | Yes (data unaffected) |
|
||||
| ADD CONSTRAINT | DROP CONSTRAINT | Yes |
|
||||
| DROP CONSTRAINT | ADD CONSTRAINT | Yes (if data still valid) |
|
||||
| ALTER COLUMN TYPE | ALTER COLUMN TYPE (back) | Depends on conversion |
|
||||
| INSERT rows | DELETE matching rows | Yes (if identifiable) |
|
||||
| UPDATE rows | UPDATE with original values | Only if originals saved |
|
||||
| DELETE rows | INSERT saved rows | Only if backed up |
|
||||
|
||||
---
|
||||
|
||||
## Rollback Classification
|
||||
|
||||
### Fully Reversible (Green)
|
||||
|
||||
Operations that can be undone with no data loss:
|
||||
- RENAME operations (table, column)
|
||||
- ADD/DROP INDEX
|
||||
- ADD/DROP CONSTRAINT (when data satisfies constraint)
|
||||
- ADD COLUMN (drop it in rollback)
|
||||
|
||||
### Partially Reversible (Yellow)
|
||||
|
||||
Operations where structure is restored but data is lost:
|
||||
- CREATE TABLE (rollback = DROP TABLE; data lost)
|
||||
- DROP COLUMN (rollback = ADD COLUMN; column data gone)
|
||||
- ALTER COLUMN TYPE narrowing then widening (precision lost)
|
||||
|
||||
### Irreversible (Red)
|
||||
|
||||
Operations that cannot be meaningfully undone:
|
||||
- DROP TABLE without backup (data permanently gone)
|
||||
- TRUNCATE TABLE without backup
|
||||
- DELETE without WHERE without backup
|
||||
- Data transformation that loses information (e.g., hash, round)
|
||||
|
||||
---
|
||||
|
||||
## Backup Strategies
|
||||
|
||||
### Pre-Migration Table Backup
|
||||
|
||||
For migrations that will cause data loss, generate backup commands:
|
||||
|
||||
**PostgreSQL:**
|
||||
```sql
|
||||
-- Full table backup
|
||||
CREATE TABLE _backup_users_20240115 AS SELECT * FROM users;
|
||||
|
||||
-- Column-only backup
|
||||
CREATE TABLE _backup_users_email_20240115 AS
|
||||
SELECT id, legacy_email FROM users;
|
||||
```
|
||||
|
||||
**Export to file:**
|
||||
```bash
|
||||
pg_dump --table=users --column-inserts dbname > users_backup_20240115.sql
|
||||
```
|
||||
|
||||
### Restoration Commands
|
||||
|
||||
Include restoration commands in rollback section:
|
||||
|
||||
```sql
|
||||
-- Restore from backup table
|
||||
INSERT INTO users (id, legacy_email)
|
||||
SELECT id, legacy_email FROM _backup_users_email_20240115;
|
||||
|
||||
-- Clean up backup
|
||||
DROP TABLE IF EXISTS _backup_users_email_20240115;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Alembic Downgrade Patterns
|
||||
|
||||
```python
|
||||
def downgrade():
|
||||
# Reverse of upgrade, in opposite order
|
||||
op.drop_index('ix_orders_user_id', table_name='orders')
|
||||
op.drop_table('orders')
|
||||
```
|
||||
|
||||
For complex downgrades with data restoration:
|
||||
```python
|
||||
def downgrade():
|
||||
# Re-create dropped column
|
||||
op.add_column('users', sa.Column('legacy_email', sa.String(255), nullable=True))
|
||||
# Note: Data cannot be restored automatically
|
||||
# Restore from backup: _backup_users_email_YYYYMMDD
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Prisma Rollback Patterns
|
||||
|
||||
Prisma does not have native downgrade support. Generate a new migration that reverses the operations:
|
||||
|
||||
```sql
|
||||
-- Rollback: undo add_orders_table
|
||||
DROP TABLE IF EXISTS "order_items";
|
||||
DROP TABLE IF EXISTS "orders";
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Raw SQL Rollback Patterns
|
||||
|
||||
Always include DOWN section in migration files:
|
||||
|
||||
```sql
|
||||
-- UP
|
||||
CREATE TABLE orders (
|
||||
id SERIAL PRIMARY KEY,
|
||||
user_id INTEGER REFERENCES users(id),
|
||||
total DECIMAL(10,2) NOT NULL
|
||||
);
|
||||
|
||||
-- DOWN
|
||||
DROP TABLE IF EXISTS orders;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Point-of-No-Return Identification
|
||||
|
||||
Flag migrations that cross the point of no return:
|
||||
|
||||
1. **Data deletion without backup step**: Mark as irreversible
|
||||
2. **Type narrowing that truncates data**: Data is permanently altered
|
||||
3. **Hash/encrypt transformations**: Original values unrecoverable
|
||||
4. **Aggregate/merge operations**: Individual records lost
|
||||
|
||||
When a migration includes irreversible operations, the rollback section must clearly state: "This migration cannot be fully rolled back. Data backup is required before applying."
|
||||
Reference in New Issue
Block a user