Current State
Two Separate Migration Systems
SQL Migrations
- Runs automatically at application startup
- Uses golang-migrate
- Commands:
migratesql up, migratesql down, migratesql force
- No plan/preview capability
- No manual control - just happens on boot
Redis Migrations
- Separate binary:
outpost-migrate-redis
- Must be run manually before deployment
- Requires maintenance window
- Commands:
list, plan, apply, verify, cleanup, unlock
- Full plan/preview capability
The Problem: Two Different Experiences
Different Mental Models
| Aspect |
SQL |
Redis |
| When to run |
"It just happens" |
"I need to run this manually" |
| Visibility |
Hidden in startup logs |
Explicit CLI output |
| Planning |
Can't preview changes |
plan shows exactly what will change |
| Verification |
Hope it worked |
verify confirms success |
| Recovery |
Dig through logs, use force |
Clear unlock command |
Different Commands
# SQL - minimal interface
migratesql up
migratesql down 1
migratesql force 3
# Redis - full interface
outpost-migrate-redis list
outpost-migrate-redis plan
outpost-migrate-redis apply --yes
outpost-migrate-redis verify
outpost-migrate-redis cleanup
outpost-migrate-redis unlock
Different Deployment Workflows
SQL: No action needed - migrations run on app startup
# Just deploy, migrations happen automatically
kubectl apply -f deployment.yaml
Redis: Requires explicit step before deployment
# 1. Run migration job (maintenance window)
kubectl apply -f migration-job.yaml
kubectl wait --for=condition=complete job/outpost-migrate-redis
# 2. Then deploy
kubectl apply -f deployment.yaml
Cognitive Overhead
Users must understand:
- There are two migration systems
- They work differently
- They have different commands
- They require different operational procedures
- One is automatic, one is manual
End Goal
Unified experience:
outpost migrate list # Shows ALL migrations (SQL + Redis)
outpost migrate plan # Shows what WILL change
outpost migrate apply # Applies ALL pending migrations
outpost migrate verify # Verifies success
Explicit control:
- No auto-run at startup
- Application refuses to start if migrations are pending
- User explicitly runs
outpost migrate apply before deployment
Single workflow:
# 1. Run migrations (same command regardless of what's pending)
outpost migrate apply --yes
# 2. Deploy application
outpost serve
Current State
Two Separate Migration Systems
SQL Migrations
migratesql up,migratesql down,migratesql forceRedis Migrations
outpost-migrate-redislist,plan,apply,verify,cleanup,unlockThe Problem: Two Different Experiences
Different Mental Models
planshows exactly what will changeverifyconfirms successforceunlockcommandDifferent Commands
Different Deployment Workflows
SQL: No action needed - migrations run on app startup
Redis: Requires explicit step before deployment
Cognitive Overhead
Users must understand:
End Goal
Unified experience:
Explicit control:
outpost migrate applybefore deploymentSingle workflow: