Skip to content

feat(uploads): say when an upload expires - #1049

Merged
yeongseon merged 1 commit into
mainfrom
feat/issue-1047-upload-expires-at
Oct 6, 2026
Merged

yeongseon merged 1 commit into
mainfrom
feat/issue-1047-upload-expires-at

Conversation

@Eomdahyeon

Copy link
Copy Markdown
Collaborator

Closes #1047

#1046 리뷰에서 요청하신 후속이다: 보관 기간이 업로드를 지우는데 사용자가 언제인지 미리 알 방법이 없었다.

변경

  • service/uploads_service.py: 업로드 메타데이터에 expires_at. created_at + 지금 적용 중인 보관 일수이고, 정리가 쓰는 것과 같은 경계다. 아무것도 지우지 않는 경우 — 단일 사용자 배포, 보관을 끈 배포 — 에는 null. 키는 항상 있다.
    • POST /uploads 의 응답과 GET /uploads/{upload_id} 둘 다.
    • 답할 때 계산한다. 운영자가 보관 일수를 바꾸면 날짜도 바뀐다 — 저장해 두면 실제 삭제 시점과 어긋난다.
  • 계약 1.86.0 (additive): UploadMetadata.expires_at (string | null, 필수 아님), 업로드 예시에 값 하나.
  • CHANGELOG.

테스트 (tests/unit/test_upload_limits.py)

  • 업로드 응답의 expires_at - created_at 이 30일이고, 다시 조회해도 같다. 보관 일수를 7로 바꾸면 7일이다.
  • 필드가 말하는 시점과 정리가 실제로 지우는 시점이 같다: 29일 된 업로드는 expires_at 이 미래이고 정리에 남고, 31일 된 업로드는 expires_at 이 과거이고 정리에 지워진다.
  • 보관을 끄면 null(키는 있다). 단일 사용자 배포에서도 null.

검증

  • pytest tests/unit -k "upload or contract or fixture or file_source or preview" → 808 passed, 1 skipped.
  • check_contract_compat.py --base origin/main → contract compatible with origin/main: 1.85.0 -> 1.86.0.
  • Studio main 의 contractDrift.test.ts 를 이 계약으로 → Tests 579 passed (579). 새 필드는 additive 이고 이름 붙은 오류 예시가 없어 Studio 쪽 선행 변경이 필요 없다.
  • ruff, mypy src 통과. 전체 스위트는 CI 에 맡긴다.

작업 중 실수 하나 — 고쳤고, 남은 질문

계약 예시에 expires_at 을 넣으면서 같은 created_at 값을 가진 작업 상태 예시 6곳(Running, Succeeded, Accepted 등)에도 잘못 넣었다가 되돌렸다. 지금 계약 diff 에서 예시는 업로드 하나뿐이다(git diff 로 확인).

짚어 둘 것은 그 잘못된 상태에서도 계약 테스트 457개가 통과했다는 점이다. BuildJob 예시에 스키마에 없는 필드가 있어도 걸리지 않는다 — 예시와 스키마의 대조가 추가 필드를 보지 않는 것으로 보인다. 원인은 확인하지 않았다. 필요하면 이슈로 올리겠다.

이 PR 이 하지 않는 것

Studio 가 이 값을 보여 주는 것 — 필드가 생겼으니 kpubdata-studio 이슈로 따로 올린다.

🤖 Generated with Claude Code

A multi-user deployment deletes an upload once it is older than the retention
period (#1045), and its owner could not see that coming: the metadata carried
created_at and the period is a server setting. Upload metadata now carries
expires_at - created_at plus the period in force, the boundary the clean-up
uses - and null when nothing will delete the upload.

Closes #1047

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@yeongseon yeongseon left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

diff 를 읽었고 CLEAN 이라 승인합니다. #1046 리뷰에서 요청한 후속입니다.

  • expires_at 을 저장하지 않고 답할 때 계산하는 것이 맞습니다 — 운영자가 보관 일수를 바꾸면 실제 삭제 시점과 함께 움직입니다.
  • 필드가 말하는 시점과 정리가 지우는 시점이 같다는 것을 테스트가 양쪽에서 봅니다(29일 된 것은 미래이고 남고, 31일 된 것은 과거이고 지워진다).
  • 아무것도 지우지 않는 배포에서는 null 이고 키는 항상 있습니다.
  • 이름 붙은 오류 예시가 없어 Studio 의 선행 변경이 필요 없다는 것, Studio main 의 drift 테스트를 이 계약으로 돌려 579개가 통과했다는 것을 확인했습니다.

"작업 중 실수" 로 적은 것 — 이슈로 올려 주세요. BuildJob 예시에 스키마에 없는 필드를 넣어도 계약 테스트 457개가 통과했다는 것은, 예시와 스키마의 대조가 추가 필드를 보지 않는다는 뜻입니다. 예시가 fixture 가 되고 Studio 가 그 fixture 로 파싱을 검사하므로, 틀린 예시는 두 저장소에 조용히 퍼집니다. 원인 확인부터입니다.

@yeongseon
yeongseon merged commit 275b750 into main Oct 6, 2026
23 checks passed
@yeongseon
yeongseon deleted the feat/issue-1047-upload-expires-at branch October 7, 2026 22:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(uploads): an upload does not say when it expires

2 participants