import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query' import { agentWorkItemService } from '../services/agentWorkItemService' import type { AgentWorkItemFilters } from '../provider/IAgentWorkItemProvider' import type { AgentEditableField } from '../domain/agentWorkItem' import { useToastStore } from '../stores/toastStore' import { STALE_AGENT_WORK_ITEMS } from '../lib/constants' import { QK_AGENT_PROTOCOL } from './useAgentProtocol' export const QK_AGENT_WORK_ITEMS = 'agentWorkItems' export const QK_AGENT_KPIS = 'agentKpis' export function useAgentWorkItems(filters?: AgentWorkItemFilters) { return useQuery({ queryKey: [QK_AGENT_WORK_ITEMS, filters ?? {}], queryFn: () => agentWorkItemService.getAll(filters), staleTime: STALE_AGENT_WORK_ITEMS, select: (res) => res.data ?? [], }) } export function useAgentWorkItem(id: string | null) { return useQuery({ queryKey: [QK_AGENT_WORK_ITEMS, 'item', id], queryFn: () => agentWorkItemService.getById(id!), staleTime: STALE_AGENT_WORK_ITEMS, enabled: !!id, select: (res) => res.data ?? null, }) } /** Die drei Kennzahlen der Auswertung — reagieren auf dieselben Filter wie der Verlauf. */ export function useAgentKpis(filters?: AgentWorkItemFilters) { return useQuery({ queryKey: [QK_AGENT_KPIS, filters ?? {}], queryFn: () => agentWorkItemService.getKpis(filters), staleTime: STALE_AGENT_WORK_ITEMS, select: (res) => res.data, }) } /** * Jede Entscheidung verschiebt einen Vorgang zwischen den Reitern, verändert die * Kennzahlen und schreibt ins Protokoll — alle drei Bestände müssen zusammen * entwertet werden, sonst zeigt die Oberfläche widersprüchliche Zahlen. */ function useWorkItemInvalidation() { const queryClient = useQueryClient() return () => { queryClient.invalidateQueries({ queryKey: [QK_AGENT_WORK_ITEMS] }) queryClient.invalidateQueries({ queryKey: [QK_AGENT_KPIS] }) queryClient.invalidateQueries({ queryKey: [QK_AGENT_PROTOCOL] }) } } export function useApproveWorkItem() { const invalidate = useWorkItemInvalidation() return useMutation({ mutationFn: (id: string) => agentWorkItemService.approve(id), onSuccess: () => { invalidate() useToastStore.getState().showToast('Vorgang freigegeben.', 'success') }, onError: () => { useToastStore.getState().showToast('Freigabe fehlgeschlagen.', 'error') }, }) } export function useRejectWorkItem() { const invalidate = useWorkItemInvalidation() return useMutation({ mutationFn: ({ id, reason }: { id: string; reason?: string }) => agentWorkItemService.reject(id, reason), onSuccess: () => { invalidate() useToastStore.getState().showToast('Vorgang zurückgewiesen.', 'warning') }, onError: () => { useToastStore.getState().showToast('Zurückweisung fehlgeschlagen.', 'error') }, }) } export function useSaveWorkItemEdit() { const invalidate = useWorkItemInvalidation() return useMutation({ mutationFn: ({ id, fields }: { id: string; fields: AgentEditableField[] }) => agentWorkItemService.saveEdit(id, fields), onSuccess: () => { invalidate() useToastStore .getState() .showToast('Änderungen gespeichert. Der Vorgang wartet weiterhin auf die Entscheidung.', 'info') }, onError: () => { useToastStore.getState().showToast('Änderungen konnten nicht gespeichert werden.', 'error') }, }) } export function useAnswerWorkItemQuery() { const invalidate = useWorkItemInvalidation() return useMutation({ mutationFn: ({ id, answer }: { id: string; answer: string }) => agentWorkItemService.answerQuery(id, answer), onSuccess: () => { invalidate() useToastStore.getState().showToast('Rückfrage beantwortet.', 'success') }, onError: () => { useToastStore.getState().showToast('Antwort konnte nicht gespeichert werden.', 'error') }, }) } export function useMarkWorkItemDone() { const invalidate = useWorkItemInvalidation() return useMutation({ mutationFn: (id: string) => agentWorkItemService.markDone(id), onSuccess: () => { invalidate() useToastStore.getState().showToast('Vorgang als erledigt markiert.', 'success') }, onError: () => { useToastStore.getState().showToast('Vorgang konnte nicht abgeschlossen werden.', 'error') }, }) }