Просмотр исходного кода

📝 docs(prd): 新增数据库迁移修复史诗文档

- 创建史诗007文档,详细描述数据库迁移问题与解决方案
- 定义三个故事:修复TypeORM配置、实现迁移工具模块、集成web包启动流程
- 包含技术实现细节、依赖关系和验收标准

📦 build(server): 更新package.json配置并添加数据源文件

- 添加TypeORM相关脚本:db:migrate、db:migrate:generate、db:migrate:revert
- 添加tsx依赖以支持TypeORM CLI执行
- 创建src/data-source.ts文件,初始化数据源并导出供TypeORM使用
- 导入所有模块实体确保迁移时能正确识别数据库结构
yourname 1 месяц назад
Родитель
Сommit
b5561efd37

+ 140 - 0
docs/prd/epic-007-database-migration-fixes.md

@@ -0,0 +1,140 @@
+# 史诗007:数据库迁移问题修复与web集成
+
+## 史诗状态
+**进度**: 0/3 故事完成 (0%)
+**最近更新**: 2025-12-16 (史诗重写)
+**当前状态**: 所有故事待开始
+
+## 史诗目标
+修复当前数据库迁移脚本问题,使server包提供可用的迁移功能,web包能够正确调用并集成到启动流程。
+
+## 史诗描述
+
+### 当前问题
+1. **server包TypeORM脚本问题**:
+   - `packages/server/package.json`中的迁移脚本路径错误(指向`./src/server/data-source.ts`但不存在)
+   - 缺少`tsx`依赖,脚本无法执行
+   - 已创建`packages/server/src/data-source.ts`但脚本未更新
+
+2. **web包迁移脚本缺失**:
+   - `web/package.json`中的`db:migrate`脚本指向不存在的`scripts/migrate.ts`文件
+   - `pnpm start`启动流程未集成数据库迁移
+   - web包无法使用server包的迁移功能
+
+3. **迁移功能未封装**:
+   - 没有统一的迁移工具模块
+   - 无法在程序化代码中调用迁移
+   - 缺少错误处理和日志
+
+### 解决方案
+1. **修复server包基础配置**:修正脚本路径,添加依赖,使TypeORM命令可工作
+2. **实现迁移工具模块**:在server包中创建可导出的迁移工具,支持API和CLI调用
+3. **集成web包启动流程**:修复web脚本,集成自动迁移到`pnpm start`
+
+## 故事
+
+### 故事1:修复server包TypeORM基础配置
+**目标**:使`packages/server`中的TypeORM命令能够正确执行
+
+**具体任务**:
+1. 修正`packages/server/package.json`中的脚本路径:
+   - 当前:`./src/server/data-source.ts` → 修正为:`./src/data-source.ts`
+2. 确保`tsx`依赖已添加(已添加)
+3. 验证基础命令可工作:
+   - `pnpm db:migrate` - 运行迁移
+   - `pnpm db:migrate:generate` - 生成迁移文件
+   - `pnpm db:migrate:revert` - 回滚迁移
+
+**成功标准**:
+- ✅ `pnpm db:migrate`能够正确连接到数据库
+- ✅ TypeORM能够找到数据源配置
+- ✅ 迁移相关命令无路径错误
+
+### 故事2:实现server包迁移工具模块
+**目标**:在server包中创建可导出的迁移工具,供其他包调用
+
+**具体任务**:
+1. 创建迁移工具模块:`packages/server/src/migration-runner.ts`
+   - 导出`runMigrations()`函数:运行所有待处理迁移
+   - 导出`getMigrationStatus()`函数:查看迁移状态
+   - 支持错误处理和详细日志
+2. 创建CLI入口:`packages/server/src/cli/migrate.ts`
+   - 支持命令行调用:`tsx packages/server/src/cli/migrate.ts run`
+   - 支持状态查看:`tsx packages/server/src/cli/migrate.ts status`
+3. 更新package.json导出配置:
+   - 确保迁移工具可以被其他包导入
+   - 添加必要的TypeScript类型导出
+
+**成功标准**:
+- ✅ 可以从其他包导入`@d8d/server`的迁移工具
+- ✅ `runMigrations()`函数可以程序化调用
+- ✅ CLI工具能够执行迁移操作
+- ✅ 错误处理完善,日志清晰
+
+### 故事3:修复web包脚本并集成自动迁移
+**目标**:修复web包缺失的迁移脚本,集成自动迁移到启动流程
+
+**具体任务**:
+1. 修复web包迁移脚本:
+   - 创建`web/scripts/migrate.ts`文件
+   - 调用server包的`runMigrations()`函数
+   - 修复`web/package.json`中的`db:migrate`脚本路径
+2. 集成自动迁移到启动流程:
+   - 更新`web/package.json`中的`start`脚本
+   - 在启动服务器前自动运行迁移
+   - 支持环境变量控制:`AUTO_MIGRATE=true/false`
+3. 错误处理:
+   - 迁移失败时阻止应用启动
+   - 显示清晰的错误信息
+   - 保持现有数据库管理脚本(备份、恢复等)正常工作
+
+**成功标准**:
+- ✅ `pnpm db:migrate`在web包中能够正确执行
+- ✅ `pnpm start`在启动前自动运行数据库迁移(可配置)
+- ✅ 迁移失败时应用启动流程终止并显示错误
+- ✅ 现有数据库管理脚本继续正常工作
+
+## 技术实现细节
+
+### 数据源配置
+```typescript
+// packages/server/src/data-source.ts (已存在)
+import { initializeDataSource } from '@d8d/shared-utils'
+// 导入所有实体并初始化
+```
+
+### 迁移工具接口
+```typescript
+// packages/server/src/migration-runner.ts
+export async function runMigrations(): Promise<void>
+export async function getMigrationStatus(): Promise<MigrationStatus>
+```
+
+### web包集成
+```json
+// web/package.json
+{
+  "scripts": {
+    "db:migrate": "tsx scripts/migrate.ts",
+    "start": "AUTO_MIGRATE=true tsx scripts/migrate.ts && PORT=8080 cross-env NODE_ENV=production node server"
+  }
+}
+```
+
+## 依赖关系
+- **故事1** → **故事2**:需要基础TypeORM配置正常工作才能实现迁移工具
+- **故事2** → **故事3**:需要server包迁移工具完成才能集成到web包
+
+## 验收标准
+1. ✅ server包TypeORM命令可正确执行
+2. ✅ web包`db:migrate`脚本可正常工作
+3. ✅ `pnpm start`自动运行数据库迁移(可配置)
+4. ✅ 迁移失败时应用不启动,显示清晰错误
+
+## 后续优化(非本史诗范围)
+1. 完整的迁移目录结构和TypeORM配置文件
+2. 数据库创建/删除脚本
+3. 种子数据管理
+4. 迁移使用指南和集成测试
+
+本史诗专注于解决最紧急的数据库迁移问题,确保生产环境部署时数据库架构可以正确更新。

