{
  "ok": false,
  "severity": "attention",
  "checkedAt": "2026-06-18T12:03:13.233Z",
  "data": {
    "generatedAt": "2026-06-18T04:00:54.466Z",
    "temporalUpdatedAt": "2026-06-18T12:03:13.252Z",
    "dataAgeHours": 0,
    "sourceDataAgeHours": 8,
    "teams": 48,
    "matches": 104,
    "finished": 23,
    "inProgress": 0,
    "pendingResults": 1,
    "finishedWithoutTimeline": 0,
    "scoringTimelineMismatches": 0,
    "malformedScoringEvents": 0,
    "squadShortfalls": 0,
    "fullSquadPlayers": 1248,
    "defaultMatchId": "m28",
    "modelVersion": "wc-analytics-v2.1-agentic-202606182003"
  },
  "staticFallback": {
    "generatedAt": "2026-06-18T04:00:54.466Z",
    "temporalUpdatedAt": "2026-06-18T09:12:02.636Z",
    "dataAgeHours": 2.9,
    "sourceDataAgeHours": 8,
    "teams": 48,
    "matches": 104,
    "finished": 24,
    "inProgress": 0,
    "defaultMatchId": "m28",
    "usable": true,
    "alignedWithLive": false,
    "alignmentStatus": "lagging",
    "maxAgeHours": 48
  },
  "dynamicPages": {
    "matchRoute": "/matches/*",
    "teamRoute": "/teams/*",
    "tournamentRoute": "/tournament/*",
    "sourcePreference": "live-agent-first",
    "fallback": "static-package",
    "cacheSeconds": 60,
    "enabled": true
  },
  "calendar": {
    "fullSchedule": "/calendar/worldcup-2026.ics",
    "singleMatchRoute": "/calendar/match/<matchId>.ics",
    "reminderMinutesBeforeKickoff": 30,
    "enabled": true
  },
  "agent": {
    "lastStartedAt": "2026-06-18T11:40:54.467Z",
    "silenceMinutes": 22.3,
    "lastError": null,
    "staticSync": {
      "configured": false,
      "triggered": false,
      "reason": "waiting-for-first-score-change"
    },
    "reason": "post-match-window-throttled",
    "nextPostMatchRefreshAt": "2026-06-18T17:55:00.000Z",
    "watchedMatches": [
      {
        "id": "m23",
        "home": "uzb",
        "away": "col",
        "homeName": "Uzbekistan",
        "awayName": "Colombia",
        "kickoffAt": "2026-06-18T02:00:00.000Z",
        "expectedRefreshStartAt": "2026-06-18T03:55:00.000Z",
        "expectedRefreshEndAt": "2026-06-18T11:55:00.000Z"
      }
    ],
    "nextWatchedMatches": [
      {
        "id": "m28",
        "home": "cze",
        "away": "rsa",
        "homeName": "Czech Republic",
        "awayName": "South Africa",
        "kickoffAt": "2026-06-18T16:00:00.000Z",
        "expectedRefreshStartAt": "2026-06-18T17:55:00.000Z",
        "expectedRefreshEndAt": "2026-06-19T01:55:00.000Z"
      },
      {
        "id": "m26",
        "home": "sui",
        "away": "bih",
        "homeName": "Switzerland",
        "awayName": "Bosnia and Herzegovina",
        "kickoffAt": "2026-06-18T19:00:00.000Z",
        "expectedRefreshStartAt": "2026-06-18T20:55:00.000Z",
        "expectedRefreshEndAt": "2026-06-19T04:55:00.000Z"
      },
      {
        "id": "m27",
        "home": "can",
        "away": "qat",
        "homeName": "Canada",
        "awayName": "Qatar",
        "kickoffAt": "2026-06-18T22:00:00.000Z",
        "expectedRefreshStartAt": "2026-06-18T23:55:00.000Z",
        "expectedRefreshEndAt": "2026-06-19T07:55:00.000Z"
      },
      {
        "id": "m25",
        "home": "mex",
        "away": "kor",
        "homeName": "Mexico",
        "awayName": "South Korea",
        "kickoffAt": "2026-06-19T01:00:00.000Z",
        "expectedRefreshStartAt": "2026-06-19T02:55:00.000Z",
        "expectedRefreshEndAt": "2026-06-19T10:55:00.000Z"
      },
      {
        "id": "m31",
        "home": "usa",
        "away": "aus",
        "homeName": "United States",
        "awayName": "Australia",
        "kickoffAt": "2026-06-19T19:00:00.000Z",
        "expectedRefreshStartAt": "2026-06-19T20:55:00.000Z",
        "expectedRefreshEndAt": "2026-06-20T04:55:00.000Z"
      }
    ],
    "watchCoverage": {
      "watchNeeded": true,
      "monitoredCount": 6,
      "watchedCount": 1,
      "nextWatchedCount": 5,
      "unfinishedCount": 81,
      "inProgressCount": 0,
      "pendingCount": 1,
      "inProgressUnwatched": [],
      "pendingUnwatched": [],
      "nextRefreshLagMinutes": -351.8,
      "postMatchWatchCoverageOk": true,
      "inProgressWatchCoverageOk": true,
      "nextRefreshScheduleOk": true,
      "detail": "6 monitored / 81 unfinished",
      "inProgressDetail": "0/0 live · 1/1 pending covered",
      "scheduleDetail": "2026-06-18T17:55:00.000Z · lag -351.8m"
    },
    "watchedCount": 1,
    "nextWatchedCount": 5,
    "recentRuns": 12
  },
  "incidents": [
    {
      "type": "static-live-drift",
      "level": "attention",
      "label": "实时包与静态包不完全一致",
      "detail": "lagging; live agent is primary",
      "action": "动态页面已优先读取实时包；下一次内容部署时同步静态兜底和 SEO 文件。"
    },
    {
      "type": "pending-result",
      "level": "risk",
      "matchId": "m23",
      "label": "Uzbekistan vs Colombia",
      "detail": "m23 · 比赛时间已过但赛果仍待确认 · 赛果待确认",
      "action": "核对公开赛果源；若超过赛后窗口仍未更新，人工确认比分并重建数据包。",
      "matchPage": "/matches/m23/"
    }
  ],
  "checks": [
    {
      "key": "dataReachable",
      "ok": true,
      "label": "数据接口可访问",
      "detail": "",
      "level": "risk",
      "action": "若失败，先查看 Worker /api/status，再确认 Pages /api/data 的 live-to-static fallback 是否可用。"
    },
    {
      "key": "dataFresh",
      "ok": true,
      "label": "页面时间状态新鲜度",
      "detail": "0h",
      "level": "risk",
      "action": "超过阈值时先等待下一次 Cron；若 30 分钟仍未恢复，检查 Worker Cron 和上游赛果源。"
    },
    {
      "key": "sourceDataFresh",
      "ok": true,
      "label": "上游赛果成功抓取",
      "detail": "8h",
      "level": "ok",
      "action": "按每场比赛结束后的赛后窗口刷新；若比分已确认但未更新，按 runbook 手动重建数据。"
    },
    {
      "key": "staticFallbackReachable",
      "ok": true,
      "label": "静态兜底包可访问",
      "detail": "",
      "level": "risk",
      "action": "若失败，重新运行 npm run build:seo 与 deploy:cloudflare，确认 /data/worldcup-real-data.json 可访问。"
    },
    {
      "key": "staticFallbackUsable",
      "ok": true,
      "label": "静态兜底包可用性",
      "detail": "2.9h / 104 matches",
      "level": "risk",
      "action": "静态包不可用时立即重新部署；它是 Worker 失败时的兜底数据源。"
    },
    {
      "key": "staticLiveAligned",
      "ok": true,
      "label": "实时与静态数据对齐",
      "detail": "lagging; live agent is primary",
      "level": "attention",
      "action": "实时包可用时前台和比赛详情页仍会更新；赛果稳定后运行 update_and_deploy.ps1，同步静态兜底 JSON、日历、球队页和 sitemap。"
    },
    {
      "key": "liveOperationsClean",
      "ok": true,
      "label": "实时包运营文案",
      "detail": "clean",
      "level": "risk",
      "action": "发现旧小程序或 6-12 小时文案时，重新生成数据包并部署。"
    },
    {
      "key": "staticOperationsClean",
      "ok": true,
      "label": "静态包运营文案",
      "detail": "clean",
      "level": "risk",
      "action": "静态包出现旧文案时，运行 update_and_deploy.ps1 重新生成静态兜底包。"
    },
    {
      "key": "matchCount",
      "ok": true,
      "label": "赛程数量",
      "detail": "104",
      "level": "risk",
      "action": "数量异常时不要发布新版本，先检查上游赛程解析和静态数据包。"
    },
    {
      "key": "teamCount",
      "ok": true,
      "label": "球队数量",
      "detail": "48",
      "level": "risk",
      "action": "球队数量异常时不要发布新版本，先检查 FIFA 阵容和 teamList 生成。"
    },
    {
      "key": "squadCoverage",
      "ok": true,
      "label": "完整阵容覆盖",
      "detail": "1248 players",
      "level": "ok",
      "action": "每队应保留 26 人完整阵容；若不足，先重新生成 FIFA 阵容包再部署。"
    },
    {
      "key": "scoringTimelineConsistency",
      "ok": true,
      "label": "比分与进球记录一致",
      "detail": "clean",
      "level": "ok",
      "action": "例如 4-1 必须有 5 条进球事件；发现不一致时先修复 scoringEvents 再发布。"
    },
    {
      "key": "scoringEventFields",
      "ok": true,
      "label": "进球事件字段完整",
      "detail": "clean",
      "level": "ok",
      "action": "每条进球事件必须包含分钟、球员、主客队 side 和对应 teamId。"
    },
    {
      "key": "agentReachable",
      "ok": true,
      "label": "自动更新智能体可访问",
      "detail": "",
      "level": "risk",
      "action": "若不可访问，运行 wrangler deployments/tail 检查 Worker；前台会继续使用静态兜底。"
    },
    {
      "key": "agentRecent",
      "ok": true,
      "label": "智能体最近运行",
      "detail": "22.3m",
      "level": "risk",
      "action": "超过 30 分钟且没有明确赛后窗口时检查 Cloudflare Cron Triggers 和 Worker 日志。"
    },
    {
      "key": "agentLastRun",
      "ok": true,
      "label": "最近刷新结果",
      "detail": "ok",
      "level": "ok",
      "action": "最近一次失败时先看 status.recentRuns；若连续失败，再查看 Worker tail 和上游 fetch 状态。"
    },
    {
      "key": "staticSyncWebhook",
      "ok": true,
      "label": "静态同步触发器",
      "detail": "waiting-for-first-score-change",
      "level": "ok",
      "action": "配置 STATIC_SYNC_WEBHOOK_URL 后，赛果变化可自动触发静态兜底、日历、球队页和 sitemap 同步；比赛详情页已由动态函数读取实时包。"
    },
    {
      "key": "postMatchWatchCoverage",
      "ok": true,
      "label": "赛后监控覆盖",
      "detail": "6 monitored / 81 unfinished",
      "level": "ok",
      "action": "有赛中、待确认或未完赛赛程时，Worker 必须返回当前或下一批 watched matches；缺失时检查 Cron、fixture 时区和 status.nextWatchedMatches。"
    },
    {
      "key": "inProgressWatchCoverage",
      "ok": true,
      "label": "赛中比赛监控",
      "detail": "0/0 live · 1/1 pending covered",
      "level": "ok",
      "action": "赛中比赛必须进入当前或下一批监控名单，保证预计结束后自动拉取赛果。"
    },
    {
      "key": "nextRefreshSchedule",
      "ok": true,
      "label": "下一次赛后检测排期",
      "detail": "2026-06-18T17:55:00.000Z · lag -351.8m",
      "level": "ok",
      "action": "若下一次检测时间缺失或落后超过 30 分钟，打开 Worker /api/status 并确认 Cron Triggers 正常。"
    },
    {
      "key": "dynamicMatchPages",
      "ok": true,
      "label": "动态比赛落地页",
      "detail": "/matches/* reads live data first",
      "level": "ok",
      "action": "比赛详情页通过 Pages Function 读取 Worker 实时包，静态文件只作为兜底和搜索发现资产。"
    },
    {
      "key": "dynamicTeamPages",
      "ok": true,
      "label": "动态球队落地页",
      "detail": "/teams/* reads live data first",
      "level": "ok",
      "action": "球队详情页通过 Pages Function 读取 Worker 实时包，阵容、赛果和赛程说明与前台数据保持一致。"
    },
    {
      "key": "dynamicTournamentPage",
      "ok": true,
      "label": "动态赛事结构页",
      "detail": "/tournament/* reads live data first",
      "level": "ok",
      "action": "赛事结构页通过 Pages Function 读取 Worker 实时包，小组积分、第三名竞争和淘汰赛路径与当前赛果保持一致。"
    },
    {
      "key": "singleMatchCalendar",
      "ok": true,
      "label": "单场日历提醒",
      "detail": "/calendar/match/<matchId>.ics",
      "level": "ok",
      "action": "每场比赛可下载独立 ICS，包含 30 分钟提醒；全赛程 ICS 继续作为静态订阅文件。"
    },
    {
      "key": "eventTimelineCoverage",
      "ok": true,
      "label": "已完赛事件流覆盖",
      "detail": "0",
      "level": "ok",
      "action": "公开源没有事件流时先保留透明说明；若能找到可靠事件来源，再补 scoringEvents。"
    },
    {
      "key": "noPendingResults",
      "ok": false,
      "label": "赛果待确认",
      "detail": "1",
      "level": "risk",
      "action": "待确认通常等公开源更新；若比赛结束超过赛后窗口仍未确认，人工核对公开源并重建数据。"
    }
  ]
}