Skip to content

fix(onboarding): 회원가입 사진의 content URI를 업로드 없이 profileUrl로 전송한다 #2024

Open

Description

@OnlyReadOneBook

작업 유형

bug — 버그·오동작

주 담당 모듈

onboarding — 온보딩

개요

회원가입 프로필에서 갤러리 사진을 선택하면 앱 기기에만 유효한 content://... 주소가 서버의 profileUrl로 그대로 전달됩니다. 선택 화면의 미리보기는 로컬 URI로 그릴 수 있지만 서버와 다른 기기는 해당 URI의 사진을 읽을 수 없습니다. 회원가입 사진 선택을 실제 저장 가능한 원격 이미지 주소와 연결해야 합니다.

확인한 흐름(develop 816e9272):

  • OnboardingProfileEntry.kt의 onProfileImagePicked = { viewModel.onProfileImagePicked(it.toString()) }는 picker URI를 문자열로 보관합니다.
  • SignUpViewModel.kt:220는 profileUrl = state.profileImageUri로 제출합니다.
  • AccountRepositoryImpl.kt:98는 받은 문자열을 SignUpRequestDto에 그대로 넣습니다. 이 경로에는 업로드가 없습니다.
  • core/network/.../dto/AuthDto.kt:61은 이를 JSON profileUrl로 직렬화합니다.

2026-09-13 실제 ViewModel QA: 선택 결과로 content://media/picker/0/com.android.providers.media.photopicker/media/100001을 전달하고 가입을 실행하자 fake repository가 받은 profileUrl도 같은 문자열이었습니다. 회원가입·로그인 성공 응답에서는 isSignedUp=true까지 진행합니다. 서버 응답을 fake로 대체했으므로 실서버 저장 성공이나 특정 HTTP 오류를 재현했다고 주장하지 않습니다.

완료 조건:

  • 사진 선택 상태가 서버가 소비할 수 있는 실제 업로드 결과와 연결되는지 확인한다.
  • 기기 전용 content: 주소가 회원가입 원격 이미지 필드로 나가지 않도록 한다.
  • 사진 업로드 실패와 회원가입 성공을 잘못 합치지 않으며, 사진 미선택 및 picker 취소 보존 동작을 유지한다.
  • 실제 사용 가능한 미인증 가입 단계 업로드 계약을 먼저 확인한다. 계약이 없다면 필요한 BE 계약을 별도로 확인하고 임시 URL·형식만 추측해 구현하지 않는다.

중복 확인: 현재 열린 onboarding 이슈 및 프로필 가입, 사진 업로드 가입, profileUrl 검색에 같은 결함 없음. #1115는 picker 취소가 직전 선택을 지우던 결함이며 업로드와 다릅니다. #1438/#2003은 setting 화면으로 담당·실제 소비 경로가 다릅니다. #1963·#1825 최종 트리에도 이 경로가 남습니다.

검증 결과: 실제 SignUpViewModel의 fake repository 기반 테스트 3건 전체 통과(현재 결함 발생을 단언). 구현이 고쳐졌다는 뜻은 아닙니다. 로컬 QA 코드/원본 XML은 이 작업의 보고서에 보관했습니다.

Activity

  1. github-actions commented on Sep 13, 2026

    @github-actions
    Contributor

    bug 이슈는 사이드바 Fields > Priority 로 심각도를 지정해야 합니다. 판정 기준:

    • Urgent: 치명 — 크래시·데이터 소실·보안 무력화·핵심 경로 차단·가짜 성공
    • High: 심각 — 실패·틀린 값의 정상 위장, 핵심 기능 무동작
    • Medium: 불편 — 우회로가 있는 오동작·틀린 표시, 핵심 흐름은 유지
    • Low: 경미 — 문구·정렬·마감 품질 흠, 기능 영향 없음

    값이 비어 있어도 이슈를 닫지는 않습니다. 이 안내는 이슈당 한 번만 답니다.

  2. Sadturtleman commented on Sep 16, 2026

    @Sadturtleman
    Collaborator

    선행 확인 — 「미인증 가입 단계 업로드 계약」은 없다 (2026-09-16 실측)

    완료 조건 첫 줄의 확인분이다. 구현은 하지 않았다.

    1. 가입 시점에는 업로드할 수단이 없다

    POST /api/v1/files/presigned-url 은 swagger 전역 bearer-key 보안에 걸려 있고 operation 단위 예외가 없다. 토큰 없이 부르면 거절된다.

    $ curl -s -o /dev/null -w '%{http_code}' -X POST https://afternote.kro.kr/api/v1/files/presigned-url \
        -H 'Content-Type: application/json' -d '{}'
    401
    

    가입 API 자체는 토큰을 내려주지 않는다 — SignUpViewModel.submitSignUp() 의 KDoc 이 「회원가입 API 는 토큰을 내려주지 않으므로 같은 자격증명으로 자동 로그인」이라 적고, 실제로 accountRepository.signUp(...) 성공 뒤 loginUseCase(LoginType.Email(...)) 를 잇는다. 즉 토큰은 계정이 만들어진 뒤에야 생긴다.

    SignupRequest 스키마의 profileUrl 은 "example": "https://s3.~~" 로 원격 주소를 기대한다. 지금 SignUpViewModel 은 그 자리에 picker 의 content://... 를 그대로 싣는다.

    2. FE 에 이미 있는 수단

    3. 그래서 갈림은 둘이고, 어느 쪽도 FE 가 정할 수 없다

    • (A) 계정이 생긴 뒤에 붙인다 — 자동 로그인 성공 후 업로드하고 PATCH users/me 로 사진만 따로 붙인다. 기존 수단만 쓰므로 BE 변경이 없다. 대신 「계정 생성」과 「사진 저장」이 두 단계로 갈려, 업로드가 실패해도 가입은 성공으로 남는다 — 그 경우의 안내와 재시도 자리를 정해야 한다. 완료 조건의 「사진 업로드 실패와 회원가입 성공을 잘못 합치지 않는다」가 이 결정을 요구한다.
    • (B) 가입 단계 업로드를 연다 — BE 가 미인증 presigned 발급이나 가입 요청 자체의 파일 수용을 계약으로 연다. 가입 한 번으로 끝나지만 미인증 업로드 경로가 생긴다.

    4. BE 에 걸린 계약이 없다

    presigned · 프로필 사진 · 회원가입 이미지 · profileUrl · 가입 업로드 로 Afternote-BE 를 훑었고, 이 갈림을 다루는 열린 이슈는 없다. FE 쪽 중복도 이 이슈뿐이다.

    다음

    (A)/(B) 판정을 PM·BE 에서 받아야 착수할 수 있다. 확정 전에는 임시 URL·형식을 추측해 구현하지 않는다. (B) 로 가면 BE 이슈를 새로 걸어야 한다.

    착수 시 주의 — SignUpViewModel 은 지금 열린 PR #2102 · #2103 이 함께 고치고 있어, 구현은 그 위에 스택해야 충돌이 없다.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area:onboarding온보딩 기능 영역bugSomething isn't working

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions