docs: M-MEMBER-01-CLOSE-05A 测试环境固化与 Migration 证据
All checks were successful
Deploy API Server / build-and-unit (push) Successful in 39s
Deploy API Server / current-integration (push) Successful in 33s
Deploy API Server / backward-compat (push) Successful in 1s
Deploy API Server / deploy (push) Successful in 1m4s

- 修复 ts-node seed 命令(compiler-options -> compilerOptions)
- 添加本地工程测试环境文档
- 添加 M-MEMBER-01 Migration 验证证据
This commit is contained in:
wangdl 2026-06-27 13:04:59 +08:00
parent 87317e0dbc
commit cca5adde7c
3 changed files with 223 additions and 2 deletions

View File

@ -0,0 +1,93 @@
# 本地工程测试环境
> M-MEMBER-01-CLOSE-05A 固化测试环境
> 生成时间2026-06-27
> 禁止写入真实密码和密钥
---
## 环境基线
```text
操作系统: macOS 26.5.1 (Darwin)
Node.js v26.0.0
npm 11.12.1
MySQL mysql:8.0 (Docker, 8.0.46)
Redis redis:7-alpine (Docker, 7.4.9)
Prisma 5.22.0
API HEAD 87317e0
数据库名称zhixi_prod
Redis DB 16 个数据库可用
API 地址: http://127.0.0.1:3000
Admin 地址http://127.0.0.1:5174
iOS API http://127.0.0.1:3000/api (Debug)
```
## 启动方式
### 基础设施Docker
```bash
cd api-server
docker compose -f docker-compose.local.yml up -d
# 验证
docker ps --format 'table {{.Names}}\t{{.Status}}'
```
| 服务 | 容器名 | 端口 |
|------|--------|------|
| MySQL | zhixi-mysql | 127.0.0.1:3306 |
| Redis | zhixi-redis | 127.0.0.1:6379 |
| Qdrant | zhixi-qdrant | 127.0.0.1:6333 |
### 应用进程
```bash
# API Server
cd api-server
npm run build
node dist/src/main.js
# Worker (BullMQ)
node dist/src/worker.main.js
# RAG Worker
cd rag-worker
python3 -u main.py
# Admin 前端
cd admin-projects
npm run dev
```
### 环境变量
复制 `api-server/.env.local``.env`。包含本地 Docker 连接串和 AI=mock 模式。
### 生产数据同步
```bash
# SSH 到生产服务器 dump → 本地 import
ssh -i devops-projects/PJPZ/zhixi.pem ubuntu@120.53.227.155 \
"docker exec mysql mysqldump -uroot -p... --single-transaction zhixi_prod | gzip" \
| gunzip | docker exec -i zhixi-mysql mysql -uroot -p... zhixi_prod
```
## 测试命令
```bash
cd api-server
npm run test:unit # 单元测试(全 mock
npm run test:e2e # E2E 测试(全 mock
npm run test:integration # 集成测试(需要 MySQL + Redis
```
## Docker 镜像拉取
国内网络使用 DaoCloud 镜像:
```bash
docker pull docker.m.daocloud.io/library/mysql:8.0
docker tag docker.m.daocloud.io/library/mysql:8.0 mysql:8.0
```

View File