+ 6 - 1
packages/server/package.json

@@ -25,7 +25,11 @@
     "test:unit": "vitest run tests/unit",
     "test:integration": "vitest run tests/integration",
     "test:coverage": "vitest --coverage",
-    "test:typecheck": "tsc --noEmit"
+    "test:typecheck": "tsc --noEmit",
+    "typeorm": "tsx --env-file=.env ./node_modules/typeorm/cli.js",
+    "db:migrate": "pnpm typeorm migration:run -d ./src/data-source.ts",
+    "db:migrate:generate": "pnpm typeorm migration:generate -d ./src/data-source.ts",
+    "db:migrate:revert": "pnpm typeorm migration:revert -d ./src/data-source.ts"
   },
   "dependencies": {
     "@asteasolutions/zod-to-openapi": "^8.1.0",
@@ -70,6 +74,7 @@
     "@types/pg": "^8.11.10",
     "tsc-alias": "^1.8.10",
     "typescript": "^5.8.3",
+    "tsx": "^4.19.3",
     "vitest": "^3.2.4",
     "@vitest/coverage-v8": "^3.2.4"
   },

+ 35 - 0
packages/server/src/data-source.ts

@@ -0,0 +1,35 @@
+import "reflect-metadata"
+import { initializeDataSource, AppDataSource as SharedAppDataSource } from '@d8d/shared-utils'
+
+// 导入所有实体模块
+import { UserEntityMt, RoleMt } from '@d8d/user-module-mt'
+import { FileMt } from '@d8d/file-module-mt'
+import { TenantEntityMt } from '@d8d/tenant-module-mt'
+import { SystemConfigMt } from '@d8d/core-module-mt/system-config-module-mt'
+import { AreaEntityMt } from '@d8d/geo-areas-mt'
+import { PaymentMtEntity } from '@d8d/mini-payment-mt'
+import { Advertisement, AdvertisementType } from '@d8d/advertisements-module-mt'
+import { DeliveryAddressMt } from '@d8d/delivery-address-module-mt'
+import { GoodsMt, GoodsCategoryMt } from '@d8d/goods-module-mt'
+import { MerchantMt } from '@d8d/merchant-module-mt'
+import { OrderMt, OrderGoodsMt, OrderRefundMt } from '@d8d/orders-module-mt'
+import { SupplierMt } from '@d8d/supplier-module-mt'
+import { CreditBalanceMt, CreditBalanceLogMt } from '@d8d/credit-balance-module-mt'
+
+// 初始化数据源
+initializeDataSource([
+  // 已实现的包实体
+  UserEntityMt, RoleMt, FileMt,
+  TenantEntityMt,
+  AreaEntityMt, PaymentMtEntity,
+  Advertisement, AdvertisementType,
+  DeliveryAddressMt,
+  GoodsMt, GoodsCategoryMt,
+  MerchantMt,
+  OrderMt, OrderGoodsMt, OrderRefundMt,
+  SupplierMt, SystemConfigMt,
+  CreditBalanceMt, CreditBalanceLogMt
+])
+
+// 导出数据源实例供TypeORM CLI使用
+export const AppDataSource = SharedAppDataSource