diff --git a/docs/architecture/saas-product-and-api-roadmap.md b/docs/architecture/saas-product-and-api-roadmap.md new file mode 100644 index 0000000..08b22d3 --- /dev/null +++ b/docs/architecture/saas-product-and-api-roadmap.md @@ -0,0 +1,255 @@ +# SaaS 题库产品边界与后续接口路线 + +本文档定义平台端、租户端、学生端的目标边界,以及下一阶段接口开发顺序。当前 ASP.NET Core 后端是实现基线;旧 NestJS 和 `tiki-web` 只用于核对业务行为,yudao 只用于参考套餐、商城、支付和后台运营的模块划分。 + +## 当前判断 + +现有后端已经具备继续开发的基础:Host 租户解析、强租户隔离、共享与私有题库、RBAC、Provider 解耦、租户前端运行时配置、学生练习闭环、交易基础和 Worker 基座均已落地。 + +后续重点应从“迁移旧 URL”转为“补齐 SaaS 产品闭环”。当前主要缺口是: + +- 平台向租户销售套餐的商城、订单、支付、订阅和计量闭环。 +- 教师发布作业、考试、批阅和查看班级结果的教学闭环。 +- 套餐业务能力、后台权限模块和前端菜单仍需彻底分层。 +- Provider 自助配置、公共题库运营和高流量查询读模型仍需完善。 + +## 三端边界 + +### 平台端 + +平台端是 SaaS 控制面,负责: + +- 租户、租户 Owner、状态、域名和生命周期。 +- SaaS 业务模块、套餐、附加包、价格和额度。 +- 租户订阅、SaaS 订单、支付、退款、账单、发票、催缴和用量。 +- 平台员工、平台角色、平台权限、审计和告警。 +- 公共题库、公共分类、题目版本、发布和反馈质量运营。 +- 平台自身的收款 Provider,不使用租户配置的学生商城支付账号。 + +### 租户端 + +租户端是机构控制面,负责: + +- 员工、自定义角色、权限、班级、学生和数据范围。 +- 私有题库、公共题库消费、分类扩展、组卷、导入和导出。 +- 作业、考试、每日一练、批阅和教学报告。 +- 品牌、主题、导航、首页模块和自定义域名。 +- 身份、SMS、对象存储、学生商城支付、通知和 AI Provider。 +- 学生商品、会员、优惠券、激活码、积分、CRM、推广和分佣。 +- 本租户 SaaS 订阅、账单、用量、续费和升级。 + +### 学生端 + +学生端是租户域名下的数据面,负责: + +- 根据 Host 获取租户品牌、功能、导航和允许的登录方式。 +- 登录、绑定、个人资料和通知。 +- 题库、练习、考试、作业、错题、收藏和学习报告。 +- 词汇、知识手册、视频、分数线等可选内容模块。 +- 租户自己的学生商城、订单、支付、优惠券、积分和权益。 + +## 套餐能力与权限分层 + +不能用一套“模块”同时表达套餐、权限和菜单。目标模型固定为: + +| 概念 | 用途 | +| --- | --- | +| `SaaSFeature` | 平台可销售的业务能力 | +| `PlanFeatureEntitlement` | 套餐包含哪些业务能力 | +| `FeatureLimit` | 员工席位、学生数、题目数、存储、导出和 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 商城 + +- 业务模块 CRUD、发布和下架。 +- 套餐 CRUD、不可变套餐版本、价格版本和套餐对比。 +- 附加包和额度定义。 +- 租户侧套餐目录、报价、结算、下单和支付。 +- 试用转正式、续费、升级、降级和取消。 +- SaaS 订单、支付、退款、账单、发票、用量和超额计费后台。 + +租户自助账务接口建议统一在 `/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 延迟。 + +## 实施顺序 + +### 9A:产品能力模型 + +- 拆分套餐业务能力、权限模块、菜单和额度。 +- 定义核心能力、可售卖能力和附加包。 +- 套餐改为不可变版本,并引入统一 `IFeatureAccessService`。 +- 所有租户后台授权同时经过套餐能力和 RBAC 判断。 +- 重新生成 OpenAPI 迁移清单,替换已过时的接口比较结果。 + +退出标准:套餐决定租户买了什么,角色决定员工能做什么,菜单只表达前端展示。 + +### 9B:平台 SaaS 商城 + +- 套餐、模块、附加包和价格后台。 +- 租户报价、下单、支付和订阅变更。 +- SaaS 订单、退款、账单、发票、用量和催缴。 +- 平台支付与租户学生支付彻底分离。 + +退出标准:租户可从选择套餐到支付开通自动完成。 + +### 9C:租户自助初始化 + +- 创建 Owner、选择套餐、创建订阅。 +- 域名验证和激活。 +- 登录、SMS、OSS、支付和通知 Provider 配置与连通性测试。 +- 品牌、主题、导航和首页发布。 +- 账务中心、用量、续费和升级。 + +退出标准:平台不需要直接修改数据库即可交付新租户。 + +### 9D:教师教学与考试 + +- 作业、考试、班级发布、批阅和教学报告。 +- 智能组卷、每日一练、PDF 命题和战报持久化。 +- 导出任务通过 Worker 和对象存储交付。 + +### 9E:学生端与性能治理 + +- runtime 登录选项、手机号绑定和找回密码。 +- 作业/考试中心、断点续答和报告。 +- 根据产品决定是否迁移备考时间线和择校功能。 +- 完成分页、索引、缓存、聚合投影和性能基线测试。 + +### 9F:AI 独立阶段 + +- 面向租户教师的基础对话和后续 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 运行时。 diff --git a/docs/migration-roadmap.md b/docs/migration-roadmap.md index 70da159..738b91c 100644 --- a/docs/migration-roadmap.md +++ b/docs/migration-roadmap.md @@ -35,6 +35,8 @@ - [第八阶段:AI 底座与教师端对话](migration/phase-8-ai-foundation.md) - [API 契约基线](migration/contracts/README.md) +后续产品化开发统一按 [SaaS 题库产品边界与后续接口路线](architecture/saas-product-and-api-roadmap.md) 执行。该文档定义三端边界、平台 SaaS 商城与租户学生商城的双交易域、套餐能力与 RBAC 分层,以及阶段 9A~9F。 + ## 剩余范围 ### 1. AI 教师端对话与反馈审核