Files
tiku-backend.net/docs/architecture/overview.md
xiong 3385649a8d
Some checks failed
ci / release-gate (push) Has been cancelled
docs(architecture): sync runtime diagram and guidance
2026-08-04 14:40:25 +08:00

6.3 KiB
Raw Blame History

系统架构与业务边界

本文描述当前仓库的实际代码结构和运行时职责。接口路径、DTO 和响应模型以运行时 OpenAPI 为准。

分层与依赖

+------------------+  +------------------+  +-----------------+
| 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.ApiTiku.Worker 是独立运行时入口,Tiku.DbMigrator 是部署时迁移和 seed 入口。

运行时组件

API

Tiku.Api/Program.cs 只负责组合服务、构建应用和启用请求管线。管线的关键顺序是:

结构化请求日志 / 数据库请求指标 / 异常处理
  -> 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 启动 ViteProduction 仍应独立构建和部署API 不托管平台前端静态文件。

DbMigrator

Tiku.DbMigrator 是唯一迁移入口,执行顺序为:

  1. 解析 ConnectionStrings:DatabaseDATABASE_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,限制为 103600 秒 校验自定义域名 CNAME/TXT调用网关 TLS 接口并失效租户缓存
SaasSubscriptionWorker 60 秒 处理到期、宽限期等 SaaS 订阅生命周期
FeatureUsageWorker FeatureUsageReconciliation:IntervalMinutes,限制为 11440 分钟 按真实业务数据校准租户 Feature 用量
BackgroundJobsWorker 默认 2 秒、4 个分区 使用租约处理 PostgreSQL 中的即时、延时和待重试任务
AuthorizationCacheInvalidationWorker 默认 2 秒 重试 PostgreSQL 中待处理的 Redis 授权缓存失效事件
CommercialBillingWorker 60 秒 生成续费应收与催缴提醒、投递启用渠道并执行已审批退款
PlatformApprovalWorker 默认 2 秒 异步执行已经满足审批策略的平台命令

后台任务处理器由所属 Infrastructure 模块实现并注册Jobs 模块按 JobType 调度。当前类型包括 content_importcontent_exportasset_security_scantenant_exportstatistics_aggregationcommerce_reconciliationtenant_domain_recheck;架构测试校验处理器数量、类型和模块注册。安全扫描通过 ClamAV INSTREAM 流式处理对象,未通过扫描或扫描不可用时不签发资源访问地址。

即时任务与 RunAfter 延时任务统一写入 background_jobsBackgroundJobsWorker 使用 FOR UPDATE SKIP LOCKED 和五分钟租约,允许多个 Worker 实例并行消费;其余六个周期处理器使用 PostgreSQL advisory lock 保持集群单例执行。商业续费、应收、退款和催缴投递仍以 PostgreSQL 表为权威,不引入消息代理。

数据与持久化

  • 数据库使用标准 PostgreSQL普通 schema 由 EF Core entity、Fluent Configuration 和 Migration 管理。
  • 当前模型启用 citextltreepg_trgm 扩展,并统一映射为 snake_case
  • Data Protection key ring 由 API 持久化到 PostgreSQL非 Development 必须使用 X509 证书保护。
  • 后台任务状态、执行时间、重试和结果由 background_jobs 持久化。
  • PostgreSQL 不启用 RLS租户隔离由应用和数据库多层共同保证详见认证、授权与租户隔离

业务入口

Audience 主要边界
Platform 租户开通与生命周期、员工/RBAC、治理审批、平台题库、SaaS 账务、运营与告警
Tenant 成员与 DataScope、内容题库、学习运营、学生/班级、CRM、商城增长及租户 Provider 配置
Student/Public Host 运行时配置、认证资料、学习与进度、商城权益、推荐关系和公开内容

具体操作、权限元数据和 DTO 以运行时 OpenAPI 为准。

外部服务边界

Application 通过接口表达身份、短信、对象存储、支付、通知、域名和 AI 能力Infrastructure 当前包含自托管身份、阿里云短信/OSS、S3 兼容本地对象存储、微信、支付宝、站内通知、DNS JSON 查询和 HTTP 网关实现。

租户级 Provider 元数据和密钥分别存入 TenantExternalProviderTenantSecret。密钥由 32 字节 master key 加密API 不应把明文、SecretRef 或 Provider 内部 payload 返回给客户端。