107 lines
6.3 KiB
Markdown
107 lines
6.3 KiB
Markdown
# 系统架构与业务边界
|
||
|
||
本文描述当前仓库的实际代码结构和运行时职责。接口路径、DTO 和响应模型以运行时 OpenAPI 为准。
|
||
|
||
## 分层与依赖
|
||
|
||
```text
|
||
+------------------+ +------------------+ +-----------------+
|
||
| Tiku.Api | | Tiku.Worker | | Tiku.DbMigrator |
|
||
| HTTP API | | Background loops | | Migrate + Seed |
|
||
+--------+---------+ +--------+---------+ +--------+--------+
|
||
| | |
|
||
+---------------------+---------------------+
|
||
v
|
||
+---------------------+
|
||
| Tiku.Infrastructure |
|
||
+----------+----------+
|
||
v
|
||
+---------------------+
|
||
| Tiku.Application |
|
||
+----------+----------+
|
||
v
|
||
+---------------------+
|
||
| Tiku.Domain |
|
||
+---------------------+
|
||
```
|
||
|
||
- `Tiku.Domain` 保存领域实体、枚举和基础类型。除 Identity stores 抽象外,不依赖持久化或 Provider SDK。
|
||
- `Tiku.Application` 定义用例契约、Provider 接口、安全上下文和业务目录,依赖 Domain。
|
||
- `Tiku.Infrastructure` 实现 EF Core、PostgreSQL、Identity、外部 Provider 和后台任务,依赖 Application 与 Domain。
|
||
- `Tiku.Api` 与 `Tiku.Worker` 是独立运行时入口,`Tiku.DbMigrator` 是部署时迁移和 seed 入口。
|
||
|
||
## 运行时组件
|
||
|
||
### API
|
||
|
||
`Tiku.Api/Program.cs` 只负责组合服务、构建应用和启用请求管线。管线的关键顺序是:
|
||
|
||
```text
|
||
结构化请求日志 / 数据库请求指标 / 异常处理
|
||
-> Forwarded Headers / HTTPS / 响应压缩
|
||
-> Routing / CORS
|
||
-> Host 租户解析
|
||
-> 浏览器 CSRF
|
||
-> JWT 认证 / 认证专用限流 / 全局限流
|
||
-> 当前用户上下文 / 授权
|
||
-> SaaS Feature 校验
|
||
-> Output Cache
|
||
-> Controllers
|
||
```
|
||
|
||
OpenAPI 和 Scalar 只在 Development 映射。平台管理端位于独立的 `Tiku.PlatformAdmin.Web` React 工程,由 OpenAPI 生成接口契约;Development 通过 `Tiku.Api.csproj` 的 SPA Proxy 启动 Vite,Production 仍应独立构建和部署,API 不托管平台前端静态文件。
|
||
|
||
### DbMigrator
|
||
|
||
`Tiku.DbMigrator` 是唯一迁移入口,执行顺序为:
|
||
|
||
1. 解析 `ConnectionStrings:Database` 或 `DATABASE_URL`。
|
||
2. 进入带审计原因的 System Scope。
|
||
3. 执行 `Database.MigrateAsync()`。
|
||
4. seed 内置 SaaS Feature、PermissionModule、BackendPermission、BackendMenu 和 `starter` 套餐目录。
|
||
5. 默认 Development seed 在尚无平台角色绑定时创建平台管理员与演示数据;`--skip-development-seed` 可关闭该行为,`--bootstrap-platform-admin` 用于显式创建首个平台管理员。
|
||
|
||
API 不自动迁移数据库。
|
||
|
||
### Worker 后台处理
|
||
|
||
`Tiku.Worker` 独立注册七个 Hosted Service。API 不承载这些生产后台循环;仅 Development 会额外注册 `.localhost` 域名生命周期旁路,方便本地建站验收。
|
||
|
||
| Worker | 周期 | 当前职责 |
|
||
| --- | --- | --- |
|
||
| `TenantDomainWorker` | `TenantDomains:PollSeconds`,限制为 10~3600 秒 | 校验自定义域名 CNAME/TXT,调用网关 TLS 接口并失效租户缓存 |
|
||
| `SaasSubscriptionWorker` | 60 秒 | 处理到期、宽限期等 SaaS 订阅生命周期 |
|
||
| `FeatureUsageWorker` | `FeatureUsageReconciliation:IntervalMinutes`,限制为 1~1440 分钟 | 按真实业务数据校准租户 Feature 用量 |
|
||
| `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`。`BackgroundJobsWorker` 使用 `FOR UPDATE SKIP LOCKED` 和五分钟租约,允许多个 Worker 实例并行消费;其余六个周期处理器使用 PostgreSQL advisory lock 保持集群单例执行。商业续费、应收、退款和催缴投递仍以 PostgreSQL 表为权威,不引入消息代理。
|
||
|
||
## 数据与持久化
|
||
|
||
- 数据库使用标准 PostgreSQL,普通 schema 由 EF Core entity、Fluent Configuration 和 Migration 管理。
|
||
- 当前模型启用 `citext`、`ltree` 和 `pg_trgm` 扩展,并统一映射为 `snake_case`。
|
||
- Data Protection key ring 由 API 持久化到 PostgreSQL;非 Development 必须使用 X509 证书保护。
|
||
- 后台任务状态、执行时间、重试和结果由 `background_jobs` 持久化。
|
||
- PostgreSQL 不启用 RLS;租户隔离由应用和数据库多层共同保证,详见[认证、授权与租户隔离](security-and-tenancy.md)。
|
||
|
||
## 业务入口
|
||
|
||
| Audience | 主要边界 |
|
||
| --- | --- |
|
||
| Platform | 租户开通与生命周期、员工/RBAC、治理审批、平台题库、SaaS 账务、运营与告警 |
|
||
| Tenant | 成员与 DataScope、内容题库、学习运营、学生/班级、CRM、商城增长及租户 Provider 配置 |
|
||
| Student/Public | Host 运行时配置、认证资料、学习与进度、商城权益、推荐关系和公开内容 |
|
||
|
||
具体操作、权限元数据和 DTO 以运行时 OpenAPI 为准。
|
||
|
||
## 外部服务边界
|
||
|
||
Application 通过接口表达身份、短信、对象存储、支付、通知、域名和 AI 能力;Infrastructure 当前包含自托管身份、阿里云短信/OSS、S3 兼容本地对象存储、微信、支付宝、站内通知、DNS JSON 查询和 HTTP 网关实现。
|
||
|
||
租户级 Provider 元数据和密钥分别存入 `TenantExternalProvider` 与 `TenantSecret`。密钥由 32 字节 master key 加密,API 不应把明文、`SecretRef` 或 Provider 内部 payload 返回给客户端。
|