forked from wangziqi/gongxue-base
12 KiB
12 KiB
后端重构进度
已完成
- 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:域名/租户解析。
- 鉴权上下文已支持 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支持教师/班主任/助教/学生分组,教师按负责班级查看学生,字段权限可脱敏学生手机号。 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,并断言核心学生端接口、内容导航/组卷、租户隔离、资源权限和题目导入。
已验证接口
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
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
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/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
GET /api/tenant-admin/students
PUT /api/tenant-admin/students
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/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,不保存明文;本地
mockprovider 才会返回debugCode。 platform-admin已支持平台管理员 Supabase JWT;x-platform-admin-key只作为非生产兼容保护。- B 端合作商年费/服务费使用
tenant_invoices、tenant_invoice_items、tenant_invoice_payments,不与 C 端学生订单混表。 - 订单金额以后端套餐价格为准,不信任前端传价。
- 激活码兑换和支付成功都走同一套
grantSvipEntitlement权益开通逻辑。 - 租户支付账户、短信、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 当前完成配置、密钥入私密表、客资入队和队列查询;真实 webhook 发送、重试、签名在后续
apps/worker中实现。 - 内容资源当前完成台账、租户后台维护、学生端 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管线。
下一步
- 完善内容导入和文件上传:Excel/CSV、分数线、视频导入,对象存储上传后校验、PDF 预览、防盗链和视频水印。
- 接入真实短信 provider:阿里云/腾讯云,密钥放
app_private.tenant_secrets或生产 Vault。 - 接入真实 OAuth provider:微信网页、微信小程序、QQ,并处理旧 PocketBase 身份映射。
- 增加真实支付 provider:XPay、微信支付、支付宝,并完善 webhook 幂等。
- 增加
apps/worker:支付补偿、CRM webhook、日报统计、导入后检查。 - 开始 Taro scaffold,把
supabaseApi抽到跨端包或适配层。
测试命令
npm run test:api
npm run check:refactor