Files
gongxue-base/docs/refactor/backend-progress.md
2026-06-22 00:58:36 +08:00

197 lines
10 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.

# 后端重构进度
## 已完成
- Docker Desktop + Supabase local 已可用。
- API Docker 镜像 `tiku-saas-dev-api:latest` 已可构建,并可从容器连接宿主 Supabase PostgreSQL。
- API 已按 `core/features` 分层:
- `auth`:短信验证码登录、迁移期 session、OAuth provider 预留。
- `catalog`公开题库、地区、内容入口、分类树、题目集合、练习蓝图、手册、商品、SVIP 套餐、资料资源只读/下载接口。
- `learning`:顺序/随机/全真模拟组卷 session、答题记录、错题、收藏、背单词进度/收藏/统计。
- `profile`:学生个人中心、目标院校/专业、会员状态、统计聚合、最近练习。
- `scoreline`:分数线字段、院校、专业、记录、趋势、年份。
- `video`:题目视频讲解、批量预加载、通用视频搜索。
- `commerce`:订单、支付确认、激活码兑换、权益查询。
- `referral`:销售/代理邀请码、首绑客资保护、销售统计、团队关系、CRM 队列。
- `platform-admin`平台方租户管理、SaaS 套餐、订阅、账单、服务费收款、使用量。
- `tenant-admin`:租户资料、品牌、公开设置、域名、支付账户、登录 provider、私密密钥掩码、活动内容、激活码批次、优惠券、成员管理、权限矩阵、审计查询。
- `tenant-content`:租户后台内容入口、任意深度分类树、考试意向标记、题目集合、练习蓝图、题目、视频、分数线、单词、知识手册、资料资源、题目/单词/知识手册 JSON 导入维护。
- `tenant`:域名/租户解析。
- `src/services/supabaseApi.ts` 已加入新 API 客户端方法,供旧 Web 逐步替换和后续 Taro 复用。
- 已新增 `npm run db:smoke-seed`,用于 `supabase:reset` 后恢复最小烟测数据。
- 已新增 `npm run smoke:core-api`,用于验证个人中心、分数线、题目视频、背单词进度/收藏等学生端核心 API。
- 已新增 `npm run test:api`,自动 seed、构建、启动临时 API并断言核心学生端接口、内容导航/组卷、租户隔离、资源权限和题目导入。
## 已验证接口
```text
GET /health
POST /api/auth/sms/send
POST /api/auth/sms/verify
GET /api/auth/me
POST /api/auth/logout
POST /api/auth/oauth/wechat
POST /api/auth/oauth/wechat-miniapp
POST /api/auth/oauth/qq
GET /api/tenant/resolve
GET /api/platform-admin/overview
GET /api/platform-admin/plans
GET /api/platform-admin/tenants
POST /api/platform-admin/tenants
GET /api/platform-admin/tenants/detail
PATCH /api/platform-admin/tenants/status
PUT /api/platform-admin/tenants/billing-profile
POST /api/platform-admin/subscriptions
GET /api/platform-admin/invoices
POST /api/platform-admin/invoices
POST /api/platform-admin/invoices/from-subscription
POST /api/platform-admin/invoices/payments/manual-confirm
GET /api/platform-admin/usage
POST /api/platform-admin/usage
GET /api/catalog/*
GET /api/catalog/content-entries
GET /api/catalog/content-nodes
GET /api/catalog/question-collections
GET /api/catalog/question-collections/questions
GET /api/catalog/practice-blueprints
GET /api/catalog/assets
GET /api/catalog/assets/download
POST /api/learning/answers
GET /api/learning/favorites/questions
POST /api/learning/favorites/questions
GET /api/learning/wrong-questions
GET /api/learning/vocabulary/progress
POST /api/learning/vocabulary/progress
GET /api/learning/vocabulary/favorites
POST /api/learning/vocabulary/favorites
GET /api/learning/vocabulary/stats
GET /api/profile/me
PATCH /api/profile/me
GET /api/scoreline/fields
GET /api/scoreline/schools
GET /api/scoreline/majors
GET /api/scoreline/records
GET /api/scoreline/trend
GET /api/scoreline/years
GET /api/questions/{questionId}/videos
POST /api/questions/videos/batch
GET /api/videos/search
GET /api/tenant-content/content-entries
PUT /api/tenant-content/content-entries
GET /api/tenant-content/content-nodes
PUT /api/tenant-content/content-nodes
GET /api/tenant-content/question-collections
PUT /api/tenant-content/question-collections
PUT /api/tenant-content/question-collections/items
GET /api/tenant-content/practice-blueprints
PUT /api/tenant-content/practice-blueprints
POST /api/tenant-content/questions
PATCH /api/tenant-content/questions
GET /api/tenant-content/assets
PUT /api/tenant-content/assets
POST /api/tenant-content/assets/sign-upload
POST /api/tenant-content/assets/sign-download
POST /api/tenant-content/imports/preview/questions
POST /api/tenant-content/imports/questions
POST /api/tenant-content/imports/preview/vocabulary
POST /api/tenant-content/imports/vocabulary
POST /api/tenant-content/imports/preview/handbook
POST /api/tenant-content/imports/handbook
GET /api/tenant-content/imports
GET /api/tenant-content/imports/issues
PUT /api/tenant-content/videos
POST /api/tenant-content/question-videos
PUT /api/tenant-content/scoreline/schools
PUT /api/tenant-content/scoreline/majors
PUT /api/tenant-content/scoreline/fields
PUT /api/tenant-content/scoreline/records
PUT /api/tenant-content/vocabulary-units
PUT /api/tenant-content/vocabulary-words
PUT /api/tenant-content/handbook-subjects
PUT /api/tenant-content/handbook-chapters
PUT /api/tenant-content/handbook-entries
POST /api/commerce/orders
GET /api/commerce/orders
POST /api/commerce/payments/manual-confirm
POST /api/commerce/activation-codes/redeem
GET /api/commerce/entitlements
GET /api/commerce/entitlements/check
POST /api/referral/invite-code
POST /api/referral/resolve
POST /api/referral/track-event
POST /api/referral/bind
GET /api/referral/stats
GET /api/referral/sales-stats
GET /api/referral/sales-clients
POST /api/referral/manual-bind
GET /api/referral/team
PUT /api/referral/team
POST /api/referral/qrcode
GET /api/crm/config
PUT /api/crm/config
GET /api/crm/queue
GET /api/tenant-admin/permissions
GET /api/tenant-admin/overview
PUT /api/tenant-admin/branding
PUT /api/tenant-admin/settings
GET /api/tenant-admin/domains
POST /api/tenant-admin/domains
GET /api/tenant-admin/payment-accounts
PUT /api/tenant-admin/payment-accounts
GET /api/tenant-admin/auth-providers
PUT /api/tenant-admin/auth-providers
GET /api/tenant-admin/secrets
PUT /api/tenant-admin/secrets
GET /api/tenant-admin/banners
PUT /api/tenant-admin/banners
GET /api/tenant-admin/faqs
PUT /api/tenant-admin/faqs
GET /api/tenant-admin/announcements
PUT /api/tenant-admin/announcements
GET /api/tenant-admin/code-batches
PUT /api/tenant-admin/code-batches
GET /api/tenant-admin/activation-codes
PUT /api/tenant-admin/activation-codes
POST /api/tenant-admin/activation-codes/generate
GET /api/tenant-admin/coupons
PUT /api/tenant-admin/coupons
GET /api/tenant-admin/members
PUT /api/tenant-admin/members
POST /api/tenant-admin/members/disable
GET /api/tenant-admin/audit-logs
```
## 迁移期约定
- 当前写接口用 `x-tenant-id``x-user-id` 做迁移期上下文。
- `auth` 当前签发迁移期 `tk_` sessiontoken hash 存在 `app_private.auth_sessions`;后续接 Supabase Auth 后,`x-user-id` 要替换为 JWT 用户身份解析。
- 短信验证码只保存 HMAC hash不保存明文本地 `mock` provider 才会返回 `debugCode`
- `platform-admin` 当前用 `x-platform-admin-key` 做迁移期保护,生产后必须替换为平台管理员 JWT/服务端会话。
- B 端合作商年费/服务费使用 `tenant_invoices``tenant_invoice_items``tenant_invoice_payments`,不与 C 端学生订单混表。
- 订单金额以后端套餐价格为准,不信任前端传价。
- 激活码兑换和支付成功都走同一套 `grantSvipEntitlement` 权益开通逻辑。
- 租户支付账户、短信、OAuth 登录配置接口只保存公开配置;密钥进入 `app_private.tenant_secrets` 或生产 KMS/VaultAPI 只返回 `secretRef` 和掩码状态。
- `tenant-admin` 采用角色默认权限 + `tenant_memberships.permissions` 覆盖的权限矩阵。成员可进入后台,但每个接口会校验具体权限点;学生和跨租户成员会被拒绝。
- 当前默认角色:`tenant_owner`/`tenant_admin` 全权限,`tenant_operator` 可维护内容和活动,`teacher` 可维护内容,`sales` 可维护激活码和优惠券,`agent` 只读部分兑换码/优惠券。
- 销售/代理客资采用首绑保护:普通扫码/分享事件不会覆盖已有归属,只有具备 `referral:write` 的租户成员可手动强制补绑。
- CRM 当前完成配置、密钥入私密表、客资入队和队列查询;真实 webhook 发送、重试、签名在后续 `apps/worker` 中实现。
- 内容资源当前完成台账、租户后台维护、学生端 SVIP 下载权限,以及 `local_dev`、阿里云 OSS、腾讯 COS、Supabase Storage 的上传/下载签名 provider。真实对象存在性校验、PDF 预览渲染、防盗链、水印和大文件上传后 worker 校验仍需继续补。
- 题库内容导航当前以 `content_entries/content_nodes` 为主模型,可表达“入口 -> 多级分类 -> 院校/专业/学科/销售意向标记”;题目集合和练习方式由 `question_collections/practice_blueprints` 管理,练习 session 会保存当次题目 ID 快照。
- 批量导入当前支持题目、单词、知识手册 JSON 预览、逐行 issue、job/item 台账、执行导入、幂等跳过,并可落到新内容入口和分类节点。旧单词模板的 `vocabulary_units_示例数据` / `vocabulary_示例数据`、知识手册的书籍/章节/小节/知识点嵌套结构都由后端规范化。Excel/CSV、分数线/视频导入会继续复用同一套 `content_import_jobs` 管线。
## 下一步
1. 完善内容导入和文件上传Excel/CSV、分数线、视频导入对象存储上传后校验、PDF 预览、防盗链和视频水印。
2. 接入真实短信 provider阿里云/腾讯云,密钥放 `app_private.tenant_secrets` 或生产 Vault。
3. 接入真实 OAuth provider微信网页、微信小程序、QQ并处理旧 PocketBase 身份映射。
4. 增加真实支付 providerXPay、微信支付、支付宝并完善 webhook 幂等。
5. 增加 `apps/worker`支付补偿、CRM webhook、日报统计、导入后检查。
6. 开始 Taro scaffold`supabaseApi` 抽到跨端包或适配层。
## 测试命令
```text
npm run test:api
npm run check:refactor
```