Files
tiku-backend.net/docs/migration/phase-5-backoffice-worker-operations.md

195 lines
6.6 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.

# 阶段五后台能力底座、Worker 基座与运营闭环
状态已完成第一轮底座实现并通过本地验收2026-07-28
本阶段从核心 SaaS 架构重构进入后台运营能力补齐。目标不是逐字兼容旧 NestJS而是在当前 ASP.NET Core + EF Core + PostgreSQL 架构下重建后台权限、菜单、审计、交易运营和 Worker 基座,并参考 yudao 的后台能力清单补齐系统底座。
## 固定 SDK 选型
微信生态统一使用 Senparc
- `Senparc.Weixin`
- `Senparc.Weixin.MP`
- `Senparc.Weixin.WxOpen`
- `Senparc.Weixin.TenPayV3`
已移除并禁止:
- `SKIT.FlurlHttpClient.Wechat.*`
其他外部服务:
- OSS`AlibabaCloud.OSS.V2`
- 阿里云短信:`AlibabaCloud.SDK.Dysmsapi20170525`
- 支付宝:`AlipaySDKNet.Standard`
- Worker`Microsoft.Extensions.Hosting` + `BackgroundService`
业务层仍然只依赖 Application 接口:
- `IIdentityProvider`
- `IObjectStorageService`
- `ISmsProvider`
- `IPaymentProvider`
- `INotificationProvider`
第三方 SDK namespace 只允许出现在 Infrastructure provider 实现中。
## 5A微信 Provider 收敛
`WechatPayProvider` 已切换到 `Senparc.Weixin.TenPayV3`
- JSAPI / H5 下单参数生成走 Senparc TenPayV3。
- JSAPI 前端支付参数使用 Senparc 签名 helper 生成。
- 支付 provider 继续通过 `IPaymentProvider` 暴露,不向 Application 或 API 泄漏 Senparc 类型。
- 架构测试禁止生产代码引用 `SKIT.FlurlHttpClient.Wechat`
说明:当前 `IPaymentProvider` 的回调入口抽象为 body + headers不直接暴露 `HttpContext`。Senparc 官方推荐的 `TenPayNotifyHandler(HttpContext)` 回调验签/解密模式后续可以在 Infrastructure 的 HTTP 适配层补强,但不能把 Senparc 类型扩散到业务层。
## 5B后台权限、菜单、角色与审计底座
新增后台基础模型:
- `BackendPermission`
- `BackendMenu`
- `TenantBackendRole`
- `TenantBackendRolePermission`
- `TenantBackendRoleMenu`
- `TenantBackendUserRole`
- `PlatformBackendRole`
- `PlatformBackendRolePermission`
- `PlatformBackendRoleMenu`
- `PlatformBackendUserRole`
设计边界:
- 权限点是稳定字符串 code。
- 菜单只控制后台 UI 展示,不作为唯一 API 鉴权来源。
- 平台角色和租户角色分表。
- 租户角色绑定包含 `TenantId`,平台角色绑定不带租户键。
- 角色、权限、菜单、用户角色绑定写操作落 `AuditLog`
新增接口:
- `GET /api/backoffice/tenant/bootstrap`
- `POST /api/backoffice/tenant/roles`
- `PUT /api/backoffice/tenant/roles/{roleId}/bindings`
- `PUT /api/backoffice/tenant/users/{userId}/roles`
- `GET /api/backoffice/platform/bootstrap`
- `POST /api/backoffice/platform/roles`
- `PUT /api/backoffice/platform/roles/{roleId}/bindings`
- `PUT /api/backoffice/platform/users/{userId}/roles`
`TenantAdminDirect` 继续作为过渡入口;新增后台能力使用 `backoffice` 模块命名。
## 5E交易运营底座
在现有 commerce 模型上补齐租户后台运营服务:
- 退款申请。
- 退款状态流转。
- 退款事件记录。
- 对账批次创建。
- 对账 issue 查询与状态流转。
- 退款、对账写操作落审计。
退款状态流转由服务控制,不能任意跳转。支付、回调、退款后续仍统一走 `IPaymentProvider`,初期不默认开启真实自动退款。
新增租户交易运营接口:
- `GET /api/tenant-commerce/refunds`
- `POST /api/tenant-commerce/refunds`
- `POST /api/tenant-commerce/refunds/status`
- `GET /api/tenant-commerce/refunds/{refundRequestId}/events`
- `GET /api/tenant-commerce/reconciliation/batches`
- `POST /api/tenant-commerce/reconciliation/batches`
- `GET /api/tenant-commerce/reconciliation/issues`
- `POST /api/tenant-commerce/reconciliation/issues/status`
## 5FWorker 与后台任务基座
新增统一任务模型 `BackgroundJob`
- `JobType`
- `TenantId`
- `Payload`
- `Status`
- `RetryCount`
- `MaxRetries`
- `LockedBy`
- `LockExpiresAt`
- `RunAfter`
- `StartedAt`
- `CompletedAt`
- `LastError`
- `OutputAssetId`
- `Result`
Worker 基于 `Microsoft.Extensions.Hosting` + `BackgroundService`,暂不引入 Hangfire。后续需要复杂 cron 时再评估 `Quartz.Extensions.Hosting`
当前任务处理器建立了幂等租户 Scope 入口和状态机骨架,覆盖以下 job type
- `content_export`
- `content_import`
- `asset_security_scan`
- `statistics_aggregation`
- `commerce_reconciliation`
- `tenant_domain_recheck`
新增租户后台任务接口:
- `GET /api/backoffice/tenant/jobs`
- `POST /api/backoffice/tenant/jobs`
API 只负责创建任务和查询任务Worker 必须通过 `ITenantExecutionScope` 初始化执行上下文。
## 阿里云短信 Provider
`ISmsProvider` 默认接入租户 Provider 配置:
- 未配置短信 provider 时,本地/测试降级为 `noop`
- 配置 `aliyun_sms` 时,从 `TenantExternalProvider(capability=sms)` 读取公开配置。
- `signName``templateCode``endpoint``regionId` 等公开字段放 `ConfigPublic`
- `accessKeyId``accessKeySecret` 只允许通过 `TenantSecret` 解密获得。
- 发送失败会记录 `SmsVerificationStatus.Failed`,不会留下可验证验证码。
## 数据库约束补强
阶段五重建 `InitialSchema` 时同步补齐阶段三遗漏的两个 PostgreSQL 硬约束:
- `TenantQuestionReference` 只能引用平台主体公共题或当前租户私题。
- `TaxonomyNode` 父节点只能属于平台主体或当前租户。
这类跨表租户不变量不能靠 EF Core FK / check constraint 自动表达,统一放在 `PostgreSqlTenantConstraintSql`,由 migration 调用,并由真实 PostgreSQL 集成测试覆盖。
## 架构测试
新增或强化禁止项:
- 生产代码不得引用 `SKIT.FlurlHttpClient.Wechat`
- 业务层不得直接引用阿里云 OSS、阿里云短信、Senparc、支付宝 SDK namespace。
- 生产代码不得回流 Supabase provider、Supabase Storage 或旧专用 provider 表模型。
- 普通业务目录继续禁止 `IgnoreQueryFilters``FromSql``ExecuteSql` 和直接 `NpgsqlCommand`
## 验收结果
本阶段本地验收:
```bash
dotnet restore TIKU-BACKEND.slnx
dotnet build TIKU-BACKEND.slnx --no-restore
dotnet test Tiku.UnitTests/Tiku.UnitTests.csproj --no-build
dotnet test Tiku.IntegrationTests/Tiku.IntegrationTests.csproj --no-build
dotnet ef migrations script --project Tiku.Infrastructure --startup-project Tiku.DbMigrator
git diff --check
```
结果:
- build0 警告0 错误。
- unit tests18/18 通过。
- integration tests264/264 通过。
- migration script生成成功。
- 空 PostgreSQL 通过 `Tiku.DbMigrator` 建库成功。
- PostgreSQL 验证两个租户约束 trigger 已创建。