feat(WEB): UniversalListPage 전체 마이그레이션 및 코드 정리

- UniversalListPage/IntegratedListTemplateV2 컴포넌트 기능 개선
- 회계, HR, 건설, 고객센터, 결재, 설정 등 전체 리스트 컴포넌트 마이그레이션
- 테스트 페이지 및 미사용 API 라우트 정리 (board-test, order-management-test 등)
- 미들웨어 토큰 갱신 로직 개선
- AuthenticatedLayout 구조 개선
- claudedocs 문서 업데이트

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
byeongcheolryu
2026-01-16 15:19:09 +09:00
parent 8639eee5df
commit ad493bcea6
90 changed files with 19864 additions and 20305 deletions

View File

@@ -1,97 +0,0 @@
import { NextRequest, NextResponse } from 'next/server';
/**
* PHP 백엔드 프록시 유틸리티
*
* 역할:
* - Next.js API Routes → PHP Backend 단순 프록시
* - HttpOnly 쿠키의 access_token을 Bearer token으로 전달
* - PHP 응답을 그대로 프론트엔드로 반환
*
* 보안:
* - tenant.id 검증은 PHP 백엔드에서 수행
* - Next.js는 단순히 요청/응답 전달만
*/
/**
* PHP 백엔드로 프록시 요청 전송
*
* @param request NextRequest 객체
* @param phpEndpoint PHP 백엔드 엔드포인트 (예: '/api/v1/tenants/282/item-master-config')
* @param options fetch options (method, body 등)
* @returns NextResponse
*/
export async function proxyToPhpBackend(
request: NextRequest,
phpEndpoint: string,
options?: RequestInit
): Promise<NextResponse> {
try {
// 1. 쿠키에서 access_token 추출
const accessToken = request.cookies.get('access_token')?.value;
if (!accessToken) {
return NextResponse.json(
{
success: false,
error: {
code: 'UNAUTHORIZED',
message: '인증이 필요합니다.',
},
},
{ status: 401 }
);
}
// 2. PHP 백엔드 URL 생성
const phpUrl = `${process.env.NEXT_PUBLIC_API_URL}${phpEndpoint}`;
// 3. PHP 백엔드 호출
const response = await fetch(phpUrl, {
...options,
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': `Bearer ${accessToken}`,
'X-API-KEY': process.env.API_KEY || '',
...options?.headers,
},
});
// 4. PHP 응답을 그대로 반환
const data = await response.json().catch(() => ({}));
return NextResponse.json(data, { status: response.status });
} catch (error) {
console.error('[PHP Proxy Error]', error);
return NextResponse.json(
{
success: false,
error: {
code: 'SERVER_ERROR',
message: '서버 오류가 발생했습니다.',
},
},
{ status: 500 }
);
}
}
/**
* Query Parameters를 URL에 추가하는 헬퍼
*
* @param baseUrl 기본 URL
* @param searchParams URLSearchParams
* @returns Query string이 추가된 URL
*/
export function appendQueryParams(baseUrl: string, searchParams: URLSearchParams): string {
const params = new URLSearchParams();
searchParams.forEach((value, key) => {
params.append(key, value);
});
const queryString = params.toString();
return queryString ? `${baseUrl}?${queryString}` : baseUrl;
}