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
45 changes: 0 additions & 45 deletions app/api/roomSegment/route.ts

This file was deleted.

28 changes: 12 additions & 16 deletions hooks/useChatSegment.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,29 @@
import { useQuery } from "@tanstack/react-query";
import { usePrivy } from "@privy-io/react-auth";
import { useApiOverride } from "@/hooks/useApiOverride";
import { getChatSegment } from "@/lib/chats/getChatSegment";

interface RoomSegmentResponse {
segmentId: string | null;
error?: string;
}

export const useChatSegment = (roomId?: string) => {
const { getAccessToken } = usePrivy();
const apiOverride = useApiOverride();

return useQuery({
queryKey: ["roomSegment", roomId],
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Key room segment query by token and API base

The query function now depends on both accessToken and baseUrl, but the cache key only includes roomId. In React Query, if the user logs out/in in the same tab (or changes ?api= override) while roomId stays constant, the hook can reuse cached data for up to the 5-minute staleTime and skip refetching, which can show segment data fetched under a different auth/backend context. Add auth/backend scope to the key (or invalidate on token/base URL changes) so cached results cannot bleed across sessions/environments.

Useful? React with 👍 / 👎.

queryFn: async (): Promise<RoomSegmentResponse> => {
if (!roomId) {
return { segmentId: null };
}
if (!roomId) return { segmentId: null };

const response = await fetch(`/api/roomSegment?roomId=${roomId}`);
if (!response.ok) {
const error = await response.json();
console.error("[useChatSegment] API error:", {
status: response.status,
error,
});
throw new Error(error.error || "Failed to fetch segment ID");
}
const accessToken = await getAccessToken();
if (!accessToken) throw new Error("No access token");

const data = await response.json();
return data;
const data = await getChatSegment(roomId, accessToken, apiOverride ?? undefined);
return { segmentId: data.segment_id ?? null };
},
enabled: !!roomId,
staleTime: 1000 * 60 * 5, // Cache for 5 minutes
staleTime: 1000 * 60 * 5,
retry: 2,
});
};
32 changes: 32 additions & 0 deletions lib/chats/getChatSegment.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { NEW_API_BASE_URL } from "@/lib/consts";

interface ChatSegmentResponse {
status: string;
room_id: string;
segment_id: string | null;
segment_exists: boolean;
}

/**
* Fetches the segment associated with a chat room.
*/
export async function getChatSegment(
roomId: string,
accessToken: string,
baseUrl?: string,
): Promise<ChatSegmentResponse> {
const url = baseUrl || NEW_API_BASE_URL;

const response = await fetch(`${url}/api/chats/${encodeURIComponent(roomId)}/segment`, {
headers: {
Authorization: `Bearer ${accessToken}`,
},
});

if (!response.ok) {
const error = await response.json();
throw new Error(error.error || "Failed to fetch segment ID");
}

return response.json();
}
Loading