190 lines
5.5 KiB
Bash
Executable File
190 lines
5.5 KiB
Bash
Executable File
#!/usr/bin/env bash
|
||
set -euo pipefail
|
||
|
||
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||
default_output="$repo_root/docs/design/00_Management/14_AI_Audit_Diff_Latest.md"
|
||
output_file="$default_output"
|
||
strict_mode="false"
|
||
|
||
while [[ $# -gt 0 ]]; do
|
||
case "$1" in
|
||
--output)
|
||
output_file="$2"
|
||
shift 2
|
||
;;
|
||
--strict)
|
||
strict_mode="true"
|
||
shift
|
||
;;
|
||
*)
|
||
echo "未知参数: $1"
|
||
echo "用法: $0 [--output <输出文件>] [--strict]"
|
||
exit 1
|
||
;;
|
||
esac
|
||
done
|
||
|
||
formal_files=(
|
||
"docs/design/01_Overview/03_Summary_Design.md"
|
||
"docs/design/02_Detailed_Design/01_Detailed_Design.md"
|
||
"docs/design/03_Technical_Design/01_Database_Design.md"
|
||
"docs/design/03_Technical_Design/03_Interface_Design.md"
|
||
"docs/design/03_Technical_Design/04_Security_Design.md"
|
||
"docs/design/03_Technical_Design/05_Deployment_Design.md"
|
||
"docs/design/00_Management/04_Writing_Guide.md"
|
||
"docs/design/00_Management/10_AI_Retrieval_Whitelist.md"
|
||
"docs/design/00_Management/11_Main_Doc_Chapter_Index.md"
|
||
)
|
||
|
||
archive_root="$repo_root/docs/design/04_Appendix/Archive"
|
||
archive_tag_index="$archive_root/00_Archive_Tag_Index.md"
|
||
|
||
tmp_diff="$(mktemp)"
|
||
trap 'rm -f "$tmp_diff"' EXIT
|
||
|
||
diff_id=0
|
||
|
||
add_diff() {
|
||
local category="$1"
|
||
local file="$2"
|
||
local line_no="$3"
|
||
local symptom="$4"
|
||
local suggestion="$5"
|
||
local severity="$6"
|
||
|
||
diff_id=$((diff_id + 1))
|
||
symptom="${symptom//|/\\|}"
|
||
suggestion="${suggestion//|/\\|}"
|
||
printf "%s\t%s\t%s\t%s\t%s\t%s\t%s\n" \
|
||
"$diff_id" "$category" "$file" "$line_no" "$symptom" "$suggestion" "$severity" >>"$tmp_diff"
|
||
}
|
||
|
||
scan_pattern() {
|
||
local category="$1"
|
||
local pattern="$2"
|
||
local suggestion="$3"
|
||
local severity="$4"
|
||
|
||
for rel_file in "${formal_files[@]}"; do
|
||
local abs_file="$repo_root/$rel_file"
|
||
[[ -f "$abs_file" ]] || continue
|
||
|
||
while IFS= read -r row; do
|
||
[[ -z "$row" ]] && continue
|
||
local file_part="${row%%:*}"
|
||
local rest="${row#*:}"
|
||
local line_no="${rest%%:*}"
|
||
local content="${rest#*:}"
|
||
local file_rel="${file_part#"$repo_root/"}"
|
||
|
||
if [[ "$category" == "数据库口径" ]] && grep -q "替换为达梦数据库" <<<"$content"; then
|
||
continue
|
||
fi
|
||
|
||
add_diff "$category" "$file_rel" "$line_no" "$content" "$suggestion" "$severity"
|
||
done < <(rg -n --no-heading --color never --with-filename --pcre2 "$pattern" "$abs_file" || true)
|
||
done
|
||
}
|
||
|
||
# 规则 1:系统名称混用
|
||
scan_pattern \
|
||
"系统名称口径" \
|
||
"营业收费系统|数智营收管理系统|客户服务平台" \
|
||
"统一使用“福建水务营收系统”(引用原文除外)" \
|
||
"P2"
|
||
|
||
# 规则 2:数据库旧口径
|
||
scan_pattern \
|
||
"数据库口径" \
|
||
"OpenGauss|openGauss" \
|
||
"统一为“达梦数据库 8.0+”,历史记录场景需显式标注" \
|
||
"P1"
|
||
|
||
# 规则 3:接口占位编号
|
||
scan_pattern \
|
||
"接口编号规范" \
|
||
"IF-XXX|EXT-XXX" \
|
||
"使用 IF-UP/IF-REV/IF-CS/IF-METER/IF-INST/IF-EXT 规则" \
|
||
"P1"
|
||
|
||
# 规则 4:旧模块编号残留
|
||
scan_pattern \
|
||
"模块编号规范" \
|
||
"SERVICE-[0-9]{3}" \
|
||
"统一使用 CS-00x 编号规则" \
|
||
"P2"
|
||
|
||
# 规则 5:Archive 标签覆盖检查
|
||
if [[ ! -f "$archive_tag_index" ]]; then
|
||
add_diff \
|
||
"Archive 标签覆盖" \
|
||
"docs/design/04_Appendix/Archive/00_Archive_Tag_Index.md" \
|
||
"-" \
|
||
"缺少 Archive 标签索引文件" \
|
||
"先执行 make archive-tag-index 生成标签索引" \
|
||
"P1"
|
||
else
|
||
while IFS= read -r abs_md; do
|
||
rel_md="${abs_md#"$repo_root/"}"
|
||
if ! grep -Fq "\`$rel_md\`" "$archive_tag_index"; then
|
||
add_diff \
|
||
"Archive 标签覆盖" \
|
||
"$rel_md" \
|
||
"-" \
|
||
"未在 Archive 标签索引中登记" \
|
||
"执行 make archive-tag-index 更新标签清单" \
|
||
"P2"
|
||
fi
|
||
done < <(find "$archive_root" -type f -name "*.md" ! -name "00_Archive_Tag_Index.md" | sort)
|
||
fi
|
||
|
||
total_count="$(wc -l < "$tmp_diff" | tr -d ' ')"
|
||
p1_count="$(awk -F'\t' '$7=="P1"{c++} END{print c+0}' "$tmp_diff")"
|
||
p2_count="$(awk -F'\t' '$7=="P2"{c++} END{print c+0}' "$tmp_diff")"
|
||
|
||
output_dir="$(dirname "$output_file")"
|
||
mkdir -p "$output_dir"
|
||
|
||
{
|
||
echo "# 福建水务营收系统 AI 抽检差异清单(自动生成)"
|
||
echo
|
||
echo "## 1. 生成信息"
|
||
echo
|
||
echo "| 项目 | 内容 |"
|
||
echo "| --- | --- |"
|
||
echo "| 生成时间 | $(date '+%Y-%m-%d %H:%M:%S') |"
|
||
echo "| 扫描范围 | P0 主文档 + P1 治理入口(非 Archive) |"
|
||
echo "| 差异总数 | $total_count |"
|
||
echo "| P1 差异数 | $p1_count |"
|
||
echo "| P2 差异数 | $p2_count |"
|
||
echo
|
||
echo "## 2. 差异明细"
|
||
echo
|
||
echo "| 编号 | 类别 | 文件 | 行号 | 现象 | 建议 | 级别 |"
|
||
echo "| --- | --- | --- | --- | --- | --- | --- |"
|
||
|
||
if [[ "$total_count" -eq 0 ]]; then
|
||
echo "| - | - | - | - | 未发现口径差异 | 无需修复 | - |"
|
||
else
|
||
while IFS=$'\t' read -r id category file line_no symptom suggestion severity; do
|
||
printf '| %s | %s | `%s` | %s | %s | %s | %s |\n' \
|
||
"$id" "$category" "$file" "$line_no" "$symptom" "$suggestion" "$severity"
|
||
done < "$tmp_diff"
|
||
fi
|
||
|
||
echo
|
||
echo "## 3. 建议动作"
|
||
echo
|
||
echo "1. 先修复 P1 差异,再处理 P2 优化项。"
|
||
echo '2. 修复后执行:`make check-links`、`make validate-mermaid`、`make check-ai-governance`。'
|
||
echo '3. 周检归档可复用 `docs/design/00_Management/12_AI_Weekly_Audit_Template.md`。'
|
||
} >"$output_file"
|
||
|
||
echo "✅ AI 抽检差异清单已生成: $output_file"
|
||
echo " 差异总数: $total_count (P1=$p1_count, P2=$p2_count)"
|
||
|
||
if [[ "$strict_mode" == "true" && "$total_count" -gt 0 ]]; then
|
||
echo "❌ 严格模式下存在差异,返回失败。"
|
||
exit 1
|
||
fi
|