# License Manager 产品级发布完善建议报告

| 项目 | 说明 |
| ---- | ---- |
| 文档版本 | v1.6 |
| 评估日期 | 2026-08-27 |
| 评估范围 | 后端（.NET 8）、前端（Vue 3 + Element Plus）、基础设施、安全、合规、运维 |
| 当前质量基线 | 后端 2209 项测试全绿通过（Core 195 / Platform 742 / Infrastructure 172 / Server 34 / Api 1066，2026-09-24 复核）；前端 Vite 零错误零警告构建通过（element-plus 主包优化至 905KB/gzip 293KB）；i18n 双端键零缺失零重复 |

优先级定义：**P0** = 阻断发布，必须完成；**P1** = 正式发布前应完成；**P2** = 可随迭代逐步完善。

> **v1.6 更新摘要（2026-10-08，商业化裁剪）：** 平台的商业/财务/合规模块已整体下线（订单、订阅策略、支付、试用、优惠券、退款、催缴、账单对账、PSP、税务、发票、汇率、品牌配置、数据驻留等均已删除），资金流由外部销售系统承接。本文此前各轮摘要为历史快照、不再回改；正文中涉及已删模块的现行口吻条目已加注「已随商业化下线」。保留的许可语义：许可证签发/激活/设备/用量、订阅续期（每小时自动扫描 + `POST /v1/admin/subscriptions/renewal/execute`，出站事件 `subscription.renewed` / `subscription.payment_failed`）、DSR、EULA/LegalDocument、Plan（许可配额）、TokenPool。

> **v1.5 更新摘要（2026-09 迭代，与代码实测对齐）：** ① 测试基线更正为 **2208** 项（Core 195 / Platform 742 / Infrastructure 172 / Server 34 / Api 1065，修正 v1.4 头部 1963 与文尾 1958 的自相矛盾）；② 持久化覆盖条目残留矛盾清理——Quote / PaymentMethod / Integration / SsoProvider 等已全部完成 EF 化（`services.Replace` 共 45 个实体），第一节建议与发布路径 1.1 同步销项；③ EULA 实体已迁移至 EF 持久化（§6.2 更新）。

> **v1.4 更新摘要（2026-08-27 迭代，发布就绪全项闭环）：** ① **EF Core 持久化全面覆盖（P0 完成）**：全部 45 个领域实体已全量从 Platform 内存仓储切换至 `EfRepository<T>`，彻底消除服务重启丢失报价单、支付方式、租户、设备、EULA 签署留痕与 SSO 绑定的风险；② **个人资料与自主修改密码（P1 - 4b.1 完成）**：新增 `/v1/auth/me`（GET/PUT）与 `/v1/auth/change-password`（POST）API 端点，前端上线 `/profile` 个人资料与安全管理视图，顶部头像下拉菜单集成快捷入口，中英文双语全覆盖；③ **前端分包体积优化（P1 - 5.1 完成）**：拆分 `@element-plus/icons-vue` 为独立 chunk，`element-plus` 主包体积从 1,076 kB 降至 905 kB（gzip 293 kB），完全消除 Vite 构建阈值警告；④ **发布工件与容器化（P1 - 4b.3 / 8.4 完成）**：新增 `Dockerfile`（.NET 8 API 多阶段镜像）、`Dockerfile.admin`（Vue 3 + Nginx）、`nginx.conf`（安全标头、gzip 与 SPA 路由）、`docker-compose.prod.yml` 与标准 `CHANGELOG.md`。

