feat(aihr): close functional checklist gaps
This commit is contained in:
@@ -14,16 +14,16 @@
|
||||
| 正式试点数据导出 | `GET /api/train/practice/export?startDate=YYYY-MM-DD&endDate=YYYY-MM-DD` | 起止日期必填且包含结束日;只统计窗口内能通过唯一手机号或外部 ID 映射到在职组织快照的正式会话,排除重复手机号和身份碰撞。完训定义为每人至少 10 次,校准必须关联同一窗口内正式会话;CSV 同时给出校准命中数、SOP 可用数、满意度响应数/平均分,以及明细级 AI 分、人工校准分、校准人、校准时间、最终采用分、满意度分和意见,避免用四舍五入后的比率反推门禁状态;汇总和明细均携带正式人员及项目口径,不混入历史 seed/开发身份 |
|
||||
| 对练语音 | `POST /api/ai/asr`(multipart 字段 `file`,≤5MB)、`POST /api/ai/tts`(JSON `{text≤300字, voice?, voiceProfile?:{role,voice?,speed?,emotion?,dialect?}, practiceContext?:{sessionId,turnIndex,role:'customer'}}`,`dialect` 仅接受 `mandarin/cantonese/sichuanese`,非法值返回业务码 `400`;旧 `voice` 兼容;成功返回 `ossId`,客户端播放地址为受控的内联 `data:audio/*`,不返回原始 OSS URL)、`GET /api/aihr/mobile/oss/{ossId}` | ASR 按供应商分流:SiliconFlow 等 OpenAI audio 兼容服务继续走 `/audio/transcriptions` multipart;阿里云百炼 `dashscope/qianwen + qwen3-asr-flash` 走工作空间 `/compatible-mode/v1/chat/completions`,将短音频编码为 Base64 `input_audio` 并读取 `choices[0].message.content`,请求上限仍由本接口收窄为 5MB。生产 TTS 优先阿里 `qwen-audio-3.0-tts-flash`,旧 SiliconFlow CosyVoice2 保留兼容;按角色映射老师傅/业主/面试官音色,业主对练再按已有情绪分切换平静/严肃/强烈语气和语速;dialect 作为语气提示传给支持表现力提示词的 TTS,不含克隆,也不等同于方言正式验收。`practiceContext` 仅允许已认证 APP 员工把本次服务端生成的业主 TTS 绑定到本人当前或刚完成会话的指定原话术回合;服务端重新校验租户、员工身份、回合和文本,不接受员工端传 OSS ID 或任意角色。设备语音降级按方言选择语言:粤语使用 `zh-HK`,四川话无法由设备语音可靠模拟时明确提示用户转用服务端语音或文字,不伪装成普通话。模型管理需启用 `category=asr/tts` 配置;移动端优先用浏览器录音,`getUserMedia/MediaRecorder` 不可用或麦克风权限失败时,用 `audio/*` file input 选择/录制音频后继续调同一 ASR 接口;ASR/TTS 未配置或失败返回 fail,前端降级设备语音或文本;训练/每日题录音只通过 `audioOssId` 走受保护下载,历史客户端传入的 HTTP `audioUrl` 不再回显;TTS 成功音频仍写入 `sys_oss` 留痕,同时用内联 data URL 保持旧客户端可播放;移动端 OSS 下载只允许经本人或主管项目范围验证的 APP 身份,后台账号若需回放必须使用未来独立、受审计的管理端契约。 |
|
||||
| 实时对练 Beta(WebRTC) | `POST /api/train/practice/realtime/sdp`、`GET /realtime/personas`、`POST /realtime/session`、`POST /realtime/tools/invoke` | H5 浏览器及 App-Plus renderjs WebView 内的 WebRTC 直连阿里云(音频不过服务端),后端仅代理 SDP 交换(3 次/分/账号,sessionId 仅作日志关联且限字符)。人设为服务端 `AihrRealtimePersonaRegistry` 白名单:`owner-calm` 业主·常规(默认)、`owner-impatient` 业主·急躁、`digital-mentor` 数字师傅;人设绑定默认音色,客户端只选不编。`session.update`(instructions/音色/turn_detection/tools 声明)由 `/realtime/session` 组装下发,客户端原样转发;personaId 空白回落默认人设;会话记录写 Redis 30min(成功工具调用滑动续期),创建限流 6 次/分/账号。`digital-mentor` 声明 `search_knowledge` 工具:模型 function calling 命中(`response.function_call_arguments.done`)时客户端回传 `/realtime/tools/invoke`,服务端按登录态 + Redis 会话归属 + 人设工具白名单三重校验后走 `searchAuthorized` 浅层检索(不生成 LLM 答案、不落 `aihr_agent_run`;`source=realtime` 跳过 SOP 评审与知识缺口写入),output 拼接 ≤3 条片段并截断 1200 字;工具按账号限流 20 次/分,无授权/无结果/超时一律返回软着陆文案让模型如实作答,不中断语音会话。实时 Beta 不计分、不持久化训练数据;H5 与 App-Plus 均支持,App-Plus 在 renderjs 视图层执行媒体/WebRTC 并通过逻辑层复用受认证 SDP 与工具接口;需 APP 员工登录态,不启用模型 `enable_search`。配置 `AIHR_QWEN_REALTIME_ENDPOINT` / `AIHR_QWEN_REALTIME_API_KEY` / `AIHR_QWEN_REALTIME_MODEL`(模型白名单 `qwen3.5-omni-(flash|plus)-realtime`),密钥只放 `.env.local` 或外部环境变量。 |
|
||||
| 案例沉淀 `/knowledge/cases` | `GET /api/knowledge/case/capabilities`、`POST /api/knowledge/case/upload`、`/organize`、`/curate`、`GET /records`、`GET /records/{caseId}`、`POST /records/{caseId}/review`、`GET /records/{caseId}/media` | `/capabilities` 返回服务端判定的案例提交/查看能力,移动端不再向普通员工展示无权提交的素材表单;`/upload` 改为 multipart 真实语音上传并走 ASR,服务端只接受 MP3/WAV/M4A/WebM/OGG/AAC/FLAC,成功后原始音频写入 `sys_oss`,案例记录只保存 `mediaOssId` 供受保护媒体接口读取,不向客户端回传原始 `mediaUrl`;`/organize` 用真实转写调 chat 模型整理案例,未配置模型时按真实 transcript 本地结构化,并从背景外的真实摘要项提取学习点;APP 用户必须先以认证手机号精确校验在职 `person_phone`,再由可信主体解析 `aihr_org_snapshot` 项目范围;案例 SQL 不得把 `person_phone` 与 `ext_party_id` 作为替代查询键。上传、整理、入库、列表和详情均按该项目范围校验,未完成正式组织映射时安全拒绝,不接受前端伪造项目范围;员工列表/详情只返回 `已入库` 案例,管理端系统用户保留全局运营视图;移动端和管理端案例详情通过受保护媒体接口回放原始音频,主管/项目负责人可提交脱敏点评;预渲染视频样片仍待正式媒体资产接入 |
|
||||
| 案例沉淀 `/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)。 |
|
||||
| 工作助手确认式统一采集 `/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}/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}`、`POST /api/aihr/broadcast/messages`、`POST /api/aihr/broadcast/messages/{id}/withdraw` | 发布支持全员或按部门/岗位/人员定向、必读、单个公司文件与异步提炼。文件支持 txt/md/PDF/Word/Excel/PPT,100MB 内;先受控写入 OSS,再异步解析并复用现有模型生成摘要,只有 `READY` 且未绑定、属于当前租户和上传人的文件才可随消息发布。文件提炼完成后异步生成生活顾问、保洁、保安、工程维修、财务、人力、运营、审计风控、管理层中有原文依据的岗位解读;员工详情附件返回 `insightStatus/defaultPerspectiveCode/perspectiveLabels/perspectives`,每项依据仅含原文段号与已校验的短引用,不返回提取全文或原始 OSS 地址。`defaultPerspectiveCode` 由服务端按当前 APP 手机号精确匹配在职岗位,客户端不能指定;所有有权限员工仍可查看并切换全部已生成视角。`PENDING/PARTIAL/FAILED` 均不阻断摘要、原文件下载、消息发布或追问。下载和追问每次重新校验当前 APP 在职身份、租户和消息状态,追问上下文由服务端拼接消息正文与提取文本,客户端仍只传 `broadcastMessageId`。定向目标在界面称“定向提醒”,用于必读与范围提示,不改变全租户公开频道的可见性。发布、阅读和撤回保持既有幂等与审计约束;管理接口只允许 `superadmin` 或 `hr_operator`。当前仍不包含消息修订、撤回后补推或短信/电话强触达。 |
|
||||
| 银城大喇叭 | 员工 `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`。当前仍不包含消息修订、撤回后补推或短信/电话强触达。 |
|
||||
| 员工直通车 `/pages/user/direct/index`、管理端 `/content/direct` | 员工 `GET /api/aihr/direct/channels`、`POST /api/aihr/direct/feedback`、`GET /api/aihr/direct/mine`、`GET /api/aihr/direct/mine/{id}`;处理端 `GET /api/aihr/direct/admin/feedback`、`POST /api/aihr/direct/admin/feedback/{id}/reply`;处理人配置 `GET /api/aihr/direct/admin/handlers`、`GET /api/aihr/direct/admin/handlers/{channelCode}/candidates`、`POST /api/aihr/direct/admin/handlers/{channelCode}`、`POST /api/aihr/direct/admin/handlers/{channelCode}/remove` | 员工可选择总裁、财务、人力、审计、运营并点对点提交;反馈内容支持语音转文字输入(复用 `/api/ai/asr`;文字为主路径,录音不可用或权限失败仅提示改文字输入)。总裁/审计默认匿名;匿名仅表示业务处理界面不显示提交人,系统仍保存内部账号和姓名快照供本人查询、幂等与审计。`direct_president/direct_finance/direct_hr/direct_audit/direct_operations` 仅处理各自频道,`superadmin` 可处理全部;列表、详情和回复均由服务端按角色收窄。只有 `superadmin` 可维护五通道处理人;候选人由服务端限定为当前租户已启用的后台用户并排除 APP 用户、超级管理员和已绑定用户,写请求必须回传当前 `tenantId` 防止租户上下文漂移;建议每个通道至少配置 2 人,但系统不自动绑定账号。一个反馈只允许一次正式回复,员工可在“我的反馈”查看状态和回复;当前不扩展为工单 SLA、转派或多轮聊天。 |
|
||||
| 成果投稿(当前页面名“工作上报”)`/pages/user/report/index` | `POST /api/aihr/work-report/organize`、`POST /attachment`、`POST /reports`、`GET /reports/mine`;主管/运营另有列表和审核接口 | 只承载 CASE/VIDEO/SOP/KNOWLEDGE 四类投稿。会话式页面、无状态整理、附件、幂等正式提交和历史状态已部署;审核通过不自动入知识库。当前整理服务不读取图片/视频内容,只把附件名称作为不可信元数据;不得与日常工作记录或“今日工作成果”混用 |
|
||||
| 资料处理 `/knowledge/processing` | `GET /api/knowledge/processing/overview`、`POST /api/knowledge/doc/upload-async`、`GET /api/knowledge/doc/upload-items`、`POST /api/knowledge/doc/upload-items/{id}/retry`、`POST /api/knowledge/doc/processing-tasks/{attachmentId}/retry` | 已接入解析任务状态聚合;页面只保留“批量导入”,接口暂存+入队即秒回,后台 worker(并发 2)逐条解析/归类/向量化;ZIP 在 worker 内安全解压后把支持的子文件继续入同一批次队列,页面按批次轮询进度。零片段媒体不再记为完成或永久“等待解析”,而是保留为可重试失败;管理端可从原 OSS 文件重新入队,无需用户重复上传;不提供浏览器目录选择或服务端目录导入入口 |
|
||||
| 资料处理 `/knowledge/processing` | `GET /api/knowledge/processing/overview`、`POST /api/knowledge/doc/upload-async`、`GET /api/knowledge/doc/upload-items`、`POST /api/knowledge/doc/upload-items/{id}/retry`、`POST /api/knowledge/doc/processing-tasks/{attachmentId}/retry`;运维 `GET /actuator/health/aihrUploadCapacity` | 已接入解析任务状态聚合;页面只保留“批量导入”,接口暂存+入队即秒回,后台 worker(单实例并发 2)逐条解析/归类/向量化;ZIP 在 worker 内安全解压后把支持的子文件继续入同一批次队列,页面按批次轮询进度。单文件上限 500MiB、ZIP 解压总量 2GiB、失败暂存保留 72 小时;生产暂存盘通过 `AIHR_UPLOAD_STAGING` 指定,默认可用空间健康门禁为 10GiB。零片段媒体不再记为完成或永久“等待解析”,而是保留为可重试失败;管理端可从原 OSS 文件重新入队,无需用户重复上传;不提供浏览器目录选择或服务端目录导入入口。约 600 名用户不等于 600 并发,峰值、P95、错误率和压测模型仍须另行签认 |
|
||||
| 组织人员同步 | `POST /api/aihr/org/sync` | 从开放组织同步系统的 `/api/open/v1/sync/snapshot` 拉取 `company/department/employee/employee_project_assignment` 快照,分页参数使用 `limit`;员工手机号只落 `person_phone` 用于移动端身份映射,不在组织列表响应暴露;岗位识别 `position/job_title/post/job_name/role/title` 等字段。`dryRun` 必须显式传入 `true`(预检)或 `false`(写入),省略或传 `null` 直接拒绝;默认 `replaceExisting=true`,写入前必须先运行 `{"dryRun":true}`。dry-run 不访问本地快照表、不执行 DDL/写库,返回 `phoneLinked/maskedPhone/suspectText/warnings` 且 `syncedCount=0`。非 dry-run 写入(含 `replaceExisting=false`)遇到脱敏手机号一律默认拒绝,避免空值覆盖本地登录身份;覆盖写入遇到员工被跳过、手机号不完整、疑似乱码或同项目重复关系时同样默认拒绝;`allowPartialReplace=true` 只能在身份字段契约一致且异常逐项确认后使用,不能绕过主体身份漂移或重复成员关系,此时脱敏员工的本地既有有效手机号会被保留而非清空。相同员工可由多条有效项目分配展开为多个项目成员行,唯一约束为 `tenant_id + project_code + ext_party_id`。2026-07-25 生产安全状态:既有快照 3417 行、2938 人在职、3392 个手机号映射;姓名已按稳定 `employee_id` 定向补齐,未执行全量覆盖。当前上游返回 3424 名员工、3398 个脱敏手机号和 1 条重复项目成员关系,优先字段 `employee_number` 仅匹配既有主体 `7/3417`,稳定 `employee_id` 匹配 `3417/3417`;全量覆盖仍只允许 dry-run,日常岗位变化使用下方增量接口。 |
|
||||
| 组织人员增量同步 | `POST /api/aihr/org/sync-changes` | 主动拉取上游 `/sync/changes?resource_type=employee`,即使事件没有进入 outbox、`changed_fields` 为空,也会按 `resource_id` 回源 `/employees/{id}`,并结合任职快照只替换受影响员工。主体固定使用稳定 `employee.id`;上游只返回脱敏手机号时保留本地既有有效手机号,上游显式清空手机号时同步清除本地值(对应移动端登录身份失效),手机号字段整体缺失则拒绝写入;范围字段明确不一致视为迁出,写入时删除该员工本地旧记录,范围字段缺失则保守跳过不删。任职快照失败、资源 ID 不一致或项目关系重复时拒绝写入。首次调用必须传 `sinceTime`,后续可传响应的 `nextCursor`;仍须先 `dryRun=true` 再以相同起点执行 `dryRun=false`,且只处理当前租户有效组织绑定范围。 |
|
||||
| 移动端手机号登录 | `GET /resource/sms/code`、`POST /auth/mobile/sms-login` | 已复用 sms4j 阿里云配置 `config1` 和 RuoYi `sms` 授权策略;移动专用接口固定服务端默认租户,客户端不传也不能选择 `tenantId`。dev 默认 `aihr.sms.verification-enabled=false`,移动 APP 客户端可只提交手机号,便于本地自动化;只有同时设置后端 `AIHR_SMS_VERIFICATION_ENABLED=true` 与前端 `VITE_SMS_VERIFICATION_ENABLED=true` 才恢复验证码控件和校验。启用后,验证码按“默认租户 + 手机号”隔离,并在手机号粒度的分布式锁内完成校验:仅匹配成功才消费,输错不会作废原验证码。生产默认保持验证码校验开启。移动端令牌只关联 `app_user`;若同一手机号存在任何后台/系统账号,一律拒绝登录;手机号完全不存在时才自动注册 `app_user`。固定码仍仅用于显式开启验证后的联调;生产固定码必须同时设置 `AIHR_SMS_DEV_FIXED_CODE` 与 `AIHR_SMS_PROD_FIXED_CODE_ENABLED=true`。 |
|
||||
@@ -32,8 +32,10 @@
|
||||
| 移动端员工训练与主管复盘闭环 | 员工复用 `POST /api/train/practice/start`、`/turn`、`/finish`,查询 `GET /api/aihr/mobile/practice/history`、`/practice/mistakes`、`/profile`;训练完成后提交 `POST /api/aihr/mobile/practice/satisfaction`;主管查询 `GET /api/aihr/mobile/practice/team`、`/practice/alerts`、`/practice/reviews`、`/practice/reviews/{id}`,标记 `POST /api/aihr/mobile/practice/reviews/{id}/reviewed`,指派 `POST /api/aihr/mobile/practice/assignments` | 员工端登录后带 `Authorization` 与 `clientid` 调用;服务端固定身份和 `mode=mobile` 后才写入 `aihr_practice_session` 并进入员工/主管统计。员工历史、错题、画像、成长进度、晋升证据和满意度均只使用当前认证手机号经服务端验证得到的受控历史别名;后台内容/任务运营只通过独立 `/api/train/practice/**` 契约,不得向 `/api/aihr/mobile/**` 传入外部 ID 读取个人或主管数据。主管 `/practice/team` 的范围只含已验证外部 ID;历史训练或任务若存的是同一员工的旧手机号,只在该手机号能无碰撞规范化到团队外部 ID 时才展示/统计,避免把另一人的外部 ID 误并入团队。管理端 `mode=preview` 仅是运营调试记录,不能伪装成员工训练、满意度、复盘、成长或试点证据。满意度接口只接受本人已完成训练的 1-5 分,意见脱敏后落库,未填写不补默认值。错题本按员工本人聚合低分/红线回合,并关联已有 `retry` assignment,不伪造错题结论。主管 `/practice/team` 在同一项目权限范围内额外返回 `mistakes` 聚合,按场景/归因统计次数、影响人数、平均分和最近发生时间;普通员工返回“无主管权限”。主管接口以后端当前登录手机号先解析为在职组织外部 ID,仅允许岗位为“主管/项目经理”的账号,并按租户和项目范围返回真实成员、全状态训练记录及非 daily 专项。复盘标记只允许首次 `待复盘 -> 已复盘` 创建后续专项,并发重复提交幂等;可带 `incentivePoint` 写入贡献度。每日三题正式只对 `hire_date` 在当前日期前三个月内的在职员工派发,且只会从已发布、已启用、风险审核完成的同岗位场景题库取题;选择时优先补最低未覆盖的成长层/能力项,仅作为训练推荐,不自动调整职级或形成硬性解锁。没有入职日期时不使用训练次数推断,开发 Demo 的旧回退只有在 `dev/local` profile 且由 `aihr.practice.allow-legacy-daily-drill-fallback` 显式开启时生效,生产 profile 强制关闭。 |
|
||||
| 移动端候选人闭环 | 页面拆为 `/pages/candidate/index/index`、`/interview/index`、`/materials/index`、`/progress/index`、`/study/index`;面试复用 `POST /api/recruit/interview/start`、`/answer`、`/finish` 和 `GET /records`;资料 `POST/GET /api/aihr/mobile/candidate/materials`;预习 `POST /api/knowledge/search`;HR 审核 `GET /api/aihr/hr/candidate/materials`、`POST /api/aihr/hr/candidate/materials/{id}/review` | 候选人端登录后带 `Authorization` 与 `clientid` 调用;首页只按当前手机号对应的真实面试记录和最新资料状态分流,不读取公开 home seed。APP 候选人身份以后端登录手机号为准,前端 `candidateId/candidateName` 只作非 APP 场景兼容参数;面试支持文字作答和复用 `/api/ai/asr` 的录音转文字/选音频,`/answer` 可带可选 `answerAudioOssId`,服务端只接受当前候选人名下处于 `staged/bound` 状态的音频并将 `ossId` 写入问题快照,不向客户端暴露原始 OSS URL;`/answer` 与 `/finish` 还会校验当前 APP 手机号与启动会话的候选人 ID 一致,未知或他人会话直接拒绝;面试拉题/评分走真实模型优先;资料写 `sys_oss`/MinIO 和 `aihr_candidate_material`,HR 审核后进度页同步三态;岗前预习查询正式 SOP,不兜前端示例答案 |
|
||||
| 每日题反馈与常见难题 | `POST /api/aihr/mobile/practice/assignments/{id}/feedback`、`GET /api/aihr/mobile/practice/difficulties`、`POST /api/aihr/mobile/practice/difficulties/assign` | 反馈区分题目有用性与答案正确性;仅认证 APP 主管可按其项目范围聚合岗位、时间、次数、人数和均分,并基于难题创建专项。管理端不得调用移动主管接口;后台人工任务只走受角色保护的 `/api/train/practice/assignments/manage/**`。 |
|
||||
| 岗位考试 | 员工 `GET /api/aihr/mobile/exams`、`GET /exams/{id}`、`POST /exams/{id}/submit`;主管 `GET/POST /exams/supervisor`、`GET/PUT /exams/supervisor/{id}`、`POST /exams/supervisor/{id}/publish`、`GET /exams/supervisor/{id}/results` | 主管按项目范围选择真实员工、组卷、发布和查成绩;员工只读本人目标考试。发布和提交接受请求 ID 并保持幂等,不得重复生成成绩或奖励 |
|
||||
| 岗位考试 | 员工 `GET /api/aihr/mobile/exams`、`GET /exams/{id}`、`POST /exams/{id}/submit`;主管 `GET/POST /exams/supervisor`、`GET/PUT /exams/supervisor/{id}`、`POST /exams/supervisor/{id}/publish`、`GET /exams/supervisor/{id}/results`、`POST /exams/supervisor/question-bank/draw` | 主管按项目范围选择真实员工、组卷、发布和查成绩;员工只读本人目标考试。题库只有 `APPROVED + enabled + exam_enabled` 的题目可抽取,抽题请求 ID 会冻结岗位/题型/题数与题目快照,配置变更复用同一 ID 会拒绝;保存试卷时服务端重新加载快照并保存来源题目 ID、版本和 hash,后续题库编辑不改写已发布试卷。发布和提交接受请求 ID 并保持幂等,不得重复生成成绩或奖励。 |
|
||||
| 正式学习中心与任务 | 管理端 `/api/train/practice/onboard-tasks/manage`、`/materials`、`/exams`、`/batch`;员工 `GET /api/aihr/mobile/onboard/tasks`、`POST /api/aihr/mobile/onboard/tasks/{id}/complete` | 管理端按租户、项目、规范岗位和在职外部 ID 派发正式学习任务;材料只允许当前租户 `READY` 附件并保存标题/版本快照,任务支持一次/每日/每周/月度周期、起效时间、截止时间、进度和到期提醒。`MANUAL_CONFIRM` 才能人工确认,`EXAM_PASS` 只能由关联考试通过完成;重复请求 ID 返回逐人 `DUPLICATE`,配置不一致拒绝。员工只读本人已生效任务,原文继续经受保护资源接口鉴权;“每日三题”仍留在练习入口,不混入学习中心主任务列表。 |
|
||||
| 开放问题榜与积分 | 移动端 `/api/aihr/community/questions`、`questions/{id}`、`questions/{id}/answers`、`questions/{id}/best-answer`、`points/me`;后台 `/api/aihr/question-admin/**`、`/api/aihr/incentive-admin/rules` | 问题、答案、最佳答案和奖励全程按租户/身份授权;重复选优不重复入账。奖励只有积分与学习学分,不代表现金或提现 |
|
||||
| 未解决反馈转人工 | `POST /api/aihr/community/questions/from-answer-feedback`,仅提交 `requestId`、`idempotencyKey` | 服务端重读本人 `down` 反馈和查询审计,问题固定进入 `PENDING`;重复请求返回同一问题,不自动公开或奖励,客户端不得提交重构答案、引用或身份 |
|
||||
| 全网 AI | 员工 `GET /api/aihr/web-ai/capabilities`、`POST /api/aihr/web-ai/query`;提供方管理 `/api/aihr/web-search/providers/**` | 与企业知识问答分入口和来源。仅接受公网 HTTPS 提供方,地址或密钥变更后必须重新连接测试;未配置/未启用时返回明确不可用,不生成假答案 |
|
||||
|
||||
## 数字师傅 Agent 接入
|
||||
|
||||
@@ -20,19 +20,29 @@
|
||||
|
||||
客户在 2026-07-17 反馈的主要回退和新增项已经进入当前生产包,包括语音输入与关键内容播报、总结卡图片、全局三级字号、主管学习端、姓名多选与快捷截止日期、每日题轮换和题目反馈、常见难题、开放问题榜与积分、完整岗位考试、全网 AI 独立入口、多租户知识空间管理,以及问师傅短期多轮、追问改写和受控原文件/视频交付。
|
||||
|
||||
当前工作树另有一批 **2026-08-02 已实现并完成本地验证、尚未部署** 的增量:大喇叭 `ALL/TARGET_ONLY` 真正可见性、受控在线查看与动态水印、下载门禁和带原文依据的主题标签;问师傅未解决反馈确认转问题榜;正式学习任务、审核题库随机组卷及考试关联;案例经验“候选→审核→发布→下线”;原生异常恢复回归,以及资料暂存盘容量健康门禁。以下生产结论不包含这批增量,生产仍以本文件第 5 节的已验证发布证据为准。
|
||||
|
||||
完成状态必须分层表达:
|
||||
|
||||
| 层级 | 当前状态 | 证据与边界 |
|
||||
|---|---|---|
|
||||
| 已实现 | 是 | 已有阶段一主功能,公司消息 R1—R3 已实现直通车与公司文件提炼闭环;接口事实见 [API_INTEGRATION.md](API_INTEGRATION.md) |
|
||||
| 本地自动化/API 验证 | 是 | 训练运营定向后端测试 `76` 项;公司消息新增后端 `30` 项、管理端 `2` 项、移动端 `2` 项;管理端/H5 构建通过 |
|
||||
| 本地浏览器/视觉验证 | 部分 | 已检查管理端目录/任务、两轮动态对练、岗位不匹配拦截、直通处理和文件消息;线上已以认证态员工完成公司消息回归。Android 标准基座生产 ASR 已通过,训练完整写入和原生全项验收仍未完成 |
|
||||
| 已部署 | 是 | 2026-07-25 完整包已包含公司消息 R1—R3、训练内容运营、M2 求助事件和租户组织治理;2026-07-29 又发布资料处理媒体恢复的 schema、管理端和后端,移动 H5 未重发 |
|
||||
| 已实现 | 是 | 已有阶段一主功能;当前工作树另实现大喇叭投放控制、反馈转人工、正式学习任务/随机组卷、案例经验治理、原生异常恢复和上传容量门禁;接口事实见 [API_INTEGRATION.md](API_INTEGRATION.md) |
|
||||
| 本地自动化/API 验证 | 是 | 当前工作树管理端生产构建、移动端类型检查和 `216/216` 单测通过;后端 Surefire 共 `107` 份报告、`838` 项测试,失败/错误/跳过均为 `0`;迁移静态清单通过,Docker/MySQL 幂等执行未完成 |
|
||||
| 本地浏览器/视觉验证 | 部分 | `390×844` 已实际点击员工“今日/练/问”、大喇叭登录门禁和直通车登录门禁,无横向溢出或重叠;管理端认证后的案例发布弹窗因后端/MySQL 未运行而未验证。既有生产公司消息回归和 Android ASR 证据不外推到本批增量 |
|
||||
| 已部署 | 部分 | 2026-07-25 至 2026-07-31 的既有生产基线已部署;当前工作树的四个 `aihr_20260802_*` 迁移及对应后端、管理端和移动端增量均未部署 |
|
||||
| 生产基础验证 | 是 | 服务 `active`;根站、租户接口和移动首页 API 正常;媒体重试列/索引契约通过,4 个历史零片段任务均恢复为已完成且有片段/向量。当前未执行包含移动 H5 的完整包匹配 |
|
||||
| 生产完整业务验收 | 部分 | 公司消息已完成认证态全员文件消息和直通车闭环,单台 Android 标准基座已完成生产 ASR;训练写入、主管复盘、定向人群正反例、正式处理人绑定、其他真机媒体与严格试点窗口仍未完成 |
|
||||
|
||||
“已部署”不等于“正式试点通过”。当前可以确认生产包和基础运行状态,不能把未执行的正式账号、真机和业务窗口验收写成已完成。
|
||||
|
||||
### 2026-08-02 当前工作树未发布增量
|
||||
|
||||
- 大喇叭:`TARGET_ONLY` 冻结目标收件人并在所有读取链路执行同一可见性校验;在线查看、下载策略、主题标签和文件访问审计由正式迁移补齐。下载副本按文件格式加水印仍未实现,动态页面水印不得宣传为防泄漏。
|
||||
- 问题榜与学习:本人 `down` 反馈可经再次确认创建待审核问题;学习任务保存材料版本、周期和考试完成规则,随机组卷只使用审核启用题库并冻结题目来源。正式题库内容和任务规则仍须业务审核。
|
||||
- 经验治理:案例审核与正式发布拆分,只有来源授权、已脱敏、适用岗位、版本、负责人和生效期完整的 `PUBLISHED` 经验才向员工开放;下线立即停止召回。
|
||||
- 运行门禁:资料暂存盘默认要求至少 10GiB 可用空间,生产 HTTP 请求启用 P50/P95/P99 指标;约 600 名用户不是 600 并发,压测模型和通过阈值仍待业务、实施和运维签认。
|
||||
- 发布边界:四个正式迁移已纳入 Runbook;本地 Docker 未运行,未执行 MySQL 首次/重复迁移、完整后端认证 API、签名 APK、真机或生产验证。
|
||||
|
||||
### 2026-07-29 资料处理媒体恢复发布边界
|
||||
|
||||
历史图片/视频在视觉模型不接受原始分辨率/编码,或模型、ASR、关键帧链路没有返回可检索文字时,旧逻辑会留下状态 0、片段 0 的附件,页面长期显示“等待解析”,却没有从原件重新入队的入口。当前实现先对图片纠正方向、缩放和重编码;异步队列只有生成至少一个片段才进入完成态,零片段明确保持可重试失败。管理端可调用 `POST /api/knowledge/doc/processing-tasks/{attachmentId}/retry`,服务端按当前租户从原 OSS 对象重新暂存,通过附件状态 CAS 防止重复入队,并用 `source_attach_id` 关联新队列条目。
|
||||
@@ -80,15 +90,18 @@
|
||||
| 问师傅语音与播报 | 录音、选择音频、ASR、TTS/设备语音降级恢复;答案、总结卡、每日题、点评等关键内容可播报 | 生产短音频 ASR 已切换为 `dashscope/qwen3-asr-flash`,并在一台 Android HBuilderX 标准基座完成“按住说话”请求;自定义基座权限、弱网、方言、多机型和完整播报仍未验收 |
|
||||
| 问师傅连续对话与资料 | 认证用户短期会话保留 30 分钟/最新 6 轮,追问改写并路由 `QA/FILE/VIDEO/DATA_TOOL`;原文件/视频只从当前命中且实时授权的附件交付,无资源不造假链接 | 公司文件消息的认证下载与追问已生产验证;一般知识命中文件/视频的真机下载仍待复验 |
|
||||
| 问页面有效会话区与消息追问 | 会话开始后收起占位辅助区;大喇叭详情仅以消息 ID 受控进入短会话,消息/知识回答不伪造待办 | 生产认证态发布—阅读—文件追问已验证;390×844 最终截图和真机体验仍待补 |
|
||||
| 银城大喇叭 | 全员/定向、必读、未读/已读、发布/撤回、单文件异步提炼、摘要、受控下载和文件追问已部署 | 全员文件消息闭环已生产认证验证,测试消息已撤回;仍不含修订、补推和外部强触达,定向正反例待补 |
|
||||
| 银城大喇叭 | 生产已有全员公开、定向提醒、必读、单文件提炼和受控追问;当前工作树新增 `TARGET_ONLY` 真正可见性、受控在线查看/动态水印、下载门禁和带依据主题标签 | 全员文件消息闭环已生产认证验证;当前工作树增量未部署,目标可见性正反例、在线查看审计和禁止下载仍待迁移后验证;下载副本水印、修订、补推和外部强触达仍不包含 |
|
||||
| 员工直通车 | 已部署高管、财务、人力、审计、运营五个点对点频道,业务匿名、分角色收件和一次正式回复 | 生产已验证员工提交—审计处理—员工查看;五类角色已建,真实处理人员仍须按业务名单绑定 |
|
||||
| 图片/视频与总结卡图片 | 问师傅附件仅用于本次现场分析;总结卡可下载 PNG | 生产包已部署;iOS/Android H5 下载和相册/文件权限未复验 |
|
||||
| 录音归属、提交无反馈、筛选错位 | 账号/页面代次隔离、旧请求回写保护、明确加载/失败状态和窄屏布局已修 | 本地双账号/交互测试通过;生产认证态未重放 |
|
||||
| 每日题变化与题目反馈 | 五岗位题库按日期、岗位和员工身份轮换;每日题/专项支持有用/无用反馈 | 生产 schema 和包已部署;正式题库内容审核与业务样本待补 |
|
||||
| 常见难题与一键派专项 | 管理端按岗位、时间、次数、人数、均分排序并可生成专项 | 生产页面已打开复核;正式团队样本待补 |
|
||||
| 指派姓名、多选、快捷日期 | 项目内在职人员姓名选择,最多 100 人,四档快捷日期,幂等批量提交和逐人结果 | 本地真实 API 已验证;生产大团队、时区边界和权限正反例待补 |
|
||||
| 开放问题榜与奖励 | 提问、回答、审核、最佳答案、积分规则和积分/学习学分双账户已实现;重复选优不重复发奖 | 生产页面/schema 已验证;正式运营规则和认证写链路待验收;不是现金、不可提现 |
|
||||
| 岗位入职考试 | 主管选择岗位/项目/员工、组卷、发布、截止日期和成绩;员工答题、播报、提交、逐题结果;提交幂等 | 本地发布与 100 分提交/重放通过;生产正式账号未重放 |
|
||||
| 开放问题榜与奖励 | 提问、回答、审核、最佳答案和积分/学习学分已实现;当前工作树新增本人未解决反馈确认转待审核问题,创建和选优均幂等 | 既有生产页面/schema 已验证;反馈转人工增量未部署,正式运营规则和认证写链路仍待验收;不是现金、不可提现 |
|
||||
| 正式学习中心 | 当前工作树支持按人员派发带材料版本、周期、截止时间和完成规则的正式任务,`EXAM_PASS` 与关联考试结果绑定;每日三题保持独立 | 未部署、未执行 MySQL 迁移或正式账号验证;材料、任务规则和提醒内容仍须业务审核,不包含外部强触达 |
|
||||
| 岗位入职考试 | 既有固定试卷、发布、作答和幂等提交保留;当前工作树新增从审核启用题库幂等随机抽题,并在发布时冻结题目来源、答案和解析 | 本地服务测试通过;新增题库/抽题迁移未在 MySQL 执行,生产正式账号未重放 |
|
||||
| 案例经验治理 | 当前工作树将候选、业务审核、正式发布和下线拆分;员工仅可读取当前生效的 `PUBLISHED` 经验 | 未部署、未执行迁移或正式内容审核;不能用模型分数、投稿审核或测试数据冒充正式经验资产 |
|
||||
| 资料容量门禁 | 当前工作树新增暂存盘可写/可用空间健康指标,默认门槛 10GiB,并开启生产 HTTP P50/P95/P99 指标 | 只完成本地单测和文档契约;峰值并发、流量模型、P95 和错误率目标未签认,未做隔离环境压测 |
|
||||
| 问 AI(全网) | 与企业问师傅分入口、接口、来源和提示;只允许已测试启用的公网 HTTPS 提供方 | 管理页已生产打开;未配置正式提供方密钥时明确不可用,不生成假答案 |
|
||||
| 多租户知识空间 | 空间、授权、调用应用、统一问答、审计、限流和受控数据工具已实现 | 生产页面/schema 已验证;银城/美途正式空间、授权矩阵、令牌和内容迁移仍需业务确认后执行 |
|
||||
|
||||
|
||||
@@ -108,6 +108,7 @@ mysql --default-character-set=utf8mb4 "$DB_NAME" < backend/script/sql/update/aih
|
||||
mysql --default-character-set=utf8mb4 "$DB_NAME" < backend/script/sql/update/aihr_20260714_practice_evidence_mysql8.sql
|
||||
mysql --default-character-set=utf8mb4 "$DB_NAME" < backend/script/sql/update/aihr_20260714_case_media_mysql8.sql
|
||||
mysql --default-character-set=utf8mb4 "$DB_NAME" < backend/script/sql/update/aihr_20260714_case_learning_mysql8.sql
|
||||
mysql --default-character-set=utf8mb4 "$DB_NAME" < backend/script/sql/update/aihr_20260802_case_experience_governance_mysql8.sql
|
||||
mysql --default-character-set=utf8mb4 "$DB_NAME" < backend/script/sql/update/aihr_20260714_practice_five_dimensions_mysql8.sql
|
||||
mysql --default-character-set=utf8mb4 "$DB_NAME" < backend/script/sql/update/aihr_20260715_practice_session_evidence_mysql8.sql
|
||||
mysql --default-character-set=utf8mb4 "$DB_NAME" < backend/script/sql/update/aihr_20260723_practice_m2_help_event_mysql8.sql
|
||||
@@ -124,6 +125,7 @@ mysql --default-character-set=utf8mb4 "$DB_NAME" < backend/script/sql/update/aih
|
||||
mysql --default-character-set=utf8mb4 "$DB_NAME" < backend/script/sql/update/aihr_20260717_practice_five_position_catalog_mysql8.sql
|
||||
mysql --default-character-set=utf8mb4 "$DB_NAME" < backend/script/sql/update/aihr_20260723_practice_content_operations_mysql8.sql
|
||||
mysql --default-character-set=utf8mb4 "$DB_NAME" < backend/script/sql/update/aihr_20260724_practice_growth_curriculum_mysql8.sql
|
||||
mysql --default-character-set=utf8mb4 "$DB_NAME" < backend/script/sql/update/aihr_20260802_learning_task_exam_bank_mysql8.sql
|
||||
mysql --default-character-set=utf8mb4 "$DB_NAME" < backend/script/sql/update/aihr_20260717_web_ai_question_reward_mysql8.sql
|
||||
mysql --default-character-set=utf8mb4 "$DB_NAME" < backend/script/sql/update/aihr_20260718_knowledge_conversation_mysql8.sql
|
||||
mysql --default-character-set=utf8mb4 "$DB_NAME" < backend/script/sql/update/aihr_20260718_release_collation_compat_mysql8.sql
|
||||
@@ -142,6 +144,7 @@ mysql --default-character-set=utf8mb4 "$DB_NAME" < backend/script/sql/update/aih
|
||||
mysql --default-character-set=utf8mb4 "$DB_NAME" < backend/script/sql/update/aihr_20260724_direct_feedback_mysql8.sql
|
||||
mysql --default-character-set=utf8mb4 "$DB_NAME" < backend/script/sql/update/aihr_20260724_broadcast_attachment_mysql8.sql
|
||||
mysql --default-character-set=utf8mb4 "$DB_NAME" < backend/script/sql/update/aihr_20260725_broadcast_multi_role_insight_mysql8.sql
|
||||
mysql --default-character-set=utf8mb4 "$DB_NAME" < backend/script/sql/update/aihr_20260802_broadcast_delivery_controls_mysql8.sql
|
||||
mysql --default-character-set=utf8mb4 "$DB_NAME" < backend/script/sql/update/aihr_20260722_broadcast_question_context_mysql8.sql
|
||||
mysql --default-character-set=utf8mb4 "$DB_NAME" < backend/script/sql/update/aihr_20260724_agent_orchestration_mysql8.sql
|
||||
mysql --default-character-set=utf8mb4 "$DB_NAME" < backend/script/sql/update/aihr_20260725_deepseek_v4_model_mysql8.sql
|
||||
@@ -152,6 +155,7 @@ mysql --default-character-set=utf8mb4 "$DB_NAME" < backend/script/sql/update/aih
|
||||
mysql --default-character-set=utf8mb4 "$DB_NAME" < backend/script/sql/update/aihr_20260802_data_quality_observability_mysql8.sql
|
||||
mysql --default-character-set=utf8mb4 "$DB_NAME" < backend/script/sql/update/aihr_20260803_data_quality_structure_mysql8.sql
|
||||
mysql --default-character-set=utf8mb4 "$DB_NAME" < backend/script/sql/update/aihr_20260804_data_quality_feedback_loop_mysql8.sql
|
||||
mysql --default-character-set=utf8mb4 "$DB_NAME" < backend/script/sql/update/aihr_20260802_feedback_question_bridge_mysql8.sql
|
||||
mysql --default-character-set=utf8mb4 "$DB_NAME" < backend/script/sql/update/aihr_20260805_knowledge_attachment_immutability_mysql8.sql
|
||||
mysql --default-character-set=utf8mb4 "$DB_NAME" < backend/script/sql/update/aihr_20260806_data_quality_extraction_evidence_mysql8.sql
|
||||
mysql --default-character-set=utf8mb4 "$DB_NAME" < backend/script/sql/update/aihr_20260807_data_quality_semantic_conflict_mysql8.sql
|
||||
@@ -173,6 +177,8 @@ mysql --default-character-set=utf8mb4 "$DB_NAME" < backend/script/sql/aihr_perso
|
||||
|
||||
顺序原因:场景补充依赖三张场景/Rubric 基础表;五维迁移依赖场景和 Rubric;五岗位题库之后的内容运营迁移为每个场景补齐唯一的初始 Rubric、五个稳定评分维度与训练时评分规则快照列,并只修正仍处于待训练状态的旧每日题场景编号,不重写已完成记录。紧随其后的成长目录迁移只在既有场景和会话表上增加岗位/层级/能力项/审核状态与会话快照,以及复盘会话专用的 `growth_confirmation_level/growth_confirmed_by/growth_confirmed_time`;它只允许记录主管对当前会话下一训练层级的确认,不改写原训练快照或人事结论,并补齐/修复派发请求的 `(tenant_id,request_key,ext_party_id)` 唯一键与最近内容过滤索引。它保留既有启停可用性和历史会话,不把迁移结果写成业务内容签字。生产环境不得设置 `AIHR_PRACTICE_RUNTIME_SCHEMA_BOOTSTRAP=true`:应用请求只读校验表、列和关键索引,任何缺失都必须先执行本节正式 SQL,不能由任一用户请求触发补列、补索引或状态回填。岗位/SOP/任务/资格迁移只补正式数据契约,不写业务行,也不代表岗位适用范围、任务规则或资格标准已经获得 HR 确认。住宅 SOP 和 Prompt 迁移只补内置内容,不代表内容已完成业务复核。知识会话迁移只新增短期上下文表,不生成业务对话。排序规则兼容迁移先对齐本批发布表,全量排序规则迁移再统一历史 `aihr_*` 表;两者都读取目标库 `aihr_knowledge_info.tenant_id` 的实际排序规则。服务记忆迁移创建候选、统一采集、兼容项目记录和版本留痕四张表;工作上报幂等迁移随后只补原表列与唯一索引;知识分类迁移新增空间内分类表及附件成员的可空 `category_id`,不迁移、删除或扩大任何空间授权与检索范围;正式知识来源治理迁移只创建附件级权威类型、生命周期、版本、生效期、适用范围和原文件哈希契约,不自动批准任何历史附件。移动端政策问答只使用有效的 `FORMAL_POLICY + APPROVED` 注册项,治理表缺失、来源未批准、已失效、版本或哈希为空时均按无正式依据关闭。银城大喇叭 M0 迁移创建消息、阅读和不可变 v1 快照三表,为已存在消息补一次快照,并补发布请求键/载荷哈希、撤回原因及 `(tenant_id,published_by,publish_request_key)` 唯一约束。紧接着 M1 定向迁移补充必读与目标载荷字段,以及规则快照、命中对象快照两表;它只决定提醒/必读对象,不改变全租户公开频道的可见性。直通车迁移创建点对点反馈表,并给正式租户 `000000` 幂等预置总裁、财务、人力、审计、运营五个处理角色;人员仍须由管理员按职责分配,业务匿名不抹除内部审计身份。公司文件迁移创建异步提炼表并给消息增加可空 `attachment_id`,不迁移或公开已有文件;紧随其后的多岗位解读迁移只在附件表增加生成状态、经引用校验的结构化结果和规则版本,并建立异步队列索引,不回填旧文件、不改变文件 READY 或消息发布状态。随后,消息追问迁移只给短期会话增加可空 `broadcast_message_id`;它不保存消息正文,并用于约束同一会话不能切换公司消息。历史普通会话保持 `NULL`。Agent 迁移只新增最小运行审计表,不保存问题、答案、密钥或模型推理。个人资料迁移最后创建独立 `aihr_personal_*` 表,并从当前租户既有 MinIO 配置派生私有 `personal-minio` 配置;`ruoyi-personal` bucket 必须由受控运维流程创建和验证,不能在文档或日志中输出访问密钥。它们同样对齐目标排序规则,兼容历史生产库与全新 MySQL 8 数据库。
|
||||
|
||||
`aihr_20260802_broadcast_delivery_controls_mysql8.sql` 必须位于公司文件及多岗位解读之后、消息追问上下文之前。它增加 `ALL/TARGET_ONLY` 可见模式、下载控制、带原文依据的主题标签表和文件访问审计表,不自动修改既有消息受众、下载策略或标签。
|
||||
|
||||
## 迁移后只读核验
|
||||
|
||||
执行后只读检查结构和内置内容,不修改业务数据:
|
||||
@@ -189,7 +195,7 @@ WHERE table_schema = DATABASE()
|
||||
'aihr_knowledge_space_grant', 'aihr_knowledge_app', 'aihr_knowledge_app_space', 'aihr_knowledge_category',
|
||||
'aihr_knowledge_query_log', 'aihr_knowledge_admin_audit', 'aihr_knowledge_conversation', 'aihr_agent_run',
|
||||
'aihr_practice_question_feedback',
|
||||
'aihr_onboard_exam', 'aihr_onboard_exam_target', 'aihr_onboard_exam_question',
|
||||
'aihr_onboard_exam', 'aihr_onboard_exam_target', 'aihr_onboard_exam_question', 'aihr_exam_question_draw',
|
||||
'aihr_onboard_exam_attempt', 'aihr_onboard_exam_answer',
|
||||
'aihr_web_search_provider', 'aihr_web_ai_secret', 'aihr_web_ai_query_audit',
|
||||
'aihr_community_question', 'aihr_community_answer',
|
||||
@@ -214,7 +220,7 @@ SELECT table_name, column_name
|
||||
FROM information_schema.columns
|
||||
WHERE table_schema = DATABASE()
|
||||
AND (
|
||||
(table_name = 'aihr_case_record' AND column_name IN ('media_oss_id', 'media_url', 'learning_points', 'supervisor_comment'))
|
||||
(table_name = 'aihr_case_record' AND column_name IN ('media_oss_id', 'media_url', 'learning_points', 'supervisor_comment', 'knowledge_status', 'source_type', 'applicable_positions', 'content_version', 'source_authorized', 'deidentified', 'effective_from', 'effective_to', 'release_owner', 'release_note', 'released_by', 'released_time', 'retire_reason'))
|
||||
OR (table_name = 'aihr_practice_session' AND column_name IN ('dim_task_completion', 'dim_response_timeliness', 'response_latency_ms', 'rubric_code', 'rubric_version', 'rubric_snapshot_json', 'annotations_json', 'review_advice', 'incentive_point', 'satisfaction_score', 'satisfaction_comment', 'position_snapshot', 'project_type_snapshot', 'growth_level', 'competency_code', 'collaboration_positions', 'curriculum_version', 'growth_confirmation_level', 'growth_confirmed_by', 'growth_confirmed_time'))
|
||||
OR (table_name = 'aihr_practice_scenario' AND column_name IN ('content_version', 'content_hash', 'growth_level', 'competency_code', 'collaboration_positions', 'review_status', 'risk_level', 'curriculum_version', 'reviewer', 'reviewer_user_id', 'reviewed_time', 'second_reviewer', 'second_reviewer_user_id', 'second_reviewed_time'))
|
||||
OR (table_name = 'aihr_practice_assignment' AND column_name IN ('score', 'score_mode', 'due_date', 'request_key', 'content_version', 'question_snapshot', 'reference_answer_snapshot', 'content_hash'))
|
||||
@@ -227,7 +233,9 @@ WHERE table_schema = DATABASE()
|
||||
OR (table_name = 'aihr_interview_result' AND column_name IN ('questions_json', 'reviewed_score', 'review_status', 'reviewer', 'review_note', 'reviewed_time'))
|
||||
OR (table_name = 'aihr_position_responsibility' AND column_name IN ('position_code', 'responsibility_text', 'sop_id', 'sop_code'))
|
||||
OR (table_name = 'aihr_sop_applicability' AND column_name IN ('sop_id', 'sop_code', 'project_type', 'industry', 'org_scope'))
|
||||
OR (table_name = 'aihr_onboard_task' AND column_name IN ('ext_party_id', 'position_code', 'task_type', 'status', 'assign_by'))
|
||||
OR (table_name = 'aihr_learning_question' AND column_name IN ('exam_format', 'exam_options_json', 'exam_answers_json', 'exam_explanation', 'exam_enabled', 'review_status', 'review_note', 'reviewed_by', 'reviewed_time'))
|
||||
OR (table_name = 'aihr_onboard_exam_question' AND column_name IN ('source_question_id', 'source_question_code', 'source_content_version', 'source_content_hash'))
|
||||
OR (table_name = 'aihr_onboard_task' AND column_name IN ('ext_party_id', 'position_code', 'task_type', 'status', 'assign_by', 'material_type', 'material_attachment_id', 'material_title', 'material_version', 'progress_percent', 'completion_rule', 'exam_id', 'recurrence_type', 'recurrence_series_key', 'dispatch_request_key'))
|
||||
OR (table_name = 'aihr_qualification_gate' AND column_name IN ('ext_party_id', 'position_code', 'cert_id', 'passed', 'valid_thru'))
|
||||
OR (table_name = 'aihr_work_report' AND column_name IN ('request_key', 'request_hash'))
|
||||
OR (table_name = 'aihr_broadcast_message' AND column_name IN ('publish_request_key', 'publish_request_hash', 'withdraw_reason', 'attachment_id'))
|
||||
@@ -312,6 +320,8 @@ ORDER BY d.dimension_code;
|
||||
|
||||
本批完整发布要求 `release-preflight` 的 `64/64` 必需表与列契约均存在,新增项包括 `aihr_practice_help_event`、`aihr_direct_feedback`、`aihr_broadcast_attachment`、`aihr_broadcast_message.attachment_id` 和 `aihr_agent_run`;资料重试还必须通过 `remote_media_reprocess_contract=1/1`,即 `source_attach_id` 与 `(tenant_id, source_attach_id, id)` 索引同时存在。此前 `57/57`、`62/62` 都只代表较窄的历史发布清单。2026-07-25 生产只读预检已达到 `64/64`,后端 JAR/AIHR 模块与发布源一致,并确认公司文件附件契约 `15/15` 及多岗位解读队列索引存在;这只证明迁移与产物已发布,不替代 Agent、训练或试点业务验收。Agent 审计字段应为 `14/14`,且表中不得出现问题、答案或附件列。工作上报幂等字段为 `2/2`,大喇叭发布/撤回审计字段为 `3/3`,其发布幂等索引为 `0 | tenant_id,published_by,publish_request_key | 0`,M1 必读/目标载荷字段契约为 `2/2`,两张目标表字段契约为 `16/16`,定向规则与对象快照唯一约束分别为 `4/4`、`3/3`,公司文件附件字段和消息绑定字段契约为 `15/15`,并应存在 `(insight_status,status,update_time)` 解读队列索引;公司消息追问会话字段为 `1/1`,工作助手新增字段为 `8/8`,会话证据字段为 `8/8`,专项批量/内容快照字段为 `8/8`,候选资料审核字段为 `2/2`,面试复核字段为 `6/6`,字段查询覆盖所有列,内置 Prompt 数量为 `6`。私有资料配置只应返回 `ruoyi-personal`、私有策略和 `configured` 状态,不显示访问密钥。五个岗位各有 `20` 个场景,`daily/special` 各有 `100` 道题;其中 `14` 个未完成正式审核的高风险场景及其 `28` 道题保持禁用。岗位/SOP/任务/资格表及新记忆表为空是允许的;结构、索引和内置内容通过只证明 schema/seed 与发布产物一致,不证明员工直达反馈、文件提炼、多岗位解读、员工确认记忆、完整个人知识库或严格试点已经完成业务验收。
|
||||
|
||||
新增学习任务/题库迁移后,预检还必须确认 `aihr_exam_question_draw`、题库审核字段、试卷来源快照字段,以及任务材料/周期/幂等字段和唯一索引;这只证明结构可用,不代表题库内容已完成业务审核或正式试点验收。
|
||||
|
||||
## 迁移后应用回归
|
||||
|
||||
1. 重启 `wygj-aihr.service`,确认状态为 `active`。
|
||||
|
||||
+1
-1
@@ -255,7 +255,7 @@ docker compose -f docker-compose.dev.yml stop
|
||||
- 本地组织 seed 带演示手机号;从 `aihr_org_snapshot` 按角色查询测试账号,分别验证员工端岗位识别和主管端项目范围,不在文档保存具体号码
|
||||
- 生产移动端回归同样由执行者从 `aihr_org_snapshot` 只读选择账号,不等待人工提供手机号:限定目标岗位、`employment_status='active'`、11 位 `person_phone`,并确认手机号与 `ext_party_id` 双向唯一。账号值只注入当前浏览器进程,不输出到终端、截图、报告或仓库。试点固定码开启时,登录顺序仍为先请求 `/resource/sms/code`、再提交固定码;直接提交固定码会得到 `Captcha invalid`,不应误判为账号或功能故障。
|
||||
- SOP 知识库支持 `.txt/.md/.markdown/.pdf/.doc/.docx/.xls/.xlsx/.ppt/.pptx` 上传到 MinIO 后解析入库,接口为 `POST /api/knowledge/doc/upload`,单文件上限 100MB;管理端上传请求单独放宽到 180s,PDF 解析/归类/向量化较慢时不要改全局 axios 超时。
|
||||
- 资料处理中心异步接口支持文档、图片、视频和 `.zip` 单文件 ≤500MB;生产 Spring/Undertow multipart 配置必须保持 `max-file-size=500MB`、`max-request-size=520MB`(源文件 `backend/ruoyi-admin/src/main/resources/application-prod.yml`,线上外置 `/opt/wygj/config/application-prod.yml`),`TikaKnowledgeDocumentParser.MAX_INPUT_BYTES` 必须同步保持 500MiB,修改后重启 `wygj-aihr.service`。ZIP 最多 1000 个子文件、单个受支持子文件 ≤500MB、解压总量 ≤2GB,不支持嵌套 ZIP。同步 SOP 上传和公司文件仍按各自的 100MB 契约执行。
|
||||
- 资料处理中心异步接口支持文档、图片、视频和 `.zip` 单文件 ≤500MB;生产 Spring/Undertow multipart 配置必须保持 `max-file-size=500MB`、`max-request-size=520MB`(源文件 `backend/ruoyi-admin/src/main/resources/application-prod.yml`,线上外置 `/opt/wygj/config/application-prod.yml`),`TikaKnowledgeDocumentParser.MAX_INPUT_BYTES` 必须同步保持 500MiB,修改后重启 `wygj-aihr.service`。ZIP 最多 1000 个子文件、单个受支持子文件 ≤500MB、解压总量 ≤2GB,不支持嵌套 ZIP。同步 SOP 上传和公司文件仍按各自的 100MB 契约执行。异步 worker 单实例并发固定为 2;暂存盘通过 `AIHR_UPLOAD_STAGING` 配置,`/actuator/health/aihrUploadCapacity` 默认以 10GiB 可用空间为健康门禁,低磁盘必须先扩容,完整口径见 `docs/KNOWLEDGE_PLATFORM_RUNBOOK.md`。
|
||||
- 视频(`.mp4/.mov/.avi/.mkv/.webm/.m4v`,≤500MB、≤60 分钟)只走资料处理中心批量导入(异步队列):ffmpeg 抽音轨分段调 asr 转写 + 抽关键帧调 vision 提取画面文字,合并后归类切片入库,片段带 `[mm:ss]` 时间戳;**依赖服务器安装 ffmpeg/ffprobe**(macOS `brew install ffmpeg`,Linux `apt install ffmpeg`)
|
||||
- 服务端目录导入接口为 `POST /api/knowledge/doc/import-local-task`,只读取导入根目录下的相对目录,后台逐文件复用同一上传解析链路;`POST /api/knowledge/doc/import-tasks/{id}/cancel` 可取消运行中任务;`POST /api/knowledge/doc/import-local` 保留为同步调试接口。这组接口仅供运维/调试,不在资料处理页提供入口。
|
||||
- 启用 `aihr_model_config.category='vector'` 的模型配置后,上传会同步写入片段 embedding,并尽力 upsert 到 Qdrant;模型配置页可查看 Qdrant 维度、点数和片段向量数,并在维度不一致时重建索引;未配置或 Qdrant 不可用时只走 MySQL Fulltext/seed fallback,不影响检索。
|
||||
|
||||
@@ -151,7 +151,22 @@ order by id desc;
|
||||
|
||||
队列状态固定为 `0=待处理、1=处理中、2=完成、3=失败`。成功条件是最新队列条目为 2、附件为 2、片段数大于 0,并按当前向量配置确认相应片段已向量化;零片段必须保持失败态,不能显示为完成。普通失败条目只有在 72 小时暂存保留期内才可调用 `POST /api/knowledge/doc/upload-items/{id}/retry`;暂存已清理时应重新上传。历史附件重试不依赖旧暂存文件,而是从 OSS 原件重新入队。
|
||||
|
||||
### 5.3 细粒度 SOP 迁入 `yc_property_sop`
|
||||
### 5.3 RC-007 容量与存储门禁
|
||||
|
||||
当前资料加工 worker 固定为单实例并发 2,单文件上限 500MiB,ZIP 解压总量上限 2GiB,失败暂存保留 72 小时。默认暂存目录为 `./.data/staging`,生产必须通过 `AIHR_UPLOAD_STAGING` 或 `aihr.upload.staging` 指向独立、可监控的持久磁盘,不得依赖系统临时目录。`aihrUploadCapacity` 健康组件默认要求可用空间不少于 10GiB;可用 `AIHR_UPLOAD_MINIMUM_FREE_BYTES` 调整,但只能在完成容量测算后修改。
|
||||
|
||||
发布前先只读检查:
|
||||
|
||||
```bash
|
||||
curl -fsS https://<backend-host>/actuator/health/aihrUploadCapacity
|
||||
curl -fsS https://<backend-host>/actuator/metrics/http.server.requests
|
||||
```
|
||||
|
||||
健康详情必须满足 `status=UP`、`stagingWritable=true`、`capacityReady=true`,并核对 `workerConcurrency=2`、`maxFileBytes=524288000`、`maxArchiveUnpackedBytes=2147483648`。生产配置已为 `http.server.requests` 开启 P50/P95/P99 分位统计;错误率按同一指标的 `status/outcome` 标签计算。出现低磁盘健康失败时先扩容或迁移暂存盘,不得通过降低门禁值冒充恢复。
|
||||
|
||||
录音中的约 600 名生活管家只是用户规模,不是 600 并发。压测前由业务、实施和运维另行签认峰值在线人数、并发到达率、业务流量占比、文件大小分布、弱网条件、P95 目标、错误率目标和持续时长;未签认前只可验证健康门禁和现有并发上限,不得宣称容量验收通过。压测必须使用隔离环境和脱敏/合成数据,不对生产执行写压测。
|
||||
|
||||
### 5.4 细粒度 SOP 迁入 `yc_property_sop`
|
||||
|
||||
现有“投诉处理 SOP、催缴沟通 SOP、报修跟进 SOP”等 `legacy_*` 空间不直接改名。按以下顺序执行:
|
||||
|
||||
|
||||
@@ -13,12 +13,18 @@
|
||||
| 员工正例 | 1 | 当前项目在职、可完成训练与每日题 |
|
||||
| 主管正例 | 1 | 当前项目带教范围、可查看复盘并派发专项 |
|
||||
| 员工越权反例 | 1 | 无主管权限,用于验证主管页与写接口均被拒绝 |
|
||||
| 真机体验样本 | iOS/Android 各 1 | 已获测试同意,用于媒体、下载、字号与读屏验证 |
|
||||
| Android App-Plus 真机样本 | 2 | 一台 Android 10 基线机型和一台当前主流机型,均安装本批同一签名 APK |
|
||||
| iOS App-Plus 真机样本 | 0 或 2 | 仅当本批明确包含 iOS 原生包时启用;不得拿 H5 Safari 代替原生包验收 |
|
||||
| H5 兼容样本 | 0 或 2 | 仅当本批包含 H5 发布时启用;iOS Safari 与 Android Chrome 各一台,不与 App-Plus 结果合并 |
|
||||
|
||||
试点批次:`<项目名称>`
|
||||
|
||||
统计窗口:`<YYYY-MM-DD>` 至 `<YYYY-MM-DD>`
|
||||
|
||||
本批交付面:`Android App-Plus / iOS App-Plus / H5`(逐项勾选;未勾选的交付面不得写入通过结论)
|
||||
|
||||
版本证据:`APK version/versionCode/SHA-256`、`后端 JAR SHA-256`、`管理端/H5 构建哈希`、`schema 预检结果`、`回滚点`
|
||||
|
||||
内容负责人 / 业务审核人 / 试点负责人:`<在受控系统登记>`
|
||||
|
||||
---
|
||||
@@ -79,16 +85,24 @@
|
||||
|
||||
## 三、P0-2 真机能力验收
|
||||
|
||||
**设备要求**:
|
||||
- iOS真机(iPhone,iOS 15+,微信内置浏览器 + Safari各一台)
|
||||
- Android真机(Android 10+,微信内置浏览器 + Chrome各一台)
|
||||
**设备矩阵**:
|
||||
- 当前 Android 正式试点:同一签名 APK 至少覆盖 Android 10 基线机型和一台当前主流机型;所有 App-Plus 项目均在这两台设备执行。
|
||||
- 本批包含 iOS 原生包时:同一签名包至少覆盖 iOS 15 基线机型和一台当前刘海或灵动岛机型;结果独立记录。
|
||||
- 本批包含 H5 时:另用 iOS Safari 和 Android Chrome 各一台执行 H5 兼容验收;微信内置浏览器仅在业务明确要求时加入,不代替系统浏览器或原生包。
|
||||
- 每条证据必须记录交付面、设备型号、系统版本、应用版本和结果;不得把一个交付面的成功外推到另一个交付面。
|
||||
|
||||
### 语音输入与播报
|
||||
- [ ] **真机体验样本** → 问师傅页 → 点击麦克风图标 → 允许麦克风权限
|
||||
- [ ] 说话5秒("今天客户投诉了停车费问题怎么处理") → 停止录音 → 文本框自动填入识别后的文字
|
||||
- [ ] 点击"搜索" → 等待回答 → 点击"播报"按钮 → 听到TTS语音播报回答内容
|
||||
- [ ] 首次拒绝麦克风权限 → 页面明确提示可再次授权或改选音频,不启动录音;再次点击仍可申请权限
|
||||
- [ ] 选择“以后不再询问”后再次点击麦克风 → 页面明确引导到系统设置,不反复弹出无效授权框
|
||||
- [ ] 真机验证降级:飞行模式 → 点击"播报" → 检查是否降级到浏览器`speechSynthesis`(iOS Safari可能无声,属已知限制)
|
||||
- [ ] 真机验证录音兜底:长按5秒说话但ASR接口超时 → 检查是否显示"选择音频文件"兜底选项
|
||||
- [ ] 系统音频/附件选择器取消 → 页面安静回到可操作状态,不显示失败;选择器权限或读取失败 → 显示稳定中文错误并可重试
|
||||
- [ ] 弱网或接口超时 → 当前请求终止、loading 结束、原输入保留;恢复网络后可重试且不重复提交
|
||||
- [ ] 会话过期返回 401 → 清理旧登录态并回到登录页;完成 OTP 重登后返回原业务页,403 业务拒绝不得误退出
|
||||
- [ ] 录音、转写、播报或附件选择期间切到后台再回前台 → 不残留播放/录音/loading;系统权限页和文件选择器返回时不得误取消当前选择
|
||||
|
||||
### 图片/视频上传
|
||||
- [ ] **真机体验样本** → 问师傅页 → 点击"上传图片"图标 → 从相册选择一张图片(≤10MB)
|
||||
@@ -157,12 +171,11 @@
|
||||
- [ ] 员工越权访问主管功能被拦截,3个反例全部拦截成功
|
||||
|
||||
### P0-2 真机能力
|
||||
- [ ] 语音录音+ASR转文字在iOS/Android微信+浏览器各通过1次
|
||||
- [ ] 语音播报+降级在iOS/Android各通过1次
|
||||
- [ ] 图片/视频上传在iOS/Android各通过1次
|
||||
- [ ] 总结卡下载在iOS/Android各保存成功1次
|
||||
- [ ] 全局字号三档在iOS/Android各验证持久化+全局覆盖
|
||||
- [ ] 读屏/键盘导航在iOS VoiceOver + Android TalkBack各通过1次
|
||||
- [ ] Android App-Plus 两台设备均完成语音录音、ASR、TTS、图片/视频/文档、受控下载、字号持久化和前后台恢复
|
||||
- [ ] Android TalkBack 和外接键盘至少在一台设备完成核心路径验证
|
||||
- [ ] 若本批包含 iOS App-Plus,两台 iOS 设备执行同一能力矩阵,并另行完成 VoiceOver 验收
|
||||
- [ ] 若本批包含 H5,iOS Safari 与 Android Chrome 各完成一次同等 H5 能力矩阵;结果不得与 App-Plus 合并
|
||||
- [ ] 文件和媒体失败时只允许重新鉴权后重试或回到受控在线内容,不产生可复制、长期复用的原文件链接
|
||||
|
||||
### P0-3 严格试点窗口
|
||||
- [ ] 窗口结束时,完成率≥80%(≥16人完成≥10次训练)
|
||||
@@ -177,7 +190,7 @@
|
||||
| 相对时间 | 里程碑 | 责任人 | 状态 |
|
||||
|---|---|---|---|
|
||||
| 窗口开始前 | P0-1权限正反例全部验证 | 开发+测试 | 待执行 |
|
||||
| 窗口开始前 | P0-2真机能力验证(iOS+Android各2台) | 测试 | 待执行 |
|
||||
| 窗口开始前 | P0-2 按本批交付面执行设备矩阵;Android App-Plus 固定 2 台 | 测试 | 待执行 |
|
||||
| 窗口中点 | P0-3中期检查(完成率/校准样本) | 项目经理 | 待执行 |
|
||||
| 窗口结束前 5 天 | P0-3末期检查(完成率冲刺) | 主管团队 | 待执行 |
|
||||
| 窗口结束日 | 统计最终数据 | 项目经理 | 待执行 |
|
||||
@@ -200,7 +213,7 @@
|
||||
- **应急预案**:
|
||||
- 语音失败 → 检查ASR/TTS接口配额,切换备用提供方或降级到纯文本
|
||||
- 上传失败 → 检查OSS配额,临时扩容或限制单日上传次数
|
||||
- 下载失败 → 降级为"复制链接"分享,用户自行浏览器打开下载
|
||||
- 下载失败 → 重新鉴权后重试或回到受控在线内容;不得复制原文件地址、OSS 地址或长期下载链接
|
||||
- 字号/读屏失败 → 记录为P1缺陷,不阻塞试点(可访问性为增强项)
|
||||
|
||||
### 风险3:越权拦截失效
|
||||
|
||||
+1
-1
@@ -62,7 +62,7 @@
|
||||
| [帮道8月1日Android安装包测试版任务计划-20260727.md](帮道8月1日Android安装包测试版任务计划-20260727.md)([Word 同步版](帮道8月1日Android安装包测试版任务计划-20260727.docx)) | 2026-08-01 Android 受控内测 APK 的冻结范围、P0 任务、倒排日程、真机门禁、Go/No-Go 与后续边界;Markdown 为事实源 |
|
||||
| [AI陪练二期开发推进计划.md](AI陪练二期开发推进计划.md) | 2026-07-11 历史推进记录;保留 M0-M5 的工程追溯,不再作为当前施工范围 |
|
||||
| [员工端版本功能对比与功能对齐清单-20260717.md](员工端版本功能对比与功能对齐清单-20260717.md) | 旧版/历史需求/当前实现/生产验收的版本对比,以及 2026-07-17 客户反馈逐项处理结果 |
|
||||
| [BRD_IMPLEMENTATION_AUDIT.md](BRD_IMPLEMENTATION_AUDIT.md) | 当前生产基线、三端输入/BRD 匹配、客户反馈完成分层和正式试点剩余硬门槛;旧发布流水从当前真相源移除 |
|
||||
| [BRD_IMPLEMENTATION_AUDIT.md](BRD_IMPLEMENTATION_AUDIT.md) | 当前生产基线、尚未部署的本地增量、三端输入/BRD 匹配、客户反馈完成分层和正式试点剩余硬门槛;旧发布流水从当前真相源移除 |
|
||||
| [BRD_PRODUCTION_MIGRATION_RUNBOOK.md](BRD_PRODUCTION_MIGRATION_RUNBOOK.md) | AIHR BRD 生产 schema/内置内容迁移顺序、结构核验、当前运行基线、单项热修复回滚和发布后回归口径 |
|
||||
| [20260708/uni-app用户侧前端重建计划.md](20260708/uni-app用户侧前端重建计划.md) | `mobile-uni/` 重建阶段留档;当前完成状态以 BRD 审查和版本功能对比为准 |
|
||||
| [20260708/数字师傅学练问报整合方案.md](20260708/数字师傅学练问报整合方案.md) | 产品定义(学练问报+问题榜+学分晋升+个人 AI 助理)及 v1.8 “问”模块 Agent 关联与实施边界 |
|
||||
|
||||
@@ -86,7 +86,7 @@ flowchart LR
|
||||
|---|---|---|
|
||||
| 正式制度 | 普通知识接入后,另由 `aihr_knowledge_source_governance` 登记 `APPROVED`、版本、生效/失效日期;只有识别为正式制度意图时附加过滤 | 特殊意图受控;普通检索仍可能命中相同片段。证据:`backend/script/sql/update/aihr_20260730_formal_knowledge_source_governance_mysql8.sql:5`;`backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/knowledge/service/AihrKnowledgeQueryService.java:662` |
|
||||
| 个人知识 | `POST /api/aihr/personal-assistant/items/text|file|url` -> 私有 item/fragment;HR/超级管理员审核发布 -> 脱敏后的 fragment 直接复制到企业知识表 | 是,审批后直接写企业表,但绕过通用附件/版本/质量/重新解析链。证据:`backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/personal/controller/PersonalAssistantController.java:89`、`:94`、`:103`;`backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/personal/service/PersonalPublishService.java:107`、`:232` |
|
||||
| 案例录音 | `/api/knowledge/case/upload` -> OSS + ASR -> `aihr_case_record`;`organize` 用模型或本地兜底总结;`curate` 直接标“已入库”;主管 `review` 只是事后点评 | 是案例库可见数据,但没有前置发布审批。证据:`backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrCaseController.java:53`、`:61`、`:69`、`:108`;`backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrCaseService.java:96`、`:107`、`:127` |
|
||||
| 案例录音 | `/api/knowledge/case/upload` -> OSS + ASR -> `aihr_case_record`;`organize` 用模型或本地兜底总结;`curate` 只进入候选池;`review` 完成业务审核;`publish` 在来源授权、脱敏、适用岗位、版本和负责人齐全后才标记 `knowledge_status=PUBLISHED` | 员工列表/详情只读取 `knowledge_status=PUBLISHED`,审核通过不会自动进入正式知识库。迁移:`backend/script/sql/update/aihr_20260802_case_experience_governance_mysql8.sql`;服务:`backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrCaseService.java` |
|
||||
| AI 考试题 | `AihrExamService.generateDraft` 从租户片段抽取 grounding,模型/规则生成草稿;主管创建并发布考试 | 不直接自动发布,但 grounding 未要求来源批准、附件有效或授权空间。证据:`backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/learning/AihrExamService.java:185`、`:482`、`:541` |
|
||||
| 陪练 | 用户回答、音频、LLM/seed 评分写 session/assignment;可选 calibration 保存人工校准 | 不写企业知识表,但属于运行/评测数据,当前缺少统一 synthetic、置信度、模型版本和数据用途隔离。证据:`backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrPracticeSeedService.java:1513`;`backend/script/sql/aihr_practice_mysql8.sql:27`、`:168` |
|
||||
| 陪练场景 | 场景有草稿、待业务审核、已发布、已下线;高风险需不同用户双审并校验内容版本/哈希 | 局部强控制。证据:`backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrPracticeSeedService.java:599`、`:675`、`:696`;`backend/script/sql/aihr_practice_mysql8.sql:184` |
|
||||
|
||||
Reference in New Issue
Block a user