141 lines
6.6 KiB
Bash
141 lines
6.6 KiB
Bash
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
|
SCRIPT="$ROOT_DIR/scripts/demo-check.sh"
|
|
|
|
assert_contains() {
|
|
local text="$1"
|
|
grep -Fq "$text" "$SCRIPT" || {
|
|
echo "FAIL: demo-check.sh missing: $text" >&2
|
|
exit 1
|
|
}
|
|
}
|
|
|
|
assert_not_contains() {
|
|
local text="$1"
|
|
if grep -Fq "$text" "$SCRIPT"; then
|
|
echo "FAIL: demo-check.sh still contains unsafe match: $text" >&2
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
assert_contains 'AIHR_PILOT_START_DATE'
|
|
assert_contains 'AIHR_PILOT_END_DATE'
|
|
assert_contains 'AIHR_DEMO_CHECK_LIBRARY_ONLY'
|
|
assert_contains 'safe_org AS'
|
|
assert_contains 'HAVING SUM(s.session_count) >= 10'
|
|
assert_contains 'HAVING COUNT(DISTINCT ext_party_id) = 1'
|
|
assert_contains 'finished_time >='
|
|
assert_contains 'reviewed_time >='
|
|
assert_not_contains 'p.identity_key = o.ext_party_id OR p.identity_key = o.person_phone'
|
|
assert_not_contains 's.ext_party_id = o.ext_party_id OR s.ext_party_id = o.person_phone'
|
|
|
|
if ! command -v docker >/dev/null || ! docker ps --format '{{.Names}}' | grep -qx 'wygj-mysql'; then
|
|
echo "SKIP: behavioral pilot gate test requires wygj-mysql"
|
|
exit 0
|
|
fi
|
|
|
|
export AIHR_DEMO_CHECK_LIBRARY_ONLY=true
|
|
# shellcheck source=../demo-check.sh
|
|
source "$SCRIPT"
|
|
|
|
unset AIHR_PILOT_DB
|
|
[[ "$(pilot_sql_scalar 'SELECT 1')" == "1" ]] || {
|
|
echo "FAIL: default ry-vue pilot database is unavailable" >&2
|
|
exit 1
|
|
}
|
|
|
|
TEST_DB="wygj_demo_check_test_$$"
|
|
cleanup() {
|
|
docker exec wygj-mysql mysql -uroot -proot -e "DROP DATABASE IF EXISTS \`$TEST_DB\`" >/dev/null 2>&1 || true
|
|
}
|
|
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_session (tenant_id varchar(20), session_id varchar(100), ext_party_id varchar(100), mode varchar(30), finished_time datetime);
|
|
CREATE TABLE aihr_practice_assignment (tenant_id varchar(20), ext_party_id varchar(100), create_time datetime);
|
|
CREATE TABLE aihr_org_snapshot (
|
|
tenant_id varchar(20), employment_status varchar(20), ext_party_id varchar(100),
|
|
project_code varchar(50), person_phone varchar(30)
|
|
);
|
|
CREATE TABLE aihr_practice_calibration (
|
|
id bigint auto_increment primary key, tenant_id varchar(20), session_id varchar(100),
|
|
original_score int, corrected_score int, create_time datetime
|
|
);
|
|
CREATE TABLE aihr_sop_answer_review (
|
|
tenant_id varchar(20), status varchar(30), usable tinyint,
|
|
reviewed_time datetime, create_time datetime
|
|
);
|
|
|
|
INSERT INTO aihr_practice_scenario
|
|
SELECT '000000','生活顾问',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_org_snapshot VALUES
|
|
('000000','active','A','P1','13900000001'),
|
|
('000000','active','B','P1','13900000001'),
|
|
('000000','active','C','P2','D'),
|
|
('000000','active','D','P2','13900000004'),
|
|
('000000','active','E','P3','13900000005'),
|
|
('000000','active','F','P3','13900000006');
|
|
INSERT INTO aihr_practice_assignment VALUES
|
|
('000000','D','2026-07-08 08:00:00'),
|
|
('000000','13900000001','2026-07-08 08:00:00'),
|
|
('000000','E','2026-07-08 08:00:00'),
|
|
('000000','13900000005','2026-07-08 08:00:00'),
|
|
('000000','F','2026-07-08 08:00:00');
|
|
INSERT INTO aihr_practice_session
|
|
SELECT '000000', CONCAT('e-', n), CASE WHEN n <= 5 THEN 'E' ELSE '13900000005' END, 'mobile', '2026-07-08 09:00:00'
|
|
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
|
|
) n;
|
|
INSERT INTO aihr_practice_session
|
|
SELECT '000000', CONCAT('f-', n), 'F','mobile','2026-07-08 10:00:00' 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
|
|
) n;
|
|
INSERT INTO aihr_practice_session VALUES
|
|
('000000','e-out','E','mobile','2026-07-06 10:00:00'),
|
|
('000000','unsafe-inside','D','mobile','2026-07-08 10:00:00');
|
|
INSERT INTO aihr_practice_calibration (tenant_id,session_id,original_score,corrected_score,create_time) VALUES
|
|
('000000','f-1',80,82,'2026-07-08 11:00:00'),
|
|
('000000','unsafe-inside',80,40,'2026-07-08 11:00:00'),
|
|
('000000','e-out',80,40,'2026-07-06 11:00:00');
|
|
INSERT INTO aihr_sop_answer_review VALUES
|
|
('000000','已评审',1,'2026-07-08 12:00:00','2026-07-08 11:00:00'),
|
|
('000000','已评审',0,'2026-07-06 12:00:00','2026-07-06 11:00:00'),
|
|
('000000','待评审',NULL,NULL,'2026-07-08 13:00:00'),
|
|
('000000','待评审',NULL,NULL,'2026-07-06 13:00:00');
|
|
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" == *'org_login=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; }
|
|
[[ "$pilot_output" == *'org_ten_sessions=1/2'* ]] || { echo "FAIL: formal 9/10 boundary: $pilot_output" >&2; exit 1; }
|
|
[[ "$pilot_output" == *'calibration=1/20 consistency=1/1'* ]] || { echo "FAIL: calibration window: $pilot_output" >&2; exit 1; }
|
|
[[ "$pilot_output" == *'sop_usable=1/1 sop_pending=1'* ]] || { echo "FAIL: SOP window: $pilot_output" >&2; exit 1; }
|
|
|
|
pilot_sql_scalar "INSERT INTO aihr_practice_session VALUES ('000000','e-10','13900000005','mobile','2026-07-09 09:00:00')" >/dev/null
|
|
pilot_output="$(AIHR_PILOT_START_DATE=2026-07-07 AIHR_PILOT_END_DATE=2026-07-10 check_pilot_samples)"
|
|
[[ "$pilot_output" == *'org_ten_sessions=2/2'* ]] || { echo "FAIL: formal 10/10 boundary: $pilot_output" >&2; exit 1; }
|
|
|
|
if (AIHR_PILOT_STRICT=true AIHR_PILOT_START_DATE= AIHR_PILOT_END_DATE= check_pilot_samples) >/tmp/wygj-pilot-strict-test.log 2>&1; then
|
|
echo "FAIL: strict mode accepted an implicit date window" >&2
|
|
exit 1
|
|
fi
|
|
grep -Fq 'strict pilot check requires AIHR_PILOT_START_DATE and AIHR_PILOT_END_DATE' /tmp/wygj-pilot-strict-test.log || {
|
|
echo "FAIL: strict mode missing-date error is unclear" >&2
|
|
exit 1
|
|
}
|
|
|
|
echo "PASS: demo pilot gates use a bounded window and unique formal identities"
|