feat: persistent per-application config with GET/PUT endpoints
Add application_config table (V4 migration), repository, and REST
controller. GET /api/v1/config/{app} returns config, PUT saves and
pushes CONFIG_UPDATE to all LIVE agents via SSE. UI tracing toggle
now uses config API instead of direct SET_TRACED_PROCESSORS command.
Tracing store syncs with server config on load.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { useState, useMemo, useCallback } from 'react'
|
||||
import { useState, useMemo, useCallback, useEffect } from 'react'
|
||||
import { useParams, useNavigate } from 'react-router'
|
||||
import {
|
||||
Badge, StatusDot, MonoText, CodeBlock, InfoCallout,
|
||||
@@ -10,7 +10,7 @@ import { useCorrelationChain } from '../../api/queries/correlation'
|
||||
import { useDiagramLayout } from '../../api/queries/diagrams'
|
||||
import { mapDiagramToRouteNodes } from '../../utils/diagram-mapping'
|
||||
import { useTracingStore } from '../../stores/tracing-store'
|
||||
import { useSendGroupCommand } from '../../api/queries/commands'
|
||||
import { useApplicationConfig, useUpdateApplicationConfig } from '../../api/queries/commands'
|
||||
import styles from './ExchangeDetail.module.css'
|
||||
|
||||
// ── Helpers ──────────────────────────────────────────────────────────────────
|
||||
@@ -187,27 +187,35 @@ export default function ExchangeDetail() {
|
||||
// ── Tracing toggle ──────────────────────────────────────────────────────
|
||||
const { toast } = useToast()
|
||||
const tracingStore = useTracingStore()
|
||||
const sendCommand = useSendGroupCommand()
|
||||
const app = detail?.applicationName ?? ''
|
||||
const { data: appConfig } = useApplicationConfig(app || undefined)
|
||||
const updateConfig = useUpdateApplicationConfig()
|
||||
|
||||
// Sync tracing store with server config
|
||||
useEffect(() => {
|
||||
if (appConfig?.tracedProcessors && app) {
|
||||
tracingStore.syncFromServer(app, appConfig.tracedProcessors)
|
||||
}
|
||||
}, [appConfig, app])
|
||||
|
||||
const handleToggleTracing = useCallback((processorId: string) => {
|
||||
if (!processorId || !detail?.applicationName) return
|
||||
if (!processorId || !detail?.applicationName || !appConfig) return
|
||||
const newMap = tracingStore.toggleProcessor(app, processorId)
|
||||
sendCommand.mutate({
|
||||
group: detail.applicationName,
|
||||
type: 'set-traced-processors',
|
||||
payload: { processors: newMap },
|
||||
}, {
|
||||
onSuccess: (data) => {
|
||||
const updatedConfig = {
|
||||
...appConfig,
|
||||
tracedProcessors: { ...newMap },
|
||||
}
|
||||
updateConfig.mutate(updatedConfig, {
|
||||
onSuccess: (saved) => {
|
||||
const action = processorId in newMap ? 'enabled' : 'disabled'
|
||||
toast({ title: `Tracing ${action}`, description: `${processorId} — sent to ${data?.targetCount ?? 0} agent(s)`, variant: 'success' })
|
||||
toast({ title: `Tracing ${action}`, description: `${processorId} — config v${saved.version}`, variant: 'success' })
|
||||
},
|
||||
onError: () => {
|
||||
tracingStore.toggleProcessor(app, processorId)
|
||||
toast({ title: 'Command failed', description: 'Could not send tracing command', variant: 'error' })
|
||||
toast({ title: 'Config update failed', description: 'Could not save configuration', variant: 'error' })
|
||||
},
|
||||
})
|
||||
}, [detail, app, tracingStore, sendCommand, toast])
|
||||
}, [detail, app, appConfig, tracingStore, updateConfig, toast])
|
||||
|
||||
// Correlation chain
|
||||
const correlatedExchanges = useMemo(() => {
|
||||
@@ -372,7 +380,7 @@ export default function ExchangeDetail() {
|
||||
return [{
|
||||
label: tracingStore.isTraced(app, pid) ? 'Disable Tracing' : 'Enable Tracing',
|
||||
onClick: () => handleToggleTracing(pid),
|
||||
disabled: sendCommand.isPending,
|
||||
disabled: updateConfig.isPending,
|
||||
}]
|
||||
}}
|
||||
/>
|
||||
@@ -391,7 +399,7 @@ export default function ExchangeDetail() {
|
||||
return [{
|
||||
label: tracingStore.isTraced(app, pid) ? 'Disable Tracing' : 'Enable Tracing',
|
||||
onClick: () => handleToggleTracing(pid),
|
||||
disabled: sendCommand.isPending,
|
||||
disabled: updateConfig.isPending,
|
||||
}]
|
||||
}}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user