feat(personal-assistant): add confirmed project memory

This commit is contained in:
2026-07-19 08:19:24 +08:00
parent 151cc26caf
commit 24da833fa6
31 changed files with 4037 additions and 60 deletions
+62
View File
@@ -0,0 +1,62 @@
#!/usr/bin/env bash
set -euo pipefail
API_BASE="${API_BASE:-https://wygj-api.localhost}"
TOKEN="${TOKEN:-}"
CLIENT_ID="${CLIENT_ID:-428a8310cd442757ae699df5d894f051}"
fail() {
echo "personal-assistant-smoke: $*" >&2
exit 1
}
request() {
local path="$1"
local body_file
local status
body_file="$(mktemp)"
if [[ -n "$TOKEN" ]]; then
status="$(curl -ksS --max-time 15 -o "$body_file" -w '%{http_code}' \
-H "Authorization: Bearer $TOKEN" \
-H "clientid: $CLIENT_ID" \
"$API_BASE$path")" || {
rm -f "$body_file"
fail "request failed: $path"
}
else
status="$(curl -ksS --max-time 15 -o "$body_file" -w '%{http_code}' "$API_BASE$path")" || {
rm -f "$body_file"
fail "request failed: $path"
}
fi
RESPONSE_BODY="$(tr -d '\n' < "$body_file")"
RESPONSE_STATUS="$status"
rm -f "$body_file"
}
assert_protected_or_success() {
local label="$1"
local path="$2"
request "$path"
if [[ -z "$TOKEN" ]]; then
if [[ "$RESPONSE_STATUS" =~ ^(401|403)$ ]] || printf '%s' "$RESPONSE_BODY" | grep -Eq '"code"[[:space:]]*:[[:space:]]*(401|403)'; then
echo "$label=protected"
return
fi
fail "$label allowed anonymous access (HTTP $RESPONSE_STATUS): $RESPONSE_BODY"
fi
[[ "$RESPONSE_STATUS" == "200" ]] || fail "$label HTTP $RESPONSE_STATUS: $RESPONSE_BODY"
printf '%s' "$RESPONSE_BODY" | grep -Eq '"code"[[:space:]]*:[[:space:]]*200([[:space:]]*[,}])' \
|| fail "$label business response failed: $RESPONSE_BODY"
echo "$label=200"
}
assert_protected_or_success "memory_candidates" "/api/aihr/personal-assistant/memory-candidates?status=DRAFT"
assert_protected_or_success "service_memories" "/api/aihr/service-memories?limit=5"
if [[ -z "$TOKEN" ]]; then
echo "personal-assistant-smoke: authentication boundary passed; set TOKEN to add read-only authenticated checks"
else
echo "personal-assistant-smoke: authenticated read-only checks passed"
fi
+4 -1
View File
@@ -153,6 +153,9 @@ FROM (
UNION ALL SELECT 'aihr_sop_applicability'
UNION ALL SELECT 'aihr_onboard_task'
UNION ALL SELECT 'aihr_qualification_gate'
UNION ALL SELECT 'aihr_memory_candidate'
UNION ALL SELECT 'aihr_service_memory'
UNION ALL SELECT 'aihr_service_memory_version'
) required
LEFT JOIN information_schema.tables actual
ON actual.table_schema = DATABASE() AND actual.table_name = required.table_name
@@ -163,7 +166,7 @@ REMOTE
)" || fail "remote schema check failed: $remote_ssh:$remote_db"
[[ -z "$missing" ]] || fail "remote schema missing required tables: $(printf '%s' "$missing" | tr '\n' ', ' | sed 's/, $//')"
echo "remote_schema=35/35 $remote_ssh:$remote_db"
echo "remote_schema=38/38 $remote_ssh:$remote_db"
}
changed_files="$(git status --porcelain)"
+1
View File
@@ -24,6 +24,7 @@ docker exec -i wygj-mysql mysql -uroot -proot --default-character-set=utf8mb4 ry
docker exec -i wygj-mysql mysql -uroot -proot --default-character-set=utf8mb4 ry-vue < "$ROOT_DIR/backend/script/sql/aihr_practice_mysql8.sql"
docker exec -i wygj-mysql mysql -uroot -proot --default-character-set=utf8mb4 ry-vue < "$ROOT_DIR/backend/script/sql/aihr_interview_result_mysql8.sql"
docker exec -i wygj-mysql mysql -uroot -proot --default-character-set=utf8mb4 ry-vue < "$ROOT_DIR/backend/script/sql/aihr_org_snapshot_mysql8.sql"
docker exec -i wygj-mysql mysql -uroot -proot --default-character-set=utf8mb4 ry-vue < "$ROOT_DIR/backend/script/sql/aihr_service_memory_mysql8.sql"
docker exec wygj-mysql mysql -uroot -proot --default-character-set=utf8mb4 ry-vue \
-e "select count(*) as tables_count from information_schema.tables where table_schema = 'ry-vue';"
+10 -1
View File
@@ -185,4 +185,13 @@ test "$candidate_interview_tables" = 'aihr_candidate_employee_link,aihr_candidat
candidate_interview_columns="$(mysql "$LEGACY_DB" -N -B -e "SELECT COUNT(*) FROM information_schema.columns WHERE table_schema='$LEGACY_DB' AND ((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')));")"
test "$candidate_interview_columns" = '8'
echo "PASS: AIHR legacy schema migrations are idempotent, including practice evidence, knowledge feedback, candidate interview review, and position/SOP qualification contracts"
service_memory_migration="$ROOT_DIR/backend/script/sql/update/aihr_20260719_service_memory_mysql8.sql"
test -f "$service_memory_migration"
mysql "$DB" < "$service_memory_migration"
mysql "$DB" < "$service_memory_migration"
service_memory_tables="$(mysql "$DB" -N -B -e "SELECT GROUP_CONCAT(table_name ORDER BY table_name) FROM information_schema.tables WHERE table_schema='$DB' AND table_name IN ('aihr_memory_candidate','aihr_service_memory','aihr_service_memory_version');")"
test "$service_memory_tables" = 'aihr_memory_candidate,aihr_service_memory,aihr_service_memory_version'
service_memory_version_columns="$(mysql "$DB" -N -B -e "SELECT COUNT(*) FROM information_schema.columns WHERE table_schema='$DB' AND ((table_name = 'aihr_memory_candidate' AND column_name IN ('version','confirm_idempotency_key','confirm_request_hash','source_conversation_id','source_request_id')) OR (table_name = 'aihr_service_memory' AND column_name IN ('project_code','version')) OR (table_name = 'aihr_service_memory_version' AND column_name IN ('memory_id','version')));")"
test "$service_memory_version_columns" = '9'
echo "PASS: AIHR legacy schema migrations are idempotent, including practice evidence, knowledge feedback, candidate interview review, position/SOP qualification contracts, and the project service memory slice"