aios-core
Version:
Synkra AIOS: AI-Orchestrated System for Full Stack Development - Core Framework
740 lines (532 loc) • 16.4 kB
Markdown
# Task: Rollback Database
**Purpose**: Restore database to previous snapshot or run rollback script
**Elicit**: true
## Execution Modes
**Choose your execution mode:**
### 1. YOLO Mode - Fast, Autonomous (0-1 prompts)
- Autonomous decision making with logging
- Minimal user interaction
- **Best for:** Simple, deterministic tasks
### 2. Interactive Mode - Balanced, Educational (5-10 prompts) **[DEFAULT]**
- Explicit decision checkpoints
- Educational explanations
- **Best for:** Learning, complex decisions
### 3. Pre-Flight Planning - Comprehensive Upfront Planning
- Task analysis phase (identify all ambiguities)
- Zero ambiguity execution
- **Best for:** Ambiguous requirements, critical work
**Parameter:** `mode` (optional, default: `interactive`)
## Task Definition (AIOS Task Format V1.0)
```yaml
task: dbRollback()
responsável: Dara (Sage)
responsavel_type: Agente
atomic_layer: Organism
**Entrada:**
- campo: query
tipo: string
origem: User Input
obrigatório: true
validação: Valid SQL query
- campo: params
tipo: object
origem: User Input
obrigatório: false
validação: Query parameters
- campo: connection
tipo: object
origem: config
obrigatório: true
validação: Valid PostgreSQL connection via Supabase
**Saída:**
- campo: query_result
tipo: array
destino: Memory
persistido: false
- campo: records_affected
tipo: number
destino: Return value
persistido: false
- campo: execution_time
tipo: number
destino: Memory
persistido: false
```
## Pre-Conditions
**Purpose:** Validate prerequisites BEFORE task execution (blocking)
**Checklist:**
```yaml
pre-conditions:
- [ ] Database connection established; query syntax valid
tipo: pre-condition
blocker: true
validação: |
Check database connection established; query syntax valid
error_message: "Pre-condition failed: Database connection established; query syntax valid"
```
## Post-Conditions
**Purpose:** Validate execution success AFTER task completes
**Checklist:**
```yaml
post-conditions:
- [ ] Query executed; results returned; transaction committed
tipo: post-condition
blocker: true
validação: |
Verify query executed; results returned; transaction committed
error_message: "Post-condition failed: Query executed; results returned; transaction committed"
```
## Acceptance Criteria
**Purpose:** Definitive pass/fail criteria for task completion
**Checklist:**
```yaml
acceptance-criteria:
- [ ] Data persisted correctly; constraints respected; no orphaned data
tipo: acceptance-criterion
blocker: true
validação: |
Assert data persisted correctly; constraints respected; no orphaned data
error_message: "Acceptance criterion not met: Data persisted correctly; constraints respected; no orphaned data"
```
## Tools
**External/shared resources used by this task:**
- **Tool:** supabase
- **Purpose:** PostgreSQL database connection via Supabase client
- **Source:** @supabase/supabase-js
- **Tool:** query-validator
- **Purpose:** SQL query syntax validation
- **Source:** .aios-core/utils/db-query-validator.js
## Scripts
**Agent-specific code for this task:**
- **Script:** db-query.js
- **Purpose:** Execute PostgreSQL queries with error handling via Supabase
- **Language:** JavaScript
- **Location:** .aios-core/scripts/db-query.js
## Error Handling
**Strategy:** abort
**Common Errors:**
1. **Error:** Connection Failed
- **Cause:** Unable to connect to Neo4j database
- **Resolution:** Check connection string, credentials, network
- **Recovery:** Retry with exponential backoff (max 3 attempts)
2. **Error:** Query Syntax Error
- **Cause:** Invalid Cypher query syntax
- **Resolution:** Validate query syntax before execution
- **Recovery:** Return detailed syntax error, suggest fix
3. **Error:** Transaction Rollback
- **Cause:** Query violates constraints or timeout
- **Resolution:** Review query logic and constraints
- **Recovery:** Automatic rollback, preserve data integrity
## Performance
**Expected Metrics:**
```yaml
duration_expected: 5-15 min (estimated)
cost_estimated: $0.003-0.010
token_usage: ~3,000-10,000 tokens
```
**Optimization Notes:**
- Break into smaller workflows; implement checkpointing; use async processing where possible
## Metadata
```yaml
story: N/A
version: 1.0.0
dependencies:
- N/A
tags:
- database
- infrastructure
updated_at: 2025-11-17
```
## Inputs
- `target` (string): Path to snapshot file or rollback script
## Process
### 1. Confirm Rollback
**CRITICAL WARNING**: Display to user before proceeding
```
⚠️ DATABASE ROLLBACK WARNING ⚠️
You are about to restore the database to a previous state.
Target: {target}
This will:
✓ Drop and recreate all schema objects
✓ Preserve existing data (if schema-only snapshot)
✗ Lose any schema changes made after snapshot
✗ Potentially break application if schema incompatible
Are you ABSOLUTELY SURE you want to proceed?
```
Ask user to type: `ROLLBACK` to confirm
### 2. Pre-Rollback Safety Checks
```bash
# Create emergency snapshot before rollback
echo "Creating emergency snapshot before rollback..."
TS=$(date +%Y%m%d_%H%M%S)
EMERGENCY="supabase/snapshots/${TS}_emergency_before_rollback.sql"
pg_dump "$SUPABASE_DB_URL" \
--schema-only \
--clean \
--if-exists \
> "$EMERGENCY"
if [ $? -eq 0 ]; then
echo "✓ Emergency snapshot: $EMERGENCY"
else
echo "❌ Emergency snapshot failed - ABORTING ROLLBACK"
exit 1
fi
```
### 3. Validate Rollback Target
```bash
TARGET="{target}"
# Check file exists
if [ ! -f "$TARGET" ]; then
echo "❌ Rollback target not found: $TARGET"
exit 1
fi
# Check file is valid SQL
if ! grep -q "CREATE\|DROP\|ALTER" "$TARGET"; then
echo "❌ File doesn't appear to be valid SQL"
exit 1
fi
echo "✓ Rollback target validated: $TARGET"
echo " File size: $(ls -lh "$TARGET" | awk '{print $5}')"
echo " Modified: $(ls -lh "$TARGET" | awk '{print $6, $7, $8}')"
```
### 4. Acquire Exclusive Lock
Prevent concurrent operations:
```bash
echo "Acquiring exclusive lock..."
psql "$SUPABASE_DB_URL" -v ON_ERROR_STOP=1 -c \
"SELECT pg_try_advisory_lock(hashtext('dbsage:rollback')) AS got" \
| grep -q t || { echo "❌ Another operation is running"; exit 1; }
echo "✓ Lock acquired"
```
### 5. Execute Rollback
```bash
echo ""
echo "=== EXECUTING ROLLBACK ==="
echo "Started: $(date -Iseconds)"
echo ""
# Run rollback in single transaction
psql "$SUPABASE_DB_URL" -v ON_ERROR_STOP=1 -f "$TARGET"
RESULT=$?
echo ""
echo "Completed: $(date -Iseconds)"
echo ""
if [ $RESULT -eq 0 ]; then
echo "✅ ROLLBACK SUCCESSFUL"
else
echo "❌ ROLLBACK FAILED"
echo "Emergency snapshot available: $EMERGENCY"
echo "Attempting to restore from emergency snapshot..."
# Try to restore emergency snapshot
psql "$SUPABASE_DB_URL" -v ON_ERROR_STOP=1 -f "$EMERGENCY"
if [ $? -eq 0 ]; then
echo "✓ Restored from emergency snapshot"
else
echo "❌ Emergency restore also failed - DATABASE MAY BE INCONSISTENT"
echo "Manual intervention required"
fi
exit 1
fi
```
### 6. Post-Rollback Validation
```bash
echo ""
echo "=== POST-ROLLBACK VALIDATION ==="
echo ""
# Count schema objects
echo "Schema object counts:"
psql "$SUPABASE_DB_URL" -t -c \
"SELECT
(SELECT COUNT(*) FROM pg_tables WHERE schemaname='public') AS tables,
(SELECT COUNT(*) FROM pg_policies WHERE schemaname='public') AS policies,
(SELECT COUNT(*) FROM pg_proc WHERE pronamespace='public'::regnamespace) AS functions;"
# Check for basic sanity
echo ""
echo "Quick sanity checks:"
psql "$SUPABASE_DB_URL" -v ON_ERROR_STOP=1 <<'SQL'
-- Check tables exist
SELECT 'Tables exist' AS check, COUNT(*) > 0 AS pass
FROM pg_tables WHERE schemaname='public';
-- Check functions exist
SELECT 'Functions exist' AS check, COUNT(*) > 0 AS pass
FROM pg_proc WHERE pronamespace='public'::regnamespace;
-- Check for orphaned objects (optional)
-- SELECT 'No orphaned triggers' AS check, COUNT(*) = 0 AS pass
-- FROM pg_trigger WHERE tgrelid NOT IN (SELECT oid FROM pg_class);
SQL
```
### 7. Release Lock & Create Post-Rollback Snapshot
```bash
# Release lock
psql "$SUPABASE_DB_URL" -v ON_ERROR_STOP=1 -c \
"SELECT pg_advisory_unlock(hashtext('dbsage:rollback'));"
echo "✓ Lock released"
# Create post-rollback snapshot
POST_SNAPSHOT="supabase/snapshots/${TS}_post_rollback.sql"
pg_dump "$SUPABASE_DB_URL" --schema-only --clean --if-exists > "$POST_SNAPSHOT"
echo "✓ Post-rollback snapshot: $POST_SNAPSHOT"
```
### 8. Report Results
```
✅ DATABASE ROLLBACK COMPLETED
Rolled back to: {target}
Timestamp: {TS}
Snapshots created:
- Emergency (before): $EMERGENCY
- Post-rollback (after): $POST_SNAPSHOT
Next steps:
1. *smoke-test - Validate schema
2. *rls-audit - Check security
3. Test application functionality
4. Monitor for issues
If issues detected:
*rollback $EMERGENCY # Restore to pre-rollback state
```
## Rollback Strategies
### Strategy 1: Snapshot Restore (Recommended)
**Use when**: Reverting schema changes
```bash
*rollback supabase/snapshots/20251026_pre_migration.sql
```
**Pros**:
- ✅ Fast
- ✅ Complete schema state
- ✅ Tested with pg_dump
**Cons**:
- ❌ Data preserved (may be incompatible)
- ❌ Requires prior snapshot
### Strategy 2: Explicit Rollback Script
**Use when**: Surgical changes to specific objects
```sql
-- supabase/rollback/20251026_rollback_user_roles.sql
BEGIN;
-- Undo changes in reverse order
DROP TRIGGER IF EXISTS set_user_role_timestamp ON user_roles;
DROP FUNCTION IF EXISTS update_user_role_timestamp();
DROP TABLE IF EXISTS user_roles;
-- Restore previous state if needed
-- ...
COMMIT;
```
```bash
*rollback supabase/rollback/20251026_rollback_user_roles.sql
```
**Pros**:
- ✅ Precise control
- ✅ Documented undo process
- ✅ Can be tested
**Cons**:
- ❌ Must write manually
- ❌ Easy to forget steps
- ❌ Must maintain with migration
### Strategy 3: Forward Fix
**Use when**: Rollback is dangerous, fix forward instead
```sql
-- Instead of rolling back, apply corrective migration
-- migration: 20251026_fix_user_roles_bug.sql
```
**Pros**:
- ✅ No data loss risk
- ✅ Maintains history
- ✅ Safe in production
**Cons**:
- ❌ More work
- ❌ Leaves intermediate state in history
## Rollback Decision Matrix
| Situation | Strategy | Command |
|-----------|----------|---------|
| Migration failed mid-way | Restore snapshot | `*rollback snapshot_before.sql` |
| Schema breaks app | Restore snapshot | `*rollback snapshot_before.sql` |
| Wrong migration applied | Restore snapshot | `*rollback snapshot_before.sql` |
| Minor bug in function | Forward fix | Create fix migration |
| Data corruption risk | Forward fix | Don't rollback |
| Production with users | Forward fix | Avoid schema rollback |
## Safety Checklist
Before executing rollback:
- [ ] Emergency snapshot created automatically ✓
- [ ] Application stopped or in maintenance mode
- [ ] Users notified of downtime
- [ ] Team aware of rollback operation
- [ ] Rollback target validated
- [ ] Exclusive lock acquired
- [ ] Post-rollback test plan ready
## Rollback in Different Environments
### Development
```bash
# Fast and loose - just do it
*rollback snapshot.sql
```
### Staging
```bash
# Test the rollback process
*rollback snapshot.sql
*smoke-test
# Test app functionality
```
### Production
```bash
# CAREFUL - follow full checklist
# 1. Notify stakeholders
# 2. Enable maintenance mode
# 3. Create emergency snapshot (automatic)
# 4. Coordinate with team
*rollback snapshot.sql
# 5. Validation
*smoke-test
*rls-audit
# 6. Test critical flows
# 7. Disable maintenance mode
# 8. Monitor closely
```
## Common Rollback Scenarios
### Scenario 1: Migration Failed During Apply
**Situation**: `*apply-migration` failed halfway
**Action**: PostgreSQL already rolled back transaction ✓
**No rollback needed**: Database unchanged
**Next steps**:
1. Fix migration file
2. `*dry-run` to test
3. `*apply-migration` again
### Scenario 2: Migration Succeeded but Breaks App
**Situation**: Schema change incompatible with application
**Action**: Rollback to pre-migration snapshot
```bash
*rollback supabase/snapshots/20251026_143022_pre_migration.sql
*smoke-test
# Deploy previous app version or fix app
```
### Scenario 3: Wrong Migration Applied
**Situation**: Applied v1.3.0 migration instead of v1.2.5
**Action**: Rollback to last known good state
```bash
*rollback supabase/snapshots/20251026_120000_v1_2_4.sql
*smoke-test
# Apply correct migration
*apply-migration v1_2_5.sql
```
### Scenario 4: Data Corruption After Migration
**Situation**: Schema change caused data integrity issues
**Action**: DON'T rollback schema - fix data
```sql
-- Forward fix with data correction
BEGIN;
-- Fix data
UPDATE users SET status = 'active' WHERE status IS NULL;
-- Add constraint to prevent recurrence
ALTER TABLE users ADD CONSTRAINT status_not_null CHECK (status IS NOT NULL);
COMMIT;
```
## Troubleshooting
### "Rollback failed: relation already exists"
**Problem**: Objects from new schema still exist
**Fix**: Snapshot should have `DROP ... IF EXISTS` statements
Check snapshot file:
```bash
grep -c "DROP.*IF EXISTS" snapshot.sql
```
If missing, regenerate snapshot with `--clean --if-exists` flags.
### "Rollback succeeded but app still broken"
**Problem**: Application incompatible with rolled-back schema
**Solutions**:
1. Deploy previous app version
2. Fix app code to work with old schema
3. Roll forward with new migration instead
### "Emergency snapshot failed during rollback"
**Problem**: Cannot create safety snapshot
**Action**: ABORT ROLLBACK
```
❌ ROLLBACK ABORTED
Cannot proceed without emergency snapshot
Check database connectivity and disk space
```
### "Rollback created orphaned objects"
**Problem**: Some objects not cleaned up
**Fix**: Manually identify and remove
```sql
-- Find orphaned triggers
SELECT tgname FROM pg_trigger
WHERE tgrelid NOT IN (SELECT oid FROM pg_class);
-- Find orphaned indexes
SELECT indexname FROM pg_indexes
WHERE tablename NOT IN (SELECT tablename FROM pg_tables);
```
## Best Practices
### DO
- ✅ Always snapshot before rollback (automatic)
- ✅ Test rollback in staging first
- ✅ Coordinate with team
- ✅ Have post-rollback test plan
- ✅ Monitor application after rollback
- ✅ Document why rollback was needed
### DON'T
- ❌ Rollback in production without coordination
- ❌ Rollback without emergency snapshot
- ❌ Rollback when forward fix is safer
- ❌ Rollback if data corruption risk
- ❌ Rollback during peak usage times
- ❌ Rollback without understanding impact
## Zero-Downtime Alternatives
Instead of rollback, consider:
### Blue-Green Deployment
- Keep old schema running
- Deploy new app + schema separately
- Switch traffic when ready
- Rollback = switch back
### Feature Flags
- Deploy schema changes
- Keep old code paths active
- Toggle features via flags
- Rollback = flip flag
### Backward Compatible Migrations
- Add new columns as nullable
- Keep old columns temporarily
- Remove old columns in later migration
- Rollback = just remove new columns
## Rollback Metrics
Track these after rollback:
- **Rollback duration**: How long did it take?
- **Downtime**: How long was app unavailable?
- **Data loss**: Any data lost? (should be none)
- **Schema object count**: Before vs after
- **Application errors**: Any post-rollback issues?
- **Recovery time**: Time to full functionality
```bash
# Log rollback event
echo "$(date -Iseconds) | ROLLBACK | $TARGET | Duration: ${DURATION}s" \
>> supabase/rollback/rollback.log
```
## Related Commands
- `*snapshot {label}` - Create rollback point
- `*apply-migration {path}` - Creates automatic snapshots
- `*smoke-test` - Validate after rollback
- `*rls-audit` - Check security after rollback
## Emergency Contacts
If rollback fails critically:
1. **Check emergency snapshot**: `$EMERGENCY`
2. **Review Supabase dashboard**: Check for locks/issues
3. **Contact team**: Get help immediately
4. **Document state**: Save logs and error messages
5. **Consider Supabase restore**: Point-in-time recovery
**Never panic**: Emergency snapshot has your back.