feat: improve webhook filtering, worker status startup handling, and timestamp parsing
- Skip half_hour_report events from webhook posts in people_flow - Handle pre-existing stale worker status files during startup gracefully - Make store_dwell_alert timestamp parsing robust against invalid/empty values - Update lessons learned and todo documentation Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -212,23 +212,25 @@ def _build_summary(ctx: ManageContext) -> dict:
|
||||
continue
|
||||
|
||||
if payload.get("event") == "half_hour_report":
|
||||
last_report_time = _string_value(payload.get("window_end"))
|
||||
active_count = _int_value(payload.get("active_customer_count"))
|
||||
stat = _build_window_stat(payload)
|
||||
window_stats.append(stat)
|
||||
longest_dwell_seconds = max(
|
||||
longest_dwell_seconds,
|
||||
stat["max_wait_seconds"],
|
||||
)
|
||||
queue_level = stat["queue_level"]
|
||||
over_threshold_count = stat["over_threshold_count"]
|
||||
under_threshold_count = stat["under_threshold_count"]
|
||||
status_change = stat["status_change"]
|
||||
|
||||
window_stats.sort(
|
||||
key=lambda item: _parse_timestamp(item["window_end"]),
|
||||
reverse=True,
|
||||
)
|
||||
window_stats.sort(key=lambda item: _sort_timestamp(item["window_end"]), reverse=True)
|
||||
|
||||
for stat in window_stats:
|
||||
if _parse_timestamp(stat["window_end"]) is None:
|
||||
continue
|
||||
last_report_time = stat["window_end"]
|
||||
active_count = stat["active_customer_count"]
|
||||
queue_level = stat["queue_level"]
|
||||
over_threshold_count = stat["over_threshold_count"]
|
||||
under_threshold_count = stat["under_threshold_count"]
|
||||
status_change = stat["status_change"]
|
||||
break
|
||||
|
||||
headline = "No reports yet"
|
||||
if last_report_time:
|
||||
@@ -411,8 +413,20 @@ def _latest_timestamp(*values: str) -> str:
|
||||
return latest_raw
|
||||
|
||||
|
||||
def _parse_timestamp(value: str) -> datetime:
|
||||
parsed = datetime.fromisoformat(value)
|
||||
def _sort_timestamp(value: str) -> tuple[int, datetime]:
|
||||
parsed = _parse_timestamp(value)
|
||||
if parsed is None:
|
||||
return (0, datetime.min.replace(tzinfo=datetime.now().astimezone().tzinfo))
|
||||
return (1, parsed)
|
||||
|
||||
|
||||
def _parse_timestamp(value: str) -> datetime | None:
|
||||
if not value.strip():
|
||||
return None
|
||||
try:
|
||||
parsed = datetime.fromisoformat(value)
|
||||
except ValueError:
|
||||
return None
|
||||
if parsed.tzinfo is None:
|
||||
return parsed.replace(tzinfo=datetime.now().astimezone().tzinfo)
|
||||
return parsed
|
||||
|
||||
Reference in New Issue
Block a user