mirror of
https://github.com/ZhuLinsen/daily_stock_analysis
synced 2026-09-20 10:53:33 +08:00
fix: preserve malformed region snapshot failures
This commit is contained in:
@@ -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 文本猜测。
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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 = [
|
||||
|
||||
Reference in New Issue
Block a user