> **v1.3 更新摘要（2026-08-19 迭代，遗留项优化）：** ① **PspConfig 持久化 + 双轨统一**：新增 `psp_config` 表（迁移 `20260818222817_PersistPspConfigs`），PSP 凭据与 Webhook secret 经 `SecretProtector`（AES-GCM）加密入库；启动时 webhook secret 注入双轨统一——env/config 兜底、PspConfig 数据库覆盖（`PaymentRegistrationHostedService`）；② **回调事件幂等**：新增 `webhook_event_record` 表（迁移 `20260818223908_TrackWebhookEvents`），PSP 回调按事件 ID + provider 去重，重投递跳过、中途失败补偿重试；③ **SSRF 强化**：出站 HTTP 在 DNS 解析后、TCP 连接前校验解析出的实际 IP（`SocketsHttpHandler.ConnectCallback`，防 DNS rebinding）；④ **限流分布式**：`RateLimit:Distributed` 开关（默认 `false`），开启后经 Redis `IDistributedCache` 全局计数，多实例部署必须开启；⑤ **证书族 PSP 防护**：Alipay / WeChatPay / Braintree / UnionPay 验签 fail-dead（证书校验落地前恒拒回调，防伪造）；⑥ **前端支付闭环**：订单支付改走 `OrderPayDialog`（渠道 = 已激活 psp-configs ∪ mock、3 秒轮询意图状态、confirm 模拟收银台），不再手动 mark-paid。EF 实体 20 → 22（+PspConfig / WebhookEventRecord），迁移 5 → 7；Platform 测试 653 → 658。第一节、第二节、第三节相关条目状态已同步更新。

> **v1.2 更新摘要（2026-08-18 迭代）：** 本次迭代完成支付与 Webhook 链路专项修复 —— ① 财务/集成域 5 实体（PaymentIntent / Refund / WebhookDelivery / WebhookEndpoint / Invoice）完成 EF 持久化，EF 实体总数达 20 个（新增迁移 `20260818150547_AddRefundTrackingAndCaptureToPaymentIntents`：`refunded_amount` / `provider_capture_id` / `row_version` 三列）；② 退款防护闭环：仅 `Succeeded` 意图可退、剩余可退余额校验、`row_version` 乐观并发令牌防并发超额退款；③ 支付确认后自动履约（confirm → MarkPaidAsync → 自动履约）；④ 出站 Webhook 投递修复：`WebhookDeliveryWorker` 真实实现（HMAC 签名 + 时间戳头、指数退避重试、端点订阅匹配、终态记录 30 天清理、SSRF 校验、endpoint_not_found 不再无签名发送），管理端补投递列表/详情/手动重放端点；⑤ PayPal 适配器修复：退款优先使用 `provider_capture_id`、`currency_code` 按请求币种、幂等键（PayPal-Request-Idempotency）、零小数货币格式化、ClientId/ClientSecret 注入与 token 过期自愈刷新；⑥ Stripe 适配器修复：退款金额按意图币种换算、幂等键、验签支持多 v1 密钥轮换。第一节、三节相关条目状态已同步更新。

> **v1.1 更新摘要（2026-07-26 迭代）：** 本次迭代完成 UI 一致性与代码可维护性专项 —— ① 仪表盘新增快捷入口（角色感知）与系统状态实时探活面板；② 全部 63 张数据表格统一接入 `EmptyState` 空态组件（新增 `common.noData` / `common.noDataHint` 双语言键）；③ 7 个视图的本地状态映射函数收敛至统一工具 `tagTypeOf`（LicenseList / LicenseDetail / PersonalAccessTokens / WebhookDeliveries / OfflineActivation / BatchOperations / PaymentList）；④ 用户手册仪表盘章节重写并补 3 张分角色截图；⑤ 新建授权 / 订单 / 计划 / 试用 / 订阅策略 5 个对话框的原始 ID 输入统一改为可搜索下拉选择（复用 product/customer store），订阅策略列表同步显示产品名称。下列 5.x / 8.x 相关条目的状态已同步更新。

---

## 一、数据持久化（P0 — 已全部完成）

**现状：** 全部 45 个核心领域实体已完成 EF Core 仓储切换（`EfRepository<T>`，见 `DependencyInjection.cs`），包括身份与租户、产品与目录、授权与激活、订单与订阅、发票与报价、支付与退款、浮动许可、审计与 Webhook、系统密钥与通知、高级模块（命名用户、订阅策略、权益集、令牌池、EULA 签署、SSO 提供商与绑定、集成同步等），全面保证生产环境数据持久化安全。（注：其中订单、发票、报价、支付、退款、订阅策略等商业实体已随商业化裁剪通过 `RemoveCommerce` 迁移移除，45 实体为裁剪前口径，资金流由外部销售系统承接。）

**风险（历史，已消解）：** 商业、财务、合规域数据（报价单、支付方式、EULA 接受记录）在生产环境重启后丢失的风险——发票、支付意图、退款与 Webhook 投递记录已于 2026-08 迭代迁移至 EF 持久化，Quote / PaymentMethod / Integration / SsoProvider / EULA 等其余实体亦已全部完成 EF 化（45 个实体全量覆盖）。

**建议：**
1. ~~按域分批迁移至 `EfRepository<T>`~~ **已全部完成**：第一批财务域（Invoice / Quote / PaymentIntent / Refund / PaymentMethod）、第二批合规域（Eula / EulaAcceptance / BrandProfile 等）、第三批集成域（WebhookEndpoint / WebhookDelivery / Integration / SsoProvider）及其余配置与目录实体均已迁移，`services.Replace` 共覆盖 45 个实体。
2. 每批迁移遵循既有模式：DbContext 注册实体 → 处理 jsonb 集合（参照 `TestDbContext` 的 Ignore 约定与 `JsonValueConverterConvention`）→ `services.Replace` 覆盖注册 → EF migration → 回归测试。
3. 注意已踩过的坑：`--no-build` 加迁移前必须先重新构建 API 项目；含 jsonb 集合的实体（Order.Items、Invoice.LineItems，均已随商业化裁剪移除）在测试环境需覆盖回 `InMemoryRepository<T>`。

## 二、安全加固

| # | 优先级 | 事项 | 现状与建议 |
| - | ---- | ---- | ---- |
| 2.1 | P0 | **OIDC JWT 签名验证** | **已修复（JWKS 验签）**：`OidcClient.ValidateIdTokenAsync` 已通过 IdP 的 JWKS 公钥完成 JWT 签名校验，并同时校验 issuer、audience、expiry、nonce（签名校验失败返回 null，fail-closed）。 |
| 2.2 | P0 | **默认管理员口令** | 已通过 `Seed:AdminPassword` 可配置；需在部署清单中强制检查：生产环境未显式配置时启动即拒绝（fail-fast），而非使用默认值。 |
| 2.2b | P0 | **数据保护密钥强制配置** | `SecretProtector` 已在生产环境强制要求 `LICENSEMANAGER_DATA_PROTECTION_KEY`（base64 32 字节 AES-GCM），未配置即拒绝启动 —— 部署文档与 Helm/Compose 模板需显式包含该变量的生成与注入步骤，并纳入上线检查清单。 |
| 2.3 | P0 | **密钥类配置入 Vault** | SMTP 凭据、Webhook secret 等当前走配置文件（原 PSP 密钥与 `psp_config` 表已随商业化裁剪移除）。生产发布前仍应接入密钥管理服务（Azure Key Vault / AWS Secrets Manager / Vault），配置文件只留引用。 |
| 2.4 | P1 | **Penetration Test** | 发布前完成一次第三方或内部渗透测试，重点覆盖：JWT 伪造、越权（横向/纵向）、批量吊销接口的二次确认绕过、速率限制绕过、Webhook 重放。 |
| 2.5 | P1 | **依赖漏洞扫描门禁** | CI 中加入 `dotnet list package --vulnerable` 与 `npm audit --audit-level=high`，高危漏洞阻断合并。 |
| 2.6 | P2 | **审计日志防篡改** | 审计日志已只读，建议增加周期性哈希链或外发 WORM 存储，满足金融级合规。 |

## 三、支付与第三方集成

> 本章 3.1 / 3.2 / 3.3 中 PSP 相关内容已随商业化裁剪下线，资金流由外部销售系统承接；出站 Webhook 投递（3.3）与 SMTP（3.4）仍然适用。

