forked from xiongyuxing/tiku-backend.net
182 lines
7.1 KiB
Markdown
182 lines
7.1 KiB
Markdown
# TIKU Backend
|
||
|
||
题库 SaaS 正式后端。项目正在从旧 PocketBase / Supabase / Nest 方案迁到更可控的 ASP.NET Core + PostgreSQL 架构。本仓库是后续开发的唯一目标后端,架构决策见 [`docs/adr/0001-authoritative-dotnet-backend.md`](docs/adr/0001-authoritative-dotnet-backend.md)。
|
||
|
||
当前判断很明确:现在团队已经有后端开发,继续把核心认证、权限、多租户隔离、业务一致性交给 BaaS 规则,会让复杂度藏在平台、SQL policy 和前端约定之间。新后端把这些东西收回应用层和数据库约束里,开发、排查、审计都会更直接。
|
||
|
||
## 技术栈与分层
|
||
|
||
- ASP.NET Core Controller API
|
||
- Entity Framework Core + Npgsql
|
||
- PostgreSQL
|
||
- Serilog
|
||
- ZLinq
|
||
- AlibabaCloud.OSS.V2
|
||
- xUnit
|
||
|
||
```text
|
||
Tiku.Api # HTTP API、认证授权、OpenAPI/Scalar
|
||
Tiku.Application # 应用服务、用例编排、接口抽象
|
||
Tiku.Domain # 领域实体、枚举、基础类型
|
||
Tiku.Infrastructure # EF Core、PostgreSQL、外部服务实现
|
||
Tiku.DbMigrator # 数据库迁移启动项目
|
||
Tiku.Worker # 后台任务入口
|
||
Tiku.UnitTests # 单元测试
|
||
Tiku.IntegrationTests # API / EF 模型集成测试
|
||
```
|
||
|
||
## 相比原版的主要优势
|
||
|
||
### 1. 安全边界更清楚
|
||
|
||
旧版把安全逻辑分散在 Nest API、Supabase Auth/RLS、SQL policy、脚本和前端约定里。新后端改为:
|
||
|
||
- ASP.NET Authentication 负责身份认证。
|
||
- ASP.NET Authorization 负责权限策略。
|
||
- JWT + 数据库 `auth_sessions` 负责 access/refresh/session 闭环。
|
||
- `ICurrentUser` / 只读 `ITenantContext` 统一当前用户和请求租户上下文。
|
||
- EF Core Query Filter、写入拦截器和 PostgreSQL 组合约束共同阻断跨租户读写。
|
||
- PostgreSQL FK / unique / check / index 负责数据完整性底线。
|
||
- 审计事件表记录关键行为。
|
||
|
||
新系统不照搬 Supabase RLS、`app_private` schema 和生产防护 SQL,权限主要在应用层实现,数据库负责硬约束。
|
||
|
||
### 2. 多租户约束不再靠“大家小心”
|
||
|
||
新库以多租户为一等设计:
|
||
|
||
- 租户数据表默认带 `TenantId`。
|
||
- 跨租户引用优先使用 composite FK,例如 `(tenant_id, id)`。
|
||
- 业务 API 默认从当前请求上下文解析租户,不信任请求 body 里的 `tenantId`。
|
||
- 租户域名、品牌、设置、角色、班级、学生运营都已经有独立模型。
|
||
|
||
这比旧版在 API、RLS、前端之间反复拼 tenant 条件更可控。
|
||
|
||
### 3. PostgreSQL 能力被正经使用
|
||
|
||
- JSON 字段统一使用 C# `JsonElement`,映射 PostgreSQL `jsonb`。
|
||
- 内容树路径使用 `ltree`。
|
||
- 域名、兑换码等大小写不敏感字段使用 `citext`。
|
||
- 数组使用 PostgreSQL array,不塞字符串。
|
||
- 钱相关字段使用 cents 或明确 decimal precision。
|
||
- 关键唯一性和状态底线落数据库约束。
|
||
|
||
### 4. 运行时地基补齐
|
||
|
||
旧版对连接池、日志、跨域、限流、配置校验这些工程底座比较薄。新后端已经补上:
|
||
|
||
- 单例 `NpgsqlDataSource` + scoped `AddDbContext<TikuDbContext>`,避免租户状态跨请求复用。
|
||
- Serilog 结构化日志和请求上下文日志。
|
||
- 集中 CORS 配置,生产默认不放开 Origin。
|
||
- ASP.NET RateLimiter 全局限流。
|
||
- Options `ValidateOnStart()` 启动校验。
|
||
- ZLinq 作为后续热路径低分配工具。
|
||
|
||
### 5. 资源存储不绑 Supabase
|
||
|
||
旧版资源层实际使用 Node `ali-oss`。新后端按这个方向迁移到 `AlibabaCloud.OSS.V2`:
|
||
|
||
- Application 只依赖 `IObjectStorageService`。
|
||
- Infrastructure 收敛阿里云 OSS SDK 细节。
|
||
- 对象 key 默认要求租户前缀,避免资源混放。
|
||
- 上传签名前校验 MIME、大小和 provider。
|
||
- 下载/预览必须先过业务授权,再签发临时 URL。
|
||
- OSS HEAD metadata 用于上传确认、大小/MIME/ETag/安全扫描校验。
|
||
|
||
## 当前阶段成果
|
||
|
||
### 数据库
|
||
|
||
数据库模型迁移已经完成到 greenfield 初始 schema:
|
||
|
||
```text
|
||
Tiku.Infrastructure/Persistence/Migrations/20260727084726_InitialSchema.cs
|
||
```
|
||
|
||
当前 EF 模型覆盖:
|
||
|
||
- 租户、用户、成员、认证、Session、短信验证码
|
||
- 地区、模块、院校、专业、科目、分类
|
||
- 平台公共题库、租户私有题库、题目引用和题目版本
|
||
- 公共分类主干、租户扩展分类、内容入口、题集和练习蓝图
|
||
- 词汇、手册、用户单词进度
|
||
- 资源、图片、App 资源、视频解析、导入任务
|
||
- 版本锁定练习、答题、收藏、错题、报告、统计
|
||
- 自定义域名 DNS/TLS 生命周期和版本化前端运行时配置
|
||
- 商品、订单、支付、权益、兑换码、优惠券
|
||
- 推广、CRM、佣金
|
||
- Banner、FAQ、公告、通知、徽章、审计
|
||
- 平台账单、催收、审计告警
|
||
- PocketBase 导入审计
|
||
|
||
### 安全与认证
|
||
|
||
已完成:
|
||
|
||
- JWT Bearer 认证。
|
||
- 数据库 Session 校验;登出/撤销后旧 token 会被拒绝。
|
||
- 手机号 + 密码登录。
|
||
- 短信验证码登录。
|
||
- 微信网页 OAuth 登录。
|
||
- 微信小程序登录。
|
||
- 当前用户 `/api/me`。
|
||
- 当前租户 `/api/tenants/current`。
|
||
- 租户公开解析和公开配置。
|
||
- 统一异常响应和请求日志。
|
||
|
||
### 已迁移 API
|
||
|
||
2026-07-27 运行时 OpenAPI 基线包含 192 个路径、237 个操作。已完成的业务/API 闭环包括:
|
||
|
||
- health
|
||
- tenant resolve / current public
|
||
- auth password / sms / wechat / refresh / logout
|
||
- me / current tenant
|
||
- catalog 基础只读
|
||
- content navigation 只读
|
||
- question bank 只读
|
||
- vocabulary / handbook 只读
|
||
- asset / image / app asset / video catalog 只读
|
||
- asset download / preview 授权签名
|
||
|
||
## 还剩多少待迁移
|
||
|
||
运行时契约基线显示,旧 NestJS 有 342 个操作,当前 .NET 有 237 个操作:
|
||
|
||
```text
|
||
旧版 endpoint 总量:约 342
|
||
当前 .NET 操作:237
|
||
```
|
||
|
||
两边路径设计并非逐字兼容,不能用 `342 - 237` 推算剩余工作量。详细机械比较和后续取舍入口见 [`docs/migration/contracts/operation-inventory.csv`](docs/migration/contracts/operation-inventory.csv)。旧版里有不少平台运营、商业化自动化、审计告警、积分、督导、对账等后段能力,应按新架构重新筛选。
|
||
|
||
优先级建议:
|
||
|
||
1. 运营内容只读:Banner、FAQ、公告、考试日期、商品/SVIP 套餐。
|
||
2. 学习闭环:练习会话、提交答案、收藏、错题、单词进度。
|
||
3. 资源管理:上传签名、上传确认、导入任务查询。
|
||
4. 租户后台:角色、班级、学生、域名、品牌、登录 Provider。
|
||
5. 商业化:订单、支付、权益、兑换码、优惠券。
|
||
6. 内容管理:题目、题集、词汇、手册、视频的后台写接口。
|
||
7. 推广/CRM/佣金。
|
||
8. 平台后台:租户、账单、对账、退款、催收、审计告警。
|
||
9. Worker:导入、统计、资产扫描、通知、对账、账单。
|
||
|
||
## 常用命令
|
||
|
||
```bash
|
||
dotnet restore TIKU-BACKEND.slnx
|
||
dotnet build TIKU-BACKEND.slnx --no-restore
|
||
dotnet test TIKU-BACKEND.slnx --no-build
|
||
dotnet format TIKU-BACKEND.slnx --verify-no-changes --no-restore
|
||
git diff --check
|
||
```
|
||
|
||
生成数据库 SQL:
|
||
|
||
```bash
|
||
dotnet ef migrations script \
|
||
--project Tiku.Infrastructure \
|
||
--startup-project Tiku.DbMigrator
|
||
```
|