export const dynamic = "force-dynamic"; import { SITE_ID } from "@/src/shared/config"; import { normalizeSelectData } from "@/app/store/common/code/normalizeSelectData"; import { NextResponse } from "next/server"; export const revalidate = 86400; //60 * 60 * 24; type SelectDataType = { text: string; val: string; }; type EnvPartSelectDataType = SelectDataType & { adstDliStrCd: string; }; const codeMapping = { WR001: "bdstUsgCd", WR002: "rswtBdstType", WR003: "rainFcltCd", WR004: "bdstGrntchClass", WR005: "rswtPrscCdMthdCd", WR006: "orgwtKndCd", WR007: "ruseMngMtd", WR008: "rusePrcsMthdCd", WR009: "erctUswtrPrcsMeth", WR010: "ruseFcltSpot", WR011: "pplQulity", WR012: "pplLenght", WR013: "bdstFilterYn", WR014: "rainRswtMng", WR015: "rainFcltFlowRate", WR016: "dmdUszCd", WR017: "sewageInFcltUse", WR018: "sewageOutFclttUse", WR019: "htdPowerMthdCd", WR020: "htdUtztnUsgCd", } as const; const defaultHeaders = { accept: "application/json", "X-Site-Id": SITE_ID, }; function getServerBaseUrl() { const port = process.env.PORT ?? process.env.NEXT_PUBLIC_PORT ?? "3000"; const proxyHost = process.env.NEXT_PUBLIC_PROXY_HOST; if (process.env.NODE_ENV === "production" && process.env.HOSTNAME) { return `http://${process.env.HOSTNAME}:${port}`; } return proxyHost || `http://localhost:${port}`; } async function fetchJson(url: string, cookieHeader?: string) { const response = await fetch(url, { method: "GET", headers: { ...defaultHeaders, ...(cookieHeader ? { cookie: cookieHeader } : {}), }, next: { revalidate }, }); if (!response.ok) { const responseText = await response.text(); throw new Error( `Failed to fetch ${url}: ${response.status} ${response.statusText}${ responseText ? ` - ${responseText}` : "" }` ); } return response.json(); } async function fetchOperationData(path: string, cookieHeader?: string) { const json = await fetchJson( `${getServerBaseUrl()}/operation-service${path}`, cookieHeader ); return json.data; } async function fetchCmsData(path: string, cookieHeader?: string) { return fetchJson(`${getServerBaseUrl()}${path}`, cookieHeader); } async function fetchCommonCodesByKeys(keys: string[], cookieHeader?: string) { const targets = [...new Set(keys)].filter( (cd) => Boolean(codeMapping[cd as keyof typeof codeMapping]) ); const entries = await Promise.all( targets.map(async (cd) => { const mapping = codeMapping[cd as keyof typeof codeMapping]; const lwCd = await fetchCmsData( `/cms-service/api/v1/lwpo-cds/up-cd/${cd}`, cookieHeader ); const list = Array.isArray(lwCd) ? lwCd : (lwCd.content ?? []); return [ mapping, list.map((it: any) => ({ text: it.lwpoCdNm, val: it.lwpoCd, })), ] as const; }) ); return Object.fromEntries(entries) as Record; } export async function GET(request: Request) { try { const cookieHeader = request.headers.get("cookie") ?? ""; const [sgg, city, rvbsn, mdmbsn, lgbsn, lclgvrnmnt, upCd] = await Promise.all([ fetchOperationData("/addr/sgg", cookieHeader), fetchOperationData("/addr/city", cookieHeader), fetchOperationData("/addr/sarea", cookieHeader), fetchOperationData("/addr/midArea", cookieHeader), fetchOperationData("/addr/largeArea", cookieHeader), fetchOperationData("/addr/govArea", cookieHeader), fetchCmsData( "/cms-service/api/v1/up-codes?keyword=&upCd=&cdSe=&useYn=Y&siteId=WR&page=0&size=100&sort=string", cookieHeader ), ]); const upWrCode: string[] = (upCd.content ?? []) .filter((item: any) => item.upCd.slice(0, 2) === "WR") .map((cd: any) => cd.upCd); const lwCds = await fetchCommonCodesByKeys(upWrCode, cookieHeader); const payload = { sggCd: [ ...((sgg ?? []).map((item: any) => ({ text: item.gugun || "", val: String(item.adstDstrCd) || "", })) as SelectDataType[]), ], cityCd: normalizeSelectData( (city ?? []).map((item: any) => ({ val: item.adstDstrCd, text: item.sido, })), ), rvbsnCd: [ { val: "0", text: "전체" }, ...((rvbsn ?? []).map((item: any) => ({ val: item.rvbsnCd, text: item.rvbsn, })) as SelectDataType[]), ], mdmbsnCd: [ { val: "0", text: "전체" }, ...((mdmbsn ?? []).map((item: any) => ({ val: item.rvbsnCd, text: item.mdmbsn, })) as SelectDataType[]), ], lgbsnCd: [ { val: "0", text: "전체" }, ...((lgbsn ?? []).map((item: any) => ({ val: item.rvbsnCd, text: item.lgbsn, })) as SelectDataType[]), ], lclgvrnmntCd: [ { val: "0", text: "전체", adstDliStrCd: "" }, ...((lclgvrnmnt ?? []).map((item: any) => ({ val: item.lclgvrnmntCd, text: item.lclgvrnmntNm, adstDliStrCd: item.adstDliStrCd || "", })) as EnvPartSelectDataType[]), ], rainFcltCd: lwCds["rainFcltCd"] ?? [], bdstUsgCd: lwCds["bdstUsgCd"] ?? [], orgwtKndCd: lwCds["orgwtKndCd"] ?? [], pplQulity: lwCds["pplQulity"] ?? [], pplLenght: lwCds["pplLenght"] ?? [], dmdUszCd: lwCds["dmdUszCd"] ?? [], sewageOutFclttUse: lwCds["sewageOutFclttUse"] ?? [], rainRswtMng: lwCds["rainRswtMng"] ?? [], rainFcltFlowRate: lwCds["rainFcltFlowRate"] ?? [], ruseMngMtd: lwCds["ruseMngMtd"] ?? [], rusePrcsMthdCd: lwCds["rusePrcsMthdCd"] ?? [], erctUswtrPrcsMeth: lwCds["erctUswtrPrcsMeth"] ?? [], bdstGrntchClass: lwCds["bdstGrntchClass"] ?? [], htdPowerMthdCd: lwCds["htdPowerMthdCd"] ?? [], htdUtztnUsgCd: lwCds["htdUtztnUsgCd"] ?? [], rswtBdstType: lwCds["rswtBdstType"] ?? [], bdstTotalUsgType: (lwCds["bdstUsgCd"] ?? []).concat(lwCds["rswtBdstType"] ?? []), }; return NextResponse.json(payload, { headers: { "Cache-Control": "s-maxage=86400, stale-while-revalidate=3600", }, }); } catch (error) { console.error("Failed to load common codes:", error); const message = error instanceof Error ? error.message : "Failed to load common codes"; return NextResponse.json( { message: "Failed to load common codes", detail:message , }, { status: 500 } ); } }