| # | 优先级 | 事项 | 现状与建议 |
| - | ---- | ---- | ---- |
| 3.1 | P0 | **Stripe / Alipay 适配器落地** | ~~Stripe 已完成真实 API 对接（下单/退款/验签 fail-closed；2026-08 迭代补齐：退款金额按意图币种换算、退款幂等键 `refund:{intent}:{minor}`、零小数货币清单扩至 16 种、验签支持多 v1 密钥轮换；生产 key 对账联调待做）；Alipay 等其余 8 个 PSP 仍为桩（其中证书验签族 Alipay / WeChatPay / Braintree / UnionPay 的回调验证已 fail-dead 恒拒，证书校验落地前不放过任何回调，防伪造），若发布范围包含相应收款渠道需完成对接。~~ **已随商业化下线：支付适配器随资金流一并移交外部销售系统，本条不再适用。** |
| 3.2 | P1 | **PayPal 沙箱全链路验收** | ~~verify-webhook-signature 已接真实 API（IHttpClientFactory 注入）；2026-08 迭代补齐：退款优先使用 `provider_capture_id`、`currency_code` 按请求币种、PayPal-Request-Idempotency 幂等键、零小数货币格式化、ClientId/ClientSecret 环境变量注入（token 过期 401 自愈刷新重试一次）。发布前仍需在 PayPal Sandbox 完成创建订单 → 支付 → Webhook 回调 → 履约的端到端验收并留档。~~ **已随商业化下线：本条不再适用。** |
| 3.3 | P1 | **Webhook 投递可靠性** | `WebhookDeliveryWorker` 已真实实现（HMAC-SHA256 签名 + `X-LicenseManager-Timestamp` 防重放、指数退避重试 5s→1h、终态记录 30 天清理、SSRF 校验）；手动重放端点已提供（`POST /v1/admin/webhooks/deliveries/{id}/replay`）。（原入站 PSP 回调幂等去重机制已随商业化裁剪移除。）仍建议补充：失败投递的死信队列视图、投递延迟指标告警。 |
| 3.4 | P2 | **SMTP 发信可观测** | 已加 30s 超时；建议增加发信成功率指标与失败告警（接入既有遥测体系）。 |

## 四、可观测性与运维

| # | 优先级 | 事项 | 建议 |
| - | ---- | ---- | ---- |
| 4.1 | P0 | **健康检查分级** | **已完成**：`/v1/healthz`（进程存活）与 `/v1/readyz`（检查数据库连接与 Redis，任一不可用返回 503）已实现（参考 `StatusController.cs`），可直接供 K8s liveness/readiness 探针分别使用。 |
| 4.2 | P0 | **结构化日志 + 告警规则** | 确认生产日志采集链路（ELK/Loki），预置告警：5xx 比例 >1%、订阅续期续费失败事件（`subscription.payment_failed`）、授权签发失败、DB 连接池耗尽。 |
| 4.3 | P1 | **数据库备份策略** | 制定并演练：每日全量 + binlog 增量，RPO ≤ 15min，RTO ≤ 1h；每季度恢复演练一次。 |
| 4.4 | P1 | **EF 迁移上线流程** | 固化发布流程：先应用迁移（向后兼容）→ 再滚动更新应用 → 最后清理旧列（如需），避免新旧代码与 schema 不兼容窗口。 |
| 4.5 | P2 | **容量规划** | 基于 `EfRepository.ListAsync` 的 Take(10000) 上限，评估单表 1 万行以上的实体（审计日志、消费记录）是否需要归档策略或分页接口改造。 |

## 四b、产品功能缺口（已完成闭环）

| # | 优先级 | 事项 | 建议与完成状态 |
| - | ---- | ---- | ---- |
| 4b.1 | ✔ | **个人资料 / 修改密码页面** | **已完成**：新增 `/v1/auth/me`（GET/PUT）与 `/v1/auth/change-password`（POST，含旧密码校验与 >=8 位强度规则），前端上线 `/profile` 个人资料卡片与改密表单，顶部下拉菜单已集成入口。 |
| 4b.2 | P1 | **LicenseManager.Core（LMC）发布形态未定** | 核心授权库面向 ISV 集成场景，需明确发布形态：NuGet 包（内部源或 nuget.org）+ 版本策略 + API 兼容性承诺 + 符号包（snupkg）与 XML 文档随包发布。 |
| 4b.3 | ✔ | **容器镜像构建与发布工件** | **已完成**：提供标准多阶段 `Dockerfile`（.NET 8 API）、`Dockerfile.admin`（Vue 3 + Nginx）、`nginx.conf` 与生产环境 `docker-compose.prod.yml` 编排。 |

## 五、性能与扩展性

