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 |
세션 TTL 만료 (선택 구현) |
B. 실패 처리
| 시나리오 |
처리 방식 |
| 업로드 중 네트워크 끊김 |
세션 유지, tus 재개 허용 |
| 완료 후 검증 실패 |
UploadSession = FAILED, 임시 파일 삭제 |
| quota 초과 |
최종 확정 거부, 파일 반영 금지 |
| 파일 이동 성공 후 DB 저장 실패 |
고아 파일 정리 배치 또는 보상 로직 필요 |
| 완료 콜백 중복 호출 |
idempotency 보장 필요 |
C. 트랜잭션 경계
아래 순서는 원자성 보장이 중요하며, 메타데이터 반영은 하나의 트랜잭션으로 묶는 것을 권장한다. 파일 이동은 트랜잭션 외부에서 수행되므로 전후 보상 로직이 필요하다.
주의: 파일 이동 성공 후 트랜잭션 실패 시 고아 파일이 발생할 수 있으므로, 정기 정리 배치 또는 보상 트랜잭션을 설계해야 한다.
D. 보안 포인트
| 항목 |
내용 |
| 클라이언트 MIME 신뢰 금지 |
서버에서 직접 MIME 타입을 추정하여 사용 |
| 사용자 입력 파일명 검증 |
특수문자, 예약어, 인코딩 우회 등 검사 |
| Path Traversal 방지 |
../ 등 경로 탈출 시도 차단 |
| 내부 실제 경로 외부 노출 금지 |
storage_key와 응답 경로 분리 |
| 최종 저장 경로 격리 |
사용자 표시 폴더 구조와 실제 디스크 경로 분리 |