feat(aihr): 重构运营后台与租户知识治理

- 重构运营总览、侧栏和内容运营工作台\n- 增加大喇叭、成果审核与运营统计链路\n- 补齐租户、知识空间、分类和知识维护闭环\n- 加固标签页租户上下文、停用租户写保护与迁移预检
This commit is contained in:
2026-07-23 01:24:22 +08:00
parent 333c365c6f
commit 163b08ecfe
94 changed files with 8610 additions and 1114 deletions
+163 -2
View File
@@ -130,6 +130,7 @@ FROM (
UNION ALL SELECT 'aihr_knowledge_space_grant'
UNION ALL SELECT 'aihr_knowledge_app'
UNION ALL SELECT 'aihr_knowledge_app_space'
UNION ALL SELECT 'aihr_knowledge_category'
UNION ALL SELECT 'aihr_knowledge_query_log'
UNION ALL SELECT 'aihr_knowledge_conversation'
UNION ALL SELECT 'aihr_knowledge_admin_audit'
@@ -161,6 +162,9 @@ FROM (
UNION ALL SELECT 'aihr_service_memory'
UNION ALL SELECT 'aihr_service_memory_version'
UNION ALL SELECT 'aihr_work_report'
UNION ALL SELECT 'aihr_broadcast_message'
UNION ALL SELECT 'aihr_broadcast_read'
UNION ALL SELECT 'aihr_broadcast_version'
) required
LEFT JOIN information_schema.tables actual
ON actual.table_schema = DATABASE() AND actual.table_name = required.table_name
@@ -193,6 +197,73 @@ REMOTE
[[ -z "$missing_work_report_columns" ]] \
|| fail "remote work-report schema missing required columns: $(printf '%s' "$missing_work_report_columns" | tr '\n' ', ' | sed 's/, $//')"
local missing_knowledge_category_columns
missing_knowledge_category_columns="$(ssh -o BatchMode=yes -o ConnectTimeout=10 "$remote_ssh" bash -s -- "$remote_db" <<'REMOTE'
set -euo pipefail
db="$1"
mysql --batch --skip-column-names --connect-timeout=5 "$db" <<'SQL'
SELECT CONCAT(required.table_name, '.', required.column_name)
FROM (
SELECT 'aihr_knowledge_category' AS table_name, 'tenant_id' AS column_name
UNION ALL SELECT 'aihr_knowledge_category', 'knowledge_id'
UNION ALL SELECT 'aihr_knowledge_category', 'code'
UNION ALL SELECT 'aihr_knowledge_category', 'name'
UNION ALL SELECT 'aihr_knowledge_category', 'status'
UNION ALL SELECT 'aihr_knowledge_category', 'sort_order'
UNION ALL SELECT 'aihr_knowledge_attach', 'category_id'
) required
LEFT JOIN information_schema.columns actual
ON actual.table_schema = DATABASE()
AND actual.table_name = required.table_name
AND actual.column_name = required.column_name
WHERE actual.column_name IS NULL
ORDER BY required.table_name, required.column_name;
SQL
REMOTE
)" || fail "remote knowledge-category schema check failed: $remote_ssh:$remote_db"
[[ -z "$missing_knowledge_category_columns" ]] \
|| fail "remote knowledge-category schema missing required columns: $(printf '%s' "$missing_knowledge_category_columns" | tr '\n' ', ' | sed 's/, $//')"
local knowledge_attach_category_index
knowledge_attach_category_index="$(ssh -o BatchMode=yes -o ConnectTimeout=10 "$remote_ssh" bash -s -- "$remote_db" <<'REMOTE'
set -euo pipefail
db="$1"
mysql --batch --skip-column-names --connect-timeout=5 "$db" <<'SQL'
SELECT CONCAT(
MIN(non_unique), '|',
COALESCE(GROUP_CONCAT(column_name ORDER BY seq_in_index), ''), '|',
SUM(sub_part IS NOT NULL)
)
FROM information_schema.statistics
WHERE table_schema = DATABASE()
AND table_name = 'aihr_knowledge_attach'
AND index_name = 'idx_aihr_knowledge_attach_category';
SQL
REMOTE
)" || fail "remote knowledge-attachment category-index check failed: $remote_ssh:$remote_db"
[[ "$knowledge_attach_category_index" = "1|tenant_id,knowledge_id,category_id|0" ]] \
|| fail "remote knowledge-attachment category index invalid: expected full columns tenant_id,knowledge_id,category_id; got ${knowledge_attach_category_index:-missing}"
local knowledge_category_code_index
knowledge_category_code_index="$(ssh -o BatchMode=yes -o ConnectTimeout=10 "$remote_ssh" bash -s -- "$remote_db" <<'REMOTE'
set -euo pipefail
db="$1"
mysql --batch --skip-column-names --connect-timeout=5 "$db" <<'SQL'
SELECT CONCAT(
MIN(non_unique), '|',
COALESCE(GROUP_CONCAT(column_name ORDER BY seq_in_index), ''), '|',
SUM(sub_part IS NOT NULL)
)
FROM information_schema.statistics
WHERE table_schema = DATABASE()
AND table_name = 'aihr_knowledge_category'
AND index_name = 'uk_aihr_knowledge_category_code';
SQL
REMOTE
)" || fail "remote knowledge-category unique-index check failed: $remote_ssh:$remote_db"
[[ "$knowledge_category_code_index" = "0|tenant_id,knowledge_id,code|0" ]] \
|| fail "remote knowledge-category unique index invalid: expected unique full columns tenant_id,knowledge_id,code; got ${knowledge_category_code_index:-missing}"
local work_report_unique_index
work_report_unique_index="$(ssh -o BatchMode=yes -o ConnectTimeout=10 "$remote_ssh" bash -s -- "$remote_db" <<'REMOTE'
set -euo pipefail
@@ -213,6 +284,89 @@ REMOTE
[[ "$work_report_unique_index" = "0|tenant_id,submitter_user_id,request_key|0" ]] \
|| fail "remote work-report unique index invalid: expected unique full columns tenant_id,submitter_user_id,request_key; got ${work_report_unique_index:-missing}"
local missing_broadcast_publish_columns
missing_broadcast_publish_columns="$(ssh -o BatchMode=yes -o ConnectTimeout=10 "$remote_ssh" bash -s -- "$remote_db" <<'REMOTE'
set -euo pipefail
db="$1"
mysql --batch --skip-column-names --connect-timeout=5 "$db" <<'SQL'
SELECT required.column_name
FROM (
SELECT 'publish_request_key' AS column_name
UNION ALL SELECT 'publish_request_hash'
UNION ALL SELECT 'withdraw_reason'
) required
LEFT JOIN information_schema.columns actual
ON actual.table_schema = DATABASE()
AND actual.table_name = 'aihr_broadcast_message'
AND actual.column_name = required.column_name
WHERE actual.column_name IS NULL
ORDER BY required.column_name;
SQL
REMOTE
)" || fail "remote broadcast publish-audit schema check failed: $remote_ssh:$remote_db"
[[ -z "$missing_broadcast_publish_columns" ]] \
|| fail "remote broadcast message schema missing required columns: $(printf '%s' "$missing_broadcast_publish_columns" | tr '\n' ', ' | sed 's/, $//')"
local broadcast_publish_unique_index
broadcast_publish_unique_index="$(ssh -o BatchMode=yes -o ConnectTimeout=10 "$remote_ssh" bash -s -- "$remote_db" <<'REMOTE'
set -euo pipefail
db="$1"
mysql --batch --skip-column-names --connect-timeout=5 "$db" <<'SQL'
SELECT CONCAT(
MIN(non_unique), '|',
COALESCE(GROUP_CONCAT(column_name ORDER BY seq_in_index), ''), '|',
SUM(sub_part IS NOT NULL)
)
FROM information_schema.statistics
WHERE table_schema = DATABASE()
AND table_name = 'aihr_broadcast_message'
AND index_name = 'uk_aihr_broadcast_message_publish_request';
SQL
REMOTE
)" || fail "remote broadcast publish unique-index check failed: $remote_ssh:$remote_db"
[[ "$broadcast_publish_unique_index" = "0|tenant_id,published_by,publish_request_key|0" ]] \
|| fail "remote broadcast publish unique index invalid: expected unique full columns tenant_id,published_by,publish_request_key; got ${broadcast_publish_unique_index:-missing}"
local broadcast_read_unique_index
broadcast_read_unique_index="$(ssh -o BatchMode=yes -o ConnectTimeout=10 "$remote_ssh" bash -s -- "$remote_db" <<'REMOTE'
set -euo pipefail
db="$1"
mysql --batch --skip-column-names --connect-timeout=5 "$db" <<'SQL'
SELECT CONCAT(
MIN(non_unique), '|',
COALESCE(GROUP_CONCAT(column_name ORDER BY seq_in_index), ''), '|',
SUM(sub_part IS NOT NULL)
)
FROM information_schema.statistics
WHERE table_schema = DATABASE()
AND table_name = 'aihr_broadcast_read'
AND index_name = 'uk_aihr_broadcast_read';
SQL
REMOTE
)" || fail "remote broadcast-read unique-index check failed: $remote_ssh:$remote_db"
[[ "$broadcast_read_unique_index" = "0|tenant_id,message_id,user_id|0" ]] \
|| fail "remote broadcast-read unique index invalid: expected unique full columns tenant_id,message_id,user_id; got ${broadcast_read_unique_index:-missing}"
local broadcast_version_unique_index
broadcast_version_unique_index="$(ssh -o BatchMode=yes -o ConnectTimeout=10 "$remote_ssh" bash -s -- "$remote_db" <<'REMOTE'
set -euo pipefail
db="$1"
mysql --batch --skip-column-names --connect-timeout=5 "$db" <<'SQL'
SELECT CONCAT(
MIN(non_unique), '|',
COALESCE(GROUP_CONCAT(column_name ORDER BY seq_in_index), ''), '|',
SUM(sub_part IS NOT NULL)
)
FROM information_schema.statistics
WHERE table_schema = DATABASE()
AND table_name = 'aihr_broadcast_version'
AND index_name = 'uk_aihr_broadcast_version';
SQL
REMOTE
)" || fail "remote broadcast-version unique-index check failed: $remote_ssh:$remote_db"
[[ "$broadcast_version_unique_index" = "0|tenant_id,message_id,version|0" ]] \
|| fail "remote broadcast-version unique index invalid: expected unique full columns tenant_id,message_id,version; got ${broadcast_version_unique_index:-missing}"
local missing_work_assistant_columns
missing_work_assistant_columns="$(ssh -o BatchMode=yes -o ConnectTimeout=10 "$remote_ssh" bash -s -- "$remote_db" <<'REMOTE'
set -euo pipefail
@@ -226,6 +380,7 @@ FROM (
UNION ALL SELECT 'aihr_assistant_capture', 'source_snapshot_json'
UNION ALL SELECT 'aihr_assistant_capture', 'business_status'
UNION ALL SELECT 'aihr_knowledge_conversation', 'project_code'
UNION ALL SELECT 'aihr_knowledge_conversation', 'broadcast_message_id'
UNION ALL SELECT 'aihr_daily_work_result', 'content_hash'
) required
LEFT JOIN information_schema.columns actual
@@ -240,9 +395,15 @@ REMOTE
[[ -z "$missing_work_assistant_columns" ]] \
|| fail "remote work-assistant schema missing required columns: $(printf '%s' "$missing_work_assistant_columns" | tr '\n' ', ' | sed 's/, $//')"
echo "remote_schema=43/43 $remote_ssh:$remote_db"
echo "remote_schema=47/47 $remote_ssh:$remote_db"
echo "remote_work_report_idempotency=3/3 $remote_ssh:$remote_db"
echo "remote_work_assistant_columns=7/7 $remote_ssh:$remote_db"
echo "remote_knowledge_category_columns=7/7 $remote_ssh:$remote_db"
echo "remote_broadcast_publish_audit_columns=3/3 $remote_ssh:$remote_db"
echo "remote_broadcast_publish_idempotency=3/3 $remote_ssh:$remote_db"
echo "remote_broadcast_read_idempotency=3/3 $remote_ssh:$remote_db"
echo "remote_broadcast_version_uniqueness=3/3 $remote_ssh:$remote_db"
echo "remote_broadcast_question_context=1/1 $remote_ssh:$remote_db"
echo "remote_work_assistant_columns=8/8 $remote_ssh:$remote_db"
}
changed_files="$(git status --porcelain)"