feat: 품목관리 파일 업로드 기능 개선

- 파일 업로드 API에 field_key, file_id 파라미터 추가
- ItemMaster 타입에 files 필드 추가 (새 API 구조 지원)
- DynamicItemForm에서 files 객체 파싱 로직 추가
- 시방서/인정서 파일 UI 개선: 파일명 표시 + 다운로드/수정/삭제 버튼
- 기존 API 구조와 새 API 구조 모두 지원 (폴백 처리)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
byeongcheolryu
2025-12-12 18:35:43 +09:00
parent ded0bc2439
commit c026130a65
19 changed files with 772 additions and 331 deletions

View File

@@ -16,6 +16,22 @@ export class ApiError extends Error {
}
}
/**
* 품목코드 중복 에러 클래스
* - 백엔드에서 400 에러와 함께 duplicate_id, duplicate_code 반환 시 사용
* - 2025-12-11: 백엔드 DuplicateCodeException 대응
*/
export class DuplicateCodeError extends ApiError {
constructor(
public message: string,
public duplicateId: number,
public duplicateCode: string
) {
super(400, message);
this.name = 'DuplicateCodeError';
}
}
/**
* API 응답 에러를 처리하고 ApiError를 throw
* @param response - fetch Response 객체
@@ -25,9 +41,15 @@ export const handleApiError = async (response: Response): Promise<never> => {
const data = await response.json().catch(() => ({}));
// 401 Unauthorized - 토큰 만료 또는 인증 실패
// ✅ 자동 리다이렉트 제거: 각 페이지에서 에러를 직접 처리하도록 변경
// 이를 통해 개발자가 Network 탭에서 에러를 확인할 수 있음
// ✅ 자동으로 로그인 페이지로 리다이렉트
if (response.status === 401) {
console.warn('⚠️ 401 Unauthorized - 로그인 페이지로 이동합니다.');
// 클라이언트 사이드에서만 리다이렉트
if (typeof window !== 'undefined') {
window.location.href = '/login';
}
throw new ApiError(
401,
data.message || '인증이 필요합니다. 로그인 상태를 확인해주세요.',
@@ -44,6 +66,21 @@ export const handleApiError = async (response: Response): Promise<never> => {
);
}
// 400 Bad Request - 품목코드 중복 에러 체크
// 백엔드 DuplicateCodeException이 duplicate_id, duplicate_code 반환
if (response.status === 400 && data.duplicate_id) {
console.warn('⚠️ 품목코드 중복 감지:', {
duplicateId: data.duplicate_id,
duplicateCode: data.duplicate_code,
message: data.message
});
throw new DuplicateCodeError(
data.message || '해당 품목코드가 이미 존재합니다.',
data.duplicate_id,
data.duplicate_code
);
}
// 422 Unprocessable Entity - Validation 에러
if (response.status === 422) {
// 상세 validation 에러 로그 출력