Files
tiku-backend.net/README.md

180 lines
6.8 KiB
Markdown
Raw 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
题库 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` / `ICurrentTenant` 统一当前用户和租户上下文。
- 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` + `AddDbContextPool<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/20260725220742_InitialSchema.cs
```
当前 EF 模型覆盖:
- 租户、用户、成员、认证、Session、短信验证码
- 地区、模块、院校、专业、科目、分类
- 题库、题目、题目版本
- 内容入口、内容节点、题集、练习蓝图
- 词汇、手册、用户单词进度
- 资源、图片、App 资源、视频解析、导入任务
- 练习、答题、收藏、错题、报告、统计
- 商品、订单、支付、权益、兑换码、优惠券
- 推广、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
```