375 lines
11 KiB
Markdown
375 lines
11 KiB
Markdown
# Tenant Migration Implementation - Complete
|
|
|
|
## ✅ Implementation Summary
|
|
|
|
All tenant migration functionality has been successfully added to the backend. This implementation provides comprehensive tools for managing database schema changes across all tenants in the multi-tenant platform.
|
|
|
|
## 📁 Files Created
|
|
|
|
### Scripts Directory: `/root/neo/backend/scripts/`
|
|
|
|
1. **`migrate-tenant.ts`** (167 lines)
|
|
- Migrates a single tenant by slug or ID
|
|
- Handles password decryption
|
|
- Provides detailed progress output
|
|
- Usage: `npm run migrate:tenant <slug-or-id>`
|
|
|
|
2. **`migrate-all-tenants.ts`** (170 lines)
|
|
- Migrates all active tenants in sequence
|
|
- Collects success/failure statistics
|
|
- Provides comprehensive summary
|
|
- Exits with error code if any tenant fails
|
|
- Usage: `npm run migrate:all-tenants`
|
|
|
|
3. **`check-migration-status.ts`** (181 lines)
|
|
- Checks migration status across all tenants
|
|
- Shows completed and pending migrations
|
|
- Identifies which tenants need updates
|
|
- Usage: `npm run migrate:status`
|
|
|
|
4. **`README.md`** (Comprehensive documentation)
|
|
- Detailed usage instructions
|
|
- Security notes on password encryption
|
|
- Troubleshooting guide
|
|
- Best practices
|
|
- Example workflows
|
|
|
|
### Documentation Files
|
|
|
|
5. **`/root/neo/TENANT_MIGRATION_GUIDE.md`** (Root level guide)
|
|
- Quick start guide
|
|
- Architecture diagrams
|
|
- Complete workflow examples
|
|
- CI/CD integration examples
|
|
- Security documentation
|
|
|
|
### Updated Files
|
|
|
|
6. **`/root/neo/backend/package.json`**
|
|
- Added 6 new migration scripts to the `scripts` section
|
|
|
|
## 🚀 Available Commands
|
|
|
|
| Command | Description |
|
|
|---------|-------------|
|
|
| `npm run migrate:make <name>` | Create a new migration file in `migrations/tenant/` |
|
|
| `npm run migrate:status` | Check migration status for all tenants |
|
|
| `npm run migrate:tenant <slug>` | Run pending migrations for a specific tenant |
|
|
| `npm run migrate:all-tenants` | Run pending migrations for all active tenants |
|
|
| `npm run migrate:latest` | Run migrations on default database (rarely used) |
|
|
| `npm run migrate:rollback` | Rollback last migration on default database |
|
|
|
|
## 🔧 How It Works
|
|
|
|
### Architecture
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────┐
|
|
│ Central Database │
|
|
│ │
|
|
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
|
|
│ │ Tenant │ │ Tenant │ │ Tenant │ │
|
|
│ │ 1 │ │ 2 │ │ N │ │
|
|
│ └──────────┘ └──────────┘ └──────────┘ │
|
|
│ │ │ │ │
|
|
│ │ (encrypted │ │ │
|
|
│ │ password) │ │ │
|
|
└───────┼──────────────┼──────────────┼───────────────────┘
|
|
│ │ │
|
|
▼ ▼ ▼
|
|
┌───────────┐ ┌───────────┐ ┌───────────┐
|
|
│ Tenant │ │ Tenant │ │ Tenant │
|
|
│ DB 1 │ │ DB 2 │ │ DB N │
|
|
│ │ │ │ │ │
|
|
│ Migrations│ │ Migrations│ │ Migrations│
|
|
│ Applied │ │ Applied │ │ Applied │
|
|
└───────────┘ └───────────┘ └───────────┘
|
|
```
|
|
|
|
### Migration Flow
|
|
|
|
1. **Creating a Migration**
|
|
```bash
|
|
npm run migrate:make add_custom_fields
|
|
# Creates: migrations/tenant/20250127123456_add_custom_fields.js
|
|
```
|
|
|
|
2. **Testing on Single Tenant**
|
|
```bash
|
|
npm run migrate:tenant acme-corp
|
|
# Output:
|
|
# 📋 Tenant: Acme Corp (acme-corp)
|
|
# 📊 Database: acme_corp_db
|
|
# 🔄 Running migrations...
|
|
# ✅ Ran 1 migration(s):
|
|
# - 20250127123456_add_custom_fields.js
|
|
```
|
|
|
|
3. **Checking Status**
|
|
```bash
|
|
npm run migrate:status
|
|
# Shows which tenants have pending migrations
|
|
```
|
|
|
|
4. **Applying to All Tenants**
|
|
```bash
|
|
npm run migrate:all-tenants
|
|
# Migrates all active tenants sequentially
|
|
# Provides summary of successes/failures
|
|
```
|
|
|
|
## 🔐 Security Features
|
|
|
|
### Password Encryption
|
|
- Tenant database passwords are encrypted using **AES-256-CBC**
|
|
- Stored encrypted in central database
|
|
- Automatically decrypted during migration
|
|
- Requires `DB_ENCRYPTION_KEY` environment variable
|
|
|
|
### Environment Setup
|
|
```bash
|
|
# Required for migration scripts
|
|
export DB_ENCRYPTION_KEY="your-32-character-secret-key!!"
|
|
```
|
|
|
|
This key must match the key used by `TenantService` for encryption/decryption.
|
|
|
|
## 📋 Example Workflows
|
|
|
|
### Scenario 1: Adding a Field to All Tenants
|
|
|
|
```bash
|
|
# 1. Create migration
|
|
npm run migrate:make add_priority_field
|
|
|
|
# 2. Edit the generated file
|
|
# migrations/tenant/20250127120000_add_priority_field.js
|
|
|
|
# 3. Test on one tenant
|
|
npm run migrate:tenant test-company
|
|
|
|
# 4. Check status
|
|
npm run migrate:status
|
|
|
|
# 5. Apply to all
|
|
npm run migrate:all-tenants
|
|
```
|
|
|
|
### Scenario 2: Checking Migration Status
|
|
|
|
```bash
|
|
npm run migrate:status
|
|
|
|
# Output:
|
|
# 📋 Found 3 active tenant(s)
|
|
#
|
|
# 📦 Acme Corp (acme-corp)
|
|
# Database: acme_corp_db
|
|
# Completed: 5 migration(s)
|
|
# ✅ Up to date
|
|
#
|
|
# 📦 TechStart (techstart)
|
|
# Database: techstart_db
|
|
# Completed: 4 migration(s)
|
|
# ⚠️ Pending: 1 migration(s)
|
|
# - 20250127120000_add_priority_field.js
|
|
#
|
|
# 💡 Run: npm run migrate:all-tenants
|
|
```
|
|
|
|
### Scenario 3: New Tenant Provisioning (Automatic)
|
|
|
|
When a new tenant is created via the API:
|
|
```typescript
|
|
// Happens automatically in TenantProvisioningService
|
|
POST /tenants
|
|
{
|
|
"name": "New Company",
|
|
"slug": "new-company"
|
|
}
|
|
|
|
// Backend automatically:
|
|
// 1. Creates database
|
|
// 2. Runs all migrations
|
|
// 3. Sets tenant status to ACTIVE
|
|
```
|
|
|
|
## 🛠️ Technical Implementation
|
|
|
|
### Script Structure
|
|
|
|
All scripts follow this pattern:
|
|
|
|
1. **Import Dependencies**
|
|
```typescript
|
|
import { PrismaClient as CentralPrismaClient } from '../prisma/generated-central/client';
|
|
import knex, { Knex } from 'knex';
|
|
import { createDecipheriv } from 'crypto';
|
|
```
|
|
|
|
2. **Decrypt Password**
|
|
```typescript
|
|
function decryptPassword(encryptedPassword: string): string {
|
|
// AES-256-CBC decryption
|
|
}
|
|
```
|
|
|
|
3. **Create Tenant Connection**
|
|
```typescript
|
|
function createTenantKnexConnection(tenant: any): Knex {
|
|
const decryptedPassword = decryptPassword(tenant.dbPassword);
|
|
return knex({ /* config */ });
|
|
}
|
|
```
|
|
|
|
4. **Run Migrations**
|
|
```typescript
|
|
const [batchNo, log] = await tenantKnex.migrate.latest();
|
|
```
|
|
|
|
5. **Report Results**
|
|
```typescript
|
|
console.log(`✅ Ran ${log.length} migrations`);
|
|
```
|
|
|
|
## 🧪 Testing the Implementation
|
|
|
|
### 1. Verify Scripts Are Available
|
|
```bash
|
|
cd /root/neo/backend
|
|
npm run | grep migrate
|
|
```
|
|
|
|
Expected output:
|
|
```
|
|
migrate:make
|
|
migrate:latest
|
|
migrate:rollback
|
|
migrate:status
|
|
migrate:tenant
|
|
migrate:all-tenants
|
|
```
|
|
|
|
### 2. Test Creating a Migration
|
|
```bash
|
|
npm run migrate:make test_migration
|
|
```
|
|
|
|
Should create a file in `migrations/tenant/`
|
|
|
|
### 3. Check Status (if tenants exist)
|
|
```bash
|
|
npm run migrate:status
|
|
```
|
|
|
|
### 4. Test Single Tenant Migration (if tenants exist)
|
|
```bash
|
|
npm run migrate:tenant <your-tenant-slug>
|
|
```
|
|
|
|
## 📚 Documentation Locations
|
|
|
|
- **Quick Reference**: `/root/neo/TENANT_MIGRATION_GUIDE.md`
|
|
- **Detailed Scripts Docs**: `/root/neo/backend/scripts/README.md`
|
|
- **Architecture Overview**: `/root/neo/MULTI_TENANT_IMPLEMENTATION.md`
|
|
|
|
## 🎯 Key Features
|
|
|
|
✅ **Single Tenant Migration** - Target specific tenants for testing
|
|
✅ **Bulk Migration** - Update all tenants at once
|
|
✅ **Status Checking** - See which tenants need updates
|
|
✅ **Progress Tracking** - Detailed output for each operation
|
|
✅ **Error Handling** - Graceful failure with detailed error messages
|
|
✅ **Security** - Encrypted password storage and decryption
|
|
✅ **Comprehensive Docs** - Multiple levels of documentation
|
|
|
|
## 🔄 Integration Points
|
|
|
|
### With Existing Code
|
|
|
|
1. **TenantProvisioningService**
|
|
- Already uses `runTenantMigrations()` method
|
|
- New scripts complement automatic provisioning
|
|
- Same migration directory: `migrations/tenant/`
|
|
|
|
2. **Knex Configuration**
|
|
- Uses existing `knexfile.js`
|
|
- Same migration table: `knex_migrations`
|
|
- Compatible with existing migrations
|
|
|
|
3. **Prisma Central Client**
|
|
- Scripts use central DB to fetch tenant list
|
|
- Same encryption/decryption logic as backend services
|
|
|
|
## 🚦 Next Steps
|
|
|
|
### To Use This Implementation:
|
|
|
|
1. **Ensure Environment Variables**
|
|
```bash
|
|
export DB_ENCRYPTION_KEY="your-32-character-secret-key!!"
|
|
```
|
|
|
|
2. **Generate Prisma Client** (if not already done)
|
|
```bash
|
|
cd /root/neo/backend
|
|
npx prisma generate --schema=prisma/schema-central.prisma
|
|
```
|
|
|
|
3. **Check Current Status**
|
|
```bash
|
|
npm run migrate:status
|
|
```
|
|
|
|
4. **Create Your First Migration**
|
|
```bash
|
|
npm run migrate:make add_my_feature
|
|
```
|
|
|
|
5. **Test and Apply**
|
|
```bash
|
|
# Test on one tenant
|
|
npm run migrate:tenant <slug>
|
|
|
|
# Apply to all
|
|
npm run migrate:all-tenants
|
|
```
|
|
|
|
## 📊 Complete File List
|
|
|
|
```
|
|
/root/neo/
|
|
├── TENANT_MIGRATION_GUIDE.md (new)
|
|
└── backend/
|
|
├── package.json (updated - 6 new scripts)
|
|
├── knexfile.js (existing)
|
|
├── migrations/
|
|
│ └── tenant/ (existing)
|
|
│ ├── 20250126000001_create_users_and_rbac.js
|
|
│ ├── 20250126000002_create_object_definitions.js
|
|
│ ├── 20250126000003_create_apps.js
|
|
│ ├── 20250126000004_create_standard_objects.js
|
|
│ └── 20250126000005_add_ui_metadata_to_fields.js
|
|
├── scripts/ (new directory)
|
|
│ ├── README.md (new)
|
|
│ ├── migrate-tenant.ts (new)
|
|
│ ├── migrate-all-tenants.ts (new)
|
|
│ └── check-migration-status.ts (new)
|
|
└── src/
|
|
└── tenant/
|
|
└── tenant-provisioning.service.ts (existing - uses migrations)
|
|
```
|
|
|
|
## ✨ Summary
|
|
|
|
The tenant migration system is now fully implemented with:
|
|
- ✅ 3 TypeScript migration scripts
|
|
- ✅ 6 npm commands
|
|
- ✅ 2 comprehensive documentation files
|
|
- ✅ Full integration with existing architecture
|
|
- ✅ Security features (password encryption)
|
|
- ✅ Error handling and progress reporting
|
|
- ✅ Status checking capabilities
|
|
|
|
You can now manage database migrations across all tenants efficiently and safely! 🎉
|