diff --git a/docs/architecture/overview.md b/docs/architecture/overview.md index f372a4e..eed9c70 100644 --- a/docs/architecture/overview.md +++ b/docs/architecture/overview.md @@ -65,7 +65,7 @@ API 不自动迁移数据库。 ### Worker 后台处理 -`Tiku.Worker` 独立注册六个 Hosted Service。API 不承载这些生产后台循环;仅 Development 会额外注册 `.localhost` 域名生命周期旁路,方便本地建站验收。 +`Tiku.Worker` 独立注册七个 Hosted Service。API 不承载这些生产后台循环;仅 Development 会额外注册 `.localhost` 域名生命周期旁路,方便本地建站验收。 | Worker | 周期 | 当前职责 | | --- | --- | --- | @@ -75,10 +75,11 @@ API 不自动迁移数据库。 | `BackgroundJobsWorker` | 默认 2 秒、4 个分区 | 使用租约处理 PostgreSQL 中的即时、延时和待重试任务 | | `AuthorizationCacheInvalidationWorker` | 默认 2 秒 | 重试 PostgreSQL 中待处理的 Redis 授权缓存失效事件 | | `CommercialBillingWorker` | 60 秒 | 生成续费应收与催缴提醒、投递启用渠道并执行已审批退款 | +| `PlatformApprovalWorker` | 默认 2 秒 | 异步执行已经满足审批策略的平台命令 | 后台任务处理器由所属 Infrastructure 模块实现并注册,Jobs 模块按 `JobType` 调度。当前类型包括 `content_import`、`content_export`、`asset_security_scan`、`tenant_export`、`statistics_aggregation`、`commerce_reconciliation` 和 `tenant_domain_recheck`;架构测试校验处理器数量、类型和模块注册。安全扫描通过 ClamAV `INSTREAM` 流式处理对象,未通过扫描或扫描不可用时不签发资源访问地址。 -即时任务与 `RunAfter` 延时任务统一写入 `background_jobs`。后台任务用 `FOR UPDATE SKIP LOCKED` 和五分钟租约协调;六个周期处理器使用 PostgreSQL advisory lock,允许部署多个 Worker 实例而不重复执行同一周期循环。商业续费、应收、退款和催缴投递仍以 PostgreSQL 表为权威,不引入消息代理。 +即时任务与 `RunAfter` 延时任务统一写入 `background_jobs`。`BackgroundJobsWorker` 使用 `FOR UPDATE SKIP LOCKED` 和五分钟租约,允许多个 Worker 实例并行消费;其余六个周期处理器使用 PostgreSQL advisory lock 保持集群单例执行。商业续费、应收、退款和催缴投递仍以 PostgreSQL 表为权威,不引入消息代理。 ## 数据与持久化 diff --git a/docs/architecture/security-and-tenancy.md b/docs/architecture/security-and-tenancy.md index 4708908..a3fbe19 100644 --- a/docs/architecture/security-and-tenancy.md +++ b/docs/architecture/security-and-tenancy.md @@ -4,10 +4,14 @@ ## 认证入口 -API 支持两组认证接口: +API 按客户端边界提供四组认证接口: -- `/api/tenant/auth/**` 返回 access token 与 refresh token,适合 Bearer 客户端。 -- `/api/tenant/auth/browser/**` 把 token 写入 HttpOnly Cookie,适合同源浏览器客户端。 +- `/api/platform/auth/**`:平台授权域的 Bearer 客户端入口。 +- `/api/tenant/auth/**`:租户员工授权域的 Bearer 客户端入口。 +- `/api/student/auth/**`:学生客户端入口;与租户端共享本地账号能力,但必须使用租户授权域且匹配当前租户上下文。 +- `/api/tenant/auth/browser/**`:租户同源浏览器入口,把 token 写入 HttpOnly Cookie。 + +前三组 Bearer 路径共享认证实现,但路由与请求中的 Realm 必须一致;平台路径只接受 Platform Realm,租户端和学生端路径不接受 Platform Realm。 当前登录方式: diff --git a/docs/assets/tiku-backend-architecture.svg b/docs/assets/tiku-backend-architecture.svg index a5b9313..1793c87 100644 --- a/docs/assets/tiku-backend-architecture.svg +++ b/docs/assets/tiku-backend-architecture.svg @@ -1,6 +1,6 @@ TIKU Backend 当前技术架构图 - TIKU Backend 是 ASP.NET Core 模块化单体。API 承载 HTTP,Worker 独立处理后台任务,DbMigrator 负责迁移,运行时依赖 PostgreSQL、Redis 和外部服务。 + TIKU Backend 是 ASP.NET Core 模块化单体。API 按平台、租户和学生客户端边界承载 HTTP,Worker 独立处理后台任务与平台审批,DbMigrator 负责迁移,运行时依赖 PostgreSQL、Redis、对象存储和外部服务。 @@ -47,7 +47,7 @@ P 平台管理端 React / Vite 管理端 - 平台账号 · SaaS 运营 + Platform Realm · 治理审批 @@ -61,7 +61,7 @@ H5 学员端 H5 / 小程序 / App - 学习 · 题库 · 商城 + Student 路径 · Tenant Realm @@ -91,7 +91,7 @@ Controller 边界 - 平台 SaaS 管理 · 租户后台 + 平台治理审批 · SaaS 管理 · 租户后台 题库内容学习 · 商城增长 认证运行时 · 支付回调 · 后台任务 @@ -107,7 +107,7 @@ Tiku.Application:契约与执行上下文 - 用例接口 / Provider 接口 · TenantContext · CurrentUser + 用例 / Provider 契约 · Tenant / User / SystemScope 仅引用 Domain;不包含 EF Core 与第三方 SDK @@ -123,7 +123,7 @@ 身份认证 租户 / 域名 RBAC / Feature - SaaS / 审计 + SaaS / 治理审批 教育业务 @@ -158,8 +158,8 @@ 独立后台运行时 域名 / 订阅 / 用量 任务 / 授权缓存失效 - 商业账务 / Worker 心跳 - PostgreSQL 锁与任务租约 + 商业账务 / 平台审批 + 任务租约 / Advisory Lock @@ -185,16 +185,16 @@ PG PostgreSQL EF Core 实体 / Identity / AuthSession - 业务数据 / BackgroundJob / Session - Query Filter · 写入拦截 · 数据库 Guard + 业务 / BackgroundJob / 审批与审计 + 事实源 · Query Filter · 写入拦截 · Guard R Redis - 安全频控 + 安全频控 / 授权缓存 Feature / Output Cache - Production 必需 + 非事实源 · Production 必需 @@ -206,7 +206,7 @@ 对象存储 - Alibaba Cloud OSS + Alibaba OSS / S3 / MinIO 预签名上传 / 资源访问 IObjectStorageService diff --git a/docs/operations.md b/docs/operations.md index cc74802..3c2d51b 100644 --- a/docs/operations.md +++ b/docs/operations.md @@ -104,7 +104,7 @@ Redis key 使用环境前缀;配置解析会强制 `AbortOnConnectFail=false` `TenantProvisioning:DefaultBaseOfferingCode` 必须指向 Active 基础套餐的有效 Published 版本。Production 启动与租户开通事务都会校验,缺失时返回 `default_offering_unavailable`。完整流程见[空数据库到租户建站验收](tenant-provisioning.md)。 -后台任务状态和 `RunAfter` 存在 PostgreSQL。Worker 使用 `FOR UPDATE SKIP LOCKED`、五分钟租约和有限重试;周期循环使用 PostgreSQL advisory lock 防止多实例重复执行。通用任务由模块注册的 `IBackgroundJobHandler` 处理,Jobs 模块负责查找、租约、重试和失败补偿。六个循环处理域名、订阅、Feature 用量、通用任务、授权缓存失效和商业账务。`Worker:Enabled=false` 会关闭全部循环。 +后台任务状态和 `RunAfter` 存在 PostgreSQL。`BackgroundJobsWorker` 使用 `FOR UPDATE SKIP LOCKED`、五分钟租约和有限重试,允许多个 Worker 实例并行消费;其他周期处理器使用 PostgreSQL advisory lock 防止重复执行。通用任务由模块注册的 `IBackgroundJobHandler` 处理,Jobs 模块负责查找、租约、重试和失败补偿。七个循环处理域名、订阅、Feature 用量、通用任务、授权缓存失效、商业账务和平台审批执行。`Worker:Enabled=false` 会关闭全部循环。 API 和 Worker 必须使用同一 PostgreSQL 数据库与一致的对象存储配置。迁移必须在两者启动前由 `Tiku.DbMigrator` 单独执行。 @@ -119,7 +119,7 @@ API 和 Worker 应独立设置副本数与资源限制。发布顺序固定为 ` ## 发布门禁、备份恢复和告警 -`.github/workflows/ci.yml` 执行 restore、build、完整测试、format、EF 模型漂移、幂等 Migration SQL、平台前端检查、OpenAPI 生成漂移、API/Worker 镜像构建和 `git diff --check`。本地发布前应执行相同检查。 +`.gitea/workflows/ci.yaml` 执行 restore、build、完整测试、format、EF 模型漂移、幂等 Migration SQL、平台前端检查、OpenAPI 生成漂移、API/Worker 镜像构建和 `git diff --check`。本地发布前应执行相同检查。 PostgreSQL 恢复演练使用标准 `PGHOST`、`PGPORT`、`PGUSER`、`PGPASSWORD` 环境变量,并通过 `TIKU_BACKUP_SOURCE_DATABASE` 指定源数据库: