Add monitoring service and database schema

- Implement monitoring service with heartbeat, lease tasks, resume tasks, and task result handling.
- Create monitoring time utilities for business date calculations.
- Add unit tests for date window resolution and business day handling.
- Define database schema for monitoring-related tables including quotas, daily reports, and task management.
- Establish migration scripts for creating and dropping monitoring tables.
This commit is contained in:
2026-04-12 09:56:18 +08:00
parent 9b4dd09780
commit 6066f43a7d
67 changed files with 16312 additions and 125 deletions
+132 -1
View File
@@ -50,6 +50,8 @@ const enUS = {
upgrade: "Upgrade",
copy: "Copy",
copySuccess: "Content copied",
yes: "Yes",
no: "No",
},
nav: {
workspace: "Workspace",
@@ -123,7 +125,11 @@ const enUS = {
},
tracking: {
title: "Data Details",
description: "No matching backend APIs exist in this repository yet.",
description: "Inspect plugin-sampled brand performance, platform coverage, hot questions, and citation attribution.",
},
trackingQuestion: {
title: "Question Detail",
description: "Inspect answer content, citation sources, citation analysis, and content citations for a single question.",
},
knowledge: {
title: "Knowledge Base",
@@ -155,6 +161,131 @@ const enUS = {
emptyTemplates: "No template cards available yet",
noRecentArticles: "No recent generations yet",
},
tracking: {
eyebrow: "AI Brand Monitoring",
brandPlaceholder: "Select brand",
keywordPlaceholder: "Select keyword",
collectNow: "Collect Now",
collectKeywordRequired: "Select a keyword before collecting the current question set.",
pluginMode: "Plugin sampling",
pluginHint: "Plugin-mode data depends on device uptime. Low coverage should be treated as directional only.",
awaitingSnapshot: "Waiting for the next valid snapshot",
infoStrip:
"{mode} · target {desired} · planned {planned} · sampled {actual} · coverage {coverage} · updated {updatedAt} · {trigger}",
latestSnapshot: "Latest Snapshot",
coverage: "Coverage",
coverageTitle: "Sampling Coverage",
coverageSummary: "Target {desired} · Sampled {actual} · Coverage {coverage}",
platformMatrix: "Platform Matrix",
platformMatrixTitle: "Platform Comparison Matrix",
hotQuestions: "Hot Questions",
hotQuestionsTitle: "Hot Questions",
hotQuestionsHint: "Questions come from the brand library under the selected keyword.",
questionSearchPlaceholder: "Search questions under the selected keyword",
questionDetailEyebrow: "Question Detail",
questionDetailCollectedAt: "Collected at {time}",
questionDetailFallback: "Question Detail",
backToQuestions: "Back to questions",
citationRanking: "Citation Ranking",
citationRankingTitle: "Citation Ranking",
citationRankingHint: "Track how often content published from this system appears across model answers.",
citedArticles: "Cited Articles",
citedArticlesTitle: "Cited Articles",
answerContent: "Answer Content",
citationSources: "Citation Sources",
citationSourcesTitle: "Citation Sources",
citationAnalysis: "Citation Analysis",
citationAnalysisTitle: "Citation Analysis",
contentCitations: "Content Citations",
contentCitationsTitle: "Content Citations",
taskDebugTitle: "Async Task Debug",
taskDebugHint: "For troubleshooting the callback -> queue -> worker flow only. The four main content sections above stay unchanged.",
contentCitationBadge: "Content Citation",
noQuestions: "No hot questions for the current filters",
noCitationRanking: "No attributable citations in the current window",
noCitedArticles: "No content citations in the current window",
noAnswer: "No sampled answer for this platform",
noCitations: "No citations for this platform",
noCitationAnalysis: "No citation analysis for this platform",
noContentCitations: "No content citations for the active platform",
noTaskDebug: "No async task debug data for the current filters",
samples: "samples",
citations: "citations",
citedArticleMeta: "{count} cited articles",
contentCitationMeta: "{count} content references",
manual: "Manual",
automatic: "Automatic",
noChange: "Flat",
metrics: {
mentionRate: "Mention Rate",
top1MentionRate: "Top-1 Mention Rate",
firstRecommendRate: "First Recommendation Rate",
positiveMentionRate: "Positive Mention Rate",
},
columns: {
platform: "Platform",
appearances: "Appearances",
citedAnswers: "Cited Answers",
citedArticles: "Cited Articles",
citationRate: "Citation Rate",
citations: "Citations",
sourcePlatform: "Source",
domain: "Domain",
share: "Share",
contentName: "Content",
publishPlatform: "Publish Platform",
distinctSites: "Distinct Sites",
brandContent: "Has Brand Content",
},
status: {
sampled: "Sampled",
partial: "Partially Sampled",
unsampled: "Unsampled",
pending: "Pending",
not_logged_in: "Not Logged In",
unavailable: "Unavailable",
},
confidence: {
high: "High confidence",
medium: "Medium confidence",
low: "Low confidence",
},
taskDebug: {
labels: {
plannedAt: "Planned At",
leasedAt: "Leased At",
callbackReceivedAt: "Callback Received At",
queueEnqueuedAt: "Queued At",
completedAt: "Completed At",
leaseExpiresAt: "Lease Expires At",
runId: "Run ID",
runStatus: "Run Status",
providerModel: "Model",
requestId: "Request ID",
providerRequestId: "Provider Request ID",
receivedAlertCount: "Received Alert Count",
receivedAlertedAt: "Last Alerted At",
skipReason: "Skip Reason",
errorMessage: "Task Error",
lastQueuePublishError: "Queue Publish Error",
},
taskStatus: {
pending: "Pending",
leased: "Leased",
received: "Received",
completed: "Completed",
failed: "Failed",
skipped: "Skipped",
expired: "Expired",
},
queueStatus: {
pending: "Pending Queue",
queued: "Queued",
publish_failed: "Publish Failed",
invalid_payload: "Invalid Payload",
},
},
},
templateMeta: {
top_x_article: {
eyebrow: "Ranked Content",
+132 -1
View File
@@ -50,6 +50,8 @@ const zhCN = {
upgrade: "去升级",
copy: "复制",
copySuccess: "内容已复制",
yes: "是",
no: "否",
},
nav: {
workspace: "工作台",
@@ -123,7 +125,11 @@ const zhCN = {
},
tracking: {
title: "数据详情",
description: "当前仓库还没有匹配的后端接口,页面暂保持为设计占位。",
description: "围绕插件采样快照查看品牌表现、平台矩阵、高频问题和引用归因。",
},
trackingQuestion: {
title: "问题详情",
description: "按问题查看大模型回答、引用来源、引用分析和内容引用。",
},
knowledge: {
title: "知识库",
@@ -155,6 +161,131 @@ const zhCN = {
emptyTemplates: "暂无模版卡片数据",
noRecentArticles: "暂无最近生成内容",
},
tracking: {
eyebrow: "AI Brand Monitoring",
brandPlaceholder: "选择品牌",
keywordPlaceholder: "选择关键词",
collectNow: "立即采集",
collectKeywordRequired: "请先选择关键词,再立即采集当前问题",
pluginMode: "插件采样",
pluginHint: "插件模式下结果受设备在线率影响,低覆盖样本仅供趋势参考。",
awaitingSnapshot: "等待下一次有效快照",
infoStrip:
"{mode} · 目标 {desired} · 计划 {planned} · 已采样 {actual} · 覆盖率 {coverage} · 更新于 {updatedAt} · {trigger}",
latestSnapshot: "Latest Snapshot",
coverage: "Coverage",
coverageTitle: "采样覆盖条",
coverageSummary: "目标 {desired} · 已采样 {actual} · 覆盖率 {coverage}",
platformMatrix: "Platform Matrix",
platformMatrixTitle: "平台对比矩阵",
hotQuestions: "Hot Questions",
hotQuestionsTitle: "高频问题",
hotQuestionsHint: "高频问题来自品牌库当前关键词下的全部问题。",
questionSearchPlaceholder: "搜索当前关键词下的问题",
questionDetailEyebrow: "Question Detail",
questionDetailCollectedAt: "采集时间 {time}",
questionDetailFallback: "问题详情",
backToQuestions: "返回问题列表",
citationRanking: "Citation Ranking",
citationRankingTitle: "引用排行",
citationRankingHint: "统计系统发布内容在各模型回答中出现的次数与覆盖率。",
citedArticles: "Cited Articles",
citedArticlesTitle: "被引用文章",
answerContent: "答案内容",
citationSources: "Citation Sources",
citationSourcesTitle: "引用来源",
citationAnalysis: "Citation Analysis",
citationAnalysisTitle: "引用分析",
contentCitations: "Content Citations",
contentCitationsTitle: "内容引用",
taskDebugTitle: "异步任务调试",
taskDebugHint: "仅用于排查 callback -> queue -> worker 的异步流转,不影响上方四块主内容。",
contentCitationBadge: "内容引用",
noQuestions: "当前筛选条件下暂无高频问题",
noCitationRanking: "当前时间窗口内暂无可归因引用",
noCitedArticles: "当前时间窗口内暂无内容引用",
noAnswer: "该平台暂无采样回答",
noCitations: "该平台无引用来源",
noCitationAnalysis: "该平台暂无引用分析",
noContentCitations: "当前平台暂无内容引用",
noTaskDebug: "当前条件下暂无异步任务调试数据",
samples: "次采样",
citations: "次引用",
citedArticleMeta: "{count} 篇内容被引用",
contentCitationMeta: "含 {count} 条内容引用",
manual: "手动",
automatic: "自动",
noChange: "持平",
metrics: {
mentionRate: "提及率",
top1MentionRate: "首位提及率",
firstRecommendRate: "首选推荐率",
positiveMentionRate: "正面提及率",
},
columns: {
platform: "平台",
appearances: "出现次数",
citedAnswers: "引用回答数",
citedArticles: "引用文章数",
citationRate: "引用率",
citations: "引用次数",
sourcePlatform: "来源平台",
domain: "来源域名",
share: "占比",
contentName: "内容名称",
publishPlatform: "发布平台",
distinctSites: "引用站点数",
brandContent: "含品牌内容",
},
status: {
sampled: "已采样",
partial: "部分采样",
unsampled: "未采样",
pending: "等待采样",
not_logged_in: "未登录",
unavailable: "不可用",
},
confidence: {
high: "高置信度",
medium: "中等置信度",
low: "低置信度",
},
taskDebug: {
labels: {
plannedAt: "计划时间",
leasedAt: "领取时间",
callbackReceivedAt: "回调收到时间",
queueEnqueuedAt: "入队时间",
completedAt: "完成时间",
leaseExpiresAt: "租约过期时间",
runId: "Run ID",
runStatus: "Run 状态",
providerModel: "模型",
requestId: "请求 ID",
providerRequestId: "Provider Request ID",
receivedAlertCount: "Received 告警次数",
receivedAlertedAt: "最近告警时间",
skipReason: "跳过原因",
errorMessage: "任务错误",
lastQueuePublishError: "队列投递错误",
},
taskStatus: {
pending: "待采集",
leased: "已领取",
received: "已收到回调",
completed: "已完成",
failed: "已失败",
skipped: "已跳过",
expired: "已过期",
},
queueStatus: {
pending: "待入队",
queued: "已入队",
publish_failed: "入队失败",
invalid_payload: "消息无效",
},
},
},
templateMeta: {
top_x_article: {
eyebrow: "榜单内容",