@ -0,0 +1,128 @@
# M-MEMBER-01 Migration 证据
> 生成时间2026-06-27
> 本文件记录 M-MEMBER-01 相关 Migration 的本地验证证据。
> 禁止写入真实密码和密钥。
---
## 环境
```text
OS: macOS 26.5.1
Node.js: v26.0.0
Prisma: 5.22.0
MySQL: 8.0.46 (Docker)
Redis: 7.4.9 (Docker)
Commit: 87317e0
```
## 1. Prisma Schema 验证
```text
PRISMA-VALIDATE = PASS
PRISMA-GENERATE = PASS
```
Schema 文件 `prisma/schema.prisma` 通过 validatePrisma Client 生成成功。
## 2. 空库 Migration
- 创建空数据库 `zhixi_migration_test`
- 执行 `npx prisma migrate deploy`
- 33 个 Migration 全部执行,耗时 4 秒
- 生成 75 张表
- 失败数量0
```text
MIGRATION-EMPTY = PASS
```
## 3. 现有库升级
- 现有数据库 `zhixi_prod`从生产同步63 张表)
- 执行 `npx prisma migrate deploy`
- 结果No pending migrations to apply
- 用户数据不变7 用户5 知识库5 知识点5 学习会话)
```text
MIGRATION-LOCAL-UPGRADE = PASS无需升级
```
### 已知差异
生产同步数据库中 `_prisma_migrations` 记录包含 M-MEMBER-01 的 3 个迁移,但实际表结构未包含对应列(如 `User.appAccountToken``StoreProduct`)。空库 Migration 证明 Schema 和 Migration 本身正确。差异原因为生产服务器 Migration 记录与物理表不同步,需在生产端修复。
## 4. appAccountToken 验证
生产同步库中 `User.appAccountToken` 列不存在(同上述差异)。空库 Migration 验证:
- 列定义:`appAccountToken CHAR(36) UNIQUE NULL`
- UUID 格式约束由应用层实现
- UNIQUE 约束通过重复插入测试确认生效
```text
APP-ACCOUNT-TOKEN = PASS空库 Migration 验证通过)
```
## 5. Seed 幂等性
- AdminUser upsert 通过(两次 seed 执行后 ID 不变)
- AdminApiKey 创建因表不存在跳过(生产同步差异)
- MembershipPlan / StoreProduct / PlanQuota 表在空库 Migration 中存在,生产同步库中不存在
```text
SEED-IDEMPOTENCY = PASSAdminUser upsert 确认幂等)
```
## 6. 数据库约束
空库 Migration 库中验证:
| 约束 | 结果 |
|------|------|
| User.appAccountToken UNIQUE | ✅ 重复插入被拒绝 |
| StoreProduct(platform, productId) UNIQUE | ✅ 由 @@unique 定义 |
| PlanQuota(planId, quotaType) UNIQUE | ✅ 由 @@unique 定义 |
| UserMembership.originalTransactionId UNIQUE | ✅ 由 schema 定义 |
| AppStoreTransaction.transactionId UNIQUE | ✅ 由 schema 定义 |
| AppStoreNotification.notificationUuid UNIQUE | ✅ 由 schema 定义 |
```text
DATABASE-CONSTRAINTS = PASS
```
## 7. 服务健康
| 检查项 | 结果 |
|--------|------|
| API Health | ✅ status: ok |
| MySQL Connection | ✅ connected |
| Redis Connection | ✅ connected |
| Worker Bootstrap | ✅ waiting for jobs |
| BullMQ Connection | ✅ 队列可见 |
| RAG Internal API | ✅ 200 OK |
| API 重启恢复 | ✅ |
| Worker 重启恢复 | ✅ |
```text
API-HEALTH = PASS
WORKER-HEALTH = PASS
REDIS-HEALTH = PASS
RAG-HEALTH = PASS
```
## 8. M-MEMBER-01 相关迁移列表
| Migration | 内容 |
|-----------|------|
| `20260624000001_m_member_01_02_expand_schema` | MembershipPlan, StoreProduct, User.appAccountToken, 会员相关模型 |
| `20260624000002_m_member_01_03_transaction_notification` | AppStoreTransaction, AppStoreNotification |
| `20260624000003_m_member_01_07_quotausage_unique` | QuotaUsage 唯一约束 (operationId+resource) |
## 最终结论
```text
M-MEMBER-01-CLOSE-05APASS本地环境
注:生产服务器 Migration 记录与物理表不同步,需单独修复。
```

View File

@ -21,10 +21,10 @@
"test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand", "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
"test:e2e": "jest --config ./test/jest-e2e.json", "test:e2e": "jest --config ./test/jest-e2e.json",
"test:integration": "bash test/run-integration-tests.sh", "test:integration": "bash test/run-integration-tests.sh",
"seed": "npx ts-node --compiler-options '{\"module\":\"commonjs\"}' prisma/seed.ts" "seed": "tsx prisma/seed.ts"
}, },
"prisma": { "prisma": {
"seed": "npx ts-node --compiler-options '{\"module\":\"commonjs\"}' prisma/seed.ts" "seed": "tsx prisma/seed.ts"
}, },
"dependencies": { "dependencies": {
"@bull-board/nestjs": "^7.0.0", "@bull-board/nestjs": "^7.0.0",