## 1. 업로드 준비 단계 ### 1-1. 클라이언트가 업로드 대상 폴더를 선택한다 클라이언트는 업로드 요청 시 아래 정보를 서버에 전달한다. |항목|설명| |---|---| |`targetFolderId`|업로드 대상 폴더 식별자| |원본 파일명|사용자가 선택한 파일의 이름| |파일 크기|바이트 단위 파일 크기| |클라이언트 MIME 타입|브라우저가 판단한 MIME 타입 (신뢰 금지)| |체크섬 정보|(선택) 무결성 검증용 해시값| ### 1-2. 서버가 사용자 인증 및 권한을 검증한다 - 로그인 여부 확인 - 대상 폴더에 대한 쓰기 권한 확인 - 타 사용자 폴더 접근 차단 ### 1-3. 서버가 업로드 사전 검증을 수행한다 - 파일명 규칙 검증 - 허용 최대 크기 검증 - 확장자 / 업로드 정책 검증 - 사용자 quota 사전 검사 - 동일 폴더 내 중복 이름 정책 검사 ### 1-4. 서버가 업로드 대상 폴더를 검증한다 - 폴더 존재 여부 확인 - 삭제 상태 여부 확인 - 업로드 가능 상태 여부 확인 --- ## 2. 업로드 세션 생성 단계 ### 2-1. 서버가 `UploadSession`을 생성한다 |항목|내용| |---|---| |상태|`CREATED`| |업로드 대상 폴더 ID|`targetFolderId` 저장| |파일 정보|원본 파일명 / 예상 크기 저장| |임시 저장 경로|임시 저장 경로 또는 임시 키 발급| |tus 매핑|tus 업로드 식별자 매핑 준비| ### 2-2. 서버가 클라이언트에 tus 업로드 정보를 반환한다 - 업로드 URL - 업로드 세션 ID - 재개에 필요한 메타데이터 --- ## 3. 파일 전송 단계 ### 3-1. 클라이언트가 tus 프로토콜로 청크 업로드를 시작한다 - 청크 단위 전송 - 오프셋 검증 - 중단 시 재개 가능 - 서버는 진행 상태를 `UploadSession.received_size` 등에 반영 --- ## 4. 업로드 완료 확정 단계 ### 4-1. 서버가 업로드 완료 이벤트 또는 콜백을 수신한다 - tus 훅 또는 완료 엔드포인트 기반 처리 - 동일 세션에 대한 중복 완료 요청 방지 필요 (idempotency) ### 4-2. 서버가 임시 업로드 파일을 최종 검증한다 - 실제 파일 크기 검증 - MIME 타입 서버 측 추정 (클라이언트 값 신뢰 금지) - 손상 여부 또는 체크섬 검증 (선택) - quota 최종 재검사 - 위험 파일 정책 검사 (필요 시) ### 4-3. 서버가 최종 저장 경로를 결정하고 파일을 이동한다 - `storage_key` 생성 - 임시 경로 → 최종 object 경로로 **원자적 이동** - 사용자 표시 경로와 실제 디스크 경로는 분리 ### 4-4. 서버가 `FileItem` 메타데이터를 생성한다 |필드|설명| |---|---| |`display_name`|사용자에게 표시되는 파일명| |`folder_id`|소속 폴더 ID| |`mime_type`|서버 측 추정 MIME 타입| |`size_bytes`|실제 파일 크기| |`storage_key`|내부 저장 경로 식별자| |`preview_status`|초기값 `PENDING`| |사용자 사용량|`storage_used_bytes` 갱신 (필요 시)| ### 4-5. 서버가 `UploadSession` 상태를 완료로 변경한다 |항목|내용| |---|---| |상태|`COMPLETED`| |완료 시각|기록| |`file_id`|최종 생성된 `FileItem`과 연결| --- ## 5. 후처리 단계 ### 5-1. 서버가 후처리 작업을 비동기로 등록한다 |작업|유형| |---|---| |이미지 썸네일 생성|동기 또는 큐 기반| |텍스트 / PDF 미리보기 캐시 생성|큐 기반| |바이러스 스캔|후속 비동기| |검색 인덱싱|후속 비동기| |감사 로그 기록|동기 또는 큐 기반| ### 5-2. 서버가 클라이언트에 업로드 완료 응답을 반환한다 - 생성된 `FileItem` 정보 - 목록 갱신에 필요한 최소 메타데이터 - 프론트엔드는 현재 폴더 목록을 갱신 --- ## 6. 보강 포인트 ### A. 상태 전이 `UploadSession`의 상태는 아래와 같이 전이한다. ``` CREATED → UPLOADING → COMPLETED ↘ FAILED ↘ ABORTED ↘ EXPIRED (선택) ``` |상태|설명| |---|---| |`CREATED`|세션 생성 완료, 아직 전송 시작 전| |`UPLOADING`|청크 전송 진행 중| |`COMPLETED`|모든 검증 및 저장 완료| |`FAILED`|완료 후 검증 실패 또는 저장 오류| |`ABORTED`|클라이언트 또는 서버 측 명시적 중단| |`EXPIRED`|세션 TTL 만료 (선택 구현)| --- ### B. 실패 처리 |시나리오|처리 방식| |---|---| |업로드 중 네트워크 끊김|세션 유지, tus 재개 허용| |완료 후 검증 실패|`UploadSession = FAILED`, 임시 파일 삭제| |quota 초과|최종 확정 거부, 파일 반영 금지| |파일 이동 성공 후 DB 저장 실패|고아 파일 정리 배치 또는 보상 로직 필요| |완료 콜백 중복 호출|idempotency 보장 필요| --- ### C. 트랜잭션 경계 아래 순서는 원자성 보장이 중요하며, 메타데이터 반영은 하나의 트랜잭션으로 묶는 것을 권장한다. 파일 이동은 트랜잭션 외부에서 수행되므로 전후 보상 로직이 필요하다. ``` 1. 임시 파일 검증 2. 최종 파일 이동 ← 트랜잭션 외부 (파일시스템 작업) ──────────────────────────── 트랜잭션 시작 3. FileItem 생성 4. 사용자 사용량 갱신 5. UploadSession 완료 처리 ──────────────────────────── 트랜잭션 커밋 ``` > **주의:** 파일 이동 성공 후 트랜잭션 실패 시 고아 파일이 발생할 수 있으므로, 정기 정리 배치 또는 보상 트랜잭션을 설계해야 한다. --- ### D. 보안 포인트 |항목|내용| |---|---| |클라이언트 MIME 신뢰 금지|서버에서 직접 MIME 타입을 추정하여 사용| |사용자 입력 파일명 검증|특수문자, 예약어, 인코딩 우회 등 검사| |Path Traversal 방지|`../` 등 경로 탈출 시도 차단| |내부 실제 경로 외부 노출 금지|`storage_key`와 응답 경로 분리| |최종 저장 경로 격리|사용자 표시 폴더 구조와 실제 디스크 경로 분리|