fix(aihr): expose missing catalog schema gate
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
# BRD 功能审查与未完成项记录
|
||||
|
||||
- 2026-07-15 严格试点门禁可读性补强:`scripts/demo-check.sh` 新增 `catalog_schema=3/3`,严格模式在场景/Rubric 三张基础表缺失时明确失败,而不是只输出空的场景统计;临时库回归覆盖缺少 Rubric 表的 `catalog_schema=1/3` 状态。该修复不改变生产数据和业务门槛,仅让生产迁移缺口可被明确识别。
|
||||
|
||||
- 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 只读检查,未执行静态同步、版本化迁移、后端重启或业务写入;下一步仍需正式发布窗口、备份/回滚责任和组织同步凭据。
|
||||
|
||||
@@ -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_template_count prompt_version_schema_count requester_identity_schema_count hire_date_schema_count sop_document_count case_stored_count case_unmasked_count
|
||||
local catalog_schema_count 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 (
|
||||
@@ -123,6 +123,7 @@ check_pilot_samples() {
|
||||
GROUP BY identity_key
|
||||
HAVING COUNT(DISTINCT ext_party_id) = 1
|
||||
)"
|
||||
catalog_schema_count="$(pilot_sql_scalar "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = DATABASE() AND table_name IN ('aihr_practice_scenario','aihr_practice_rubric','aihr_practice_rubric_dimension')")"
|
||||
scenario_count="$(pilot_sql_scalar "SELECT COUNT(*) FROM aihr_practice_scenario WHERE tenant_id = '$pilot_tenant' AND position = '生活顾问' AND enabled = 1")"
|
||||
# ponytail: presence-only core-flow gate; content quality and SOP applicability still require HR review.
|
||||
scenario_service_promotion_count="$(pilot_sql_scalar "SELECT COUNT(*) FROM aihr_practice_scenario WHERE tenant_id = '$pilot_tenant' AND position = '生活顾问' AND enabled = 1 AND (scenario_type LIKE '%推介%' OR scenario_type LIKE '%增值%' OR scenario_name LIKE '%推介%' OR scenario_name LIKE '%增值%')")"
|
||||
@@ -302,9 +303,10 @@ 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_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}"
|
||||
echo "OK: pilot gates window=${pilot_start}..${pilot_end} catalog_schema=${catalog_schema_count}/3 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" ]] || {
|
||||
(( catalog_schema_count == 3 )) || fail "pilot practice catalog schema incomplete (${catalog_schema_count}/3)"
|
||||
(( scenario_count >= 12 )) || fail "pilot enabled scenarios ${scenario_count}/12"
|
||||
(( rubric_expected_count >= scenario_count && rubric_five_dimension_count >= rubric_expected_count )) || fail "pilot five-dimension rubrics ${rubric_five_dimension_count}/${rubric_expected_count}"
|
||||
(( scenario_service_promotion_count > 0 )) || fail "pilot service-promotion scenarios missing"
|
||||
|
||||
@@ -176,6 +176,7 @@ SQL
|
||||
export AIHR_PILOT_DB="$TEST_DB"
|
||||
pilot_output="$(AIHR_PILOT_START_DATE=2026-07-07 AIHR_PILOT_END_DATE=2026-07-10 check_pilot_samples)"
|
||||
[[ "$pilot_output" == *'ten_sessions=1/5'* ]] || { echo "FAIL: 9/10 boundary or raw window count: $pilot_output" >&2; exit 1; }
|
||||
[[ "$pilot_output" == *'catalog_schema=1/3'* ]] || { echo "FAIL: missing catalog schema was not visible: $pilot_output" >&2; exit 1; }
|
||||
[[ "$pilot_output" == *'core_flow=service_promotion:1 daily_service:1'* ]] || { echo "FAIL: BRD core-flow coverage counts: $pilot_output" >&2; exit 1; }
|
||||
[[ "$pilot_output" == *'org_identity=2/6'* ]] || { echo "FAIL: unsafe org identities were not excluded: $pilot_output" >&2; exit 1; }
|
||||
[[ "$pilot_output" == *'org_pilot=2/20'* ]] || { echo "FAIL: collision or dual-key identity was miscounted: $pilot_output" >&2; exit 1; }
|
||||
|
||||
Reference in New Issue
Block a user