Files
tiku-backend.net/README.md

130 lines
5.7 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 的正式后端。项目已收敛到 ASP.NET Core + EF Core + PostgreSQL本仓库是后续开发的唯一目标后端。架构决策见 [ADR 0001](docs/adr/0001-authoritative-dotnet-backend.md)。
## 架构边界
- 旧 NestJS / Supabase 仓库只作为业务行为和接口清单参考,不作为运行时依赖。
- 不兼容旧 Supabase 数据库、RLS、Storage bucket、Refresh Token 或旧题单 JSON。
- PostgreSQL 按标准 PostgreSQL 使用,不绑定 Supabase 托管能力。
- 普通 schema 由 EF Core entity、Fluent Configuration 和 Migration 管理;`Tiku.DbMigrator` 是迁移入口。
- 多租户隔离不使用 PostgreSQL RLS由 Host 租户解析、EF Query Filter、写入拦截器、PostgreSQL 约束和真实 PostgreSQL 测试共同保证。
- 身份、短信、对象存储、支付、通知和 AI 都通过 Application 层接口表达业务意图;第三方 SDK、密钥读取和 provider 细节只允许出现在 Infrastructure。
- 租户自定义域名由可信 Host 解析,不接受 query/header 伪造切换租户。
- 公共题库由唯一平台主体拥有;订阅有效租户可访问公共题,租户私题只属于本租户。
## 技术栈与目录
- ASP.NET Core Controller API
- Entity Framework Core + Npgsql
- PostgreSQL
- Serilog
- ZLinq
- AlibabaCloud OSS / SMS SDK
- Senparc.Weixin.*
- AlipaySDKNet.Standard
- Microsoft Semantic Kernel仅 Infrastructure AI 边界)
- 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 / PostgreSQL 集成测试
docs # ADR、架构说明和迁移路线
```
## 平台端静态原型
平台端 demo 已作为静态文件挂到 API 项目:
```text
GET /platform-admin/
```
它是功能原型壳,不是正式视觉规范。默认 mock 模式;联调时通过 `runtime-config.js` 注入同源 `/api`、平台 access token provider 和 API 模式。
当前不把后端改成 MVC/Razor也不为这个静态 demo 单独维护 Node 服务。后续平台端产品化时,建议迁为独立 React/Vite/Next 工程,.NET 继续提供 API。
## 数据库与 ORM 分工
EF Core code-first migration 负责:
- 表、列、索引、普通外键;
- 普通 unique/check constraint
- 模型快照和迁移历史;
- 通过 `Tiku.DbMigrator` 显式执行迁移。
PostgreSQL guard 负责 EF 无法表达的跨表租户不变量:
- `TenantQuestionReference` 只能引用平台公共题或当前租户私题;
- `TaxonomyNode` 父节点只能属于平台主体或当前租户;
- 需要读取 `tenants.mode` 或比较 owner 关系的条件约束。
维护规则:
1. SQL 只放在 `Tiku.Infrastructure/Persistence/PostgreSqlTenantConstraintSql.cs`
2. Migration 只调用 `migrationBuilder.EnsureTenantIsolationGuards()` / `DropTenantIsolationGuards()`
3. 重建 `InitialSchema` 后,`Up()` 末尾必须调用 `EnsureTenantIsolationGuards()``Down()` 开头必须调用 `DropTenantIsolationGuards()`
4. 新增 guard 前先判断能否用 EF FK / unique / check 表达;表达不了才加 PostgreSQL guard。
5. 每个 guard 必须有 migration script 断言和真实 PostgreSQL 越权测试。
## 开发约束
- 新增租户实体必须实现租户 marker并通过模型测试确认 Query Filter、租户唯一索引和组合外键。
- 普通 Controller / Service 不接受可写 `tenantId`、任意 owner tenant GUID、任意 bucket 或 provider 密钥。
- 题目写接口使用 `QuestionLocator`;答题接口使用 `sessionQuestionId`;不得恢复裸 `QuestionId` 练习写入。
- 自定义域名请求不得通过 `tenantCode``host` query 或客户端转发头切换租户。
- 业务层不得直接引用第三方 SDK namespace、拼 OSS bucket、读取微信/支付/短信/AI 密钥。
- 不新增 Supabase provider、Supabase URL 拼接、Supabase Storage 或 Supabase Auth 兼容层。
- AI 面向租户教师后台和题目反馈审核;租户 API Key 存 `TenantSecret`SK 类型不得进入 Domain/Application/API。
## 文档入口
- [当前认证、授权与 Host 安全策略](docs/architecture/authentication-authorization-security.md)
- [认证与授权待补强清单](docs/architecture/authentication-authorization-hardening-plan.md)
- [迁移路线与剩余范围](docs/migration-roadmap.md)
- [API 契约基线说明](docs/migration/contracts/README.md)
- [AI 底座设计](docs/migration/phase-8-ai-foundation.md)
## 常用命令
```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
```
检查模型是否有未生成 migration 的变更:
```bash
dotnet ef migrations has-pending-model-changes \
--project Tiku.Infrastructure \
--startup-project Tiku.DbMigrator
```
首次部署可在迁移完成后创建平台超级管理员:
```bash
export TIKU_BOOTSTRAP_PLATFORM_ADMIN_EMAIL='admin@example.com'
export TIKU_BOOTSTRAP_PLATFORM_ADMIN_PASSWORD='replace-with-a-strong-temporary-password'
export TIKU_BOOTSTRAP_PLATFORM_ADMIN_NAME='Platform Administrator'
dotnet run --project Tiku.DbMigrator -- --bootstrap-platform-admin
```
该命令只允许在不存在任何平台角色用户绑定时执行。不要把临时密码写入仓库配置或命令行参数。