Freshness diagnostics API, UI trust notes, mission control/stats updates, and deploy scripts.

Made-with: Cursor
This commit is contained in:
defiQUG
2026-04-12 06:33:54 -07:00
parent 0972178cc5
commit 3fdb812a29
63 changed files with 5163 additions and 826 deletions

View File

@@ -16,6 +16,10 @@ import {
} from '@/services/api/stats'
import { transactionsApi, type Transaction } from '@/services/api/transactions'
import { formatWeiAsEth } from '@/utils/format'
import { summarizeChainActivity } from '@/utils/activityContext'
import ActivityContextPanel from '@/components/common/ActivityContextPanel'
import FreshnessTrustNote from '@/components/common/FreshnessTrustNote'
import { resolveEffectiveFreshness, shouldExplainEmptyHeadBlocks } from '@/utils/explorerFreshness'
import OperationsPageShell, {
MetricCard,
StatusBadge,
@@ -121,6 +125,17 @@ export default function AnalyticsOperationsPage({
() => trailingWindow.reduce((max, point) => Math.max(max, point.transaction_count), 0),
[trailingWindow],
)
const activityContext = useMemo(
() =>
summarizeChainActivity({
blocks,
transactions,
latestBlockNumber: stats?.latest_block ?? blocks[0]?.number ?? null,
latestBlockTimestamp: blocks[0]?.timestamp ?? null,
freshness: resolveEffectiveFreshness(stats, bridgeStatus),
}),
[blocks, bridgeStatus, stats, transactions],
)
return (
<OperationsPageShell page={page}>
@@ -130,6 +145,17 @@ export default function AnalyticsOperationsPage({
</Card>
) : null}
<div className="mb-6">
<ActivityContextPanel context={activityContext} title="Analytics Freshness Context" />
<FreshnessTrustNote
className="mt-3"
context={activityContext}
stats={stats}
bridgeStatus={bridgeStatus}
scopeLabel="This page combines public stats, recent block samples, and indexed transactions."
/>
</div>
<div className="mb-6 grid gap-4 md:grid-cols-2 xl:grid-cols-4">
<MetricCard
title="Total Blocks"
@@ -264,6 +290,11 @@ export default function AnalyticsOperationsPage({
<Card title="Recent Blocks">
<div className="space-y-4">
{shouldExplainEmptyHeadBlocks(blocks, activityContext) ? (
<p className="rounded-xl border border-amber-200 bg-amber-50/70 px-3 py-2 text-sm text-amber-900 dark:border-amber-900/40 dark:bg-amber-950/20 dark:text-amber-100">
Recent head blocks are currently empty; use the latest transaction block for recent visible activity.
</p>
) : null}
{blocks.map((block) => (
<div
key={block.hash}

View File

@@ -51,6 +51,14 @@ function resolveSnapshot(relay?: MissionControlRelayPayload): MissionControlRela
return relay?.url_probe?.body || relay?.file_snapshot || null
}
function relayPolicyCue(snapshot: MissionControlRelaySnapshot | null): string | null {
if (!snapshot) return null
if (String(snapshot.status || '').toLowerCase() === 'paused' && snapshot.monitoring?.delivery_enabled === false) {
return 'Delivery disabled by policy'
}
return null
}
function laneToneClasses(status: string): string {
const normalized = status.toLowerCase()
if (['degraded', 'stale', 'stopped', 'down', 'snapshot-error'].includes(normalized)) {
@@ -300,6 +308,11 @@ export default function BridgeMonitoringPage({
<div className="mt-1 text-sm text-gray-600 dark:text-gray-400">
Bridge: {shortAddress(lane.bridgeAddress)}
</div>
{relayPolicyCue(resolveSnapshot((getMissionControlRelays(bridgeStatus) || {})[lane.key])) ? (
<div className="mt-3 text-xs font-medium uppercase tracking-wide text-amber-700 dark:text-amber-300">
{relayPolicyCue(resolveSnapshot((getMissionControlRelays(bridgeStatus) || {})[lane.key]))}
</div>
) : null}
</Card>
))}
</div>

View File

@@ -5,6 +5,11 @@ import { explorerFeaturePages } from '@/data/explorerOperations'
import { configApi, type CapabilitiesResponse, type NetworksConfigResponse, type TokenListResponse } from '@/services/api/config'
import { getMissionControlRelays, missionControlApi, type MissionControlBridgeStatusResponse } from '@/services/api/missionControl'
import { routesApi, type RouteMatrixResponse } from '@/services/api/routes'
import { useUiMode } from '@/components/common/UiModeContext'
import { summarizeChainActivity } from '@/utils/activityContext'
import ActivityContextPanel from '@/components/common/ActivityContextPanel'
import FreshnessTrustNote from '@/components/common/FreshnessTrustNote'
import { resolveEffectiveFreshness } from '@/utils/explorerFreshness'
function relativeAge(isoString?: string): string {
if (!isoString) return 'Unknown'
@@ -60,6 +65,7 @@ export default function OperationsHubPage({
initialTokenList = null,
initialCapabilities = null,
}: OperationsHubPageProps) {
const { mode } = useUiMode()
const [bridgeStatus, setBridgeStatus] = useState<MissionControlBridgeStatusResponse | null>(initialBridgeStatus)
const [routeMatrix, setRouteMatrix] = useState<RouteMatrixResponse | null>(initialRouteMatrix)
const [networksConfig, setNetworksConfig] = useState<NetworksConfigResponse | null>(initialNetworksConfig)
@@ -138,6 +144,19 @@ export default function OperationsHubPage({
new Set((tokenList?.tokens || []).map((token) => token.symbol).filter(Boolean) as string[])
).slice(0, 8)
}, [tokenList])
const activityContext = useMemo(
() =>
summarizeChainActivity({
blocks: [],
transactions: [],
latestBlockNumber: bridgeStatus?.data?.chains?.['138']?.block_number
? Number(bridgeStatus.data.chains['138'].block_number)
: null,
latestBlockTimestamp: null,
freshness: resolveEffectiveFreshness(null, bridgeStatus),
}),
[bridgeStatus],
)
return (
<div className="container mx-auto px-4 py-6 sm:py-8">
@@ -167,6 +186,16 @@ export default function OperationsHubPage({
</Card>
) : null}
<div className="mb-6">
<ActivityContextPanel context={activityContext} title="Operations Freshness Context" />
<FreshnessTrustNote
className="mt-3"
context={activityContext}
bridgeStatus={bridgeStatus}
scopeLabel="This page reflects mission-control freshness, public bridge status, and explorer-served config surfaces."
/>
</div>
<div className="mb-6 grid gap-4 md:grid-cols-2 xl:grid-cols-4">
<Card className="border border-sky-200 bg-sky-50/70 dark:border-sky-900/50 dark:bg-sky-950/20">
<div className="text-sm font-semibold uppercase tracking-wide text-sky-800 dark:text-sky-100">
@@ -226,7 +255,7 @@ export default function OperationsHubPage({
{relativeAge(bridgeStatus?.data?.checked_at)}
</div>
<div className="mt-2 text-sm text-gray-600 dark:text-gray-400">
Public mission-control snapshot freshness.
{mode === 'guided' ? 'Public mission-control snapshot freshness.' : 'Mission-control freshness.'}
</div>
</div>
<div className="rounded-2xl border border-gray-200 bg-gray-50 p-4 dark:border-gray-700 dark:bg-gray-900/40">
@@ -235,7 +264,7 @@ export default function OperationsHubPage({
{relativeAge(routeMatrix?.updated)}
</div>
<div className="mt-2 text-sm text-gray-600 dark:text-gray-400">
Token-aggregation route inventory timestamp.
{mode === 'guided' ? 'Token-aggregation route inventory timestamp.' : 'Route inventory timestamp.'}
</div>
</div>
<div className="rounded-2xl border border-gray-200 bg-gray-50 p-4 dark:border-gray-700 dark:bg-gray-900/40">
@@ -244,7 +273,7 @@ export default function OperationsHubPage({
{networksConfig?.defaultChainId ?? 'Unknown'}
</div>
<div className="mt-2 text-sm text-gray-600 dark:text-gray-400">
Wallet onboarding points at Chain 138 by default.
{mode === 'guided' ? 'Wallet onboarding points at Chain 138 by default.' : 'Default wallet chain.'}
</div>
</div>
<div className="rounded-2xl border border-gray-200 bg-gray-50 p-4 dark:border-gray-700 dark:bg-gray-900/40">
@@ -255,7 +284,7 @@ export default function OperationsHubPage({
: 'Partial'}
</div>
<div className="mt-2 text-sm text-gray-600 dark:text-gray-400">
`wallet_addEthereumChain` and `wallet_watchAsset` compatibility.
{mode === 'guided' ? '`wallet_addEthereumChain` and `wallet_watchAsset` compatibility.' : 'Wallet RPC support.'}
</div>
</div>
</div>

View File

@@ -33,6 +33,14 @@ function relaySnapshot(relay: MissionControlRelayPayload | undefined) {
return relay?.url_probe?.body || relay?.file_snapshot
}
function relaySummary(snapshot: ReturnType<typeof relaySnapshot>) {
if (!snapshot) return 'destination unknown'
if (snapshot.status === 'paused' && snapshot.monitoring?.delivery_enabled === false) {
return `Delivery paused · queue ${formatNumber(snapshot.queue?.size ?? 0)}`
}
return `Queue ${formatNumber(snapshot.queue?.size ?? 0)} · ${snapshot.destination?.chain_name || 'destination unknown'}`
}
export default function WethOperationsPage({
initialBridgeStatus = null,
initialPlannerCapabilities = null,
@@ -112,13 +120,13 @@ export default function WethOperationsPage({
<MetricCard
title="Mainnet WETH Lane"
value={mainnetWeth?.status || 'unknown'}
description={`Queue ${formatNumber(mainnetWeth?.queue?.size ?? 0)} · ${mainnetWeth?.destination?.chain_name || 'destination unknown'}`}
description={relaySummary(mainnetWeth)}
className="border border-sky-200 bg-sky-50/70 dark:border-sky-900/50 dark:bg-sky-950/20"
/>
<MetricCard
title="Mainnet cW Lane"
value={mainnetCw?.status || 'unknown'}
description={`Queue ${formatNumber(mainnetCw?.queue?.size ?? 0)} · ${mainnetCw?.destination?.chain_name || 'destination unknown'}`}
description={relaySummary(mainnetCw)}
className="border border-emerald-200 bg-emerald-50/70 dark:border-emerald-900/50 dark:bg-emerald-950/20"
/>
<MetricCard