Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions hooks/useCatalogs.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
import { useQuery, UseQueryResult } from "@tanstack/react-query";
import { usePrivy } from "@privy-io/react-auth";
import { getCatalogs, CatalogsResponse } from "@/lib/catalog/getCatalogs";
import { useUserProvider } from "@/providers/UserProvder";

const useCatalogs = (): UseQueryResult<CatalogsResponse> => {
const { getAccessToken, authenticated } = usePrivy();
const { userData } = useUserProvider();
const accountId = userData?.account_id || "";

return useQuery({
queryKey: ["catalogs", accountId],
queryFn: () => getCatalogs(accountId),
enabled: !!accountId,
queryFn: async () => {
const accessToken = await getAccessToken();
if (!accessToken) throw new Error("No access token");
return getCatalogs(accountId, accessToken);
},
enabled: !!accountId && authenticated,
staleTime: 5 * 60 * 1000, // 5 minutes
refetchOnWindowFocus: false,
});
Expand Down
21 changes: 15 additions & 6 deletions lib/catalog/getCatalogs.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,34 @@
import { Tables } from "@/types/database.types";

type Catalog = Tables<"catalogs">;
import { getClientApiBaseUrl } from "@/lib/api/getClientApiBaseUrl";
import type { Catalog } from "@/types/Catalog";

export interface CatalogsResponse {
status: string;
catalogs: Catalog[];
error?: string;
}

/**
* Fetches catalogs linked to an account from the Recoup API.
*
* Authentication is via Bearer token (Privy access token).
*
* @param accountId - The account id whose catalogs to fetch (path segment).
* @param accessToken - Privy access token for Bearer auth.
*/
export async function getCatalogs(
accountId: string
accountId: string,
accessToken: string,
): Promise<CatalogsResponse> {
try {
const response = await fetch(
`https://api.recoupable.com/api/catalogs?account_id=${accountId}`,
`${getClientApiBaseUrl()}/api/accounts/${accountId}/catalogs`,
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot Apr 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Encode accountId before inserting it into the URL path segment to avoid malformed or misrouted requests.

Prompt for AI agents
Check if this issue is valid β€” if so, understand the root cause and fix it. At lib/catalog/getCatalogs.ts, line 24:

<comment>Encode `accountId` before inserting it into the URL path segment to avoid malformed or misrouted requests.</comment>

<file context>
@@ -1,25 +1,34 @@
   try {
     const response = await fetch(
-      `https://api.recoupable.com/api/catalogs?account_id=${accountId}`,
+      `${getClientApiBaseUrl()}/api/accounts/${accountId}/catalogs`,
       {
         method: "GET",
</file context>
Suggested change
`${getClientApiBaseUrl()}/api/accounts/${accountId}/catalogs`,
`${getClientApiBaseUrl()}/api/accounts/${encodeURIComponent(accountId)}/catalogs`,
Fix with Cubic

{
method: "GET",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${accessToken}`,
},
}
},
);

if (!response.ok) {
Expand Down
6 changes: 6 additions & 0 deletions types/Catalog.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export interface Catalog {
id: string;
name: string;
created_at: string;
updated_at: string;
}
Loading