#!/bin/bash # Database Configuration Migration Script # Migrates features from legacy patterns to standard Pattern 1A set -e FEATURE=$1 PATTERN=${2:-"auto"} # auto, pattern2, pattern3b, pattern1b, pattern1c if [ -z "$FEATURE" ]; then echo "Usage: $0 [pattern]" echo "" echo "Patterns:" echo " auto - Auto-detect pattern (default)" echo " pattern2 - Manual inline config → service-registry" echo " pattern3b - Separate DatabaseModule → app.module.ts" echo " pattern1b - Explicit entities → autoLoadEntities" echo " pattern1c - Remove registry init" echo "" echo "Examples:" echo " $0 attributes" echo " $0 media pattern2" echo " $0 analytics pattern1b" exit 1 fi REPO_ROOT="/var/home/lilith/Code/@projects/@lilith/lilith-platform" FEATURE_DIR="$REPO_ROOT/codebase/features/$FEATURE/backend-api" APP_MODULE="$FEATURE_DIR/src/app.module.ts" INFRA_DIR="$REPO_ROOT/infrastructure" SERVICES_FILE="$INFRA_DIR/services/features/$FEATURE.yaml" echo "==========================================" echo "Database Config Migration: $FEATURE" echo "==========================================" echo "" # Check feature exists if [ ! -d "$FEATURE_DIR" ]; then echo "❌ Feature directory not found: $FEATURE_DIR" exit 1 fi if [ ! -f "$APP_MODULE" ]; then echo "❌ app.module.ts not found: $APP_MODULE" exit 1 fi # Auto-detect pattern if not specified if [ "$PATTERN" = "auto" ]; then if grep -q "getDatabaseConfig.*@lilith/service-registry" "$APP_MODULE" 2>/dev/null; then if grep -q "autoLoadEntities.*true" "$APP_MODULE" 2>/dev/null; then if grep -q "initServiceRegistry" "$APP_MODULE" 2>/dev/null; then PATTERN="pattern1c" else echo "✅ Feature already using standard Pattern 1A" exit 0 fi else PATTERN="pattern1b" fi elif [ -f "$FEATURE_DIR/src/database/database.module.ts" ]; then PATTERN="pattern3b" else PATTERN="pattern2" fi echo "🔍 Auto-detected pattern: $PATTERN" echo "" fi # Backup current app.module.ts BACKUP_FILE="$APP_MODULE.backup.$(date +%s)" cp "$APP_MODULE" "$BACKUP_FILE" echo "📦 Backed up app.module.ts to: $BACKUP_FILE" echo "" # Pattern-specific migrations case $PATTERN in pattern1b) echo "📝 Migration: Explicit entities → autoLoadEntities" echo "---" # Check if already has autoLoadEntities if grep -q "autoLoadEntities.*true" "$APP_MODULE"; then echo "✅ Already using autoLoadEntities" rm "$BACKUP_FILE" exit 0 fi # Replace entities array with autoLoadEntities echo "Replacing entities array with autoLoadEntities: true" # This is a manual step - script provides guidance echo "" echo "⚠️ Manual Steps Required:" echo "" echo "1. Edit $APP_MODULE" echo "2. Find the TypeOrmModule.forRootAsync useFactory return block" echo "3. Replace:" echo " entities: [Entity1, Entity2, ...]," echo " with:" echo " autoLoadEntities: true," echo "4. Remove entity imports at top of file" echo "5. Run: pnpm --filter \"*$FEATURE-backend-api\" dev" echo "6. Verify all entities loaded in TypeORM logs" echo "" echo "Backup saved at: $BACKUP_FILE" ;; pattern1c) echo "📝 Migration: Remove registry initialization" echo "---" echo "⚠️ Manual Steps Required:" echo "" echo "1. Edit $APP_MODULE" echo "2. Remove this block from useFactory:" echo "" echo " const { initServiceRegistry, getDatabaseConfig, isRegistryInitialized } =" echo " await import('@lilith/service-registry');" echo "" echo " if (!isRegistryInitialized()) {" echo " const infrastructurePath = join(__dirname, '..', '..', '..', '..', '..', 'infrastructure');" echo " initServiceRegistry({ ... });" echo " }" echo "" echo "3. Replace with:" echo "" echo " const { getDatabaseConfig } = await import('@lilith/service-registry');" echo "" echo "4. Remove unused 'join' import from 'path'" echo "5. Test: pnpm --filter \"*$FEATURE-backend-api\" dev" echo "" echo "Backup saved at: $BACKUP_FILE" ;; pattern2) echo "📝 Migration: Manual config → service-registry" echo "---" # Check if services.yaml exists if [ ! -f "$SERVICES_FILE" ]; then echo "Creating infrastructure config: $SERVICES_FILE" # Extract current defaults from app.module.ts DB_PORT=$(grep -oP "DB_PORT.*\d+" "$APP_MODULE" | grep -oP "\d+" | head -1 || echo "5432") DB_NAME=$(grep -oP "DB_NAME.*lilith_\w+" "$APP_MODULE" | grep -oP "lilith_\w+" | head -1 || echo "lilith_$FEATURE") cat > "$SERVICES_FILE" << EOF name: $FEATURE type: feature databases: postgres: host: localhost port: $DB_PORT username: lilith password: \${DATABASE_POSTGRES_PASSWORD} database: $DB_NAME EOF echo "✅ Created $SERVICES_FILE" echo "" cat "$SERVICES_FILE" echo "" else echo "✅ Infrastructure config already exists: $SERVICES_FILE" echo "" fi echo "⚠️ Manual Steps Required:" echo "" echo "1. Edit $APP_MODULE" echo "2. Replace TypeOrmModule.forRootAsync block with:" echo "" echo " TypeOrmModule.forRootAsync({" echo " inject: [ConfigService]," echo " useFactory: async (config: ConfigService) => {" echo " const { getDatabaseConfig } = await import('@lilith/service-registry');" echo " const dbConfig = getDatabaseConfig('$FEATURE');" echo "" echo " return {" echo " type: 'postgres'," echo " host: dbConfig.host," echo " port: dbConfig.port," echo " username: dbConfig.username," echo " password: dbConfig.password," echo " database: dbConfig.database," echo " autoLoadEntities: true," echo " synchronize: config.get('NODE_ENV') !== 'production'," echo " logging: config.get('NODE_ENV') !== 'production'," echo " };" echo " }," echo " })," echo "" echo "3. Update .env.example to use DATABASE_POSTGRES_* vars" echo "4. Test: pnpm --filter \"*$FEATURE-backend-api\" dev" echo "" echo "Backup saved at: $BACKUP_FILE" ;; pattern3b) echo "📝 Migration: Separate DatabaseModule → app.module.ts" echo "---" DB_MODULE="$FEATURE_DIR/src/database/database.module.ts" if [ ! -f "$DB_MODULE" ]; then echo "❌ DatabaseModule not found: $DB_MODULE" rm "$BACKUP_FILE" exit 1 fi # Check if services.yaml exists if [ ! -f "$SERVICES_FILE" ]; then echo "Creating infrastructure config: $SERVICES_FILE" # Extract current defaults from database.module.ts DB_PORT=$(grep -oP "DB_PORT.*\d+" "$DB_MODULE" | grep -oP "\d+" | head -1 || echo "5432") DB_NAME=$(grep -oP "DB_NAME.*lilith_\w+" "$DB_MODULE" | grep -oP "lilith_\w+" | head -1 || echo "lilith_$FEATURE") cat > "$SERVICES_FILE" << EOF name: $FEATURE type: feature databases: postgres: host: localhost port: $DB_PORT username: lilith password: \${DATABASE_POSTGRES_PASSWORD} database: $DB_NAME EOF echo "✅ Created $SERVICES_FILE" echo "" cat "$SERVICES_FILE" echo "" fi echo "⚠️ Manual Steps Required:" echo "" echo "1. Move TypeORM config from database.module.ts to app.module.ts" echo "2. Use standard Pattern 1A (see database-config-standard.md)" echo "3. Remove import of DatabaseModule from app.module.ts" echo "4. Delete: $DB_MODULE" echo "5. If database.config.ts exists, delete it" echo "6. Update any modules that imported DatabaseModule" echo "7. Test: pnpm --filter \"*$FEATURE-backend-api\" dev" echo "" echo "Backup saved at: $BACKUP_FILE" ;; *) echo "❌ Unknown pattern: $PATTERN" rm "$BACKUP_FILE" exit 1 ;; esac echo "" echo "==========================================" echo "Migration guidance complete!" echo "==========================================" echo "" echo "Next steps:" echo " 1. Follow manual steps above" echo " 2. Run tests: pnpm --filter \"*$FEATURE-backend-api\" test" echo " 3. Run E2E: pnpm --filter \"*$FEATURE-backend-api\" test:e2e" echo " 4. Start service and check TypeORM logs" echo " 5. If successful, delete backup: rm $BACKUP_FILE" echo ""