From 4e8bdc2bf2e44f120c1ca08487aee5945808caf3 Mon Sep 17 00:00:00 2001 From: autonomy Date: Sun, 22 Feb 2026 16:15:27 +0000 Subject: [PATCH 1/7] feat: migrate bounty mutation hooks to GraphQL writes --- hooks/use-bounty-mutations.ts | 272 +++++++++++++++++++++++----------- 1 file changed, 187 insertions(+), 85 deletions(-) diff --git a/hooks/use-bounty-mutations.ts b/hooks/use-bounty-mutations.ts index 37063dc..54d142e 100644 --- a/hooks/use-bounty-mutations.ts +++ b/hooks/use-bounty-mutations.ts @@ -1,98 +1,200 @@ -import { useMutation, useQueryClient } from '@tanstack/react-query'; +import { useMutation, useQueryClient } from "@tanstack/react-query"; import { - bountiesApi, - type Bounty, - type CreateBountyInput, - type UpdateBountyInput, - type PaginatedResponse, -} from '@/lib/api'; -import { bountyKeys } from './use-bounties'; + type Bounty, + type CreateBountyInput, + type UpdateBountyInput, + type PaginatedResponse, +} from "@/lib/api"; +import { fetcher } from "@/lib/graphql/client"; +import { bountyKeys } from "@/lib/query/query-keys"; + +const CREATE_BOUNTY_MUTATION = ` + mutation CreateBounty($input: CreateBountyInput!) { + createBounty(input: $input) { + id + } + } +`; + +const UPDATE_BOUNTY_MUTATION = ` + mutation UpdateBounty($input: UpdateBountyInput!) { + updateBounty(input: $input) { + id + status + updatedAt + } + } +`; + +const DELETE_BOUNTY_MUTATION = ` + mutation DeleteBounty($id: ID!) { + deleteBounty(id: $id) + } +`; + +type CreateBountyMutationResponse = { + createBounty: Bounty; +}; + +type UpdateBountyMutationResponse = { + updateBounty: Bounty; +}; + +type DeleteBountyMutationResponse = { + deleteBounty: boolean; +}; + +type UpdateBountyMutationInput = Omit & { + id: string; + status?: string; +}; + +async function createBountyMutation(input: CreateBountyInput): Promise { + const response = await fetcher< + CreateBountyMutationResponse, + { input: CreateBountyInput } + >(CREATE_BOUNTY_MUTATION, { input })(); + + return response.createBounty; +} + +async function updateBountyMutation( + input: UpdateBountyMutationInput, +): Promise { + const response = await fetcher< + UpdateBountyMutationResponse, + { input: UpdateBountyMutationInput } + >(UPDATE_BOUNTY_MUTATION, { input })(); + + return response.updateBounty; +} + +async function deleteBountyMutation(id: string): Promise { + await fetcher( + DELETE_BOUNTY_MUTATION, + { id }, + )(); +} export function useCreateBounty() { - const queryClient = useQueryClient(); - - return useMutation({ - mutationFn: (data: CreateBountyInput) => bountiesApi.create(data), - onSuccess: () => { - queryClient.invalidateQueries({ queryKey: bountyKeys.lists() }); - }, - }); + const queryClient = useQueryClient(); + + return useMutation({ + mutationFn: createBountyMutation, + onSuccess: () => { + queryClient.invalidateQueries({ queryKey: bountyKeys.lists() }); + }, + }); } export function useUpdateBounty() { - const queryClient = useQueryClient(); - - return useMutation({ - mutationFn: ({ id, data }: { id: string; data: UpdateBountyInput }) => - bountiesApi.update(id, data), - onMutate: async ({ id, data }) => { - await queryClient.cancelQueries({ queryKey: bountyKeys.detail(id) }); - const previous = queryClient.getQueryData(bountyKeys.detail(id)); - - if (previous) { - queryClient.setQueryData(bountyKeys.detail(id), { - ...previous, - ...data, - updatedAt: new Date().toISOString(), - }); - } - - return { previous, id }; - }, - onError: (_err, _vars, context) => { - if (context?.previous) { - queryClient.setQueryData(bountyKeys.detail(context.id), context.previous); - } - }, - onSettled: (_data, _err, { id }) => { - queryClient.invalidateQueries({ queryKey: bountyKeys.detail(id) }); - queryClient.invalidateQueries({ queryKey: bountyKeys.lists() }); - }, - }); + const queryClient = useQueryClient(); + + return useMutation({ + mutationFn: ({ id, data }: { id: string; data: UpdateBountyInput }) => + updateBountyMutation({ id, ...data }), + onMutate: async ({ id, data }) => { + await queryClient.cancelQueries({ queryKey: bountyKeys.detail(id) }); + const previous = queryClient.getQueryData(bountyKeys.detail(id)); + + if (previous) { + queryClient.setQueryData(bountyKeys.detail(id), { + ...previous, + ...data, + updatedAt: new Date().toISOString(), + }); + } + + return { previous, id }; + }, + onError: (_err, _vars, context) => { + if (context?.previous) { + queryClient.setQueryData( + bountyKeys.detail(context.id), + context.previous, + ); + } + }, + onSettled: (_data, _err, { id }) => { + queryClient.invalidateQueries({ queryKey: bountyKeys.detail(id) }); + queryClient.invalidateQueries({ queryKey: bountyKeys.lists() }); + }, + }); } export function useDeleteBounty() { - const queryClient = useQueryClient(); - - return useMutation({ - mutationFn: (id: string) => bountiesApi.delete(id), - onMutate: async (id) => { - await queryClient.cancelQueries({ queryKey: bountyKeys.lists() }); - - const previousLists = queryClient.getQueriesData>({ - queryKey: bountyKeys.lists(), - }); - - queryClient.setQueriesData>( - { queryKey: bountyKeys.lists() }, - (old) => old ? { - ...old, - data: old.data.filter((b) => b.id !== id), - pagination: { ...old.pagination, total: old.pagination.total - 1 }, - } : old - ); - - return { previousLists }; - }, - onError: (_err, _id, context) => { - context?.previousLists.forEach(([key, data]) => { - queryClient.setQueryData(key, data); - }); - }, - onSettled: () => { - queryClient.invalidateQueries({ queryKey: bountyKeys.lists() }); - }, - }); + const queryClient = useQueryClient(); + + return useMutation({ + mutationFn: deleteBountyMutation, + onMutate: async (id) => { + await queryClient.cancelQueries({ queryKey: bountyKeys.lists() }); + + const previousLists = queryClient.getQueriesData< + PaginatedResponse + >({ + queryKey: bountyKeys.lists(), + }); + + queryClient.setQueriesData>( + { queryKey: bountyKeys.lists() }, + (old) => + old + ? { + ...old, + data: old.data.filter((b) => b.id !== id), + pagination: { + ...old.pagination, + total: old.pagination.total - 1, + }, + } + : old, + ); + + return { previousLists }; + }, + onError: (_err, _id, context) => { + context?.previousLists.forEach(([key, data]) => { + queryClient.setQueryData(key, data); + }); + }, + onSettled: () => { + queryClient.invalidateQueries({ queryKey: bountyKeys.lists() }); + }, + }); } export function useClaimBounty() { - const queryClient = useQueryClient(); - - return useMutation({ - mutationFn: (id: string) => bountiesApi.claim(id), - onSuccess: (data, id) => { - queryClient.setQueryData(bountyKeys.detail(id), data); - queryClient.invalidateQueries({ queryKey: bountyKeys.lists() }); - }, - }); + const queryClient = useQueryClient(); + + return useMutation({ + mutationFn: (id: string) => + updateBountyMutation({ id, status: "IN_PROGRESS" }), + onMutate: async (id) => { + await queryClient.cancelQueries({ queryKey: bountyKeys.detail(id) }); + const previous = queryClient.getQueryData(bountyKeys.detail(id)); + + if (previous) { + queryClient.setQueryData(bountyKeys.detail(id), { + ...previous, + status: "claimed", + updatedAt: new Date().toISOString(), + }); + } + + return { previous, id }; + }, + onError: (_err, _id, context) => { + if (context?.previous) { + queryClient.setQueryData( + bountyKeys.detail(context.id), + context.previous, + ); + } + }, + onSettled: (_data, _err, id) => { + queryClient.invalidateQueries({ queryKey: bountyKeys.detail(id) }); + queryClient.invalidateQueries({ queryKey: bountyKeys.lists() }); + }, + }); } From 92eb248eab7299c0bb03638cdd554168621d7727 Mon Sep 17 00:00:00 2001 From: autonomy Date: Sun, 22 Feb 2026 16:45:50 +0000 Subject: [PATCH 2/7] fix: align GraphQL mutation types and claim status --- hooks/use-bounty-mutations.ts | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/hooks/use-bounty-mutations.ts b/hooks/use-bounty-mutations.ts index 54d142e..053ecf3 100644 --- a/hooks/use-bounty-mutations.ts +++ b/hooks/use-bounty-mutations.ts @@ -33,11 +33,11 @@ const DELETE_BOUNTY_MUTATION = ` `; type CreateBountyMutationResponse = { - createBounty: Bounty; + createBounty: Pick; }; type UpdateBountyMutationResponse = { - updateBounty: Bounty; + updateBounty: Pick; }; type DeleteBountyMutationResponse = { @@ -46,10 +46,12 @@ type DeleteBountyMutationResponse = { type UpdateBountyMutationInput = Omit & { id: string; - status?: string; + status?: Bounty["status"]; }; -async function createBountyMutation(input: CreateBountyInput): Promise { +async function createBountyMutation( + input: CreateBountyInput, +): Promise> { const response = await fetcher< CreateBountyMutationResponse, { input: CreateBountyInput } @@ -60,7 +62,7 @@ async function createBountyMutation(input: CreateBountyInput): Promise { async function updateBountyMutation( input: UpdateBountyMutationInput, -): Promise { +): Promise> { const response = await fetcher< UpdateBountyMutationResponse, { input: UpdateBountyMutationInput } @@ -177,7 +179,7 @@ export function useClaimBounty() { if (previous) { queryClient.setQueryData(bountyKeys.detail(id), { ...previous, - status: "claimed", + status: "IN_PROGRESS", updatedAt: new Date().toISOString(), }); } From c1bd1e1e559a606e6df76056dc6e5a0dbe3bf75a Mon Sep 17 00:00:00 2001 From: autonomy Date: Sun, 22 Feb 2026 16:50:47 +0000 Subject: [PATCH 3/7] fix: map claim status between GraphQL and local model --- hooks/use-bounty-mutations.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/hooks/use-bounty-mutations.ts b/hooks/use-bounty-mutations.ts index 053ecf3..4d34b3c 100644 --- a/hooks/use-bounty-mutations.ts +++ b/hooks/use-bounty-mutations.ts @@ -32,6 +32,9 @@ const DELETE_BOUNTY_MUTATION = ` } `; +const CLAIM_BOUNTY_MUTATION_STATUS = "IN_PROGRESS" as const; +const CLAIM_BOUNTY_OPTIMISTIC_STATUS: Bounty["status"] = "claimed"; + type CreateBountyMutationResponse = { createBounty: Pick; }; @@ -46,7 +49,7 @@ type DeleteBountyMutationResponse = { type UpdateBountyMutationInput = Omit & { id: string; - status?: Bounty["status"]; + status?: Bounty["status"] | typeof CLAIM_BOUNTY_MUTATION_STATUS; }; async function createBountyMutation( @@ -171,7 +174,7 @@ export function useClaimBounty() { return useMutation({ mutationFn: (id: string) => - updateBountyMutation({ id, status: "IN_PROGRESS" }), + updateBountyMutation({ id, status: CLAIM_BOUNTY_MUTATION_STATUS }), onMutate: async (id) => { await queryClient.cancelQueries({ queryKey: bountyKeys.detail(id) }); const previous = queryClient.getQueryData(bountyKeys.detail(id)); @@ -179,7 +182,7 @@ export function useClaimBounty() { if (previous) { queryClient.setQueryData(bountyKeys.detail(id), { ...previous, - status: "IN_PROGRESS", + status: CLAIM_BOUNTY_OPTIMISTIC_STATUS, updatedAt: new Date().toISOString(), }); } From 372d7e5cd9bf5bc2edf93813119d94eccdfec449 Mon Sep 17 00:00:00 2001 From: autonomy Date: Sun, 22 Feb 2026 19:13:54 +0000 Subject: [PATCH 4/7] fix: guard delete bounty acknowledgement --- hooks/use-bounty-mutations.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/hooks/use-bounty-mutations.ts b/hooks/use-bounty-mutations.ts index 4d34b3c..793f576 100644 --- a/hooks/use-bounty-mutations.ts +++ b/hooks/use-bounty-mutations.ts @@ -33,6 +33,7 @@ const DELETE_BOUNTY_MUTATION = ` `; const CLAIM_BOUNTY_MUTATION_STATUS = "IN_PROGRESS" as const; +// UI cache uses the REST status union where "claimed" represents GraphQL "IN_PROGRESS". const CLAIM_BOUNTY_OPTIMISTIC_STATUS: Bounty["status"] = "claimed"; type CreateBountyMutationResponse = { @@ -75,10 +76,14 @@ async function updateBountyMutation( } async function deleteBountyMutation(id: string): Promise { - await fetcher( + const response = await fetcher( DELETE_BOUNTY_MUTATION, { id }, )(); + + if (!response.deleteBounty) { + throw new Error(`deleteBounty returned false for id: ${id}`); + } } export function useCreateBounty() { From d9f66d5db63f8333f6ec1ca55375437bf5561b95 Mon Sep 17 00:00:00 2001 From: autonomy Date: Sun, 22 Feb 2026 19:45:36 +0000 Subject: [PATCH 5/7] fix: clear deleted bounty detail cache on settle --- hooks/use-bounty-mutations.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hooks/use-bounty-mutations.ts b/hooks/use-bounty-mutations.ts index 793f576..0c2598c 100644 --- a/hooks/use-bounty-mutations.ts +++ b/hooks/use-bounty-mutations.ts @@ -168,7 +168,8 @@ export function useDeleteBounty() { queryClient.setQueryData(key, data); }); }, - onSettled: () => { + onSettled: (_data, _err, id) => { + queryClient.removeQueries({ queryKey: bountyKeys.detail(id) }); queryClient.invalidateQueries({ queryKey: bountyKeys.lists() }); }, }); From faa007f7fe5dcd8ff60a43569a5b4ab941d4172b Mon Sep 17 00:00:00 2001 From: autonomy Date: Sun, 22 Feb 2026 20:27:15 +0000 Subject: [PATCH 6/7] fix: align GraphQL status typing and claim flow --- hooks/use-bounty-mutations.ts | 47 +++++++++++++++++++++++++++++------ 1 file changed, 40 insertions(+), 7 deletions(-) diff --git a/hooks/use-bounty-mutations.ts b/hooks/use-bounty-mutations.ts index 0c2598c..db8bc90 100644 --- a/hooks/use-bounty-mutations.ts +++ b/hooks/use-bounty-mutations.ts @@ -32,8 +32,19 @@ const DELETE_BOUNTY_MUTATION = ` } `; -const CLAIM_BOUNTY_MUTATION_STATUS = "IN_PROGRESS" as const; -// UI cache uses the REST status union where "claimed" represents GraphQL "IN_PROGRESS". +const CLAIM_BOUNTY_MUTATION = ` + mutation ClaimBounty($id: ID!) { + claimBounty(id: $id) { + id + status + updatedAt + } + } +`; + +type GraphQLBountyStatus = "OPEN" | "CLAIMED" | "CLOSED"; + +// UI cache uses the REST status union where "claimed" represents GraphQL "CLAIMED". const CLAIM_BOUNTY_OPTIMISTIC_STATUS: Bounty["status"] = "claimed"; type CreateBountyMutationResponse = { @@ -41,16 +52,28 @@ type CreateBountyMutationResponse = { }; type UpdateBountyMutationResponse = { - updateBounty: Pick; + updateBounty: { + id: string; + status: GraphQLBountyStatus; + updatedAt: string; + }; }; type DeleteBountyMutationResponse = { deleteBounty: boolean; }; +type ClaimBountyMutationResponse = { + claimBounty: { + id: string; + status: GraphQLBountyStatus; + updatedAt: string; + }; +}; + type UpdateBountyMutationInput = Omit & { id: string; - status?: Bounty["status"] | typeof CLAIM_BOUNTY_MUTATION_STATUS; + status?: GraphQLBountyStatus; }; async function createBountyMutation( @@ -66,7 +89,7 @@ async function createBountyMutation( async function updateBountyMutation( input: UpdateBountyMutationInput, -): Promise> { +): Promise { const response = await fetcher< UpdateBountyMutationResponse, { input: UpdateBountyMutationInput } @@ -75,6 +98,17 @@ async function updateBountyMutation( return response.updateBounty; } +async function claimBountyMutation( + id: string, +): Promise { + const response = await fetcher( + CLAIM_BOUNTY_MUTATION, + { id }, + )(); + + return response.claimBounty; +} + async function deleteBountyMutation(id: string): Promise { const response = await fetcher( DELETE_BOUNTY_MUTATION, @@ -179,8 +213,7 @@ export function useClaimBounty() { const queryClient = useQueryClient(); return useMutation({ - mutationFn: (id: string) => - updateBountyMutation({ id, status: CLAIM_BOUNTY_MUTATION_STATUS }), + mutationFn: claimBountyMutation, onMutate: async (id) => { await queryClient.cancelQueries({ queryKey: bountyKeys.detail(id) }); const previous = queryClient.getQueryData(bountyKeys.detail(id)); From a0970f5470f2ce5c130dd22fbe35a9798ddbb00c Mon Sep 17 00:00:00 2001 From: autonomy Date: Sun, 22 Feb 2026 20:59:18 +0000 Subject: [PATCH 7/7] fix: centralize bounty keys and guard delete cache cleanup --- hooks/Use-bounty-detail.ts | 2 +- hooks/use-bounties.ts | 26 +++++++++--------- hooks/use-bounty-mutations.ts | 4 ++- hooks/use-bounty.ts | 18 ++++++------- hooks/use-infinite-bounties.ts | 49 ++++++++++++++++++++-------------- lib/query/sync/handlers.ts | 23 +++++++++------- 6 files changed, 67 insertions(+), 55 deletions(-) diff --git a/hooks/Use-bounty-detail.ts b/hooks/Use-bounty-detail.ts index 3bf88bf..4bb7e5a 100644 --- a/hooks/Use-bounty-detail.ts +++ b/hooks/Use-bounty-detail.ts @@ -1,6 +1,6 @@ import { useQuery } from "@tanstack/react-query"; import { bountiesApi, type Bounty } from "@/lib/api"; -import { bountyKeys } from "./use-bounties"; +import { bountyKeys } from "@/lib/query/query-keys"; export function useBountyDetail(id: string) { return useQuery({ diff --git a/hooks/use-bounties.ts b/hooks/use-bounties.ts index eeb4ea9..a04b17a 100644 --- a/hooks/use-bounties.ts +++ b/hooks/use-bounties.ts @@ -1,17 +1,15 @@ -import { useQuery } from '@tanstack/react-query'; -import { bountiesApi, type Bounty, type BountyListParams, type PaginatedResponse } from '@/lib/api'; - -export const bountyKeys = { - all: ['bounties'] as const, - lists: () => [...bountyKeys.all, 'list'] as const, - list: (params?: BountyListParams) => [...bountyKeys.lists(), params] as const, - details: () => [...bountyKeys.all, 'detail'] as const, - detail: (id: string) => [...bountyKeys.details(), id] as const, -}; +import { useQuery } from "@tanstack/react-query"; +import { + bountiesApi, + type Bounty, + type BountyListParams, + type PaginatedResponse, +} from "@/lib/api"; +import { bountyKeys } from "@/lib/query/query-keys"; export function useBounties(params?: BountyListParams) { - return useQuery>({ - queryKey: bountyKeys.list(params), - queryFn: () => bountiesApi.list(params), - }); + return useQuery>({ + queryKey: bountyKeys.list(params), + queryFn: () => bountiesApi.list(params), + }); } diff --git a/hooks/use-bounty-mutations.ts b/hooks/use-bounty-mutations.ts index db8bc90..1def94f 100644 --- a/hooks/use-bounty-mutations.ts +++ b/hooks/use-bounty-mutations.ts @@ -203,7 +203,9 @@ export function useDeleteBounty() { }); }, onSettled: (_data, _err, id) => { - queryClient.removeQueries({ queryKey: bountyKeys.detail(id) }); + if (!_err) { + queryClient.removeQueries({ queryKey: bountyKeys.detail(id) }); + } queryClient.invalidateQueries({ queryKey: bountyKeys.lists() }); }, }); diff --git a/hooks/use-bounty.ts b/hooks/use-bounty.ts index 97512e4..d228a58 100644 --- a/hooks/use-bounty.ts +++ b/hooks/use-bounty.ts @@ -1,15 +1,15 @@ -import { useQuery } from '@tanstack/react-query'; -import { bountiesApi, type Bounty } from '@/lib/api'; -import { bountyKeys } from './use-bounties'; +import { useQuery } from "@tanstack/react-query"; +import { bountiesApi, type Bounty } from "@/lib/api"; +import { bountyKeys } from "@/lib/query/query-keys"; interface UseBountyOptions { - enabled?: boolean; + enabled?: boolean; } export function useBounty(id: string, options?: UseBountyOptions) { - return useQuery({ - queryKey: bountyKeys.detail(id), - queryFn: () => bountiesApi.getById(id), - enabled: options?.enabled ?? !!id, - }); + return useQuery({ + queryKey: bountyKeys.detail(id), + queryFn: () => bountiesApi.getById(id), + enabled: options?.enabled ?? !!id, + }); } diff --git a/hooks/use-infinite-bounties.ts b/hooks/use-infinite-bounties.ts index ac86e16..ae19c12 100644 --- a/hooks/use-infinite-bounties.ts +++ b/hooks/use-infinite-bounties.ts @@ -1,29 +1,38 @@ -import { useInfiniteQuery } from '@tanstack/react-query'; -import { bountiesApi, type Bounty, type BountyListParams, type PaginatedResponse } from '@/lib/api'; -import { bountyKeys } from './use-bounties'; +import { useInfiniteQuery } from "@tanstack/react-query"; +import { + bountiesApi, + type Bounty, + type BountyListParams, + type PaginatedResponse, +} from "@/lib/api"; +import { bountyKeys } from "@/lib/query/query-keys"; const DEFAULT_LIMIT = 20; -export function useInfiniteBounties(params?: Omit) { - return useInfiniteQuery>({ - queryKey: [...bountyKeys.lists(), 'infinite', params] as const, - queryFn: ({ pageParam }) => - bountiesApi.list({ ...params, page: pageParam as number, limit: params?.limit ?? DEFAULT_LIMIT }), - initialPageParam: 1, - getNextPageParam: (lastPage) => { - const { page, totalPages } = lastPage.pagination; - return page < totalPages ? page + 1 : undefined; - }, - getPreviousPageParam: (firstPage) => { - const { page } = firstPage.pagination; - return page > 1 ? page - 1 : undefined; - }, - }); +export function useInfiniteBounties(params?: Omit) { + return useInfiniteQuery>({ + queryKey: bountyKeys.infinite(params), + queryFn: ({ pageParam }) => + bountiesApi.list({ + ...params, + page: pageParam as number, + limit: params?.limit ?? DEFAULT_LIMIT, + }), + initialPageParam: 1, + getNextPageParam: (lastPage) => { + const { page, totalPages } = lastPage.pagination; + return page < totalPages ? page + 1 : undefined; + }, + getPreviousPageParam: (firstPage) => { + const { page } = firstPage.pagination; + return page > 1 ? page - 1 : undefined; + }, + }); } // Helper to flatten infinite query pages export function flattenBountyPages( - pages: PaginatedResponse[] | undefined + pages: PaginatedResponse[] | undefined, ): Bounty[] { - return pages?.flatMap((page) => page.data) ?? []; + return pages?.flatMap((page) => page.data) ?? []; } diff --git a/lib/query/sync/handlers.ts b/lib/query/sync/handlers.ts index d1c98a0..0f0a5d2 100644 --- a/lib/query/sync/handlers.ts +++ b/lib/query/sync/handlers.ts @@ -1,9 +1,9 @@ -import { QueryClient } from '@tanstack/react-query'; -import { Bounty, PaginatedResponse } from '@/lib/api'; -import { bountyKeys } from '@/hooks/use-bounties'; +import { QueryClient } from "@tanstack/react-query"; +import { Bounty, PaginatedResponse } from "@/lib/api"; +import { bountyKeys } from "@/lib/query/query-keys"; export function handleBountyCreated(queryClient: QueryClient, bounty: Bounty) { - console.log('[Sync] Handling bounty.created:', bounty.id); + console.log("[Sync] Handling bounty.created:", bounty.id); // Update lists queryClient.setQueriesData>( @@ -18,7 +18,7 @@ export function handleBountyCreated(queryClient: QueryClient, bounty: Bounty) { total: oldData.pagination.total + 1, }, }; - } + }, ); // Set detail cache @@ -26,7 +26,7 @@ export function handleBountyCreated(queryClient: QueryClient, bounty: Bounty) { } export function handleBountyUpdated(queryClient: QueryClient, bounty: Bounty) { - console.log('[Sync] Handling bounty.updated:', bounty.id); + console.log("[Sync] Handling bounty.updated:", bounty.id); // Update lists queryClient.setQueriesData>( @@ -37,15 +37,18 @@ export function handleBountyUpdated(queryClient: QueryClient, bounty: Bounty) { ...oldData, data: oldData.data.map((b) => (b.id === bounty.id ? bounty : b)), }; - } + }, ); // Update detail cache queryClient.setQueryData(bountyKeys.detail(bounty.id), bounty); } -export function handleBountyDeleted(queryClient: QueryClient, bountyId: string) { - console.log('[Sync] Handling bounty.deleted:', bountyId); +export function handleBountyDeleted( + queryClient: QueryClient, + bountyId: string, +) { + console.log("[Sync] Handling bounty.deleted:", bountyId); // Update lists queryClient.setQueriesData>( @@ -60,7 +63,7 @@ export function handleBountyDeleted(queryClient: QueryClient, bountyId: string) total: Math.max(0, oldData.pagination.total - 1), }, }; - } + }, ); // Invalidate or remove detail cache