feat: add assessment workbench and September reconciliation

Preserve August hydrogen revision and September audit evidence; calculate interrupted vehicle history across all prior months. Record remaining carry-policy and layout-baseline discrepancies.
This commit is contained in:
shishengliang
2026-10-09 18:21:45 +08:00
parent 3ed3548b9d
commit 65904c8270
108 changed files with 1368801 additions and 3 deletions
+33
View File
@@ -0,0 +1,33 @@
"""对运行中的开发代理和本机 API 执行虚构样本集成检查。"""
import json
from pathlib import Path
from urllib.request import Request, urlopen
from urllib.error import HTTPError
from io import BytesIO
from openpyxl import load_workbook
BASE='http://127.0.0.1:5173/api'
def call(path, data=None):
headers={'Content-Type':'application/octet-stream'}
if isinstance(data,dict):
data=json.dumps(data).encode(); headers={'Content-Type':'application/json'}
with urlopen(Request(BASE+path,data=data,headers=headers)) as r: return json.loads(r.read())
samples=Path(__file__).parent/'.data'/'samples'
lease=call('/imports/leases',(samples/'demo-leases.xlsx').read_bytes())
mileage=call('/imports/mileage?source=tbox&provider=vehicle-platform',(samples/'demo-mileage.xlsx').read_bytes())
config=json.loads((Path(__file__).parents[1]/'assessment_service/example_config.json').read_text())
config['month']='2026-08'; config['rules'][0].update(valid_from='2026-08-01',valid_to='2026-08-31')
body={'lease_import_id':lease['id'],'mileage_import_ids':[mileage['id']],'config':config}
a=call('/assessments',body); full=call('/assessments/'+a['id'])
assert a['status']=='ready',a
assert full['records'][0]['实际行驶里程(km)']==3720
assert len(full['daily_trace'])==31
assert call('/assessments',body)['id']==a['id']
with urlopen(BASE+'/assessments/'+a['id']+'/export.xlsx') as r:
wb=load_workbook(BytesIO(r.read()),read_only=True); assert wb.active.max_row==2; wb.close()
# 无里程产生异常,禁止导出。
body['mileage_import_ids']=[]
b=call('/assessments',body)
assert b['status']=='needs_review'
try: urlopen(BASE+'/assessments/'+b['id']+'/export.xlsx'); raise AssertionError('应拒绝导出')
except HTTPError as e: assert e.code==409
print('PASS: 上传、代理、3720 km 试算、31日依据、幂等快照、Excel导出、缺失拦截与409。')