Raw fetch() had no auth headers, causing 401s that silently broke tracing toggle. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
77 lines
2.5 KiB
TypeScript
77 lines
2.5 KiB
TypeScript
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
|
|
import { api } from '../client'
|
|
import { useAuthStore } from '../../auth/auth-store'
|
|
|
|
// ── Application Config ────────────────────────────────────────────────────
|
|
|
|
export interface ApplicationConfig {
|
|
application: string
|
|
version: number
|
|
updatedAt?: string
|
|
engineLevel?: string
|
|
payloadCaptureMode?: string
|
|
metricsEnabled: boolean
|
|
samplingRate: number
|
|
tracedProcessors: Record<string, string>
|
|
}
|
|
|
|
/** Authenticated fetch using the JWT from auth store */
|
|
function authFetch(url: string, init?: RequestInit): Promise<Response> {
|
|
const token = useAuthStore.getState().accessToken
|
|
const headers = new Headers(init?.headers)
|
|
if (token) headers.set('Authorization', `Bearer ${token}`)
|
|
headers.set('X-Cameleer-Protocol-Version', '1')
|
|
return fetch(url, { ...init, headers })
|
|
}
|
|
|
|
export function useApplicationConfig(application: string | undefined) {
|
|
return useQuery({
|
|
queryKey: ['applicationConfig', application],
|
|
queryFn: async () => {
|
|
const res = await authFetch(`/api/v1/config/${application}`)
|
|
if (!res.ok) throw new Error('Failed to fetch config')
|
|
return res.json() as Promise<ApplicationConfig>
|
|
},
|
|
enabled: !!application,
|
|
})
|
|
}
|
|
|
|
export function useUpdateApplicationConfig() {
|
|
const queryClient = useQueryClient()
|
|
return useMutation({
|
|
mutationFn: async (config: ApplicationConfig) => {
|
|
const res = await authFetch(`/api/v1/config/${config.application}`, {
|
|
method: 'PUT',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify(config),
|
|
})
|
|
if (!res.ok) throw new Error('Failed to update config')
|
|
return res.json() as Promise<ApplicationConfig>
|
|
},
|
|
onSuccess: (saved) => {
|
|
queryClient.setQueryData(['applicationConfig', saved.application], saved)
|
|
},
|
|
})
|
|
}
|
|
|
|
// ── Generic Group Command (kept for non-config commands) ──────────────────
|
|
|
|
interface SendGroupCommandParams {
|
|
group: string
|
|
type: string
|
|
payload: Record<string, unknown>
|
|
}
|
|
|
|
export function useSendGroupCommand() {
|
|
return useMutation({
|
|
mutationFn: async ({ group, type, payload }: SendGroupCommandParams) => {
|
|
const { data, error } = await api.POST('/agents/groups/{group}/commands', {
|
|
params: { path: { group } },
|
|
body: { type, payload } as any,
|
|
})
|
|
if (error) throw new Error('Failed to send command')
|
|
return data!
|
|
},
|
|
})
|
|
}
|