Yaltopia-Tickets-Backend/migration-scenarios.md
debudebuye 98d4bb52c3 Initial commit: Receipt Verification API with universal adapter pattern
- JWT authentication with Supabase integration
- Role-based access control (Admin, Owner, Staff, Auditor)
- Universal database adapter (Prisma/Supabase/MongoDB support)
- User management with hierarchical permissions
- Redis caching service (configured but optional)
- Comprehensive API documentation
- Production-ready NestJS architecture
- Migration scripts for provider switching
- Swagger/OpenAPI documentation
2025-12-21 22:05:22 +03:00

3.2 KiB

Database Migration Scenarios

Scenario 1: PostgreSQL → PostgreSQL (Different Provider)

Examples: Supabase → AWS RDS, Google Cloud SQL, Railway, Neon, PlanetScale

What Changes:

  • Connection string only
  • Keep all Prisma code unchanged
  • Keep all SQL queries unchanged

Migration Steps:

# 1. Update connection string
DATABASE_URL="postgresql://user:pass@new-provider.com:5432/db"

# 2. Run Prisma migration
npx prisma migrate deploy

# 3. Update environment variables
SUPABASE_URL=""  # Remove
SUPABASE_SERVICE_ROLE_KEY=""  # Remove

Code Changes Required:

// Before (Supabase)
const { data } = await this.supabase.from('users').select('*');

// After (Any PostgreSQL + Prisma)
const data = await this.prisma.user.findMany();

Effort: 1-2 days Risk: Very Low


Scenario 2: PostgreSQL → MySQL/MariaDB

Examples: Supabase → AWS RDS MySQL, PlanetScale MySQL

What Changes:

  • ⚠️ Schema syntax differences
  • ⚠️ Data type mappings
  • Prisma handles most differences

Migration Steps:

// Update datasource in schema.prisma
datasource db {
  provider = "mysql"  // Changed from postgresql
  url      = env("DATABASE_URL")
}

// Some field types may need updates
model User {
  id String @id @default(cuid())  // uuid() → cuid() for MySQL
  // ... rest unchanged
}

Effort: 3-5 days Risk: Low-Medium


Scenario 3: PostgreSQL → MongoDB

Examples: Supabase → MongoDB Atlas, AWS DocumentDB

What Changes:

  • Complete schema redesign
  • Relational → Document model
  • All queries need rewriting

Migration Complexity:

// Before (Relational)
const user = await this.prisma.user.findUnique({
  where: { id },
  include: { receipts: true, staff: true }
});

// After (Document)
const user = await this.mongodb.collection('users').findOne({
  _id: ObjectId(id)
});
// Receipts and staff would be embedded documents or separate collections

Effort: 2-4 weeks Risk: High


Scenario 4: Keep Database, Replace Supabase Services

Examples: Keep PostgreSQL, replace Auth/Storage with AWS/Firebase

Service Replacements:

Authentication:

// Before: Supabase Auth
await supabase.auth.signInWithOtp({ email });

// After: AWS Cognito
await cognito.initiateAuth({ email });

// After: Firebase Auth
await firebase.auth().sendSignInLinkToEmail(email);

// After: Auth0
await auth0.passwordlessStart({ email });

File Storage:

// Before: Supabase Storage
await supabase.storage.from('receipts').upload(fileName, file);

// After: AWS S3
await s3.upload({ Bucket: 'receipts', Key: fileName, Body: file });

// After: Google Cloud Storage
await storage.bucket('receipts').file(fileName).save(file);

// After: Cloudinary
await cloudinary.uploader.upload(file, { public_id: fileName });

Real-time:

// Before: Supabase Realtime
supabase.from('users').on('*', callback).subscribe();

// After: Socket.IO
io.on('user_updated', callback);

// After: AWS AppSync
await appSync.subscribe({ subscription: USER_UPDATED });

// After: Pusher
pusher.subscribe('users').bind('updated', callback);

Effort: 1-3 weeks per service Risk: Medium