feat: add student video and profile experience

This commit is contained in:
2026-07-28 15:23:42 +08:00
parent 5e993298e7
commit 7a3cf09a99
31 changed files with 19821 additions and 170 deletions

View File

@@ -0,0 +1,75 @@
# 第七阶段:学生端体验与内容消费闭环
第七阶段只补齐学生端和内容消费闭环,不实现 AI 推荐报告。AI 后续单独进入 Semantic Kernel 阶段,租户自己的模型 API Key 通过 `TenantExternalProvider` + `TenantSecret` 配置,业务 DTO、Controller 和普通 Service 不直接接触密钥或 `Microsoft.SemanticKernel` namespace。
## 已实现范围
### 视频消费
新增学生端视频接口:
- `GET /api/videos/search`
- `POST /api/videos/play`
- `POST /api/videos/progress`
- `GET /api/questions/videos`
- `POST /api/questions/videos/batch`
设计边界:
- 播放接口只返回当前租户可访问的视频播放信息。
- API 不暴露 OSS bucket、真实 object key 或 provider 细节。
- 公共题关联视频和租户私题关联视频都必须先通过当前租户可见性校验。
- 播放行为写入 `ContentAssetAccessEvent`
- 播放进度写入 `VideoPlaybackProgress`,同一租户、用户、视频、题目维度幂等更新。
### Profile 与积分
新增学生侧体验接口:
- `POST /api/profile/check-in`
- `GET /api/profile/score-events`
设计边界:
- 签到复用积分任务与积分流水,不另起一套奖励体系。
- 同一用户、同一租户、同一天只能成功签到一次。
- 积分任务领取和积分兑换会同步产生 `UserScoreEvent`,学生端统一从 `score-events` 查询积分变化。
-`/api/profile/activity-tasks``/api/profile/exchange-items` 不恢复为主接口;对应能力由 `/api/points/tasks``/api/points/exchange-items``/api/points/exchange-orders` 替代。
### 内容导入异步化
保留统一导入入口:
- `POST /api/tenant-content/imports/preview/{importType}`
- `POST /api/tenant-content/imports/{importType}`
- `GET /api/tenant-content/imports/detail`
设计边界:
- `questions``vocabulary``handbook``scoreline``videos` 这些旧专用导入语义统一映射为 `importType`
- 小批量可以同步执行。
- 请求显式 `async=true` 或大批量导入时创建 `content_import` 后台任务。
- Worker 通过 `ITenantExecutionScope` 初始化租户 scope 后执行导入,不在请求线程内跑重任务。
- 导入结果写回 import job可通过 detail 接口查询。
## AI 延后约定
本阶段不新增 `/api/ai/**`,不引入 `Microsoft.SemanticKernel` NuGet 包也不实现真实模型调用、prompt、RAG、导出或推荐算法。
后续 AI 阶段默认方向:
- AI Provider 使用 `TenantExternalProvider(capability=ai)`
- 租户 API Key 存入 `TenantSecret`,通过 `SecretRef` 关联。
- Semantic Kernel SDK 只允许出现在 Infrastructure AI provider 实现中。
- Application 层只暴露 `IAiRecommendationProvider``IAiKernelFactory` 等业务抽象。
- Controller 和业务 Service 不直接读取 API Key不直接引用 SK namespace。
## 验收重点
- 租户 A 不能播放租户 B 视频。
- 公共题关联视频和租户私题关联视频都按当前租户权限返回。
- 播放进度重复上报幂等更新。
- 每日签到同一天只能成功一次。
- 签到、积分任务和兑换产生可查询的积分流水。
- 异步导入创建 `content_import` jobWorker 成功写入结果。
- 本阶段不得新增 `Microsoft.SemanticKernel` 引用。