Skip to content

[Fix] 팀명 수정 공백 버그 수정 + feat: 캠페인명 수정 API 추가#62

Merged
LeeJeongHeon02 merged 4 commits into
devfrom
feat/campaign-rename-api
Jul 21, 2026
Merged

[Fix] 팀명 수정 공백 버그 수정 + feat: 캠페인명 수정 API 추가#62
LeeJeongHeon02 merged 4 commits into
devfrom
feat/campaign-rename-api

Conversation

@LeeJeongHeon02

@LeeJeongHeon02 LeeJeongHeon02 commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Summary

두 가지를 하나로 합쳤다 (PR #61 + 이 PR).

1) fix: 팀명 수정 시 앞뒤 공백 제거 누락 (PR #61 내용)

  • PR [Feat] 팀명 수정 API 추가 #60("팀명 수정 API 추가")에서 이 수정 커밋을 두 번째 커밋으로 푸시했는데, PR이 이미
    첫 번째 커밋만으로 스쿼시 머지되어 dev에는 반영되지 않은 채 남아있었다. 로컬 서버로
    실제 API를 호출하며 QA하던 중 발견한 회귀 버그가 dev(및 배포됐다면 운영)에 그대로
    살아있던 것 — 이번에 정정한다.
  • TeamMemberManagementService.renameTeam()Texts.trim() 없이 teamName을 그대로
    저장하고 있었다. 팀 생성(TeamCreateCommand)은 이미 같은 유틸로 trim하는데 rename만
    빠뜨렸던 것.
  • CodeRabbit 지적 반영: trim 테스트가 flush 없이 메모리상 엔티티만 확인하던 걸,
    flush+clear 후 DB에서 다시 조회해 실제 반영 여부를 확인하도록 보강.

2) feat: 캠페인명 수정 API 추가

  • 문의로 들어온 요청 — PATCH /api/v1/teams/{teamId}/campaigns/{campaignId}로 캠페인명
    (campaignName)만 수정할 수 있게 한다. 브랜드명·집행기간·목표 송출 횟수·소재 등 나머지
    필드 수정과 재등록은 여전히 범위 밖이다(campaign-page-api-spec.md 12절).
  • 권한/락 패턴은 기존 deleteCampaign과 동일: 팀 조회 → ACTIVE 멤버 확인 → OWNER/ADMIN
    허용(MEMBERTEAM_403_003) → campaignRepository.findByIdForUpdate로 잠금 → 이 팀
    소유가 아니면 404. 삭제와 같은 원칙으로 상태(집행 전/중/완료)와 무관하게 항상 허용한다.
  • campaignName 검증은 등록 API(CampaignRegistrationService)와 동일한 방식(수동 검증,
    trim 후 빈 값/30자 초과 시 CAMPAIGN_400_001)으로 맞췄다. DB 컬럼은 200자까지 허용하지만
    등록 시 이미 30자로 더 엄격히 막고 있어, 수정에서 다른 상한을 쓰면 모순이 생긴다.
  • TEAM_403_003(CAMPAIGN_MANAGEMENT_FORBIDDEN) 메시지를 "등록하거나 삭제"에서 "삭제하거나
    수정"으로 정정했다 — 실제로 등록은 MEMBER도 가능해 이 코드가 지금까지 막아온 건 삭제뿐이었다.
  • Team.rename()과 같은 패턴으로 Campaign.rename() 엔티티 메서드를 추가했다.

Test plan

  • renameTeam_trimsEdgeWhitespace 회귀 테스트 (flush+clear 후 DB 재조회로 검증)
  • TeamCampaignCommandServiceTest에 rename 관련 테스트 10개 추가 (OWNER/ADMIN 성공,
    MEMBER 403, 팀/캠페인 미존재, 다른 팀 소유 캠페인, 빈 값/30자 초과, trim)
  • 전체 테스트 스위트 통과 (309개, 0 실패)
  • 로컬 서버를 띄워 두 API 모두 실제 호출로 검증: 유효성 검증 전체, 인증, teamId·
    campaignId 존재하지 않음, 권한 매트릭스(OWNER/ADMIN 200 · MEMBER 403), 다른 팀 소유
    캠페인을 잘못된 teamId로 접근 시 404(소유권 검증), 동시 수정 요청 2건이 락으로
    직렬화되어 둘 다 성공하고 최종 상태가 깨지지 않는지, OpenAPI 스키마 정상 생성

🤖 Generated with Claude Code

로컬 서버를 띄워 PATCH /api/v1/teams/{teamId}를 실제로 호출하며 QA하다가 발견 -
"  이름  " 처럼 앞뒤에 공백이 있는 teamName을 그대로 저장하고 있었다.
팀 생성 API(TeamCreateCommand)는 이미 Texts.trim()으로 teamName을 정리하는데
이번에 추가한 renameTeam()만 빠뜨렸다. 같은 유틸을 적용해 동작을 맞췄다.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@LeeJeongHeon02, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 33 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 6279bba7-e375-4835-8cbc-8cab572ab684

📥 Commits

Reviewing files that changed from the base of the PR and between af4d232 and 1fd808a.

