From 53491e075a2caca712cb3a5aee2f2429df2ce24f Mon Sep 17 00:00:00 2001 From: let5sne Date: Wed, 15 Jul 2026 00:30:26 +0800 Subject: [PATCH] fix(aihr): gate built-in prompt content --- docs/BRD_IMPLEMENTATION_AUDIT.md | 2 ++ scripts/demo-check.sh | 6 ++++-- scripts/tests/demo-check-pilot-gates.test.sh | 9 +++++++++ 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/docs/BRD_IMPLEMENTATION_AUDIT.md b/docs/BRD_IMPLEMENTATION_AUDIT.md index cb52fc8a..f1521256 100644 --- a/docs/BRD_IMPLEMENTATION_AUDIT.md +++ b/docs/BRD_IMPLEMENTATION_AUDIT.md @@ -1,5 +1,7 @@ # BRD 功能审查与未完成项记录 +- 2026-07-15 严格试点门禁补强:`scripts/demo-check.sh` 原先只检查 SOP 评审的 `prompt_version` 字段,未检查 6 个内置 Prompt 是否实际落库;现新增 `prompt_templates=6/6` 查询和 strict 失败条件,并在 `scripts/tests/demo-check-pilot-gates.test.sh` 的临时库加入 6 个模板回归。该修复能阻止“schema 已迁移但 Prompt 内容为 0”的生产状态被误判为可验收;未修改生产数据。 + - 2026-07-15 线上只读复核续查:生产根站、`/h5/`、租户接口和员工首页 API 仍返回 `200`,`wygj-aihr.service` 为 `active`,服务自 `2026-07-14 22:13:55 CST` 起运行;线上管理端仍加载 `assets/index-B9T505HT.js`,H5 仍加载 `assets/index-CDn6TrX8.js`,与当前仓库可发布构建未做版本匹配。生产数据库仍缺 `aihr_practice_scenario`、`aihr_practice_rubric`、`aihr_practice_rubric_dimension`;`aihr_prompt_template` 内置模板 `0`、校准 `0`、已评审 SOP `0`、训练音频 `0`;`aihr_org_snapshot` 实际状态值为 `employment_status='active'`,active `22` 条但手机号映射 `0`。生产 `aihr_practice_session`、`aihr_practice_assignment`、SOP 评审、案例和入职日期字段仍未完整迁移。本轮仅做 GET/SSH/MySQL 只读检查,未执行静态同步、版本化迁移、后端重启或业务写入;下一步仍需正式发布窗口、备份/回滚责任和组织同步凭据。 - 2026-07-15 迁移合同回归:`scripts/tests/aihr-practice-brd-scenarios.test.sh`、`scripts/tests/aihr-knowledge-brd-sop.test.sh` 均通过幂等执行验证,`scripts/tests/pilot-export-contract.test.mjs` 通过 `5/5`;当前仓库的场景、住宅 SOP 和正式 CSV 导出合同可重复验证。该结果不替代生产迁移执行,也不把开发/本地样本算作正式试点数据。 diff --git a/scripts/demo-check.sh b/scripts/demo-check.sh index 9eee0e2b..d7e4755c 100755 --- a/scripts/demo-check.sh +++ b/scripts/demo-check.sh @@ -81,7 +81,7 @@ check_pilot_samples() { [[ "$(pilot_sql_scalar "SELECT DATE('$pilot_end') IS NOT NULL")" == "1" ]] || fail "invalid AIHR_PILOT_END_DATE: $pilot_end" [[ "$pilot_start" > "$pilot_end" ]] && fail "pilot start date must not be after end date" - local scenario_count scenario_service_promotion_count scenario_daily_service_count rubric_expected_count rubric_five_dimension_count completed_people pilot_people org_active org_phone_linked org_hire_date_linked org_pilot_people org_pilot_projects org_completed_people audio_table_count audio_upload_table_count case_media_schema_count case_learning_schema_count practice_session_schema_count daily_drill_schema_count prompt_version_schema_count requester_identity_schema_count hire_date_schema_count sop_document_count case_stored_count case_unmasked_count + local scenario_count scenario_service_promotion_count scenario_daily_service_count rubric_expected_count rubric_five_dimension_count completed_people pilot_people org_active org_phone_linked org_hire_date_linked org_pilot_people org_pilot_projects org_completed_people audio_table_count audio_upload_table_count case_media_schema_count case_learning_schema_count practice_session_schema_count daily_drill_schema_count prompt_template_count prompt_version_schema_count requester_identity_schema_count hire_date_schema_count sop_document_count case_stored_count case_unmasked_count local calibration_stats calibration_count calibration_matched sop_total sop_usable sop_pending satisfaction_count satisfaction_average local org_identity_cte=" WITH active_org AS ( @@ -145,6 +145,7 @@ check_pilot_samples() { case_learning_schema_count="$(pilot_sql_scalar "SELECT COUNT(*) FROM information_schema.columns WHERE table_schema = DATABASE() AND table_name = 'aihr_case_record' AND column_name IN ('learning_points','supervisor_comment')")" practice_session_schema_count="$(pilot_sql_scalar "SELECT COUNT(*) FROM information_schema.columns WHERE table_schema = DATABASE() AND table_name = 'aihr_practice_session' AND column_name IN ('dim_task_completion','dim_response_timeliness','response_latency_ms','annotations_json','review_advice','incentive_point','satisfaction_score','satisfaction_comment')")" daily_drill_schema_count="$(pilot_sql_scalar "SELECT COUNT(*) FROM information_schema.columns WHERE table_schema = DATABASE() AND table_name = 'aihr_practice_assignment' AND column_name IN ('answer_text','feedback','correct','finished_time','score','score_mode')")" + prompt_template_count="$(pilot_sql_scalar "SELECT COUNT(*) FROM aihr_prompt_template WHERE tenant_id = '$pilot_tenant' AND code IN ('summary_card','sop_answer','mentor_rewrite','review_annotation','prep_card','supervision_image_analysis_maintenance') AND enabled = 1")" prompt_version_schema_count="$(pilot_sql_scalar "SELECT COUNT(*) FROM information_schema.columns WHERE table_schema = DATABASE() AND table_name = 'aihr_sop_answer_review' AND column_name = 'prompt_version'")" requester_identity_schema_count="$(pilot_sql_scalar "SELECT COUNT(*) FROM information_schema.columns WHERE table_schema = DATABASE() AND table_name = 'aihr_sop_answer_review' AND column_name = 'requester_ext_party_id'")" hire_date_schema_count="$(pilot_sql_scalar "SELECT COUNT(*) FROM information_schema.columns WHERE table_schema = DATABASE() AND table_name = 'aihr_org_snapshot' AND column_name = 'hire_date'")" @@ -301,7 +302,7 @@ check_pilot_samples() { AND s.finished_time < DATE_ADD('${pilot_end}', INTERVAL 1 DAY) ) SELECT COALESCE(ROUND(AVG(satisfaction_score), 1), 0) FROM formal_sessions WHERE satisfaction_score IS NOT NULL")" - echo "OK: pilot gates window=${pilot_start}..${pilot_end} scenarios=${scenario_count}/12 rubric_five_dimensions=${rubric_five_dimension_count}/${rubric_expected_count} core_flow=service_promotion:${scenario_service_promotion_count} daily_service:${scenario_daily_service_count} sop_docs=${sop_document_count}/5 stored_cases=${case_stored_count}/20 case_unmasked=${case_unmasked_count} ten_sessions=${completed_people}/${pilot_people} org_identity=${org_phone_linked}/${org_active} org_hire_date=${org_hire_date_linked}/${org_active} org_pilot=${org_pilot_people}/20 projects=${org_pilot_projects}/1-2 org_ten_sessions=${org_completed_people}/${org_pilot_people} calibration=${calibration_count}/20 consistency=${calibration_matched}/${calibration_count} sop_usable=${sop_usable}/${sop_total} sop_pending=${sop_pending} satisfaction=${satisfaction_average}/5 responses=${satisfaction_count} audio_schema=${audio_table_count} audio_upload_schema=${audio_upload_table_count} case_media_schema=${case_media_schema_count}/2 case_learning_schema=${case_learning_schema_count}/2 practice_session_schema=${practice_session_schema_count}/8 daily_drill_schema=${daily_drill_schema_count}/6 prompt_version_schema=${prompt_version_schema_count} requester_identity_schema=${requester_identity_schema_count} hire_date_schema=${hire_date_schema_count}" + echo "OK: pilot gates window=${pilot_start}..${pilot_end} scenarios=${scenario_count}/12 rubric_five_dimensions=${rubric_five_dimension_count}/${rubric_expected_count} core_flow=service_promotion:${scenario_service_promotion_count} daily_service:${scenario_daily_service_count} sop_docs=${sop_document_count}/5 stored_cases=${case_stored_count}/20 case_unmasked=${case_unmasked_count} ten_sessions=${completed_people}/${pilot_people} org_identity=${org_phone_linked}/${org_active} org_hire_date=${org_hire_date_linked}/${org_active} org_pilot=${org_pilot_people}/20 projects=${org_pilot_projects}/1-2 org_ten_sessions=${org_completed_people}/${org_pilot_people} calibration=${calibration_count}/20 consistency=${calibration_matched}/${calibration_count} sop_usable=${sop_usable}/${sop_total} sop_pending=${sop_pending} satisfaction=${satisfaction_average}/5 responses=${satisfaction_count} audio_schema=${audio_table_count} audio_upload_schema=${audio_upload_table_count} case_media_schema=${case_media_schema_count}/2 case_learning_schema=${case_learning_schema_count}/2 practice_session_schema=${practice_session_schema_count}/8 daily_drill_schema=${daily_drill_schema_count}/6 prompt_templates=${prompt_template_count}/6 prompt_version_schema=${prompt_version_schema_count} requester_identity_schema=${requester_identity_schema_count} hire_date_schema=${hire_date_schema_count}" [[ "${AIHR_PILOT_STRICT:-false}" != "true" ]] || { (( scenario_count >= 12 )) || fail "pilot enabled scenarios ${scenario_count}/12" @@ -317,6 +318,7 @@ check_pilot_samples() { (( case_learning_schema_count == 2 )) || fail "pilot case learning schema incomplete (aihr_case_record.learning_points/supervisor_comment missing)" (( practice_session_schema_count == 8 )) || fail "pilot practice session schema incomplete (${practice_session_schema_count}/8)" (( daily_drill_schema_count == 6 )) || fail "pilot daily drill schema incomplete (${daily_drill_schema_count}/6)" + (( prompt_template_count == 6 )) || fail "pilot built-in prompt templates ${prompt_template_count}/6" (( prompt_version_schema_count == 1 )) || fail "pilot RAG traceability schema unavailable (aihr_sop_answer_review.prompt_version missing)" (( requester_identity_schema_count == 1 )) || fail "pilot SOP requester identity schema unavailable (aihr_sop_answer_review.requester_ext_party_id missing)" (( hire_date_schema_count == 1 )) || fail "pilot org hire_date schema unavailable" diff --git a/scripts/tests/demo-check-pilot-gates.test.sh b/scripts/tests/demo-check-pilot-gates.test.sh index fe2f3b29..35175410 100755 --- a/scripts/tests/demo-check-pilot-gates.test.sh +++ b/scripts/tests/demo-check-pilot-gates.test.sh @@ -66,6 +66,7 @@ docker exec -i wygj-mysql mysql -uroot -proot --default-character-set=utf8mb4 << CREATE DATABASE \`$TEST_DB\` CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci; USE \`$TEST_DB\`; CREATE TABLE aihr_practice_scenario (tenant_id varchar(20), position varchar(80), scenario_type varchar(80), scenario_name varchar(120), enabled tinyint); +CREATE TABLE aihr_prompt_template (tenant_id varchar(20), code varchar(100), enabled tinyint); CREATE TABLE aihr_knowledge_attach (tenant_id varchar(20), type varchar(50), status tinyint); CREATE TABLE aihr_case_record ( tenant_id varchar(20), status varchar(30), title varchar(120), transcript text, summary varchar(1000), @@ -103,6 +104,13 @@ END, CONCAT('scenario-', n), 1 FROM ( SELECT 1 n UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9 UNION ALL SELECT 10 UNION ALL SELECT 11 UNION ALL SELECT 12 ) n; +INSERT INTO aihr_prompt_template (tenant_id, code, enabled) VALUES + ('000000','summary_card',1), + ('000000','sop_answer',1), + ('000000','mentor_rewrite',1), + ('000000','review_annotation',1), + ('000000','prep_card',1), + ('000000','supervision_image_analysis_maintenance',1); INSERT INTO aihr_knowledge_attach SELECT '000000','sop',2 FROM ( SELECT 1 n UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 @@ -179,6 +187,7 @@ pilot_output="$(AIHR_PILOT_START_DATE=2026-07-07 AIHR_PILOT_END_DATE=2026-07-10 [[ "$pilot_output" == *'case_media_schema=2/2'* ]] || { echo "FAIL: case media schema gate: $pilot_output" >&2; exit 1; } [[ "$pilot_output" == *'case_learning_schema=2/2'* ]] || { echo "FAIL: case learning schema gate: $pilot_output" >&2; exit 1; } [[ "$pilot_output" == *'practice_session_schema=8/8 daily_drill_schema=6/6'* ]] || { echo "FAIL: practice schema gates: $pilot_output" >&2; exit 1; } +[[ "$pilot_output" == *'prompt_templates=6/6'* ]] || { echo "FAIL: built-in prompt template gate: $pilot_output" >&2; exit 1; } [[ "$pilot_output" == *'sop_usable=1/1 sop_pending=1'* ]] || { echo "FAIL: SOP window: $pilot_output" >&2; exit 1; } [[ "$pilot_output" == *'satisfaction=5.0/5 responses=19'* ]] || { echo "FAIL: safe satisfaction identity scope: $pilot_output" >&2; exit 1; }