fix: preserve malformed region snapshot failures

This commit is contained in:
ZhuLinsen
2026-08-29 22:02:08 +08:00
parent 8adb598c14
commit b91d73781f
3 changed files with 26 additions and 0 deletions

View File

@@ -32,6 +32,7 @@
- 历史详情读取失败、投影出的 `context_snapshot` 不是 JSON object或其中已存在的 `market_light_snapshots` 不是 object例如损坏的 JSON 字符串/数组)时,不再把其余更旧记录提升为 current/latest对应快照和变化对比保持不可用并返回 limitation。
- 快照校验失败时仍保留其 `trade_date` 的目标位置:最新日期无有效快照时不回退到更旧 current最近更早日期无有效快照时不越过它继续寻找更旧 previous。同一目标日期存在其他有效重跑快照时仍可使用该日期的有效版本。
- 外层市场键必须与快照内部 `region` 一致;例如 `cn` 键下的 `region=us` 快照会按无效快照处理,不能进入 A 股的 current/previous 或变化项。
- `market_light_snapshots` object 中任何已出现的 region 条目都必须仍是 object例如最新记录里的 `cn: []` 会把 CN current 标为不可用,不能被过滤后再让旧 CN 快照冒充最新。
- 历史扫描被截断等 market limitations 会同步进入 what_changed剩余快照不能在来源历史不完整时被标记为 fresh。
后续阶段可以在已有持久化契约上增加 watchlist score、portfolio exposure、ranking 和 thesis invalidation 变化;必须先有可靠的 current/previous snapshot identity不能从页面当前分页或 target 文本猜测。

View File

@@ -92,6 +92,11 @@ class DashboardOverviewService:
if snapshot_container is not None and not isinstance(snapshot_container, dict):
detail_failure_count += 1
continue
for raw_region, raw_snapshot in (snapshot_container or {}).items():
region = str(raw_region).strip().lower()
if region and not isinstance(raw_snapshot, dict):
invalid_snapshot_count += 1
regions_with_unknown_trade_date.add(region)
raw_snapshots = self._extract_snapshots(context_snapshot)
for region, raw_snapshot in raw_snapshots.items():
raw_trade_date = str(raw_snapshot.get("trade_date") or "").strip()

View File

@@ -316,6 +316,26 @@ def test_malformed_nested_snapshot_container_does_not_promote_older_snapshots()
assert "latest_completed_snapshot_unavailable" in payload["market"]["meta"]["limitations"]
def test_malformed_region_snapshot_does_not_promote_older_region_snapshot() -> None:
dependencies = _dependencies()
original_detail = dependencies["history_service"].get_history_detail_by_id.side_effect
def detail_with_malformed_region(record_id: int) -> dict:
if record_id == 1:
return {"context_snapshot": {"market_light_snapshots": {"cn": []}}}
return original_detail(record_id)
dependencies["history_service"].get_history_detail_by_id.side_effect = detail_with_malformed_region
payload = DashboardOverviewService(**dependencies).get_overview()
assert payload["market"]["data"]["latest_snapshots"] == {}
assert payload["what_changed"]["data"]["current_trade_dates"] == {}
assert payload["what_changed"]["data"]["items"] == []
assert "invalid_market_light_snapshot_skipped" in payload["market"]["meta"]["limitations"]
assert "latest_completed_snapshot_unavailable:cn" in payload["market"]["meta"]["limitations"]
def test_invalid_latest_snapshot_does_not_promote_an_older_trade_date() -> None:
dependencies = _dependencies()
reviews = [