# Prisma 数据层迁移路线

## 目标

业务 API 不再通过 `psql` shell 执行 SQL 字符串。迁移脚本可以继续是 SQL 文件，但运行时读写必须逐步收口到 Prisma 服务层。

## 当前状态

- 已有 `PrismaService` 和 Prisma schema。
- lite runtime 已新增 `backend/src/lite/prisma.mjs`，后续 `.mjs` 业务模块统一从这里获取 PrismaClient 和 transaction helper。
- 生产实际运行入口仍是 `backend/src/main.mjs`。
- 主要业务逻辑集中在 `backend/src/lite/business-pg.mjs`。
- `backend/src/lite/pg.mjs` 的 `queryJson`、`executeSql`、`sqlLiteral` 是主要安全债。
- 2026-06-08 基线：`business-pg.mjs` 约 `queryJson=247`、`executeSql=92`、`sqlLiteral=1121`。

## 模块切换顺序

1. Auth：验证码、用户 session、员工 session、PC 扫码、小程序身份。
2. Commerce：商品、购物车、订单、支付单、优惠码。
3. Payment：微信回调、支付成功幂等、权益发放。
4. Account：个人中心、会员、通知、资料。
5. Admin：用户、员工、角色、审计、CMS。
6. Expert：专家申请、预约、排期、提现。
7. Service：咨询、数据服务、任务、课程/活动核销。
8. Finance：收入、对账、发票申请、异常处理。

## 迁移规则

- 每个模块先写 Prisma repository，再保留旧接口响应字段完全一致。
- 新 repository 必须使用 `backend/src/lite/prisma.mjs`，不得直接 new PrismaClient。
- 支付成功、权益发放、优惠码核销必须使用同一个 Prisma transaction。
- 微信回调必须做幂等保护，重复回调不能重复发权益。
- 新代码不得新增 `sqlLiteral` 拼接业务 SQL。
- 删除密码字段时先清空 legacy 值，再单独迁移删除列。
- 每个模块完成后补单元测试和至少一条集成闭环。

## 第一批执行清单

1. `uploaded_files`：迁移文件元数据读写、私有文件权限判断、S3 对象记录。
2. `operational_events`：迁移异常中心列表、详情、处理、Alertmanager webhook 入库。
3. `invoice_applications`：迁移用户申请、后台处理、文件绑定、导出查询。
4. `sms_send_logs` 和 `auth_rate_limits`：迁移短信日志、限流命中记录和验证码校验辅助查询。
5. `sessions/staff_sessions`：迁移手机号登录后的 session 创建、失效和 me 查询。

## 验收方式

- 旧接口响应快照与新接口响应字段一致。
- Web、miniapp、后台对应页面不改调用方式也能跑通。
- `rg "queryJson|executeSql|sqlLiteral|runPsql" backend/src/lite/business-pg.mjs` 数量按模块下降。
- CI 中新增对应模块测试。

## 最终删除项

- `backend/src/lite/pg.mjs` 只保留迁移脚本使用，业务运行时不导入。
- `staff_accounts.password_hash`、`staff_accounts.password_salt` 删除或彻底 nullable legacy 并清空。
- 历史 SHA256 seed 不再产生任何真实可登录路径。
