Add system alerts log with nav badge and Admin Alerts tab.
Deploy / lint (push) Successful in 8s
Deploy / test (push) Failing after 1m4s
Deploy / deploy (push) Has been skipped

Persist job and ingestion warnings/errors for 7 days, surface a dismissible top-nav badge, treat stale OHLCV as a warning (e.g. ticker renames), and show market bar age on the ticker freshness chip.
This commit is contained in:
2026-07-14 13:38:04 +02:00
parent ed82d0a665
commit f59c0c3484
16 changed files with 825 additions and 7 deletions
+7 -1
View File
@@ -6,6 +6,7 @@ import { SentimentProviderSettings } from '../components/admin/SentimentProvider
import { DataCleanup } from '../components/admin/DataCleanup';
import { JobControls } from '../components/admin/JobControls';
import { PipelineReadinessPanel } from '../components/admin/PipelineReadinessPanel';
import { SystemEventsPanel } from '../components/admin/SystemEventsPanel';
import { RecommendationSettings } from '../components/admin/RecommendationSettings';
import { ScheduleSettings } from '../components/admin/ScheduleSettings';
import { SettingsForm } from '../components/admin/SettingsForm';
@@ -15,7 +16,7 @@ import { UserTable } from '../components/admin/UserTable';
import { PageHeader } from '../components/ui/PageHeader';
import { Tabs } from '../components/ui/Tabs';
const tabs = ['Users', 'Tickers', 'Settings', 'Jobs', 'Cleanup'] as const;
const tabs = ['Users', 'Tickers', 'Settings', 'Jobs', 'Alerts', 'Cleanup'] as const;
type Tab = (typeof tabs)[number];
export default function AdminPage() {
@@ -49,6 +50,11 @@ export default function AdminPage() {
<PipelineReadinessPanel />
</div>
)}
{activeTab === 'Alerts' && (
<div className="space-y-4">
<SystemEventsPanel />
</div>
)}
{activeTab === 'Cleanup' && <DataCleanup />}
</div>
</div>
+3 -1
View File
@@ -171,8 +171,10 @@ export default function TickerDetailPage() {
const dataStatus: DataStatusItem[] = useMemo(() => [
{
label: 'OHLCV',
// Market age of the latest bar (session date), not DB insert time —
// created_at stays frozen when the provider returns no new sessions.
available: !!ohlcv.data && ohlcv.data.length > 0,
timestamp: ohlcv.data?.[ohlcv.data.length - 1]?.created_at,
timestamp: ohlcv.data?.[ohlcv.data.length - 1]?.date,
selector: ['ohlcv'] as FetchSelector,
paid: true,
},