Files
tiku-backend.net/README.md
xiong 603bc24c26
Some checks are pending
ci / release-gate (push) Waiting to run
feat(cache): adopt FusionCache for business caching
2026-08-05 09:30:48 +08:00

111 lines
5.5 KiB
Markdown
Raw Permalink 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.

# TIKU Backend
TIKU Backend 是题库 SaaS 的 ASP.NET Core 模块化单体,使用 EF Core 管理 PostgreSQL 数据。`Tiku.Api` 提供平台端、租户端和学生端接口,`Tiku.Worker` 独立处理周期任务与 PostgreSQL 后台任务。
![TIKU Backend 技术架构图](docs/assets/tiku-backend-architecture.svg)
## 当前技术栈
- .NET 10 / ASP.NET Core Controller API
- Entity Framework Core 10 + Npgsql 10 + PostgreSQL
- ASP.NET Core Identity + RSA JWT + 数据库存储的 Session
- Scalar + OpenAPI仅 Development 暴露)
- FusionCache业务 L1/L2 与跨节点失效)+ Redis安全频控、授权缓存和生产输出缓存
- PostgreSQL 后台任务队列、租约和重试
- Serilog + OpenTelemetry
- xUnit 单元测试和真实 PostgreSQL 集成测试
## 解决方案结构
```text
Tiku.Api HTTP API、中间件、认证授权和 OpenAPI/Scalar
Tiku.Worker 域名、订阅、用量校准、导出和安全扫描等后台处理
Tiku.Application 用例契约、应用服务接口和安全上下文
Tiku.Domain 领域实体、枚举和值对象
Tiku.Infrastructure EF Core、PostgreSQL、认证、后台任务和外部服务实现
Tiku.DbMigrator 数据库迁移、内置目录 seed 和平台管理员引导
Tiku.UnitTests 单元测试
Tiku.IntegrationTests API、授权、EF 模型、迁移和真实 PostgreSQL 测试
```
依赖方向固定为:`Domain <- Application <- Infrastructure``Api``Worker` 是彼此独立的运行时组合根,`DbMigrator` 是部署时迁移入口;第三方 SDK、数据库访问和密钥处理只放在 Infrastructure。
## 快速启动
需要 .NET 10 SDK、Node.js 24+ 和 Docker Desktop。本地 PostgreSQL、Redis 与 S3 兼容对象存储统一由根目录的 `compose.yaml` 提供:
```bash
cp .env.example .env
set -a
source .env
set +a
docker compose up -d --wait
dotnet restore TIKU-BACKEND.slnx
dotnet build TIKU-BACKEND.slnx --no-restore
dotnet run --project Tiku.DbMigrator
dotnet run --project Tiku.Api --launch-profile http
```
另开终端启动 Worker 时必须再次导入 `.env`
```bash
set -a
source .env
set +a
dotnet run --project Tiku.Worker
```
必须先从 `.env.example` 创建本地 `.env`,并在每个运行 .NET 的新终端中导入;否则 DbMigrator、API 和 Worker 可能连接到错误的 PostgreSQL/Redis。`.env` 不进入 Git。`docker compose ps` 应显示 PostgreSQL、Redis 与 MinIO 均为 `healthy`。Development 未配置阿里云 OSS 时,`local_dev` Provider 会把对象实际保存到 MinIO而不是返回占位结果。默认账号和密码只用于本机开发不能用于共享或生产环境。完整配置、内网访问、停止和排障步骤见[本地开发快速上手](docs/quickstart.md)。
默认 Development seed 会在尚无平台角色绑定时创建平台管理员 `admin@tiku.local` 和演示数据;随机临时密码只在首次创建时输出。日常步骤见[本地开发快速上手](docs/quickstart.md),不含演示数据的完整 SaaS 验收见[空数据库到租户建站验收](docs/tenant-provisioning.md)。
默认开发入口:
- 平台管理端:首次在 `Tiku.PlatformAdmin.Web` 执行 `npm install`;之后启动 `Tiku.Api` 时会在 Development 自动启动前端,访问 <http://localhost:5173>
- Scalar<http://localhost:5090/scalar/v1>
- OpenAPI<http://localhost:5090/openapi/v1.json>
- Liveness<http://localhost:5090/api/system/health>
- Readiness<http://localhost:5090/api/system/health/ready>
## 运行时边界
- API 不自动执行数据库迁移;部署和本地初始化都使用 `Tiku.DbMigrator`
- API 不运行后台循环;生产环境必须独立部署至少一个 `Tiku.Worker` 实例。
- 多 Worker 实例通过 PostgreSQL advisory lock、任务租约和 `FOR UPDATE SKIP LOCKED` 协调。
- Development 可不配置 RedisProduction 缺少 Redis 时 API 会拒绝启动。
- 租户目录、Feature 快照和运行时配置使用独立的 `TikuBusiness` FusionCache无 Redis 时退化为进程内 L1Redis 不是业务事实源。
- 租户由可信 Host 解析;平台 Host 上只有允许的路径可通过 `x-tenant-code``tenantCode` 指定租户。
- 租户数据由 EF Query Filter、写入拦截器、租户限定外键/唯一索引和 PostgreSQL guard 共同隔离。
- 普通请求默认要求认证;匿名接口必须显式声明 `[AllowAnonymous]`
- API 只在 Development 映射 OpenAPI 和 Scalar不应把文档端点作为生产依赖。
## 常用验证
```bash
dotnet build TIKU-BACKEND.slnx --no-restore
dotnet test TIKU-BACKEND.slnx --no-build
dotnet format TIKU-BACKEND.slnx --verify-no-changes --no-restore
dotnet ef migrations has-pending-model-changes \
--project Tiku.Infrastructure \
--startup-project Tiku.DbMigrator \
--no-build
git diff --check
```
PostgreSQL 特有的迁移、事务、约束和跨租户不变量必须由 `Tiku.IntegrationTests` 在真实 PostgreSQL 上验证,不能只依赖 EF InMemory。
## 文档
当前文档统一从[文档总览](docs/README.md)进入:
- [系统架构与业务边界](docs/architecture/overview.md)
- [模块边界与所有权](docs/architecture/module-boundaries.md)
- [认证、授权与租户隔离](docs/architecture/security-and-tenancy.md)
- [配置与后台任务](docs/operations.md)
- [本地开发快速上手](docs/quickstart.md)
- [空数据库到租户建站验收](docs/tenant-provisioning.md)
接口、DTO、请求参数和响应模型以运行时 OpenAPI/Scalar 为准;文档不再维护手写接口清单或迁移过程记录。