| # | 优先级 | 事项 | 建议与完成状态 |
| - | ---- | ---- | ---- |
| 5.1 | ✔ | **前端首包体积** | **已完成**：优化 Vite `manualChunks` 拆分 `@element-plus/icons-vue` 为独立包，`element-plus` 主包体积降低至 905 kB（gzip 293 kB），完全消除 Vite 构建阈值警告。 |
| 5.2 | P1 | **大列表服务端分页** | 当前产品/客户/授权/用户为客户端分页（全量拉取后过滤）。数据量超过约 5k 行的列表（授权、审计）应改服务端分页 + 服务端搜索，前端保留 `useClientPagedList` 仅用于小数据量页面。 |
| 5.3 | P2 | **高频接口缓存** | 产品/客户名称映射（前端 `useEntityNames`）已做幂等加载；后端可考虑对只读目录类接口（特性目录、货币、税率）加短期缓存。 |

## 六、合规与法务

| # | 优先级 | 事项 | 建议 |
| - | ---- | ---- | ---- |
| 6.1 | P0 | **隐私政策与数据处理协议（DPA）** | 系统已具备 DSR（数据主体请求）页面（数据驻留页面已随商业化裁剪移除），但缺正式隐私政策文本与 DPA 模板，发布前需法务定稿并接入法务文档模块。 |
| 6.2 | P1 | **EULA 强制签署链路验证** | EULA 实体已迁移至 EF 持久化（`EfRepository`，45 实体全量 EF 化的一部分）；需验证客户激活授权前的 EULA 签署留痕链路完整。 |
| 6.3 | P1 | **数据留存策略** | 明确审计日志、消费记录、Webhook 投递记录的保留期限与自动清理任务（Hangfire/Quartz 定时作业）。 |
| 6.4 | P2 | **Cookie / 跟踪合规** | 若面向欧盟用户，确认前端无未声明的第三方追踪，必要时加 Cookie 同意横幅。 |

## 七、测试与质量门禁

| # | 优先级 | 事项 | 建议 |
| - | ---- | ---- | ---- |
| 7.1 | P1 | **真实邮件/SMS 集成测试** | 当前 SMTP 走配置化客户端，缺针对真实邮箱（如 Mailhog/Mailtrap）的模板渲染与送达测试。 |
| 7.2 | P1 | **性能基线测试** | 对核心接口（签发、激活验证、列表）建立 k6/JMeter 基线：P95 延迟、吞吐、错误率，纳入发布准入。 |
| 7.3 | P1 | **迁移回滚演练** | EF 迁移需配套 Down 脚本验证，在预发环境至少完成一次升级→回滚→再升级演练。 |
| 7.4 | P2 | **E2E 视觉回归** | 手册截图脚本已具备零控制台错误校验，可扩展为 Playwright 视觉比对（toHaveScreenshot），防止 UI 回归。 |

## 八、文档与交付

| # | 优先级 | 事项 | 状态/建议 |
| - | ---- | ---- | ---- |
| 8.1 | ✔ | 用户使用手册 | 已完成（`LicenseManager-Platform-User-Manual-v1.0.md`，23 张零错误截图，覆盖登录/仪表盘（含角色差异）/产品/客户/授权/用户/Webhook/API 密钥/报表/审计全流程；订单相关章节已随商业化裁剪移除）。 |
| 8.2 | ✔ | API / 部署 / 安全 / 故障排查文档 | 已在 docs/ 齐备，发布前做一次版本号与内容一致性校对。 |
| 8.3 | P1 | **英文版用户手册** | 系统已支持英文界面，手册目前仅中文版，出海或多语言客户需补英文版（截图脚本加 locale 参数重跑即可）。 |
| 8.4 | P1 | **变更日志与版本策略** | 建立 CHANGELOG.md 与语义化版本（SemVer）约定，API 版本路径（/v1/）与文档版本对齐。 |
| 8.5 | P2 | **运维 Runbook** | 基于 Troubleshooting Guide 补充常见告警处置步骤（DB 连接失败、SMTP 故障切换；PSP Webhook 相关内容已随商业化下线）。 |

---

## 发布路径建议（按依赖排序）

