Files
tiku-backend.net/README.md

143 lines
6.0 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 方案迁移到可控的 ASP.NET Core + PostgreSQL 架构。
这个仓库目前处在新后端初始化和数据库模型迁移阶段Domain 实体、EF Core Fluent 配置、PostgreSQL 初始建库 migration、模型约束测试已经建立API/Worker 的具体业务实现会在这个基础上继续推进。
## 为什么换掉 Supabase
旧方案的问题不只是“用了 Supabase”而是安全、权限、业务约束分散在太多地方
- 应用代码、Supabase RLS、SQL policy、Edge/脚本、前端约定之间边界不清。
- 多租户业务复杂后RLS policy 会越来越难审查,调试成本高。
- 团队现在已经有后端开发,继续把核心权限和业务一致性绑在 BaaS 规则上,反而增加维护难度。
- 复杂导入、对账、退款、CRM、资产安全扫描、平台账单等后台任务更适合由明确的 Worker + 应用层权限 + 数据库约束来承载。
- 新系统需要长期演进,直接掌控 PostgreSQL schema、迁移、索引、FK、事务边界会比依赖 Supabase 平台约束更可控。
新的方向不是“数据库裸奔”,而是把职责重新分层:
- ASP.NET Core 负责认证、授权、租户上下文、业务流程、审计记录。
- PostgreSQL 负责数据完整性、外键、唯一约束、检查约束、索引、JSONB/数组/ltree/citext 等原生能力。
- Worker 负责导入、对账、退款、通知、资产扫描、统计等后台任务。
- 测试负责持续验证 EF 模型和数据库约束没有退化。
## 技术栈
- .NET / ASP.NET Core
- Entity Framework Core
- PostgreSQL
- Npgsql
- xUnit
项目分层:
```text
Tiku.Api # HTTP API 入口
Tiku.Application # 应用服务、用例编排
Tiku.Domain # 领域实体、枚举、基础类型
Tiku.Infrastructure # EF Core、PostgreSQL 持久化配置、migration
Tiku.DbMigrator # 数据库迁移启动项目
Tiku.Worker # 后台任务
Tiku.UnitTests # 单元测试
Tiku.IntegrationTests # EF 模型/持久化约束测试
```
## 数据库策略
当前数据库以 PostgreSQL 为核心能力,而不是把 PostgreSQL 当成普通 KV 存储:
- JSON 字段统一使用 C# `JsonElement`,映射到 PostgreSQL `jsonb`
- 树形内容路径使用 `ltree`
- 大小写不敏感编码/域名/兑换码等使用 `citext`
- PostgreSQL array 使用 `text[]` / `uuid[]`,不把数组塞成字符串。
- 钱相关字段用整型 cents 或明确 decimal precision避免浮点误差。
- 多租户表默认有 `TenantId`
- 租户内跨表引用优先使用 composite FK例如 `(tenant_id, id)`
- 关键业务唯一性落数据库唯一索引或过滤唯一索引。
- 用 check constraint 保护金额、数量、状态范围等底线。
当前 migration 已压成一个 greenfield baseline
```text
Tiku.Infrastructure/Persistence/Migrations/20260725220742_InitialSchema.cs
```
因为新库还没正式上线,保留一堆开发过程 migration 意义不大。现在单个初始 migration 更适合作为新后端的起点。
## 新安全策略
这次迁移的核心安全思路是:不照搬 Supabase RLS而是在应用层建立明确、可测试、可审计的安全边界同时用 PostgreSQL 约束守住数据完整性底线。
### 已落地
- 多租户数据表普遍包含 `TenantId`
- 大量租户内关系使用 composite FK避免只靠应用代码约定租户一致性。
- 不迁移 Supabase RLS、`app_private` schema、生产保护 policy。
- 敏感配置不原样落明文字段,例如 CRM / 支付 / webhook 只保留 `secret_ref` 或公开配置。
- PB 导入有专门审计表:
- `pb_import_runs`
- `pb_raw_records`
- `pb_import_issues`
- 关键业务流保留审计/事件表,例如:
- `audit_logs`
- `auth_login_events`
- `payment_events`
- `commerce_refund_events`
- `commerce_reconciliation_issue_events`
- `content_asset_access_events`
- `content_asset_security_scan_events`
- `platform_audit_alerts`
- 模型测试覆盖:
- 表数量和表名
- JSONB 映射
- `ltree` 映射
- 关键唯一索引
- decimal precision
- 租户关系 composite FK
- PB raw record 可追踪主键
### 计划落地
后续 API / Worker 实现时,需要继续把下面这些策略固化成代码和测试:
- 统一租户上下文解析,禁止从请求 body 直接信任 `tenantId`
- API 层基于用户、租户成员、角色模板、权限 JSON 做授权。
- 平台管理员、租户管理员、教师/运营、学生等权限边界明确拆分。
- Repository / Query 层默认带租户过滤,平台级查询必须显式声明。
- 所有跨租户资源访问必须走应用服务校验,不允许 controller 直查。
- 审计日志覆盖高风险操作:
- 登录、认证失败、短信验证
- 订单/支付/退款/对账调整
- 题库导入/导出/公库采纳
- 资产下载签名和安全扫描
- 租户配置、域名、品牌、支付账号变更
- 平台账单、催收、告警处理
- Secret 管理独立化,只在应用层通过安全服务解析 `secret_ref`
- 后台 Worker 使用最小权限的应用服务,不直接绕过业务规则写库。
- 对账、导入、批处理任务要求幂等键和可重跑设计。
- 生产环境连接串、密钥、对象存储凭据不进入仓库。
## 常用命令
```bash
dotnet build /home/xiong/Games/Anii/TIKU-BACKEND/TIKU-BACKEND.slnx
dotnet test /home/xiong/Games/Anii/TIKU-BACKEND/TIKU-BACKEND.slnx
dotnet format /home/xiong/Games/Anii/TIKU-BACKEND/TIKU-BACKEND.slnx --verify-no-changes
git -C /home/xiong/Games/Anii/TIKU-BACKEND diff --check
```
生成数据库 SQL
```bash
dotnet ef migrations script \
--project Tiku.Infrastructure \
--startup-project Tiku.DbMigrator
```
## 当前状态
- 数据库模型迁移已完成到初始 schema。
- migration 已整理为单个初始建库 migration。
- 当前模型测试通过。
- 下一步重点是 API / Worker 层的授权、审计、导入、核心业务流程实现。