# tiku-supabase 这是题库项目从 PocketBase/SQLite 重构到 Supabase/PostgreSQL 的新后端仓库。 当前仓库重点承载“商用 SaaS 版本”的新架构代码,包括多租户数据库、业务 API、PocketBase 数据导入器、本地验证脚本和重构进度文档。旧 PocketBase/React 项目仍保留在原工作区作为功能参照和迁移来源,但这个 Git 仓库不打算作为旧项目全量镜像。 ## 当前状态 更新时间:2026-06-29 目前已经完成并在本地验证通过的内容: - Supabase/PostgreSQL 多租户数据库 schema、RLS、索引、触发器。 - `apps/api` 独立业务 API,后续供 H5、Taro 小程序、管理后台统一调用;已支持 Supabase Auth JWT 和迁移期 `tk_` session 双入口。 - 租户后台能力:品牌、主题模板/草稿/发布、域名、公开设置、支付账户、登录配置、私密密钥掩码、活动内容、考试日期、题目反馈处理、激活码、优惠券、勋章管理/发放、成员权限、自定义角色模板、班级/教师/学生范围权限、学生批量导入、批量分班、学生备注、跟进任务、审计日志。 - 租户内容能力:可配置题库入口、任意深度分类树、考试意向标记、题目集合、顺序/随机/全真模拟蓝图、题目录入/更新、视频绑定、分数线、单词、知识手册、资料资源台账、题目/单词/知识手册/分数线/视频 JSON/CSV/Excel 批量导入。 - 学生端能力:题库入口、分类树、题目集合、顺序/随机/模考 session 组卷快照、答题、错题本、收藏夹、背单词进度、个人中心、勋章、考试倒计时、签到积分、题目反馈、排行榜、分数线、题目视频、订单详情/状态轮询、优惠券领取/抵扣、权益、激活码预检查/兑换、资料下载。 - 平台后台能力:租户管理、SaaS 套餐、订阅、账单、服务费收款、用量记录、公共题库授权。 - 公共题库商业化能力:租户可采纳平台授权题库为本租户副本,并可手动或由 worker 自动同步平台新增/更新题目;同步会保护租户自改题目,返回冲突而不覆盖,后台可查询冲突明细。 - 题库导出能力:租户内容编辑可按题目集合、内容入口或分类节点导出 JSON、`paper_json`、打印 payload、PDF、Word 和每日一练图片 ZIP 素材包,后端强制租户隔离、答案/解析开关、复合题子题脱敏、导出 job 和审计;PDF/Word/ZIP 由 exports worker 生成水印文件或运营素材并发布到 `content_assets`;`daily_practice` 支持每日一练九宫格 metadata、PDF/Word 版式、9 张 PNG/SVG 卡片和拼图包。 - 销售/代理/CRM 增长链路:邀请码、扫码/分享事件、首绑客资保护、销售统计、团队关系、CRM 配置和队列。 - `apps/worker` 后台任务进程:CRM webhook 队列消费、generic/钉钉/飞书/企微机器人发送、签名、失败重试和日志;commerce worker 可补偿查询微信/支付宝支付和退款状态;assets worker 可复检托管资源元数据并自动下架异常资源;imports worker 可执行大批量导入;public-banks worker 可自动同步公共题库采纳副本;exports worker 可渲染 PDF/Word 导出文件和每日一练 ZIP 图片素材包。 - 销售/代理分佣结算基础闭环:租户默认比例、成员比例、激活码批次比例、订单/激活码归因、结算单生成、审核、线下打款状态和权限隔离。 - 订单售后基础闭环:退款请求、审核、处理状态流、微信/支付宝发起退款、微信/支付宝退款查询确认、微信/支付宝退款通知 webhook、退款金额累计、部分/全额退款订单状态、全额退款权益撤销、退款事件和审计日志。 - PocketBase schema/数据导入器雏形和导入后校验脚本。 - 本地 Supabase reset、烟测 seed、API 集成测试、完整重构检查命令。 还没有达到生产交付的部分: - Supabase Auth/JWT、租户角色模板、班级/教师/学生范围权限已可联调;生产前还要做真实云端 Auth/JWKS 回归和 RLS 深测。 - 阿里云/腾讯云短信、微信小程序登录、微信网页登录、QQ 登录、手机号绑定/换绑、微信支付、支付宝主链路、微信/支付宝发起退款/查询确认/退款通知、支付/退款补偿 worker 已完成本地适配;完整资金流水对账和真实生产账号联调还没接完。 - OSS/COS/Supabase Storage 上传下载签名 provider 已接入;上传后校验、PDF/图片预览、资源访问事件、锁定资源 CDN 边界和资源复检 worker 已完成,杀毒扫描、视频动态水印、CDN 刷新和对象生命周期策略还没完成。 - Excel/CSV 导入解析已完成并复用 `content_import_jobs/items/issues` 管线;大批量异步导入 worker 基础已接入,支持 queued job 消费、重试和审计;导入后复检、模板下载和字段映射 API 已完成,前端 UI 待接。 - 题库导出已完成服务端结构化 payload、PDF/Word 二进制 worker、每日一练基础导出和每日一练 ZIP 图片素材包;后续还要补更精细试卷模板、多模板排版和导出操作台体验。 - 勋章管理/手动发放已可联调;自动发放规则、积分活动联动、分佣真实打款、结算导出、发票/凭证、CRM 轮询/定向分配、富卡片模板、失败告警、销售转化看板、公共题库版本通知和冲突处理操作台还没完成。 - `apps/taro` 已建立 Taro 4 React 跨端前端地基,包含 H5 学生端、租户后台、平台后台三套构建入口、租户解析、统一 API client 和 Supabase Auth client 初始化;学生端第一批页面已接入登录、首页、题库、练习、背单词、知识手册、分数线、资料和个人中心;租户后台第一批页面已接入工作台、数据看板、学生/班级、题库内容、营销中心和租户设置,设置页已接主题模板、草稿预览/发布、角色模板和成员绑定第一版;平台后台已接入工作台、租户管理、账务中心、公共题库授权,以及创建租户、状态变更、订阅、账单、收款、用量和题库授权第一版写操作。 - 根目录已清理为新 Supabase SaaS monorepo 编排层;旧 PocketBase/React 项目和旧构建产物仅保留在 `参考/` 目录作为迁移参考,不进入 Git 提交。 更完整的进度看这些文档: - `docs/refactor/implementation-status.md` - `docs/refactor/backend-progress.md` - `docs/refactor/backend-handoff-roadmap.md` - `docs/refactor/ai-development-guardrails.md` - `docs/refactor/content-import-contract.md` - `docs/refactor/object-storage.md` - `docs/refactor/project-structure.md` - `docs/refactor/frontend-handoff-index.md` - `docs/refactor/backend-capability-status.md` - `docs/refactor/legacy-feature-gap-matrix.md` - `docs/refactor/supabase-frontend-access-strategy.md` - `docs/refactor/taro-frontend-integration.md` - `docs/refactor/multitenant-auth-security-contract.md` - `docs/refactor/next-development-todo.md` - `docs/refactor/blueprint-coverage.md` - `docs/refactor/api-structure.md` ## 目录结构 ```text apps/api/ Node.js 业务 API apps/taro/ Taro 4 React 跨端前端,H5 三入口,后续扩展小程序 apps/worker/ 后台异步任务:CRM webhook、支付/退款补偿、资源复检、导入执行、公共题库同步、题库导出渲染等 packages/config/ 共享配置 packages/db/ PostgreSQL 连接池和查询封装 packages/domain/ 领域常量和共享类型 supabase/migrations/ 数据库迁移:schema、RLS、索引、触发器 supabase/seed.sql 最小租户 seed scripts/import-pocketbase/ PocketBase schema/数据导入器和校验器 scripts/smoke-seed.js 本地集成测试 seed 数据 scripts/api-integration-test.js docs/refactor/ 重构架构、进度、治理文档 docker-compose.api.yml API 容器化运行配置 ``` 旧项目参考文件在本机 `F:\project\参考\旧题库项目`,旧前端构建产物在 `F:\project\参考\旧构建产物`。这两个目录都只用于对照和迁移,不作为当前新项目源码。 ## 本地开发 前置要求: - Node.js 20+ - Docker Desktop - Supabase CLI 启动本地 Supabase 和 API: ```bash npm install npm run supabase:start npm run supabase:reset npm run db:smoke-seed npm run dev:api ``` Taro H5 本地开发: ```bash npm run dev:taro:h5 ``` 三套 H5 构建: ```bash npm run build:taro:h5:student npm run build:taro:h5:tenant npm run build:taro:h5:platform ``` 对应产物: ```text apps/taro/dist/h5-student apps/taro/dist/h5-tenant-admin apps/taro/dist/h5-platform-admin ``` 推荐分别部署到学生端域名、租户后台域名、平台后台域名;三者共用 `apps/taro/src/services/api.ts` 请求层,业务数据默认调用 `apps/api`,不要在页面里直写 Supabase 表。 学生端当前页面: ```text apps/taro/src/pages/student/login apps/taro/src/pages/student/home apps/taro/src/pages/student/catalog apps/taro/src/pages/student/practice apps/taro/src/pages/student/vocabulary apps/taro/src/pages/student/handbook apps/taro/src/pages/student/scoreline apps/taro/src/pages/student/assets apps/taro/src/pages/student/profile ``` 租户后台当前页面: ```text apps/taro/src/pages/tenant-admin/workbench apps/taro/src/pages/tenant-admin/dashboard apps/taro/src/pages/tenant-admin/students apps/taro/src/pages/tenant-admin/content apps/taro/src/pages/tenant-admin/marketing apps/taro/src/pages/tenant-admin/settings ``` 平台后台当前页面: ```text apps/taro/src/pages/platform-admin/workbench apps/taro/src/pages/platform-admin/tenants apps/taro/src/pages/platform-admin/billing apps/taro/src/pages/platform-admin/question-banks ``` 单次运行 CRM worker: ```bash npm --workspace @tiku-saas/worker run crm:once ``` 单次运行支付/退款补偿 worker: ```bash npm --workspace @tiku-saas/worker run commerce:once ``` 单次运行内容资源复检 worker: ```bash npm --workspace @tiku-saas/worker run assets:once ``` 单次运行内容导入 worker: ```bash npm --workspace @tiku-saas/worker run imports:once ``` 单次运行公共题库自动同步 worker: ```bash npm --workspace @tiku-saas/worker run public-banks:once ``` 单次运行题库 PDF/Word/每日一练 ZIP 导出 worker: ```bash npm --workspace @tiku-saas/worker run exports:once ``` 默认本地数据库: ```text postgresql://postgres:postgres@127.0.0.1:54322/postgres ``` 默认 API 地址: ```text http://127.0.0.1:8787 ``` ## 验证命令 完整后端重构检查: ```bash npm run check:refactor ``` 这个命令会依次执行: - API TypeScript 检查 - PocketBase importer TypeScript 检查 - PocketBase 导入后校验 - 本地 smoke seed - API 构建 - 本地 API 集成测试 常用单项命令: ```bash npm run check:api npm run check:worker npm run check:importer npm run check:taro npm run audit:runtime npm run pb:import:dry-run npm run pb:import:validate npm run test:readiness npm run test:pb:dry-run npm run test:api npm run test:worker:crm npm run test:worker:commerce npm run test:worker:assets npm run test:worker:exports npm run test:worker:imports npm run test:worker:public-banks ``` ## 生产就绪检查 填好生产 `.env` 后,先跑环境变量级检查: ```bash npm run readiness:production ``` 确认 `DATABASE_URL` 指向生产 Supabase/PostgreSQL 后,再跑数据库配置检查: ```bash npm run readiness:production:db ``` 这个检查会阻断默认弱密钥、`CORS=*`、mock 短信、legacy 身份头、local_dev 存储、对象存储未配置、CRM insecure localhost 等生产风险;带 `:db` 的版本还会检查租户 provider 公开配置是否混入密钥、活跃短信/OAuth/支付 provider 是否缺少 `app_private.tenant_secrets`、域名是否未验证。 ## PocketBase 迁移 Dry-Run 把旧 PocketBase 导出的集合 JSON 放到仓库根目录 `pb_export/` 后,先执行不写数据库的静态 dry-run: ```bash npm run pb:import:dry-run ``` 需要给 CI 或脚本读取时: ```bash npm run pb:import:dry-run -- --json ``` dry-run 会检查导出目录、JSON 形态、核心集合缺失、重复/缺失旧 ID、敏感字段、旧 schema 关系断裂和未映射集合。存在 blocker 时命令返回非 0;所有 blocker 处理完后,再执行 `npm run pb:import:json` 和 `npm run pb:import:validate`。 ## API 模块 当前 API 目录: ```text apps/api/src/features/ auth/ 短信登录、迁移期 session、微信小程序登录、微信网页登录、QQ 登录 catalog/ 学生端目录、内容入口、分类树、题目集合、资料、商城只读接口 commerce/ 订单、支付确认、激活码、优惠券、权益 health/ 健康检查 learning/ 练习 session 组卷、答题、错题、收藏、学习进度、排行榜 platform-admin/ 平台方租户、SaaS 套餐、订阅、账单、用量 profile/ 学生个人中心、勋章 referral/ 销售/代理客资追踪、CRM 队列 referral/commission.ts 分佣设置、汇总、来源明细、结算单、审核/打款状态 scoreline/ 分数线 tenant/ 租户解析 tenant-admin/ 租户后台配置、主题、成员权限、班级学生、活动、勋章和审计 tenant-content/ 租户内容导航、题库维护、资源管理、批量导入和题库导出 video/ 题目视频讲解 ``` API 身份上下文: - 推荐:`Authorization: Bearer `,可配合 `x-tenant-id` 提供当前租户上下文。 - 本地/迁移期:`Authorization: Bearer `。 - 兼容旧测试:`x-user-id`、`x-platform-admin-key` 仅允许在 `ALLOW_LEGACY_AUTH_HEADERS=true`、`ALLOW_PLATFORM_ADMIN_KEY=true` 的非生产环境使用。 生产环境必须设置 `ALLOW_LEGACY_AUTH_HEADERS=false` 和 `ALLOW_PLATFORM_ADMIN_KEY=false`,前端不能再传 `x-user-id` 代表当前用户。 ## 重要安全约定 - 租户公开配置和主题配置不能存放密钥;主题 token 只能是后端允许的颜色、半径、安全 CSS 变量、图标 token 和公开素材引用。 - 商户密钥、短信密钥、OAuth app secret 等必须进入 `app_private.tenant_secrets`,或后续生产 KMS/Vault。 - 资料、PDF、视频等资源必须先进入 `content_assets` 台账,再由 API 校验权限并下发签名 URL;学生端预览、锁定资料和视频会使用短 TTL。`members/svip/private` 外部 CDN URL 默认拒绝,除非显式登记 provider-managed 访问;所有上传签名、上传确认、下载/预览 granted/denied 都写入 `content_asset_access_events`。生产环境应定时运行 assets worker 复检对象元数据,异常资源会被标记 failed 并退回 draft。 - 题库入口和分类使用 `content_entries/content_nodes`;题目列表和练习规则使用 `question_collections/practice_blueprints`,前端不要再把旧树字段当成唯一业务结构。 - 批量导入必须先写 `content_import_jobs/items/issues`,保留原始 payload、规范化 payload、逐行问题和审计记录。题目、单词、知识手册、分数线和视频 JSON/CSV/Excel 导入已走这套后台校验管线;大批量任务可提交 `executionMode=async`,由 imports worker 消费,前端只轮询 job 状态和展示 issues。 - 题库导出必须由后端按权限生成,不允许前端直接读取数据库拼导出文件;不开启答案/解析时,顶层题目和复合题子题都必须脱敏;PDF/Word/每日一练 ZIP 只通过 exports worker 写入 `content_assets` 后再签名下载/预览。 - 支付 webhook 必须先设计幂等键和验签流程,再进入生产使用;生产环境还应定时运行 commerce worker 兜底供应商漏通知和处理中退款。 ## 最近一次验证 最近本地验证命令: ```text npx supabase db reset npm run check:api npm run check:worker npm run test:worker:assets npm run test:api npm run check:refactor npm run audit:runtime git diff --check ``` 结果:通过。`npm run test:api` 已覆盖资源访问事件、锁定 CDN 资源拒绝、provider-managed CDN 显式放行、学生短 TTL 下载/预览和访问记录查询。`npm run test:worker:assets` 已覆盖托管资源复检和异常资源自动下架。`npm run audit:runtime` 无 high/critical 漏洞;当前运行时依赖树仍有 `exceljs -> uuid` 的 moderate 级提示,修复需要破坏性降级 `exceljs`,后续应在导入 Excel 回归充分后单独处理。 注意:`apps/taro` 是静态构建工程,线上发布 `apps/taro/dist/**`,不发布 `node_modules`。Taro 4.2.0 当前构建工具链仍会触发 `npm run audit:taro:toolchain` 的上游 high/critical 提示,不能用 `npm audit fix --force` 降级到 Taro 3 破坏构建;上线验收时以 `audit:runtime`、构建产物、前端密钥检查和静态服务器配置为准,并持续跟进 Taro 官方修复。 ## 下一步建议 优先继续补: 1. 真实云端 Auth/JWKS 回归、RLS 深测和生产环境配置验收。 2. 继续补 Taro 前端:学生端视频/反馈/模考报告/订单收银台,租户后台写入表单/导入操作台/公共题库同步/角色模板 UI,平台后台租户详情/审计/自动计费增强,小程序兼容验证。 3. 对象存储 CDN 防盗链、杀毒扫描、视频动态水印和生命周期策略。 4. 题库导出模板精排、导出操作台、真实数据 dry-run、导入字段映射 UI 和复检结果操作台。 5. 真实 OAuth/短信/支付生产账号联调、完整资金流水对账、公共题库版本通知/冲突处理操作台、积分活动深化,以及排行榜防刷/预聚合。