Move business logic out of App Router into module packages, add boundary validation scripts, and keep all routes as thin re-exports without changing URLs or API behavior. Co-authored-by: Cursor <cursoragent@cursor.com>
97 lines
2.5 KiB
TypeScript
97 lines
2.5 KiB
TypeScript
import { NextRequest, NextResponse } from "next/server";
|
|
|
|
/**
|
|
* Same-origin BFF proxy → beauty business service.
|
|
* Browser calls /api/beauty-business/* so TLS/CORS/DNS issues
|
|
* do not block CRUD from the SuperApp origin.
|
|
*/
|
|
const UPSTREAM =
|
|
process.env.BEAUTY_BUSINESS_SERVICE_URL ||
|
|
process.env.NEXT_PUBLIC_BEAUTY_BUSINESS_API_URL ||
|
|
"http://localhost:8011";
|
|
|
|
async function proxy(req: NextRequest, pathSegments: string[]) {
|
|
const path = pathSegments.join("/");
|
|
const url = new URL(req.url);
|
|
const target = `${UPSTREAM.replace(/\/$/, "")}/${path}${url.search}`;
|
|
|
|
const headers = new Headers();
|
|
const pass = ["authorization", "content-type", "x-tenant-id", "accept"];
|
|
for (const h of pass) {
|
|
const v = req.headers.get(h);
|
|
if (v) headers.set(h, v);
|
|
}
|
|
|
|
let body: ArrayBuffer | undefined;
|
|
if (req.method !== "GET" && req.method !== "HEAD") {
|
|
body = await req.arrayBuffer();
|
|
}
|
|
|
|
try {
|
|
const res = await fetch(target, {
|
|
method: req.method,
|
|
headers,
|
|
body,
|
|
cache: "no-store",
|
|
});
|
|
const outHeaders = new Headers();
|
|
const ct = res.headers.get("content-type");
|
|
if (ct) outHeaders.set("content-type", ct);
|
|
return new NextResponse(await res.arrayBuffer(), {
|
|
status: res.status,
|
|
headers: outHeaders,
|
|
});
|
|
} catch (err) {
|
|
const detail = err instanceof Error ? err.message : "upstream_unreachable";
|
|
return NextResponse.json(
|
|
{
|
|
error: {
|
|
code: "beauty_business_proxy_error",
|
|
message: `پروکسی زیبایی به ${UPSTREAM} وصل نشد — ${detail}`,
|
|
},
|
|
},
|
|
{ status: 502 }
|
|
);
|
|
}
|
|
}
|
|
|
|
export async function GET(
|
|
req: NextRequest,
|
|
ctx: { params: Promise<{ path: string[] }> }
|
|
) {
|
|
const { path } = await ctx.params;
|
|
return proxy(req, path);
|
|
}
|
|
|
|
export async function POST(
|
|
req: NextRequest,
|
|
ctx: { params: Promise<{ path: string[] }> }
|
|
) {
|
|
const { path } = await ctx.params;
|
|
return proxy(req, path);
|
|
}
|
|
|
|
export async function PATCH(
|
|
req: NextRequest,
|
|
ctx: { params: Promise<{ path: string[] }> }
|
|
) {
|
|
const { path } = await ctx.params;
|
|
return proxy(req, path);
|
|
}
|
|
|
|
export async function PUT(
|
|
req: NextRequest,
|
|
ctx: { params: Promise<{ path: string[] }> }
|
|
) {
|
|
const { path } = await ctx.params;
|
|
return proxy(req, path);
|
|
}
|
|
|
|
export async function DELETE(
|
|
req: NextRequest,
|
|
ctx: { params: Promise<{ path: string[] }> }
|
|
) {
|
|
const { path } = await ctx.params;
|
|
return proxy(req, path);
|
|
}
|