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

145 lines
3.2 KiB
Markdown

# 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