fix(migration): add production migration support for Docker

- Add data-source.prod.ts for compiled JS migrations
- Add migration:run:prod script to package.json
- Update deploy.sh to try prod migration first, fallback to dev
- Keep SQL fallback in full-reset as safety net with proper indexes

This ensures migrations work in Docker where ts-node may not be available.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
hailin 2026-01-24 08:05:14 -08:00
parent 90917b3ac8
commit b70035ad2f
3 changed files with 33 additions and 4 deletions

View File

@ -971,8 +971,9 @@ do_full_reset() {
sleep 5 # 等待数据库完全初始化
do_db migrate
# 7.1 添加 V2 咨询流程所需的数据库列
log_step "添加 V2 咨询流程数据库列..."
# 7.1 备用:确保 V2 咨询流程数据库列存在(迁移可能因各种原因失败)
# 这些 ALTER 语句使用 IF NOT EXISTS与 TypeORM 迁移保持一致
log_step "验证 V2 数据库列..."
docker exec -i iconsulting-postgres psql -U postgres -d iconsulting -c "
ALTER TABLE conversations ADD COLUMN IF NOT EXISTS consulting_stage VARCHAR(30) DEFAULT 'greeting';
ALTER TABLE conversations ADD COLUMN IF NOT EXISTS consulting_state JSONB;
@ -980,7 +981,9 @@ do_full_reset() {
ALTER TABLE conversations ADD COLUMN IF NOT EXISTS recommended_programs TEXT[];
ALTER TABLE conversations ADD COLUMN IF NOT EXISTS conversion_path VARCHAR(30);
ALTER TABLE conversations ADD COLUMN IF NOT EXISTS device_info JSONB;
" 2>/dev/null && log_success "V2 数据库列已添加" || log_warning "V2 数据库列添加跳过"
CREATE INDEX IF NOT EXISTS idx_conversations_consulting_stage ON conversations (consulting_stage);
CREATE INDEX IF NOT EXISTS idx_conversations_conversion_path ON conversations (conversion_path);
" 2>/dev/null && log_success "V2 数据库列已验证" || log_warning "V2 数据库列验证跳过"
# 8. 启动所有后端服务
log_step "启动后端服务..."
@ -1317,7 +1320,8 @@ do_db() {
# 在容器中执行迁移命令
for service in user payment knowledge conversation evolution; do
local dir="${SERVICE_DIRS[$service]}"
run_in_builder "cd $dir && pnpm run migration:run 2>/dev/null" || log_warning "$service 无迁移或迁移失败"
# 先尝试生产环境迁移使用编译后的JS如果失败再尝试开发环境迁移需要ts-node
run_in_builder "cd $dir && (pnpm run migration:run:prod 2>/dev/null || pnpm run migration:run 2>/dev/null)" || log_warning "$service 无迁移或迁移失败"
done
log_success "数据库迁移完成"
;;

View File

@ -13,7 +13,9 @@
"test:watch": "jest --watch",
"test:cov": "jest --coverage",
"typeorm": "typeorm-ts-node-commonjs",
"typeorm:prod": "typeorm",
"migration:run": "npm run typeorm migration:run -- -d src/data-source.ts",
"migration:run:prod": "npm run typeorm:prod migration:run -- -d dist/data-source.prod.js",
"migration:revert": "npm run typeorm migration:revert -- -d src/data-source.ts",
"migration:generate": "npm run typeorm migration:generate -- -d src/data-source.ts"
},

View File

@ -0,0 +1,23 @@
import { DataSource } from 'typeorm';
import * as dotenv from 'dotenv';
// Load environment variables
dotenv.config({ path: '.env.local' });
dotenv.config({ path: '.env' });
/**
* Production data source for running migrations
* Uses compiled JS files instead of TypeScript
*/
export const AppDataSource = new DataSource({
type: 'postgres',
host: process.env.POSTGRES_HOST || 'localhost',
port: parseInt(process.env.POSTGRES_PORT || '5432', 10),
username: process.env.POSTGRES_USER || 'iconsulting',
password: process.env.POSTGRES_PASSWORD,
database: process.env.POSTGRES_DB || 'iconsulting',
entities: [__dirname + '/**/*.entity.js'],
migrations: [__dirname + '/migrations/*.js'],
synchronize: false,
logging: true,
});