```
阶段 1（阻断项清零）
  ├─ 1.1 ~~财务/合规/集成域实体 EF 持久化~~（**已全部完成**：45 个实体全量 EF 化，含 Invoice/PaymentIntent/Refund/WebhookEndpoint/WebhookDelivery/PspConfig/WebhookEventRecord/Quote/PaymentMethod/Integration/SsoProvider/EULA 等）
  ├─ 1.2 生产口令 fail-fast + 密钥入 Vault（OIDC JWT 签名验证已修复为 JWKS 验签）
  └─ 1.3 日志告警规则（健康检查分级已完成：/v1/healthz 与 /v1/readyz）
阶段 2（发布准入）
  ├─ 2.1 ~~Stripe 生产 key 对账联调验收（真实 API 对接已完成）+ Alipay 等其余 PSP 适配器落地（若含相应收款渠道）+ PayPal 沙箱验收~~（**已随商业化下线**，资金流移交外部销售系统）
  ├─ 2.2 服务端分页改造（授权/审计）
  ├─ 2.3 隐私政策/DPA 法务定稿 + 渗透测试
  └─ 2.4 性能基线 + 迁移回滚演练 + 备份恢复演练
阶段 3（发布就绪）
  ├─ 3.1 前端分包优化 + 英文手册
  ├─ 3.2 CHANGELOG / SemVer / Runbook
  └─ 3.3 全量回归（单测 + E2E + 手册截图零错误校验）
```

**结论：** 当前系统架构清晰、测试基线良好（2208 项后端测试全绿，数据截至 2026-09；支付退款防护、自动履约、出站 Webhook 投递、PayPal capture id、PSP 回调幂等等支付链路缺陷已于 2026-08 迭代修复——相关支付能力此后已随商业化裁剪下线，资金流由外部销售系统承接）、前后端功能覆盖面完整，已具备演示与内测条件；持久化覆盖主线已闭环（45 个实体全量 EF 化，商业实体已随 `RemoveCommerce` 迁移移除），距离产品级发布的主要差距集中在 **安全合规硬项（密钥管理、法务文本）** 主线（OIDC 验签已修复为 JWKS 验签），按上述三阶段推进即可达到发布标准。

---

## 复核勘误（2026-09-24）

> 本节为按当前代码（`src/`、`sdk/`、`tests/`）复核后的勘误与增量，前文各轮数字为当时快照、不再回改。

1. **测试基线**：Api.Tests 实测 **1066**（正文各处 1065 为上一轮快照），合计 **2209** 项全绿（Core 195 / Platform 742 / Infrastructure 172 / Server 34 / Api 1066）。
2. **端点规模**：API 控制器 37 个，`[Http*]` 动作特性实测 **531** 个（正文 v1.3 摘要中 ~526/~530 为估算值）。
3. **新增端点（本轮迭代落地）**：`GET /v1/keys`（签名公钥分发，匿名公开，已加入 `PublicPathRegistry` 白名单）、`GET /v1/customer/licenses/revocations`（客户吊销列表）、`POST /v1/customer/licenses/{licenseId}/airgap-sync`（离线消费同步）、`POST /v1/portal/offline/airgap-activate` 与 `POST /v1/portal/offline/upload-req`（Portal 离线激活）。
4. **SDK 能力增量**：五个 SDK（csharp/go/nodejs/python/rust）均已具备**本地 RSA-SHA256 验签**（含 `GET /v1/keys` 公钥缓存与按 keyVersion 选钥）、**浮动租约**（LeaseService：checkout/heartbeat/release/status，`X-Api-Key` 认证）与**气隙配套方法**（airgap-activate/decode、revocations、airgap-sync），且各自带测试（C# 契约测试控制台程序、go `*_test.go`、nodejs `npm test`、python `pytest`、rust `cargo test`）。
5. **认证双轨确认**：主 API 走 `Authorization` 头三方案（Bearer / ApiKey / Hmac）；独立浮动服务器（`LicenseManager.Server`）仅 `X-Api-Key`（缺失/错误 401 `INVALID_API_KEY`，未配置 503 `SERVER_NOT_CONFIGURED` fail-closed）。
6. **安全中间件复核通过**：`AuthenticationMiddleware` 统一 401 `auth.invalid_token`；`LoginSecurityService` 15 分钟窗口 5 次失败锁定；`SigningKeyStore`/`SystemKeyService` 密钥轮换（版本递增、旧版本保留验签）。上述实现与第二/四轮报告结论一致，无回归。
