@pfm-platform/accounts-data-access 0.2.0 → 0.2.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.js CHANGED
@@ -1,107 +1,18 @@
1
1
  import { useQuery, useQueryClient, useMutation } from '@tanstack/react-query';
2
- import { AccountsResponseSchema, AccountSchema, NetWorthResponseSchema, useAppMode, AccountCreateSchemaAdmin, AccountCreateSchemaUser, AccountUpdateSchema, NetWorthAccountCreateSchema, NetWorthAssetSchema, NetWorthDebtSchema, NetWorthAccountUpdateSchema, NetWorthAccountDeleteSchema } from '@pfm-platform/shared';
3
- import axios from 'axios';
2
+ import { supabase, AccountsResponseSchema, AccountSchema, useAppMode, AccountCreateSchemaAdmin, AccountCreateSchemaUser, AccountUpdateSchema } from '@pfm-platform/shared';
4
3
 
5
4
  // src/queries/useAccounts.ts
6
5
 
7
6
  // src/keys.ts
8
7
  var accountKeys = {
9
- /**
10
- * Root key for all account-related queries
11
- */
12
8
  all: ["accounts"],
13
- /**
14
- * Key for all account list queries
15
- */
16
9
  lists: () => [...accountKeys.all, "list"],
17
- /**
18
- * Key for a specific user's account list
19
- * @param userId - User ID
20
- */
21
10
  list: (userId) => [...accountKeys.lists(), userId],
22
- /**
23
- * Key for all account detail queries
24
- */
25
11
  details: () => [...accountKeys.all, "detail"],
26
- /**
27
- * Key for a specific account detail
28
- * @param userId - User ID
29
- * @param accountId - Account ID
30
- */
31
12
  detail: (userId, accountId) => [...accountKeys.details(), userId, accountId],
32
- /**
33
- * Key for all account investment queries
34
- */
35
- investments: () => [...accountKeys.all, "investments"],
36
- /**
37
- * Key for a specific account's investments
38
- * @param userId - User ID
39
- * @param accountId - Account ID
40
- */
41
- investment: (userId, accountId) => [...accountKeys.investments(), userId, accountId],
42
- /**
43
- * Key for all account transaction queries
44
- */
45
- transactions: () => [...accountKeys.all, "transactions"],
46
- /**
47
- * Key for a specific account's transactions
48
- * @param userId - User ID
49
- * @param accountId - Account ID
50
- * @param page - Page number for pagination
51
- */
52
- transaction: (userId, accountId, page) => [...accountKeys.transactions(), userId, accountId, page],
53
- /**
54
- * Key for all net worth queries
55
- */
56
- networth: () => [...accountKeys.all, "networth"],
57
- /**
58
- * Key for a specific user's net worth summary
59
- * @param userId - User ID
60
- */
61
- networthSummary: (userId) => [...accountKeys.networth(), userId],
62
- /**
63
- * Key for all net worth account queries
64
- */
65
- networthAccounts: () => [...accountKeys.networth(), "accounts"],
66
- /**
67
- * Key for a specific net worth account
68
- * @param userId - User ID
69
- * @param accountId - Net worth account ID
70
- */
71
- networthAccount: (userId, accountId) => [...accountKeys.networthAccounts(), userId, accountId]
13
+ institutions: () => [...accountKeys.all, "institutions"],
14
+ institution: (userId) => [...accountKeys.institutions(), userId]
72
15
  };
73
- var api = axios.create({
74
- baseURL: "/api",
75
- headers: {
76
- "Content-Type": "application/json"
77
- },
78
- timeout: 1e4
79
- // 10 second timeout
80
- });
81
- api.interceptors.request.use(
82
- (config) => {
83
- const token = localStorage.getItem("auth_token");
84
- if (token) {
85
- config.headers.Authorization = `Bearer ${token}`;
86
- }
87
- return config;
88
- },
89
- (error) => {
90
- return Promise.reject(error);
91
- }
92
- );
93
- api.interceptors.response.use(
94
- (response) => response,
95
- (error) => {
96
- if (error.response?.status === 401) {
97
- localStorage.removeItem("auth_token");
98
- if (typeof window !== "undefined") {
99
- window.location.href = "/login";
100
- }
101
- }
102
- return Promise.reject(error);
103
- }
104
- );
105
16
 
106
17
  // src/queries/useAccounts.ts
