Files
dukang/server/dukang-api/prisma/V31_MIGRATION.md
T
2026-07-01 14:36:50 +08:00

283 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# V3.1 Schema 迁移清单
> 生成自 `init_v3.sql` → `schema.v31.prisma`(已通过 `prisma validate`
> 旧版备份:`schema.legacy-v21.prisma`(当前运行中的 `schema.prisma`
## 激活步骤(P0
```bash
cd server/dukang-api
# 1. 备份并切换 schema
cp prisma/schema.prisma prisma/schema.legacy-v21.prisma # 若尚未备份
cp prisma/schema.v31.prisma prisma/schema.prisma
# 2. 开发库建议删库重建
mysql -u root -p -e "DROP DATABASE IF EXISTS dukang_haoke; CREATE DATABASE dukang_haoke ..."
# 或:mysql < prisma/init_v3.sql
# 3. 生成 Client
pnpm db:generate
npx prisma db push # 或 prisma migrate dev --name v31_init
# 4. 新 seed(待编写 seed-v31.ts
pnpm prisma:seed
```
---
## 表对照(27 张 v3.1
| v3.1 物理表 | Prisma Model | 旧表/Model | 变化 |
|-------------|--------------|------------|------|
| `common_wx_app_config` | `CommonWxAppConfig` | `wx_app_configs` / `WxAppConfig` | 重命名 |
| `common_resource` | `CommonResource` | — | **新增**(替代 `store_media`、裸 URL |
| `common_event` | `CommonEvent` | `benefit_ledgers`, `order_status_logs`, `store_audits`, `event_logs`, `operation_logs` | **合并** |
| `common_ticket` | `CommonTicket` | `after_sale_tickets`, `refunds`, `delivery_intercepts`, `alerts` | **合并** |
| `common_product_item` | `CommonProductItem` | `products` / `Product` | 重命名 + `cover_resource_id` |
| `common_store_category` | `CommonStoreCategory` | `store_categories` / `StoreCategory` | 重命名 |
| `common_promo_code` | `CommonPromoCode` | `promo_codes` / `PromoCode` | 重命名 + `qrcode_resource_id` |
| `common_city` | `CommonCity` | `cities` / `City` | 重命名 |
| `common_city_commission_rule` | `CommonCityCommissionRule` | `city_commission_rules` | 重命名 |
| `partner_partner` | `Partner` | `partners` | 重命名 + 合同字段内联 |
| `partner_account` | `PartnerAccount` | `partner_accounts` | 重命名 |
| `partner_bill` | `PartnerBill` | `partner_bills` | 状态枚举精简 |
| `hq_account` | `HqAccount` | `hq_accounts` | 重命名 |
| `user_user` | `User` | `users` | 重命名;`phone` 可空;含 `deviceKey`/合并字段 |
| `user_address` | `UserAddress` | `user_addresses` | 重命名 |
| `user_city_preference` | `UserCityPreference` | `user_city_preferences` | 重命名 |
| `user_promo_attribution` | `UserPromoAttribution` | `user_promo_attributions` | 重命名 |
| `store_store` | `Store` | `stores` | `cover_url``cover_resource_id` |
| `store_account` | `StoreAccount` | `store_accounts` | 重命名 |
| `user_order` | `Order` | `orders` | **无 order_items**;商品快照内嵌 |
| `user_order_delivery` | `OrderDelivery` | `order_deliveries` | 重命名 + `sign_photo_resource_id` |
| `user_benefit_coupon` | `BenefitCoupon` | `benefit_coupons` | 重命名 |
| `user_redeem_record` | `RedeemRecord` | `redeem_records` | 重命名 |
| `user_store_rating` | `StoreRating` | `store_ratings` | 重命名 |
| `store_payout` | `StorePayout` | `store_payouts` | 重命名 |
| `log_third_party` | `LogThirdParty` | `payments`, `sms_logs` | **合并** |
| `log_user_analytics` | `LogUserAnalytics` | `event_logs`(埋点部分) | **拆分** |
### 删除的表(v3.1 不再存在)
| 旧表 | 替代方案 |
|------|----------|
| `store_media` | `common_resource``owner_type=STORE` |
| `partner_contracts` | `partner_partner.contract_*` + `common_resource` CONTRACT |
| `order_items` | `user_order` 内嵌快照字段 |
| `order_status_logs` | `common_event(ORDER_STATUS)` |
| `payments` | `log_third_party` + `user_order.pay_*` |
| `refunds` | `common_ticket(REFUND)` |
| `delivery_intercepts` | `common_ticket(ALERT)` 或 RESHIPMENT |
| `benefit_ledgers` | `common_event(BENEFIT_LEDGER)` |
| `redeem_tokens` | **仅 Redis** |
| `order_commissions` | `partner_bill` 汇总(无明细表) |
| `partner_withdrawals` | 手册 v3.1 未包含(后续按需) |
| `store_audits` | `common_event(STORE_AUDIT)` |
| `after_sale_tickets` | `common_ticket` |
| `alerts` | `common_ticket(ALERT)` |
| `operation_logs` | `common_event(HQ_OPERATION)` |
| `event_logs` | `common_event` + `log_user_analytics` |
### preV1 扩展字段(已并入 v3.1
| 字段 | 表 | 说明 |
|------|-----|------|
| `device_key` / `phone_verified_at` / `merged_into_user_id` | `user_user` | 访客 JWT + 验机 + 账号合并 |
| `client_ip` / `ip_*` / `gps_*` | `user_order` | 下单位置快照 |
~~以下字段在切换后丢失~~**已保留**
---
## Prisma Client 调用变更速查
| 旧调用 | v3.1 调用 |
|--------|-----------|
| `prisma.product` | `prisma.commonProductItem` |
| `prisma.city` | `prisma.commonCity` |
| `prisma.cityCommissionRule` | `prisma.commonCityCommissionRule` |
| `prisma.storeCategory` | `prisma.commonStoreCategory` |
| `prisma.promoCode` | `prisma.commonPromoCode` |
| `prisma.orderDelivery` | `prisma.orderDelivery`(表名变 `user_order_delivery` |
| `prisma.benefitCoupon` | `prisma.benefitCoupon`(表 `user_benefit_coupon` |
| `prisma.benefitLedger` | `prisma.commonEvent``eventType=BENEFIT_LEDGER` |
| `prisma.redeemToken` | **删除**,改 Redis |
| `prisma.storeMedia` | `prisma.commonResource` |
| `prisma.storeAudit` | `prisma.commonEvent``eventType=STORE_AUDIT` |
| `prisma.payment` | `prisma.logThirdParty` |
| `prisma.orderStatusLog` | `prisma.commonEvent``eventType=ORDER_STATUS` |
| `prisma.orderItem` | **删除**,读写 `order` 快照字段 |
> `Partner`、`Store`、`User`、`Order` 等 Model 名保留,仅 `@@map` 物理表名变化。
---
## 后端模块影响面
### P0 — 基础设施
| 路径 | 影响 | 工作量 |
|------|------|--------|
| `prisma/schema.prisma` | 已切换为 v3.1 | ✅ |
| `prisma/schema.v31.prisma` | 与 `schema.prisma` 同步源 | ✅ |
| `prisma/seed-prev1.ts` | 保留为 `seed-legacy`;主 seed 为 `seed-v31.ts` | ✅ |
| `prisma/sync-benefit-to-price.ts` | `product``commonProductItem` | 低 |
| `packages/shared-types` | `ClientApp` 去掉 `USER_H5` 等;新增 Resource/Event 枚举 | 中 |
### P1 — common 模块(新建)
| 路径 | 说明 |
|------|------|
| `src/modules/common/common.module.ts` | **新建** |
| `src/modules/common/resource.service.ts` | OSS 凭证、登记、CRUD |
| `src/modules/common/resource.controller.ts` | `/common/resources/*` |
| `src/modules/common/event.service.ts` | 事件写入/查询/时间线 |
| `src/modules/common/ticket.service.ts` | 工单 CRUD |
### P2 — IAM
| 路径 | 关键改动 |
|------|----------|
| `modules/iam/auth.service.ts` | 去掉访客 `deviceKey` 流程;`user.phone` 必填;`prisma.user` 字段变更 |
| `modules/iam/user-address.service.ts` | 表名映射,逻辑基本不变 |
| `common/guards/phone-verified.guard.ts` | 适配新 User 模型 |
| `common/guards/super-admin.guard.ts` | 无大变 |
### P3 — catalog
| 路径 | 关键改动 |
|------|----------|
| `modules/catalog/catalog.service.ts` | `city``commonCity``product``commonProductItem`;返回 `coverResource.url` |
### P4 — trade(改动最大)
| 路径 | 关键改动 |
|------|----------|
| `modules/trade/trade.service.ts` | 下单写 `user_order` 快照(无 `orderItem`);支付写 `log_third_party`;状态变更写 `common_event`;去掉 IP/GPS 字段或扩展 |
| `integrations/pay/*` | 回调改查 `log_third_party` |
| `jobs/*`(配送 Mock | `orderDelivery` 字段对齐 |
### P5 — benefit
| 路径 | 关键改动 |
|------|----------|
| `modules/benefit/benefit.service.ts` | 发券逻辑保留;流水从 `benefitLedger.create``commonEvent.create(BENEFIT_LEDGER)`;读明细改查 `commonEvent` |
### P6 — redeem
| 路径 | 关键改动 |
|------|----------|
| `modules/redeem/redeem.service.ts` | **删除** `redeemToken` DB 写入,仅 Redis`cityCommissionRule``commonCityCommissionRule` |
### P7 — store
| 路径 | 关键改动 |
|------|----------|
| `modules/store/store.service.ts` | `storeAudit``commonEvent`;封面改 `coverResourceId``city``commonCity` |
### P8 — settlement
| 路径 | 关键改动 |
|------|----------|
| `modules/settlement/settlement.service.ts` | `partnerBill` 状态枚举变更;去掉 `orderCommission` 明细 |
### P9 — analytics
| 路径 | 关键改动 |
|------|----------|
| `modules/analytics/analytics.service.ts` | `eventLog``logUserAnalytics` |
### P10 — opsHQ 后台)
| 路径 | 关键改动 |
|------|----------|
| `modules/ops/admin-stores.service.ts` | `storeMedia``commonResource``coverUrl``coverResourceId``city``commonCity` |
| `modules/ops/admin-benefit.service.ts` | 流水列表改查 `commonEvent` |
| `modules/ops/admin-orders.service.ts` | 订单含内嵌商品快照;无 `items` include |
| `modules/ops/admin-dashboard.service.ts` | 统计字段:去掉 guest/merged 用户计数 |
| `modules/ops/admin-cities.service.ts` | `city``commonCity` |
| `modules/ops/admin-partners.service.ts` | 订单关联 `city.partnerId` 不变 |
| `modules/ops/admin-redeem.service.ts` | 表名映射 |
| `modules/ops/admin-users.service.ts` | 去掉 merged/guest 相关 |
| `admin-stores.controller.ts` | `/admin/store-media``/admin/resources` 或复用 common API |
---
## 前端影响面
| 应用 | 影响 |
|------|------|
| `apps/h5-user` | 登录流(phone 必填);商品图 URL 来源;订单详情无 items 数组 |
| `apps/h5-shop` | 门店详情封面 URL |
| `apps/h5-partner` | 录店上传走 `/common/resources` |
| `apps/admin-web` | 门店资源页改 `common_resource`;权益流水改 event;订单详情结构调整 |
| `packages/shared-types` | 枚举与 DTO 同步 |
---
## P1 进度(common 模块)
| 项 | 状态 |
|----|------|
| `modules/common/` Resource/Event/Ticket/ThirdPartyLog | ✅ |
| `common/event/event.helpers.ts` 权益/订单事件 | ✅ |
| 业务层改用 `commonEvent` / `commonResource` / `logThirdParty` | ✅ |
| `pnpm run build` | ✅ |
## P2–P6 进度(业务层 + 兼容层 + 后台)
| 项 | 状态 |
|----|------|
| P2 IAM + catalog 适配 v3.1 | ✅ |
| P3 trade + benefit(下单/发券/支付日志/事件) | ✅ |
| P4 redeem + storeRedis token + 封面资源) | ✅ |
| P5 ops 后台(订单/门店/权益/城市/合伙人) | ✅ |
| P6 兼容层 `v31-compat.ts`(订单 items、门店 coverUrl、流水/状态日志) | ✅ |
| `admin/products` CRUD + HQ 商品页 | ✅ |
| `sync-benefit-to-price.ts``commonProductItem` | ✅ |
| `schema.prisma``schema.v31.prisma` 同步 | ✅ |
| smoke 脚本 `scripts/smoke-prev1.mjs` | ✅ |
### 新增 HQ API
| 路径 | 说明 |
|------|------|
| `GET/POST /admin/products` | 商品列表/新建 |
| `GET/PUT /admin/products/:id` | 商品详情/更新 |
### 新增 API`/api/v1/common/*`
| 路径 | 说明 |
|------|------|
| `POST /common/resources/upload-token` | Mock OSS 直传凭证 |
| `POST/GET/PUT/DELETE /common/resources` | 资源 CRUD |
| `POST/GET /common/events` | 事件写入/查询 |
| `GET /common/events/timeline` | 时间线 |
| `POST/GET/PUT /common/tickets` | 工单 |
| `GET /common/third-party-logs` | HQ 只读支付/第三方日志 |
## 建议实施顺序
```
P0 schema 切换 + seed-v31
→ P1 common 模块(resource + event
→ P2 IAM + catalog(可登录、可看商品)
→ P3 trade + benefit(可下单发券)
→ P4 redeem + store(可核销)
→ P5 ops 后台 + settlement
→ P6 前端对齐 + smoke
```
**冻结规则**:P0~P1 期间不新增业务功能,只修迁移阻塞项。
---
## 文件索引
| 文件 | 说明 |
|------|------|
| `prisma/init_v3.sql` | DDL 源 |
| `prisma/schema.v31.prisma` | **新生成**,待激活 |
| `prisma/schema.legacy-v21.prisma` | 旧版备份 |
| `prisma/schema.prisma` | 当前运行版(**v3.1 已激活** |