feat: govern knowledge assets and source citations
This commit is contained in:
+74
-3
@@ -26,7 +26,7 @@
|
||||
| 资料处理 `/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 文件重新入队,无需用户重复上传;不提供浏览器目录选择或服务端目录导入入口 |
|
||||
| 组织人员同步 | `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`;验证码按“默认租户 + 手机号”隔离。校验在手机号粒度的分布式锁内完成:仅匹配成功才消费,输错不会作废原验证码。移动端令牌只关联 `app_user`;若同一手机号存在任何后台/系统账号(即使同时存在 `app_user`),一律拒绝登录而不复用或并置身份;手机号完全不存在时才自动注册 `app_user`。`aihr.sms.dev-fixed-code` 非空时不真发短信、验证码固定(dev 默认 `123456`)。prod 默认关闭,试点期只有同时设置 `AIHR_SMS_DEV_FIXED_CODE` 与 `AIHR_SMS_PROD_FIXED_CODE_ENABLED=true` 才启用固定码。 |
|
||||
| 移动端手机号登录 | `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`。 |
|
||||
| 用户侧三端首页 `mobile-uni` hash 路由;旧 `/h5/user`、`/h5/candidate`、`/h5/supervisor` 兼容重定向 | `GET /api/aihr/mobile/home/{role}` | 未登录请求只返回不读取租户业务统计的公开首屏 seed;已登录移动端请求自动携带 `Authorization/clientid`,才返回员工/主管真实统计;移动端本地 fallback 保演示 |
|
||||
| 移动端登录后角色识别 | `GET /api/aihr/mobile/me` | 认证后仅以手机号精确查询 `person_phone`(`activeByMobilePhone`,不使用组织模糊搜索);`position_level` 为“主管/项目经理”时进入主管端,否则进入员工端。响应返回去重后的 `projects[]` 供页面按项目名称选择,不要求用户输入或记忆编码;同一人员在多个项目的快照行按 `tenant_id + project_code + ext_party_id` 保留。登录身份缺失、组织查询异常或没有有效在职主体时一律明确失败关闭,不再静默回退员工端。 |
|
||||
| 移动端员工训练与主管复盘闭环 | 员工复用 `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 强制关闭。 |
|
||||
@@ -93,7 +93,7 @@ curl -fsS -X POST "$API_BASE/api/aihr/agent/actions/<draftId>/dismiss" \
|
||||
|
||||
当前管理端 AI 面试和案例沉淀已改为真实模型/ASR 优先;移动端首页和部分演示态数据仍保留 fallback。知识库、模型能力、文档解析、RAG、chat 按 [ruoyi-ai 能力分片迁移计划](RUOYI_AI_INCREMENTAL_MIGRATION.md) 逐片引入;知识库 DDL 与住宅类 SOP seed 在 `backend/script/sql/aihr_knowledge_mysql8.sql`,模型 DDL 在 `backend/script/sql/aihr_model_mysql8.sql`,训练记录 DDL 在 `backend/script/sql/aihr_practice_mysql8.sql`,AI 面试结果 DDL 在 `backend/script/sql/aihr_interview_result_mysql8.sql`,候选人资料 DDL 在 `backend/script/sql/aihr_candidate_material_mysql8.sql`,组织人员快照表在 `backend/script/sql/aihr_org_snapshot_mysql8.sql`,本地 reset 带 2 个住宅项目 22 人 seed;配置开放组织同步系统后用 `POST /api/aihr/org/sync` 覆盖为外部快照。
|
||||
|
||||
直接打后端 `/api/**` 通常需要登录后的 `Authorization: Bearer <access_token>`;浏览器内通过已登录前端和 `/dev-api` 代理访问。移动端登录接口为 `POST /auth/mobile/sms-login`,请求 `{ phonenumber, smsCode }`,内部固定使用 app 客户端 `428a8310cd442757ae699df5d894f051` 和 `sms` grant;验证码通过后若手机号不存在,会创建 `app_user`,用户名为手机号,备注为“移动端短信自动注册”。移动端首页接口 `GET /api/aihr/mobile/home/{role}` 仍保留 `@SaIgnore` 以保证真正未登录的首屏可用,匿名分支只返回不读取业务统计的公开数据;已登录请求必须是有效 `app_user`,并按认证手机号校验员工/主管身份后返回真实统计。已登录但身份缺失、后台账号误用、组织查询失败或客户端收到未知角色时均明确失败关闭,不得静默回到公开数据、默认员工端或旧岗位缓存。
|
||||
直接打后端 `/api/**` 通常需要登录后的 `Authorization: Bearer <access_token>`;浏览器内通过已登录前端和 `/dev-api` 代理访问。移动端登录接口为 `POST /auth/mobile/sms-login`,dev 默认请求 `{ phonenumber }`,显式开启验证码后请求 `{ phonenumber, smsCode }`;内部固定使用 app 客户端 `428a8310cd442757ae699df5d894f051` 和 `sms` grant。手机号不存在时会创建 `app_user`,用户名为手机号,备注为“移动端短信自动注册”。移动端首页接口 `GET /api/aihr/mobile/home/{role}` 仍保留 `@SaIgnore` 以保证真正未登录的首屏可用,匿名分支只返回不读取业务统计的公开数据;已登录请求必须是有效 `app_user`,并按认证手机号校验员工/主管身份后返回真实统计。已登录但身份缺失、后台账号误用、组织查询失败或客户端收到未知角色时均明确失败关闭,不得静默回到公开数据、默认员工端或旧岗位缓存。
|
||||
|
||||
阿里云短信复用 RuoYi 的 `sms.blends.config1`。本地开发把真实短信参数放根目录 `.env.local` 或外部环境变量,`scripts/dev-backend.sh` 会自动加载;`application-dev.yml` / `application-prod.yml` 只保留占位,不写真实密钥。
|
||||
|
||||
@@ -114,6 +114,8 @@ ALIYUN_SMS_SIGN_NAME=物业AI助手
|
||||
|
||||
SOP 文档上传第三片已经落最小后端边界:
|
||||
|
||||
> 说明(2026-08-01):下表中仍保留的“直接写入 `aihr_knowledge_fragment`/机会性向量化”是历史兼容实现说明,不代表经过质量批准。批量资料和视频必须使用 `POST /api/knowledge/doc/upload-async`,先进入不可变候选 asset/version/chunk revision 和 `REVIEW_PENDING/QUARANTINED`;只有人工发布后才投影到生产 fragment、数据集成员和 Qdrant outbox。同步 `POST /api/knowledge/doc/upload` 仅供 SOP 单文件即时预览,不得作为批量生产导入入口。新代码或运维脚本不得绕过 `/api/knowledge/quality/assets/{assetId}/publish`。
|
||||
|
||||
| 能力 | 后端接口 | 处理 |
|
||||
|---|---|---|
|
||||
| 文档上传解析 | `POST /api/knowledge/doc/upload` | `multipart/form-data`,字段 `file` 和 `category`;支持 `.txt/.md/.markdown/.pdf/.doc/.docx/.xls/.xlsx/.ppt/.pptx` 及图片 `.jpg/.jpeg/.png/.gif/.webp/.bmp`、100MB 内;先写 `sys_oss`,再绑定 `aihr_knowledge_attach.oss_id` 并切分写入 `aihr_knowledge_fragment`;管理端该接口 timeout 为 180s,避免 PDF 同步解析/归类/向量化接近默认 50s 时被客户端断开 |
|
||||
@@ -252,6 +254,75 @@ curl -fsS -X POST "$API_BASE/api/knowledge/doc/rebuild-vector-index" -H "Authori
|
||||
|
||||
浏览器验收仍按 [DEMO_ACCEPTANCE.md](DEMO_ACCEPTANCE.md) 的四条关键路径执行。
|
||||
|
||||
## 知识数据质量准入
|
||||
|
||||
文件上传、个人经验转企业知识和 AI 整理案例都先进入候选版本,不直接写入生产检索。质量审核接口仅允许当前租户的 `superadmin` 或 `hr_operator` 调用,租户上下文和审核人均从登录态取得,不接受请求体指定。
|
||||
|
||||
```http
|
||||
GET /api/knowledge/quality/assets?status=REVIEW_PENDING&limit=50
|
||||
GET /api/knowledge/quality/assets/{assetId}/issues
|
||||
GET /api/knowledge/quality/assets/{assetId}/conflicts
|
||||
GET /api/knowledge/quality/index-health
|
||||
GET /api/knowledge/quality/metrics
|
||||
GET /api/knowledge/quality/alerts?includeResolved=false&limit=100
|
||||
GET /api/knowledge/quality/glossary?status=ACTIVE&limit=100
|
||||
POST /api/knowledge/quality/glossary
|
||||
POST /api/knowledge/quality/glossary/{id}/approve
|
||||
POST /api/knowledge/quality/glossary/{id}/reject
|
||||
POST /api/knowledge/quality/glossary/{id}/deprecate
|
||||
GET /api/knowledge/quality/rules?status=SHADOW&limit=100
|
||||
POST /api/knowledge/quality/rules
|
||||
POST /api/knowledge/quality/rules/{ruleId}/status
|
||||
POST /api/knowledge/quality/rules/{ruleId}/evaluations
|
||||
GET /api/knowledge/quality/rules/{ruleId}/metrics
|
||||
POST /api/knowledge/quality/rules/{ruleId}/samples
|
||||
GET /api/knowledge/quality/rules/{ruleId}/samples?status=PENDING&limit=100
|
||||
POST /api/knowledge/quality/rules/samples/{sampleId}/review
|
||||
POST /api/knowledge/quality/rules/samples/schedule?limit=200
|
||||
GET /api/knowledge/quality/pipeline-runs?status=ALL&limit=100
|
||||
POST /api/knowledge/quality/pipeline-runs
|
||||
POST /api/knowledge/quality/pipeline-runs/{runId}/finish
|
||||
GET /api/knowledge/quality/golden-datasets?status=DRAFT&limit=100
|
||||
POST /api/knowledge/quality/golden-datasets
|
||||
GET /api/knowledge/quality/golden-datasets/{datasetId}/samples?limit=200
|
||||
POST /api/knowledge/quality/golden-datasets/{datasetId}/samples
|
||||
POST /api/knowledge/quality/golden-datasets/{datasetId}/freeze
|
||||
GET /api/knowledge/quality/rules/{ruleId}/acceptance-profiles
|
||||
POST /api/knowledge/quality/rules/{ruleId}/acceptance-profiles
|
||||
POST /api/knowledge/quality/rules/{ruleId}/acceptance-profiles/{profileId}/freeze
|
||||
GET /api/knowledge/quality/rules/{ruleId}/readiness
|
||||
POST /api/knowledge/quality/conflicts/{conflictId}/review
|
||||
GET /api/knowledge/quality/assets/{assetId}/privacy-preview
|
||||
POST /api/knowledge/quality/assets/{assetId}/publish
|
||||
POST /api/knowledge/quality/assets/{assetId}/withdraw
|
||||
GET /api/knowledge/quality/legacy/preview?afterAttachmentId=0&limit=50
|
||||
POST /api/knowledge/quality/legacy/stage?afterAttachmentId=0&limit=50
|
||||
```
|
||||
|
||||
`publish` 必须带人工审核意见、用途、来源权威级别和来源版本。请求中的 `acceptedReasonCodes` 只能确认当前版本仍开放的软提示,服务端会再次统计开放问题,遗漏任何一项都拒绝发布;`HARD` 问题不能在发布动作中接受,必须修订原资料并生成新版本,或通过后续独立的显式纠错流程解决。规范性知识仅接受 `FORMAL_POLICY / COMPANY_POLICY / REGULATION / APPROVED_SOP` 且版本非空;同名已发布资料内容变化会产生 `VERSION_CONFLICT`,规范性知识必须再传 `supersedesAssetId`,服务端验证同租户、同来源名和旧资产仍已发布后,在同一事务内撤回旧版本并发布新版本。
|
||||
|
||||
规范化采用版本化的 NFKC、换行、控制字符和空白处理;解析正文和规范化正文作为不可变审计证据保留,不作为下游生产内容。`privacy-redaction-v1` 从规范化正文生成独立的 `redacted_content/redacted_source_name`,记录派生 hash、分类计数、隐私状态和规则版本,并对派生正文及全部派生 chunk 复扫。只有 `CLEAN/REDACTED` 派生版本参与结构化切片、异步语义分析、模型调用、发布和检索;重复文件复用的历史摘要、模型新生成的摘要/标签/归类理由以及上传 snippet 也必须在返回或保存前走同一脱敏规则,不能因 OSS 对象复用而绕过。残留敏感模式写入 `BLOCKED / PII_DETECTED` 并拒绝发布,已完成替换写入 `PII_REDACTED` 证据。`GET /assets/{assetId}/privacy-preview` 只返回脱敏文件名、分类计数和截断后的脱敏正文,不返回原始正文。
|
||||
|
||||
按标题、段落、Q&A 与 SOP 步骤切片,只有超长结构块使用 overlap。处理结果只写新版本,不覆盖 raw;`aihr_data_version` 保存 SimHash、结构画像、extractor 和规则版本。精确重复、近重复、语义重复和版本冲突只产生 reason code 与候选关系,不由算法自动删除、批准或合并。语义分析在接入事务外异步执行;PII、提示词注入或已隔离内容不发送到外部 embedding。租户未配置可用向量模型时使用本地 hash 向量,并写入 `SEMANTIC_ANALYSIS_DEGRADED`,不得冒充完整语义检测;状态未达到 `COMPLETE/NOT_REQUIRED` 时发布失败。
|
||||
|
||||
制度与专家材料由确定性规则提取 claim 候选,只比较同租户已发布 claim,正反约束或数值不一致写入 `EXPERT_CONFLICT` 和 `aihr_claim_conflict`。审核人通过 `/conflicts/{conflictId}/review` 明确提交 `CONFIRMED/FALSE_POSITIVE/RESOLVED` 及依据;`PENDING_REVIEW/CONFIRMED` 冲突存在时后端拒绝发布。算法和 LLM 均不能自行裁决适用范围、权威来源或替代关系。
|
||||
|
||||
发布后才创建 `aihr_knowledge_fragment`、生产数据集成员和向量 outbox;撤回会在同一数据库事务中先删除 MySQL 生产片段、停用数据集成员,再排队删除 Qdrant 文档。向量失败不恢复 MySQL 可检索性。outbox 最多自动尝试 8 次,之后进入 `DEAD_LETTER`;`index-health` 返回待处理、重试、死信数量和最老事件时间,运营必须处理死信而不能把数据库 `PUBLISHED/DEPRECATED` 状态改回去掩盖漂移。每次查询的召回证据写入 `aihr_query_evidence`,记录实际 rank、score、`FULLTEXT/KEYWORD/VECTOR/HYBRID_RRF` 通道和 used 标记,可反查 chunk revision、数据版本、资产、原附件和 OSS 对象。
|
||||
|
||||
`legacy/preview` 只读返回下一批 `discovered/sourceAvailable/sourceUnavailable/nextCursor/moreAvailable`,不读取对象正文、不写治理表或索引。`legacy/stage` 按附件 ID 游标小批次纳管历史资料:存在当前租户可验证的 OSS 原件时,服务端从 MinIO 下载到受限临时文件,重新执行解析、质量门禁和切片;没有原件或原件不可读取时,创建 `QUARANTINED / SOURCE_UNAVAILABLE` 的不可变版本。写接口返回 `discovered/staged/reparsed/quarantined/failedAttachmentIds/nextCursor/moreAvailable`。它不从既有 fragment 反向伪造原始来源、不自动批准、不覆盖 MinIO;失败 ID 必须显式复核或从该 ID 前重新运行,只有人工确认来源、版本和适用范围后才能发布。
|
||||
|
||||
术语表采用不可变修订:创建接口只产生 `DRAFT`,只有人工 `approve` 后的 `ACTIVE` 版本参与同租户、项目和角色范围内的召回查询扩展;批准新版本会失效同一术语的旧活动版本。当前认证上下文没有可靠区域字段,带 `applicableRegion` 的词条 fail-closed,不参与扩展。`definition` 不进入模型事实上下文,`deprecate` 后立即停止扩展。对应迁移为 `aihr_20260809_knowledge_glossary_mysql8.sql`。AI 整理案例永久保留 synthetic、生成器/模型、prompt、原始音频 OSS、摘要 hash 和人工审核信息,对应迁移为 `aihr_20260810_case_provenance_mysql8.sql`;人工通过不改变其合成身份。
|
||||
|
||||
员工“没解决”反馈可携带本轮知识查询 `requestId`。服务端只接受该请求实际召回且属于当前租户的 fragment,创建 `DOWNSTREAM_ANSWER_DISPUTED` 再审问题,不自动撤回资料。后台复核接口 `POST /api/knowledge/answer-feedback/{id}/review` 只接受 `{action: "KEEP"|"WITHDRAW", note: "..."}`:`KEEP` 将争议标为误报并保留资料,`WITHDRAW` 必须由已认证审核人填写理由并调用统一生命周期撤回,随后触发向量 DELETE outbox。
|
||||
|
||||
质量监控由 `AihrKnowledgeQualityMonitoringService` 按租户定时扫描。`metrics` 返回资产生命周期、开放问题、待裁决重复/冲突、24 小时查询证据覆盖率、生产来源可追溯率和索引一致性;`alerts` 返回稳定 reason code、严重级别、首次/最近发生时间、累计次数、证据和解决状态。监控只报警和自动关闭已恢复告警,不批准、发布、合并、替代或删除资产。Actuator 健康组件名为 `aihrKnowledgeQuality`;迁移未执行时返回 `UNKNOWN`,存在生产血缘缺口、索引漂移、死信、过期发布资产或查询证据缺口时返回 `DOWN`。对应新增表迁移为 `backend/script/sql/update/aihr_20260808_data_quality_monitoring_mysql8.sql`。
|
||||
|
||||
规则演进第一批接口只保存版本化规则草稿、人工/黄金集期望与影子结果的对照、误放行/误隔离指标以及风险抽样复核。规则动作只允许 `FLAG/REVIEW/QUARANTINE`,不允许批准、发布或删除;服务端只允许 `DRAFT -> SHADOW -> PAUSED/RETIRED` 及 `PAUSED -> SHADOW/RETIRED`,在独立自动执行安全门、真实黄金集和灰度回滚能力完成前拒绝进入 `CANARY/ACTIVE`。影子评估和抽样结果不修改 `aihr_data_asset`、质量问题、审核决定或索引。对应迁移为 `backend/script/sql/update/aihr_20260811_rule_evolution_mysql8.sql`。
|
||||
|
||||
规则演进第二批新增 `aihr_pipeline_run` 和影子评估自动抽样。`pipeline-runs` 保存同租户的阶段、处理器及版本、输入/输出版本、触发方式、指标、错误和起止时间;完成状态只允许 `SUCCEEDED/FAILED/CANCELLED`,不能把 `PUBLISHED` 伪装成处理结果。定时任务及 `/rules/samples/schedule` 只读取仍处于 `SHADOW` 的评估:误放行/误隔离 100% 进入待复核,其余按 `CRITICAL=100% / HIGH=50% / MEDIUM=20% / LOW=10%` 做稳定哈希抽样,唯一键保证重复调度幂等。自动抽样只创建 `PENDING` 样本和运行证据,`assetMutationCount` 固定为 0;它不修改资产、问题、审核、发布或索引。管理端资料处理页只开放草稿、影子、暂停、退役和人工样本复核,不提供 `CANARY/ACTIVE`。对应迁移为 `backend/script/sql/update/aihr_20260812_pipeline_run_sampling_mysql8.sql`。
|
||||
|
||||
规则演进第三批新增版本化黄金集和风险验收门槛。黄金集先创建 `DRAFT`,只能由登录后台人员逐条写入稳定样本键、风险、期望决定、reason code 和人工证据;冻结时生成 SHA-256 内容哈希,此后不可修改,修订必须新建版本。`expectedSource=GOLDEN` 的影子评估必须引用当前租户已冻结的 `goldenSampleId`,期望决定、样本身份和资产版本由服务端从冻结样本加载,客户端不能自称黄金标签。每个规则版本可建立并人工冻结一份风险门槛,`readiness` 分别检查总样本、黄金样本、人工复核、一致率、误放行、误隔离、复核覆盖和待复核差异,返回稳定原因码;`enforcementEnabled` 固定为 `false`,证据就绪不等于允许 `CANARY/ACTIVE`。对应迁移为 `backend/script/sql/update/aihr_20260813_golden_calibration_mysql8.sql`。
|
||||
|
||||
## 多租户知识空间统一问答
|
||||
|
||||
内部员工端、主管端和管理端统一调用:
|
||||
@@ -287,7 +358,7 @@ Content-Type: application/json
|
||||
|
||||
成功响应包含 `requestId`、`answer`、`citations`、`usedSpaceCodes`、`noEvidence` 和兼容 `legacy` 数据。引用携带 `spaceCode/sourceType/docId/title/snippet/fragmentId`;客户端不得把无引用回答包装成有知识依据的正式答案。
|
||||
|
||||
空间、空间内分类、授权和应用管理接口统一位于 `/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}` 只解绑当前空间成员;其他空间仍引用同一 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)。
|
||||
空间、空间内分类、授权和应用管理接口统一位于 `/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)。
|
||||
|
||||
## 工作助手确认式统一采集
|
||||
|
||||
|
||||
Reference in New Issue
Block a user