107
18
  function useAccounts(params, options) {
@@ -109,11 +20,11 @@ function useAccounts(params, options) {
109
20
  return useQuery({
110
21
  queryKey: accountKeys.list(userId),
111
22
  queryFn: async () => {
112
- const response = await api.get(`/users/${userId}/accounts/all`);
113
- return AccountsResponseSchema.parse(response.data);
23
+ const { data, error } = await supabase.from("accounts").select("*").eq("user_id", userId).order("name");
24
+ if (error) throw error;
25
+ return { accounts: AccountsResponseSchema.parse(data) };
114
26
  },
115
27
  staleTime: 1e3 * 60 * 5,
116
- // 5 minutes - accounts don't change frequently
117
28
  ...options
118
29
  });
119
30
  }
@@ -122,24 +33,61 @@ function useAccount(params, options) {
122
33
  return useQuery({
123
34
  queryKey: accountKeys.detail(userId, accountId),
124
35
  queryFn: async () => {
125
- const response = await api.get(`/users/${userId}/accounts/${accountId}`);
126
- return AccountSchema.parse(response.data);
36
+ const { data, error } = await supabase.from("accounts").select("*").eq("id", accountId).eq("user_id", userId).single();
37
+ if (error) throw error;
38
+ return AccountSchema.parse(data);
127
39
  },
128
40
  staleTime: 1e3 * 60 * 5,
129
- // 5 minutes
130
41
  ...options
131
42
  });
132
43
  }
133
44
  function useNetWorth(params, options) {
134
45
  const { userId } = params;
135
46
  return useQuery({
136
- queryKey: accountKeys.networthSummary(userId),
47
+ queryKey: [...accountKeys.all, "networth", userId],
137
48
  queryFn: async () => {
138
- const response = await api.get(`/users/${userId}/networth`);
139
- return NetWorthResponseSchema.parse(response.data);
49
+ const { data: accounts, error: accountsError } = await supabase.from("networth_accounts").select("*").eq("user_id", userId);
50
+ if (accountsError) throw accountsError;
51
+ const { data: histories, error: historiesError } = await supabase.from("networth_history").select("*").eq("user_id", userId).order("year", { ascending: true }).order("month", { ascending: true });
52
+ if (historiesError) throw historiesError;
53
+ const assets = (accounts || []).filter((a) => a.account_type === "asset").map((a) => ({
54
+ id: a.id,
55
+ name: a.name,
56
+ balance: String(a.balance),
57
+ account_type: a.account_type,
58
+ additional_networth_account: a.additional_networth_account
59
+ }));
60
+ const debts = (accounts || []).filter((a) => a.account_type === "debt").map((a) => ({
61
+ id: a.id,
62
+ name: a.name,
63
+ balance: String(a.balance),
64
+ account_type: a.account_type,
65
+ additional_networth_account: a.additional_networth_account
66
+ }));
67
+ const totalAssets = assets.reduce((sum, a) => sum + parseFloat(a.balance), 0);
68
+ const totalDebts = debts.reduce((sum, d) => sum + parseFloat(d.balance), 0);
69
+ const networthHistories = (histories || []).map((h) => ({
70
+ total: String(h.total),
71
+ total_asset: String(h.total_asset),
72
+ total_debt: String(h.total_debt),
73
+ month: String(h.month).padStart(2, "0"),
74
+ year: String(h.year),
75
+ since_last_month: String(h.since_last_month)
76
+ }));
77
+ return {
78
+ meta: {
79
+ net_worth: String(totalAssets - totalDebts),
80
+ net_worth_change: "0",
81
+ // TODO: compute from networth_history
82
+ total_assets: String(totalAssets),
83
+ total_debts: String(totalDebts)
84
+ },
85
+ assets,
86
+ debts,
87
+ networth_histories: networthHistories
88
+ };
140
89
  },
141
90
  staleTime: 1e3 * 60 * 5,
142
- // 5 minutes - net worth doesn't change frequently
143
91
  ...options
144
92
  });
145
93
  }
@@ -147,27 +95,22 @@ function useCreateAccount(options) {
147
95
  const queryClient = useQueryClient();
148
96
  const { mode } = useAppMode();
149
97
  return useMutation({
150
- mutationFn: async ({ userId, data }) => {
98
+ mutationFn: async ({ data }) => {
151
99
  const schema = mode === "admin" ? AccountCreateSchemaAdmin : AccountCreateSchemaUser;
152
100
  const validated = schema.parse(data);
153
- const response = await api.post(
154
- `/users/${userId}/accounts`,
155
- validated
156
- );
157
- return AccountSchema.parse(response.data);
101
+ const { data: created, error } = await supabase.from("accounts").insert(validated).select().single();
102
+ if (error) throw error;
103
+ return AccountSchema.parse(created);
158
104
  },
159
- onSuccess: (newAccount, variables, context, mutation) => {
105
+ onSuccess: (newAccount, variables, onMutateResult, context) => {
160
106
  queryClient.setQueryData(
161
107
  accountKeys.list(variables.userId),
162
108
  (oldData) => {
163
- if (!oldData?.accounts) return oldData;
164
- return {
165
- ...oldData,
166
- accounts: [...oldData.accounts, newAccount]
167
- };
109
+ if (!oldData) return { accounts: [newAccount] };
110
+ return { accounts: [...oldData.accounts, newAccount] };
168
111
  }
169
112
  );
170
- options?.onSuccess?.(newAccount, variables, context, mutation);
113
+ options?.onSuccess?.(newAccount, variables, onMutateResult, context);
171
114
  },
172
115
  ...options
173
116
  });
@@ -175,13 +118,11 @@ function useCreateAccount(options) {
175
118
  function useUpdateAccount(options) {
176
119
  const queryClient = useQueryClient();
177
120
  return useMutation({
178
- mutationFn: async ({ userId, accountId, data }) => {
121
+ mutationFn: async ({ accountId, data }) => {
179
122
  const validated = AccountUpdateSchema.parse(data);
180
- const response = await api.put(
181
- `/users/${userId}/accounts/${accountId}`,
182
- validated
183
- );
184
- return AccountSchema.parse(response.data);
123
+ const { data: updated, error } = await supabase.from("accounts").update(validated).eq("id", accountId).select().single();
124
+ if (error) throw error;
125
+ return AccountSchema.parse(updated);
185
126
  },
186
127
  onSuccess: (_, { userId, accountId }) => {
187
128
  queryClient.invalidateQueries({
@@ -197,8 +138,9 @@ function useUpdateAccount(options) {
197
138
  function useDeleteAccount(options) {
198
139
  const queryClient = useQueryClient();
199
140
  return useMutation({
200
- mutationFn: async ({ userId, accountId }) => {
201
- await api.delete(`/users/${userId}/accounts/${accountId}`);
141
+ mutationFn: async ({ accountId }) => {
142
+ const { error } = await supabase.from("accounts").delete().eq("id", accountId);
143
+ if (error) throw error;
202
144
  },
203
145
  onSuccess: (_, { userId, accountId }) => {
204
146
  queryClient.invalidateQueries({
@@ -214,11 +156,10 @@ function useDeleteAccount(options) {
214
156
  function useArchiveAccount(options) {
215
157
  const queryClient = useQueryClient();
216
158
  return useMutation({
217
- mutationFn: async ({ userId, accountId }) => {
218
- const response = await api.put(
219
- `/users/${userId}/accounts/${accountId}/archive`
220
- );
221
- return AccountSchema.parse(response.data);
159
+ mutationFn: async ({ accountId }) => {
160
+ const { data, error } = await supabase.from("accounts").update({ is_active: false }).eq("id", accountId).select().single();
161
+ if (error) throw error;
162
+ return AccountSchema.parse(data);
222
163
  },
223
164
  onSuccess: (_, { userId, accountId }) => {
224
165
  queryClient.invalidateQueries({
@@ -235,21 +176,18 @@ function useCreateNetWorthAccount(options) {
235
176
  const queryClient = useQueryClient();
236
177
  return useMutation({
237
178
  mutationFn: async ({ userId, data }) => {
238
- const validated = NetWorthAccountCreateSchema.parse(data);
239
- const response = await api.post(
240
- `/users/${userId}/networth/accounts`,
241
- validated
242
- );
243
- const accountType = validated.networth_account.account_type;
244
- if (accountType === "asset") {
245
- return NetWorthAssetSchema.parse(response.data);
246
- } else {
247
- return NetWorthDebtSchema.parse(response.data);
248
- }
179
+ const { error } = await supabase.from("networth_accounts").insert({
180
+ user_id: userId,
181
+ name: data.networth_account.name,
182
+ balance: parseFloat(data.networth_account.balance),
183
+ account_type: data.networth_account.account_type,
184
+ additional_networth_account: true
185
+ });
186
+ if (error) throw error;
249
187
  },
250
188
  onSuccess: (_, { userId }) => {
251
189
  queryClient.invalidateQueries({
252
- queryKey: accountKeys.networthSummary(userId)
190
+ queryKey: [...accountKeys.all, "networth", userId]
253
191
  });
254
192
  },
255
193
  ...options
@@ -258,21 +196,17 @@ function useCreateNetWorthAccount(options) {
258
196
  function useUpdateNetWorthAccount(options) {
259
197
  const queryClient = useQueryClient();
260
198
  return useMutation({
261
- mutationFn: async ({ userId, accountId, data }) => {
262
- const validated = NetWorthAccountUpdateSchema.parse(data);
263
- const response = await api.put(
264
- `/users/${userId}/networth/accounts/${accountId}`,
265
- validated
266
- );
267
- try {
268
- return NetWorthAssetSchema.parse(response.data);
269
- } catch {
270
- return NetWorthDebtSchema.parse(response.data);
271
- }
199
+ mutationFn: async ({ accountId, data }) => {
200
+ const { error } = await supabase.from("networth_accounts").update({
201
+ name: data.networth_account.name,
202
+ balance: parseFloat(data.networth_account.balance),
203
+ account_type: data.networth_account.account_type
204
+ }).eq("id", String(accountId));
205
+ if (error) throw error;
272
206
  },
273
207
  onSuccess: (_, { userId }) => {
274
208
  queryClient.invalidateQueries({
275
- queryKey: accountKeys.networthSummary(userId)
209
+ queryKey: [...accountKeys.all, "networth", userId]
276
210
  });
277
211
  },
278
212
  ...options
@@ -281,19 +215,19 @@ function useUpdateNetWorthAccount(options) {
281
215
  function useDeleteNetWorthAccount(options) {
282
216
  const queryClient = useQueryClient();
283
217
  return useMutation({
284
- mutationFn: async ({ userId, accountId }) => {
285
- NetWorthAccountDeleteSchema.parse({ id: accountId });
286
- await api.delete(`/users/${userId}/networth/accounts/${accountId}`);
218
+ mutationFn: async ({ accountId }) => {
219
+ const { error } = await supabase.from("networth_accounts").delete().eq("id", String(accountId));
220
+ if (error) throw error;
287
221
  },
288
222
  onSuccess: (_, { userId }) => {
289
223
  queryClient.invalidateQueries({
290
- queryKey: accountKeys.networthSummary(userId)
224
+ queryKey: [...accountKeys.all, "networth", userId]
291
225
  });
292
226
  },
293
227
  ...options
294
228
  });
295
229
  }
296
230
 
297
- export { accountKeys, api, useAccount, useAccounts, useArchiveAccount, useCreateAccount, useCreateNetWorthAccount, useDeleteAccount, useDeleteNetWorthAccount, useNetWorth, useUpdateAccount, useUpdateNetWorthAccount };
231
+ export { accountKeys, useAccount, useAccounts, useArchiveAccount, useCreateAccount, useCreateNetWorthAccount, useDeleteAccount, useDeleteNetWorthAccount, useNetWorth, useUpdateAccount, useUpdateNetWorthAccount };
298
232
  //# sourceMappingURL=index.js.map
299
233
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/keys.ts","../src/client.ts","../src/queries/useAccounts.ts","../src/queries/useAccount.ts","../src/queries/useNetWorth.ts","../src/mutations/useCreateAccount.ts","../src/mutations/useUpdateAccount.ts","../src/mutations/useDeleteAccount.ts","../src/mutations/useArchiveAccount.ts","../src/mutations/useCreateNetWorthAccount.ts","../src/mutations/useUpdateNetWorthAccount.ts","../src/mutations/useDeleteNetWorthAccount.ts"],"names":["useQuery","AccountSchema","useQueryClient","useMutation","NetWorthAssetSchema","NetWorthDebtSchema"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Query key factory for Accounts domain\n * Following TanStack Query best practices for hierarchical cache keys\n *\n * Key structure:\n * - ['accounts'] - Root key for all account queries\n * - ['accounts', 'list', userId] - List of accounts for a user\n * - ['accounts', 'detail', userId, accountId] - Single account detail\n * - ['accounts', 'investments', userId, accountId] - Account investments\n * - ['accounts', 'transactions', userId, accountId, page] - Account transactions\n */\n\nexport const accountKeys = {\n /**\n * Root key for all account-related queries\n */\n all: ['accounts'] as const,\n\n /**\n * Key for all account list queries\n */\n lists: () => [...accountKeys.all, 'list'] as const,\n\n /**\n * Key for a specific user's account list\n * @param userId - User ID\n */\n list: (userId: string) => [...accountKeys.lists(), userId] as const,\n\n /**\n * Key for all account detail queries\n */\n details: () => [...accountKeys.all, 'detail'] as const,\n\n /**\n * Key for a specific account detail\n * @param userId - User ID\n * @param accountId - Account ID\n */\n detail: (userId: string, accountId: number) =>\n [...accountKeys.details(), userId, accountId] as const,\n\n /**\n * Key for all account investment queries\n */\n investments: () => [...accountKeys.all, 'investments'] as const,\n\n /**\n * Key for a specific account's investments\n * @param userId - User ID\n * @param accountId - Account ID\n */\n investment: (userId: string, accountId: number) =>\n [...accountKeys.investments(), userId, accountId] as const,\n\n /**\n * Key for all account transaction queries\n */\n transactions: () => [...accountKeys.all, 'transactions'] as const,\n\n /**\n * Key for a specific account's transactions\n * @param userId - User ID\n * @param accountId - Account ID\n * @param page - Page number for pagination\n */\n transaction: (userId: string, accountId: number, page: number) =>\n [...accountKeys.transactions(), userId, accountId, page] as const,\n\n /**\n * Key for all net worth queries\n */\n networth: () => [...accountKeys.all, 'networth'] as const,\n\n /**\n * Key for a specific user's net worth summary\n * @param userId - User ID\n */\n networthSummary: (userId: string) =>\n [...accountKeys.networth(), userId] as const,\n\n /**\n * Key for all net worth account queries\n */\n networthAccounts: () => [...accountKeys.networth(), 'accounts'] as const,\n\n /**\n * Key for a specific net worth account\n * @param userId - User ID\n * @param accountId - Net worth account ID\n */\n networthAccount: (userId: string, accountId: number) =>\n [...accountKeys.networthAccounts(), userId, accountId] as const,\n};\n","/**\n * Base API client for Accounts domain\n * Uses axios with interceptors for auth and error handling\n */\n\nimport axios from 'axios';\n\n/**\n * Axios instance configured for PFM API\n * Base URL can be overridden via VITE_API_BASE_URL environment variable\n */\nexport const api = axios.create({\n baseURL: '/api',\n headers: {\n 'Content-Type': 'application/json',\n },\n timeout: 10000, // 10 second timeout\n});\n\n/**\n * Request interceptor to add authentication token\n * Reads token from localStorage and adds to Authorization header\n */\napi.interceptors.request.use(\n (config) => {\n const token = localStorage.getItem('auth_token');\n if (token) {\n config.headers.Authorization = `Bearer ${token}`;\n }\n return config;\n },\n (error) => {\n return Promise.reject(error);\n }\n);\n\n/**\n * Response interceptor for global error handling\n * - 401: Redirect to login\n * - 403: Access forbidden\n * - 5xx: Server errors\n */\napi.interceptors.response.use(\n (response) => response,\n (error) => {\n if (error.response?.status === 401) {\n // Unauthorized - clear token and redirect to login\n localStorage.removeItem('auth_token');\n if (typeof window !== 'undefined') {\n window.location.href = '/login';\n }\n }\n return Promise.reject(error);\n }\n);\n","/**\n * Query hook for fetching all accounts for a user\n * Legacy API: GET /users/{userId}/accounts/all\n */\n\nimport { useQuery, UseQueryOptions } from '@tanstack/react-query';\nimport { AccountsResponseSchema, AccountsResponse } from '@pfm-platform/shared';\nimport { accountKeys } from '../keys';\nimport { api } from '../client';\n\nexport interface UseAccountsParams {\n userId: string;\n}\n\n/**\n * Fetch all accounts for a user\n * Uses Zod validation to ensure API response matches expected schema\n *\n * @param params - Query parameters\n * @param options - TanStack Query options\n * @returns Query result with validated accounts data\n *\n * @example\n * ```tsx\n * function AccountsList() {\n * const { data, isLoading, error } = useAccounts({ userId: 'user123' });\n *\n * if (isLoading) return <div>Loading...</div>;\n * if (error) return <div>Error: {error.message}</div>;\n *\n * return (\n * <ul>\n * {data.accounts.map(account => (\n * <li key={account.id}>{account.name}</li>\n * ))}\n * </ul>\n * );\n * }\n * ```\n */\nexport function useAccounts(\n params: UseAccountsParams,\n options?: Omit<\n UseQueryOptions<AccountsResponse>,\n 'queryKey' | 'queryFn'\n >\n) {\n const { userId } = params;\n\n return useQuery({\n queryKey: accountKeys.list(userId),\n queryFn: async () => {\n const response = await api.get(`/users/${userId}/accounts/all`);\n\n // Validate response with Zod schema from Mini-Arc 1\n // This ensures type safety and catches API contract changes\n return AccountsResponseSchema.parse(response.data);\n },\n staleTime: 1000 * 60 * 5, // 5 minutes - accounts don't change frequently\n ...options,\n });\n}\n","/**\n * Query hook for fetching a single account by ID\n * Legacy API: GET /users/{userId}/accounts/{id}\n */\n\nimport { useQuery, UseQueryOptions } from '@tanstack/react-query';\nimport { AccountSchema, Account } from '@pfm-platform/shared';\nimport { accountKeys } from '../keys';\nimport { api } from '../client';\n\nexport interface UseAccountParams {\n userId: string;\n accountId: number;\n}\n\n/**\n * Fetch a single account by ID\n * Uses Zod validation to ensure API response matches expected schema\n *\n * @param params - Query parameters\n * @param options - TanStack Query options\n * @returns Query result with validated account data\n *\n * @example\n * ```tsx\n * function AccountDetail({ accountId }: { accountId: number }) {\n * const { data, isLoading, error } = useAccount({\n * userId: 'user123',\n * accountId\n * });\n *\n * if (isLoading) return <div>Loading...</div>;\n * if (error) return <div>Error: {error.message}</div>;\n *\n * return (\n * <div>\n * <h2>{data.name}</h2>\n * <p>Balance: ${data.balance}</p>\n * <p>Type: {data.account_type}</p>\n * </div>\n * );\n * }\n * ```\n */\nexport function useAccount(\n params: UseAccountParams,\n options?: Omit<UseQueryOptions<Account>, 'queryKey' | 'queryFn'>\n) {\n const { userId, accountId } = params;\n\n return useQuery({\n queryKey: accountKeys.detail(userId, accountId),\n queryFn: async () => {\n const response = await api.get(`/users/${userId}/accounts/${accountId}`);\n\n // Validate response with Zod schema from Mini-Arc 1\n return AccountSchema.parse(response.data);\n },\n staleTime: 1000 * 60 * 5, // 5 minutes\n ...options,\n });\n}\n","/**\n * Query hook for fetching net worth summary for a user\n * Legacy API: GET /users/{userId}/networth\n */\n\nimport { useQuery, UseQueryOptions } from '@tanstack/react-query';\nimport { NetWorthResponseSchema, NetWorth } from '@pfm-platform/shared';\nimport { accountKeys } from '../keys';\nimport { api } from '../client';\n\nexport interface UseNetWorthParams {\n userId: string;\n}\n\n/**\n * Fetch net worth summary for a user\n * Includes: assets, debts, history, and summary metadata\n * Uses Zod validation to ensure API response matches expected schema\n *\n * @param params - Query parameters\n * @param options - TanStack Query options\n * @returns Query result with validated net worth data\n *\n * @example\n * ```tsx\n * function NetWorthSummary() {\n * const { data, isLoading, error } = useNetWorth({ userId: 'user123' });\n *\n * if (isLoading) return <div>Loading...</div>;\n * if (error) return <div>Error: {error.message}</div>;\n *\n * return (\n * <div>\n * <h2>Net Worth: {data.meta.net_worth}</h2>\n * <p>Total Assets: {data.meta.total_assets}</p>\n * <p>Total Debts: {data.meta.total_debts}</p>\n * </div>\n * );\n * }\n * ```\n */\nexport function useNetWorth(\n params: UseNetWorthParams,\n options?: Omit<\n UseQueryOptions<NetWorth>,\n 'queryKey' | 'queryFn'\n >\n) {\n const { userId } = params;\n\n return useQuery({\n queryKey: accountKeys.networthSummary(userId),\n queryFn: async () => {\n const response = await api.get(`/users/${userId}/networth`);\n\n // Validate response with Zod schema\n // This ensures type safety and catches API contract changes\n return NetWorthResponseSchema.parse(response.data);\n },\n staleTime: 1000 * 60 * 5, // 5 minutes - net worth doesn't change frequently\n ...options,\n });\n}\n","import {\n useMutation,\n useQueryClient,\n type UseMutationOptions,\n} from '@tanstack/react-query';\nimport {\n AccountCreateSchemaAdmin,\n AccountCreateSchemaUser,\n AccountSchema,\n useAppMode,\n type AccountCreate,\n type Account,\n} from '@pfm-platform/shared';\nimport { api } from '../client';\nimport { accountKeys } from '../keys';\n\n/**\n * Parameters for useCreateAccount mutation\n */\nexport interface CreateAccountParams {\n userId: string;\n data: AccountCreate;\n}\n\n/**\n * Mutation hook for creating a new account\n *\n * Creates an account manually for testing purposes.\n * Uses mode switching for validation:\n * - Admin mode: Minimal validation for test data creation\n * - User mode: Full validation with business rules\n *\n * @example\n * ```tsx\n * const createAccount = useCreateAccount();\n *\n * createAccount.mutate({\n * userId: 'user123',\n * data: {\n * name: 'Test Checking',\n * balance: '1000.00',\n * account_type: 'checking',\n * state: 'active',\n * aggregation_type: 'partner',\n * include_in_expenses: true,\n * include_in_budget: true,\n * include_in_cashflow: true,\n * include_in_dashboard: true,\n * include_in_goals: false,\n * include_in_networth: true\n * }\n * });\n * ```\n */\nexport function useCreateAccount(\n options?: Omit<UseMutationOptions<Account, Error, CreateAccountParams>, 'mutationFn'>\n) {\n const queryClient = useQueryClient();\n const { mode } = useAppMode();\n\n return useMutation({\n mutationFn: async ({ userId, data }: CreateAccountParams) => {\n // Select schema based on mode\n const schema =\n mode === 'admin'\n ? AccountCreateSchemaAdmin\n : AccountCreateSchemaUser;\n\n // Validate account data\n const validated = schema.parse(data);\n\n // POST to create new account\n const response = await api.post(\n `/users/${userId}/accounts`,\n validated\n );\n\n // Return created account\n return AccountSchema.parse(response.data);\n },\n onSuccess: (newAccount, variables, context, mutation) => {\n // Update the cache directly with the new account\n queryClient.setQueryData(\n accountKeys.list(variables.userId),\n (oldData: any) => {\n if (!oldData?.accounts) return oldData;\n return {\n ...oldData,\n accounts: [...oldData.accounts, newAccount],\n };\n }\n );\n\n // Call user-provided onSuccess callback if provided\n options?.onSuccess?.(newAccount, variables, context, mutation);\n },\n ...options,\n });\n}\n","/**\n * Mutation hook for updating an account\n * Legacy API: PUT /users/{userId}/accounts/{id}\n */\n\nimport {\n useMutation,\n UseMutationOptions,\n useQueryClient,\n} from '@tanstack/react-query';\nimport {\n AccountUpdateSchema,\n AccountSchema,\n Account,\n AccountUpdate,\n} from '@pfm-platform/shared';\nimport { accountKeys } from '../keys';\nimport { api } from '../client';\n\nexport interface UpdateAccountParams {\n userId: string;\n accountId: number;\n data: AccountUpdate;\n}\n\n/**\n * Update an existing account\n * Validates input with Zod schema and invalidates related queries on success\n *\n * @param options - TanStack Mutation options\n * @returns Mutation result\n *\n * @example\n * ```tsx\n * function AccountEditForm({ account }: { account: Account }) {\n * const updateAccount = useUpdateAccount();\n *\n * const handleSubmit = (formData) => {\n * updateAccount.mutate({\n * userId: 'user123',\n * accountId: account.id,\n * data: {\n * nickname: formData.nickname,\n * goal_amount: formData.goalAmount,\n * }\n * }, {\n * onSuccess: () => {\n * toast.success('Account updated!');\n * },\n * onError: (error) => {\n * toast.error(`Failed to update: ${error.message}`);\n * }\n * });\n * };\n *\n * return <form onSubmit={handleSubmit}>...</form>;\n * }\n * ```\n */\nexport function useUpdateAccount(\n options?: Omit<\n UseMutationOptions<Account, Error, UpdateAccountParams>,\n 'mutationFn'\n >\n) {\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: async ({ userId, accountId, data }: UpdateAccountParams) => {\n // Validate input with Zod schema from Mini-Arc 1\n // This ensures type safety before sending to API\n const validated = AccountUpdateSchema.parse(data);\n\n const response = await api.put(\n `/users/${userId}/accounts/${accountId}`,\n validated\n );\n\n // Validate response\n return AccountSchema.parse(response.data);\n },\n onSuccess: (_, { userId, accountId }) => {\n // Invalidate account list query to refetch updated data\n queryClient.invalidateQueries({\n queryKey: accountKeys.list(userId),\n });\n\n // Invalidate specific account detail query\n queryClient.invalidateQueries({\n queryKey: accountKeys.detail(userId, accountId),\n });\n },\n ...options,\n });\n}\n","/**\n * Mutation hook for deleting an account\n * Legacy API: DELETE /users/{userId}/accounts/{id}\n */\n\nimport {\n useMutation,\n UseMutationOptions,\n useQueryClient,\n} from '@tanstack/react-query';\nimport { accountKeys } from '../keys';\nimport { api } from '../client';\n\nexport interface DeleteAccountParams {\n userId: string;\n accountId: number;\n}\n\n/**\n * Delete an account\n * Removes account from user's account list\n * Invalidates related queries on success\n *\n * @param options - TanStack Mutation options\n * @returns Mutation result\n *\n * @example\n * ```tsx\n * function AccountDeleteButton({ accountId }: { accountId: number }) {\n * const deleteAccount = useDeleteAccount();\n *\n * const handleDelete = () => {\n * if (confirm('Are you sure you want to delete this account?')) {\n * deleteAccount.mutate({\n * userId: 'user123',\n * accountId\n * }, {\n * onSuccess: () => {\n * toast.success('Account deleted successfully');\n * navigate('/accounts');\n * },\n * onError: (error) => {\n * toast.error(`Failed to delete: ${error.message}`);\n * }\n * });\n * }\n * };\n *\n * return (\n * <button onClick={handleDelete} disabled={deleteAccount.isPending}>\n * {deleteAccount.isPending ? 'Deleting...' : 'Delete Account'}\n * </button>\n * );\n * }\n * ```\n */\nexport function useDeleteAccount(\n options?: Omit<\n UseMutationOptions<void, Error, DeleteAccountParams>,\n 'mutationFn'\n >\n) {\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: async ({ userId, accountId }: DeleteAccountParams) => {\n await api.delete(`/users/${userId}/accounts/${accountId}`);\n // DELETE returns 204 No Content - no response body to validate\n },\n onSuccess: (_, { userId, accountId }) => {\n // Invalidate account list to refetch without deleted account\n queryClient.invalidateQueries({\n queryKey: accountKeys.list(userId),\n });\n\n // Remove specific account from cache\n queryClient.removeQueries({\n queryKey: accountKeys.detail(userId, accountId),\n });\n },\n ...options,\n });\n}\n","/**\n * Mutation hook for archiving an account (soft delete)\n * Legacy API: PUT /users/{userId}/accounts/{id}/archive\n */\n\nimport {\n useMutation,\n UseMutationOptions,\n useQueryClient,\n} from '@tanstack/react-query';\nimport { AccountSchema, Account } from '@pfm-platform/shared';\nimport { accountKeys } from '../keys';\nimport { api } from '../client';\n\nexport interface ArchiveAccountParams {\n userId: string;\n accountId: number;\n}\n\n/**\n * Archive an account (soft delete)\n * Changes account state to 'archived' instead of permanently deleting\n * Invalidates related queries on success\n *\n * @param options - TanStack Mutation options\n * @returns Mutation result\n *\n * @example\n * ```tsx\n * function AccountArchiveButton({ accountId }: { accountId: number }) {\n * const archiveAccount = useArchiveAccount();\n *\n * const handleArchive = () => {\n * archiveAccount.mutate({\n * userId: 'user123',\n * accountId\n * }, {\n * onSuccess: (archivedAccount) => {\n * toast.success(`${archivedAccount.name} archived`);\n * },\n * onError: (error) => {\n * toast.error(`Failed to archive: ${error.message}`);\n * }\n * });\n * };\n *\n * return (\n * <button onClick={handleArchive} disabled={archiveAccount.isPending}>\n * {archiveAccount.isPending ? 'Archiving...' : 'Archive Account'}\n * </button>\n * );\n * }\n * ```\n */\nexport function useArchiveAccount(\n options?: Omit<\n UseMutationOptions<Account, Error, ArchiveAccountParams>,\n 'mutationFn'\n >\n) {\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: async ({ userId, accountId }: ArchiveAccountParams) => {\n const response = await api.put(\n `/users/${userId}/accounts/${accountId}/archive`\n );\n\n // Validate response - returns updated account with state='archived'\n return AccountSchema.parse(response.data);\n },\n onSuccess: (_, { userId, accountId }) => {\n // Invalidate account list to refetch with updated states\n queryClient.invalidateQueries({\n queryKey: accountKeys.list(userId),\n });\n\n // Invalidate specific account detail\n queryClient.invalidateQueries({\n queryKey: accountKeys.detail(userId, accountId),\n });\n },\n ...options,\n });\n}\n","/**\n * Mutation hook for creating a manual net worth account\n * Legacy API: POST /users/{userId}/networth/accounts\n */\n\nimport {\n useMutation,\n useQueryClient,\n type UseMutationOptions,\n} from '@tanstack/react-query';\nimport {\n NetWorthAccountCreateSchema,\n NetWorthAssetSchema,\n NetWorthDebtSchema,\n type NetWorthAccountCreate,\n type NetWorthAsset,\n type NetWorthDebt,\n} from '@pfm-platform/shared';\nimport { api } from '../client';\nimport { accountKeys } from '../keys';\n\n/**\n * Parameters for useCreateNetWorthAccount mutation\n */\nexport interface CreateNetWorthAccountParams {\n userId: string;\n data: NetWorthAccountCreate;\n}\n\n/**\n * Mutation hook for creating a manual net worth account\n *\n * Creates a manual asset or debt account for net worth tracking.\n * Returns either an asset or debt object depending on account_type.\n *\n * @example\n * ```tsx\n * const createAccount = useCreateNetWorthAccount();\n *\n * // Create asset\n * createAccount.mutate({\n * userId: 'user123',\n * data: {\n * networth_account: {\n * account_type: 'asset',\n * balance: '250000.00',\n * name: 'My House'\n * }\n * }\n * });\n *\n * // Create debt\n * createAccount.mutate({\n * userId: 'user123',\n * data: {\n * networth_account: {\n * account_type: 'debt',\n * balance: '15000.00',\n * name: 'Car Loan'\n * }\n * }\n * });\n * ```\n */\nexport function useCreateNetWorthAccount(\n options?: Omit<\n UseMutationOptions<NetWorthAsset | NetWorthDebt, Error, CreateNetWorthAccountParams>,\n 'mutationFn'\n >\n) {\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: async ({ userId, data }: CreateNetWorthAccountParams) => {\n // Validate account data\n const validated = NetWorthAccountCreateSchema.parse(data);\n\n // POST to create new net worth account\n const response = await api.post(\n `/users/${userId}/networth/accounts`,\n validated\n );\n\n // Validate response based on account type\n const accountType = validated.networth_account.account_type;\n if (accountType === 'asset') {\n return NetWorthAssetSchema.parse(response.data);\n } else {\n return NetWorthDebtSchema.parse(response.data);\n }\n },\n onSuccess: (_, { userId }) => {\n // Invalidate net worth summary to refetch with new account\n queryClient.invalidateQueries({\n queryKey: accountKeys.networthSummary(userId),\n });\n },\n ...options,\n });\n}\n","/**\n * Mutation hook for updating a manual net worth account\n * Legacy API: PUT /users/{userId}/networth/accounts/{id}\n */\n\nimport {\n useMutation,\n useQueryClient,\n type UseMutationOptions,\n} from '@tanstack/react-query';\nimport {\n NetWorthAccountUpdateSchema,\n NetWorthAssetSchema,\n NetWorthDebtSchema,\n type NetWorthAccountUpdate,\n type NetWorthAsset,\n type NetWorthDebt,\n} from '@pfm-platform/shared';\nimport { api } from '../client';\nimport { accountKeys } from '../keys';\n\n/**\n * Parameters for useUpdateNetWorthAccount mutation\n */\nexport interface UpdateNetWorthAccountParams {\n userId: string;\n accountId: number;\n data: NetWorthAccountUpdate;\n}\n\n/**\n * Mutation hook for updating a manual net worth account\n *\n * Updates name, balance, or account type for a manual net worth account.\n * All fields are optional - only provided fields will be updated.\n *\n * @example\n * ```tsx\n * const updateAccount = useUpdateNetWorthAccount();\n *\n * // Update only balance\n * updateAccount.mutate({\n * userId: 'user123',\n * accountId: 5,\n * data: {\n * networth_account: {\n * balance: '260000.00'\n * }\n * }\n * });\n *\n * // Update name and type\n * updateAccount.mutate({\n * userId: 'user123',\n * accountId: 5,\n * data: {\n * networth_account: {\n * name: 'Updated House Name',\n * account_type: 'debt'\n * }\n * }\n * });\n * ```\n */\nexport function useUpdateNetWorthAccount(\n options?: Omit<\n UseMutationOptions<NetWorthAsset | NetWorthDebt, Error, UpdateNetWorthAccountParams>,\n 'mutationFn'\n >\n) {\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: async ({ userId, accountId, data }: UpdateNetWorthAccountParams) => {\n // Validate update data\n const validated = NetWorthAccountUpdateSchema.parse(data);\n\n // PUT to update net worth account\n const response = await api.put(\n `/users/${userId}/networth/accounts/${accountId}`,\n validated\n );\n\n // Validate response - could be asset or debt\n // Try asset first, fall back to debt\n try {\n return NetWorthAssetSchema.parse(response.data);\n } catch {\n return NetWorthDebtSchema.parse(response.data);\n }\n },\n onSuccess: (_, { userId }) => {\n // Invalidate net worth summary to refetch with updated account\n queryClient.invalidateQueries({\n queryKey: accountKeys.networthSummary(userId),\n });\n },\n ...options,\n });\n}\n","/**\n * Mutation hook for deleting a manual net worth account\n * Legacy API: DELETE /users/{userId}/networth/accounts/{id}\n */\n\nimport {\n useMutation,\n useQueryClient,\n type UseMutationOptions,\n} from '@tanstack/react-query';\nimport { NetWorthAccountDeleteSchema } from '@pfm-platform/shared';\nimport { api } from '../client';\nimport { accountKeys } from '../keys';\n\n/**\n * Parameters for useDeleteNetWorthAccount mutation\n */\nexport interface DeleteNetWorthAccountParams {\n userId: string;\n accountId: number;\n}\n\n/**\n * Mutation hook for deleting a manual net worth account\n *\n * Permanently deletes a manual asset or debt account from net worth tracking.\n * This operation cannot be undone.\n *\n * @example\n * ```tsx\n * const deleteAccount = useDeleteNetWorthAccount();\n *\n * deleteAccount.mutate({\n * userId: 'user123',\n * accountId: 5\n * }, {\n * onSuccess: () => {\n * console.log('Net worth account deleted successfully');\n * }\n * });\n * ```\n */\nexport function useDeleteNetWorthAccount(\n options?: Omit<\n UseMutationOptions<void, Error, DeleteNetWorthAccountParams>,\n 'mutationFn'\n >\n) {\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: async ({ userId, accountId }: DeleteNetWorthAccountParams) => {\n // Validate account ID\n NetWorthAccountDeleteSchema.parse({ id: accountId });\n\n // DELETE net worth account\n await api.delete(`/users/${userId}/networth/accounts/${accountId}`);\n },\n onSuccess: (_, { userId }) => {\n // Invalidate net worth summary to refetch without deleted account\n queryClient.invalidateQueries({\n queryKey: accountKeys.networthSummary(userId),\n });\n },\n ...options,\n });\n}\n"]}
1
+ {"version":3,"sources":["../src/keys.ts","../src/queries/useAccounts.ts","../src/queries/useAccount.ts","../src/queries/useNetWorth.ts","../src/mutations/useCreateAccount.ts","../src/mutations/useUpdateAccount.ts","../src/mutations/useDeleteAccount.ts","../src/mutations/useArchiveAccount.ts","../src/mutations/useCreateNetWorthAccount.ts","../src/mutations/useUpdateNetWorthAccount.ts","../src/mutations/useDeleteNetWorthAccount.ts"],"names":["useQuery","AccountSchema","useQueryClient","useMutation"],"mappings":";;;;;;AAUO,IAAM,WAAA,GAAc;AAAA,EACzB,GAAA,EAAK,CAAC,UAAU,CAAA;AAAA,EAEhB,OAAO,MAAM,CAAC,GAAG,WAAA,CAAY,KAAK,MAAM,CAAA;AAAA,EAExC,IAAA,EAAM,CAAC,MAAA,KAAmB,CAAC,GAAG,WAAA,CAAY,KAAA,IAAS,MAAM,CAAA;AAAA,EAEzD,SAAS,MAAM,CAAC,GAAG,WAAA,CAAY,KAAK,QAAQ,CAAA;AAAA,EAE5C,MAAA,EAAQ,CAAC,MAAA,EAAgB,SAAA,KACvB,CAAC,GAAG,WAAA,CAAY,OAAA,EAAQ,EAAG,MAAA,EAAQ,SAAS,CAAA;AAAA,EAE9C,cAAc,MAAM,CAAC,GAAG,WAAA,CAAY,KAAK,cAAc,CAAA;AAAA,EAEvD,WAAA,EAAa,CAAC,MAAA,KACZ,CAAC,GAAG,WAAA,CAAY,YAAA,IAAgB,MAAM;AAC1C;;;ACIO,SAAS,WAAA,CACd,QACA,OAAA,EACA;AACA,EAAA,MAAM,EAAE,QAAO,GAAI,MAAA;AAEnB,EAAA,OAAO,QAAA,CAAS;AAAA,IACd,QAAA,EAAU,WAAA,CAAY,IAAA,CAAK,MAAM,CAAA;AAAA,IACjC,SAAS,YAAmC;AAC1C,MAAA,MAAM,EAAE,IAAA,EAAM,KAAA,EAAM,GAAI,MAAM,SAC3B,IAAA,CAAK,UAAU,CAAA,CACf,MAAA,CAAO,GAAG,CAAA,CACV,EAAA,CAAG,WAAW,MAAM,CAAA,CACpB,MAAM,MAAM,CAAA;AAEf,MAAA,IAAI,OAAO,MAAM,KAAA;AAEjB,MAAA,OAAO,EAAE,QAAA,EAAU,sBAAA,CAAuB,KAAA,CAAM,IAAI,CAAA,EAAE;AAAA,IACxD,CAAA;AAAA,IACA,SAAA,EAAW,MAAO,EAAA,GAAK,CAAA;AAAA,IACvB,GAAG;AAAA,GACJ,CAAA;AACH;AC5BO,SAAS,UAAA,CACd,QACA,OAAA,EACA;AACA,EAAA,MAAM,EAAE,MAAA,EAAQ,SAAA,EAAU,GAAI,MAAA;AAE9B,EAAA,OAAOA,QAAAA,CAAS;AAAA,IACd,QAAA,EAAU,WAAA,CAAY,MAAA,CAAO,MAAA,EAAQ,SAAS,CAAA;AAAA,IAC9C,SAAS,YAAY;AACnB,MAAA,MAAM,EAAE,MAAM,KAAA,EAAM,GAAI,MAAM,QAAA,CAC3B,IAAA,CAAK,UAAU,CAAA,CACf,MAAA,CAAO,GAAG,CAAA,CACV,EAAA,CAAG,MAAM,SAAS,CAAA,CAClB,GAAG,SAAA,EAAW,MAAM,EACpB,MAAA,EAAO;AAEV,MAAA,IAAI,OAAO,MAAM,KAAA;AAEjB,MAAA,OAAO,aAAA,CAAc,MAAM,IAAI,CAAA;AAAA,IACjC,CAAA;AAAA,IACA,SAAA,EAAW,MAAO,EAAA,GAAK,CAAA;AAAA,IACvB,GAAG;AAAA,GACJ,CAAA;AACH;ACCO,SAAS,WAAA,CACd,QACA,OAAA,EACA;AACA,EAAA,MAAM,EAAE,QAAO,GAAI,MAAA;AAEnB,EAAA,OAAOA,QAAAA,CAAS;AAAA,IACd,UAAU,CAAC,GAAG,WAAA,CAAY,GAAA,EAAK,YAAY,MAAM,CAAA;AAAA,IACjD,SAAS,YAA0C;AAEjD,MAAA,MAAM,EAAE,IAAA,EAAM,QAAA,EAAU,KAAA,EAAO,aAAA,KAAkB,MAAM,QAAA,CACpD,IAAA,CAAK,mBAAmB,EACxB,MAAA,CAAO,GAAG,CAAA,CACV,EAAA,CAAG,WAAW,MAAM,CAAA;AAEvB,MAAA,IAAI,eAAe,MAAM,aAAA;AAGzB,MAAA,MAAM,EAAE,IAAA,EAAM,SAAA,EAAW,KAAA,EAAO,cAAA,EAAe,GAAI,MAAM,QAAA,CACtD,IAAA,CAAK,kBAAkB,CAAA,CACvB,MAAA,CAAO,GAAG,CAAA,CACV,EAAA,CAAG,SAAA,EAAW,MAAM,CAAA,CACpB,KAAA,CAAM,MAAA,EAAQ,EAAE,SAAA,EAAW,IAAA,EAAM,CAAA,CACjC,KAAA,CAAM,OAAA,EAAS,EAAE,SAAA,EAAW,MAAM,CAAA;AAErC,MAAA,IAAI,gBAAgB,MAAM,cAAA;AAE1B,MAAA,MAAM,MAAA,GAAA,CAAU,QAAA,IAAY,EAAC,EAC1B,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,YAAA,KAAiB,OAAO,CAAA,CACxC,GAAA,CAAI,CAAC,CAAA,MAAO;AAAA,QACX,IAAI,CAAA,CAAE,EAAA;AAAA,QACN,MAAM,CAAA,CAAE,IAAA;AAAA,QACR,OAAA,EAAS,MAAA,CAAO,CAAA,CAAE,OAAO,CAAA;AAAA,QACzB,cAAc,CAAA,CAAE,YAAA;AAAA,QAChB,6BAA6B,CAAA,CAAE;AAAA,OACjC,CAAE,CAAA;AAEJ,MAAA,MAAM,KAAA,GAAA,CAAS,QAAA,IAAY,EAAC,EACzB,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,YAAA,KAAiB,MAAM,CAAA,CACvC,GAAA,CAAI,CAAC,CAAA,MAAO;AAAA,QACX,IAAI,CAAA,CAAE,EAAA;AAAA,QACN,MAAM,CAAA,CAAE,IAAA;AAAA,QACR,OAAA,EAAS,MAAA,CAAO,CAAA,CAAE,OAAO,CAAA;AAAA,QACzB,cAAc,CAAA,CAAE,YAAA;AAAA,QAChB,6BAA6B,CAAA,CAAE;AAAA,OACjC,CAAE,CAAA;AAEJ,MAAA,MAAM,WAAA,GAAc,MAAA,CAAO,MAAA,CAAO,CAAC,GAAA,EAAK,CAAA,KAAM,GAAA,GAAM,UAAA,CAAW,CAAA,CAAE,OAAO,CAAA,EAAG,CAAC,CAAA;AAC5E,MAAA,MAAM,UAAA,GAAa,KAAA,CAAM,MAAA,CAAO,CAAC,GAAA,EAAK,CAAA,KAAM,GAAA,GAAM,UAAA,CAAW,CAAA,CAAE,OAAO,CAAA,EAAG,CAAC,CAAA;AAE1E,MAAA,MAAM,qBAA6C,SAAA,IAAa,EAAC,EAAG,GAAA,CAAI,CAAC,CAAA,MAAO;AAAA,QAC9E,KAAA,EAAO,MAAA,CAAO,CAAA,CAAE,KAAK,CAAA;AAAA,QACrB,WAAA,EAAa,MAAA,CAAO,CAAA,CAAE,WAAW,CAAA;AAAA,QACjC,UAAA,EAAY,MAAA,CAAO,CAAA,CAAE,UAAU,CAAA;AAAA,QAC/B,OAAO,MAAA,CAAO,CAAA,CAAE,KAAK,CAAA,CAAE,QAAA,CAAS,GAAG,GAAG,CAAA;AAAA,QACtC,IAAA,EAAM,MAAA,CAAO,CAAA,CAAE,IAAI,CAAA;AAAA,QACnB,gBAAA,EAAkB,MAAA,CAAO,CAAA,CAAE,gBAAgB;AAAA,OAC7C,CAAE,CAAA;AAEF,MAAA,OAAO;AAAA,QACL,IAAA,EAAM;AAAA,UACJ,SAAA,EAAW,MAAA,CAAO,WAAA,GAAc,UAAU,CAAA;AAAA,UAC1C,gBAAA,EAAkB,GAAA;AAAA;AAAA,UAClB,YAAA,EAAc,OAAO,WAAW,CAAA;AAAA,UAChC,WAAA,EAAa,OAAO,UAAU;AAAA,SAChC;AAAA,QACA,MAAA;AAAA,QACA,KAAA;AAAA,QACA,kBAAA,EAAoB;AAAA,OACtB;AAAA,IACF,CAAA;AAAA,IACA,SAAA,EAAW,MAAO,EAAA,GAAK,CAAA;AAAA,IACvB,GAAG;AAAA,GACJ,CAAA;AACH;AC7FO,SAAS,iBACd,OAAA,EACA;AACA,EAAA,MAAM,cAAc,cAAA,EAAe;AACnC,EAAA,MAAM,EAAE,IAAA,EAAK,GAAI,UAAA,EAAW;AAE5B,EAAA,OAAO,WAAA,CAAY;AAAA,IACjB,UAAA,EAAY,OAAO,EAAE,IAAA,EAAK,KAA2B;AACnD,MAAA,MAAM,MAAA,GACJ,IAAA,KAAS,OAAA,GACL,wBAAA,GACA,uBAAA;AAEN,MAAA,MAAM,SAAA,GAAY,MAAA,CAAO,KAAA,CAAM,IAAI,CAAA;AAEnC,MAAA,MAAM,EAAE,IAAA,EAAM,OAAA,EAAS,KAAA,KAAU,MAAM,QAAA,CACpC,IAAA,CAAK,UAAU,EACf,MAAA,CAAO,SAAS,CAAA,CAChB,MAAA,GACA,MAAA,EAAO;AAEV,MAAA,IAAI,OAAO,MAAM,KAAA;AAEjB,MAAA,OAAOC,aAAAA,CAAc,MAAM,OAAO,CAAA;AAAA,IACpC,CAAA;AAAA,IACA,SAAA,EAAW,CAAC,UAAA,EAAY,SAAA,EAAW,gBAAgB,OAAA,KAAY;AAC7D,MAAA,WAAA,CAAY,YAAA;AAAA,QACV,WAAA,CAAY,IAAA,CAAK,SAAA,CAAU,MAAM,CAAA;AAAA,QACjC,CAAC,OAAA,KAAsC;AACrC,UAAA,IAAI,CAAC,OAAA,EAAS,OAAO,EAAE,QAAA,EAAU,CAAC,UAAU,CAAA,EAAE;AAC9C,UAAA,OAAO,EAAE,QAAA,EAAU,CAAC,GAAG,OAAA,CAAQ,QAAA,EAAU,UAAU,CAAA,EAAE;AAAA,QACvD;AAAA,OACF;AAEA,MAAA,OAAA,EAAS,SAAA,GAAY,UAAA,EAAY,SAAA,EAAW,cAAA,EAAgB,OAAO,CAAA;AAAA,IACrE,CAAA;AAAA,IACA,GAAG;AAAA,GACJ,CAAA;AACH;ACvCO,SAAS,iBACd,OAAA,EAIA;AACA,EAAA,MAAM,cAAcC,cAAAA,EAAe;AAEnC,EAAA,OAAOC,WAAAA,CAAY;AAAA,IACjB,UAAA,EAAY,OAAO,EAAE,SAAA,EAAW,MAAK,KAA2B;AAC9D,MAAA,MAAM,SAAA,GAAY,mBAAA,CAAoB,KAAA,CAAM,IAAI,CAAA;AAEhD,MAAA,MAAM,EAAE,IAAA,EAAM,OAAA,EAAS,OAAM,GAAI,MAAM,SACpC,IAAA,CAAK,UAAU,EACf,MAAA,CAAO,SAAS,EAChB,EAAA,CAAG,IAAA,EAAM,SAAS,CAAA,CAClB,MAAA,GACA,MAAA,EAAO;AAEV,MAAA,IAAI,OAAO,MAAM,KAAA;AAEjB,MAAA,OAAOF,aAAAA,CAAc,MAAM,OAAO,CAAA;AAAA,IACpC,CAAA;AAAA,IACA,WAAW,CAAC,CAAA,EAAG,EAAE,MAAA,EAAQ,WAAU,KAAM;AACvC,MAAA,WAAA,CAAY,iBAAA,CAAkB;AAAA,QAC5B,QAAA,EAAU,WAAA,CAAY,IAAA,CAAK,MAAM;AAAA,OAClC,CAAA;AACD,MAAA,WAAA,CAAY,iBAAA,CAAkB;AAAA,QAC5B,QAAA,EAAU,WAAA,CAAY,MAAA,CAAO,MAAA,EAAQ,SAAS;AAAA,OAC/C,CAAA;AAAA,IACH,CAAA;AAAA,IACA,GAAG;AAAA,GACJ,CAAA;AACH;ACxCO,SAAS,iBACd,OAAA,EAIA;AACA,EAAA,MAAM,cAAcC,cAAAA,EAAe;AAEnC,EAAA,OAAOC,WAAAA,CAAY;AAAA,IACjB,UAAA,EAAY,OAAO,EAAE,SAAA,EAAU,KAA2B;AACxD,MAAA,MAAM,EAAE,KAAA,EAAM,GAAI,MAAM,QAAA,CACrB,IAAA,CAAK,UAAU,CAAA,CACf,MAAA,EAAO,CACP,EAAA,CAAG,IAAA,EAAM,SAAS,CAAA;AAErB,MAAA,IAAI,OAAO,MAAM,KAAA;AAAA,IACnB,CAAA;AAAA,IACA,WAAW,CAAC,CAAA,EAAG,EAAE,MAAA,EAAQ,WAAU,KAAM;AACvC,MAAA,WAAA,CAAY,iBAAA,CAAkB;AAAA,QAC5B,QAAA,EAAU,WAAA,CAAY,IAAA,CAAK,MAAM;AAAA,OAClC,CAAA;AACD,MAAA,WAAA,CAAY,aAAA,CAAc;AAAA,QACxB,QAAA,EAAU,WAAA,CAAY,MAAA,CAAO,MAAA,EAAQ,SAAS;AAAA,OAC/C,CAAA;AAAA,IACH,CAAA;AAAA,IACA,GAAG;AAAA,GACJ,CAAA;AACH;AC1BO,SAAS,kBACd,OAAA,EAIA;AACA,EAAA,MAAM,cAAcD,cAAAA,EAAe;AAEnC,EAAA,OAAOC,WAAAA,CAAY;AAAA,IACjB,UAAA,EAAY,OAAO,EAAE,SAAA,EAAU,KAA4B;AACzD,MAAA,MAAM,EAAE,MAAM,KAAA,EAAM,GAAI,MAAM,QAAA,CAC3B,IAAA,CAAK,UAAU,CAAA,CACf,MAAA,CAAO,EAAE,SAAA,EAAW,KAAA,EAAO,CAAA,CAC3B,EAAA,CAAG,MAAM,SAAS,CAAA,CAClB,MAAA,EAAO,CACP,MAAA,EAAO;AAEV,MAAA,IAAI,OAAO,MAAM,KAAA;AAEjB,MAAA,OAAOF,aAAAA,CAAc,MAAM,IAAI,CAAA;AAAA,IACjC,CAAA;AAAA,IACA,WAAW,CAAC,CAAA,EAAG,EAAE,MAAA,EAAQ,WAAU,KAAM;AACvC,MAAA,WAAA,CAAY,iBAAA,CAAkB;AAAA,QAC5B,QAAA,EAAU,WAAA,CAAY,IAAA,CAAK,MAAM;AAAA,OAClC,CAAA;AACD,MAAA,WAAA,CAAY,iBAAA,CAAkB;AAAA,QAC5B,QAAA,EAAU,WAAA,CAAY,MAAA,CAAO,MAAA,EAAQ,SAAS;AAAA,OAC/C,CAAA;AAAA,IACH,CAAA;AAAA,IACA,GAAG;AAAA,GACJ,CAAA;AACH;AC1BO,SAAS,yBACd,OAAA,EAIA;AACA,EAAA,MAAM,cAAcC,cAAAA,EAAe;AAEnC,EAAA,OAAOC,WAAAA,CAAY;AAAA,IACjB,UAAA,EAAY,OAAO,EAAE,MAAA,EAAQ,MAAK,KAAmC;AACnE,MAAA,MAAM,EAAE,OAAM,GAAI,MAAM,SAAS,IAAA,CAAK,mBAAmB,EAAE,MAAA,CAAO;AAAA,QAChE,OAAA,EAAS,MAAA;AAAA,QACT,IAAA,EAAM,KAAK,gBAAA,CAAiB,IAAA;AAAA,QAC5B,OAAA,EAAS,UAAA,CAAW,IAAA,CAAK,gBAAA,CAAiB,OAAO,CAAA;AAAA,QACjD,YAAA,EAAc,KAAK,gBAAA,CAAiB,YAAA;AAAA,QACpC,2BAAA,EAA6B;AAAA,OAC9B,CAAA;AAED,MAAA,IAAI,OAAO,MAAM,KAAA;AAAA,IACnB,CAAA;AAAA,IACA,SAAA,EAAW,CAAC,CAAA,EAAG,EAAE,QAAO,KAAM;AAC5B,MAAA,WAAA,CAAY,iBAAA,CAAkB;AAAA,QAC5B,UAAU,CAAC,GAAG,WAAA,CAAY,GAAA,EAAK,YAAY,MAAM;AAAA,OAClD,CAAA;AAAA,IACH,CAAA;AAAA,IACA,GAAG;AAAA,GACJ,CAAA;AACH;AC1BO,SAAS,yBACd,OAAA,EAIA;AACA,EAAA,MAAM,cAAcD,cAAAA,EAAe;AAEnC,EAAA,OAAOC,WAAAA,CAAY;AAAA,IACjB,UAAA,EAAY,OAAO,EAAE,SAAA,EAAW,MAAK,KAAmC;AACtE,MAAA,MAAM,EAAE,OAAM,GAAI,MAAM,SACrB,IAAA,CAAK,mBAAmB,EACxB,MAAA,CAAO;AAAA,QACN,IAAA,EAAM,KAAK,gBAAA,CAAiB,IAAA;AAAA,QAC5B,OAAA,EAAS,UAAA,CAAW,IAAA,CAAK,gBAAA,CAAiB,OAAO,CAAA;AAAA,QACjD,YAAA,EAAc,KAAK,gBAAA,CAAiB;AAAA,OACrC,CAAA,CACA,EAAA,CAAG,IAAA,EAAM,MAAA,CAAO,SAAS,CAAC,CAAA;AAE7B,MAAA,IAAI,OAAO,MAAM,KAAA;AAAA,IACnB,CAAA;AAAA,IACA,SAAA,EAAW,CAAC,CAAA,EAAG,EAAE,QAAO,KAAM;AAC5B,MAAA,WAAA,CAAY,iBAAA,CAAkB;AAAA,QAC5B,UAAU,CAAC,GAAG,WAAA,CAAY,GAAA,EAAK,YAAY,MAAM;AAAA,OAClD,CAAA;AAAA,IACH,CAAA;AAAA,IACA,GAAG;AAAA,GACJ,CAAA;AACH;ACnCO,SAAS,yBACd,OAAA,EAIA;AACA,EAAA,MAAM,cAAcD,cAAAA,EAAe;AAEnC,EAAA,OAAOC,WAAAA,CAAY;AAAA,IACjB,UAAA,EAAY,OAAO,EAAE,SAAA,EAAU,KAAmC;AAChE,MAAA,MAAM,EAAE,KAAA,EAAM,GAAI,MAAM,SACrB,IAAA,CAAK,mBAAmB,CAAA,CACxB,MAAA,EAAO,CACP,EAAA,CAAG,IAAA,EAAM,MAAA,CAAO,SAAS,CAAC,CAAA;AAE7B,MAAA,IAAI,OAAO,MAAM,KAAA;AAAA,IACnB,CAAA;AAAA,IACA,SAAA,EAAW,CAAC,CAAA,EAAG,EAAE,QAAO,KAAM;AAC5B,MAAA,WAAA,CAAY,iBAAA,CAAkB;AAAA,QAC5B,UAAU,CAAC,GAAG,WAAA,CAAY,GAAA,EAAK,YAAY,MAAM;AAAA,OAClD,CAAA;AAAA,IACH,CAAA;AAAA,IACA,GAAG;AAAA,GACJ,CAAA;AACH","file":"index.js","sourcesContent":["/**\n * Query key factory for Accounts domain\n * Following TanStack Query best practices for hierarchical cache keys\n *\n * Key structure:\n * - ['accounts'] - Root key for all account queries\n * - ['accounts', 'list', userId] - List of accounts for a user\n * - ['accounts', 'detail', userId, accountId] - Single account detail\n */\n\nexport const accountKeys = {\n all: ['accounts'] as const,\n\n lists: () => [...accountKeys.all, 'list'] as const,\n\n list: (userId: string) => [...accountKeys.lists(), userId] as const,\n\n details: () => [...accountKeys.all, 'detail'] as const,\n\n detail: (userId: string, accountId: string) =>\n [...accountKeys.details(), userId, accountId] as const,\n\n institutions: () => [...accountKeys.all, 'institutions'] as const,\n\n institution: (userId: string) =>\n [...accountKeys.institutions(), userId] as const,\n};\n","/**\n * Query hook for fetching all accounts for a user\n * Supabase: accounts table filtered by user_id\n */\n\nimport { useQuery, UseQueryOptions } from '@tanstack/react-query';\nimport { AccountsResponseSchema, type Account } from '@pfm-platform/shared';\nimport { accountKeys } from '../keys';\nimport { supabase } from '../client';\n\nexport interface UseAccountsParams {\n userId: string;\n}\n\nexport interface AccountsData {\n accounts: Account[];\n}\n\n/**\n * Fetch all accounts for a user from Supabase\n *\n * Returns `{ accounts: Account[] }` to match the shape expected by\n * feature hooks (useAccountFilters, useAccountTypes, useAccountSummary).\n *\n * @example\n * ```tsx\n * const { data } = useAccounts({ userId });\n * // data.accounts is Account[]\n * ```\n */\nexport function useAccounts(\n params: UseAccountsParams,\n options?: Omit<UseQueryOptions<AccountsData>, 'queryKey' | 'queryFn'>\n) {\n const { userId } = params;\n\n return useQuery({\n queryKey: accountKeys.list(userId),\n queryFn: async (): Promise<AccountsData> => {\n const { data, error } = await supabase\n .from('accounts')\n .select('*')\n .eq('user_id', userId)\n .order('name');\n\n if (error) throw error;\n\n return { accounts: AccountsResponseSchema.parse(data) };\n },\n staleTime: 1000 * 60 * 5,\n ...options,\n });\n}\n","/**\n * Query hook for fetching a single account by ID\n * Supabase: accounts table filtered by id\n */\n\nimport { useQuery, UseQueryOptions } from '@tanstack/react-query';\nimport { AccountSchema, type Account } from '@pfm-platform/shared';\nimport { accountKeys } from '../keys';\nimport { supabase } from '../client';\n\nexport interface UseAccountParams {\n userId: string;\n accountId: string;\n}\n\n/**\n * Fetch a single account by ID from Supabase\n *\n * @example\n * ```tsx\n * const { data } = useAccount({ userId, accountId });\n * // data is Account\n * ```\n */\nexport function useAccount(\n params: UseAccountParams,\n options?: Omit<UseQueryOptions<Account>, 'queryKey' | 'queryFn'>\n) {\n const { userId, accountId } = params;\n\n return useQuery({\n queryKey: accountKeys.detail(userId, accountId),\n queryFn: async () => {\n const { data, error } = await supabase\n .from('accounts')\n .select('*')\n .eq('id', accountId)\n .eq('user_id', userId)\n .single();\n\n if (error) throw error;\n\n return AccountSchema.parse(data);\n },\n staleTime: 1000 * 60 * 5,\n ...options,\n });\n}\n","/**\n * Query hook for fetching net worth data\n * TODO: Wire to Supabase networth_summary view + networth_accounts table\n */\n\nimport { useQuery, UseQueryOptions } from '@tanstack/react-query';\nimport { accountKeys } from '../keys';\nimport { supabase } from '../client';\n\nexport interface NetWorthAccount {\n id: string;\n name: string;\n balance: string;\n account_type: 'asset' | 'debt';\n additional_networth_account: boolean;\n}\n\nexport interface NetWorthMeta {\n net_worth: string;\n net_worth_change: string;\n total_assets: string;\n total_debts: string;\n}\n\nexport interface NetWorthHistoryEntry {\n total: string;\n total_asset: string;\n total_debt: string;\n month: string;\n year: string;\n since_last_month: string;\n}\n\nexport interface NetWorthData {\n meta: NetWorthMeta;\n assets: NetWorthAccount[];\n debts: NetWorthAccount[];\n networth_histories: NetWorthHistoryEntry[];\n}\n\nexport interface UseNetWorthParams {\n userId: string;\n}\n\n/**\n * Fetch net worth summary with manual accounts\n * Combines networth_summary view + networth_accounts table\n */\nexport function useNetWorth(\n params: UseNetWorthParams,\n options?: Omit<UseQueryOptions<NetWorthData | null>, 'queryKey' | 'queryFn'>\n) {\n const { userId } = params;\n\n return useQuery({\n queryKey: [...accountKeys.all, 'networth', userId],\n queryFn: async (): Promise<NetWorthData | null> => {\n // Fetch manual networth accounts\n const { data: accounts, error: accountsError } = await supabase\n .from('networth_accounts')\n .select('*')\n .eq('user_id', userId);\n\n if (accountsError) throw accountsError;\n\n // Fetch networth history\n const { data: histories, error: historiesError } = await supabase\n .from('networth_history')\n .select('*')\n .eq('user_id', userId)\n .order('year', { ascending: true })\n .order('month', { ascending: true });\n\n if (historiesError) throw historiesError;\n\n const assets = (accounts || [])\n .filter((a) => a.account_type === 'asset')\n .map((a) => ({\n id: a.id,\n name: a.name,\n balance: String(a.balance),\n account_type: a.account_type as 'asset' | 'debt',\n additional_networth_account: a.additional_networth_account,\n }));\n\n const debts = (accounts || [])\n .filter((a) => a.account_type === 'debt')\n .map((a) => ({\n id: a.id,\n name: a.name,\n balance: String(a.balance),\n account_type: a.account_type as 'asset' | 'debt',\n additional_networth_account: a.additional_networth_account,\n }));\n\n const totalAssets = assets.reduce((sum, a) => sum + parseFloat(a.balance), 0);\n const totalDebts = debts.reduce((sum, d) => sum + parseFloat(d.balance), 0);\n\n const networthHistories: NetWorthHistoryEntry[] = (histories || []).map((h) => ({\n total: String(h.total),\n total_asset: String(h.total_asset),\n total_debt: String(h.total_debt),\n month: String(h.month).padStart(2, '0'),\n year: String(h.year),\n since_last_month: String(h.since_last_month),\n }));\n\n return {\n meta: {\n net_worth: String(totalAssets - totalDebts),\n net_worth_change: '0', // TODO: compute from networth_history\n total_assets: String(totalAssets),\n total_debts: String(totalDebts),\n },\n assets,\n debts,\n networth_histories: networthHistories,\n };\n },\n staleTime: 1000 * 60 * 5,\n ...options,\n });\n}\n","import {\n useMutation,\n useQueryClient,\n type UseMutationOptions,\n} from '@tanstack/react-query';\nimport {\n AccountCreateSchemaAdmin,\n AccountCreateSchemaUser,\n AccountSchema,\n useAppMode,\n type AccountCreate,\n type Account,\n} from '@pfm-platform/shared';\nimport { supabase } from '../client';\nimport { accountKeys } from '../keys';\nimport type { AccountsData } from '../queries/useAccounts';\n\nexport interface CreateAccountParams {\n userId: string;\n data: AccountCreate;\n}\n\n/**\n * Mutation hook for creating a new account in Supabase\n *\n * Uses mode switching for validation:\n * - Admin mode: Minimal validation for test data creation\n * - User mode: Full validation with business rules\n */\nexport function useCreateAccount(\n options?: Omit<UseMutationOptions<Account, Error, CreateAccountParams>, 'mutationFn'>\n) {\n const queryClient = useQueryClient();\n const { mode } = useAppMode();\n\n return useMutation({\n mutationFn: async ({ data }: CreateAccountParams) => {\n const schema =\n mode === 'admin'\n ? AccountCreateSchemaAdmin\n : AccountCreateSchemaUser;\n\n const validated = schema.parse(data);\n\n const { data: created, error } = await supabase\n .from('accounts')\n .insert(validated)\n .select()\n .single();\n\n if (error) throw error;\n\n return AccountSchema.parse(created);\n },\n onSuccess: (newAccount, variables, onMutateResult, context) => {\n queryClient.setQueryData(\n accountKeys.list(variables.userId),\n (oldData: AccountsData | undefined) => {\n if (!oldData) return { accounts: [newAccount] };\n return { accounts: [...oldData.accounts, newAccount] };\n }\n );\n\n options?.onSuccess?.(newAccount, variables, onMutateResult, context);\n },\n ...options,\n });\n}\n","/**\n * Mutation hook for updating an account\n * Supabase: UPDATE accounts SET ... WHERE id = ...\n */\n\nimport {\n useMutation,\n UseMutationOptions,\n useQueryClient,\n} from '@tanstack/react-query';\nimport {\n AccountUpdateSchema,\n AccountSchema,\n Account,\n AccountUpdate,\n} from '@pfm-platform/shared';\nimport { accountKeys } from '../keys';\nimport { supabase } from '../client';\n\nexport interface UpdateAccountParams {\n userId: string;\n accountId: string;\n data: AccountUpdate;\n}\n\n/**\n * Update an existing account in Supabase\n */\nexport function useUpdateAccount(\n options?: Omit<\n UseMutationOptions<Account, Error, UpdateAccountParams>,\n 'mutationFn'\n >\n) {\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: async ({ accountId, data }: UpdateAccountParams) => {\n const validated = AccountUpdateSchema.parse(data);\n\n const { data: updated, error } = await supabase\n .from('accounts')\n .update(validated)\n .eq('id', accountId)\n .select()\n .single();\n\n if (error) throw error;\n\n return AccountSchema.parse(updated);\n },\n onSuccess: (_, { userId, accountId }) => {\n queryClient.invalidateQueries({\n queryKey: accountKeys.list(userId),\n });\n queryClient.invalidateQueries({\n queryKey: accountKeys.detail(userId, accountId),\n });\n },\n ...options,\n });\n}\n","/**\n * Mutation hook for deleting an account\n * Supabase: DELETE FROM accounts WHERE id = ...\n */\n\nimport {\n useMutation,\n UseMutationOptions,\n useQueryClient,\n} from '@tanstack/react-query';\nimport { accountKeys } from '../keys';\nimport { supabase } from '../client';\n\nexport interface DeleteAccountParams {\n userId: string;\n accountId: string;\n}\n\n/**\n * Delete an account from Supabase (hard delete)\n */\nexport function useDeleteAccount(\n options?: Omit<\n UseMutationOptions<void, Error, DeleteAccountParams>,\n 'mutationFn'\n >\n) {\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: async ({ accountId }: DeleteAccountParams) => {\n const { error } = await supabase\n .from('accounts')\n .delete()\n .eq('id', accountId);\n\n if (error) throw error;\n },\n onSuccess: (_, { userId, accountId }) => {\n queryClient.invalidateQueries({\n queryKey: accountKeys.list(userId),\n });\n queryClient.removeQueries({\n queryKey: accountKeys.detail(userId, accountId),\n });\n },\n ...options,\n });\n}\n","/**\n * Mutation hook for archiving an account (soft delete)\n * Supabase: UPDATE accounts SET is_active = false WHERE id = ...\n */\n\nimport {\n useMutation,\n UseMutationOptions,\n useQueryClient,\n} from '@tanstack/react-query';\nimport { AccountSchema, Account } from '@pfm-platform/shared';\nimport { accountKeys } from '../keys';\nimport { supabase } from '../client';\n\nexport interface ArchiveAccountParams {\n userId: string;\n accountId: string;\n}\n\n/**\n * Archive an account (soft delete via is_active = false)\n */\nexport function useArchiveAccount(\n options?: Omit<\n UseMutationOptions<Account, Error, ArchiveAccountParams>,\n 'mutationFn'\n >\n) {\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: async ({ accountId }: ArchiveAccountParams) => {\n const { data, error } = await supabase\n .from('accounts')\n .update({ is_active: false })\n .eq('id', accountId)\n .select()\n .single();\n\n if (error) throw error;\n\n return AccountSchema.parse(data);\n },\n onSuccess: (_, { userId, accountId }) => {\n queryClient.invalidateQueries({\n queryKey: accountKeys.list(userId),\n });\n queryClient.invalidateQueries({\n queryKey: accountKeys.detail(userId, accountId),\n });\n },\n ...options,\n });\n}\n","/**\n * Mutation hook for creating a net worth account\n * Supabase: INSERT INTO networth_accounts ...\n */\n\nimport {\n useMutation,\n UseMutationOptions,\n useQueryClient,\n} from '@tanstack/react-query';\nimport { accountKeys } from '../keys';\nimport { supabase } from '../client';\n\nexport interface CreateNetWorthAccountParams {\n userId: string;\n data: {\n networth_account: {\n name: string;\n balance: string;\n account_type: string;\n };\n };\n}\n\n/**\n * Create a net worth account in Supabase\n */\nexport function useCreateNetWorthAccount(\n options?: Omit<\n UseMutationOptions<void, Error, CreateNetWorthAccountParams>,\n 'mutationFn'\n >\n) {\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: async ({ userId, data }: CreateNetWorthAccountParams) => {\n const { error } = await supabase.from('networth_accounts').insert({\n user_id: userId,\n name: data.networth_account.name,\n balance: parseFloat(data.networth_account.balance),\n account_type: data.networth_account.account_type,\n additional_networth_account: true,\n });\n\n if (error) throw error;\n },\n onSuccess: (_, { userId }) => {\n queryClient.invalidateQueries({\n queryKey: [...accountKeys.all, 'networth', userId],\n });\n },\n ...options,\n });\n}\n","/**\n * Mutation hook for updating a net worth account\n * Supabase: UPDATE networth_accounts SET ... WHERE id = ...\n */\n\nimport {\n useMutation,\n UseMutationOptions,\n useQueryClient,\n} from '@tanstack/react-query';\nimport { accountKeys } from '../keys';\nimport { supabase } from '../client';\n\nexport interface UpdateNetWorthAccountParams {\n userId: string;\n accountId: number | string;\n data: {\n networth_account: {\n name: string;\n balance: string;\n account_type: string;\n };\n };\n}\n\n/**\n * Update a net worth account in Supabase\n */\nexport function useUpdateNetWorthAccount(\n options?: Omit<\n UseMutationOptions<void, Error, UpdateNetWorthAccountParams>,\n 'mutationFn'\n >\n) {\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: async ({ accountId, data }: UpdateNetWorthAccountParams) => {\n const { error } = await supabase\n .from('networth_accounts')\n .update({\n name: data.networth_account.name,\n balance: parseFloat(data.networth_account.balance),\n account_type: data.networth_account.account_type,\n })\n .eq('id', String(accountId));\n\n if (error) throw error;\n },\n onSuccess: (_, { userId }) => {\n queryClient.invalidateQueries({\n queryKey: [...accountKeys.all, 'networth', userId],\n });\n },\n ...options,\n });\n}\n","/**\n * Mutation hook for deleting a net worth account\n * Supabase: DELETE FROM networth_accounts WHERE id = ...\n */\n\nimport {\n useMutation,\n UseMutationOptions,\n useQueryClient,\n} from '@tanstack/react-query';\nimport { accountKeys } from '../keys';\nimport { supabase } from '../client';\n\nexport interface DeleteNetWorthAccountParams {\n userId: string;\n accountId: number | string;\n}\n\n/**\n * Delete a net worth account from Supabase\n */\nexport function useDeleteNetWorthAccount(\n options?: Omit<\n UseMutationOptions<void, Error, DeleteNetWorthAccountParams>,\n 'mutationFn'\n >\n) {\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: async ({ accountId }: DeleteNetWorthAccountParams) => {\n const { error } = await supabase\n .from('networth_accounts')\n .delete()\n .eq('id', String(accountId));\n\n if (error) throw error;\n },\n onSuccess: (_, { userId }) => {\n queryClient.invalidateQueries({\n queryKey: [...accountKeys.all, 'networth', userId],\n });\n },\n ...options,\n });\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pfm-platform/accounts-data-access",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
@@ -10,19 +10,17 @@
10
10
  }
11
11
  },
12
12
  "dependencies": {
13
- "axios": "^1.13.2",
14
13
  "zod": "4.1.12",
15
- "@pfm-platform/shared": "0.1.0"
14
+ "@pfm-platform/shared": "0.2.1"
16
15
  },
17
16
  "devDependencies": {
18
- "@testing-library/react": "^16.3.0",
19
- "@vitejs/plugin-react": "^5.1.1",
20
- "@vitest/coverage-v8": "^4.0.9",
17
+ "@testing-library/react": "^16.3.2",
18
+ "@vitejs/plugin-react": "^5.1.4",
19
+ "@vitest/coverage-v8": "^4.0.18",
21
20
  "jsdom": "^27.2.0",
22
- "msw": "^2.12.2",
23
- "react-dom": "19.2.0",
21
+ "react-dom": "19.2.4",
24
22
  "typescript": "5.9.3",
25
- "vitest": "4.0.9"
23
+ "vitest": "4.0.18"
26
24
  },
27
25
  "main": "./dist/index.js",
28
26
  "module": "./dist/index.js",