/** * 파일 저장소 모듈 — 업로드 시 `POST /api/v1/common/file/upload/{moduleId}`의 경로 조각이자 * 백엔드 파일 저장 설정(`FileStrgStngVo.strgStngId`)의 키다. * * 값은 백엔드 저장소 설정 표에서 받은 실제 목록이다(사용자 제공, 2026-08-20). * * 이슈: 설정에 없는 값을 보내도 업로드가 실패하지 않는다. 백엔드가 설정을 못 찾으면 기본 * 저장소로 폴백해 조용히 다른 곳에 저장한다(`EgovFileMngUtil.parseFileInf`). 그래서 여기 없는 * 문자열을 손으로 적지 않는다. */ export type FileModule = { id: string; /** 저장소 설명 — 어떤 파일이 어디로 가는지 이 파일만 보고 알 수 있게 함께 둔다. */ description: string; /** 백엔드가 허용하는 확장자. 화면의 `accept`와 사전 검증이 같은 값을 본다. */ extensions: readonly string[]; }; const IMAGE = ['jpg', 'png', 'gif'] as const; export const FILE_MODULE = { /** 콘텐츠(금융쇼츠·4컷금융만화) 대표 이미지. */ contentThumbnail: { id: 'MODULE_CONTENT_THUMB', description: '콘텐츠 섬네일 이미지 저장소', extensions: IMAGE, }, /** 4컷금융만화의 컷 이미지. */ toonContent: { id: 'MODULE_TOON_CONTENT', description: '4컷 만화 파일 저장소', extensions: IMAGE, }, /** 금융쇼츠의 영상. */ vodContent: { id: 'MODULE_VOD_CONTENT', description: '동영상 콘텐츠 저장소', extensions: ['mp4', 'mov', 'avi', 'mkv', 'webm', 'wmv'], }, /** 꾸미기 아이템 썸네일. */ userItem: { id: 'MODULE_USER_ITEM', description: '사용자 아이템 저장소', extensions: ['jpg', 'png', 'gif', 'svg'], }, menuIcon: { id: 'MODULE_MENU_ICON', description: '메뉴 아이콘 저장소', extensions: ['jpg', 'png', 'gif', 'svg'], }, pocket: { id: 'MODULE_POCKET', description: '용돈기입장 사진 저장소', extensions: ['jpg', 'jpeg', 'png', 'gif'], }, studentImage: { id: 'MODULE_STUDENT_IMAGE', description: '학생 원본 이미지', extensions: IMAGE, }, userProfile: { id: 'MODULE_USER_PROFILE', description: '회원 프로필 저장소', extensions: IMAGE, }, } as const satisfies Record; // TODO: 게시판(공지사항·FAQ·1:1문의) 첨부용 저장소가 목록에 없다. 지금은 이 값이 설정에 없어 // 기본 저장소로 폴백해 저장된다 — 백엔드에 모듈 추가를 요청하고 그 id로 교체한다. export const BOARD_ATTACHMENT_MODULE_ID = 'MODULE_BBS'; /** 확장자 목록 → `` 값. 화면이 백엔드 허용 목록을 직접 베끼지 않게 한다. */ export function fileModuleAccept(module: FileModule): string { return module.extensions.map((extension) => `.${extension}`).join(','); } /** 파일명의 확장자가 저장소 허용 목록에 있는지. 백엔드가 사유 없이 실패하기 전에 먼저 잡는다. */ export function isAllowedFileExtension( module: FileModule, fileName: string ): boolean { const extension = fileName.split('.').pop()?.toLowerCase() ?? ''; return module.extensions.includes(extension); } /** 첨부파일 상한. 화면(사전 차단)과 Server Action(재검증)이 같은 값을 본다. */ export const MAX_ATTACHMENT_BYTES = 10 * 1024 * 1024;