# 后端重构进度

## 已完成

- 更新时间：2026-06-30。
- 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 套餐、订阅、订阅账单候选预览/dry-run/批量生成、自动计费 worker、服务费收款、逾期标记、内部催缴台账、使用量、用量超额账单和自动开票 worker。
  - `tenant-admin`：租户资料、品牌、公开设置、域名、支付账户、登录 provider、私密密钥掩码、活动内容、考试日期、题目反馈处理和运营报表、用户站内通知查看、激活码批次、优惠券规则和核销报表、勋章管理/发放、成员管理、角色模板、班级/学生/教师范围权限、权限矩阵、审计查询。
  - `tenant-content`：租户后台内容入口、任意深度分类树、考试意向标记、题目集合、练习蓝图、题目、视频、分数线、单词、知识手册、资料资源、题目/单词/知识手册/分数线/视频 JSON 导入维护。
  - `tenant`：域名/租户解析。
- 鉴权上下文已支持 Supabase Auth JWT 和迁移期 `tk_` session 双入口，JWT 通过 `auth.users.id -> platform_users.auth_user_id -> tenant_memberships` 映射业务用户和租户；平台管理员 JWT 已可访问平台后台。
- 平台后台租户运营第一版已补齐：`GET /api/platform-admin/tenants/detail` 返回租户、域名、订阅、账单、用量和账务资料；`PUT /api/platform-admin/tenants/billing-profile` 维护开票/联系/银行掩码资料；`GET /api/platform-admin/audit-logs` 支持按租户、动作、目标、操作者、日期和关键词查询平台审计；`GET /api/platform-admin/audit-logs/export` 支持平台管理员导出 CSV/JSON，返回 base64 内容、sha256、行数和筛选条件，并对 `details` 中的 token/secret/password/key 等敏感字段递归脱敏，同时写入 `platform.audit.exported` 审计；`GET /api/platform-admin/audit-alert-rules`、`GET /api/platform-admin/audit-alerts` 和 `POST /api/platform-admin/audit-alerts/status` 支持平台内部审计告警规则查询、开放告警查询、确认/解决/忽略，API 返回告警 details 时递归脱敏敏感字段；`apps/worker --job platform-audit-alerts` 会把租户状态变更、账务资料变更、批量开票、用量超额开票、worker 失败、逾期处理、手工收款确认、审计导出等高风险平台审计动作生成内部告警；`GET/PUT /api/platform-admin/audit-notification-channels` 和 `GET /api/platform-admin/audit-notification-events` 已支持平台审计告警外部通知渠道配置和发送事件查询，`apps/worker --job platform-audit-notifications` 可按渠道把开放告警推送到 generic/钉钉/飞书/企微 webhook，签名密钥进入 `app_private.platform_secrets`，API 只回显 `secretRef` 和 webhook host/path；`GET /api/platform-admin/invoices/subscription-candidates` 和 `POST /api/platform-admin/invoices/from-subscriptions-batch` 支持订阅账单候选预览、dry-run、批量生成、重复开票跳过和平台审计；`GET /api/platform-admin/invoices/usage-overage-candidates` 和 `POST /api/platform-admin/invoices/from-usage-overage` 支持用量超额候选预览、dry-run、正式生成 `usage_overage` 账单、重复开票保护和平台审计；`apps/worker --job platform-usage-overage` 可按上一个自然月或指定 `WORKER_PLATFORM_USAGE_OVERAGE_MONTH=YYYY-MM` 自动生成超额服务费账单，复用同一套后端计算服务，非法账期或执行失败会写 `platform.invoice.usage_overage_worker_failed` 脱敏审计并进入审计告警链路；`apps/worker --job platform-billing` 可自动为即将到期且未开票订阅生成服务费账单；`POST /api/platform-admin/invoices/process-overdue`、`GET /api/platform-admin/invoices/reminders` 和 `apps/worker --job platform-dunning` 可处理已逾期未结清服务费账单，写入内部催缴台账和审计；`GET/PUT /api/platform-admin/dunning-notification-channels`、`GET /api/platform-admin/dunning-notification-events` 和 `apps/worker --job platform-dunning-notifications` 已支持平台催缴外部通知渠道配置、发送事件查询、重试和幂等发送。创建租户、状态变更、账务资料维护、订阅批量开票、自动计费、用量超额开票、超额开票失败、逾期催缴、手工收款确认、审计导出、审计告警状态更新、审计告警通知渠道变更和催缴通知渠道变更会写入审计日志，API/worker 集成测试已覆盖平台管理员可操作、学生越权拒绝、重复保护、非法输入拒绝、敏感字段脱敏和审计记录存在。
- 租户自定义角色模板已落库：`tenant_role_templates` 支持权限、菜单、模块、字段和数据范围配置，成员可通过 `role_template_id` 绑定模板。
- 班级与学生范围权限已落库：`tenant_classes`、`tenant_class_members` 支持教师/班主任/助教/学生分组，教师按负责班级查看学生，字段权限可脱敏学生手机号。
- 学生运营管理已落库：`tenant_student_notes`、`tenant_student_followups`、`tenant_student_supervision_rules` 支持学生备注、家校/班主任/销售跟进任务、可见性、指派、完成状态、督导规则模板和审计；批量学生 upsert、批量分班、禁用/恢复、学生批量 CRM 推送、跟进效果统计和学习督导自动化已接入权限校验、范围校验和集成测试。`GET /api/tenant-admin/students/followups/report` 支持 7/30/90 天或自定义日期范围、负责人/类型/班级筛选、状态/类型/优先级/负责人/班级聚合、每日趋势、逾期待办和 CRM 队列摘要，并会沿用教师班级范围与字段脱敏规则。`GET /api/tenant-admin/students/supervision/preview` 和 `POST /api/tenant-admin/students/supervision/generate` 支持按未学习、错题积压、低正确率、单词待复习和超期未完成练习生成风险候选，并用 `metadata.autoSupervision.idempotencyKey` 幂等生成 `learning` 跟进任务；`GET/PUT /api/tenant-admin/students/supervision/rules` 支持租户保存手动/每日/每周督导策略，`apps/worker --job student-supervision` 会按启用规则定时生成跟进任务并写回 `last_result/next_run_at`。
- 旧题库常用运营功能已补齐一批：`exam_dates` 支持学生端考试倒计时和租户后台维护；`reports/report_status_events` 支持学生题目反馈、租户后台状态流转和 7/30/90 天只读反馈运营报表；`user_score_events` 支持每日签到积分流水、租户配置化连续签到奖励和反馈奖励幂等；`badges/user_badges` 支持租户后台勋章维护、手动发放、重复发放幂等和学生个人中心展示；`user_notifications` 支持反馈处理、反馈奖励、勋章发放和积分兑换的学生站内通知；Taro 学生个人中心已接积分任务/兑换/积分明细和消息中心第一版，租户营销中心已接反馈运营摘要、积分任务/每日签到奖励/兑换操作台和用户通知查看第一版。
- 旧题库排行榜主链路已补齐但租户默认关闭：`GET /api/learning/leaderboard` 只有在 `feature_flags.enableLeaderboard=true` 时可用，支持刷题、积分、背单词、模考四类指标，支持全量/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、队列状态、日志和密钥不泄露；worker 已支持 `lead.created` 客资首绑事件和 `student.crm_push` 学生运营跟进事件，失败/丢弃任务会进入死信运营池。
- 已新增 commerce worker 和 `npm run test:worker:commerce`，用于补偿查询微信/支付宝支付、处理中退款和漏通知场景；支付成功会幂等更新订单/支付并开通权益，退款成功会幂等更新退款/订单/支付并在全额退款时撤销订单权益，测试覆盖密钥不泄露和重复执行不重复开通。
- 已新增 platform-billing worker 和 `npm run test:worker:platform-billing`，用于自动处理即将到期且未开票的 SaaS 订阅；worker 使用订阅行锁和账单查重保证幂等，自动生成 `tenant_invoices/tenant_invoice_items` 并写 `platform.invoice.subscription_auto_created` 审计。
- 已新增 platform-dunning worker 和 `npm run test:worker:platform-dunning`，用于扫描已过 `due_date` 且未结清的 SaaS 服务费账单；worker 使用账单行锁和每日唯一催缴约束保证幂等，自动标记 `overdue`、推送租户 `billing_status=past_due`、生成 `tenant_invoice_reminders` 内部催缴记录并写 `platform.invoice.overdue_processed` 审计。
- 已新增 platform-dunning-notifications worker 和 `npm run test:worker:platform-dunning-notifications`，用于把内部催缴记录按平台渠道推送到 generic/钉钉/飞书/企微 webhook；worker 先入队 `platform_dunning_notification_events`，再发送并记录重试、HTTP 状态、脱敏后的请求 payload，避免泄露 webhook 签名密钥、租户联系方式原文和催缴 metadata 中的敏感字段。
- 已新增 platform-audit-alerts worker 和 `npm run test:worker:platform-audit-alerts`，用于扫描高风险平台审计动作并生成内部告警；worker 匹配启用规则、对告警 details 递归脱敏、通过 `(rule_id, audit_log_id)` 保证幂等，并写 `platform.audit.alert_created` 审计。
- 已新增 platform-audit-notifications worker 和 `npm run test:worker:platform-audit-notifications`，用于把开放平台审计告警按平台配置渠道推送到 generic/钉钉/飞书/企微 webhook；worker 先入队 `platform_audit_notification_events`，再发送并记录重试、HTTP 状态、脱敏后的请求 payload，避免泄露 webhook 签名密钥和告警敏感 details。
- 已新增 assets worker 和 `npm run test:worker:assets`，用于复检 `content_assets` 托管对象元数据；正常资源会写入复检证据，异常资源会自动下架为 `draft`、标记 `upload_status=failed`，并记录审计与安全标记。
- 已新增分数线/视频 JSON 导入接口和集成测试：分数线支持字段、院校、专业、记录、动态字段值；视频支持视频元数据、资源引用、访问模式和题目绑定，全部复用 `content_import_jobs/items/issues` 管线。
- 已新增 CSV/Excel 导入解析层：题目、单词、知识手册、分数线和视频都可通过 `sourceFormat=csv/excel` 先解析为规范 payload，再进入同一套 preview/import、逐行 issue、幂等和审计管线；分数线支持多 Sheet Excel。
- 已新增 imports worker 和 `npm run test:worker:imports`：确认导入时可传 `executionMode=async`，API 将 preview job 排队为 `pending`，worker 复用同一导入 executor 消费任务，支持抢占锁、attempt/backoff、失败重试、清锁和审计。
- 已新增 student-supervision worker 和 `npm run test:worker:student-supervision`：租户可保存学习督导规则模板，worker 使用规则行锁和 stale claim 保护抢占到期规则，复用 API 候选计算和跟进生成逻辑，按 `worker:<ruleId>:<上海日期>` 幂等生成 `learning` 跟进任务，并写入成功/失败审计。

