forked from wangziqi/gongxue-base
260 lines
16 KiB
Markdown
260 lines
16 KiB
Markdown
# 后端重构进度
|
||
|
||
## 已完成
|
||
|
||
- 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`:订单创建/列表/详情/状态轮询、支付确认、支付 provider/webhook、激活码预检查/兑换、优惠券领取/抵扣、权益查询。
|
||
- `referral`:销售/代理邀请码、首绑客资保护、销售统计、团队关系、CRM 队列、分佣设置、佣金来源汇总、结算单和审核/打款状态。
|
||
- `platform-admin`:平台方租户管理、SaaS 套餐、订阅、账单、服务费收款、使用量。
|
||
- `tenant-admin`:租户资料、品牌、公开设置、域名、支付账户、登录 provider、私密密钥掩码、活动内容、考试日期、题目反馈处理、激活码批次、优惠券、成员管理、角色模板、班级/学生/教师范围权限、权限矩阵、审计查询。
|
||
- `tenant-content`:租户后台内容入口、任意深度分类树、考试意向标记、题目集合、练习蓝图、题目、视频、分数线、单词、知识手册、资料资源、题目/单词/知识手册 JSON 导入维护。
|
||
- `tenant`:域名/租户解析。
|
||
- 鉴权上下文已支持 Supabase Auth JWT 和迁移期 `tk_` session 双入口,JWT 通过 `auth.users.id -> platform_users.auth_user_id -> tenant_memberships` 映射业务用户和租户;平台管理员 JWT 已可访问平台后台。
|
||
- 租户自定义角色模板已落库:`tenant_role_templates` 支持权限、菜单、模块、字段和数据范围配置,成员可通过 `role_template_id` 绑定模板。
|
||
- 班级与学生范围权限已落库:`tenant_classes`、`tenant_class_members` 支持教师/班主任/助教/学生分组,教师按负责班级查看学生,字段权限可脱敏学生手机号。
|
||
- 学生运营管理已落库:`tenant_student_notes`、`tenant_student_followups` 支持学生备注、家校/班主任/销售跟进任务、可见性、指派、完成状态和审计;批量学生 upsert、批量分班、禁用/恢复也已接入权限校验。
|
||
- 旧题库常用运营功能已补齐一批:`exam_dates` 支持学生端考试倒计时和租户后台维护;`reports/report_status_events` 支持学生题目反馈、租户后台状态流转;`user_score_events` 支持每日签到积分流水和反馈奖励幂等。
|
||
- 旧题库排行榜主链路已补齐:`GET /api/learning/leaderboard` 支持刷题、积分、背单词、模考四类指标,支持全量/7 天/30 天周期,以及租户/地区/班级范围。
|
||
- `learning` 已接入商用访问控制:免费用户每日题量、SVIP 范围、SVIP-only 内容、答题 session 快照保护由后端强制执行。
|
||
- `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,并断言核心学生端接口、内容导航/组卷、租户隔离、资源权限和题目导入。
|
||
- 已新增 `apps/worker` 和 `npm run test:worker:crm`,用于消费 CRM webhook 队列,验证本地 fake webhook、队列状态、日志和密钥不泄露。
|
||
|
||
## 已验证接口
|
||
|
||
```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
|
||
GET /api/catalog/exam-dates
|
||
POST /api/learning/answers
|
||
GET /api/learning/leaderboard
|
||
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
|
||
POST /api/profile/check-in
|
||
GET /api/profile/score-events
|
||
GET /api/profile/feedbacks
|
||
POST /api/profile/feedbacks
|
||
GET /api/profile/exam-countdowns
|
||
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
|
||
POST /api/videos/play
|
||
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
|
||
GET /api/commerce/orders/detail
|
||
GET /api/commerce/orders/status
|
||
POST /api/commerce/payments/create
|
||
POST /api/commerce/payments/manual-confirm
|
||
POST /api/commerce/payments/notify/wechat_pay
|
||
POST /api/commerce/payments/notify/alipay
|
||
POST /api/commerce/activation-codes/check
|
||
POST /api/commerce/activation-codes/redeem
|
||
POST /api/commerce/coupons/claim
|
||
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/commission/settings
|
||
PUT /api/commission/settings
|
||
PUT /api/commission/member-rate
|
||
GET /api/commission/summary
|
||
GET /api/commission/orders
|
||
GET /api/commission/settlements
|
||
POST /api/commission/settlements/generate
|
||
POST /api/commission/settlements/status
|
||
GET /api/crm/config
|
||
PUT /api/crm/config
|
||
GET /api/crm/queue
|
||
GET /api/tenant-admin/permissions
|
||
GET /api/tenant-admin/role-templates
|
||
PUT /api/tenant-admin/role-templates
|
||
POST /api/tenant-admin/role-templates/disable
|
||
GET /api/tenant-admin/classes
|
||
PUT /api/tenant-admin/classes
|
||
POST /api/tenant-admin/classes/disable
|
||
GET /api/tenant-admin/classes/members
|
||
PUT /api/tenant-admin/classes/members
|
||
POST /api/tenant-admin/classes/members/remove
|
||
POST /api/tenant-admin/classes/members/bulk-assign
|
||
GET /api/tenant-admin/students
|
||
PUT /api/tenant-admin/students
|
||
POST /api/tenant-admin/students/bulk-upsert
|
||
POST /api/tenant-admin/students/status
|
||
GET /api/tenant-admin/students/notes
|
||
PUT /api/tenant-admin/students/notes
|
||
GET /api/tenant-admin/students/followups
|
||
PUT /api/tenant-admin/students/followups
|
||
GET /api/tenant-admin/teachers
|
||
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/exam-dates
|
||
PUT /api/tenant-admin/exam-dates
|
||
GET /api/tenant-admin/feedbacks
|
||
POST /api/tenant-admin/feedbacks/status
|
||
GET /api/tenant-admin/feedbacks/events
|
||
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
|
||
```
|
||
|
||
## 迁移期约定
|
||
|
||
- 当前 API 已支持 Supabase Auth JWT 和迁移期 `tk_` session;新前端应优先使用 `Authorization: Bearer <supabase_access_token>`。
|
||
- `x-tenant-id` 只作为租户上下文,后端会校验 JWT/session 用户确实属于该租户;`x-user-id` 只允许在非生产兼容测试中使用。
|
||
- `auth` 当前仍可签发迁移期 `tk_` session,token hash 存在 `app_private.auth_sessions`,用于旧数据迁移和本地联调。
|
||
- 短信验证码只保存 HMAC hash,不保存明文;本地 `mock` provider 才会返回 `debugCode`。
|
||
- `platform-admin` 已支持平台管理员 Supabase JWT;`x-platform-admin-key` 只作为非生产兼容保护。
|
||
- B 端合作商年费/服务费使用 `tenant_invoices`、`tenant_invoice_items`、`tenant_invoice_payments`,不与 C 端学生订单混表。
|
||
- 订单金额以后端套餐价格为准,不信任前端传价。
|
||
- 激活码兑换、支付成功和零元优惠订单都走同一套 `grantSvipEntitlement` 权益开通逻辑。
|
||
- 优惠券领取同用户同券幂等;下单后优惠券 redemption 会绑定订单并进入 `used`,订单明细会写入负数 `coupon_discount` 项。
|
||
- `/api/commerce/payments/manual-confirm` 是线下收款/迁移期能力,只允许租户后台具备 `tenant:payment:write` 的成员调用,普通学生不能伪造手工支付成功。
|
||
- `/api/commerce/refunds` 和 `/api/commerce/refunds/status` 已提供内部退款状态机;退款权限拆分为 `tenant:refund:read/write/review`,可调用微信/支付宝发起退款,并通过 `query_provider_refund` 主动查询确认供应商退款结果,全额退款成功会撤销订单来源权益;退款通知 webhook、对账 worker 后续接入。
|
||
- 租户支付账户、短信、OAuth 登录配置接口只保存公开配置;密钥进入 `app_private.tenant_secrets` 或生产 KMS/Vault,API 只返回 `secretRef` 和掩码状态。
|
||
- `tenant-admin` 采用角色默认权限 + `tenant_memberships.permissions` 覆盖的权限矩阵。成员可进入后台,但每个接口会校验具体权限点;学生和跨租户成员会被拒绝。
|
||
- 当前默认角色:`tenant_owner`/`tenant_admin` 全权限,`tenant_operator` 可维护内容和活动,`teacher` 可维护内容并按班级范围查看学生,`sales` 可维护激活码和优惠券,`agent` 只读部分兑换码/优惠券。
|
||
- 班级学生 API 会按 `tenant_memberships.role_template_id -> tenant_role_templates.data_scope`、成员显式权限和 `tenant_class_members` 共同确定可见范围;非全局权限教师只能查看自己负责班级的学生。
|
||
- 学生批量导入、批量分班、学生状态、备注和跟进任务都使用独立权限点;教师默认可为范围内学生写备注和跟进任务,但不能批量导入、禁用学生或放大可见班级。
|
||
- 销售/代理客资采用首绑保护:普通扫码/分享事件不会覆盖已有归属,只有具备 `referral:write` 的租户成员可手动强制补绑。
|
||
- CRM 当前完成配置、密钥入私密表、客资入队、队列查询和 `apps/worker` 消费;worker 支持 generic webhook、钉钉、飞书、企业微信机器人消息体/签名、失败重试和日志。
|
||
- 内容资源当前完成台账、租户后台维护、学生端 SVIP 下载权限,以及 `local_dev`、阿里云 OSS、腾讯 COS、Supabase Storage 的上传/下载签名 provider。真实对象存在性校验、PDF 预览渲染、防盗链、水印和大文件上传后 worker 校验仍需继续补。
|
||
- 题库内容导航当前以 `content_entries/content_nodes` 为主模型,可表达“入口 -> 多级分类 -> 院校/专业/学科/销售意向标记”;题目集合和练习方式由 `question_collections/practice_blueprints` 管理,练习 session 会保存当次题目 ID 快照。
|
||
- 练习访问控制由 `content_entries/content_nodes/question_collections/practice_blueprints` 的 `accessRules` 合并决定;普通用户消耗 `practice_daily_usage`,事件写入 `practice_access_events`,SVIP/staff 不消耗免费额度。
|
||
- 批量导入当前支持题目、单词、知识手册 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. 补微信退款通知 webhook、支付补偿任务、对账、异常订单自动处理和优惠券核销报表;退款查询确认主链路已完成。
|
||
5. 扩展 `apps/worker`:支付补偿、日报统计、导入后检查、CRM 死信告警和公共题库同步。
|
||
6. 开始 Taro scaffold,把 `supabaseApi` 抽到跨端包或适配层。
|
||
|
||
## 测试命令
|
||
|
||
```text
|
||
npm run test:api
|
||
npm run test:worker:crm
|
||
npm run check:refactor
|
||
```
|