Skip to content

fix: [ALT-306] 업장 신청 증빙 역할 중복 방지 및 입력 계약 회귀 검증 - #117

Open
ysw789 wants to merge 11 commits into
fix/alt-297-qa-followupfrom
fix/alt-306
Open

ysw789 wants to merge 11 commits into
fix/alt-297-qa-followupfrom
fix/alt-306

Conversation

@ysw789

@ysw789 ysw789 commented Oct 4, 2026 •

Copy link
Copy Markdown
Contributor

요약

업장 등록 신청에서 같은 파일 ID를 등록증·신분증·위임장 중 두 칸 이상에 넣으면, 서버 내부 매핑에서 앞 역할이 뒤 역할로 덮어써져 필수 증빙 하나가 빠진 신청이 저장될 수 있었습니다. 이제 이런 요청은 저장 전에 400 B001로 거부합니다.

요청·응답 필드는 바뀌지 않았습니다. DB 스키마 변경과 신규 ErrorCode도 없습니다. 운영 코드 변경은 CreateWorkspaceRequest의 검증 7줄과 Swagger 설명 2줄뿐입니다. 나머지는 기존 입력·업로드 검증이 앞으로도 바뀌지 않도록 단위 테스트로 고정한 것입니다.

변경 내용

POST /app/workspace-requests, POST /manager/workspace-requests (CreateWorkspaceRequest)

두 API는 같은 유스케이스를 쓰므로 동작이 같습니다.

  • 증빙 파일 ID 세 칸(workspaceCertFileId 사업자등록증명원, workspaceOwnIdentityFileId 대표자 신분증, workspaceWarrantFileId 위임 확인서) 중 두 칸 이상이 같으면 400 B001(ILLEGAL_ARGUMENT)을 반환합니다.
    • message: 증빙 서류는 역할별로 서로 다른 파일을 첨부해야 합니다.
    • 거부하는 조합: 등록증=신분증, 등록증=위임장, 신분증=위임장, 셋 모두 같음
    • 위임장을 보내지 않으면(null) 등록증과 신분증만 비교합니다.
  • 이 검사는 업종 조회와 신청 저장보다 먼저 실행됩니다. 그래서 거부된 요청은 신청을 저장하지 않고 파일도 연결하지 않습니다. 업종 ID까지 잘못된 요청이라도 증빙이 겹치면 이 메시지가 먼저 나옵니다.
  • 서버는 파일 ID 문자열이 정확히 같은지만 비교합니다. 파일 ID가 다르면 내용이 같은 파일이어도 막지 않습니다.

그대로 유지되는 규칙 (테스트로 고정)

  • bizName, brn, address, province, district, town, workspaceCertFileId, workspaceOwnIdentityFileId는 비우거나 공백만 넣을 수 없고, latitude, longitude, businessTypeId는 null일 수 없습니다. 어기면 400 B001입니다.
  • brn은 비어 있지만 않으면 형식을 따지지 않습니다. 123-45-12345, 1234512345, 1, letters-123이 모두 통과합니다.
  • 대표 이미지는 5개까지 넣을 수 있고, 6개부터 400 B001입니다.
  • 파일 업로드(POST /app/files, POST /manager/files, FileValidator)
    • 파일이 없거나 비어 있으면 400 B022
    • 허용 형식은 image/jpeg, image/png, image/gif, image/webp, application/pdf입니다. 그 밖의 형식(image/svg+xml 포함)이나 형식 정보가 없는 파일은 400 B023
    • 크기는 20MiB(20×1024×1024 바이트)까지 허용하고, 1바이트라도 넘으면 400 B024
    • 검증에 실패하면 S3에 올리지 않고 DB에도 저장하지 않습니다. 통과한 파일은 업로더·형식·크기와 함께 PENDING 상태로 저장됩니다.

Swagger

  • UserWorkspaceRequestControllerSpec, ManagerWorkspaceRequestControllerSpec의 업장 등록 신청 400 설명에 "등록증·신분증·위임장에 같은 파일 ID 중복 첨부"를 추가했습니다. 두 Spec 모두 예시(example) 없이 설명만 쓰고 있어 같은 방식으로 맞췄습니다.

프론트 영향

  • 업장 등록 신청 화면에서 세 증빙 칸에 같은 파일(같은 파일 ID)을 넣으면 이제 400 B001이 옵니다. 칸마다 따로 업로드한 파일 ID를 보내 주세요. 같은 B001이 다른 입력 오류에도 쓰이므로, 화면 안내가 필요하면 message로 구분해야 합니다.
  • 그 밖의 요청·응답 필드와 기존 검증은 바뀌지 않았습니다. 구버전 앱도 증빙을 칸마다 다르게 보내고 있다면 영향이 없습니다.
  • 업로드 크기 상한 안내: FileValidator는 20MiB까지 허용하지만, 실제 HTTP 요청에서는 application.yml의 multipart 상한(max-file-size, max-request-size 모두 20MB)이 먼저 걸립니다. 20MiB를 넘는 파일은 B024가 아니라 HTTP 413으로 거부됩니다. 요청 전체 크기도 20MB로 묶여 있어, 크기가 정확히 20MiB인 파일도 실제로는 413이 될 가능성이 큽니다(이 경계는 실제 요청으로 확인하지 않았습니다). 화면 안내는 "20MB 미만"으로 하는 것을 권장합니다.

