refactor(WEB): 코드 품질 개선 및 불필요 코드 제거

- 미사용 import/변수/console.log 대량 정리 (100+개 파일)
- ItemMasterContext 간소화 (미사용 로직 제거)
- IntegratedListTemplateV2 / UniversalListPage 개선
- 결재 컴포넌트(ApprovalBox, DraftBox, ReferenceBox) 정리
- HR 컴포넌트(급여/휴가/부서) 코드 간소화
- globals.css 스타일 정리 및 개선
- AuthenticatedLayout 개선
- middleware CSP 정리
- proxy route 불필요 로깅 제거

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
유병철
2026-02-10 20:55:11 +09:00
parent 437d5f6834
commit 0db6302652
138 changed files with 779 additions and 1034 deletions

View File

@@ -61,7 +61,6 @@ export async function authenticatedFetch(
}
// 4. 401 + refresh_token 있음 → 갱신 시도 (globalThis 캐시로 중복 방지)
console.log(`🔄 [${caller}] Got 401, attempting token refresh...`);
const refreshResult = await refreshAccessToken(refreshToken, caller);
if (!refreshResult.success || !refreshResult.accessToken) {
@@ -70,7 +69,6 @@ export async function authenticatedFetch(
}
// 5. 새 토큰으로 재시도
console.log(`✅ [${caller}] Token refreshed, retrying...`);
const retryHeaders = new Headers(options.headers || {});
retryHeaders.set('Authorization', `Bearer ${refreshResult.accessToken}`);
@@ -79,7 +77,6 @@ export async function authenticatedFetch(
headers: retryHeaders,
});
console.log(`🔵 [${caller}] Retry status: ${retryResponse.status}`);
// 6. 재시도도 401 → 인증 실패
if (retryResponse.status === 401) {

View File

@@ -208,7 +208,6 @@ export async function withTokenRefresh<T>(
// If 401 and token refresh needed, try refreshing
if (apiError.status === 401 && apiError.needsTokenRefresh && maxRetries > 0) {
console.log('🔄 Attempting token refresh...');
// Call refresh endpoint
const refreshResponse = await fetch('/api/auth/refresh', {
@@ -217,7 +216,6 @@ export async function withTokenRefresh<T>(
});
if (refreshResponse.ok) {
console.log('✅ Token refreshed, retrying API call');
// Retry the original API call
return withTokenRefresh(apiCall, maxRetries - 1);
} else {

View File

@@ -27,7 +27,6 @@ async function clearTokenCookies() {
cookieStore.delete('token_refreshed_at');
cookieStore.delete('is_authenticated');
console.log('🗑️ [serverFetch] 토큰 쿠키 삭제 완료');
}
/**
@@ -58,7 +57,6 @@ async function setNewTokenCookies(tokens: {
path: '/',
maxAge: 60, // 1분 후 자동 삭제
});
console.log('🔔 [setNewTokenCookies] token_refreshed_at 신호 쿠키 설정');
}
if (tokens.refreshToken) {

View File

@@ -80,7 +80,6 @@ class ServerApiClient {
cookieStore.delete('refresh_token');
cookieStore.delete('token_refreshed_at');
cookieStore.delete('is_authenticated');
console.log('🗑️ [ServerApiClient] 토큰 쿠키 삭제 완료');
}
/**

View File

@@ -160,7 +160,6 @@ export async function fetchItems(
const result = await response.json();
// 디버깅: API 응답 구조 확인
console.log('[fetchItems] API 응답:', JSON.stringify(result, null, 2).slice(0, 1000));
// 데이터 추출
let rawItems: ApiItemResponse[] = [];
@@ -180,19 +179,9 @@ export async function fetchItems(
rawItems = result;
}
// 디버깅: rawItems 첫 번째 항목 확인
if (rawItems.length > 0) {
console.log('[fetchItems] rawItems[0]:', rawItems[0]);
}
// snake_case → camelCase 변환
const transformed = rawItems.map(transformItemFromApi);
// 디버깅: 변환된 첫 번째 항목 확인
if (transformed.length > 0) {
console.log('[fetchItems] transformed[0]:', transformed[0]);
}
return transformed;
}
@@ -810,7 +799,6 @@ export async function fetchItemPrices(
}
const result = await response.json();
console.log('[fetchItemPrices] API 응답:', result);
if (result.success && result.data) {
return result.data as Record<string, ItemPriceResult>;

View File

@@ -51,11 +51,6 @@ const REFRESH_CACHE_TTL = 5000; // 5초
async function doRefreshToken(refreshToken: string): Promise<RefreshResult> {
try {
const refreshUrl = `${process.env.NEXT_PUBLIC_API_URL}/api/v1/refresh`;
console.log('🔄 [RefreshToken] Refresh request:', {
url: refreshUrl,
hasApiKey: !!process.env.API_KEY,
refreshTokenLength: refreshToken?.length,
});
const response = await fetch(refreshUrl, {
method: 'POST',
@@ -80,7 +75,6 @@ async function doRefreshToken(refreshToken: string): Promise<RefreshResult> {
}
const data = await response.json();
console.log('✅ [RefreshToken] Token refreshed successfully');
return {
success: true,
@@ -114,25 +108,21 @@ export async function refreshAccessToken(
// 1. 캐시된 성공 결과가 유효하면 즉시 반환
if (cache.result && cache.result.success && now - cache.timestamp < REFRESH_CACHE_TTL) {
console.log(`🔵 [${caller}] Using cached refresh result (age: ${now - cache.timestamp}ms)`);
return cache.result;
}
// 2. 진행 중인 refresh가 있고, 아직 결과가 없으면 기다림 (실패한 결과는 캐시 안 함)
if (cache.promise && !cache.result && now - cache.timestamp < REFRESH_CACHE_TTL) {
console.log(`🔵 [${caller}] Waiting for ongoing refresh...`);
return cache.promise;
}
// 2-1. 이전 refresh가 실패했으면 캐시 초기화
if (cache.result && !cache.result.success) {
console.log(`🔄 [${caller}] Previous refresh failed, clearing cache...`);
cache.promise = null;
cache.result = null;
}
// 3. 새 refresh 시작
console.log(`🔄 [${caller}] Starting new refresh request...`);
cache.timestamp = now;
cache.result = null;