📒 Files selected for processing (12)
  • docs/campaign-page-api-spec.md
  • docs/campaign-registration-api-spec.md
  • src/main/java/com/shinhan/klljs/domain/campaign/controller/TeamCampaignController.java
  • src/main/java/com/shinhan/klljs/domain/campaign/controller/TeamCampaignControllerDocs.java
  • src/main/java/com/shinhan/klljs/domain/campaign/dto/CampaignRenameRequest.java
  • src/main/java/com/shinhan/klljs/domain/campaign/dto/CampaignRenameResponse.java
  • src/main/java/com/shinhan/klljs/domain/campaign/entity/Campaign.java
  • src/main/java/com/shinhan/klljs/domain/campaign/service/TeamCampaignCommandService.java
  • src/main/java/com/shinhan/klljs/domain/team/exception/TeamErrorCode.java
  • src/main/java/com/shinhan/klljs/domain/team/service/TeamMemberManagementService.java
  • src/test/java/com/shinhan/klljs/domain/campaign/service/TeamCampaignCommandServiceTest.java
  • src/test/java/com/shinhan/klljs/domain/team/service/TeamMemberManagementServiceTest.java
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/campaign-rename-api

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.

LeeJeongHeon02 and others added 2 commits July 21, 2026 14:47
CodeRabbit 지적 - 기존 테스트는 flush 없이 영속성 컨텍스트에 남아있는 같은 Team
인스턴스를 검사해서, 실제로 DB에 반영됐는지가 아니라 메모리 상태만 확인하고
있었다. flush+clear 후 다시 조회하도록 고쳤다 - 같은 파일의
leaveTeam_allowsSoleOwnerToLeaveWithoutTransfer 테스트와 동일한 패턴이다.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
문의로 들어온 요청 — 캠페인명(campaignName)만 바꾸는 PATCH /api/v1/teams/{teamId}/campaigns/{campaignId}를
추가한다. 브랜드명·집행기간·목표 송출 횟수·소재 등 나머지 필드 수정과 재등록은 여전히
범위 밖이다(campaign-page-api-spec.md 12절).

- 권한/락 모두 기존 deleteCampaign과 동일한 패턴: 팀 조회 → ACTIVE 멤버 확인 →
  OWNER/ADMIN만 허용(MEMBER는 TEAM_403_003) → campaignRepository.findByIdForUpdate로
  잠금 → 이 팀 소유가 아니면 404. 상태(집행 전/중/완료)와 무관하게 항상 허용한다
  (삭제와 동일 원칙).
- campaignName 검증은 등록 API(CampaignRegistrationService)와 동일한 방식(수동 검증,
  trim 후 빈 값/30자 초과 시 CAMPAIGN_400_001)으로 맞췄다 - DB 컬럼은 200자까지 허용하지만
  등록 시 30자로 더 엄격히 막고 있어 수정에서 다른 상한을 쓰면 "등록은 막혔는데 수정으로는
  만들 수 있는" 모순이 생긴다.
- TEAM_403_003(CAMPAIGN_MANAGEMENT_FORBIDDEN) 메시지를 "등록하거나 삭제"에서 "삭제하거나
  수정"으로 정정 - 등록은 MEMBER도 가능해 이 코드가 실제로 막아온 적이 없었다.
- Team.rename()과 같은 패턴으로 Campaign.rename() 엔티티 메서드를 추가했다.

로컬 서버를 띄워 실제 API를 호출하며 검증: 유효성 검증 전체, 권한 매트릭스
(OWNER/ADMIN 200, MEMBER 403), 다른 팀 소유 캠페인을 잘못된 teamId로 접근 시 404,
동시 수정 요청 2건이 락으로 직렬화되어 둘 다 성공하고 최종 상태가 깨지지 않는지 확인.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@LeeJeongHeon02
LeeJeongHeon02 force-pushed the feat/campaign-rename-api branch from 4125684 to a960c3b Compare July 21, 2026 05:48
@LeeJeongHeon02 LeeJeongHeon02 changed the title feat: 캠페인명 수정 API 추가 fix: 팀명 수정 공백 버그 수정 + feat: 캠페인명 수정 API 추가 Jul 21, 2026
- campaign-registration-api-spec.md의 CAMPAIGN_MANAGEMENT_FORBIDDEN 메시지 인용이
  이전 값("등록하거나 삭제")으로 남아있어 campaign-page-api-spec.md와 모순되고 있었다 -
  실제 코드값("삭제하거나 수정")에 맞게 정정.
- TeamCampaignCommandService 클래스 Javadoc이 여전히 "삭제 API"만 언급하고 있어
  캠페인명 수정 기능 추가를 반영해 갱신.
- renameCampaign_trimsEdgeWhitespace가 응답 DTO만 확인하고 있던 걸, 팀명 trim
  테스트와 동일하게 flush+clear 후 DB 재조회로 실제 반영 여부까지 확인하도록 보강.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@LeeJeongHeon02
LeeJeongHeon02 merged commit 19fef8c into dev Jul 21, 2026
1 of 2 checks passed
@LeeJeongHeon02
LeeJeongHeon02 deleted the feat/campaign-rename-api branch July 21, 2026 05:58
@LeeJeongHeon02 LeeJeongHeon02 changed the title fix: 팀명 수정 공백 버그 수정 + feat: 캠페인명 수정 API 추가 [Fix] 팀명 수정 공백 버그 수정 + feat: 캠페인명 수정 API 추가 Jul 21, 2026
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.

1 participant