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.
89 lines
3.2 KiB
89 lines
3.2 KiB
# -*- 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')
|
|
|