Deleted: - 26 old markdown summary/documentation files - 16 debug/test Python scripts (debug_*, test_*, diagnose_*) - 10 untracked JSON files from api_response_samples - terms-of-usage.md, pane_not_found.png Also includes pending web app changes: - Jobs management UI (JobsView, Sidebar components) - API routes for job streaming and comparison - Enhanced ReviewAnalytics and ScraperTest components Final clean structure: ├── api_server_production.py (main entry) ├── modules/ (core Python) ├── web/ (Next.js frontend) ├── tests/ (test suite) ├── docs/ (documentation) └── examples/ (usage examples) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
58 lines
1.6 KiB
TypeScript
58 lines
1.6 KiB
TypeScript
import { NextRequest } from 'next/server';
|
|
|
|
const API_BASE_URL = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:8000';
|
|
|
|
export const dynamic = 'force-dynamic';
|
|
|
|
export async function GET(
|
|
request: NextRequest,
|
|
{ params }: { params: Promise<{ jobId: string }> }
|
|
) {
|
|
const { jobId } = await params;
|
|
const encoder = new TextEncoder();
|
|
|
|
const stream = new ReadableStream({
|
|
async start(controller) {
|
|
try {
|
|
const response = await fetch(`${API_BASE_URL}/jobs/${jobId}/stream`, {
|
|
headers: {
|
|
'Accept': 'text/event-stream',
|
|
'Cache-Control': 'no-cache',
|
|
},
|
|
});
|
|
|
|
if (!response.ok || !response.body) {
|
|
controller.enqueue(encoder.encode(`event: error\ndata: {"error": "Failed to connect to backend"}\n\n`));
|
|
controller.close();
|
|
return;
|
|
}
|
|
|
|
const reader = response.body.getReader();
|
|
|
|
while (true) {
|
|
const { done, value } = await reader.read();
|
|
if (done) {
|
|
break;
|
|
}
|
|
// Forward the SSE data as-is
|
|
controller.enqueue(value);
|
|
}
|
|
} catch (error) {
|
|
console.error('SSE stream error:', error);
|
|
controller.enqueue(encoder.encode(`event: error\ndata: {"error": "Stream connection failed"}\n\n`));
|
|
} finally {
|
|
controller.close();
|
|
}
|
|
},
|
|
});
|
|
|
|
return new Response(stream, {
|
|
headers: {
|
|
'Content-Type': 'text/event-stream',
|
|
'Cache-Control': 'no-cache, no-transform',
|
|
'Connection': 'keep-alive',
|
|
'X-Accel-Buffering': 'no',
|
|
},
|
|
});
|
|
}
|