Files
gongxue-base/docs/refactor/backend-capability-status.md
2026-07-01 06:09:23 +08:00

245 lines
38 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.

# 后端当前能力盘点
更新时间2026-07-01
当前后端已经完成商用 SaaS 题库系统的主干骨架PostgreSQL 多租户 schema、Node.js 业务 API、PocketBase 数据导入工具、本地 seed、API 集成测试和对象存储签名 provider。
状态分为:
- `可联调`:前端可以开始接入,本地测试已覆盖主链路。
- `迁移期`:能支撑开发联调,但生产前必须替换或加固。
- `待补齐`:旧题库已有或商用交付需要,但新后端还没完整实现。
## 基础工程
| 模块 | 状态 | 说明 |
| --- | --- | --- |
| Supabase/PostgreSQL schema | 可联调 | `supabase/migrations` 已包含多租户、题库、学习、订单、内容、CRM、平台账务等表 |
| RLS/租户隔离 | 可联调 | 表层普遍有 `tenant_id` 和 RLS 策略API 已支持 `tk_` 迁移 session 与 Supabase Auth JWT 双入口,并覆盖跨租户/伪造身份集成测试;生产前继续补真实云端 JWT/RLS 回归 |
| API 分层 | 可联调 | `apps/api/src/core` + `apps/api/src/features/*` |
| Docker API | 可联调 | `docker-compose.api.yml``apps/api/Dockerfile` 可用 |
| 生产配置门禁 | 可联调 | `readiness:production`/`:db` 和 API/worker 启动 fail-fast 会阻断弱密钥、mock/未知短信 provider、legacy 身份头、local_dev/未知存储、非 HTTPS 存储公开 URL、非官方阿里云 OSS endpoint、阿里云 OSS 内网直签、未接外部资源扫描、provider 公开配置混入密钥、OAuth/支付回调非 HTTPS 或缺必填字段 |
| 测试 | 可联调 | `npm run check:refactor` 覆盖 TS 检查、导入校验、生产 readiness 脚本测试、seed、API 集成测试;排行榜已覆盖默认关闭、四类指标、班级范围和跨租户拒绝 |
| 根 workspace | 可联调 | 根目录已清理为新技术栈 monorepo 编排层 |
## 租户与品牌
| 能力 | 状态 | 后端接口/模型 |
| --- | --- | --- |
| 域名/小程序码解析租户 | 可联调 | `GET /api/tenant/resolve` |
| 品牌名、Logo、客服、主题 JSON | 可联调 | `tenant_branding``tenant_settings` |
| 功能开关 | 可联调 | `features``adminFeatures` |
| 自定义域名管理 | 可联调 | `GET/POST /api/tenant-admin/domains` |
| 多套主题模板 | 可联调 | `tenant_theme_templates``tenant_theme_configs` + `/api/tenant-admin/theme-templates``theme``theme/preview``theme/publish`;已内置经典蓝、专注绿、高对比三套模板,支持租户草稿预览、发布、审计和公开解析返回已发布主题 |
## 鉴权与权限
| 能力 | 状态 | 说明 |
| --- | --- | --- |
| 短信验证码登录 | 可联调 | 已有验证码、冷却、hash、登录事件支持 mock、阿里云短信、腾讯云短信 provider生产仍需真实账号联调 |
| 迁移期 session | 迁移期 | `tk_` token hash 存在 `app_private.auth_sessions`,用户态接口已优先解析 bearer session 并拒绝伪造 userId/tenantId |
| Supabase Auth JWT | 可联调 | API 已用 Bearer JWT 验签并通过 `auth.users.id -> platform_users.auth_user_id -> tenant_memberships` 映射业务身份;支持 HS256 JWT secret 或 JWKS测试覆盖学生、租户管理员、平台管理员、错租户、坏签名 |
| 微信小程序登录 | 可联调 | `/api/auth/oauth/wechat-miniapp` 已接 `code2Session`、openid/unionid 身份、session 签发和登录审计 |
| 手机号绑定/换绑 | 可联调 | `/api/auth/phone/bind` 使用 `bind_phone` 短信验证码,后端校验当前登录态、手机号唯一性、移除旧手机号 identity并撤销其它迁移期 session |
| 微信网页/QQ OAuth | 可联调 | `/api/auth/oauth/wechat` 已完成微信网页登录 code 换 token、userinfo、unionid 合并、session 签发和审计;`/api/auth/oauth/qq` 已完成 code/token/openid/userinfo 主链路;生产前需真实开放平台账号和回调域名联调 |
| 平台管理员鉴权 | 可联调 | 已支持平台管理员 Supabase JWT平台账号以后端 `platform_users.primary_role='platform_admin'``status='active'``platform_permissions` 为准;`GET /api/platform-admin/permissions` 返回权限目录和当前账号 `effective` 能力,平台路由按 `platform:staff:*``platform:tenant:*``platform:billing:*``platform:audit:*``platform:question_bank:*` 等权限点强制校验;`GET/PUT/PATCH /api/platform-admin/staff` 可管理平台员工,禁用员工会拒绝后续 JWT 映射并撤销迁移期 session`x-platform-admin-key` 仅作本地/迁移期兼容且可通过配置禁用 |
| 平台 SaaS 用量采集和超额账单 | 可联调 | `GET/POST /api/platform-admin/usage` 保留平台用量台账和手工调整能力;`apps/worker --job platform-usage` 会按月自动从权威业务表采集学生数、活跃学生、题量、资源数、存储 GB、视频数、视频播放、视频次数消耗、已支付订单、GMV 和有效权益,写入 `tenant_usage_records.metadata.source=platform_usage_worker` 和审计日志;手工调整记录不被覆盖,平台概览优先取每租户每指标最新 worker 快照;`GET /api/platform-admin/invoices/usage-overage-candidates``POST /api/platform-admin/invoices/from-usage-overage` 已支持按账期读取最新用量、套用 SaaS 套餐 `included_quotas/overage_prices` 或订阅 metadata 覆盖、dry-run/正式生成 `usage_overage` 账单、重复开票保护和平台审计;`apps/worker --job platform-usage-overage` 会校验 `YYYY-MM` 账期、自动生成上月超额账单,失败时写入脱敏 `platform.invoice.usage_overage_worker_failed` 审计并由平台审计告警 worker 生成高优先级告警 |
| 租户角色权限 | 可联调 | `tenant_memberships.role + permissions + role_template_id`,接口有权限点校验 |
| 自定义角色模板 | 可联调 | `tenant_role_templates` + `/api/tenant-admin/role-templates`支持权限、菜单、模块、字段、数据范围配置Taro 租户设置页已接创建、编辑、停用、权限点、菜单、模块、字段和基础数据范围配置第一版 |
| 班级/教师/学生范围权限 | 可联调 | `tenant_classes``tenant_class_members` + `/api/tenant-admin/classes``classes/members``students``teachers`;教师默认只看自己负责班级,字段权限可脱敏学生手机号 |
| 学生运营备注、跟进和学习督导 | 可联调 | `tenant_student_notes``tenant_student_followups``tenant_student_supervision_rules` + `/api/tenant-admin/students/notes``students/followups``students/supervision/preview``students/supervision/generate``students/supervision/rules`;教师/班主任只能操作范围内学生,支持备注可见性、任务指派、完成状态、学习风险候选预览、自动生成跟进任务、督导规则模板和审计;`apps/worker --job student-supervision` 可按启用规则定时生成 `learning` 跟进任务 |
## 学生端题库主链路
| 能力 | 状态 | 后端接口/模型 |
| --- | --- | --- |
| 地区/科目/分类兼容查询 | 可联调 | `/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`后端强制校验免费额度、SVIP 范围和内容访问规则 |
| 答题记录 | 可联调 | `POST /api/learning/answers`;题目必须属于本人有效 session 快照;客观题后端判分、主观题 `selfJudgedCorrect` 自评、阅读理解/案例分析用 `subAnswers` 保存和判分每个子题 |
| 错题本 | 可联调 | `/api/learning/wrong-questions` |
| 收藏夹 | 可联调 | `/api/learning/favorites/questions` |
| 免费用户题量限制 | 可联调 | `practice_daily_usage` + `practice_access_events`;支持内容 accessRules、每日额度、session 截断、SVIP-only 拦截 |
| 模考交卷报告 | 可联调 | `POST /api/learning/practice-sessions/submit``GET /api/learning/practice-sessions/report``GET /api/learning/practice-reports`;后端按 session 快照评分、分段统计、错题解析汇总,复合题返回 `questionResults[].subResults` 和部分得分,重复提交幂等 |
| 学习历史/统计/趋势 | 可联调 | `GET /api/learning/practice-sessions/history``GET /api/learning/stats``GET /api/learning/trend`;可支撑个人中心、练习历史、正确率趋势和题型分布 |
| 错题复习计划 | 可联调 | `GET /api/learning/wrong-questions/review-plan` + `POST /api/learning/practice-sessions``mode=wrong_review`,后端从本人错题本安全组卷 |
| 学习排行榜 | 可联调 | `GET /api/learning/leaderboard`;租户 `feature_flags.enableLeaderboard` 默认关闭,开启后支持 `questions``score``vocabulary``mock_exam` 四类指标,支持 `all``7d``30d` 周期和租户/地区/班级范围,返回当前用户排名并拒绝跨租户 session返回头像只使用 `avatarPreset` 默认头像路径,不暴露第三方头像 URL当前产品默认不在学生端请求排行榜日常激励以后台配置勋章自动发放为主 |
| 考试倒计时 | 可联调 | `GET /api/catalog/exam-dates``GET /api/profile/exam-countdowns`;返回租户/地区匹配考试日期和 `daysLeft` |
| 学生预设头像 | 可联调 | `GET/PATCH /api/profile/me`;仅支持 `avatarPreset=male/female` 和系统默认头像路径Taro 学生个人中心已接二选一 UI 和默认静态资源;后端拒绝直接 `PATCH avatarUrl`,不提供用户头像上传;微信/QQ 登录、PocketBase 导入脚本、租户后台学生 upsert/批量导入/批量分班均不会把第三方头像 URL 写入学生资料,学生写入口带头像字段会返回或逐行记录 `STUDENT_AVATAR_URL_UNSUPPORTED` |
| 题目反馈/纠错 | 可联调 | `GET/POST /api/profile/feedbacks`,题目必须属于当前租户;租户后台可处理状态流转,处理结果和奖励积分会写入用户站内通知;`GET /api/tenant-admin/feedbacks/report` 已提供 7/30/90 天只读运营聚合,包含状态/类型/分类/优先级分布、处理效率、奖励积分、高频题目和待处理积压 |
| 签到积分 | 可联调 | `POST /api/profile/check-in``GET /api/profile/score-events`;积分流水幂等、事务加锁,重复签到不重复加分;租户可用 `taskType=daily_check_in` 积分任务配置基础/连续签到奖励,后端自动写积分流水和领取记录;真实签到成功会触发 `check_in``score` 规则勋章自动发放,重复签到不重复发放 |
| 积分活动/兑换 | 可联调 | `GET /api/profile/activity-tasks``POST /api/profile/activity-tasks/claim``GET /api/profile/exchange-items``POST /api/profile/exchange-items/redeem``GET /api/tenant-admin/points-risk-report`;复用 `user_score_events` 积分账本,任务领取和兑换均事务加锁;手动/练习/单词/模考类任务有后端证据校验,反馈解决等系统任务禁止学生自领;兑换支持库存、个人限购、余额校验、幂等 key、优惠券履约、兑换订单和完成/待履约站内通知;租户后台积分风控报表按 7/30/90 天只读聚合异常用户、大额积分事件、高频任务和大额兑换,不直接改账、封禁或冻结权益 |
| 学生勋章 | 可联调 | `GET /api/profile/badges`;支持分类筛选、已解锁/未解锁展示,后端只返回当前租户当前用户的勋章状态;签到连续天数、积分阈值、反馈解决、积分活动、练习次数、单词掌握和模考成绩规则已支持自动发放,自动/手动获得勋章会写入用户站内通知 |
| 学生站内通知 | 可联调 | `GET /api/profile/notifications``POST /api/profile/notifications/status`;学生只能查看和更新自己的通知,支持未读/已读/忽略/归档、类型筛选和状态汇总 |
## 背单词、知识手册、分数线、视频
| 能力 | 状态 | 后端接口/模型 |
| --- | --- | --- |
| 单词单元/单词列表 | 可联调 | `/api/catalog/vocabulary-units``vocabulary-words` |
| 单词进度/收藏/统计 | 可联调 | `/api/learning/vocabulary/*` |
| 单词复习算法/每日计划 | 可联调 | `GET /api/learning/vocabulary/review-plan``POST /api/learning/vocabulary/review`;后端计算 `nextReviewDate`、连续正确、掌握状态和待复习计划 |
| 知识手册目录/内容 | 可联调 | `/api/catalog/handbook-*` |
| 知识手册 JSON 导入 | 可联调 | `/api/tenant-content/imports/*/handbook` |
| 分数线字段/院校/专业/记录/趋势 | 可联调 | `/api/scoreline/*``records` 支持 `field.<key>``min.<key>``max.<key>` 动态字段筛选,只允许 `scoreline_fields.is_filter=true` 且字段名安全的字段参与查询 |
| 分数线 JSON 导入 | 可联调 | `/api/tenant-content/imports/preview/scoreline``/api/tenant-content/imports/scoreline`;支持字段、院校、专业、记录、动态字段值、逐行 issue、幂等和审计 |
| AI 择校推荐 | 可联调 | `ai_recommendation_reports` + `/api/ai/school-recommendations*`;默认要求当前学生有有效 SVIP后端读取学生目标地区和分数线上下文使用 `local_rules` 生成稳定 JSON 报告并写入报告台账和审计;已支持本人报告 Markdown/HTML 导出、hash、审计和跨用户拒绝真实 AI provider、人工 prompt 编排和 PDF worker 渲染待补 |
| 题目视频/批量预加载/搜索 | 可联调 | `/api/questions/*/videos``/api/videos/search`;付费视频列表不返回可播放 URL |
| 视频会员播放次数 | 可联调 | `POST /api/videos/play` 支持 SVIP/视频次数校验、签名播放、次数扣减、播放日志和动态水印上下文;`POST /api/videos/progress` 支持播放开始、心跳、完成上报租户后台媒体报表已可按视频、用户、traceId 查询播放事件、观看秒数和完成率;深度防盗链和转码级水印继续补 |
| 视频 JSON 导入和批量绑定 | 可联调 | `/api/tenant-content/imports/preview/videos``/api/tenant-content/imports/videos`;支持视频元数据、资源引用、播放模式、题目绑定和题目视频标记 |
## 资料与对象存储
| 能力 | 状态 | 说明 |
| --- | --- | --- |
| 内容资源台账 | 可联调 | `content_assets` |
| 租户后台资源维护 | 可联调 | `/api/tenant-content/assets` |
| 学生端资源列表/下载签名 | 可联调 | `/api/catalog/assets``/api/catalog/assets/download`;学生端锁定资源使用短 TTL访问事件写入 `content_asset_access_events` |
| 阿里云 OSS 签名 | 可联调 | `aliyun_oss` provider |
| 腾讯 COS 签名 | 可联调 | `tencent_cos` provider |
| Supabase Storage 签名 | 可联调 | `supabase_storage` provider |
| 上传后对象校验 | 可联调 | `/api/tenant-content/assets/confirm-upload`;托管对象必须 verified 后才能发布/下载 |
| PDF/图片预览签名 | 可联调 | `/api/catalog/assets/preview``/api/tenant-content/assets/sign-preview`;使用 inline 短期签名,学生预览默认短 TTL |
| 托管资源 worker 复检 | 可联调 | `apps/worker --job assets` 定期复检 pending/verified 对象元数据;异常资源会标记 failed 并从 active 退回 draft写入审计和 `security_flags` |
| 内容资源安全扫描 | 可联调 | `content_assets.security_scan_status` + `content_asset_security_scan_events`;托管对象确认上传后进入 `pending/scanning`,内置 `metadata_rules` 和可选外部 HTTP scanner 通过后才可发布、下载、预览或视频播放;失败或外部 scanner 不可用默认 fail-closed会下架并写审计 |
| 资源访问审计 | 可联调 | `content_asset_access_events` + `GET /api/tenant-content/assets/access-events` + `/api/tenant-content/media-analytics/*`;记录上传签名/确认、学生下载/预览、后台下载/预览的 granted/denied、TTL、签名模式、IP、UA 和水印 traceId并支持租户后台汇总、Top 资源和 traceId 回查 |
| CDN 访问边界 | 可联调 | `members/svip/private` 外部 CDN URL 默认拒绝,必须显式 `metadata.providerManagedAccess=true``cdnAccessMode=signed_by_provider`;视频绑定资源也复用该规则 |
| 深度防盗链/水印/杀毒 | 部分覆盖 | 内置 metadata 规则扫描、外部 HTTP scanner 接入层、失败关闭、生产 readiness 阻断、签名访问动态水印上下文和 traceId 审计已完成;商用上线前继续联调真实 AV/内容安全服务、转码/CDN 级水印、CDN 刷新和对象生命周期策略 |
## 订单、会员、营销
| 能力 | 状态 | 说明 |
| --- | --- | --- |
| SVIP 套餐 | 可联调 | `/api/catalog/svip-plans` |
| 创建订单/订单列表/订单详情/状态轮询 | 可联调 | `/api/commerce/orders``orders/detail``orders/status`;订单金额、优惠券抵扣、零元订单都以后端计算为准 |
| 手工支付确认 | 迁移期 | `/api/commerce/payments/manual-confirm` 仅允许具备 `tenant:payment:write` 的租户后台成员调用,用于线下收款/本地测试 |
| 微信支付 JSAPI | 可联调 | `/api/commerce/payments/create``notify/wechat_pay`,已覆盖 API v3 签名、通知解密、幂等和权益开通 |
| 支付宝 WAP/H5 | 可联调 | `/api/commerce/payments/create``notify/alipay`,已覆盖 RSA2 通知验签、幂等和权益开通 |
| 权益查询/校验 | 可联调 | `/api/commerce/entitlements` |
| 激活码预检查/兑换 | 可联调 | `/api/commerce/activation-codes/check``redeem`;支持地区校验、自用码拒绝、已用码稳定 reasonCode |
| 优惠券后台配置 | 可联调 | `/api/tenant-admin/coupons`;支持状态启停/归档、活动分组、最低订单金额、优惠封顶、单用户限次、首单限制、适用套餐/地区和 metadata |
| 优惠券前台领取/下单抵扣 | 可联调 | `/api/commerce/coupons/claim`;支持同用户同券未核销幂等领取、多次核销限额、规则快照、下单后端复核、负数订单项、全额优惠自动开通权益 |
| 优惠券核销报表 | 可联调 | `/api/tenant-admin/coupons/redemptions``/api/tenant-admin/coupons/report`;支持按券、状态、活动分组、日期查询核销明细、领取数、使用数、抵扣金额、成交金额、转化率和按日趋势 |
| 退款状态机和供应商确认 | 可联调 | `/api/commerce/refunds``/api/commerce/refunds/status``/api/commerce/refunds/notify/{provider}`;支持退款申请、审核、调用微信/支付宝发起退款、`query_provider_refund` 查询确认、微信/支付宝退款通知、处理中、成功/失败/拒绝/取消、退款金额累计、部分退款、全额退款权益撤销、退款事件和审计 |
| 支付/退款补偿 worker | 可联调 | `apps/worker --job commerce` 查询微信/支付宝订单和处理中退款,补偿漏通知支付、补发权益、确认退款、全额退款撤销权益;`npm run test:worker:commerce` 覆盖幂等和密钥不泄露 |
| 资金流水对账 | 可联调 | `commerce_reconciliation_batches/items` + `/api/commerce/reconciliation/preview/import/batches/items/anomalies`;租户后台需 `tenant:reconciliation:read/write`,支持支付/退款账单行手工或 API 导入、来源 hash、批次统计、逐行匹配、金额/状态差异、本地缺失、供应商缺失、重复行、无效行和审计;对账只生成差异,不自动改订单/权益 |
| 对账差错工单 | 可联调 | `commerce_reconciliation_issues/events` + `/api/commerce/reconciliation/issues*`;异常明细可创建工单,支持分配、开始处理、升级、解决、忽略、重开、事件轨迹和审计;处理结论只作为财务审核记录,不直接修改订单、支付、退款或权益 |
| 官方账单下载 | 可联调 | `commerce_bill_download_jobs` + `/api/commerce/reconciliation/provider-bills/request/jobs` + `apps/worker --job provider-bills`;租户后台需 `tenant:reconciliation:download` 创建任务worker 后端使用租户商户密钥申请微信/支付宝官方账单下载 URL、校验 hash、解析 JSON/CSV/ZIP 账单并复用同一套 `provider_download` 对账导入响应只暴露任务状态、下载域名、hash 和对账批次 ID不暴露下载 URL 或密钥 |
| 异常订单运营台和财务报表 | 可联调 | `commerce_adjustment_vouchers/events` + `/api/commerce/operations/anomalies``/api/commerce/adjustment-vouchers*`;支持聚合未关闭对账工单、失败官方账单任务、支付事件错误、长时间 pending 支付/退款,支持人工调整凭证提交、审批、驳回、作废、事件轨迹和复核报表;需 `tenant:reconciliation:read/write/review`凭证只做审计证据不直接修改订单、支付、退款或权益Taro 租户财务运营台第一版已接入,真实生产账单格式抽样仍待继续验收 |
## 租户后台与平台后台
| 能力 | 状态 | 后端接口 |
| --- | --- | --- |
| 租户概览、品牌、主题、设置 | 可联调 | `/api/tenant-admin/overview``branding``theme-templates``theme``theme/preview``theme/publish``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/point-activity-tasks``point-activity-claims``point-exchange-items``point-exchange-orders``points-risk-report`;使用 `marketing:points:read/write` 或兼容 `marketing:read/write` 权限,积分风控支持 `marketing:points:risk:read` 且兼容 `marketing:points:read`;支持任务配置、兑换商品配置、领取记录、兑换订单、只读风控报表、审计和跨租户拒绝 |
| 勋章管理/发放 | 可联调 | `/api/tenant-admin/badges``/api/tenant-admin/badge-grants`;支持后台维护、同 `legacyId` 幂等更新、手动发放、重复发放幂等、租户隔离和权限点 `badges:read/write/grant``unlockType=check_in/score/feedback_resolved/activity_reward/practice_count/vocabulary_mastered/mock_exam_score` 会由签到、积分奖励、反馈解决、活动任务、练习交卷、单词掌握和模考成绩事件自动发放,并写入用户站内通知 |
| 考试日期维护 | 可联调 | `/api/tenant-admin/exam-dates`,支持地区维度维护和公开倒计时展示 |
| 题目反馈处理 | 可联调 | `/api/tenant-admin/feedbacks``feedbacks/report``feedbacks/status``feedbacks/events`;支持状态流转、处理备注、审计事件、幂等奖励积分、用户站内通知和只读运营聚合报表 |
| 激活码批次/生成/列表 | 可联调 | `/api/tenant-admin/code-batches``activation-codes` |
| 成员/角色权限/审计 | 可联调 | `/api/tenant-admin/members``permissions``role-templates``audit-logs` |
| 班级/学生/教师管理 | 可联调 | `/api/tenant-admin/classes``classes/members``students``teachers`,支持班级范围权限和审计 |
| 学生批量运营 | 可联调 | `/api/tenant-admin/students/bulk-upsert``students/status``classes/members/bulk-assign``students/notes``students/followups``students/followups/report``students/supervision/preview``students/supervision/generate``students/supervision/rules``students/crm-push`;支持逐行结果、限量、防跨租户和教师范围校验;跟进报表支持 7/30/90 天或自定义日期范围、状态/类型/优先级/负责人/班级聚合、逾期待办、CRM 推送队列摘要和每日趋势;学习督导由后端读取答题、错题、单词待复习和未完成练习数据,按阈值预览候选并幂等生成 `learning` 跟进任务,也可保存手动/每日/每周规则交给 worker 定时生成,要求 `students:supervision:read/write`;批量 CRM 推送会为学生生成跟进任务并写入异步 CRM 队列,要求 `crm:write``students:read``students:followups:write`;学生导入/upsert/分班禁止 `avatarUrl/avatar_url/avatar/headimgurl/figureurl``primaryRole/primary_role`,避免绕过预设头像与租户角色体系 |
| 用户站内通知查看 | 可联调 | `GET /api/tenant-admin/user-notifications`;需要 `notifications:read` 权限,支持按用户、状态、类型查询租户内通知和状态汇总,租户后台只读不直接代学生改状态 |
| 平台租户/详情/账务资料/员工/审计/告警/套餐/订阅/账单/用量 | 可联调 | `/api/platform-admin/*`;已支持当前平台账号权限目录、平台员工列表、平台员工创建/编辑、平台员工禁用/恢复、租户列表、创建租户、租户详情、状态变更、账务资料维护、平台审计日志查询、CSV/JSON 审计导出、平台审计告警规则查询、告警列表、确认/解决/忽略、审计告警外部通知渠道和发送事件、SaaS 套餐、订阅、账单、订阅账单候选预览、dry-run、批量生成、自动计费 worker、重复开票保护、用量超额账单候选预览/dry-run/生成/自动开票 worker、收款、逾期标记、内部催缴台账、催缴外部通知渠道和发送事件、用量台账和平台用量自动采集 worker平台 API 已拆分 `platform:staff:read/write/status``platform:tenant:read/write/status/billing_profile``platform:billing:read/write/payment/dunning/notification``platform:usage:read/write``platform:audit:read/export/alert/notification``platform:question_bank:read/grant/ops` 等权限点;审计导出、平台员工操作、告警响应和通知事件都会对 `details`/payload 中的 token/secret/password/key 等敏感字段递归脱敏;`apps/worker --job platform-usage` 会生成月度 SaaS 用量快照并保留手工调整记录;平台超额账单只使用后端权威用量快照和套餐/订阅 metadata前端不得自行计算服务费`apps/worker --job platform-usage-overage` 自动开票失败会写脱敏审计并进入 `platform-audit-alerts` 高优先级告警;`apps/worker --job platform-audit-alerts` 会把租户状态变更、账务资料变更、批量开票、超额开票、worker 失败、逾期处理、手工收款确认、审计导出等高风险平台审计动作生成内部告警;`apps/worker --job platform-audit-notifications` 会按 `platform_audit_notification_channels` 把开放告警推送到 generic/钉钉/飞书/企微 webhook签名密钥放 `app_private.platform_secrets` 且 API 不回显原文;`apps/worker --job platform-dunning-notifications` 会按 `platform_dunning_notification_channels` 把内部催缴记录推送到 generic/钉钉/飞书/企微 webhook发送成功会推进提醒状态失败会退避重试联系方式和请求 payload 会脱敏;创建租户、平台员工变更、状态变更、账务资料维护、订阅批量开票、自动开票、用量采集、用量超额开票、超额开票失败、逾期催缴、手工收款确认、审计导出、告警状态更新、通知渠道变更和催缴通知渠道变更会写入审计 |
| 数据看板聚合接口 | 可联调 | `GET /api/tenant-admin/dashboard`;支持 `7d/30d/90d`、地区筛选、学生/学习/内容/订单/激活码/反馈卡片、趋势、24h 活跃、题型分布、科目排行、地区统计、套餐销量和运营动态 |
| 平台公共题库授权 | 可联调 | `/api/platform-admin/question-banks``question-bank-grants`;支持按 SaaS 套餐、指定租户或全部活跃租户披露平台公共题库,并可限制授权地区和科目。平台保存 grant 时会校验 `allowedRegionIds``allowedSubjectIds` 属于源平台题库租户,且已发布题目的科目必须被授权科目覆盖 |
| 租户采纳/同步公共题库 | 可联调 | `/api/tenant-content/public-question-banks``public-question-banks/adopt``public-question-banks/sync``public-question-banks/conflicts``public-question-banks/conflicts/resolve``public-question-banks/conflicts/resolve-batch``tenant-content/notifications``/api/platform-admin/question-bank-sync-status`;租户只能看到自己 `question_bank_grants`、有效 `tenant_subscriptions``platform_saas_plans.feature_flags.publicQuestionBanks` 和订阅 `metadata.publicQuestionBankAccess` 同时允许的题库。基础版默认 `limited_regions` 且需要地区 allowlist专业版默认 `national`;采纳、同步和冲突处理都会重新校验当前授权,越权 grant 返回 `QUESTION_BANK_GRANT_NOT_AVAILABLE`。采纳后生成租户自己的题库、入口、集合和题目快照,可直接进入练习;平台更新后可手动或由 worker 自动同步,新增/更新、冲突和 worker 失败会生成租户内容通知;租户自改题目会标记冲突并跳过;后台可查询最近一次冲突明细,并可单条或批量选择“采纳平台版本”/“保留本地版本”,操作会写入逐条审计,冲突全部处理后相关通知自动 resolved失败通知会在后续同步恢复成功后自动 resolved平台运营接口需 `platform:question_bank:ops`,只返回跨租户同步摘要和通知数量,不返回题目正文/答案/解析 |
| 题库导出 | 可联调 | `/api/tenant-content/exports/questions``/api/tenant-content/exports/jobs`;支持按题目集合、内容入口或分类节点导出 JSON/试卷 payload也支持 `pdf/docx/daily_practice_zip` 异步导出;`exportType=daily_practice` 可生成每日一练九宫格运营素材 metadata、PDF/Word 基础版式和 ZIP 图片素材包;后端校验租户内容编辑权限、跨租户隔离、答案/解析开关、复合题子题脱敏、导出 job 和审计;`apps/worker --job exports` 负责 PDF/Word/ZIP 渲染、生成 `content_assets`、记录 hash/size/assetId前端通过资源签名接口下载/预览 |
## 销售、代理、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``/api/crm/dead-letters``/api/crm/queue/logs``/api/crm/queue/action`CRM 配置支持 `none/direct/round_robin/referrer` 客资跟进分配策略、租户内候选成员校验、轮询游标、分配审计,客资首绑成功后会写入 `assignedToUserId` 并进入队列 payload失败/丢弃任务可进入死信运营池,租户管理员可查看脱敏日志、手动重试或忽略,动作写入日志和审计 |
| CRM webhook worker | 可联调 | `apps/worker` 已支持 generic webhook、钉钉、飞书、企微群机器人消息体/签名、`lead.created` 客资首绑事件和 `student.crm_push` 学生运营跟进事件、到期任务消费、失败退避重试、最终失败、discarded 和 `crm_webhook_log` |
| CRM 增强 | 待补齐 | 富卡片模板、外部失败告警升级和更细销售转化看板 |
| 分佣结算基础闭环 | 可联调 | `/api/commission/settings``member-rate``summary``orders``settlements``settlements/generate``settlements/status``settlements/export``settlements/proofs`;支持订单/激活码归因、批次/成员/默认比例优先级、北京时间账期、结算单生成、审核、打款状态、已打款锁定、CSV/JSON 导出、打款凭证登记/复核、销售/代理本人范围和租户隔离 |
| 分佣打款增强 | 待补齐 | 银行/微信/支付宝真实打款 provider、发票管理、批量凭证上传、异常调整单和分佣看板 |
## 内容导入与迁移
| 能力 | 状态 | 说明 |
| --- | --- | --- |
| PocketBase schema/导出分析 | 可联调 | `scripts/import-pocketbase` 支持 schema summary/risk、`npm run pb:import:dry-run` 导出目录静态迁移报告 |
| PocketBase JSON dry-run | 可联调 | 不写数据库检查导出目录、JSON 形态、核心集合、旧 ID、敏感字段、schema relation、未映射集合和关键业务计数`--profile=production` 会额外检查生产迁移必需集合和关键字段覆盖率,正式切换建议配合 `--fail-on-warnings` |
| PocketBase SQLite 标准化导入 | 可联调 | 已支持真实 SQLite 只读导出后的核心集合标准化,新增覆盖 `user_answer_records -> answer_records/wrong_questions``mock_exam_configs -> practice_blueprints``referral_qrcodes -> referral_qrcodes/referral_codes``commission_settings -> tenant_commission_settings`;干净本地 Supabase 全量真实导入 248555 条记录最近约 10 分 11 秒,`pb:import:validate` 为 0 failures、3 warnings已补 `npm run pb:import:sample` 只读业务抽样,当前真实迁移库为 0 failures、6 warnings、1 skipped、39 passed覆盖题库入口、内容节点、题目合集、练习蓝图、题目版本、学习记录、单词、手册、分数线、订单、支付、权益、激活码、资源和敏感字段泄露导入后会生成 11 个题库入口、2830 个内容节点、1597 个题目合集、82106 条合集题目关系和 3102 个顺序/随机练习蓝图,并回填全部已发布旧题的 `entry_id/content_node_id/primary_collection_id`;缺用户订单会进入财务复核且不自动开权益,缺归属手册章节会进入“迁移待复核手册”并写 `pb_import_issues`;正式切换前仍需人工处理 7 个已支付缺用户订单和 22 个待复核手册章节 |
| 题目 JSON preview/import | 可联调 | 后端负责规范化、issue、幂等、审计 |
| 公共题库采纳、手动同步和自动同步 | 可联调 | 平台授权后,租户可采纳公共题库并复制已发布题目快照;同步 API 和 `public-banks` worker 支持新增/更新题目、重新校验授权、跨租户拒绝、审计记录、租户内容通知和租户自改冲突保护;冲突处理 API 已支持单条/批量采纳平台版本和保留租户本地版本worker 失败会写 `public_question_bank_sync_failed` 租户通知并保留稳定错误码,恢复成功会自动关闭失败通知;平台可通过 `/api/platform-admin/question-bank-sync-status` 查看跨租户同步运营状态;已覆盖跨租户、重复采纳、采纳后组卷、同步新增题、通知隔离/已读/自动 resolved、冲突不覆盖、单条/批量冲突处理、worker 自动同步/失败通知/恢复关闭、starter 单地区不可见/不可采纳第二地区题库、pro 全国套餐可见第二地区题库等测试 |
| 单词 JSON preview/import | 可联调 | 兼容旧模板 |
| 知识手册 JSON preview/import | 可联调 | 支持书籍/章节/小节/知识点归一化 |
| 分数线 JSON preview/import | 可联调 | 支持 `fields/schools/majors/records` 分桶或 `items` 列表,后端校验租户地区和院校/专业引用 |
| 视频 JSON preview/import | 可联调 | 支持 `videos/items`,后端校验题目、科目、资源引用,导入后写入 `question_videos` |
| Excel/CSV 导入 | 可联调 | 题目、单词、知识手册、分数线、视频已支持 CSV 和 `.xlsx` 解析,解析后复用 `content_import_jobs/items/issues` 管线并保留 `parser_metadata`;模板下载、字段映射 API、字段映射覆盖白名单、导入任务详情、异步 worker 状态、导入后复检已接入Taro 租户内容页已接上传/粘贴 preview/import、字段别名编辑、异步任务轮询和复检详情第一版 |
| 大批量异步导入 | 可联调 | `executionMode=async` 会将 preview job 置为 `pending``apps/worker --job imports` 抢占 queued job复用 API 导入 executor支持重试、清锁和审计 |
| 题库导出任务 | 可联调 | `content_export_jobs` 记录导出范围、格式、题量、输出 hash、选项、执行人、异步状态、重试次数和 `asset_id`JSON 类导出返回 inline base64`pdf/docx/daily_practice_zip` 由 exports worker 渲染为资源台账文件 |
| 公共题库自动同步增强 | 部分覆盖 | `apps/worker --job public-banks` 已可抢占待同步采纳记录、自动同步平台新增/更新题目、记录失败和审计;同步新增/更新、冲突和 worker 失败会写入 `tenant_content_notifications`,租户后台已有通知列表、已读/忽略、失败查看、单条和批量冲突处理第一版;平台侧已有 `/api/platform-admin/question-bank-sync-status` 运营摘要接口。后续需接入生产定时调度、外部告警升级和更完整运营消息 |
## 当前验证
最近需通过:
```bash
npx supabase db reset
npm run audit:runtime
npm run security:repo
npm run check:refactor
npm run check:taro
npm run build:taro:h5:student
npm run build:taro:h5:tenant
npm run build:taro:h5:platform
npm run test:readiness
npm run test:pb:dry-run
npm run test:worker:imports
npm run test:worker:crm
npm run test:worker:commerce
npm run test:worker:platform-billing
npm run test:worker:platform-dunning
npm run test:worker:platform-dunning-notifications
npm run test:worker:platform-audit-alerts
npm run test:worker:platform-audit-notifications
npm run test:worker:assets
npm run test:worker:exports
npm run test:worker:public-banks
npm run test:worker:student-supervision
npm run smoke:launch-persona
npm run perf:api:local
git diff --check
```
当前产品边界:学生头像只支持男女预设,不做上传、裁剪或第三方头像同步;排行榜后端具备可选能力,但默认关闭,学生端默认不请求,只有租户显式购买/开启活动并完成专项压测后再补日/周榜预聚合和防刷。
`check:refactor` 包含:
- API TypeScript 检查
- importer TypeScript 检查
- PocketBase 导入校验
- smoke seed
- API build
- API integration tests
真实迁移专项最近已通过:
```bash
npx supabase db reset
$env:DATABASE_URL='postgresql://postgres:postgres@127.0.0.1:54322/postgres'
npm run pb:import:json
npm run pb:import:validate
npm run pb:import:sample
npm run check:importer
```
结果:`pb:import:json` 用时约 10 分 11 秒,`pb:import:validate` 为 0 failures、3 warnings`pb:import:sample` 为 0 failures、6 warnings、1 skipped、39 passed。新题库导航计数11 个 `content_entries`、2830 个 `content_nodes`、1597 个 `question_collections`、82106 条 `question_collection_items`、3102 个 `practice_blueprints`,已发布旧题缺入口/节点/合集数为 0。`npm run pb:import:dry-run -- --profile=production --json` 仍按预期返回非 0因为真实旧数据还有 30 个订单缺 `userId` 和 22 个手册章节缺 `subjectId` 两个上线前 blocker。