test(aihr): gate missing core practice flows

This commit is contained in:
2026-07-14 13:06:54 +08:00
parent c899050473
commit dd601c3482
3 changed files with 15 additions and 4 deletions
+1
View File
@@ -255,3 +255,4 @@
- 2026-07-14 线上只读核对:生产根站、`/h5/` 和 `/prod-api/auth/tenant/list` 均返回 `200`,线上仍加载管理端 `index-CJZ3Ax3Z.js` 与 H5 `index-D4-NrEpb.js`;本轮 `aa7e1508`、`5d85d63c` 两个 BRD 修复提交尚未发布。未执行生产同步、重启或业务数据写入。
- 2026-07-14 发布证据链复核:`release-preflight.sh` 原先只检查构建产物存在和 hash,旧产物可能被误当成当前提交发布;现增加跨 macOS/Linux 的产物时间门禁,管理端、H5 入口/主资源和后端 jar 必须不早于当前 `HEAD`,否则明确要求重建。该修复只收紧本地发布前检查,未修改生产环境。
- 2026-07-14 BRD 发布边界复核:基于当前 `HEAD=0433250b` 重新构建管理端、`mobile-uni` H5 和后端 jar 后,`release-preflight.sh` 的产物新鲜度检查通过;线上根站与 `/h5/` 仍返回 `200`,但线上仍加载管理端 `assets/index-CJZ3Ax3Z.js`、H5 `assets/index-D4-NrEpb.js`,本地当前产物分别为 `assets/index-ClaGy0E5.js`、`assets/index-C5pwI-WO.js`。预检随后因两份用户未提交的 Figma 文档停止;本轮未修改、暂存或提交这两份文档,也未执行生产同步、后端重启或业务数据写入,因此当前 BRD 修复仍未被证明在线上生效。
- 2026-07-14 BRD 4.3.4 门禁补强:严格试点预检不再只按启用场景数量判断覆盖,新增“服务推介/增值”和“日常服务”场景存在性统计;当前仅增加事实检查,不臆造场景内容,场景成功条件、SOP 适用范围和正式质量仍需内容负责人确认。行为测试夹具已覆盖两类统计,严格门禁会在缺任一核心流程时明确失败。
+7 -2
View File
@@ -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 completed_people pilot_people org_active org_phone_linked org_pilot_people org_pilot_projects org_completed_people audio_table_count prompt_version_schema_count sop_document_count case_stored_count case_unmasked_count
local scenario_count scenario_service_promotion_count scenario_daily_service_count completed_people pilot_people org_active org_phone_linked org_pilot_people org_pilot_projects org_completed_people audio_table_count prompt_version_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 (
@@ -124,6 +124,9 @@ check_pilot_samples() {
HAVING COUNT(DISTINCT ext_party_id) = 1
)"
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 '%增值%')")"
scenario_daily_service_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_name LIKE '%日常%')")"
audio_table_count="$(pilot_sql_scalar "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = DATABASE() AND table_name = 'aihr_practice_audio'")"
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'")"
sop_document_count="$(pilot_sql_scalar "SELECT COUNT(*) FROM aihr_knowledge_attach WHERE tenant_id = '$pilot_tenant' AND type = 'sop' AND status = 2")"
@@ -270,10 +273,12 @@ 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 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_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} prompt_version_schema=${prompt_version_schema_count}"
echo "OK: pilot gates window=${pilot_start}..${pilot_end} scenarios=${scenario_count}/12 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_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} prompt_version_schema=${prompt_version_schema_count}"
[[ "${AIHR_PILOT_STRICT:-false}" != "true" ]] || {
(( scenario_count >= 12 )) || fail "pilot enabled scenarios ${scenario_count}/12"
(( scenario_service_promotion_count > 0 )) || fail "pilot service-promotion scenarios missing"
(( scenario_daily_service_count > 0 )) || fail "pilot daily-service scenarios missing"
(( sop_document_count >= 5 )) || fail "pilot residential SOP documents ${sop_document_count}/5"
(( case_stored_count >= 20 )) || fail "pilot stored cases ${case_stored_count}/20"
(( case_unmasked_count == 0 )) || fail "pilot stored cases contain unmasked known PII (${case_unmasked_count})"
+7 -2
View File
@@ -56,7 +56,7 @@ trap cleanup EXIT
docker exec -i wygj-mysql mysql -uroot -proot --default-character-set=utf8mb4 <<SQL >/dev/null
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), enabled tinyint);
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_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)
@@ -77,7 +77,11 @@ CREATE TABLE aihr_sop_answer_review (
);
INSERT INTO aihr_practice_scenario
SELECT '000000','生活顾问',1 FROM (
SELECT '000000','生活顾问', CASE
WHEN n = 1 THEN '服务推介(增值)'
WHEN n = 2 THEN '日常服务'
ELSE '投诉处理'
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;
@@ -144,6 +148,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" == *'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; }
[[ "$pilot_output" == *'projects=1/1-2'* ]] || { echo "FAIL: safe pilot project count: $pilot_output" >&2; exit 1; }