import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react' import { getConfigValue } from '@brojs/cli' import { keycloak } from '../kc' import type { ChallengeTask, ChallengeChain, ChallengeSubmission, SystemStats, SystemStatsV2, UserStats, CreateTaskRequest, UpdateTaskRequest, CreateChainRequest, UpdateChainRequest, SubmitRequest, TestSubmissionResult, APIResponse, } from '../../types/challenge' export const api = createApi({ reducerPath: 'api', baseQuery: fetchBaseQuery({ baseUrl: getConfigValue('challenge-admin.api'), fetchFn: async ( input: RequestInfo | URL, init?: RequestInit | undefined, ) => { const response = await fetch(input, init) if (response.status === 403) keycloak.login() return response }, headers: { 'Content-Type': 'application/json;charset=utf-8', }, prepareHeaders: (headers) => { headers.set('Authorization', `Bearer ${keycloak.token}`) }, }), tagTypes: ['Task', 'Chain', 'User', 'Submission', 'Stats'], endpoints: (builder) => ({ // Tasks getTasks: builder.query({ query: () => '/challenge/tasks', transformResponse: (response: { body: ChallengeTask[] }) => response.body, providesTags: ['Task'], }), getTask: builder.query({ query: (id) => `/challenge/task/${id}`, transformResponse: (response: { body: ChallengeTask }) => response.body, providesTags: (_result, _error, id) => [{ type: 'Task', id }], }), createTask: builder.mutation({ query: (body) => ({ url: '/challenge/task', method: 'POST', body, }), transformResponse: (response: { body: ChallengeTask }) => response.body, invalidatesTags: ['Task'], }), updateTask: builder.mutation({ query: ({ id, data }) => ({ url: `/challenge/task/${id}`, method: 'PUT', body: data, }), transformResponse: (response: { body: ChallengeTask }) => response.body, invalidatesTags: (_result, _error, { id }) => [{ type: 'Task', id }, 'Task'], }), deleteTask: builder.mutation({ query: (id) => ({ url: `/challenge/task/${id}`, method: 'DELETE', }), invalidatesTags: ['Task', 'Chain'], }), // Chains getChains: builder.query({ query: () => '/challenge/chains/admin', transformResponse: (response: { body: ChallengeChain[] }) => response.body, providesTags: ['Chain'], }), getChain: builder.query({ query: (id) => `/challenge/chain/${id}`, transformResponse: (response: { body: ChallengeChain }) => response.body, providesTags: (_result, _error, id) => [{ type: 'Chain', id }], }), createChain: builder.mutation({ query: (body) => ({ url: '/challenge/chain', method: 'POST', body, }), transformResponse: (response: { body: ChallengeChain }) => response.body, invalidatesTags: ['Chain'], }), updateChain: builder.mutation({ query: ({ id, data }) => ({ url: `/challenge/chain/${id}`, method: 'PUT', body: data, }), transformResponse: (response: { body: ChallengeChain }) => response.body, invalidatesTags: (_result, _error, { id }) => [{ type: 'Chain', id }, 'Chain'], }), deleteChain: builder.mutation({ query: (id) => ({ url: `/challenge/chain/${id}`, method: 'DELETE', }), invalidatesTags: ['Chain'], }), // Statistics getSystemStats: builder.query({ query: () => '/challenge/stats', transformResponse: (response: { body: SystemStats }) => response.body, providesTags: ['Stats'], }), getSystemStatsV2: builder.query({ query: (chainId) => ({ url: '/challenge/stats/v2', params: chainId ? { chainId } : undefined, }), transformResponse: (response: { body: SystemStatsV2 }) => response.body, providesTags: ['Stats'], }), getUserStats: builder.query({ query: (userId) => `/challenge/user/${userId}/stats`, transformResponse: (response: { body: UserStats }) => response.body, providesTags: (_result, _error, userId) => [{ type: 'User', id: userId }], }), // Submissions getUserSubmissions: builder.query({ query: ({ userId, taskId }) => { const params = taskId ? `?taskId=${taskId}` : '' return `/challenge/user/${userId}/submissions${params}` }, transformResponse: (response: { body: ChallengeSubmission[] }) => response.body, providesTags: ['Submission'], }), // Test submission (LLM check without creating a real submission) testSubmission: builder.mutation({ query: ({ userId, taskId, result, isTest = true, hiddenInstructions }) => ({ url: '/challenge/submit', method: 'POST', body: { userId, taskId, result, isTest, hiddenInstructions, }, }), transformResponse: (response: APIResponse) => response.data, }), }), }) export const { useGetTasksQuery, useGetTaskQuery, useCreateTaskMutation, useUpdateTaskMutation, useDeleteTaskMutation, useGetChainsQuery, useGetChainQuery, useCreateChainMutation, useUpdateChainMutation, useDeleteChainMutation, useGetSystemStatsQuery, useGetSystemStatsV2Query, useGetUserStatsQuery, useGetUserSubmissionsQuery, useTestSubmissionMutation, } = api