fix: support authenticated video citation playback

This commit is contained in:
key
2026-08-02 22:04:09 +08:00
parent 6ad8a017a4
commit a07bbcca07
7 changed files with 83 additions and 26 deletions
+2 -2
View File
@@ -17,7 +17,7 @@
| 案例沉淀 `/knowledge/cases` | `GET /api/knowledge/case/capabilities`、`POST /api/knowledge/case/upload`、`/organize`、`/curate`、`GET /records`、`GET /records/{caseId}`、`POST /records/{caseId}/review`、`POST /records/{caseId}/publish`、`POST /records/{caseId}/retire`、`GET /records/{caseId}/media` | `/capabilities` 返回服务端判定的案例提交/查看能力,移动端不再向普通员工展示无权提交的素材表单;`/upload` 改为 multipart 真实语音上传并走 ASR,服务端只接受 MP3/WAV/M4A/WebM/OGG/AAC/FLAC,成功后原始音频写入 `sys_oss`,案例记录只保存 `mediaOssId` 供受保护媒体接口读取,不向客户端回传原始 `mediaUrl`;`/organize` 用真实转写调 chat 模型整理案例,未配置模型时按真实 transcript 本地结构化,并从背景外的真实摘要项提取学习点;`/curate` 只进入经验候选池,`/review` 只完成业务审核,`/publish` 才能在来源授权、脱敏、适用岗位、负责人、版本和生效期齐全时进入正式经验库,`/retire` 要求填写下线原因并立即停止员工召回;APP 用户必须先以认证手机号精确校验在职 `person_phone`,再由可信主体解析 `aihr_org_snapshot` 项目范围;案例 SQL 不得把 `person_phone` 与 `ext_party_id` 作为替代查询键。上传、整理、候选、审核、发布、下线、列表和详情均按该项目范围校验,未完成正式组织映射时安全拒绝,不接受前端伪造项目范围;员工列表/详情只返回 `knowledge_status=PUBLISHED` 且处于生效期的 `已入库` 案例,管理端系统用户保留全局运营视图;移动端和管理端案例详情通过受保护媒体接口回放原始音频,主管/项目负责人可提交脱敏点评;预渲染视频样片仍待正式媒体资产接入 |
| 案例媒体安全 | `GET /api/knowledge/case/records/{caseId}/media` | 案例详情只返回 `mediaOssId`,不返回原始 `sys_oss.url`;媒体下载会重复执行登录、后台角色或 APP 项目范围校验,再由服务端流式读取 OSS。管理端与 `mobile-uni` 通过鉴权 blob/temp 文件播放,关闭详情页时释放本地对象 URL |
| 问·数字师傅工作 Agent `/pages/user/sop/index` | `POST /api/aihr/agent/messages`、`POST /api/aihr/agent/messages/media`、`POST /api/aihr/agent/actions/{draftId}/confirm`、`POST /api/aihr/agent/actions/{draftId}/dismiss` | 移动端文字、ASR 转写和图片/视频统一进入 Agent。服务端根据消息规划 `KNOWLEDGE_QA/RESOURCE_DELIVERY/LIVE_MY_WORK/LIVE_TEAM_WORK/PRACTICE_COACHING/CAPTURE_FACT/MEDIA_UNDERSTANDING/WEB_RESEARCH/CLARIFY/SOCIAL`,再由固定策略校验当前登录身份和工具权限;客户端不提交 `toolCode`,模型也不能自由指定身份、SQL、URL 或任意工具。知识、训练概况、当前待办、确认式记忆、媒体分析和全网查询均复用现有领域服务;普通图片问答只做本次视觉分析,不要求先具备知识空间,用户明确问现场制度/流程时才校验授权空间并补充 SOP。全网查询先返回 `NEEDS_INPUT`,只有用户明确同意后才调用外部服务。统一响应使用结构化 `status/sourceSummary/citations/resources/actionDraft/clarification`;按钮不从答案文本推断。写入动作只接受 30 分钟有效的不透明 `draftId`,最终确认继续复用既有版本、幂等与可见性规则。每次运行只审计租户、主体、意图、工具、状态、来源类型、耗时和错误码,不保存原始问题、答案或附件。 |
| SOP 知识底层服务 `/knowledge/sop` 与旧客户端兼容 | `POST /api/knowledge/query`、`POST /api/knowledge/query-media`、`GET /api/knowledge/resources/{attachmentId}/content`、`POST /api/knowledge/answer-feedback`、`GET /api/knowledge/position-sop`、`GET /api/aihr/mobile/onboard/tasks`、`POST /api/aihr/mobile/onboard/tasks/{id}/complete`、`GET /api/aihr/mobile/qualification`、`POST /api/knowledge/doc/upload` | Agent 按规划结果调用该层;管理端和旧客户端接口继续兼容。文字/现场附件查询走统一知识空间授权和 MySQL Fulltext + Qdrant 混合召回;内部登录端可选传 `conversationId/contextVersion`,服务端保留 30 分钟不活跃过期、最新 6 轮脱敏截断上下文,用现有 chat 模型或保守规则输出 `QA/FILE/VIDEO/DATA_TOOL` 和 `rewrittenQuery`,旧版本冲突返回 `409`。员工从银城大喇叭详情追问时只传 `broadcastMessageId`:服务端每轮按当前 APP 在职员工、当前租户和 `PUBLISHED` 状态重新取消息,响应仅回显 `{messageId,title,publishedAt}`,消息正文不写入客户端存储、会话 JSON 或查询审计;同一会话的消息来源不可改绑,撤回、跨租户或非在职员工均拒绝。该上下文只说明公司消息,不可据此捏造个人任务;上下文模式拒绝现场媒体和数据工具,外部无状态 API 不接受该参数。岗位 SOP 的项目范围复用当前 APP 已验证主体的 `projectCodes`,不得以管理端组织快照的模糊/别名查询作为后备。原文件/视频仅从当前命中且仍有授权的附件返回,内容接口每次重新计算租户、应用和主体权限;无资源时明确返回空列表,不生成假链接。搜索继续返回 `reviewId/promptVersion`,员工反馈保存评审批次;员工学习页按当前 APP 身份读取正式岗前/入职任务,资格证据无正式数据时明确返回 `NOT_CONFIGURED`。详细边界见 [专项设计](20260718/问师傅多轮会话与原始资料交付设计.md)。 |
| SOP 知识底层服务 `/knowledge/sop` 与旧客户端兼容 | `POST /api/knowledge/query`、`POST /api/knowledge/query-media`、`GET /api/knowledge/citations/{detailRef}`、`POST /api/knowledge/citations/{detailRef}/media-link`、`GET /api/knowledge/resources/{attachmentId}/content`、`POST /api/knowledge/resources/{attachmentId}/download-link`、`GET /api/knowledge/resources/{attachmentId}/download?ticket=`、`POST /api/knowledge/answer-feedback`、`GET /api/knowledge/position-sop`、`GET /api/aihr/mobile/onboard/tasks`、`POST /api/aihr/mobile/onboard/tasks/{id}/complete`、`GET /api/aihr/mobile/qualification`、`POST /api/knowledge/doc/upload` | Agent 按规划结果调用该层;管理端和旧客户端接口继续兼容。文字/现场附件查询走统一知识空间授权和 MySQL Fulltext + Qdrant 混合召回;内部登录端可选传 `conversationId/contextVersion`,服务端保留 30 分钟不活跃过期、最新 6 轮脱敏截断上下文,用现有 chat 模型或保守规则输出 `QA/FILE/VIDEO/DATA_TOOL` 和 `rewrittenQuery`,旧版本冲突返回 `409`。员工从银城大喇叭详情追问时只传 `broadcastMessageId`:服务端每轮按当前 APP 在职员工、当前租户和 `PUBLISHED` 状态重新取消息,响应仅回显 `{messageId,title,publishedAt}`,消息正文不写入客户端存储、会话 JSON 或查询审计;同一会话的消息来源不可改绑,撤回、跨租户或非在职员工均拒绝。该上下文只说明公司消息,不可据此捏造个人任务;上下文模式拒绝现场媒体和数据工具,外部无状态 API 不接受该参数。岗位 SOP 的项目范围复用当前 APP 已验证主体的 `projectCodes`,不得以管理端组织快照的模糊/别名查询作为后备。原文件、图片和视频只从当前命中且仍有授权的附件返回;回答只携带不透明 `detailRef` 和最小定位摘要,详情及媒体票据接口每次重新计算租户、应用、主体和来源状态。文本详情返回受控分段和命中标记,图片/视频通过短期单附件票据以内联 MIME 响应读取,视频支持 HTTP Range;不返回原始 OSS 地址或登录令牌。无资源时明确返回空列表,不生成假链接。搜索继续返回 `reviewId/promptVersion`,员工反馈保存评审批次;员工学习页按当前 APP 身份读取正式岗前/入职任务,资格证据无正式数据时明确返回 `NOT_CONFIGURED`。详细边界见 [专项设计](20260718/问师傅多轮会话与原始资料交付设计.md)和[引用详情实施计划](superpowers/plans/2026-07-31-mobile-citation-source-viewer.md)。 |
| 工作助手确认式统一采集 `/pages/user/sop/index`、`/pages/user/assistant/memories` | Agent 主入口返回 `actionDraft`,确认/忽略走 `/api/aihr/agent/actions/{draftId}/confirm|dismiss`;旧接口 `POST /api/knowledge/query`、`POST /api/knowledge/query-media`、`GET /api/aihr/personal-assistant/memory-candidates?status=DRAFT`、`POST /api/aihr/personal-assistant/memory-candidates/{id}/confirm|dismiss` 继续兼容;确认记录读写使用 `GET /api/aihr/personal-assistant/assistant-captures?limit=50`、`POST /assistant-captures/{id}/status`、`GET /assistant-captures/{id}/status-history`、`GET /assistant-captures/{id}/source`,旧项目记录继续使用 `/api/aihr/service-memories` | 文字、ASR 转写和现场媒体复用同一候选检测。项目工作必须从 `/api/aihr/mobile/me` 返回的项目名称列表选择当前项目,内部 `projectCode` 仍由服务端按当前登录主体授权收窄;个人笔记可以不绑定项目。显式“记一下”生成 `ASSISTANT_CAPTURE/DRAFT`,系统建议 `ATTENDANCE/INSPECTION/SERVICE_LEAD/RESIDENT_PROFILE/CASE/PERSONAL_NOTE/FOLLOW_UP/PROJECT_NOTE`。确认必须带 `expectedVersion + idempotencyKey + saveScope(PRIVATE|COMPANY)`;PRIVATE 仅本人可见,COMPANY 写入 PENDING 待流转。状态更新只允许 `RECORDED/PENDING/IN_PROGRESS/COMPLETED/VOID`,幂等键不得跨记录或目标状态复用。来源文件重新鉴权交付;正式外部接收端未配置前不得显示已送达。 |
| 今日工作成果 `/pages/user/work-results/index`、`/pages/supervisor/work-results/index` | 员工 `POST /api/aihr/work-results/mine/generate?projectCode=...&workDate=YYYY-MM-DD`;主管 `GET /api/aihr/work-results/project?projectCode=...&workDate=YYYY-MM-DD` | 按员工 + 项目 + Asia/Shanghai 自然日确定性聚合已确认记录;两页默认当天并可按日期查看历史成果,客户端禁止选择未来日期。内容未变化时重复生成不增加版本,记录或状态变化后版本递增。主管只可查看本人在目标项目具备主管身份的团队结果;APP 登录身份同时兼容组织快照中的外部人员 ID 与手机号,普通员工或跨项目请求返回 403。外部接口未接通时只显示本地状态和 PENDING,不伪造派单或考勤同步成功 |
| 银城大喇叭 | 员工 `GET /api/aihr/broadcast/unread-count`、`GET /api/aihr/broadcast/messages?pageNum=&pageSize=`、`GET /api/aihr/broadcast/messages/{id}`、`POST /api/aihr/broadcast/messages/{id}/read`、`GET /api/aihr/broadcast/attachments/{id}/view`、`GET /api/aihr/broadcast/attachments/{id}/content`;员工详情可经统一 `POST /api/knowledge/query` 的 `broadcastMessageId` 发起文字追问;管理 `GET /api/aihr/broadcast/admin/messages`、`POST /api/aihr/broadcast/admin/attachments`、`GET /api/aihr/broadcast/admin/attachments/{id}`、`PUT /api/aihr/broadcast/admin/attachments/{id}/topic-tags`、`POST /api/aihr/broadcast/messages`、`POST /api/aihr/broadcast/messages/{id}/withdraw` | 发布支持 `visibilityMode=ALL/TARGET_ONLY`、必读、单个公司文件与异步提炼;`TARGET_ONLY` 必须有目标,发布时冻结匹配收件人,列表、详情、未读、阅读、附件和追问统一复核可见性,非目标员工按不存在处理。`ALL` 下目标只作定向提醒。附件支持 txt/md/PDF/Word/Excel/PPT,100MB 内;只有 `READY` 且未绑定、属于当前租户和上传人的文件才可发布。`allowDownload=false` 时员工端不返回下载入口,后端 `/content` 也拒绝;`/view` 返回受控提取文本并记录独立查看审计,客户端叠加含内部账号和分钟的动态水印。水印用于追溯,不等于阻止截屏或泄露;下载副本水印仍须按文件格式另行实现和验收。主题标签仅由固定关键词规则或人工修正产生,均保存可在原文逐字找到的短依据,且绝不参与授权。文件岗位解读继续返回有原文依据的 `insightStatus/defaultPerspectiveCode/perspectiveLabels/perspectives`,不返回原始 OSS 地址。下载、查看和追问每次重新校验 APP 在职身份、租户、消息状态和可见范围;客户端追问仍只传 `broadcastMessageId`。发布、阅读、文件访问和撤回保持幂等与审计约束;管理接口只允许 `superadmin` 或 `hr_operator`。当前仍不包含消息修订、撤回后补推或短信/电话强触达。 |
@@ -358,7 +358,7 @@ Content-Type: application/json
{"queryText":"你们提供哪些服务?","spaceCodes":["mt_customer_service"],"limit":5}
```
成功响应包含 `requestId`、`answer`、`citations`、`usedSpaceCodes`、`noEvidence` 和兼容 `legacy` 数据。引用携带 `spaceCode/sourceType/docId/title/snippet/fragmentId`;客户端不得把无引用回答包装成有知识依据的正式答案。
成功响应包含 `requestId`、`answer`、`citations`、`usedSpaceCodes`、`noEvidence` 和兼容 `legacy` 数据。引用携带 `spaceCode/sourceType/docId/title/snippet/fragmentId`,可查看原始出处的 `DOCUMENT` 引用另带 `mediaType/detailRef/locatorSummary`;`detailRef` 是短期不透明引用,只能交给受认证的引用详情接口重新鉴权,客户端不得解析或拼接附件身份。客户端不得把无引用回答包装成有知识依据的正式答案。
空间、空间内分类、授权和应用管理接口统一位于 `/api/knowledge/admin`:`spaces`、`spaces/{id}/categories`、`spaces/{id}/documents`、`spaces/{id}/documents/{attachId}/category`、`spaces/{id}/grants`、`apps`、`apps/{id}/spaces`、`apps/{id}/rotate-token`。分类仅在当前有效租户和当前知识空间内维护;停用分类不能继续归类,删除前必须先移走其知识,分类不会扩大空间授权或调用应用的检索范围。`DELETE /spaces/{id}/documents/{attachId}` 只解绑当前空间成员;若该成员对应已批准或已发布的治理资产,服务端会先以当前人工操作人执行统一 `WITHDRAW`,立即切断 MySQL 生产可见性并通过 outbox 删除向量。其他空间或治理资产仍引用同一 OSS 时原文件不会删除,引用核验失败时也必须保留原件。仅知识平台管理角色可调用,API_TOKEN 创建或轮换后只返回一次明文。超级管理员由“租户管理”进入知识维护时,通过 `GET /system/tenant/dynamic/{tenantId}` 设置服务端动态租户,再由 `GET /system/tenant/dynamic` 回读当前上下文;仅正常状态的已存在租户允许切换。动态租户按当前 Sa-Token 与浏览器页面生成的匿名上下文共同隔离,客户端每次请求回传页面上下文及当前展示租户;两者与服务端不一致时服务端返回 `409` 并拒绝读写,避免多标签页误写。知识平台不接受客户端传入的 `tenantId` 来选租户。完整初始化、令牌保管、legacy 迁移与回滚步骤见 [KNOWLEDGE_PLATFORM_RUNBOOK.md](KNOWLEDGE_PLATFORM_RUNBOOK.md)。