## 已验证接口

```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
GET  /api/platform-admin/audit-logs
GET  /api/platform-admin/audit-logs/export
GET  /api/platform-admin/audit-alert-rules
GET  /api/platform-admin/audit-alerts
POST /api/platform-admin/audit-alerts/status
GET  /api/platform-admin/audit-notification-channels
PUT  /api/platform-admin/audit-notification-channels
GET  /api/platform-admin/audit-notification-events
GET  /api/platform-admin/dunning-notification-channels
PUT  /api/platform-admin/dunning-notification-channels
GET  /api/platform-admin/dunning-notification-events
POST /api/platform-admin/subscriptions
GET  /api/platform-admin/invoices
POST /api/platform-admin/invoices
GET  /api/platform-admin/invoices/subscription-candidates
POST /api/platform-admin/invoices/from-subscription
POST /api/platform-admin/invoices/from-subscriptions-batch
GET  /api/platform-admin/invoices/usage-overage-candidates
POST /api/platform-admin/invoices/from-usage-overage
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/badges
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
POST /api/tenant-content/imports/preview/scoreline
POST /api/tenant-content/imports/scoreline
POST /api/tenant-content/imports/preview/videos
POST /api/tenant-content/imports/videos
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/reconciliation/preview
POST /api/commerce/reconciliation/import
GET  /api/commerce/reconciliation/batches
GET  /api/commerce/reconciliation/items
GET  /api/commerce/reconciliation/anomalies
POST /api/commerce/reconciliation/issues/create
GET  /api/commerce/reconciliation/issues
POST /api/commerce/reconciliation/issues/status
GET  /api/commerce/reconciliation/issues/events
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/crm/dead-letters
GET  /api/crm/queue/logs
POST /api/crm/queue/action
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/students/followups/report
GET  /api/tenant-admin/students/supervision/preview
POST /api/tenant-admin/students/supervision/generate
POST /api/tenant-admin/students/crm-push
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/badges
PUT  /api/tenant-admin/badges
GET  /api/tenant-admin/badge-grants
POST /api/tenant-admin/badge-grants
GET  /api/tenant-admin/exam-dates
PUT  /api/tenant-admin/exam-dates
GET  /api/tenant-admin/feedbacks
GET  /api/tenant-admin/feedbacks/report
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/coupons/redemptions
GET  /api/tenant-admin/coupons/report
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` 权益开通逻辑。
- 优惠券领取对同用户同券未核销记录幂等；若 `per_user_limit > 1`，前一次 redemption 核销后可继续领取直到达到限额。优惠券状态、活动分组、最低金额、优惠封顶、首单限制、适用套餐/地区和单用户次数都由后端在领取和下单时复核；下单后 redemption 会绑定订单并进入 `used`，订单明细会写入负数 `coupon_discount` 项和规则快照。
- `/api/commerce/payments/manual-confirm` 是线下收款/迁移期能力，只允许租户后台具备 `tenant:payment:write` 的成员调用，普通学生不能伪造手工支付成功。
- `/api/commerce/refunds`、`/api/commerce/refunds/status` 和 `/api/commerce/refunds/notify/{provider}` 已提供内部退款状态机；退款权限拆分为 `tenant:refund:read/write/review`，可调用微信/支付宝发起退款，通过 `query_provider_refund` 主动查询确认供应商退款结果，也可接收微信/支付宝退款通知 webhook，全额退款成功会撤销订单来源权益；`apps/worker --job commerce` 会定时补偿查询支付和退款状态；`/api/commerce/reconciliation/*` 已支持租户资金对账导入、预览、批次/明细/异常查询、差错工单状态流、事件轨迹和审计。
- 租户支付账户、短信、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；上传确认、访问审计、动态水印上下文、租户后台媒体运营报表、assets worker 对象元数据校验/复检、内置 `metadata_rules` 安全扫描和外部 HTTP scanner 接入层已完成。PDF 深度预览体验、防盗链、转码/CDN 级水印和真实 AV/内容安全服务联调仍需继续补。
- 题库内容导航当前以 `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/CSV/Excel 预览、逐行 issue、job/item 台账、同步执行或 `executionMode=async` 异步执行、幂等跳过，并可落到新内容入口、分类节点、分数线表或题目视频绑定。旧单词模板的 `vocabulary_units_示例数据` / `vocabulary_示例数据`、知识手册的书籍/章节/小节/知识点嵌套结构都由后端规范化。导入后复检、模板下载和字段映射 API 已补齐，前端 UI 待接。

## 下一步

1. 完善内容导入和文件上传：字段映射 UI、真实数据 dry-run、PDF 预览渲染、防盗链、真实 AV/内容安全服务联调和转码/CDN 级视频水印。
2. 完成真实短信 provider 联调：阿里云/腾讯云，密钥放 `app_private.tenant_secrets` 或生产 Vault。
3. 完成真实 OAuth provider 联调：微信网页、微信小程序、QQ，确认回调域名、开放平台账号和旧 PocketBase 身份映射策略。
4. 补真实生产账单格式验收、前端财务操作台和营销活动 UI；支付/退款补偿、退款查询确认、退款通知、微信/支付宝官方账单下载、资金对账导入比对、差错工单、异常订单运营台和优惠券核销报表主链路已完成。
5. 扩展 `apps/worker`：日报统计、CRM 外部失败告警升级、学习督导触达联动、公共题库同步失败告警和更完整冲突处理运营台；CRM 死信运营、公共题库同步 worker、学习督导规则 worker 和同步通知已具备基础闭环。
6. 继续 Taro H5/小程序兼容验证，重点看公式、题图资源字段化、支付容器和分享链路。

## 测试命令

```text
npm run test:api
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:imports
npm run test:worker:public-banks
npm run test:worker:student-supervision
npm run check:refactor
```
