feat(freshness): enhance diagnostics and update snapshot structure
- Introduced a new Diagnostics struct to capture transaction visibility state and activity state. - Updated BuildSnapshot function to return diagnostics alongside snapshot, completeness, and sampling. - Enhanced test cases to validate the new diagnostics data. - Updated frontend components to utilize the new diagnostics information for improved user feedback on freshness context. This change improves the observability of transaction activity and enhances the user experience by providing clearer insights into the freshness of data.
This commit is contained in:
@@ -9,7 +9,12 @@ import {
|
||||
type MissionControlRelayPayload,
|
||||
type MissionControlRelaySnapshot,
|
||||
} from '@/services/api/missionControl'
|
||||
import { statsApi, type ExplorerStats } from '@/services/api/stats'
|
||||
import { explorerFeaturePages } from '@/data/explorerOperations'
|
||||
import { summarizeChainActivity } from '@/utils/activityContext'
|
||||
import ActivityContextPanel from '@/components/common/ActivityContextPanel'
|
||||
import FreshnessTrustNote from '@/components/common/FreshnessTrustNote'
|
||||
import { resolveEffectiveFreshness } from '@/utils/explorerFreshness'
|
||||
|
||||
type FeedState = 'connecting' | 'live' | 'fallback'
|
||||
|
||||
@@ -61,6 +66,9 @@ function relayPolicyCue(snapshot: MissionControlRelaySnapshot | null): string |
|
||||
if (snapshot.last_error?.scope === 'bridge_inventory') {
|
||||
return 'Queued release waiting on bridge inventory'
|
||||
}
|
||||
if (snapshot.last_error?.scope === 'bridge_inventory_probe') {
|
||||
return 'Bridge inventory check is temporarily unavailable'
|
||||
}
|
||||
if (String(snapshot.status || '').toLowerCase() === 'paused' && snapshot.monitoring?.delivery_enabled === false) {
|
||||
return 'Delivery disabled by policy'
|
||||
}
|
||||
@@ -130,10 +138,13 @@ function ActionLink({
|
||||
|
||||
export default function BridgeMonitoringPage({
|
||||
initialBridgeStatus = null,
|
||||
initialStats = null,
|
||||
}: {
|
||||
initialBridgeStatus?: MissionControlBridgeStatusResponse | null
|
||||
initialStats?: ExplorerStats | null
|
||||
}) {
|
||||
const [bridgeStatus, setBridgeStatus] = useState<MissionControlBridgeStatusResponse | null>(initialBridgeStatus)
|
||||
const [stats, setStats] = useState<ExplorerStats | null>(initialStats)
|
||||
const [feedState, setFeedState] = useState<FeedState>(initialBridgeStatus ? 'fallback' : 'connecting')
|
||||
const page = explorerFeaturePages.bridge
|
||||
|
||||
@@ -142,9 +153,15 @@ export default function BridgeMonitoringPage({
|
||||
|
||||
const loadSnapshot = async () => {
|
||||
try {
|
||||
const snapshot = await missionControlApi.getBridgeStatus()
|
||||
const [snapshot, latestStats] = await Promise.all([
|
||||
missionControlApi.getBridgeStatus(),
|
||||
statsApi.get().catch(() => null),
|
||||
])
|
||||
if (!cancelled) {
|
||||
setBridgeStatus(snapshot)
|
||||
if (latestStats) {
|
||||
setStats(latestStats)
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
if (!cancelled && process.env.NODE_ENV !== 'production') {
|
||||
@@ -178,6 +195,19 @@ export default function BridgeMonitoringPage({
|
||||
}
|
||||
}, [])
|
||||
|
||||
const activityContext = useMemo(
|
||||
() =>
|
||||
summarizeChainActivity({
|
||||
blocks: [],
|
||||
transactions: [],
|
||||
latestBlockNumber: stats?.latest_block,
|
||||
latestBlockTimestamp: null,
|
||||
freshness: resolveEffectiveFreshness(stats, bridgeStatus),
|
||||
diagnostics: stats?.diagnostics ?? bridgeStatus?.data?.diagnostics ?? null,
|
||||
}),
|
||||
[bridgeStatus, stats],
|
||||
)
|
||||
|
||||
const relayLanes = useMemo((): RelayLaneCard[] => {
|
||||
const relays = getMissionControlRelays(bridgeStatus)
|
||||
if (!relays) return []
|
||||
@@ -191,7 +221,12 @@ export default function BridgeMonitoringPage({
|
||||
return {
|
||||
key,
|
||||
label: getMissionControlRelayLabel(key),
|
||||
status: snapshot?.last_error?.scope === 'bridge_inventory' ? 'underfunded' : status,
|
||||
status:
|
||||
snapshot?.last_error?.scope === 'bridge_inventory'
|
||||
? 'underfunded'
|
||||
: snapshot?.last_error?.scope === 'bridge_inventory_probe'
|
||||
? 'warning'
|
||||
: status,
|
||||
profile: snapshot?.service?.profile || key,
|
||||
sourceChain: snapshot?.source?.chain_name || 'Unknown',
|
||||
destinationChain: snapshot?.destination?.chain_name || 'Unknown',
|
||||
@@ -244,6 +279,17 @@ export default function BridgeMonitoringPage({
|
||||
</Card>
|
||||
) : null}
|
||||
|
||||
<div className="mb-6">
|
||||
<ActivityContextPanel context={activityContext} title="Bridge Freshness Context" />
|
||||
<FreshnessTrustNote
|
||||
className="mt-3"
|
||||
context={activityContext}
|
||||
stats={stats}
|
||||
bridgeStatus={bridgeStatus}
|
||||
scopeLabel="Bridge relay posture is shown alongside the same explorer freshness model used on the homepage and core explorer routes"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="mb-6 grid gap-4 lg:grid-cols-3">
|
||||
<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">
|
||||
|
||||
Reference in New Issue
Block a user