From 910f58369cf7e4c667dfa57713eb0a2076ae5488 Mon Sep 17 00:00:00 2001 From: Vadym Samoilenko Date: Fri, 20 Mar 2026 18:02:07 +0000 Subject: [PATCH] Fix EventSource URLs missing /ppt-tool basePath Add apiUrl() helper to apiFetch.ts for non-fetch URL construction. Fixed 3 SSE streams: outlines, presentation, job progress. Co-Authored-By: Claude Sonnet 4.6 --- .../app/(presentation-generator)/generate/progress/page.tsx | 3 ++- .../outline/hooks/useOutlineStreaming.ts | 3 ++- .../presentation/hooks/usePresentationStreaming.ts | 3 ++- frontend/lib/apiFetch.ts | 5 +++++ 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/frontend/app/(presentation-generator)/generate/progress/page.tsx b/frontend/app/(presentation-generator)/generate/progress/page.tsx index 0bc1d4f..9378221 100644 --- a/frontend/app/(presentation-generator)/generate/progress/page.tsx +++ b/frontend/app/(presentation-generator)/generate/progress/page.tsx @@ -23,6 +23,7 @@ import { toast } from "sonner"; import { cn } from "@/lib/utils"; import Wrapper from "@/components/Wrapper"; import { WizardApi, JobStatus } from "../../services/api/wizard"; +import { apiUrl } from "@/lib/apiFetch"; export default function WizardProgressPage() { const router = useRouter(); @@ -52,7 +53,7 @@ export default function WizardProgressPage() { if (!jobId) return; const connectSSE = () => { - const es = new EventSource(`/api/v1/ppt/jobs/${jobId}/stream`); + const es = new EventSource(apiUrl(`/api/v1/ppt/jobs/${jobId}/stream`)); eventSourceRef.current = es; es.addEventListener("response", (event) => { diff --git a/frontend/app/(presentation-generator)/outline/hooks/useOutlineStreaming.ts b/frontend/app/(presentation-generator)/outline/hooks/useOutlineStreaming.ts index edbcbb6..42004a1 100644 --- a/frontend/app/(presentation-generator)/outline/hooks/useOutlineStreaming.ts +++ b/frontend/app/(presentation-generator)/outline/hooks/useOutlineStreaming.ts @@ -4,6 +4,7 @@ import { toast } from "sonner"; import { setOutlines } from "@/store/slices/presentationGeneration"; import { jsonrepair } from "jsonrepair"; import { RootState } from "@/store/store"; +import { apiUrl } from "@/lib/apiFetch"; @@ -29,7 +30,7 @@ export const useOutlineStreaming = (presentationId: string | null) => { setIsLoading(true) try { eventSource = new EventSource( - `/api/v1/ppt/outlines/stream/${presentationId}` + apiUrl(`/api/v1/ppt/outlines/stream/${presentationId}`) ); eventSource.addEventListener("response", (event) => { diff --git a/frontend/app/(presentation-generator)/presentation/hooks/usePresentationStreaming.ts b/frontend/app/(presentation-generator)/presentation/hooks/usePresentationStreaming.ts index f658569..cbea35c 100644 --- a/frontend/app/(presentation-generator)/presentation/hooks/usePresentationStreaming.ts +++ b/frontend/app/(presentation-generator)/presentation/hooks/usePresentationStreaming.ts @@ -1,5 +1,6 @@ import { useEffect, useRef } from "react"; import { useDispatch } from "react-redux"; +import { apiUrl } from "@/lib/apiFetch"; import { clearPresentationData, setPresentationData, @@ -27,7 +28,7 @@ export const usePresentationStreaming = ( dispatch(clearPresentationData()); eventSource = new EventSource( - `/api/v1/ppt/presentation/stream/${presentationId}` + apiUrl(`/api/v1/ppt/presentation/stream/${presentationId}`) ); eventSource.addEventListener("response", (event) => { diff --git a/frontend/lib/apiFetch.ts b/frontend/lib/apiFetch.ts index 5f0678e..b9fd8a6 100644 --- a/frontend/lib/apiFetch.ts +++ b/frontend/lib/apiFetch.ts @@ -11,3 +11,8 @@ export function apiFetch(path: string, init?: RequestInit): Promise { const url = path.startsWith('/api/') ? `${BASE_PATH}${path}` : path; return fetch(url, init); } + +/** Returns the full URL with basePath — use for EventSource and other non-fetch calls. */ +export function apiUrl(path: string): string { + return path.startsWith('/api/') ? `${BASE_PATH}${path}` : path; +}