테스트

모두 Spring 컨텍스트나 DB 없이 도는 단위 테스트입니다.

  • CreateWorkspaceRequestTests(보강, Mockito)
    • 증빙 중복 4조합이 B001과 위 메시지로 거부되고, 신청 저장과 파일 연결이 일어나지 않는지 확인합니다. 업종 조회 실패도 B001이라 처음에는 중복 검증이 없어도 통과할 수 있었는데, 이제 메시지까지 비교하므로 검증이 빠지면 실제로 실패합니다.
    • 세 파일이 모두 다르면 위임장까지 각 역할로 연결되는지 확인합니다.
  • WorkspaceRequestValidationTests(신규) — DTO 필수값·공백 거부, brn 형식 미제한, 대표 이미지 5개 상한
  • FileValidatorTests(신규) — 허용 MIME 5종의 20MiB 허용, 1바이트 초과 거부, 비허용·형식 없는 파일 거부, 빈 파일·파일 없음 거부
  • FileUploadServiceTests(신규, Mockito) — 형식·크기 검증 실패 시 S3·DB 미호출, 정상 업로드의 PENDING 저장
  • 전체 ./gradlew test 732건 통과(실패·에러·skip 0)

리뷰 반영 전 기준: 초안 시점에 로컬 서버로 APP·MANAGER 각각 중복 3조합(등록증=신분증, 등록증=위임장, 신분증=위임장)을 실제 HTTP로 보내 400 B001과 위 메시지, 신청·파일 연결 무변경을 확인했습니다. 21MiB PDF 업로드는 HTTP 413으로 거부됐습니다.

남긴 것

  • 사업자등록번호 10자리·하이픈 정규화 규칙은 기획 합의가 없어 새로 만들지 않았습니다. 현재는 비어 있지만 않으면 통과합니다.
  • QA B-01(프론트가 업종 문자열·고정 좌표를 보내는 문제)은 최신 프론트·배포 요청을 확보하지 못해 해결 여부를 확인하지 못했습니다.
  • 실제 S3 업로드 → 신청 → 승인 전체 흐름과 정확히 20MiB인 파일의 HTTP 업로드는 확인하지 않았습니다. 개발 버킷이 운영 환경으로 설정돼 있어 실제 S3 쓰기를 하지 않았습니다.
  • 새 migration은 없습니다.

병합 순서

base는 fix/alt-297-qa-followup이고, PR #108의 앞부분(연락처 정규화)입니다. PR #108을 먼저 병합한 뒤 이 PR을 병합해 주세요.

관련 문서

추가 반영: 업로드 크기 한도 정리

  • spring.servlet.multipart.max-request-size를 20MB→25MB로 올렸습니다(max-file-size 20MB 유지). 기존에는 multipart 경계·헤더가 요청 크기에 더해져 정확히 20MiB인 파일이 413으로 막혔습니다.
  • GlobalExceptionHandler에 MaxUploadSizeExceededException 처리를 추가해, 한도 초과를 스프링 기본 413 대신 프로젝트 오류 형식의 400/B024로 응답합니다. 새 ErrorCode는 없습니다.
  • 로컬 서버 실제 HTTP 확인(POST /api/manager/files, 매니저 토큰): 정확히 20MiB(text/plain, S3 업로드 전 차단)→400/B023, 20MiB+1B·22MB·24MiB·26MiB(image/png)→모두 400/B024. 연결 끊김 없이 응답을 받았습니다. 정상 파일 업로드(S3)는 실행하지 않았습니다.
  • ./gradlew clean build 전체 733건 통과.
  • 별도로, 개발 서버 nginx에 client_max_body_size가 없어 1MB를 넘는 업로드가 nginx 413으로 막히던 문제를 client_max_body_size 25m로 고쳤습니다(서버 설정 변경, 이 PR 코드와 무관). 운영 nginx는 아직 반영 전입니다.

@coderabbitai

coderabbitai Bot commented Oct 4, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

🗂️ Base branches to auto review: 2
  • main
  • dev

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

Run configuration

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@hodoon hodoon 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.

리뷰했습니다. 인라인 코멘트 확인 부탁드립니다.

@ysw789 ysw789 self-assigned this Oct 21, 2026
@ysw789
ysw789 force-pushed the fix/alt-297-qa-followup branch from 5230a96 to bf154a3 Compare October 28, 2026 10:38
@ysw789
ysw789 marked this pull request as ready for review October 28, 2026 10:39

This branch has not been deployed

No deployments
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.

2 participants