Files
tiku-backend.net/docs/architecture/saas-product-and-api-roadmap.md

231 lines
9.5 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.

# SaaS 题库产品边界与后续接口路线
本文档定义平台端、租户端、学生端的目标边界,以及下一阶段接口开发顺序。当前 ASP.NET Core 后端是实现基线;旧 NestJS 和 `tiki-web` 只用于核对业务行为yudao 只用于参考套餐、商城、支付和后台运营的模块划分。
## 当前判断
现有后端已经具备继续开发的基础Host 租户解析、强租户隔离、共享与私有题库、RBAC、Provider 解耦、租户前端运行时配置、学生练习闭环、交易基础和 Worker 基座均已落地。
第九阶段已经完成 SaaS 产品与交付闭环。当前主要缺口是:
- 教师发布作业、考试、批阅和查看班级结果的教学闭环。
- Provider 自助配置、公共题库运营和高流量查询读模型仍需完善。
## 三端边界
### 平台端
平台端是 SaaS 控制面,负责:
- 租户、租户 Owner、状态、域名和生命周期。
- SaaS 业务模块、套餐、附加包、价格和额度。
- 租户订阅、SaaS 订单、支付、退款、账单、发票、催缴和用量。
- 平台员工、平台角色、平台权限、审计和告警。
- 公共题库、公共分类、题目版本、发布和反馈质量运营。
- 平台自身的收款 Provider不使用租户配置的学生商城支付账号。
### 租户端
租户端是机构控制面,负责:
- 员工、自定义角色、权限、班级、学生和数据范围。
- 私有题库、公共题库消费、分类扩展、组卷、导入和导出。
- 作业、考试、每日一练、批阅和教学报告。
- 品牌、主题、导航、首页模块和自定义域名。
- 身份、SMS、对象存储、学生商城支付、通知和 AI Provider。
- 学生商品、会员、优惠券、激活码、积分、CRM、推广和分佣。
- 本租户 SaaS 订阅、账单、用量、续费和升级。
### 学生端
学生端是租户域名下的数据面,负责:
- 根据 Host 获取租户品牌、功能、导航和允许的登录方式。
- 登录、绑定、个人资料和通知。
- 题库、练习、考试、作业、错题、收藏和学习报告。
- 词汇、知识手册、视频、分数线等可选内容模块。
- 租户自己的学生商城、订单、支付、优惠券、积分和权益。
## 套餐能力与权限分层
不能用一套“模块”同时表达套餐、权限和菜单。目标模型固定为:
| 概念 | 用途 |
| --- | --- |
| `SaaSFeature` | 平台可销售的业务能力 |
| `SaasOfferingVersionFeature` | 不可变套餐版本包含哪些业务能力 |
| `SaasOfferingVersionLimit` | 套餐版本的员工、学生、题目、存储、导出和 AI 额度 |
| `PermissionModule` | 后台权限页面的业务分组 |
| `BackendPermission` | `view/create/update/import/export/approve/retry` 等操作权限 |
| `BackendMenu` | 根据有效权限生成的前端导航,不作为鉴权依据 |
建议的可售卖能力包括:
- `question_bank.private`
- `learning.practice`
- `learning.assignment`
- `learning.exam`
- `content.vocabulary`
- `content.handbook`
- `content.video`
- `content.scoreline`
- `marketing.site_content`
- `student.management`
- `commerce.student_store`
- `crm.followup`
- `growth.referral_commission`
- `ai.teacher_assistant`
身份安全、角色管理、账务中心和续费入口属于核心能力。即使套餐过期,也不能阻止租户查看账单、配置管理员或完成续费。
每次受保护的业务请求必须同时满足:
```text
租户有效
+ 订阅状态允许当前读写操作
+ 套餐或附加包包含业务能力
+ 未超过对应额度
+ 当前角色具有操作权限
+ DataScope 允许访问目标数据
```
## 双交易域
平台 SaaS 商城和租户学生商城必须是两个独立边界。
### PlatformBilling
平台向租户收费,包含:
- SaaS 套餐、附加包和报价。
- SaaS 订单、支付、退款、订阅、账单和发票。
- 平台收款 Provider 和平台支付回调。
- 租户用量、超额计费、额度预警和催缴。
### TenantCommerce
租户向学生收费,包含:
- SVIP、课程资料和其他学生商品。
- 学生订单、支付、退款、优惠券、激活码和权益。
- 当前租户配置的支付 Provider 和回调。
两类订单、支付账号、回调地址、审计和对账不得共用业务表或服务。
## 已完成的 SaaS 商城与交付接口
### 平台 SaaS 商城
- 平台模块、额度定义、基础套餐、附加包和不可变版本统一在 `/api/platform-admin/saas/**`
- 租户目录、报价、下单、支付、订阅变更、续费、取消、用量和发票统一在 `/api/tenant-billing/**`
- 人工、微信和支付宝平台收款使用平台主体 Provider订单和回调与学生商城分离。
- `/api/tenant-onboarding/status` 汇总 Owner、订阅、域名、登录方式、Provider 和前端发布状态。
租户自助账务接口建议统一在 `/api/tenant-billing/**`
```text
GET /api/tenant-billing/catalog
POST /api/tenant-billing/quotes
POST /api/tenant-billing/orders
POST /api/tenant-billing/payments
GET /api/tenant-billing/orders/{orderNo}
GET /api/tenant-billing/subscription
POST /api/tenant-billing/subscription/change
POST /api/tenant-billing/subscription/renew
POST /api/tenant-billing/subscription/cancel
GET /api/tenant-billing/usage
GET /api/tenant-billing/invoices
```
### Provider 自助管理
统一使用 `TenantExternalProvider + TenantSecret`,补齐:
```text
GET /api/tenant-admin/providers
PUT /api/tenant-admin/providers
POST /api/tenant-admin/providers/test
POST /api/tenant-admin/providers/activate
POST /api/tenant-admin/providers/disable
PUT /api/tenant-admin/providers/secrets
POST /api/tenant-admin/providers/secrets/rotate
```
运行时 bootstrap 需要增加脱敏的登录方式配置,不能返回 SecretRef、密钥或第三方内部配置。
### 教师教学闭环
- 作业、考试、每日一练的创建和发布。
- 发布目标:班级、学生组、指定学生。
- 开始时间、截止时间、限时、补交和自动交卷规则。
- 学生答题草稿、断点续答和最终提交。
- 客观题自动批改,主观题教师批阅、复核和评语。
- 完成率、成绩分布、薄弱知识点和学生明细。
- 试卷、成绩、每日一练和战报导出。
现有 `PracticeBlueprint``PracticeSession` 可以作为题目装配及作答底座,但不能代替教师发布对象和班级任务状态。
### 平台公共题库运营
- 公共题库和公共分类主干管理。
- 题目草稿、审核、发布、撤回和版本对比。
- 重复题检测、反馈汇总和人工复核。
- 使用量、错误率、反馈率和版本采用情况。
- 已发布旧版本禁止物理删除。
### 查询性能和读模型
- 普通列表采用游标分页和稳定排序,禁止默认返回大集合。
- 题目、院校和知识点搜索优先使用 PostgreSQL trigram/全文索引。
- 首页、排行榜和运营看板使用聚合表或异步投影。
- 公共目录和 runtime bootstrap 使用 Redis 缓存并主动失效。
- 导入、导出、统计、资源扫描和对账进入 Worker。
- 使用 OpenTelemetry 观测慢查询、接口耗时、缓存命中和 Worker 延迟。
## 实施顺序
### 9A9C已完成
- `SaasFeature``PermissionModule``BackendPermission``BackendMenu` 已分层。
- `SaasOfferingVersion` 发布后由 Application 和 PostgreSQL guard 双重禁止修改。
- `IFeatureAccessService` 统一处理租户、订阅、Feature、覆盖、额度与权限过滤。
- PlatformBilling 与 TenantCommerce 使用独立订单、支付、回调和 Provider 配置。
- 平台创建租户及 Owner 后,租户可完成购买、开通和 onboarding。
### 9D教师教学与考试
- 作业、考试、班级发布、批阅和教学报告。
- 智能组卷、每日一练、PDF 命题和战报持久化。
- 导出任务通过 Worker 和对象存储交付。
### 9E学生端与性能治理
- runtime 登录选项、手机号绑定和找回密码。
- 作业/考试中心、断点续答和报告。
- 根据产品决定是否迁移备考时间线和择校功能。
- 完成分页、索引、缓存、聚合投影和性能基线测试。
### 9FAI 独立阶段
- 面向租户教师的基础对话和后续 Function Call。
- AI 题目反馈审核,只输出建议和人工复核标记。
- Semantic Kernel 仅存在于 Infrastructure。
- 租户 API Key 保存到 `TenantSecret`
- AI 调用量、成本和额度进入 SaaS 计量体系。
## 验收原则
- 套餐未包含的功能不能分配权限、不能显示菜单、不能调用 API、不能由 Worker 绕过执行。
- 平台角色、租户角色和学生身份不能跨 realm 使用。
- 租户 A 不能读取或修改租户 B 的配置、学生、题库、订单和 Provider。
- 平台 SaaS 支付与租户学生支付使用不同配置、订单域和回调链路。
- 套餐过期后业务写入受限,但账务、续费、安全和历史数据仍可访问。
- 高风险操作、支付状态变化、订阅变化和 Provider 变化都有审计记录。
- 关键查询在接近生产的数据量下验证执行计划、分页稳定性和响应时间。
## 参考边界
- 旧 NestJS核对已有接口语义、状态机和异常行为不要求保留旧 URL。
- `tiki-web`:参考已实际使用的刷题、词汇、手册、商城、营销、教研和运营功能,不复制 PocketBase 查询方式。
- yudao参考租户套餐、商城订单、支付、退款、权限和审计的模块拆分不照搬菜单 ID 套餐模型或 Java 运行时。