WI-...-028~033 에 대응하는 FE-OC-027~032 owner 노트.
- 각 노트의 제외 범위에 'use case·domain model·business rule' 을 명시해
이 skeleton 이 port 와 adapter 계약까지임을 못박았다
- 근거 절에 '근거 등급 경계' 문단을 넣어 project-local default 와
외부 근거를 구분했다 (수집은 FE-Q-011~014 가 소유)
- 구현 가이드 절은 비워 두고 사유를 남겼다 — 근거 raw 없이 채우면
모든 cell 이 UNSUPPORTED_IMPL_DECISION 이 된다
- multi-protocol 노트는 '신규 port 0개' 를 제외 범위에 명시했다.
port 가 늘어나면 그 자체가 회귀 신호다
파일 선택·다운로드·로컬 바이너리 저장은 등록된 port를 MUST 경유하고, 원시 File/Blob handle과 object URL 수명은 adapter 경계를 MUST NOT 벗어남
DELEG-FE-008 로 handle 수명을 위임
수신한 위임
없음. 이 branch 는 DELEG-FE-008 의 delegator 다.
가져온 흐름 단계
Stage Ref
Order
Owner
Input
Action
Output
목표
UploadTransferPort 와 StreamingDownloadPort 를 정의하고, presigned URL 획득과 byte 전송 사이의 credential 경계를 고정한다. 이 계약이 없으면 presigned URL 로 나가는 요청에 session 헤더가 그대로 붙어 제3자 스토리지 도메인에 인증 정보가 전달된다. 재개 가능 전송의 part 상태 소유자도 함께 고정한다.
이슈:
PR:
범위
포함 범위
UploadTransferPort — presign 결과 소비, part 분할·병렬·재시도, 진행 스트림, 취소
StreamingDownloadPort — ReadableStream 소비, range/resume, 진행 스트림
credential-less transfer transport 와 그 경계의 negative fixture
무결성 검증(체크섬·크기)과 TRANSFER_INTEGRITY_MISMATCH
MediaUrlPolicy — CDN base·허용 transform 기반 URL 파생 (순수 함수)
§9.6 전송 진행 surface state
CAP_FE_LARGE_TRANSFER capability 행 소유
제외 범위
use case, domain model, business rule — port 와 adapter 계약까지만 정의한다
backend 의 presign 발급 endpoint 설계와 서명 알고리즘
object storage vendor 선택과 그 제약(part 최소 크기·만료) — FE-Q-012
근거 등급 경계: FE-D029(credential 경계)의 rationale 은 credential 유출 방지 invariant, project decision 이고 FE-D030(part 정책)은 project-local default, 외부 source claim 아님 이다. presigned URL·multipart 의 vendor 별 제약을 다룬 raw 자료는 없으며 FE-Q-012 가 수집을 소유한다. part size 8 MiB·병렬도 3 은 측정값이 아니라 초기 default 다.
TODO
UploadTransferPort·StreamingDownloadPort 인터페이스 확정 — 등급: planned
credential-less transport 분리와 negative fixture — 등급: planned
presign 만료 감지와 재획득 1회 경로 — 등급: planned
part 재시도 상한(≤2)과 상태 보존 — 등급: planned
무결성 검증과 불일치 시 재전송 1회 — 등급: planned
range 기반 다운로드 재개 — 등급: planned
MediaUrlPolicy 순수 함수와 허용 transform 강제 — 등급: planned
FE-GATE-029 transfer report 산출 — 등급: planned
진행 중 메모
PRESIGN_SAMPLE_UPLOAD 는 FE-REG-API 에 등록되지만 실제 byte 전송 대상 URL 은 registry 에 등록하지 않는다. registry 는 우리 backend 의 operation 장부이고, presigned URL 은 제3자 도메인의 일회용 주소이기 때문이다. 이 비대칭이 FE-OC-006("모든 HTTP 는 shared client 경유")의 유일한 선언적 예외이며, 예외라는 사실 자체를 §범위에 남긴다.
결정 사항
2026-07-28: transfer adapter 가 shared client interceptor 를 재사용하지 않음 / 이유: interceptor 체인에 auth 첨부가 있으면 제3자 URL 로 새어나감 / 검토한 대안: interceptor 에 skip 플래그 추가 / 근거: FE-D029
2026-07-28: MediaUrlPolicy 를 port 로 만들지 않음 / 이유: URL 파생에 I-O 가 없어 port 로 만들면 test double 만 늘어남 / 검토한 대안: MediaUrlPort / 근거: 설계문서 §5.2
결정-근거 매핑
Decision ID
Decision
선택 조건 (언제 이 결정 / 언제 대안)
Supporting Claims
Evidence Strength
Open Risk
D1
별도 transport 로 credential 분리
항상. 스토리지가 same-origin proxy 만 제공하면 FE-D029 재검토
없음 — FE-Q-011, FE-Q-012
project decision
두 transport 의 timeout·retry 정책이 갈라질 수 있음
D2
presigned URL 을 어디에도 남기지 않음
항상
없음 — FE-Q-011
project-local default
디버깅이 어려워짐. 실패 시 operation ID 만으로 추적 가능해야 함
D3
MediaUrlPolicy 는 순수 함수
항상. CDN 이 서명된 URL 을 요구하면 port 로 승격 재검토
없음 — FE-Q-011
project-local default
서명 필요 CDN 을 만나면 설계가 바뀜
구현 가이드
근거 raw 자료(FE-Q-011, FE-Q-012) 수집 전까지 비워 둔다. 특히 part size·병렬도·만료 처리는 storage vendor 제약에 직접 의존하므로, vendor 확정 전에 쓰면 전부 UNSUPPORTED_IMPL_DECISION 이 된다.
엣지·실패·의존
실패·엣지 경로
presigned URL 만료 → PRESIGN_EXPIRED, 재획득 1회 후 같은 위치에서 재개. 재획득도 실패하면 사용자 주도 retry
part 재시도 상한 소진 → UPLOAD_PART_FAILED, part 상태 보존 후 transfer-paused
체크섬/크기 불일치 → TRANSFER_INTEGRITY_MISMATCH, 해당 part 폐기 후 재전송 1회, 재실패면 terminal
다운로드 스트림 중단 → STREAM_INTERRUPTED, resumeStrategy: range 면 받은 범위부터 재개
사용자 취소 → REQUEST_ABORTED 재사용, part 상태 폐기 여부를 명시
UPLOAD_PART_STATE 저장 실패 → BLOB_STORE_UNAVAILABLE. 이 행은 fallback 이 없으므로 전송을 재개 불가로 표시하고 조용히 memory 로 넘어가지 않음