forked from wangziqi/gongxue-base
docs: add backend and taro handoff guides
This commit is contained in:
15
README.md
15
README.md
@@ -37,6 +37,11 @@
|
||||
- `docs/refactor/content-import-contract.md`
|
||||
- `docs/refactor/object-storage.md`
|
||||
- `docs/refactor/project-structure.md`
|
||||
- `docs/refactor/frontend-handoff-index.md`
|
||||
- `docs/refactor/backend-capability-status.md`
|
||||
- `docs/refactor/legacy-feature-gap-matrix.md`
|
||||
- `docs/refactor/taro-frontend-integration.md`
|
||||
- `docs/refactor/multitenant-auth-security-contract.md`
|
||||
- `docs/refactor/next-development-todo.md`
|
||||
- `docs/refactor/blueprint-coverage.md`
|
||||
- `docs/refactor/api-structure.md`
|
||||
@@ -167,8 +172,8 @@ npm run check:refactor
|
||||
|
||||
优先继续补:
|
||||
|
||||
1. 对象存储上传后校验、PDF 预览、防盗链和视频水印。
|
||||
2. Excel/CSV 以及分数线、视频批量导入;把现有 JSON 导入升级为可排队异步执行。
|
||||
3. Supabase Auth/JWT 正式鉴权和生产 RLS 验证。
|
||||
4. 微信/QQ 登录、短信、微信支付、支付宝支付 adapter。
|
||||
5. Taro 前端 scaffold,让 H5 和小程序共用同一套 API。
|
||||
1. Supabase Auth/JWT 正式鉴权、生产配置 fail-fast、请求体大小限制和租户隔离回归测试。
|
||||
2. Taro 前端 scaffold,让 H5 和小程序共用同一套 API。
|
||||
3. 对象存储上传后校验、PDF 预览、防盗链和视频水印。
|
||||
4. Excel/CSV 以及分数线、视频批量导入;把现有 JSON 导入升级为可排队异步执行。
|
||||
5. 微信/QQ 登录、短信、微信支付、支付宝支付 adapter。
|
||||
|
||||
@@ -21,11 +21,16 @@
|
||||
- `docs/refactor/content-import-contract.md`:题目、单词、知识手册导入契约,明确后端校验、旧格式转换和前端职责。
|
||||
- `docs/refactor/next-development-todo.md`:后端剩余缺口、Taro 前端接入顺序、上云测试前待办。
|
||||
- `docs/refactor/backend-handoff-roadmap.md`:进入 Taro 前端前的后端进度同步、缺口清单和接入路线图。
|
||||
- `docs/refactor/frontend-handoff-index.md`:交给前端同事的阅读入口和当前可开工范围。
|
||||
- `docs/refactor/backend-capability-status.md`:后端已覆盖、迁移期、待补齐能力盘点。
|
||||
- `docs/refactor/legacy-feature-gap-matrix.md`:对照旧题库功能的新后端差距矩阵。
|
||||
- `docs/refactor/taro-frontend-integration.md`:Taro/H5/小程序启动、请求封装、页面/API 映射。
|
||||
- `docs/refactor/multitenant-auth-security-contract.md`:多租户隔离、鉴权、权限和资源安全红线。
|
||||
|
||||
下一步优先级:
|
||||
|
||||
1. 先按 `docs/refactor/backend-handoff-roadmap.md` 的 P0 清单补齐上云测试和 Taro 主链路所需能力。
|
||||
2. 导出 PocketBase 真实数据到 `pb_export/*.json`,执行 `npm run pb:import:json` 和 `npm run pb:import:validate`。
|
||||
3. 新建 `apps/taro`,优先接租户解析、首页、题库练习、背单词、知识手册、个人中心。
|
||||
1. 先按 `docs/refactor/multitenant-auth-security-contract.md` 的 P0 清单补齐鉴权、生产配置和租户隔离测试。
|
||||
2. 新建 `apps/taro`,按 `docs/refactor/taro-frontend-integration.md` 优先接租户解析、首页、题库练习、背单词、知识手册、个人中心。
|
||||
3. 导出 PocketBase 真实数据到 `pb_export/*.json`,执行 `npm run pb:import:json` 和 `npm run pb:import:validate`。
|
||||
4. 为对象存储、分数线、视频、Excel/CSV 补齐 provider/导入能力,并复用 `content_import_jobs` 管线。
|
||||
5. 接真实短信、微信/QQ 登录、微信支付/支付宝和 CRM worker,进入商用验收。
|
||||
|
||||
156
docs/refactor/backend-capability-status.md
Normal file
156
docs/refactor/backend-capability-status.md
Normal file
@@ -0,0 +1,156 @@
|
||||
# 后端当前能力盘点
|
||||
|
||||
更新时间:2026-06-28
|
||||
|
||||
当前后端已经完成商用 SaaS 题库系统的主干骨架:PostgreSQL 多租户 schema、Node.js 业务 API、PocketBase 数据导入工具、本地 seed、API 集成测试和对象存储签名 provider。
|
||||
|
||||
状态分为:
|
||||
|
||||
- `可联调`:前端可以开始接入,本地测试已覆盖主链路。
|
||||
- `迁移期`:能支撑开发联调,但生产前必须替换或加固。
|
||||
- `待补齐`:旧题库已有或商用交付需要,但新后端还没完整实现。
|
||||
|
||||
## 基础工程
|
||||
|
||||
| 模块 | 状态 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| Supabase/PostgreSQL schema | 可联调 | `supabase/migrations` 已包含多租户、题库、学习、订单、内容、CRM、平台账务等表 |
|
||||
| RLS/租户隔离 | 迁移期 | 表层普遍有 `tenant_id` 和 RLS 策略,但 API 目前使用服务端连接,生产前要补真实 JWT/RLS 回归 |
|
||||
| API 分层 | 可联调 | `apps/api/src/core` + `apps/api/src/features/*` |
|
||||
| Docker API | 可联调 | `docker-compose.api.yml` 和 `apps/api/Dockerfile` 可用 |
|
||||
| 测试 | 可联调 | `npm run check:refactor` 覆盖 TS 检查、导入校验、seed、API 集成测试 |
|
||||
| 根 workspace | 可联调 | 根目录已清理为新技术栈 monorepo 编排层 |
|
||||
|
||||
## 租户与品牌
|
||||
|
||||
| 能力 | 状态 | 后端接口/模型 |
|
||||
| --- | --- | --- |
|
||||
| 域名/小程序码解析租户 | 可联调 | `GET /api/tenant/resolve` |
|
||||
| 品牌名、Logo、客服、主题 JSON | 可联调 | `tenant_branding`、`tenant_settings` |
|
||||
| 功能开关 | 可联调 | `features`、`adminFeatures` |
|
||||
| 自定义域名管理 | 可联调 | `GET/POST /api/tenant-admin/domains` |
|
||||
| 多套主题模板 | 待补齐 | 当前只有租户 theme JSON,缺平台主题模板、预览、发布流程 |
|
||||
|
||||
## 鉴权与权限
|
||||
|
||||
| 能力 | 状态 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| 短信验证码登录 | 迁移期 | 已有验证码、冷却、hash、登录事件;mock provider 可本地联调 |
|
||||
| 迁移期 session | 迁移期 | `tk_` token hash 存在 `app_private.auth_sessions` |
|
||||
| 微信/QQ OAuth | 待补齐 | 目前是 placeholder |
|
||||
| 平台管理员鉴权 | 迁移期 | 当前用 `x-platform-admin-key`,生产前必须换 JWT/服务端会话 |
|
||||
| 租户角色权限 | 可联调 | `tenant_memberships.role + permissions`,接口有权限点校验 |
|
||||
| 自定义角色模板 | 待补齐 | 当前有权限 JSON 覆盖,缺角色模板、菜单/模块/字段级权限配置 UI/API |
|
||||
|
||||
## 学生端题库主链路
|
||||
|
||||
| 能力 | 状态 | 后端接口/模型 |
|
||||
| --- | --- | --- |
|
||||
| 地区/科目/分类兼容查询 | 可联调 | `/api/catalog/regions`、`subjects`、`categories` |
|
||||
| 新内容入口 | 可联调 | `/api/catalog/content-entries` |
|
||||
| 任意深度分类树 | 可联调 | `/api/catalog/content-nodes` |
|
||||
| 题目列表/集合 | 可联调 | `/api/catalog/question-collections`、`question-collections/questions` |
|
||||
| 顺序/随机/全真模拟规则 | 可联调 | `/api/catalog/practice-blueprints` |
|
||||
| 创建练习 session | 可联调 | `POST /api/learning/practice-sessions` |
|
||||
| 答题记录 | 可联调 | `POST /api/learning/answers` |
|
||||
| 错题本 | 可联调 | `/api/learning/wrong-questions` |
|
||||
| 收藏夹 | 可联调 | `/api/learning/favorites/questions` |
|
||||
| 免费用户题量限制 | 待补齐 | 旧项目有保护逻辑,新后端需按租户/套餐/内容范围实现 |
|
||||
| 模考交卷报告 | 待补齐 | 已有 session/answer 基础,缺完整交卷、评分报告、错题解析汇总 |
|
||||
|
||||
## 背单词、知识手册、分数线、视频
|
||||
|
||||
| 能力 | 状态 | 后端接口/模型 |
|
||||
| --- | --- | --- |
|
||||
| 单词单元/单词列表 | 可联调 | `/api/catalog/vocabulary-units`、`vocabulary-words` |
|
||||
| 单词进度/收藏/统计 | 可联调 | `/api/learning/vocabulary/*` |
|
||||
| 艾宾浩斯复习算法 | 待补齐 | 当前有 next_review 字段基础,缺完整算法和每日计划 |
|
||||
| 知识手册目录/内容 | 可联调 | `/api/catalog/handbook-*` |
|
||||
| 知识手册 JSON 导入 | 可联调 | `/api/tenant-content/imports/*/handbook` |
|
||||
| 分数线字段/院校/专业/记录/趋势 | 可联调 | `/api/scoreline/*` |
|
||||
| 题目视频/批量预加载/搜索 | 可联调 | `/api/questions/*/videos`、`/api/videos/search` |
|
||||
| 视频会员播放次数 | 待补齐 | 缺播放次数扣减、播放日志、防盗链、水印 |
|
||||
|
||||
## 资料与对象存储
|
||||
|
||||
| 能力 | 状态 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| 内容资源台账 | 可联调 | `content_assets` |
|
||||
| 租户后台资源维护 | 可联调 | `/api/tenant-content/assets` |
|
||||
| 学生端资源列表/下载签名 | 可联调 | `/api/catalog/assets`、`/api/catalog/assets/download` |
|
||||
| 阿里云 OSS 签名 | 可联调 | `aliyun_oss` provider |
|
||||
| 腾讯 COS 签名 | 可联调 | `tencent_cos` provider |
|
||||
| Supabase Storage 签名 | 可联调 | `supabase_storage` provider |
|
||||
| PDF 预览/防盗链/水印 | 待补齐 | 商用上线前补齐 |
|
||||
| 上传后对象校验 | 待补齐 | 需 worker 或 API 回调确认 size/hash/mime |
|
||||
|
||||
## 订单、会员、营销
|
||||
|
||||
| 能力 | 状态 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| SVIP 套餐 | 可联调 | `/api/catalog/svip-plans` |
|
||||
| 创建订单/订单列表 | 可联调 | `/api/commerce/orders` |
|
||||
| 手工支付确认 | 迁移期 | 可用于测试,不是生产支付 |
|
||||
| 权益查询/校验 | 可联调 | `/api/commerce/entitlements` |
|
||||
| 激活码兑换 | 可联调 | 事务开通权益 |
|
||||
| 优惠券后台配置 | 可联调 | `/api/tenant-admin/coupons` |
|
||||
| 优惠券前台兑换/下单抵扣 | 待补齐 | 后端还需接入下单计算 |
|
||||
| 微信/支付宝/小程序支付 | 待补齐 | 需 provider、验签、幂等、退款、补偿 |
|
||||
|
||||
## 租户后台与平台后台
|
||||
|
||||
| 能力 | 状态 | 后端接口 |
|
||||
| --- | --- | --- |
|
||||
| 租户概览、品牌、设置 | 可联调 | `/api/tenant-admin/overview`、`branding`、`settings` |
|
||||
| 商户收款配置 | 可联调 | `/api/tenant-admin/payment-accounts` |
|
||||
| 登录 provider 配置 | 可联调 | `/api/tenant-admin/auth-providers` |
|
||||
| 密钥掩码/引用 | 迁移期 | API 有掩码,生产前要做 KMS/Vault 或 envelope encryption |
|
||||
| 活动、Banner、FAQ、公告 | 可联调 | `/api/tenant-admin/banners`、`faqs`、`announcements` |
|
||||
| 激活码批次/生成/列表 | 可联调 | `/api/tenant-admin/code-batches`、`activation-codes` |
|
||||
| 成员/角色权限/审计 | 可联调 | `/api/tenant-admin/members`、`permissions`、`audit-logs` |
|
||||
| 平台租户/套餐/订阅/账单/用量 | 可联调 | `/api/platform-admin/*` |
|
||||
| 数据看板聚合接口 | 待补齐 | 表基础已有,缺完整 dashboard API |
|
||||
|
||||
## 销售、代理、CRM
|
||||
|
||||
| 能力 | 状态 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| 邀请码/二维码记录 | 可联调 | `/api/referral/invite-code`、`qrcode` |
|
||||
| 扫码/分享事件 | 可联调 | `/api/referral/track-event` |
|
||||
| 首绑客资保护 | 可联调 | `/api/referral/bind` |
|
||||
| 手工补绑 | 可联调 | 需要 `referral:write` |
|
||||
| 销售统计/客户列表/团队 | 可联调 | `/api/referral/sales-*`、`team` |
|
||||
| CRM 配置/队列 | 可联调 | `/api/crm/config`、`/api/crm/queue` |
|
||||
| 真实 CRM webhook worker | 待补齐 | 钉钉/飞书/企微发送、签名、重试、死信 |
|
||||
| 分佣结算 | 待补齐 | 缺佣金规则、结算单、审核、导出 |
|
||||
|
||||
## 内容导入与迁移
|
||||
|
||||
| 能力 | 状态 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| PocketBase schema 分析 | 可联调 | `scripts/import-pocketbase` |
|
||||
| 题目 JSON preview/import | 可联调 | 后端负责规范化、issue、幂等、审计 |
|
||||
| 单词 JSON preview/import | 可联调 | 兼容旧模板 |
|
||||
| 知识手册 JSON preview/import | 可联调 | 支持书籍/章节/小节/知识点归一化 |
|
||||
| Excel/CSV 导入 | 待补齐 | 应复用 `content_import_jobs` 管线 |
|
||||
| 分数线/视频批量导入 | 待补齐 | 应复用同一导入管线 |
|
||||
| 大批量异步导入 | 待补齐 | 需要 `apps/worker` |
|
||||
|
||||
## 当前验证
|
||||
|
||||
最近已通过:
|
||||
|
||||
```bash
|
||||
npm audit
|
||||
npm run check:refactor
|
||||
```
|
||||
|
||||
`check:refactor` 包含:
|
||||
|
||||
- API TypeScript 检查
|
||||
- importer TypeScript 检查
|
||||
- PocketBase 导入校验
|
||||
- smoke seed
|
||||
- API build
|
||||
- API integration tests
|
||||
|
||||
48
docs/refactor/frontend-handoff-index.md
Normal file
48
docs/refactor/frontend-handoff-index.md
Normal file
@@ -0,0 +1,48 @@
|
||||
# 前端交接索引
|
||||
|
||||
更新时间:2026-06-28
|
||||
|
||||
这份文件是给 Taro/H5/小程序前端同事的入口。当前仓库的前端重构建议从 `apps/taro` 新建工程开始,不再把旧 React/Vite 前端搬回根目录继续开发。
|
||||
|
||||
## 必读顺序
|
||||
|
||||
1. `docs/refactor/project-structure.md`
|
||||
- 先确认新项目目录边界,避免把 `参考/旧题库项目` 当成新源码。
|
||||
2. `docs/refactor/backend-capability-status.md`
|
||||
- 看哪些后端能力已经能联调,哪些只是迁移期可用。
|
||||
3. `docs/refactor/legacy-feature-gap-matrix.md`
|
||||
- 对照旧题库功能,确认哪些页面能按新 API 重做,哪些后端还要补。
|
||||
4. `docs/refactor/taro-frontend-integration.md`
|
||||
- Taro 启动、租户解析、请求封装、页面/API 映射、跨端注意事项。
|
||||
5. `docs/refactor/multitenant-auth-security-contract.md`
|
||||
- 多租户、鉴权、权限、资源签名和生产安全红线。
|
||||
6. `docs/refactor/content-import-contract.md`
|
||||
- 后台内容导入、题目 JSON、单词、知识手册的后端校验契约。
|
||||
|
||||
## 当前可进入的前端工作
|
||||
|
||||
- 可以开始搭建 `apps/taro`。
|
||||
- 可以复刻旧题库学生端主要视觉和交互:登录、选地区、首页、刷题、背单词、知识手册、分数线、资料、商城、个人中心。
|
||||
- 可以按新后端主模型接入内容导航:
|
||||
- `content_entries`
|
||||
- `content_nodes`
|
||||
- `question_collections`
|
||||
- `practice_blueprints`
|
||||
- 可以接入迁移期短信登录和 `tk_` session,用于本地/内网联调。
|
||||
- 可以接入租户品牌、主题、功能开关和域名/小程序参数解析。
|
||||
|
||||
## 不能误认为已商用完成的部分
|
||||
|
||||
- 生产鉴权尚未完成:当前很多接口仍用 `x-tenant-id`、`x-user-id`、`x-platform-admin-key` 作为迁移期上下文。
|
||||
- 真实短信、微信登录、QQ 登录、微信支付、支付宝支付 provider 还未正式接完。
|
||||
- 对象存储已完成签名 provider,但 PDF 预览、防盗链、视频水印、上传后校验还要补。
|
||||
- 大批量 Excel/CSV、分数线、视频导入和异步 worker 还未完成。
|
||||
- 数据看板、分佣结算、AI 择校、主题模板市场等仍是后续商用增强项。
|
||||
|
||||
## 前后端协作建议
|
||||
|
||||
- 前端先做页面骨架和 API client,不要在页面里写死租户、地区、资源地址、商户号或 provider 密钥。
|
||||
- 每个页面先接后端已有接口;缺接口时把页面期望的字段写到 issue/TODO,再由后端补聚合接口。
|
||||
- 权限判断以后端结果为准,前端只做菜单和按钮可见性优化。
|
||||
- 旧项目只作为样式、交互和字段含义参考;长期数据模型以新 API 为准。
|
||||
|
||||
111
docs/refactor/legacy-feature-gap-matrix.md
Normal file
111
docs/refactor/legacy-feature-gap-matrix.md
Normal file
@@ -0,0 +1,111 @@
|
||||
# 旧题库功能差距矩阵
|
||||
|
||||
更新时间:2026-06-28
|
||||
|
||||
旧项目位于 `F:\project\参考\旧题库项目`,只作为功能、样式、交互和迁移参考。新项目不再复刻 PocketBase/SQLite 的数据结构,而是以新多租户 SaaS 模型为准。
|
||||
|
||||
状态说明:
|
||||
|
||||
- `已覆盖`:新后端已有对应模型和接口。
|
||||
- `部分覆盖`:已有主干,但商用体验或边界还要补。
|
||||
- `未覆盖`:需要新增后端能力。
|
||||
- `前端为主`:后端已有基础,主要由 Taro/H5 实现展示和交互。
|
||||
|
||||
## 学生端功能
|
||||
|
||||
| 旧功能/页面 | 旧项目参考 | 新后端状态 | 待补齐 |
|
||||
| --- | --- | --- | --- |
|
||||
| 登录/注册 | `pages/Login.tsx` | 部分覆盖 | 短信 mock/session 已有;微信小程序、微信网页、QQ、正式 JWT 未完成 |
|
||||
| 选地区 | `pages/RegionSelector.tsx` | 已覆盖 | 需要前端按租户套餐和权益展示可选地区 |
|
||||
| 首页/学生看板 | `pages/StudentDashboardNew.tsx` | 部分覆盖 | 品牌、Banner、公告、入口、个人统计有基础;缺完整运营动态/学习任务聚合 |
|
||||
| 题库入口 | `pages/SubjectSelector.tsx`、`RegionArchitectureEditor.tsx` | 已覆盖 | 前端应改接 `content_entries/content_nodes` |
|
||||
| 多级分类树 | 旧 module/subject/category 树 | 已覆盖 | 新后端支持任意深度和 `marker_type`;前端不要写死层级 |
|
||||
| 顺序刷题 | `pages/Quiz.tsx` | 已覆盖 | 继续补题量限制、断点续练、更多题型渲染 |
|
||||
| 随机刷题 | `pages/Quiz.tsx` | 已覆盖 | 已有 blueprint/session 快照,前端需按 mode 调用 |
|
||||
| 全真模拟 | `components/AdminMockexam`、`MockExamConfigModal.tsx` | 部分覆盖 | 后端有 blueprint 基础;缺完整交卷报告、排名、复盘 |
|
||||
| 错题本 | 用户 stats/错题逻辑 | 已覆盖 | 后续补错题复习计划 |
|
||||
| 收藏夹 | `WordFavoritesPage.tsx`、题目收藏 | 已覆盖 | 题目和单词收藏已有 |
|
||||
| 题目视频 | `VideoPlayer.tsx` | 部分覆盖 | 题目视频查询已有;缺播放签名、次数扣减、水印、防下载 |
|
||||
| 背单词 | `VocabularyPage.tsx`、`VocabularyQuiz.tsx` | 部分覆盖 | 单词列表/进度/收藏/统计已有;缺完整艾宾浩斯算法、每日计划、收藏练习细节 |
|
||||
| 知识手册 | `Handbook*.tsx` | 已覆盖 | 前端需做好 Markdown/公式/图片渲染和搜索体验 |
|
||||
| 分数线 | `ScorelinePage.tsx` | 已覆盖 | 动态字段/趋势已有;缺批量导入和复杂筛选优化 |
|
||||
| 商城/SVIP | `Store.tsx`、`SvipModal.tsx` | 部分覆盖 | 套餐/订单/权益/激活码已有;缺真实支付、优惠券抵扣 |
|
||||
| 个人中心 | `Profile.tsx` | 部分覆盖 | 基本资料、权益、订单统计有;缺完整勋章、签到、学习报告 |
|
||||
| 资料下载 | `QuestionExporterPublishModal.tsx` 等 | 部分覆盖 | 资源台账/签名下载已有;缺 PDF 预览、下载水印、防盗链 |
|
||||
| AI 择校推荐 | 业务规划新增 | 未覆盖 | 需设计学生输入 schema、地区数据上下文、AI JSON 输出、PDF 报告 |
|
||||
|
||||
## 租户后台功能
|
||||
|
||||
| 旧功能/组件 | 新后端状态 | 待补齐 |
|
||||
| --- | --- | --- |
|
||||
| 用户管理 | 部分覆盖 | 租户成员 API 已有;学生用户列表、批量导入、禁用/补绑/CRM 批量推送还需完善 |
|
||||
| 销售/代理管理 | 部分覆盖 | referral/team/stats 有;缺分佣比例、结算单、审核、导出 |
|
||||
| 班级/教师管理 | 未覆盖 | 需新增班级、学生分班、教师可见范围 |
|
||||
| 数据看板 | 部分覆盖 | 表基础有;缺收益、注册、答题、活跃、套餐销量等聚合 API |
|
||||
| 地区管理 | 部分覆盖 | 地区和内容入口已有;缺按 SaaS 套餐限制地区/题库授权的完整流程 |
|
||||
| 品牌配置 | 已覆盖 | 需要前端做预览和主题发布体验 |
|
||||
| 自定义域名 | 已覆盖 | 生产需补 DNS 校验、证书状态、回源校验 |
|
||||
| 主题系统 | 部分覆盖 | 当前 theme JSON 可用;缺三套平台主题模板和素材管理 |
|
||||
| 商户收款配置 | 部分覆盖 | 配置 API 有;缺真实支付 provider 和验签 |
|
||||
| 登录配置 | 部分覆盖 | 配置 API 有;缺真实短信/OAuth provider 实现 |
|
||||
| Banner/公告/FAQ/活动 | 已覆盖 | 前端运营后台可以接 |
|
||||
| SVIP 套餐 | 已覆盖 | 后续补地区/分类/专业增项限制规则 |
|
||||
| 优惠券 | 部分覆盖 | 后台配置有;前台兑换、下单抵扣待补 |
|
||||
| 激活码 | 已覆盖 | 批次、生成、兑换主链路已有 |
|
||||
| 勋章管理 | 部分覆盖 | 表结构有 badges/user_badges;缺后台和学生端 API |
|
||||
| 题库录入 | 已覆盖 | 单题创建/更新、JSON 导入、集合/蓝图已有 |
|
||||
| 题库导出 PDF/Word/JSON | 未覆盖 | 旧前端有导出组件;新后端需决定是否服务端导出或前端导出 |
|
||||
| 题型分组/模拟卷配置 | 部分覆盖 | question_type_groups 表和 blueprint 有基础;后台配置体验待补 |
|
||||
| 背单词维护 | 已覆盖 | 单元/单词 CRUD 和导入已有 |
|
||||
| 知识手册维护 | 已覆盖 | subject/chapter/entry CRUD 和导入已有 |
|
||||
| 分数线维护 | 已覆盖 | 字段/院校/专业/记录 CRUD 已有 |
|
||||
| 视频维护/绑定 | 已覆盖 | video CRUD 和 question-video 绑定已有 |
|
||||
| CRM 配置和队列 | 部分覆盖 | 配置/队列已有;发送 worker 待补 |
|
||||
| 对象存储配置 | 部分覆盖 | 系统 env provider 已有;租户级存储策略、上传后校验待补 |
|
||||
|
||||
## 平台 SaaS 后台功能
|
||||
|
||||
| 功能 | 新后端状态 | 待补齐 |
|
||||
| --- | --- | --- |
|
||||
| 创建/管理租户 | 已覆盖 | 平台后台页面待做 |
|
||||
| SaaS 套餐 | 已覆盖 | 需要和地区/题库授权策略打通 |
|
||||
| 年费/服务费账单 | 已覆盖 | 真实支付/开票/催缴流程待补 |
|
||||
| 租户用量记录 | 已覆盖 | 自动采集 worker 待补 |
|
||||
| 公共题库/地区题库 | 部分覆盖 | question_banks 有 source_scope;缺租户采纳、授权、版本同步 |
|
||||
| 跨租户运营看板 | 部分覆盖 | overview 有基础;缺完整 BI 聚合 |
|
||||
| 租户安全审计 | 部分覆盖 | audit logs 有;缺平台级审计报表 |
|
||||
|
||||
## 旧功能中应重新设计的点
|
||||
|
||||
- 旧项目把很多用户状态放在 JSON 或前端逻辑里,新项目应拆到独立表或后端服务。
|
||||
- 旧树形结构只作为迁移来源,新前端应使用 `content_entries/content_nodes/question_collections/practice_blueprints`。
|
||||
- 旧资料/视频 URL 不能继续让前端直连私有资源,新项目统一走 `content_assets` 和签名 URL。
|
||||
- 旧后台的一些“隐藏入口/超管直贴 JSON”应改为 preview/import/job/issue 审计流。
|
||||
- 旧支付和激活码逻辑要统一成订单、支付事件、权益开通、幂等 webhook。
|
||||
- 旧销售追踪要升级为租户内角色权限 + 首绑保护 + 分佣结算 + CRM worker。
|
||||
|
||||
## 后端补齐优先级
|
||||
|
||||
### P0:前端联调到云端前
|
||||
|
||||
1. 正式鉴权:Supabase Auth/JWT 或服务端 session,替换迁移期请求头。
|
||||
2. 生产配置 fail-fast:默认密钥、`CORS=*`、mock SMS、平台默认 key 必须禁止。
|
||||
3. JSON body size limit:导入接口可配置更大限制,但必须有上限。
|
||||
4. 真实租户隔离测试:跨租户读写、角色越权、资源下载越权。
|
||||
5. 真实短信/微信小程序登录最小闭环。
|
||||
|
||||
### P1:商用主链路
|
||||
|
||||
1. 微信/支付宝支付和 webhook 幂等。
|
||||
2. 对象存储 PDF 预览、视频播放签名、防盗链、水印。
|
||||
3. Excel/CSV、分数线、视频批量导入。
|
||||
4. 数据看板和销售/代理分佣结算。
|
||||
5. 公共题库授权、租户采纳和版本同步。
|
||||
|
||||
### P2:增强体验
|
||||
|
||||
1. 主题模板、素材库、主题预览/发布。
|
||||
2. 班级、教师、学生分组和学习督导。
|
||||
3. AI 择校推荐和 PDF 报告。
|
||||
4. 题库导出、试卷生成、每日一练运营工具。
|
||||
|
||||
156
docs/refactor/multitenant-auth-security-contract.md
Normal file
156
docs/refactor/multitenant-auth-security-contract.md
Normal file
@@ -0,0 +1,156 @@
|
||||
# 多租户与鉴权安全契约
|
||||
|
||||
更新时间:2026-06-28
|
||||
|
||||
这个系统后续要卖给同行作为题库 SaaS,因此租户隔离、鉴权、资源权限和审计是商用红线。前端可以先按迁移期接口联调,但正式上云验收前必须完成本文件的 P0 项。
|
||||
|
||||
## 安全边界
|
||||
|
||||
| 边界 | 规则 |
|
||||
| --- | --- |
|
||||
| 平台超级管理员 | 可管理全部租户、SaaS 套餐、订阅、账单、用量、公共题库 |
|
||||
| 租户管理员 | 只能管理自己租户的品牌、域名、成员、内容、营销、订单和 CRM |
|
||||
| 租户成员 | 按角色和 permissions 访问,例如运营、教师、销售、代理 |
|
||||
| 学生用户 | 只能访问自己所在租户下被授权的内容和自己的学习数据 |
|
||||
| 公共题库 | 必须通过平台授权/租户采纳后才对租户可见 |
|
||||
| 私有资源 | 必须通过后端权限校验后签名访问,不能前端直连对象存储 |
|
||||
|
||||
## 当前迁移期状态
|
||||
|
||||
当前后端仍存在这些迁移期实现:
|
||||
|
||||
- `x-tenant-id` 用于租户上下文。
|
||||
- `x-user-id` 或 body/query 的 `userId` 用于用户上下文。
|
||||
- `x-platform-admin-key` 用于平台管理员接口。
|
||||
- 本地短信 provider 可使用 `mock`。
|
||||
- 默认开发密钥存在于 `.env.example` 和 config fallback。
|
||||
|
||||
这些只允许用于本地开发和内网联调,不允许作为正式云端验收方案。
|
||||
|
||||
## P0:正式云端测试前必须完成
|
||||
|
||||
1. 正式用户鉴权
|
||||
- 使用 Supabase Auth/JWT 或服务端 session 解析可信 userId。
|
||||
- 禁止前端通过 query/body/header 指定 userId。
|
||||
- `GET /api/auth/me` 返回当前用户、租户成员、角色、权限。
|
||||
|
||||
2. 正式租户上下文
|
||||
- H5 可由域名解析租户。
|
||||
- 小程序可由 tenantCode 解析租户。
|
||||
- 后端必须校验用户是否属于该租户。
|
||||
- 跨租户请求必须返回 403 或 404。
|
||||
|
||||
3. 平台管理员鉴权
|
||||
- 替换 `x-platform-admin-key`。
|
||||
- 平台管理员也要有 JWT/session、角色、审计日志。
|
||||
|
||||
4. 生产配置 fail-fast
|
||||
- `NODE_ENV=production` 时禁止默认 `AUTH_CODE_PEPPER`。
|
||||
- 禁止默认 `AUTH_SESSION_SECRET`。
|
||||
- 禁止默认 `PLATFORM_ADMIN_API_KEY`。
|
||||
- 禁止 `CORS_ORIGIN=*`。
|
||||
- 禁止 `AUTH_SMS_PROVIDER=mock`。
|
||||
|
||||
5. 请求体大小限制
|
||||
- 普通 JSON API 必须有默认上限。
|
||||
- 导入接口可以有更大上限,但必须可配置且有最大值。
|
||||
- 超限返回 413。
|
||||
|
||||
6. 租户密钥保护
|
||||
- 商户密钥、短信 secret、OAuth secret 不允许明文长期存储。
|
||||
- 生产应使用 KMS/Vault 或 envelope encryption。
|
||||
- API 只返回 `secretRef`、掩码和配置状态。
|
||||
|
||||
7. RLS 与 API 双层回归
|
||||
- 数据库 RLS 要按 `tenant_id` 拦截。
|
||||
- API SQL 必须显式带 `tenant_id`。
|
||||
- 测试必须覆盖跨租户读取、写入、下载、后台权限越权。
|
||||
|
||||
## 前端必须遵守
|
||||
|
||||
- 不信任本地缓存里的 tenantId/userId 作为安全依据。
|
||||
- 不在页面里保存或展示任何商户密钥、短信密钥、OAuth secret。
|
||||
- 不在前端硬编码对象存储 bucket、私有资源路径、商户号。
|
||||
- 不在前端自行开通会员权益;必须通过订单/支付/激活码后端流程。
|
||||
- 不允许“切换销售归属”这类破坏首绑保护的入口,除非后端提供带权限的管理接口。
|
||||
- 不在前端直接判断“这个用户能不能看某题/某视频/某资料”的最终结果;必须请求后端。
|
||||
- 切换租户、退出登录、登录新账号时,清理旧租户缓存和用户缓存。
|
||||
|
||||
## 后端接口约定
|
||||
|
||||
所有业务表查询必须满足:
|
||||
|
||||
```text
|
||||
where tenant_id = currentTenantId
|
||||
```
|
||||
|
||||
管理类写接口必须满足:
|
||||
|
||||
```text
|
||||
requireTenantPermission(auth, '<scope>:<action>')
|
||||
```
|
||||
|
||||
平台类接口必须满足:
|
||||
|
||||
```text
|
||||
requirePlatformAdmin(auth)
|
||||
```
|
||||
|
||||
资源下载必须满足:
|
||||
|
||||
```text
|
||||
content_assets 台账存在
|
||||
资源属于当前 tenant
|
||||
资源状态允许访问
|
||||
用户权益满足 visibility/access_rules
|
||||
返回短期签名 URL
|
||||
```
|
||||
|
||||
支付 webhook 必须满足:
|
||||
|
||||
```text
|
||||
验签通过
|
||||
provider event id 幂等
|
||||
订单 tenant_id 匹配
|
||||
金额以后端订单金额为准
|
||||
事务内更新 payment/order/entitlement
|
||||
记录 payment_events
|
||||
```
|
||||
|
||||
## 权限点现状
|
||||
|
||||
当前默认角色:
|
||||
|
||||
| 角色 | 默认权限 |
|
||||
| --- | --- |
|
||||
| tenant_owner | `*` |
|
||||
| tenant_admin | `*` |
|
||||
| tenant_operator | 内容、营销、兑换码/优惠券只读、客资/CRM 只读 |
|
||||
| teacher | 内容维护 |
|
||||
| sales | 兑换码、优惠券、客资 |
|
||||
| agent | 兑换码/优惠券只读、本人的客资 |
|
||||
| student | 无后台权限 |
|
||||
|
||||
后续要补:
|
||||
|
||||
- 租户自定义角色模板。
|
||||
- 菜单级、模块级、字段级权限。
|
||||
- 权限变更审计。
|
||||
- 班级/教师/学生范围权限。
|
||||
|
||||
## 上线前安全验收清单
|
||||
|
||||
- `npm audit` 为 0 高危/严重漏洞。
|
||||
- `npm run check:refactor` 通过。
|
||||
- 生产环境启动时默认密钥 fail-fast 生效。
|
||||
- 跨租户学生读取题目/订单/资料返回拒绝。
|
||||
- 销售只能查看自己权限范围内客资。
|
||||
- 代理不能查看其他代理客资。
|
||||
- 教师不能修改租户商户密钥。
|
||||
- 学生不能访问租户后台接口。
|
||||
- 未开通权益不能下载 SVIP 资料或播放会员视频。
|
||||
- 支付 webhook 重放不会重复开通权益。
|
||||
- 激活码并发兑换只能成功一次。
|
||||
- 对象存储签名 URL 有短 TTL。
|
||||
- 后台关键操作写入 audit log。
|
||||
|
||||
202
docs/refactor/taro-frontend-integration.md
Normal file
202
docs/refactor/taro-frontend-integration.md
Normal file
@@ -0,0 +1,202 @@
|
||||
# Taro 前端对接指南
|
||||
|
||||
更新时间:2026-06-28
|
||||
|
||||
目标:用一套 Taro 工程同时服务微信小程序和 H5 Web 题库,统一调用 `apps/api`,并支持多租户、品牌主题、地区题库、会员权益、销售追踪和对象存储资源。
|
||||
|
||||
建议新建:
|
||||
|
||||
```text
|
||||
F:\project\apps\taro
|
||||
```
|
||||
|
||||
旧前端参考:
|
||||
|
||||
```text
|
||||
F:\project\参考\旧题库项目\src
|
||||
```
|
||||
|
||||
## 启动流程
|
||||
|
||||
### H5
|
||||
|
||||
1. 从 `window.location.host` 获取当前域名。
|
||||
2. 调用 `GET /api/tenant/resolve?host=<host>`。
|
||||
3. 保存 `tenant.id`、`tenant.slug`、`branding`、`features`、`publicConfig`。
|
||||
4. 初始化主题、Logo、页面标题、功能开关。
|
||||
5. 检查本地 session token,调用 `GET /api/auth/me`。
|
||||
6. 如果未登录,进入登录页;如果已登录,加载个人中心和首页数据。
|
||||
|
||||
### 微信小程序
|
||||
|
||||
1. 从编译环境或小程序启动参数读取 `tenantCode`。
|
||||
2. 推广码、销售码、分享码从 `options` 或 `scene` 中解析。
|
||||
3. 调用 `GET /api/tenant/resolve?tenantCode=<tenantCode>`。
|
||||
4. 如存在 referral 参数,先调用 `/api/referral/resolve` 和 `/api/referral/track-event`。
|
||||
5. 登录后再调用 `/api/referral/bind` 完成首绑保护。
|
||||
|
||||
## 请求封装
|
||||
|
||||
前端应封装一个统一 API client,所有页面禁止直接散写 `Taro.request`。
|
||||
|
||||
迁移期请求头:
|
||||
|
||||
```text
|
||||
Authorization: Bearer <tk_session>
|
||||
x-tenant-id: <tenantId>
|
||||
x-user-id: <userId>
|
||||
```
|
||||
|
||||
生产目标:
|
||||
|
||||
```text
|
||||
Authorization: Bearer <jwt_or_session>
|
||||
```
|
||||
|
||||
生产后不应再由前端传 `x-user-id`。租户可以由可信 JWT claim、服务端 session、域名解析结果共同确定;前端传入的租户参数只能作为路由/展示上下文,不能作为安全依据。
|
||||
|
||||
统一错误处理:
|
||||
|
||||
| HTTP | 前端动作 |
|
||||
| --- | --- |
|
||||
| 400 | 展示表单错误或参数错误 |
|
||||
| 401 | 清 session,跳登录 |
|
||||
| 403 | 展示无权限或会员升级 |
|
||||
| 404 | 展示空状态 |
|
||||
| 409 | 展示业务冲突,例如激活码已用 |
|
||||
| 413 | 提示上传/导入文件过大 |
|
||||
| 429 | 倒计时重试,例如短信冷却 |
|
||||
| 500 | 展示系统异常并上报日志 |
|
||||
|
||||
## 全局状态建议
|
||||
|
||||
| Store | 内容 |
|
||||
| --- | --- |
|
||||
| tenantStore | tenant、branding、theme、features、publicConfig |
|
||||
| authStore | session、user、roles、permissions、loginState |
|
||||
| regionStore | 当前地区、可选地区、地区权益 |
|
||||
| catalogStore | content entries、nodes、collections、blueprints |
|
||||
| entitlementStore | SVIP 权益、视频权益、资料下载权益 |
|
||||
| referralStore | inviteCode、referrer、scene、bindState |
|
||||
| uiStore | 当前主题、tab、loading、toast、modal |
|
||||
|
||||
注意缓存必须带租户维度,例如:
|
||||
|
||||
```text
|
||||
tenant:<tenantId>:catalog:entries
|
||||
tenant:<tenantId>:profile
|
||||
tenant:<tenantId>:theme
|
||||
```
|
||||
|
||||
切换租户或切换小程序环境时必须清理旧租户缓存。
|
||||
|
||||
## 页面/API 映射
|
||||
|
||||
| 页面 | 主要接口 |
|
||||
| --- | --- |
|
||||
| 启动页 | `GET /api/tenant/resolve` |
|
||||
| 登录页 | `POST /api/auth/sms/send`、`POST /api/auth/sms/verify`、后续微信/QQ provider |
|
||||
| 首页 | `/api/catalog/content-entries`、`/api/catalog/banners`、`/api/catalog/announcements`、`/api/profile/me` |
|
||||
| 选地区 | `/api/catalog/regions`、`/api/commerce/entitlements/check` |
|
||||
| 题库入口 | `/api/catalog/content-entries` |
|
||||
| 分类树 | `/api/catalog/content-nodes?entryId=...&parentId=root` |
|
||||
| 题目列表 | `/api/catalog/question-collections`、`/api/catalog/question-collections/questions` |
|
||||
| 开始练习 | `POST /api/learning/practice-sessions` |
|
||||
| 提交答案 | `POST /api/learning/answers` |
|
||||
| 错题本 | `GET /api/learning/wrong-questions`、`POST /api/learning/wrong-questions/resolve` |
|
||||
| 收藏夹 | `GET/POST /api/learning/favorites/questions` |
|
||||
| 题目视频 | `GET /api/questions/{questionId}/videos`、`POST /api/questions/videos/batch` |
|
||||
| 背单词 | `/api/catalog/vocabulary-units`、`/api/catalog/vocabulary-words` |
|
||||
| 单词进度 | `/api/learning/vocabulary/progress`、`/api/learning/vocabulary/stats` |
|
||||
| 单词收藏 | `/api/learning/vocabulary/favorites` |
|
||||
| 知识手册 | `/api/catalog/handbook-subjects`、`handbook-chapters`、`handbook-entries` |
|
||||
| 分数线 | `/api/scoreline/fields`、`schools`、`majors`、`records`、`trend`、`years` |
|
||||
| 资料下载 | `/api/catalog/assets`、`/api/catalog/assets/download` |
|
||||
| 商城 | `/api/catalog/svip-plans`、`POST /api/commerce/orders` |
|
||||
| 订单/权益 | `/api/commerce/orders`、`/api/commerce/entitlements` |
|
||||
| 激活码兑换 | `POST /api/commerce/activation-codes/redeem` |
|
||||
| 个人中心 | `GET/PATCH /api/profile/me` |
|
||||
| 销售分享 | `/api/referral/resolve`、`track-event`、`bind` |
|
||||
|
||||
## 题库新模型接入方式
|
||||
|
||||
旧项目常按“地区 -> 科目 -> 章节/试卷”固定层级处理。新项目不要写死层级,按下面模型渲染:
|
||||
|
||||
```text
|
||||
content_entries
|
||||
-> content_nodes 任意深度分类树
|
||||
-> question_collections 题目列表/试卷/章节/题型集合
|
||||
-> practice_blueprints 顺序/随机/全真模拟规则
|
||||
```
|
||||
|
||||
前端建议:
|
||||
|
||||
- `entryType=question_practice` 渲染为刷题入口。
|
||||
- `entryType=vocabulary` 渲染为背单词入口。
|
||||
- `entryType=handbook` 渲染为知识手册入口。
|
||||
- `markerType=school` 或 `markerType=exam_track` 可作为学生目标院校/专业意向采集。
|
||||
- 不同地区节点层级可以不同,页面组件必须支持递归树和面包屑。
|
||||
|
||||
## 多租户前端优化
|
||||
|
||||
- Logo、标题、主题色、客服信息全部来自 `tenant/resolve`。
|
||||
- 功能开关控制菜单显示,但接口权限仍以后端为准。
|
||||
- 私有图片、PDF、视频不要直接拼 URL,一律通过后端签名。
|
||||
- 支付渠道从后端返回或租户配置读取,不在页面硬编码。
|
||||
- 小程序分享路径必须带 tenantCode 和 referral code。
|
||||
- 用户首绑归属由后端保护,前端不要提供“换绑销售”入口。
|
||||
- 管理后台菜单按 `GET /api/tenant-admin/permissions` 和用户权限渲染。
|
||||
- H5 自定义域名下要注意缓存隔离,不能把 A 租户主题缓存用到 B 租户。
|
||||
|
||||
## 第一阶段页面建议
|
||||
|
||||
1. `pages/bootstrap/index`
|
||||
- 租户解析、主题初始化、登录态恢复。
|
||||
2. `pages/login/index`
|
||||
- 先接短信登录;后续接微信小程序登录。
|
||||
3. `pages/home/index`
|
||||
- Banner、公告、题库入口、会员入口、资料入口。
|
||||
4. `pages/region/index`
|
||||
- 地区选择和权益提示。
|
||||
5. `pages/catalog/index`
|
||||
- entry/node/collection/blueprint 通用导航。
|
||||
6. `pages/practice/index`
|
||||
- 刷题、答题、解析、错题、收藏。
|
||||
7. `pages/vocabulary/index`
|
||||
- 单词单元、学习、收藏。
|
||||
8. `pages/handbook/index`
|
||||
- 手册目录和阅读。
|
||||
9. `pages/scoreline/index`
|
||||
- 动态字段筛选和趋势。
|
||||
10. `pages/profile/index`
|
||||
- 会员、订单、激活码、学习数据。
|
||||
|
||||
## 租户后台前端建议
|
||||
|
||||
租户后台可以先做 H5 管理台,也可以后续使用 Taro H5 复用部分组件。优先页面:
|
||||
|
||||
- 概览:`/api/tenant-admin/overview`
|
||||
- 品牌/主题/域名/公开设置
|
||||
- 支付账户/登录 provider/密钥引用
|
||||
- 用户与成员权限
|
||||
- 内容入口/分类树/题目集合/练习蓝图
|
||||
- 题目/单词/知识手册/分数线/视频维护
|
||||
- JSON 导入 preview/import/issues
|
||||
- Banner/FAQ/公告/激活码/优惠券
|
||||
- 销售/代理/CRM 队列
|
||||
|
||||
租户后台不应在前端自行决定权限;隐藏菜单只是体验优化,接口仍会校验权限。
|
||||
|
||||
## 联调顺序
|
||||
|
||||
1. 启动页和租户解析。
|
||||
2. 短信登录和 `auth/me`。
|
||||
3. 首页、地区、内容入口、题库树。
|
||||
4. 练习 session、答题、错题、收藏。
|
||||
5. 背单词、知识手册、分数线。
|
||||
6. 会员套餐、订单、激活码。
|
||||
7. 资料下载、视频解析。
|
||||
8. 销售追踪和分享链路。
|
||||
9. 租户后台内容维护和导入。
|
||||
10. 正式鉴权、真实支付、对象存储生产联调。
|
||||
|
||||
Reference in New Issue
Block a user