feat(aihr): 重构运营后台与租户知识治理
- 重构运营总览、侧栏和内容运营工作台\n- 增加大喇叭、成果审核与运营统计链路\n- 补齐租户、知识空间、分类和知识维护闭环\n- 加固标签页租户上下文、停用租户写保护与迁移预检
This commit is contained in:
@@ -51,10 +51,12 @@ 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_daily_drill_score_mode_mysql8.sql
|
||||
mysql --default-character-set=utf8mb4 "$DB_NAME" < backend/script/sql/update/aihr_20260714_sop_requester_identity_mysql8.sql
|
||||
mysql --default-character-set=utf8mb4 "$DB_NAME" < backend/script/sql/update/aihr_20260715_knowledge_feedback_mysql8.sql
|
||||
mysql --default-character-set=utf8mb4 "$DB_NAME" < backend/script/sql/update/aihr_20260715_tenant_collation_mysql8.sql
|
||||
mysql --default-character-set=utf8mb4 "$DB_NAME" < backend/script/sql/update/aihr_20260716_knowledge_space_platform_mysql8.sql
|
||||
mysql --default-character-set=utf8mb4 "$DB_NAME" < backend/script/sql/update/aihr_20260714_org_hire_date_mysql8.sql
|
||||
mysql --default-character-set=utf8mb4 "$DB_NAME" < backend/script/sql/update/aihr_20260715_position_sop_qualification_mysql8.sql
|
||||
mysql --default-character-set=utf8mb4 "$DB_NAME" < backend/script/sql/update/aihr_20260717_practice_assignment_batch_mysql8.sql
|
||||
mysql --default-character-set=utf8mb4 "$DB_NAME" < backend/script/sql/update/aihr_20260717_practice_assignment_contract_mysql8.sql
|
||||
mysql --default-character-set=utf8mb4 "$DB_NAME" < backend/script/sql/update/aihr_20260717_learning_closure_mysql8.sql
|
||||
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_20260717_web_ai_question_reward_mysql8.sql
|
||||
@@ -67,9 +69,12 @@ mysql --default-character-set=utf8mb4 "$DB_NAME" < backend/script/sql/update/aih
|
||||
mysql --default-character-set=utf8mb4 "$DB_NAME" < backend/script/sql/update/aihr_20260719_work_report_idempotency_mysql8.sql
|
||||
mysql --default-character-set=utf8mb4 "$DB_NAME" < backend/script/sql/update/aihr_20260719_web_ai_database_secret_mysql8.sql
|
||||
mysql --default-character-set=utf8mb4 "$DB_NAME" < backend/script/sql/update/aihr_20260719_web_search_qwen_mysql8.sql
|
||||
mysql --default-character-set=utf8mb4 "$DB_NAME" < backend/script/sql/update/aihr_20260722_knowledge_category_mysql8.sql
|
||||
mysql --default-character-set=utf8mb4 "$DB_NAME" < backend/script/sql/update/aihr_20260722_broadcast_mysql8.sql
|
||||
mysql --default-character-set=utf8mb4 "$DB_NAME" < backend/script/sql/update/aihr_20260722_broadcast_question_context_mysql8.sql
|
||||
```
|
||||
|
||||
顺序原因:场景补充依赖三张场景/Rubric 基础表;五维迁移依赖场景和 Rubric;岗位/SOP/任务/资格迁移只补正式数据契约,不写业务行,也不代表岗位适用范围、任务规则或资格标准已经获得 HR 确认。住宅 SOP 和 Prompt 迁移只补内置内容,不代表内容已完成业务复核。知识会话迁移只新增短期上下文表,不生成业务对话。排序规则兼容迁移先对齐本批发布表,全量排序规则迁移再统一历史 `aihr_*` 表;两者都读取目标库 `aihr_knowledge_info.tenant_id` 的实际排序规则。服务记忆迁移创建候选、统一采集、兼容项目记录和版本留痕四张表;工作上报幂等迁移随后只补原表列与唯一索引。两者同样对齐目标排序规则,兼容历史生产库与全新 MySQL 8 数据库。
|
||||
顺序原因:场景补充依赖三张场景/Rubric 基础表;五维迁移依赖场景和 Rubric;岗位/SOP/任务/资格迁移只补正式数据契约,不写业务行,也不代表岗位适用范围、任务规则或资格标准已经获得 HR 确认。住宅 SOP 和 Prompt 迁移只补内置内容,不代表内容已完成业务复核。知识会话迁移只新增短期上下文表,不生成业务对话。排序规则兼容迁移先对齐本批发布表,全量排序规则迁移再统一历史 `aihr_*` 表;两者都读取目标库 `aihr_knowledge_info.tenant_id` 的实际排序规则。服务记忆迁移创建候选、统一采集、兼容项目记录和版本留痕四张表;工作上报幂等迁移随后只补原表列与唯一索引;知识分类迁移新增空间内分类表及附件成员的可空 `category_id`,不迁移、删除或扩大任何空间授权与检索范围;银城大喇叭迁移创建消息、阅读和不可变 v1 快照三表,为已存在消息补一次快照,并补发布请求键/载荷哈希、撤回原因及 `(tenant_id,published_by,publish_request_key)` 唯一约束。随后,消息追问迁移只给短期会话增加可空 `broadcast_message_id`;它不保存消息正文,并用于约束同一会话不能切换公司消息。历史普通会话保持 `NULL`。它们同样对齐目标排序规则,兼容历史生产库与全新 MySQL 8 数据库。
|
||||
|
||||
## 迁移后只读核验
|
||||
|
||||
@@ -83,7 +88,7 @@ WHERE table_schema = DATABASE()
|
||||
'aihr_practice_scenario', 'aihr_practice_rubric', 'aihr_practice_rubric_dimension', 'aihr_learning_question',
|
||||
'aihr_practice_audio', 'aihr_practice_audio_upload', 'aihr_practice_calibration',
|
||||
'aihr_knowledge_gap', 'aihr_knowledge_answer_feedback',
|
||||
'aihr_knowledge_space_grant', 'aihr_knowledge_app', 'aihr_knowledge_app_space',
|
||||
'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_practice_question_feedback',
|
||||
'aihr_onboard_exam', 'aihr_onboard_exam_target', 'aihr_onboard_exam_question',
|
||||
@@ -96,7 +101,7 @@ WHERE table_schema = DATABASE()
|
||||
'aihr_onboard_task', 'aihr_qualification_gate',
|
||||
'aihr_memory_candidate', 'aihr_assistant_capture', 'aihr_assistant_capture_status_log',
|
||||
'aihr_daily_work_result', 'aihr_service_memory', 'aihr_service_memory_version',
|
||||
'aihr_work_report'
|
||||
'aihr_work_report', 'aihr_broadcast_message', 'aihr_broadcast_read', 'aihr_broadcast_version'
|
||||
)
|
||||
ORDER BY table_name;
|
||||
|
||||
@@ -110,6 +115,7 @@ WHERE table_schema = DATABASE()
|
||||
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'))
|
||||
OR (table_name = 'aihr_sop_answer_review' AND column_name IN ('prompt_version', 'requester_ext_party_id'))
|
||||
OR (table_name = 'aihr_knowledge_info' AND column_name IN ('code', 'space_type', 'sensitivity_level', 'status'))
|
||||
OR (table_name = 'aihr_knowledge_attach' AND column_name = 'category_id')
|
||||
OR (table_name = 'aihr_knowledge_upload_item' AND column_name = 'space_codes_json')
|
||||
OR (table_name = 'aihr_org_snapshot' AND column_name = 'hire_date')
|
||||
OR (table_name = 'aihr_candidate_material' AND column_name IN ('reviewer', 'reviewed_time'))
|
||||
@@ -119,14 +125,23 @@ WHERE table_schema = DATABASE()
|
||||
OR (table_name = 'aihr_onboard_task' AND column_name IN ('ext_party_id', 'position_code', 'task_type', 'status', 'assign_by'))
|
||||
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'))
|
||||
OR (table_name = 'aihr_memory_candidate' AND column_name IN ('work_date', 'source_snapshot_json'))
|
||||
OR (table_name = 'aihr_assistant_capture' AND column_name IN ('work_date', 'source_snapshot_json', 'business_status'))
|
||||
OR (table_name = 'aihr_knowledge_conversation' AND column_name = 'project_code')
|
||||
OR (table_name = 'aihr_knowledge_conversation' AND column_name IN ('project_code', 'broadcast_message_id'))
|
||||
OR (table_name = 'aihr_daily_work_result' AND column_name = 'content_hash')
|
||||
OR (table_name = 'aihr_web_search_provider' AND column_name IN ('agent_id', 'agent_version'))
|
||||
)
|
||||
ORDER BY table_name, column_name;
|
||||
|
||||
SELECT MIN(non_unique) AS non_unique,
|
||||
GROUP_CONCAT(column_name ORDER BY seq_in_index) AS indexed_columns,
|
||||
SUM(sub_part IS NOT NULL) AS prefix_columns
|
||||
FROM information_schema.statistics
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = 'aihr_broadcast_message'
|
||||
AND index_name = 'uk_aihr_broadcast_message_publish_request';
|
||||
|
||||
SELECT COUNT(*) AS built_in_prompt_templates
|
||||
FROM aihr_prompt_template
|
||||
WHERE tenant_id = '000000'
|
||||
@@ -145,7 +160,7 @@ GROUP BY question_type
|
||||
ORDER BY question_type;
|
||||
```
|
||||
|
||||
预期是三张场景/Rubric 表、岗位题库、训练反馈表、五张考试表、三张全网检索表、问题榜/激励六张表、三张证据表、知识平台治理表、三张候选人/面试表、四张岗位/SOP/任务/资格契约表、四张记忆表、采集状态历史表、每日成果表和原工作上报表均存在;工作上报幂等字段为 `2/2`,工作助手新增字段为 `7/7`,会话证据字段为 `8/8`,专项批量/内容快照字段为 `8/8`,候选资料审核字段为 `2/2`,面试复核字段为 `6/6`,字段查询覆盖所有列,内置 Prompt 数量为 `6`。五个岗位各有 `20` 个场景,`daily/special` 各有 `100` 道题;其中 `14` 个未完成正式审核的高风险场景及其 `28` 道题保持禁用。岗位/SOP/任务/资格表及新记忆表为空是允许的;这只证明 schema/seed 迁移完成,不证明已有员工确认过记忆、完整个人知识库或严格试点完成。
|
||||
预期是三张场景/Rubric 表、岗位题库、训练反馈表、五张考试表、三张全网检索表、问题榜/激励六张表、三张证据表、知识平台治理表和空间内分类表、三张候选人/面试表、四张岗位/SOP/任务/资格契约表、四张记忆表、采集状态历史表、每日成果表、原工作上报表和三张大喇叭消息/阅读/v1快照表均存在;工作上报幂等字段为 `2/2`,大喇叭发布/撤回审计字段为 `3/3`,其发布幂等索引为 `0 | tenant_id,published_by,publish_request_key | 0`,公司消息追问会话字段为 `1/1`,工作助手新增字段为 `8/8`,会话证据字段为 `8/8`,专项批量/内容快照字段为 `8/8`,候选资料审核字段为 `2/2`,面试复核字段为 `6/6`,字段查询覆盖所有列,内置 Prompt 数量为 `6`。五个岗位各有 `20` 个场景,`daily/special` 各有 `100` 道题;其中 `14` 个未完成正式审核的高风险场景及其 `28` 道题保持禁用。岗位/SOP/任务/资格表及新记忆表为空是允许的;这只证明 schema/seed 迁移完成,不证明已有员工确认过记忆、完整个人知识库或严格试点完成。
|
||||
|
||||
## 迁移后应用回归
|
||||
|
||||
@@ -155,7 +170,8 @@ ORDER BY question_type;
|
||||
4. 用正式测试账号在“工作助手”选择当前项目并说“帮我记一下三栋 3203 需要保洁服务”;确认前 `aihr_assistant_capture` 不得新增。分别验证 `PRIVATE` 仅本人可召回、`COMPANY` 只显示 `PENDING` 且没有虚假送达回执;新开对话按房号查询必须只命中对应项目记录,双击确认不得重复写入。测试表达如不需长期保留,应在确认卡选择“暂不保存”,不要直接删除生产审计记录。
|
||||
5. 在“今日工作成果”按员工 + 项目 + 日期重复生成两次,内容不变时版本哈希必须一致;员工访问团队结果、主管访问非授权项目必须被拒绝。生产无主管正式测试账号时必须明确记录未验收,不以本地 seed 代替。
|
||||
6. 用员工测试账号进入“成果投稿”,确认其仍只承载优秀案例、操作视频、完整 SOP 和有用知识,不回退为日常事实表单。重复提交同一 `request_key` 只有一条 `PENDING` 记录;普通员工审核仍为 `403`,审核通过不自动写入案例、知识或积分表。
|
||||
7. 迁移完成后再按同一正式时间窗运行:
|
||||
7. 用 `superadmin` 或 `hr_operator` 在当前租户发布同一 `requestId` 两次:同内容必须只生成一条消息和一个 v1 快照,改动正文后必须返回 `409`。撤回时提交非空原因,员工端随即不可见;重复撤回不得改写首个撤回人、时间或原因。再确认管理列表不跨租户返回消息。
|
||||
8. 迁移完成后再按同一正式时间窗运行:
|
||||
|
||||
```bash
|
||||
AIHR_PILOT_TENANT_ID=000000 \
|
||||
|
||||
Reference in New Issue
Block a user