You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

90 lines
3.2 KiB

2 days ago
# -*- coding: utf-8 -*-
"""票 05 全量盘点:.bru 响应示例形态分布 + specimens 覆盖对账。
输出
A) 全仓形态统计占位/真值/双节/错误码节
B) 占位残留清单需处理
C) 占位且有真值块仅需删占位vs 占位且无真值块需写数据
D) specimens 合并 key 清单 + 对账钥匙映射缺口
"""
from __future__ import annotations
import io
import json
import re
import sys
from pathlib import Path
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
A4 = Path('D:/code/crm-api-docs/A4 客户管理')
SP = Path('.scratch/customer-integration-ready')
files = [p for p in A4.rglob('*.bru') if p.name != 'folder.bru']
print(f'[A] 全仓 .bru = {len(files)}(排除 folder.bru)')
# ---------- 形态扫描 ----------
ph_files, tv_files, dual_sec, no_sec = [], [], [], []
key_re = re.compile(r'^\s*`\s*(GET|POST)\s+(/[^\s`]+)\s*`', re.M)
file_key = {}
for p in sorted(files):
txt = p.read_text(encoding='utf-8')
rel = str(p.relative_to(A4))
has_ph = '非真实返回' in txt
has_tv = 'E2E 实测真值' in txt
n_sec = len(re.findall(r'^\s*## 响应示例', txt, re.M))
m = key_re.search(txt)
if m:
file_key[rel] = f'{m.group(1)} {m.group(2)}'
if has_ph:
ph_files.append(rel)
if has_tv:
tv_files.append(rel)
if n_sec >= 2:
dual_sec.append(rel)
if n_sec == 0:
no_sec.append(rel)
print(f'[A] 含占位标记 = {len(ph_files)};含真值标记 = {len(tv_files)};双响应示例节 = {len(dual_sec)};无响应示例节 = {len(no_sec)}')
# ---------- 分组 ----------
ph_set, tv_set = set(ph_files), set(tv_files)
only_ph = sorted(ph_set - tv_set) # 有占位、无真值 → 必须写回数据
both = sorted(ph_set & tv_set) # 占位+真值并存 → 删占位块即可
print(f'[C] 占位+真值并存(删占位即可)= {len(both)}')
for r in both:
print(f' {r}')
print(f'[C] 占位且无真值(需写数据)= {len(only_ph)}')
for r in only_ph:
print(f' {r}')
# ---------- specimens 合并 ----------
merged = {}
for name in ['specimens-core-r3.json', 'specimens-heavy-r3.json', 'specimens-incr-r3.json',
'specimens-graph-r3.json', 'specimens-doc-truth.json']:
data = json.loads((SP / name).read_text(encoding='utf-8'))
for k, v in data.items():
merged.setdefault(k, {'src': [], 'v': v})['src'].append(name)
print(f'[D] {name}: {len(data)} 端点')
print(f'[D] 合并后唯一端点 = {len(merged)}')
# ---------- 对账钥匙 × specimens 覆盖 ----------
covered = missing = 0
missing_list = []
for rel, k in sorted(file_key.items()):
if k in merged:
covered += 1
else:
missing += 1
missing_list.append(f'{rel}{k}')
print(f'[D] 文件端点在 specimens 中 = {covered},缺 = {missing}')
for r in missing_list:
print(f' {r}')
Path('.scratch/customer-integration-ready/audit_t05_out.txt').write_text(
'\n'.join(['PH:' + r for r in ph_files] + ['TV:' + r for r in tv_files]
+ ['DUAL:' + r for r in dual_sec] + ['NOSEC:' + r for r in no_sec]
+ ['MISS:' + r for r in missing_list]),
encoding='utf-8')
print('[done] 明细 → audit_t05_out.txt')