forked from wangziqi/gongxue-base
6.4 KiB
6.4 KiB
API 目录规范
apps/api 是 Web、Taro 小程序、管理后台共用的业务命令 API。项目采用 Supabase-first 架构:简单安全的数据访问可以走 Supabase table/view/RPC + RLS;复杂业务写入、第三方 provider、密钥、webhook、导入、支付、权益、审计进入 apps/api、Edge Functions 或 worker。
当前结构
apps/api/src/
server.ts HTTP 服务入口,只负责请求生命周期
core/
config.ts 环境变量和运行配置
db.ts PostgreSQL 连接池和查询封装
http.ts CORS、JSON 响应、统一错误
router.ts 汇总注册各业务域路由
features/
auth/ 短信验证码、迁移期 session、微信小程序登录、OAuth provider 预留
health/ 健康检查
tenant/ 租户解析、品牌配置、域名识别
catalog/ 公开题库、内容入口、分类树、题目集合、练习蓝图、手册、商城、资料资源只读接口
learning/ 组卷 session、答题、错题、收藏、练习进度、排行榜
commerce/ 订单、支付确认、退款、激活码、优惠券、权益
referral/ 销售/代理客资追踪、首绑保护、团队关系、CRM 队列
storage/ 对象存储签名 provider
video/ 题目视频列表、搜索、SVIP/次数校验和签名播放
platform-admin/ 平台方 SaaS 租户、订阅、账单、使用量
tenant-admin/ 租户品牌、域名、公开设置、登录/商户配置、成员权限、活动/兑换码运营
tenant-content/ 租户后台内容维护:入口、分类树、集合、练习蓝图、题目、视频、分数线、单词、知识手册、资料资源、批量导入
新业务域落位
后续按下面方式增加目录:
features/
auth/ 登录、绑定手机、OAuth 回调、会话换取
learning/ 顺序/随机/模考组卷、答题记录、错题、收藏、学习进度、排行榜
commerce/ 商品、订单、优惠券、支付、退款、权益开通
referral/ 销售/代理增长链路、客资归属、分佣依据、CRM 入队
platform-admin/ 平台租户管理、年费、服务费、账务审计
tenant-admin/ 合作商后台配置、品牌、域名、收款账户、登录 provider、密钥掩码、成员权限、审计、活动、兑换码、优惠券
tenant-content/ 合作商内容导航、题库维护、批量导入、资源绑定、内容审计
每个 feature 默认包含:
index.ts 导出 RouteDefinition[]
routes.ts HTTP handler
service.ts 业务编排和事务
repository.ts SQL 查询和写入
types.ts 仅本领域使用的类型
规则
server.ts不直接 import 业务 handler,只 importcreateRouter()。features/*/index.ts只注册路由,不写 SQL。routes.ts做参数解析、鉴权上下文、HTTP 错误,不写复杂事务。service.ts承接订单、支付、权益、答题判定等业务规则。repository.ts才写 SQL,所有 SQL 必须带明确租户边界。- 可预期错误用
HttpError,生产环境不向前端暴露内部异常。 - 写接口必须考虑幂等、审计和租户隔离;支付 webhook 必须先设计幂等键。
- 不要为了少写 API 而让前端直写复杂业务表。新增前端直连 table/view/RPC 必须先满足 RLS、最小 grant、跨租户测试、权限测试和索引要求。
- 新接口优先使用
Authorization: Bearer <supabase_access_token>;后端通过auth.users.id -> platform_users.auth_user_id -> tenant_memberships映射业务身份。 - 迁移期仍支持
Authorization: Bearer tk_*session;session 明文只返回客户端,数据库只保存 hash。 x-user-id和x-platform-admin-key只允许在非生产兼容模式使用;生产必须关闭ALLOW_LEGACY_AUTH_HEADERS和ALLOW_PLATFORM_ADMIN_KEY。platform-admin管平台与合作商之间的 SaaS 账务,tenant-admin管合作商自己的品牌、域名、公开配置、登录/商户配置、活动和兑换码,tenant-content管合作商自己的题库和学习内容维护。tenant-admin的敏感配置必须拆分:公开字段进入config_public,商户密钥、短信密钥、OAuth app secret 进入app_private.tenant_secrets或生产 KMS/Vault;对前端只返回secretRef和掩码状态。tenant-admin权限由tenant_memberships.role的默认权限和permissionsJSON 覆盖共同决定;后端接口必须校验具体权限点,不能只依赖前端菜单隐藏。referral是增长/客资业务域,负责邀请码、扫码事件、首绑保护、销售/代理团队归属和 CRM 入队;真实 CRM webhook 发送应由 worker 处理,API 只负责幂等入队。- 题库前端入口不再只依赖旧
module_nodes/subjects/categories;新业务主模型是content_entries/content_nodes/question_collections/practice_blueprints,用于表达可视化入口、多级分类、考试意向标记、题目列表和顺序/随机/全真模拟规则。 - 平台公共题库不能被租户前端直接跨租户读取;平台侧通过
/api/platform-admin/question-bank-grants授权,租户侧通过/api/tenant-content/public-question-banks/adopt采纳为本租户题库、入口、集合和题目快照。后续版本同步必须走 worker 和审计。 learning创建练习 session 时必须保存question_ids快照,避免随机刷题和模考过程中题目集合变化导致答题记录无法复盘。- 排行榜必须由后端按租户、地区、班级和可信用户上下文聚合,前端不能自行扫描答题记录、积分流水或单词进度后排名;后续高流量场景再通过 worker/materialized view 做日榜、周榜和防刷。
- 资料、PDF、视频等对象存储资源必须先进入
content_assets台账,再通过 API/Edge Function 做权限校验和签名 URL 下发;前端不能直接拼 OSS/COS/Supabase Storage 私有地址。 - 批量导入必须先写
content_import_jobs/items/issues,保留原始 payload、规范化 payload、逐行问题和审计记录;同步 API 当前支持题目 JSON,Excel/CSV 和其它内容类型应接入同一管线。