@pfm-platform/goals-data-access 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs ADDED
@@ -0,0 +1,266 @@
1
+ 'use strict';
2
+
3
+ var reactQuery = require('@tanstack/react-query');
4
+ var shared = require('@pfm-platform/shared');
5
+ var axios = require('axios');
6
+
7
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
8
+
9
+ var axios__default = /*#__PURE__*/_interopDefault(axios);
10
+
11
+ // src/queries/useSavingsGoals.ts
12
+ var api = axios__default.default.create({
13
+ baseURL: "/api",
14
+ headers: {
15
+ "Content-Type": "application/json"
16
+ }
17
+ });
18
+
19
+ // src/keys.ts
20
+ var goalKeys = {
21
+ all: ["goals"],
22
+ // Savings goals
23
+ savingsLists: () => [...goalKeys.all, "savings", "list"],
24
+ savingsList: (userId) => [...goalKeys.savingsLists(), userId],
25
+ savingsDetails: () => [...goalKeys.all, "savings", "detail"],
26
+ savingsDetail: (userId, goalId) => [...goalKeys.savingsDetails(), userId, goalId],
27
+ // Payoff goals
28
+ payoffLists: () => [...goalKeys.all, "payoff", "list"],
29
+ payoffList: (userId) => [...goalKeys.payoffLists(), userId],
30
+ payoffDetails: () => [...goalKeys.all, "payoff", "detail"],
31
+ payoffDetail: (userId, goalId) => [...goalKeys.payoffDetails(), userId, goalId],
32
+ // Image catalogs (no userId, global resources)
33
+ savingsImages: () => [...goalKeys.all, "savings", "images"],
34
+ payoffImages: () => [...goalKeys.all, "payoff", "images"]
35
+ };
36
+
37
+ // src/queries/useSavingsGoals.ts
38
+ function useSavingsGoals(params, options) {
39
+ const { userId } = params;
40
+ return reactQuery.useQuery({
41
+ queryKey: goalKeys.savingsList(userId),
42
+ queryFn: async () => {
43
+ const response = await api.get(`/users/${userId}/savings_goals`);
44
+ return shared.SavingsGoalsResponseSchema.parse(response.data);
45
+ },
46
+ staleTime: 1e3 * 60 * 5,
47
+ // 5 minutes (same as budgets)
48
+ ...options
49
+ });
50
+ }
51
+ function useSavingsGoal(params, options) {
52
+ const { userId, goalId } = params;
53
+ return reactQuery.useQuery({
54
+ queryKey: goalKeys.savingsDetail(userId, goalId),
55
+ queryFn: async () => {
56
+ const response = await api.get(
57
+ `/users/${userId}/savings_goals/${goalId}`
58
+ );
59
+ return shared.SavingsGoalSchema.parse(response.data);
60
+ },
61
+ staleTime: 1e3 * 60 * 5,
62
+ // 5 minutes
63
+ ...options
64
+ });
65
+ }
66
+ function useSavingsGoalImages(options) {
67
+ return reactQuery.useQuery({
68
+ queryKey: goalKeys.savingsImages(),
69
+ queryFn: async () => {
70
+ const response = await api.get("/savings_goals");
71
+ return shared.GoalImagesResponseSchema.parse(response.data);
72
+ },
73
+ staleTime: 1e3 * 60 * 60 * 24,
74
+ // 24 hours (images rarely change)
75
+ ...options
76
+ });
77
+ }
78
+ function useCreateSavingsGoal(options) {
79
+ const queryClient = reactQuery.useQueryClient();
80
+ return reactQuery.useMutation({
81
+ mutationFn: async ({ userId, data }) => {
82
+ const validated = shared.GoalCreateSchema.parse(data);
83
+ const response = await api.post(`/users/${userId}/savings_goals`, {
84
+ savings_goal: validated
85
+ });
86
+ return shared.SavingsGoalSchema.parse(response.data);
87
+ },
88
+ onSuccess: (_, { userId }) => {
89
+ queryClient.invalidateQueries({ queryKey: goalKeys.savingsLists() });
90
+ },
91
+ ...options
92
+ });
93
+ }
94
+ function useUpdateSavingsGoal(options) {
95
+ const queryClient = reactQuery.useQueryClient();
96
+ return reactQuery.useMutation({
97
+ mutationFn: async ({ userId, goalId, data }) => {
98
+ const validated = shared.GoalUpdateSchema.parse(data);
99
+ const { id, ...payload } = validated;
100
+ const response = await api.put(`/users/${userId}/savings_goals/${goalId}`, {
101
+ savings_goal: payload
102
+ });
103
+ return shared.SavingsGoalSchema.parse(response.data);
104
+ },
105
+ onSuccess: (_, { userId, goalId }) => {
106
+ queryClient.invalidateQueries({ queryKey: goalKeys.savingsLists() });
107
+ queryClient.invalidateQueries({
108
+ queryKey: goalKeys.savingsDetail(userId, goalId)
109
+ });
110
+ },
111
+ ...options
112
+ });
113
+ }
114
+ function useArchiveSavingsGoal(options) {
115
+ const queryClient = reactQuery.useQueryClient();
116
+ return reactQuery.useMutation({
117
+ mutationFn: async ({ userId, goalId }) => {
118
+ await api.put(`/users/${userId}/savings_goals/${goalId}/archive`);
119
+ },
120
+ onSuccess: (_, { userId, goalId }) => {
121
+ queryClient.invalidateQueries({ queryKey: goalKeys.savingsLists() });
122
+ queryClient.invalidateQueries({
123
+ queryKey: goalKeys.savingsDetail(userId, goalId)
124
+ });
125
+ },
126
+ ...options
127
+ });
128
+ }
129
+ function useDeleteSavingsGoal(options) {
130
+ const queryClient = reactQuery.useQueryClient();
131
+ return reactQuery.useMutation({
132
+ mutationFn: async ({ userId, goalId }) => {
133
+ await api.delete(`/users/${userId}/savings_goals/${goalId}`);
134
+ },
135
+ onSuccess: (_, { userId, goalId }) => {
136
+ queryClient.invalidateQueries({ queryKey: goalKeys.savingsLists() });
137
+ queryClient.removeQueries({
138
+ queryKey: goalKeys.savingsDetail(userId, goalId)
139
+ });
140
+ },
141
+ ...options
142
+ });
143
+ }
144
+ function usePayoffGoals(params, options) {
145
+ const { userId } = params;
146
+ return reactQuery.useQuery({
147
+ queryKey: goalKeys.payoffList(userId),
148
+ queryFn: async () => {
149
+ const response = await api.get(`/users/${userId}/payoff_goals`);
150
+ return shared.PayoffGoalsResponseSchema.parse(response.data);
151
+ },
152
+ staleTime: 1e3 * 60 * 5,
153
+ // 5 minutes (same as budgets)
154
+ ...options
155
+ });
156
+ }
157
+ function usePayoffGoal(params, options) {
158
+ const { userId, goalId } = params;
159
+ return reactQuery.useQuery({
160
+ queryKey: goalKeys.payoffDetail(userId, goalId),
161
+ queryFn: async () => {
162
+ const response = await api.get(`/users/${userId}/payoff_goals/${goalId}`);
163
+ return shared.PayoffGoalSchema.parse(response.data);
164
+ },
165
+ staleTime: 1e3 * 60 * 5,
166
+ // 5 minutes
167
+ ...options
168
+ });
169
+ }
170
+ function usePayoffGoalImages(options) {
171
+ return reactQuery.useQuery({
172
+ queryKey: goalKeys.payoffImages(),
173
+ queryFn: async () => {
174
+ const response = await api.get("/payoff_goals");
175
+ return shared.GoalImagesResponseSchema.parse(response.data);
176
+ },
177
+ staleTime: 1e3 * 60 * 60 * 24,
178
+ // 24 hours (images rarely change)
179
+ ...options
180
+ });
181
+ }
182
+ function useCreatePayoffGoal(options) {
183
+ const queryClient = reactQuery.useQueryClient();
184
+ return reactQuery.useMutation({
185
+ mutationFn: async ({ userId, data }) => {
186
+ const validated = shared.GoalCreateSchema.parse(data);
187
+ const response = await api.post(`/users/${userId}/payoff_goals`, {
188
+ payoff_goal: validated
189
+ });
190
+ return shared.PayoffGoalSchema.parse(response.data);
191
+ },
192
+ onSuccess: (_, { userId }) => {
193
+ queryClient.invalidateQueries({ queryKey: goalKeys.payoffLists() });
194
+ },
195
+ ...options
196
+ });
197
+ }
198
+ function useUpdatePayoffGoal(options) {
199
+ const queryClient = reactQuery.useQueryClient();
200
+ return reactQuery.useMutation({
201
+ mutationFn: async ({ userId, goalId, data }) => {
202
+ const validated = shared.GoalUpdateSchema.parse(data);
203
+ const { id, ...payload } = validated;
204
+ const response = await api.put(`/users/${userId}/payoff_goals/${goalId}`, {
205
+ payoff_goal: payload
206
+ });
207
+ return shared.PayoffGoalSchema.parse(response.data);
208
+ },
209
+ onSuccess: (_, { userId, goalId }) => {
210
+ queryClient.invalidateQueries({ queryKey: goalKeys.payoffLists() });
211
+ queryClient.invalidateQueries({
212
+ queryKey: goalKeys.payoffDetail(userId, goalId)
213
+ });
214
+ },
215
+ ...options
216
+ });
217
+ }
218
+ function useArchivePayoffGoal(options) {
219
+ const queryClient = reactQuery.useQueryClient();
220
+ return reactQuery.useMutation({
221
+ mutationFn: async ({ userId, goalId }) => {
222
+ await api.put(`/users/${userId}/payoff_goals/${goalId}/archive`);
223
+ },
224
+ onSuccess: (_, { userId, goalId }) => {
225
+ queryClient.invalidateQueries({ queryKey: goalKeys.payoffLists() });
226
+ queryClient.invalidateQueries({
227
+ queryKey: goalKeys.payoffDetail(userId, goalId)
228
+ });
229
+ },
230
+ ...options
231
+ });
232
+ }
233
+ function useDeletePayoffGoal(options) {
234
+ const queryClient = reactQuery.useQueryClient();
235
+ return reactQuery.useMutation({
236
+ mutationFn: async ({ userId, goalId }) => {
237
+ await api.delete(`/users/${userId}/payoff_goals/${goalId}`);
238
+ },
239
+ onSuccess: (_, { userId, goalId }) => {
240
+ queryClient.invalidateQueries({ queryKey: goalKeys.payoffLists() });
241
+ queryClient.removeQueries({
242
+ queryKey: goalKeys.payoffDetail(userId, goalId)
243
+ });
244
+ },
245
+ ...options
246
+ });
247
+ }
248
+
249
+ exports.api = api;
250
+ exports.goalKeys = goalKeys;
251
+ exports.useArchivePayoffGoal = useArchivePayoffGoal;
252
+ exports.useArchiveSavingsGoal = useArchiveSavingsGoal;
253
+ exports.useCreatePayoffGoal = useCreatePayoffGoal;
254
+ exports.useCreateSavingsGoal = useCreateSavingsGoal;
255
+ exports.useDeletePayoffGoal = useDeletePayoffGoal;
256
+ exports.useDeleteSavingsGoal = useDeleteSavingsGoal;
257
+ exports.usePayoffGoal = usePayoffGoal;
258
+ exports.usePayoffGoalImages = usePayoffGoalImages;
259
+ exports.usePayoffGoals = usePayoffGoals;
260
+ exports.useSavingsGoal = useSavingsGoal;
261
+ exports.useSavingsGoalImages = useSavingsGoalImages;
262
+ exports.useSavingsGoals = useSavingsGoals;
263
+ exports.useUpdatePayoffGoal = useUpdatePayoffGoal;
264
+ exports.useUpdateSavingsGoal = useUpdateSavingsGoal;
265
+ //# sourceMappingURL=index.cjs.map
266
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/client.ts","../src/keys.ts","../src/queries/useSavingsGoals.ts","../src/queries/useSavingsGoal.ts","../src/queries/useSavingsGoalImages.ts","../src/mutations/useCreateSavingsGoal.ts","../src/mutations/useUpdateSavingsGoal.ts","../src/mutations/useArchiveSavingsGoal.ts","../src/mutations/useDeleteSavingsGoal.ts","../src/queries/usePayoffGoals.ts","../src/queries/usePayoffGoal.ts","../src/queries/usePayoffGoalImages.ts","../src/mutations/useCreatePayoffGoal.ts","../src/mutations/useUpdatePayoffGoal.ts","../src/mutations/useArchivePayoffGoal.ts","../src/mutations/useDeletePayoffGoal.ts"],"names":["axios","useQuery","SavingsGoalsResponseSchema","SavingsGoalSchema","GoalImagesResponseSchema","useQueryClient","useMutation","GoalCreateSchema","GoalUpdateSchema","PayoffGoalsResponseSchema","PayoffGoalSchema"],"mappings":"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","file":"index.cjs","sourcesContent":["import axios from 'axios';\n\n/**\n * Axios instance for Goals API\n * Base URL configured through environment variables or defaults to relative path\n */\nexport const api = axios.create({\n baseURL: '/api',\n headers: {\n 'Content-Type': 'application/json',\n },\n});\n","/**\n * Query key factory for Goals domain\n * Handles both Savings goals and Payoff goals with shared structure\n */\n\nexport type GoalType = 'savings' | 'payoff';\n\nexport const goalKeys = {\n all: ['goals'] as const,\n\n // Savings goals\n savingsLists: () => [...goalKeys.all, 'savings', 'list'] as const,\n savingsList: (userId: string) =>\n [...goalKeys.savingsLists(), userId] as const,\n savingsDetails: () => [...goalKeys.all, 'savings', 'detail'] as const,\n savingsDetail: (userId: string, goalId: number) =>\n [...goalKeys.savingsDetails(), userId, goalId] as const,\n\n // Payoff goals\n payoffLists: () => [...goalKeys.all, 'payoff', 'list'] as const,\n payoffList: (userId: string) =>\n [...goalKeys.payoffLists(), userId] as const,\n payoffDetails: () => [...goalKeys.all, 'payoff', 'detail'] as const,\n payoffDetail: (userId: string, goalId: number) =>\n [...goalKeys.payoffDetails(), userId, goalId] as const,\n\n // Image catalogs (no userId, global resources)\n savingsImages: () => [...goalKeys.all, 'savings', 'images'] as const,\n payoffImages: () => [...goalKeys.all, 'payoff', 'images'] as const,\n};\n","import { useQuery, type UseQueryOptions } from '@tanstack/react-query';\nimport { SavingsGoalsResponseSchema, type SavingsGoalsResponse } from '@pfm-platform/shared';\nimport { api } from '../client';\nimport { goalKeys } from '../keys';\n\n/**\n * Parameters for useSavingsGoals query hook\n */\nexport interface UseSavingsGoalsParams {\n userId: string;\n}\n\n/**\n * Query hook for fetching all savings goals for a user\n *\n * @example\n * ```tsx\n * const { data, isLoading } = useSavingsGoals({ userId: 'user123' });\n * ```\n */\nexport function useSavingsGoals(\n params: UseSavingsGoalsParams,\n options?: Omit<UseQueryOptions<SavingsGoalsResponse>, 'queryKey' | 'queryFn'>\n) {\n const { userId } = params;\n\n return useQuery({\n queryKey: goalKeys.savingsList(userId),\n queryFn: async () => {\n const response = await api.get(`/users/${userId}/savings_goals`);\n return SavingsGoalsResponseSchema.parse(response.data);\n },\n staleTime: 1000 * 60 * 5, // 5 minutes (same as budgets)\n ...options,\n });\n}\n","import { useQuery, type UseQueryOptions } from '@tanstack/react-query';\nimport { SavingsGoalSchema, type SavingsGoal } from '@pfm-platform/shared';\nimport { api } from '../client';\nimport { goalKeys } from '../keys';\n\n/**\n * Parameters for useSavingsGoal query hook\n */\nexport interface UseSavingsGoalParams {\n userId: string;\n goalId: number;\n}\n\n/**\n * Query hook for fetching a single savings goal by ID\n *\n * @example\n * ```tsx\n * const { data, isLoading } = useSavingsGoal({\n * userId: 'user123',\n * goalId: 456\n * });\n * ```\n */\nexport function useSavingsGoal(\n params: UseSavingsGoalParams,\n options?: Omit<UseQueryOptions<SavingsGoal>, 'queryKey' | 'queryFn'>\n) {\n const { userId, goalId } = params;\n\n return useQuery({\n queryKey: goalKeys.savingsDetail(userId, goalId),\n queryFn: async () => {\n const response = await api.get(\n `/users/${userId}/savings_goals/${goalId}`\n );\n return SavingsGoalSchema.parse(response.data);\n },\n staleTime: 1000 * 60 * 5, // 5 minutes\n ...options,\n });\n}\n","import { useQuery, type UseQueryOptions } from '@tanstack/react-query';\nimport { GoalImagesResponseSchema, type GoalImagesResponse } from '@pfm-platform/shared';\nimport { api } from '../client';\nimport { goalKeys } from '../keys';\n\n/**\n * Query hook for fetching savings goal image catalog\n * This is a global resource (no userId required)\n *\n * @example\n * ```tsx\n * const { data, isLoading } = useSavingsGoalImages();\n * ```\n */\nexport function useSavingsGoalImages(\n options?: Omit<UseQueryOptions<GoalImagesResponse>, 'queryKey' | 'queryFn'>\n) {\n return useQuery({\n queryKey: goalKeys.savingsImages(),\n queryFn: async () => {\n const response = await api.get('/savings_goals');\n return GoalImagesResponseSchema.parse(response.data);\n },\n staleTime: 1000 * 60 * 60 * 24, // 24 hours (images rarely change)\n ...options,\n });\n}\n","import {\n useMutation,\n useQueryClient,\n type UseMutationOptions,\n} from '@tanstack/react-query';\nimport {\n GoalCreateSchema,\n SavingsGoalSchema,\n type GoalCreate,\n type SavingsGoal,\n} from '@pfm-platform/shared';\nimport { api } from '../client';\nimport { goalKeys } from '../keys';\n\n/**\n * Parameters for useCreateSavingsGoal mutation\n */\nexport interface CreateSavingsGoalParams {\n userId: string;\n data: GoalCreate;\n}\n\n/**\n * Mutation hook for creating a savings goal\n *\n * @example\n * ```tsx\n * const createSavingsGoal = useCreateSavingsGoal();\n *\n * createSavingsGoal.mutate({\n * userId: 'user123',\n * data: {\n * name: 'Emergency Fund',\n * image_name: 'piggy_bank',\n * target_value: '5000.00',\n * target_completion_on: '2026-12-31',\n * }\n * });\n * ```\n */\nexport function useCreateSavingsGoal(\n options?: Omit<\n UseMutationOptions<SavingsGoal, Error, CreateSavingsGoalParams>,\n 'mutationFn'\n >\n) {\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: async ({ userId, data }: CreateSavingsGoalParams) => {\n const validated = GoalCreateSchema.parse(data);\n\n // Request body wrapping: { savings_goal: {...} }\n const response = await api.post(`/users/${userId}/savings_goals`, {\n savings_goal: validated,\n });\n\n return SavingsGoalSchema.parse(response.data);\n },\n onSuccess: (_, { userId }) => {\n // Invalidate all savings goal lists\n queryClient.invalidateQueries({ queryKey: goalKeys.savingsLists() });\n },\n ...options,\n });\n}\n","import {\n useMutation,\n useQueryClient,\n type UseMutationOptions,\n} from '@tanstack/react-query';\nimport {\n GoalUpdateSchema,\n SavingsGoalSchema,\n type GoalUpdate,\n type SavingsGoal,\n} from '@pfm-platform/shared';\nimport { api } from '../client';\nimport { goalKeys } from '../keys';\n\n/**\n * Parameters for useUpdateSavingsGoal mutation\n */\nexport interface UpdateSavingsGoalParams {\n userId: string;\n goalId: number;\n data: GoalUpdate;\n}\n\n/**\n * Mutation hook for updating a savings goal\n *\n * @example\n * ```tsx\n * const updateSavingsGoal = useUpdateSavingsGoal();\n *\n * updateSavingsGoal.mutate({\n * userId: 'user123',\n * goalId: 456,\n * data: {\n * id: 456,\n * name: 'Updated Emergency Fund',\n * image_name: 'piggy_bank',\n * target_value: '6000.00'\n * }\n * });\n * ```\n */\nexport function useUpdateSavingsGoal(\n options?: Omit<\n UseMutationOptions<SavingsGoal, Error, UpdateSavingsGoalParams>,\n 'mutationFn'\n >\n) {\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: async ({ userId, goalId, data }: UpdateSavingsGoalParams) => {\n const validated = GoalUpdateSchema.parse(data);\n\n // Request body wrapping: { savings_goal: {...} } (without id)\n const { id, ...payload } = validated;\n const response = await api.put(`/users/${userId}/savings_goals/${goalId}`, {\n savings_goal: payload,\n });\n\n return SavingsGoalSchema.parse(response.data);\n },\n onSuccess: (_, { userId, goalId }) => {\n // Invalidate lists and specific detail\n queryClient.invalidateQueries({ queryKey: goalKeys.savingsLists() });\n queryClient.invalidateQueries({\n queryKey: goalKeys.savingsDetail(userId, goalId),\n });\n },\n ...options,\n });\n}\n","import {\n useMutation,\n useQueryClient,\n type UseMutationOptions,\n} from '@tanstack/react-query';\nimport { api } from '../client';\nimport { goalKeys } from '../keys';\n\n/**\n * Parameters for useArchiveSavingsGoal mutation\n */\nexport interface ArchiveSavingsGoalParams {\n userId: string;\n goalId: number;\n}\n\n/**\n * Mutation hook for archiving a savings goal\n * Archived goals remain in system but marked as inactive\n *\n * @example\n * ```tsx\n * const archiveSavingsGoal = useArchiveSavingsGoal();\n *\n * archiveSavingsGoal.mutate({\n * userId: 'user123',\n * goalId: 456\n * });\n * ```\n */\nexport function useArchiveSavingsGoal(\n options?: Omit<\n UseMutationOptions<void, Error, ArchiveSavingsGoalParams>,\n 'mutationFn'\n >\n) {\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: async ({ userId, goalId }: ArchiveSavingsGoalParams) => {\n await api.put(`/users/${userId}/savings_goals/${goalId}/archive`);\n // No response body expected\n },\n onSuccess: (_, { userId, goalId }) => {\n // Invalidate lists and specific detail\n queryClient.invalidateQueries({ queryKey: goalKeys.savingsLists() });\n queryClient.invalidateQueries({\n queryKey: goalKeys.savingsDetail(userId, goalId),\n });\n },\n ...options,\n });\n}\n","import {\n useMutation,\n useQueryClient,\n type UseMutationOptions,\n} from '@tanstack/react-query';\nimport { api } from '../client';\nimport { goalKeys } from '../keys';\n\n/**\n * Parameters for useDeleteSavingsGoal mutation\n */\nexport interface DeleteSavingsGoalParams {\n userId: string;\n goalId: number;\n}\n\n/**\n * Mutation hook for deleting a savings goal permanently\n *\n * @example\n * ```tsx\n * const deleteSavingsGoal = useDeleteSavingsGoal();\n *\n * deleteSavingsGoal.mutate({\n * userId: 'user123',\n * goalId: 456\n * });\n * ```\n */\nexport function useDeleteSavingsGoal(\n options?: Omit<\n UseMutationOptions<void, Error, DeleteSavingsGoalParams>,\n 'mutationFn'\n >\n) {\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: async ({ userId, goalId }: DeleteSavingsGoalParams) => {\n await api.delete(`/users/${userId}/savings_goals/${goalId}`);\n // No response body expected (204 No Content)\n },\n onSuccess: (_, { userId, goalId }) => {\n // Invalidate lists and remove specific detail from cache\n queryClient.invalidateQueries({ queryKey: goalKeys.savingsLists() });\n queryClient.removeQueries({\n queryKey: goalKeys.savingsDetail(userId, goalId),\n });\n },\n ...options,\n });\n}\n","import { useQuery, type UseQueryOptions } from '@tanstack/react-query';\nimport { PayoffGoalsResponseSchema, type PayoffGoalsResponse } from '@pfm-platform/shared';\nimport { api } from '../client';\nimport { goalKeys } from '../keys';\n\n/**\n * Parameters for usePayoffGoals query hook\n */\nexport interface UsePayoffGoalsParams {\n userId: string;\n}\n\n/**\n * Query hook for fetching all payoff goals for a user\n *\n * @example\n * ```tsx\n * const { data, isLoading } = usePayoffGoals({ userId: 'user123' });\n * ```\n */\nexport function usePayoffGoals(\n params: UsePayoffGoalsParams,\n options?: Omit<UseQueryOptions<PayoffGoalsResponse>, 'queryKey' | 'queryFn'>\n) {\n const { userId } = params;\n\n return useQuery({\n queryKey: goalKeys.payoffList(userId),\n queryFn: async () => {\n const response = await api.get(`/users/${userId}/payoff_goals`);\n return PayoffGoalsResponseSchema.parse(response.data);\n },\n staleTime: 1000 * 60 * 5, // 5 minutes (same as budgets)\n ...options,\n });\n}\n","import { useQuery, type UseQueryOptions } from '@tanstack/react-query';\nimport { PayoffGoalSchema, type PayoffGoal } from '@pfm-platform/shared';\nimport { api } from '../client';\nimport { goalKeys } from '../keys';\n\n/**\n * Parameters for usePayoffGoal query hook\n */\nexport interface UsePayoffGoalParams {\n userId: string;\n goalId: number;\n}\n\n/**\n * Query hook for fetching a single payoff goal by ID\n *\n * @example\n * ```tsx\n * const { data, isLoading } = usePayoffGoal({\n * userId: 'user123',\n * goalId: 456\n * });\n * ```\n */\nexport function usePayoffGoal(\n params: UsePayoffGoalParams,\n options?: Omit<UseQueryOptions<PayoffGoal>, 'queryKey' | 'queryFn'>\n) {\n const { userId, goalId } = params;\n\n return useQuery({\n queryKey: goalKeys.payoffDetail(userId, goalId),\n queryFn: async () => {\n const response = await api.get(`/users/${userId}/payoff_goals/${goalId}`);\n return PayoffGoalSchema.parse(response.data);\n },\n staleTime: 1000 * 60 * 5, // 5 minutes\n ...options,\n });\n}\n","import { useQuery, type UseQueryOptions } from '@tanstack/react-query';\nimport { GoalImagesResponseSchema, type GoalImagesResponse } from '@pfm-platform/shared';\nimport { api } from '../client';\nimport { goalKeys } from '../keys';\n\n/**\n * Query hook for fetching payoff goal image catalog\n * This is a global resource (no userId required)\n *\n * @example\n * ```tsx\n * const { data, isLoading } = usePayoffGoalImages();\n * ```\n */\nexport function usePayoffGoalImages(\n options?: Omit<UseQueryOptions<GoalImagesResponse>, 'queryKey' | 'queryFn'>\n) {\n return useQuery({\n queryKey: goalKeys.payoffImages(),\n queryFn: async () => {\n const response = await api.get('/payoff_goals');\n return GoalImagesResponseSchema.parse(response.data);\n },\n staleTime: 1000 * 60 * 60 * 24, // 24 hours (images rarely change)\n ...options,\n });\n}\n","import {\n useMutation,\n useQueryClient,\n type UseMutationOptions,\n} from '@tanstack/react-query';\nimport {\n GoalCreateSchema,\n PayoffGoalSchema,\n type GoalCreate,\n type PayoffGoal,\n} from '@pfm-platform/shared';\nimport { api } from '../client';\nimport { goalKeys } from '../keys';\n\n/**\n * Parameters for useCreatePayoffGoal mutation\n */\nexport interface CreatePayoffGoalParams {\n userId: string;\n data: GoalCreate;\n}\n\n/**\n * Mutation hook for creating a payoff goal\n *\n * @example\n * ```tsx\n * const createPayoffGoal = useCreatePayoffGoal();\n *\n * createPayoffGoal.mutate({\n * userId: 'user123',\n * data: {\n * name: 'Credit Card Debt',\n * image_name: 'credit_card',\n * target_value: '3000.00',\n * target_completion_on: '2026-06-30',\n * }\n * });\n * ```\n */\nexport function useCreatePayoffGoal(\n options?: Omit<\n UseMutationOptions<PayoffGoal, Error, CreatePayoffGoalParams>,\n 'mutationFn'\n >\n) {\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: async ({ userId, data }: CreatePayoffGoalParams) => {\n const validated = GoalCreateSchema.parse(data);\n\n // Request body wrapping: { payoff_goal: {...} }\n const response = await api.post(`/users/${userId}/payoff_goals`, {\n payoff_goal: validated,\n });\n\n return PayoffGoalSchema.parse(response.data);\n },\n onSuccess: (_, { userId }) => {\n // Invalidate all payoff goal lists\n queryClient.invalidateQueries({ queryKey: goalKeys.payoffLists() });\n },\n ...options,\n });\n}\n","import {\n useMutation,\n useQueryClient,\n type UseMutationOptions,\n} from '@tanstack/react-query';\nimport {\n GoalUpdateSchema,\n PayoffGoalSchema,\n type GoalUpdate,\n type PayoffGoal,\n} from '@pfm-platform/shared';\nimport { api } from '../client';\nimport { goalKeys } from '../keys';\n\n/**\n * Parameters for useUpdatePayoffGoal mutation\n */\nexport interface UpdatePayoffGoalParams {\n userId: string;\n goalId: number;\n data: GoalUpdate;\n}\n\n/**\n * Mutation hook for updating a payoff goal\n *\n * @example\n * ```tsx\n * const updatePayoffGoal = useUpdatePayoffGoal();\n *\n * updatePayoffGoal.mutate({\n * userId: 'user123',\n * goalId: 456,\n * data: {\n * id: 456,\n * name: 'Updated Credit Card',\n * image_name: 'credit_card',\n * target_value: '2500.00'\n * }\n * });\n * ```\n */\nexport function useUpdatePayoffGoal(\n options?: Omit<\n UseMutationOptions<PayoffGoal, Error, UpdatePayoffGoalParams>,\n 'mutationFn'\n >\n) {\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: async ({ userId, goalId, data }: UpdatePayoffGoalParams) => {\n const validated = GoalUpdateSchema.parse(data);\n\n // Request body wrapping: { payoff_goal: {...} } (without id)\n const { id, ...payload } = validated;\n const response = await api.put(`/users/${userId}/payoff_goals/${goalId}`, {\n payoff_goal: payload,\n });\n\n return PayoffGoalSchema.parse(response.data);\n },\n onSuccess: (_, { userId, goalId }) => {\n // Invalidate lists and specific detail\n queryClient.invalidateQueries({ queryKey: goalKeys.payoffLists() });\n queryClient.invalidateQueries({\n queryKey: goalKeys.payoffDetail(userId, goalId),\n });\n },\n ...options,\n });\n}\n","import {\n useMutation,\n useQueryClient,\n type UseMutationOptions,\n} from '@tanstack/react-query';\nimport { api } from '../client';\nimport { goalKeys } from '../keys';\n\n/**\n * Parameters for useArchivePayoffGoal mutation\n */\nexport interface ArchivePayoffGoalParams {\n userId: string;\n goalId: number;\n}\n\n/**\n * Mutation hook for archiving a payoff goal\n * Archived goals remain in system but marked as inactive\n *\n * @example\n * ```tsx\n * const archivePayoffGoal = useArchivePayoffGoal();\n *\n * archivePayoffGoal.mutate({\n * userId: 'user123',\n * goalId: 456\n * });\n * ```\n */\nexport function useArchivePayoffGoal(\n options?: Omit<\n UseMutationOptions<void, Error, ArchivePayoffGoalParams>,\n 'mutationFn'\n >\n) {\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: async ({ userId, goalId }: ArchivePayoffGoalParams) => {\n await api.put(`/users/${userId}/payoff_goals/${goalId}/archive`);\n // No response body expected\n },\n onSuccess: (_, { userId, goalId }) => {\n // Invalidate lists and specific detail\n queryClient.invalidateQueries({ queryKey: goalKeys.payoffLists() });\n queryClient.invalidateQueries({\n queryKey: goalKeys.payoffDetail(userId, goalId),\n });\n },\n ...options,\n });\n}\n","import {\n useMutation,\n useQueryClient,\n type UseMutationOptions,\n} from '@tanstack/react-query';\nimport { api } from '../client';\nimport { goalKeys } from '../keys';\n\n/**\n * Parameters for useDeletePayoffGoal mutation\n */\nexport interface DeletePayoffGoalParams {\n userId: string;\n goalId: number;\n}\n\n/**\n * Mutation hook for deleting a payoff goal permanently\n *\n * @example\n * ```tsx\n * const deletePayoffGoal = useDeletePayoffGoal();\n *\n * deletePayoffGoal.mutate({\n * userId: 'user123',\n * goalId: 456\n * });\n * ```\n */\nexport function useDeletePayoffGoal(\n options?: Omit<\n UseMutationOptions<void, Error, DeletePayoffGoalParams>,\n 'mutationFn'\n >\n) {\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: async ({ userId, goalId }: DeletePayoffGoalParams) => {\n await api.delete(`/users/${userId}/payoff_goals/${goalId}`);\n // No response body expected (204 No Content)\n },\n onSuccess: (_, { userId, goalId }) => {\n // Invalidate lists and remove specific detail from cache\n queryClient.invalidateQueries({ queryKey: goalKeys.payoffLists() });\n queryClient.removeQueries({\n queryKey: goalKeys.payoffDetail(userId, goalId),\n });\n },\n ...options,\n });\n}\n"]}