0b1d377db7
Co-Authored-By: Claude Code <noreply@anthropic.com>
49 lines
1.4 KiB
Python
49 lines
1.4 KiB
Python
"""E0-lite 数据健康——「数据截至」角标 + 实体新鲜度。
|
|
|
|
完整 E0(调度日志解析/成功率账本)二批;v1 用表新鲜度判定:
|
|
msg_daily_stats 当日有行 = 4h 消息链路活着。
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import datetime as dt
|
|
|
|
import sqlalchemy as sa
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
|
|
from app.db.models import (
|
|
ChatGroup,
|
|
Customer,
|
|
Media,
|
|
Message,
|
|
MomentsPost,
|
|
MsgDailyStats,
|
|
PhoneCall,
|
|
)
|
|
|
|
|
|
async def data_as_of(session: AsyncSession) -> int | None:
|
|
"""数据截至(ms-epoch)= MAX(msg_daily_stats.last_ts)。"""
|
|
val = (
|
|
await session.execute(sa.select(sa.func.max(MsgDailyStats.last_ts)))
|
|
).scalar_one_or_none()
|
|
return int(val) if val is not None else None
|
|
|
|
|
|
async def entity_freshness(session: AsyncSession) -> list[dict]:
|
|
"""各实体最后更新时间(UPDATED_AT 列 MAX;message 用 fetched_at)。"""
|
|
|
|
async def _max(col) -> dt.datetime | None:
|
|
return (await session.execute(sa.select(sa.func.max(col)))).scalar_one_or_none()
|
|
|
|
out = []
|
|
for name, col in (
|
|
("customer", Customer.updated_at),
|
|
("chat_group", ChatGroup.updated_at),
|
|
("phone_call", PhoneCall.updated_at),
|
|
("media", Media.updated_at),
|
|
("moments_post", MomentsPost.updated_at),
|
|
("message", Message.fetched_at),
|
|
):
|
|
out.append({"table": name, "last_seen": await _max(col)})
|
|
return out
|