All files / web/src/hooks useBktSettings.ts

0% Statements 0/93
0% Branches 0/1
0% Functions 0/1
0% Lines 0/93

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94                                                                                                                                                                                           
'use client'

import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
import { api } from '@/lib/queryClient'

/** Query key for BKT settings */
export const bktSettingsKeys = {
  all: ['bkt-settings'] as const,
  threshold: () => [...bktSettingsKeys.all, 'threshold'] as const,
}

interface BktSettingsResponse {
  bktConfidenceThreshold: number
}

/**
 * Fetch BKT settings from the API
 */
async function fetchBktSettings(): Promise<BktSettingsResponse> {
  const res = await api('settings/bkt')
  if (!res.ok) throw new Error('Failed to fetch BKT settings')
  return res.json()
}

/**
 * Update BKT settings via the API
 */
async function updateBktSettings(threshold: number): Promise<BktSettingsResponse> {
  const res = await api('settings/bkt', {
    method: 'PATCH',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ bktConfidenceThreshold: threshold }),
  })
  if (!res.ok) throw new Error('Failed to update BKT settings')
  return res.json()
}

/**
 * Hook to fetch the saved BKT confidence threshold.
 *
 * Uses a long stale time since this setting rarely changes.
 */
export function useBktSettings() {
  return useQuery({
    queryKey: bktSettingsKeys.threshold(),
    queryFn: fetchBktSettings,
    staleTime: 5 * 60 * 1000, // 5 minutes
    gcTime: 30 * 60 * 1000, // 30 minutes
  })
}

/**
 * Hook to update the saved BKT confidence threshold.
 *
 * Supports optimistic updates for immediate UI feedback.
 */
export function useUpdateBktSettings() {
  const queryClient = useQueryClient()

  return useMutation({
    mutationFn: updateBktSettings,
    // Optimistic update
    onMutate: async (newThreshold) => {
      // Cancel any outgoing refetches
      await queryClient.cancelQueries({
        queryKey: bktSettingsKeys.threshold(),
      })

      // Snapshot the previous value
      const previousSettings = queryClient.getQueryData<BktSettingsResponse>(
        bktSettingsKeys.threshold()
      )

      // Optimistically update to the new value
      queryClient.setQueryData<BktSettingsResponse>(bktSettingsKeys.threshold(), {
        bktConfidenceThreshold: newThreshold,
      })

      // Return context with the previous value
      return { previousSettings }
    },
    // If the mutation fails, roll back to the previous value
    onError: (_err, _newThreshold, context) => {
      if (context?.previousSettings) {
        queryClient.setQueryData(bktSettingsKeys.threshold(), context.previousSettings)
      }
    },
    // Always refetch after error or success
    onSettled: () => {
      queryClient.invalidateQueries({ queryKey: bktSettingsKeys.threshold() })
    },
  })
}