feat: add public question bank sync

This commit is contained in:
Codex
2026-06-29 08:37:40 +08:00
parent 69f8e28d4e
commit 35cff06df7
11 changed files with 690 additions and 128 deletions

View File

@@ -184,7 +184,7 @@ tenant:<tenantId>:theme
| 租户考试日期 | `GET/PUT /api/tenant-admin/exam-dates` |
| 租户反馈处理 | `GET /api/tenant-admin/feedbacks``POST /api/tenant-admin/feedbacks/status``GET /api/tenant-admin/feedbacks/events` |
| 租户勋章 | `GET/PUT /api/tenant-admin/badges``GET/POST /api/tenant-admin/badge-grants` |
| 公共题库采纳 | `GET /api/tenant-content/public-question-banks``POST /api/tenant-content/public-question-banks/adopt` |
| 公共题库采纳/同步 | `GET /api/tenant-content/public-question-banks``POST /api/tenant-content/public-question-banks/adopt``POST /api/tenant-content/public-question-banks/sync` |
## 练习访问控制契约
@@ -850,6 +850,7 @@ PUT /api/platform-admin/question-bank-grants
```text
GET /api/tenant-content/public-question-banks
POST /api/tenant-content/public-question-banks/adopt
POST /api/tenant-content/public-question-banks/sync
```
采纳请求:
@@ -868,7 +869,59 @@ POST /api/tenant-content/public-question-banks/adopt
- 租户只能看到后端判定为已授权的公共题库,不要在前端用套餐码自行过滤。
- 采纳成功后后端会生成本租户自己的 `questionBankId``entryId``collectionId` 和题目快照,学生端直接按普通 `/api/catalog/content-entries``question-collections``practice-sessions` 接入。
- 重复采纳返回 `QUESTION_BANK_ALREADY_ADOPTED`,前端展示“已采纳”即可。
- 当前版本是快照复制;平台公共题库后续更新不会自动进入租户题库,后续会由 worker 做版本同步、冲突处理和租户确认
- 已采纳公共题库可以手动同步平台后续新增/更新题目;同步会重新校验当前租户仍有授权,且只写入租户自己的题目副本
同步请求:
```json
{
"adoptionId": "<tenant_question_bank_adoptions.id>",
"copyLimit": 1000
}
```
同步响应关键字段:
```json
{
"item": {
"id": "...",
"syncStatus": "synced | failed",
"copiedQuestionCount": 120,
"targetQuestionBankId": "...",
"targetEntryId": "...",
"targetCollectionId": "..."
},
"sync": {
"status": "synced | conflict",
"counts": {
"inserted": 1,
"updated": 3,
"skipped": 116,
"conflicts": 0
},
"results": [
{
"sourceQuestionId": "...",
"targetQuestionId": "...",
"action": "inserted | updated | skipped | conflict",
"sourceHash": "...",
"previousSourceHash": "...",
"targetHash": "..."
}
]
}
}
```
前端处理规则:
- `sync.status=synced`:刷新公共题库列表、题目集合和题目列表。
- `sync.status=conflict``item.syncStatus=failed`:展示冲突数量和冲突题目,不要把它当系统异常。冲突表示租户已经改过这道采纳题,后端已跳过并保留租户内容。
- `action=conflict` 的记录可以进入后续“冲突处理”页面:展示平台源题 ID、租户目标题 ID、上次平台 hash、当前平台 hash、租户当前 hash。当前后端只负责保护不覆盖批量接受平台版本/保留租户版本的操作台后续补。
- `QUESTION_BANK_GRANT_NOT_AVAILABLE`:说明 SaaS 套餐/授权已失效,提示联系平台或升级套餐。
- `QUESTION_BANK_ADOPTION_NOT_FOUND`:说明不是当前租户的采纳记录或记录已归档,前端不要跨租户重试。
- 后续会补自动同步 worker、版本通知、冲突操作台和批量确认策略当前租户后台可以先提供手动“同步平台更新”按钮。
## 登录对接