forked from wangziqi/gongxue-base
feat: recheck content assets
This commit is contained in:
@@ -93,7 +93,8 @@
|
||||
| Supabase Storage 签名 | 可联调 | `supabase_storage` provider |
|
||||
| 上传后对象校验 | 可联调 | `/api/tenant-content/assets/confirm-upload`;托管对象必须 verified 后才能发布/下载 |
|
||||
| PDF/图片预览签名 | 可联调 | `/api/catalog/assets/preview`、`/api/tenant-content/assets/sign-preview`;使用 inline 短期签名 |
|
||||
| 深度防盗链/水印/杀毒 | 待补齐 | 商用上线前补 worker、CDN 防盗链、动态水印和安全扫描 |
|
||||
| 托管资源 worker 复检 | 可联调 | `apps/worker --job assets` 定期复检 pending/verified 对象元数据;异常资源会标记 failed 并从 active 退回 draft,写入审计和 `security_flags` |
|
||||
| 深度防盗链/水印/杀毒 | 待补齐 | 商用上线前继续补 CDN 防盗链、动态水印、安全扫描和对象生命周期策略 |
|
||||
|
||||
## 订单、会员、营销
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
| 知识手册 | 可联调 | 科目、章节、条目、Markdown 内容、嵌套 JSON 导入 | 富文本资源、版本管理、附件/PDF 关联 |
|
||||
| 分数线 | 可联调 | 院校、专业、动态字段、记录、年份、趋势、后台维护 | 批量导入、复杂筛选、AI 择校上下文 |
|
||||
| 视频解析 | 部分完成 | 单题视频、批量查询、后台视频绑定 | 会员播放权限、播放次数扣减、签名 URL、防盗链、水印 |
|
||||
| 资料下载 | 部分完成 | 资源台账、SVIP 权限校验、`local_dev`/阿里云 OSS/腾讯 COS/Supabase Storage 上传下载签名 | 上传后对象校验、PDF 预览、防盗链、视频水印 |
|
||||
| 资料下载 | 部分完成 | 资源台账、SVIP 权限校验、`local_dev`/阿里云 OSS/腾讯 COS/Supabase Storage 上传下载签名、上传确认、PDF/图片预览签名、assets worker 复检异常下架 | PDF 渲染、CDN 防盗链、杀毒扫描、视频水印 |
|
||||
| 会员与订单 | 可联调 | 下单、订单详情/状态轮询、优惠券领取/抵扣、零元订单自动开通、手工确认权限保护、激活码预检查/兑换、微信支付、支付宝、微信/支付宝发起退款、微信/支付宝退款查询确认、微信/支付宝退款通知 webhook、支付/退款补偿 worker、权益发放 | 完整资金流水对账、异常订单运营台 |
|
||||
| 登录认证 | 迁移期可用 | 短信 mock、迁移期 session、OAuth 配置表 | 阿里云/腾讯云短信、微信小程序/网页登录、QQ 登录、Supabase Auth |
|
||||
| 销售/代理/CRM | 基础完成 | 邀请码、首绑保护、团队关系、销售统计、CRM 入队 | 小程序码真实生成、分佣结算、钉钉/飞书/企微 worker |
|
||||
@@ -76,7 +76,7 @@
|
||||
### P0:上云测试和前端主链路前必须处理
|
||||
|
||||
- 生产鉴权:API 已支持 Supabase Auth JWT;继续做真实云端 Auth/JWKS 回归、RLS 深测,并在生产关闭 `x-user-id` 与 `x-platform-admin-key` 兼容入口。
|
||||
- 对象存储:上传/下载签名已接入阿里云 OSS、腾讯云 COS、Supabase Storage;继续完成上传后对象校验、PDF 预览、视频播放签名、防盗链和水印。
|
||||
- 对象存储:上传/下载签名已接入阿里云 OSS、腾讯云 COS、Supabase Storage;上传确认、PDF/图片预览签名和 assets worker 复检已完成,继续补 PDF 渲染、视频播放防盗链、杀毒扫描和水印。
|
||||
- 真实数据 dry-run:导出 PocketBase 用户、题库、单词、知识手册、分数线、订单、权益,跑迁移和校验报告。
|
||||
- 生产环境配置:补 `.env` 模板、数据库迁移流程、备份恢复、日志、告警和 API 容器部署说明。
|
||||
- Taro scaffold:建立 `apps/taro`,先完成租户解析、首页、题库、背单词、知识手册、个人中心主链路。
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
- 已新增 `npm run test:api`,自动 seed、构建、启动临时 API,并断言核心学生端接口、内容导航/组卷、租户隔离、资源权限和题目导入。
|
||||
- 已新增 `apps/worker` 和 `npm run test:worker:crm`,用于消费 CRM webhook 队列,验证本地 fake webhook、队列状态、日志和密钥不泄露。
|
||||
- 已新增 commerce worker 和 `npm run test:worker:commerce`,用于补偿查询微信/支付宝支付、处理中退款和漏通知场景;支付成功会幂等更新订单/支付并开通权益,退款成功会幂等更新退款/订单/支付并在全额退款时撤销订单权益,测试覆盖密钥不泄露和重复执行不重复开通。
|
||||
- 已新增 assets worker 和 `npm run test:worker:assets`,用于复检 `content_assets` 托管对象元数据;正常资源会写入复检证据,异常资源会自动下架为 `draft`、标记 `upload_status=failed`,并记录审计与安全标记。
|
||||
|
||||
## 已验证接口
|
||||
|
||||
@@ -237,14 +238,14 @@ GET /api/tenant-admin/audit-logs
|
||||
- 学生批量导入、批量分班、学生状态、备注和跟进任务都使用独立权限点;教师默认可为范围内学生写备注和跟进任务,但不能批量导入、禁用学生或放大可见班级。
|
||||
- 销售/代理客资采用首绑保护:普通扫码/分享事件不会覆盖已有归属,只有具备 `referral:write` 的租户成员可手动强制补绑。
|
||||
- CRM 当前完成配置、密钥入私密表、客资入队、队列查询和 `apps/worker` 消费;worker 支持 generic webhook、钉钉、飞书、企业微信机器人消息体/签名、失败重试和日志。
|
||||
- 内容资源当前完成台账、租户后台维护、学生端 SVIP 下载权限,以及 `local_dev`、阿里云 OSS、腾讯 COS、Supabase Storage 的上传/下载签名 provider。真实对象存在性校验、PDF 预览渲染、防盗链、水印和大文件上传后 worker 校验仍需继续补。
|
||||
- 内容资源当前完成台账、租户后台维护、学生端 SVIP 下载权限,以及 `local_dev`、阿里云 OSS、腾讯 COS、Supabase Storage 的上传/下载签名 provider;上传确认和 assets worker 已支持对象元数据校验/复检。PDF 预览渲染、防盗链、水印和安全扫描仍需继续补。
|
||||
- 题库内容导航当前以 `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` 管线。
|
||||
|
||||
## 下一步
|
||||
|
||||
1. 完善内容导入和文件上传:Excel/CSV、分数线、视频导入,对象存储上传后校验、PDF 预览、防盗链和视频水印。
|
||||
1. 完善内容导入和文件上传:Excel/CSV、分数线、视频导入,PDF 预览渲染、防盗链、杀毒扫描和视频水印。
|
||||
2. 接入真实短信 provider:阿里云/腾讯云,密钥放 `app_private.tenant_secrets` 或生产 Vault。
|
||||
3. 接入真实 OAuth provider:微信网页、微信小程序、QQ,并处理旧 PocketBase 身份映射。
|
||||
4. 补完整资金流水对账、异常订单运营台和优惠券核销报表;支付/退款补偿、退款查询确认和退款通知主链路已完成。
|
||||
@@ -257,5 +258,6 @@ GET /api/tenant-admin/audit-logs
|
||||
npm run test:api
|
||||
npm run test:worker:crm
|
||||
npm run test:worker:commerce
|
||||
npm run test:worker:assets
|
||||
npm run check:refactor
|
||||
```
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
- 公共题库商业化基础闭环已完成:平台公共题库可由平台管理员按 SaaS 套餐/指定租户/全部活跃租户授权;租户内容管理员只能看到自己被授权的公共题库,并可采纳为本租户题库、内容入口、题目集合和题目快照,采纳后可直接进入练习 session。
|
||||
- 租户后台数据看板已完成首版聚合 API:`GET /api/tenant-admin/dashboard`,支持租户/地区维度的收益、注册、学习、内容、激活码、反馈、趋势、24h 活跃、套餐销量和运营动态,前端可直接联调。
|
||||
- 支付/退款补偿 worker 已完成:`apps/worker --job commerce` 可查询微信/支付宝支付和处理中退款,补偿漏通知订单,支付成功幂等开通权益,退款成功幂等更新退款/订单/支付并在全额退款时撤销订单权益。
|
||||
- 内容资源复检 worker 已完成:`apps/worker --job assets` 可复检 `content_assets` 中的托管对象元数据,正常资源写回复检证据,异常资源自动置为 `failed + draft` 并写入审计和安全标记。
|
||||
- 本地验证:`npm run check:refactor` 已通过。
|
||||
|
||||
当前更适合进入前端联调前阅读的总览文档:
|
||||
@@ -43,7 +44,8 @@
|
||||
2. 对象存储
|
||||
- 已接阿里云 OSS、腾讯云 COS、Supabase Storage 的上传/下载签名 provider。
|
||||
- 已补上传后对象确认接口、托管对象发布前 verified 校验、PDF/图片 inline 预览签名。
|
||||
- 继续补视频深度防盗链、动态水印、worker 复检、杀毒扫描、CDN 刷新和对象生命周期策略。
|
||||
- 已补 assets worker 复检,异常托管对象会自动下架并记录审计。
|
||||
- 继续补视频深度防盗链、动态水印、杀毒扫描、CDN 刷新和对象生命周期策略。
|
||||
- `content_assets` 继续作为资源台账,不允许前端绕过台账直接访问私有资源。
|
||||
|
||||
3. 真实导入 dry-run
|
||||
|
||||
@@ -64,6 +64,12 @@ POST /api/tenant-content/assets/sign-download
|
||||
POST /api/tenant-content/assets/sign-preview
|
||||
```
|
||||
|
||||
后台资源复检 worker:
|
||||
|
||||
```bash
|
||||
npm --workspace @tiku-saas/worker run assets:once
|
||||
```
|
||||
|
||||
## 标准上传流程
|
||||
|
||||
后台前端上传 PDF、图片、视频或资料包时必须走下面流程:
|
||||
@@ -74,6 +80,8 @@ POST /api/tenant-content/assets/sign-preview
|
||||
4. 调用 `POST /api/tenant-content/assets/confirm-upload`,由后端读取对象元数据并比对大小、MIME、SHA-256。
|
||||
5. 校验通过且 `publish=true` 时,后端将资源置为 `status=active`、`uploadStatus=verified`。
|
||||
6. 学生端只能下载或预览 `active + verified` 的托管对象资源。
|
||||
7. 生产环境定时运行 assets worker,复检 `pending/verified` 托管对象的大小、MIME、SHA-256 等元数据。
|
||||
8. 如果复检发现对象丢失、跨租户 objectKey、大小/MIME/checksum 不一致,worker 会把资源置为 `uploadStatus=failed`,并将 `active` 资源退回 `draft`,同时写入 `security_flags.assetRecheckFailed=true` 和 `audit_logs`。
|
||||
|
||||
确认上传示例:
|
||||
|
||||
@@ -94,6 +102,7 @@ POST /api/tenant-content/assets/sign-preview
|
||||
- `tencent_cos` 使用 COS HEAD Object 预签名请求读取元数据。
|
||||
- `supabase_storage` 使用 Storage list metadata 做最小存在性/大小校验。
|
||||
- 如果 provider 无法返回 SHA-256,后端会记录 `checksumUnavailable=true`,生产建议上传时写入对象自定义元数据,例如 `x-oss-meta-sha256` 或 `x-cos-meta-sha256`。
|
||||
- worker 的复检证据写入 `verification_details.assetWorker`,包含 `lastCheckedAt`、`lastResult`、`expected`、`observed`、`issues`,便于租户后台定位资源异常。
|
||||
|
||||
## 安全规则
|
||||
|
||||
@@ -106,6 +115,7 @@ POST /api/tenant-content/assets/sign-preview
|
||||
- 下载和视频播放必须先经过 API 权限判断,再下发短期签名 URL。
|
||||
- 云厂商 AccessKey、SecretKey、Service Role Key 只存在服务端环境变量,不返回前端。
|
||||
- `content_assets` 是资源唯一台账,前端不得绕过台账直接访问私有 bucket。
|
||||
- 前端不能把 `uploadStatus=failed` 或 `status=draft` 的资源继续展示为可下载;列表仍返回时应展示“资料处理中”或“资源异常已下架”,真正下载/预览会被后端拒绝。
|
||||
|
||||
## 环境变量
|
||||
|
||||
@@ -149,6 +159,15 @@ SUPABASE_STORAGE_URL=https://your-project.supabase.co/storage/v1
|
||||
SUPABASE_STORAGE_SERVICE_KEY=
|
||||
```
|
||||
|
||||
assets worker:
|
||||
|
||||
```text
|
||||
WORKER_ASSET_BATCH_SIZE=50
|
||||
WORKER_ASSET_MIN_AGE_SECONDS=300
|
||||
WORKER_ASSET_RECHECK_INTERVAL_SECONDS=86400
|
||||
WORKER_ASSET_REQUEST_TIMEOUT_MS=10000
|
||||
```
|
||||
|
||||
## 生产建议
|
||||
|
||||
- 阿里云和腾讯云生产环境优先用 STS/临时密钥或 RAM/CAM 最小权限账号。
|
||||
@@ -156,7 +175,7 @@ SUPABASE_STORAGE_SERVICE_KEY=
|
||||
- 图片、PDF、视频分别设置合理的 CORS,只允许前端域名和小程序业务域名访问。
|
||||
- 开启对象版本控制、生命周期、跨区域复制或定时备份,满足后续容灾要求。
|
||||
- 视频资源已接入 SVIP/播放次数校验、短期签名和播放日志;生产阶段继续补转码、动态水印、CDN 防盗链和播放统计。
|
||||
- 大文件上传已经支持 API 即时确认;后续可增加 worker 做异步复检、杀毒、转码、水印和 CDN 刷新。
|
||||
- 大文件上传已经支持 API 即时确认和 worker 元数据复检;后续继续补杀毒、转码、水印和 CDN 刷新。
|
||||
|
||||
## 官方依据
|
||||
|
||||
|
||||
@@ -575,6 +575,7 @@ GET /api/catalog/assets/download?assetId=<assetId>
|
||||
- `download.url` 是短期 attachment URL,只给下载动作使用。
|
||||
- `ASSET_SVIP_REQUIRED`:提示开通对应地区/科目权益。
|
||||
- `ASSET_UPLOAD_NOT_VERIFIED`:展示“资料正在处理中”,并上报前端日志。
|
||||
- `ASSET_NOT_FOUND` 或列表中资源从 `active` 消失:展示“资源异常已下架”或刷新列表,不要继续使用旧签名 URL。
|
||||
- `ASSET_PREVIEW_NOT_SUPPORTED`:隐藏预览按钮,仅保留下载或提示不支持预览。
|
||||
- `previewUrl` 字段只作为公开/托管预览提示,不代表可以绕过接口直接访问。
|
||||
|
||||
@@ -598,6 +599,8 @@ sign-upload -> 直传对象存储 -> PUT assets 登记草稿 -> confirm-upload -
|
||||
|
||||
托管对象在确认前会保持 `status=draft`、`uploadStatus=pending`,学生端不会看到。确认失败时后端返回 `UPLOAD_VERIFICATION_FAILED`,后台必须展示失败原因并允许重新上传,不能前端强行改为已发布。
|
||||
|
||||
生产环境会定时运行 assets worker 复检对象存储元数据。复检发现对象丢失、跨租户 objectKey、大小/MIME/checksum 不一致时,后端会把资源置为 `uploadStatus=failed` 并从 `active` 退回 `draft`,同时写入 `securityFlags.assetRecheckFailed=true`。租户后台资源列表应对 failed 资源展示异常原因和重新上传入口;学生端不要缓存资料列表和签名 URL 作为长期状态。
|
||||
|
||||
## 考试倒计时、签到积分和反馈
|
||||
|
||||
首页可用 `GET /api/catalog/exam-dates?regionId=<regionId>` 展示地区公开考试日期;个人中心优先用 `GET /api/profile/exam-countdowns`,后端会按学生当前 `regionId/selectedSchoolId` 返回匹配倒计时。
|
||||
|
||||
Reference in New Issue
Block a user