feat(aihr): add position qualification schema contract

This commit is contained in:
2026-07-15 02:04:05 +08:00
parent 27fe838225
commit d44e9440ce
7 changed files with 200 additions and 6 deletions
+2
View File
@@ -1,5 +1,7 @@
# BRD 功能审查与未完成项记录
- 2026-07-15 BRD 4.2/M4 岗位-SOP-上岗资格数据契约补齐:复核发现 `position_responsibility`、`sop_applicability`、`onboard_task`、`qualification_gate` 在代码库中只有 TechSpec 设计,没有正式 MySQL 结构;现新增幂等迁移和 reset DDL,并把四表纳入生产 Runbook、schema 回归和严格预检的结构可见性检查。迁移不写岗位、员工、课程或资格 seed,`position-sop` 仍保持 `NOT_CONFIGURED`;正式适用范围、入职任务规则和资格标准需 HR/组织系统提供后再接读取与 gating。
- 2026-07-15 BRD 生产迁移合同防回归:发现版本化 AIHR MySQL 迁移虽已全部写入 Runbook,但此前没有测试保证新增 `aihr_*_mysql8.sql` 必须同步进入执行清单;现将目录与 `BRD_PRODUCTION_MIGRATION_RUNBOOK.md` 的覆盖检查接入 schema migration 测试。该检查只验证发布合同,不执行生产迁移,也不替代备份、回滚和逐脚本核验。
- 2026-07-15 BRD 严格门禁旧案例结构兼容修复:`scripts/demo-check.sh` 原先在 `aihr_case_record` 整表或 `learning_points/supervisor_comment` 字段缺失时直接执行查询,可能以 Unknown column/table 中断,无法输出真正的 schema 门槛;现先探测表和字段,缺失时以 `stored_cases=0`、`case_media_schema=0/2`、`case_learning_schema=0/2` 继续判定,新增旧表/无表回归。该修复只改善迁移缺口可见性,不放松案例 `20` 条和字段 `2/2` 门槛。
+10 -3
View File
@@ -39,9 +39,10 @@ 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_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_20260714_org_hire_date_mysql8.sql
mysql --default-character-set=utf8mb4 "$DB_NAME" < backend/script/sql/update/aihr_20260715_position_sop_qualification_mysql8.sql
```
顺序原因:场景补充依赖三张场景/Rubric 基础表;五维迁移依赖场景和 Rubric;其余字段迁移依赖既有业务表但不写正式业务行。住宅 SOP 和 Prompt 迁移只补内置内容,不代表内容已完成业务复核。
顺序原因:场景补充依赖三张场景/Rubric 基础表;五维迁移依赖场景和 Rubric;岗位/SOP/任务/资格迁移只补正式数据契约,不写业务行,也不代表岗位适用范围、任务规则或资格标准已经获得 HR 确认。住宅 SOP 和 Prompt 迁移只补内置内容,不代表内容已完成业务复核。
## 迁移后只读核验
@@ -55,7 +56,9 @@ WHERE table_schema = DATABASE()
'aihr_practice_scenario', 'aihr_practice_rubric', 'aihr_practice_rubric_dimension',
'aihr_practice_audio', 'aihr_practice_audio_upload', 'aihr_practice_calibration',
'aihr_knowledge_gap', 'aihr_knowledge_answer_feedback',
'aihr_candidate_material', 'aihr_interview_result', 'aihr_candidate_employee_link'
'aihr_candidate_material', 'aihr_interview_result', 'aihr_candidate_employee_link',
'aihr_position_responsibility', 'aihr_sop_applicability',
'aihr_onboard_task', 'aihr_qualification_gate'
)
ORDER BY table_name;
@@ -70,6 +73,10 @@ WHERE table_schema = DATABASE()
OR (table_name = 'aihr_org_snapshot' AND column_name = 'hire_date')
OR (table_name = 'aihr_candidate_material' AND column_name IN ('reviewer', 'reviewed_time'))
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_qualification_gate' AND column_name IN ('ext_party_id', 'position_code', 'cert_id', 'passed', 'valid_thru'))
)
ORDER BY table_name, column_name;
@@ -79,7 +86,7 @@ WHERE tenant_id = '000000'
AND code IN ('summary_card', 'sop_answer', 'mentor_rewrite', 'review_annotation', 'prep_card', 'supervision_image_analysis_maintenance');
```
预期是三张场景/Rubric 表、三张证据表、两张知识治理表和三张候选人/面试表均存在,会话证据字段为 `8/8`,候选资料审核字段为 `2/2`,面试复核字段为 `6/6`,字段查询覆盖所有列,内置 Prompt 数量为 `6`。这只证明 schema/seed 迁移完成,不证明正式试点完成。
预期是三张场景/Rubric 表、三张证据表、两张知识治理表、三张候选人/面试表和四张岗位/SOP/任务/资格契约表均存在,会话证据字段为 `8/8`,候选资料审核字段为 `2/2`,面试复核字段为 `6/6`,字段查询覆盖所有列,内置 Prompt 数量为 `6`。岗位/SOP/任务/资格表为空是允许的;这只证明 schema/seed 迁移完成,不证明正式岗位规则、资格 gating 或试点完成。
## 迁移后应用回归