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",