fix(reboot): overlay live stockplatform freshness in slo scorecard
Some checks failed
CD Pipeline / workflow-shape (push) Successful in 0s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / tests (push) Successful in 59s
CD Pipeline / build-and-deploy (push) Successful in 4m37s
CD Pipeline / post-deploy-checks (push) Has been cancelled

This commit is contained in:
Your Name
2026-07-02 19:25:19 +08:00
parent 7aa196ba5a
commit dc32550f99
3 changed files with 252 additions and 1 deletions

View File

@@ -40,6 +40,135 @@ def load_latest_reboot_auto_recovery_slo_scorecard(
return payload
def apply_stockplatform_runtime_readback(
payload: dict[str, Any],
runtime_readback: dict[str, Any],
) -> None:
"""Overlay live StockPlatform public API data truth onto the scorecard."""
readback = _dict(runtime_readback.get("readback"))
freshness_status = str(readback.get("freshness_status") or "unknown")
ingestion_status = str(readback.get("ingestion_status") or "unknown")
freshness_blockers = _strings(readback.get("freshness_blockers"))
ingestion_blockers = _strings(readback.get("ingestion_blockers"))
latest_trading_date = str(readback.get("freshness_latest_trading_date") or "")
freshness_ok = freshness_status == "ok"
ingestion_ok = ingestion_status == "ok"
stockplatform = _dict(payload.setdefault("stockplatform_data_freshness", {}))
stockplatform.update(
{
"freshness_status": freshness_status,
"ingestion_status": ingestion_status,
"latest_trading_date": latest_trading_date,
"freshness_blockers": freshness_blockers,
"ingestion_blockers": ingestion_blockers,
"freshness_sla_source_count": _int(
readback.get("freshness_sla_source_count")
),
"freshness_source_count": _int(readback.get("freshness_source_count")),
"freshness_non_ok_source_count": _int(
readback.get("freshness_non_ok_source_count")
),
"live_runtime_overlay_applied": True,
}
)
required_checks = _dict(payload.setdefault("required_checks", {}))
required_checks["stockplatform_freshness_ok"] = freshness_ok
required_checks["stockplatform_ingestion_ok"] = ingestion_ok
if not (freshness_ok and ingestion_ok):
required_checks["product_data_green"] = False
payload["product_data_green"] = False
post_reboot = _dict(payload.setdefault("post_reboot_readiness", {}))
post_reboot["product_data_green"] = False
_append_live_stockplatform_blockers(
payload=payload,
freshness_status=freshness_status,
ingestion_status=ingestion_status,
freshness_blockers=freshness_blockers,
ingestion_blockers=ingestion_blockers,
)
completed_check_count = sum(1 for value in required_checks.values() if value)
readiness_percent = _percent(
completed_check_count / max(len(required_checks), 1) * 100
)
active_blockers = _strings(payload.get("active_blockers"))
active_blocker_count = len(active_blockers)
payload["active_blocker_count"] = active_blocker_count
payload["readiness_percent"] = readiness_percent
payload["stockplatform_freshness_status"] = freshness_status
payload["stockplatform_ingestion_status"] = ingestion_status
readback_section = _dict(payload.setdefault("readback", {}))
readback_section["active_blocker_count"] = active_blocker_count
readback_section["readiness_percent"] = readiness_percent
rollups = _dict(payload.setdefault("rollups", {}))
rollups["active_blocker_count"] = active_blocker_count
rollups["completed_check_count"] = completed_check_count
rollups["readiness_percent"] = readiness_percent
rollups["product_data_green"] = payload.get("product_data_green") is True
rollups["stockplatform_freshness_status"] = freshness_status
rollups["stockplatform_ingestion_status"] = ingestion_status
rollups["stockplatform_freshness_blocker_count"] = len(freshness_blockers)
rollups["stockplatform_ingestion_blocker_count"] = len(ingestion_blockers)
rollups["stockplatform_freshness_sla_source_count"] = _int(
readback.get("freshness_sla_source_count")
)
rollups["stockplatform_freshness_source_count"] = _int(
readback.get("freshness_source_count")
)
rollups["stockplatform_freshness_non_ok_source_count"] = _int(
readback.get("freshness_non_ok_source_count")
)
service_backup = _dict(
payload.setdefault("controlled_service_data_backup_readback", {})
)
service_backup["product_data_green"] = payload.get("product_data_green") is True
service_backup["stockplatform_freshness_status"] = freshness_status
service_backup["stockplatform_ingestion_status"] = ingestion_status
blocking_fields = _strings(service_backup.get("blocking_fields"))
if not freshness_ok:
blocking_fields.append("stockplatform_freshness_status")
if not ingestion_ok:
blocking_fields.append("stockplatform_ingestion_status")
if payload.get("product_data_green") is not True:
blocking_fields.append("product_data_green")
service_backup["blocking_fields"] = _unique_strings(blocking_fields)
service_backup["controlled_service_data_backup_blocker_count"] = len(
service_backup["blocking_fields"]
)
rollups["controlled_service_data_backup_blocker_count"] = len(
service_backup["blocking_fields"]
)
service_backup["status"] = "blocked_service_data_backup_readback_not_green"
service_backup["can_clear_service_data_backup_blockers"] = False
def _append_live_stockplatform_blockers(
*,
payload: dict[str, Any],
freshness_status: str,
ingestion_status: str,
freshness_blockers: list[str],
ingestion_blockers: list[str],
) -> None:
active_blockers = _strings(payload.get("active_blockers"))
active_blockers.append("product_data_green_not_1")
if freshness_status != "ok" and not freshness_blockers:
active_blockers.append("stockplatform_freshness_status_not_ok")
if ingestion_status != "ok" and not ingestion_blockers:
active_blockers.append("stockplatform_ingestion_status_not_ok")
active_blockers.extend(
f"stockplatform_freshness_{blocker}" for blocker in freshness_blockers
)
active_blockers.extend(
f"stockplatform_ingestion_{blocker}" for blocker in ingestion_blockers
)
payload["active_blockers"] = _unique_strings(active_blockers)
def _build_payload(scorecard: dict[str, Any], path: Path) -> dict[str, Any]:
host_boot_detection = _dict(scorecard.get("host_boot_detection"))
post_reboot_readiness = _dict(scorecard.get("post_reboot_readiness"))
@@ -764,5 +893,16 @@ def _strings(value: Any) -> list[str]:
return [str(item) for item in value if item is not None]
def _unique_strings(values: list[str]) -> list[str]:
seen: set[str] = set()
unique: list[str] = []
for value in values:
if value in seen:
continue
seen.add(value)
unique.append(value)
return unique
def _taipei_now_iso() -> str:
return datetime.now(ZoneInfo("Asia/Taipei")).isoformat(timespec="seconds")