diff --git a/dashboards/admin-web/src/app/api/ai-diagnostics/[...path]/route.ts b/dashboards/admin-web/src/app/api/ai-diagnostics/[...path]/route.ts new file mode 100644 index 00000000..80da71b8 --- /dev/null +++ b/dashboards/admin-web/src/app/api/ai-diagnostics/[...path]/route.ts @@ -0,0 +1,42 @@ +/** + * AI Diagnostics API proxy — forwards requests to platform-service. + * + * GET/POST /api/ai-diagnostics/* → platform-service /api/ai-diagnostics/* + */ + +import { NextRequest, NextResponse } from 'next/server'; +import { getCurrentUserFromRequest } from '@/lib/auth-server'; +import { logError } from '@/lib/logger'; + +const PLATFORM_URL = process.env.PLATFORM_SERVICE_URL || 'http://localhost:4003'; + +async function proxy(req: NextRequest, { params }: { params: Promise<{ path: string[] }> }) { + try { + const caller = await getCurrentUserFromRequest(req); + if (!caller) return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }); + const { path } = await params; + const targetPath = `/api/ai-diagnostics/${path.join('/')}`; + const qs = new URL(req.url).search; + const headers: Record = { + 'Content-Type': 'application/json', + 'x-request-id': req.headers.get('x-request-id') || crypto.randomUUID(), + 'x-user-id': caller.id, + 'x-product-id': req.headers.get('x-product-id') || process.env.PRODUCT_ID || 'lysnrai', + }; + const fetchOptions: RequestInit = { method: req.method, headers }; + if (req.method !== 'GET' && req.method !== 'HEAD') fetchOptions.body = await req.text(); + const res = await fetch(`${PLATFORM_URL}${targetPath}${qs}`, fetchOptions); + const data = await res.json().catch(() => null); + return NextResponse.json(data ?? { error: res.statusText }, { status: res.status }); + } catch (error) { + logError('AI Diagnostics proxy error', error); + return NextResponse.json({ error: 'Service unavailable' }, { status: 502 }); + } +} + +export async function GET(req: NextRequest, ctx: { params: Promise<{ path: string[] }> }) { + return proxy(req, ctx); +} +export async function POST(req: NextRequest, ctx: { params: Promise<{ path: string[] }> }) { + return proxy(req, ctx); +} diff --git a/dashboards/admin-web/src/app/api/feedback/[...path]/route.ts b/dashboards/admin-web/src/app/api/feedback/[...path]/route.ts new file mode 100644 index 00000000..fd1ec51a --- /dev/null +++ b/dashboards/admin-web/src/app/api/feedback/[...path]/route.ts @@ -0,0 +1,45 @@ +/** + * Feedback API proxy — forwards requests to platform-service. + * + * GET/POST/DELETE /api/feedback/* → platform-service /api/feedback/* + */ + +import { NextRequest, NextResponse } from 'next/server'; +import { getCurrentUserFromRequest } from '@/lib/auth-server'; +import { logError } from '@/lib/logger'; + +const PLATFORM_URL = process.env.PLATFORM_SERVICE_URL || 'http://localhost:4003'; + +async function proxy(req: NextRequest, { params }: { params: Promise<{ path: string[] }> }) { + try { + const caller = await getCurrentUserFromRequest(req); + if (!caller) return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }); + const { path } = await params; + const targetPath = `/api/feedback/${path.join('/')}`; + const qs = new URL(req.url).search; + const headers: Record = { + 'Content-Type': 'application/json', + 'x-request-id': req.headers.get('x-request-id') || crypto.randomUUID(), + 'x-user-id': caller.id, + 'x-product-id': req.headers.get('x-product-id') || process.env.PRODUCT_ID || 'lysnrai', + }; + const fetchOptions: RequestInit = { method: req.method, headers }; + if (req.method !== 'GET' && req.method !== 'HEAD') fetchOptions.body = await req.text(); + const res = await fetch(`${PLATFORM_URL}${targetPath}${qs}`, fetchOptions); + const data = await res.json().catch(() => null); + return NextResponse.json(data ?? { error: res.statusText }, { status: res.status }); + } catch (error) { + logError('Feedback proxy error', error); + return NextResponse.json({ error: 'Service unavailable' }, { status: 502 }); + } +} + +export async function GET(req: NextRequest, ctx: { params: Promise<{ path: string[] }> }) { + return proxy(req, ctx); +} +export async function POST(req: NextRequest, ctx: { params: Promise<{ path: string[] }> }) { + return proxy(req, ctx); +} +export async function DELETE(req: NextRequest, ctx: { params: Promise<{ path: string[] }> }) { + return proxy(req, ctx); +} diff --git a/dashboards/admin-web/src/app/api/feedback/route.ts b/dashboards/admin-web/src/app/api/feedback/route.ts new file mode 100644 index 00000000..3507e91b --- /dev/null +++ b/dashboards/admin-web/src/app/api/feedback/route.ts @@ -0,0 +1,39 @@ +/** + * Feedback base route — handles GET /api/feedback. + * Maps to platform-service GET /api/feedback. + */ + +import { NextRequest, NextResponse } from 'next/server'; +import { getCurrentUserFromRequest } from '@/lib/auth-server'; +import { logError } from '@/lib/logger'; + +const PLATFORM_URL = process.env.PLATFORM_SERVICE_URL || 'http://localhost:4003'; + +async function proxyBase(req: NextRequest) { + try { + const caller = await getCurrentUserFromRequest(req); + if (!caller) return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }); + const qs = new URL(req.url).search; + const headers: Record = { + 'Content-Type': 'application/json', + 'x-request-id': req.headers.get('x-request-id') || crypto.randomUUID(), + 'x-user-id': caller.id, + 'x-product-id': req.headers.get('x-product-id') || process.env.PRODUCT_ID || 'lysnrai', + }; + const fetchOptions: RequestInit = { method: req.method, headers }; + if (req.method !== 'GET' && req.method !== 'HEAD') fetchOptions.body = await req.text(); + const res = await fetch(`${PLATFORM_URL}/api/feedback${qs}`, fetchOptions); + const data = await res.json().catch(() => null); + return NextResponse.json(data ?? { error: res.statusText }, { status: res.status }); + } catch (error) { + logError('Feedback base proxy error', error); + return NextResponse.json({ error: 'Service unavailable' }, { status: 502 }); + } +} + +export async function GET(req: NextRequest) { + return proxyBase(req); +} +export async function POST(req: NextRequest) { + return proxyBase(req); +}