# 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: ```bash # 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: ```typescript // 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: ```prisma // 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: ```typescript // 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: ```typescript // 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: ```typescript // 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: ```typescript // 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