feat(risk): show live countdown on freeze status badges

Expose freeze_until_ms from risk API and tick hub/instance badges with remaining 1h/4h/daily time.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-06-18 17:41:04 +08:00
parent 0280b4f065
commit 97370926d6
15 changed files with 272 additions and 41 deletions
+38
View File
@@ -405,6 +405,44 @@ def apply_manual_close_journal_cooloff(
)
def _next_trading_day_reset_ms(now: datetime, reset_hour: int) -> int:
from datetime import timedelta
h = max(0, min(23, int(reset_hour)))
candidate = now.replace(hour=h, minute=0, second=0, microsecond=0)
if now >= candidate:
candidate = candidate + timedelta(days=1)
return _now_ms(candidate)
def enrich_risk_status_countdown(
st: dict[str, Any],
*,
now: Optional[datetime] = None,
daily_reset_hour: int = 8,
) -> dict[str, Any]:
"""补充 freeze_until_ms / freeze_remaining_sec,供前端倒计时展示。"""
if not st.get("enabled", True):
return st
dt = now or datetime.now()
now_ms = _now_ms(dt)
until_ms: Optional[int] = None
if st.get("daily_frozen"):
until_ms = _next_trading_day_reset_ms(dt, daily_reset_hour)
elif st.get("cooloff_until_ms"):
try:
until_ms = int(st["cooloff_until_ms"])
except (TypeError, ValueError):
until_ms = None
if until_ms is not None and until_ms > now_ms:
st["freeze_until_ms"] = until_ms
st["freeze_remaining_sec"] = max(0, (until_ms - now_ms) // 1000)
else:
st["freeze_until_ms"] = None
st["freeze_remaining_sec"] = 0
return st
def compute_account_risk_status(
conn,
*,