fix: preserve multi-cause reconcile warnings and align slot blocking
Co-authored-by: genichin <4282227+genichin@users.noreply.github.com>
This commit is contained in:
co-authored by
genichin
parent
e47bebacaf
commit
45a5e4157d
@@ -263,28 +263,24 @@ def make_slots_rpc_handler(
|
||||
for s in holding_slots:
|
||||
watchdog_store.update(str(s.slot_id))
|
||||
|
||||
# Build merged slot rows (REQ-074)
|
||||
# BAT-050 / REQ-104: warn_store passed to slot_to_dict for reconcile_warned field.
|
||||
slot_rows = [
|
||||
slot_to_dict(
|
||||
s,
|
||||
snapshot_store=snapshot_store,
|
||||
watchdog_store=watchdog_store,
|
||||
pause_store=pause_store,
|
||||
warn_store=warn_store,
|
||||
watchdog_timeout_sec=watchdog_timeout_sec,
|
||||
)
|
||||
for s in slots
|
||||
]
|
||||
|
||||
# AC-0023 exclusion must precede all optional data readers so excluded
|
||||
# slots cannot expose state or make an otherwise valid response fail.
|
||||
excluded_count = 0
|
||||
warning_cases_by_slot: dict[str, set[str]] = {}
|
||||
if warn_store is not None:
|
||||
try:
|
||||
c_warned_ids = warn_store.list_c_case_warned()
|
||||
warned_slot_ids = warn_store.list_warned()
|
||||
for sid in warned_slot_ids:
|
||||
info = warn_store.get_warning_info(sid)
|
||||
if info is None:
|
||||
continue
|
||||
raw_codes = info.get("case_codes")
|
||||
if isinstance(raw_codes, list):
|
||||
codes = {str(code) for code in raw_codes if code}
|
||||
else:
|
||||
case_code = str(info.get("case_code", ""))
|
||||
codes = {case_code} if case_code else set()
|
||||
if codes:
|
||||
warning_cases_by_slot[str(sid)] = codes
|
||||
except Exception: # noqa: BLE001
|
||||
_log.exception("warn_store.list_c_case_warned() failed — fail-closed")
|
||||
_log.exception("warn_store warning query failed — fail-closed")
|
||||
return RpcResponse(payload={
|
||||
"slots": [],
|
||||
"available_slots": None,
|
||||
@@ -296,18 +292,42 @@ def make_slots_rpc_handler(
|
||||
),
|
||||
"excluded_slots": {"reconcile_quantity_mismatch": 0},
|
||||
})
|
||||
if c_warned_ids:
|
||||
included = [
|
||||
(slot, row)
|
||||
for slot, row in zip(slots, slot_rows, strict=True)
|
||||
if not (
|
||||
slot.status.value == "holding"
|
||||
and str(slot.slot_id) in c_warned_ids
|
||||
)
|
||||
]
|
||||
excluded_count = len(slots) - len(included)
|
||||
|
||||
# Build merged slot rows (REQ-074)
|
||||
slot_rows = [
|
||||
slot_to_dict(
|
||||
s,
|
||||
snapshot_store=snapshot_store,
|
||||
watchdog_store=watchdog_store,
|
||||
pause_store=pause_store,
|
||||
warning_cases_by_slot=warning_cases_by_slot,
|
||||
watchdog_timeout_sec=watchdog_timeout_sec,
|
||||
)
|
||||
for s in slots
|
||||
]
|
||||
|
||||
# Exclusion must precede all optional data readers so blocked slots cannot
|
||||
# expose state or make an otherwise valid response fail.
|
||||
excluded_count = 0
|
||||
excluded_case_counts: dict[str, int] = {}
|
||||
if warn_store is not None:
|
||||
included: list[tuple[object, dict]] = []
|
||||
for slot, row in zip(slots, slot_rows, strict=True):
|
||||
blocked_holding = (
|
||||
slot.status.value == "holding" and bool(row.get("reconcile_warned"))
|
||||
)
|
||||
if blocked_holding:
|
||||
excluded_count += 1
|
||||
for code in row.get("reconcile_warning_cases", []):
|
||||
excluded_case_counts[code] = excluded_case_counts.get(code, 0) + 1
|
||||
continue
|
||||
included.append((slot, row))
|
||||
if included:
|
||||
slots = [slot for slot, _ in included]
|
||||
slot_rows = [row for _, row in included]
|
||||
else:
|
||||
slots = []
|
||||
slot_rows = []
|
||||
|
||||
broker_qty_by_symbol: dict[str, int] = {}
|
||||
broker_qty_available = False
|
||||
@@ -410,7 +430,10 @@ def make_slots_rpc_handler(
|
||||
"message": message,
|
||||
}
|
||||
if warn_store is not None:
|
||||
base_payload["excluded_slots"] = {"reconcile_quantity_mismatch": excluded_count}
|
||||
base_payload["excluded_slots"] = {
|
||||
"reconcile_quantity_mismatch": excluded_count,
|
||||
"reconcile_warning_cases": excluded_case_counts,
|
||||
}
|
||||
return RpcResponse(payload=base_payload)
|
||||
|
||||
return handler
|
||||
|
||||
Reference in New Issue
Block a user