Skip to content

[#9] fix: dev 빌드 복구 및 누락 기능(북마크/백오피스/최근본공고/비번재설정) 통합 - #21

Merged
Bumnote merged 13 commits into
devfrom
fix/dev-integration
Jun 28, 2026
Merged

Bumnote merged 13 commits into
devfrom
fix/dev-integration

Conversation

@Bumnote

@Bumnote Bumnote commented Jun 28, 2026

Copy link
Copy Markdown
Member

📄 작업 내용

dev에 머지됐어야 할 4개 기능이 스택 PR의 부모가 먼저 머지되는 바람에 부모 브랜치에만 남고 dev에 도달하지 못했고, 동시에 dev 자체가 ErrorCode 병합 오류로 컴파일되지 않는 상태였습니다. 이를 한 번에 통합·복구합니다.

  • 빌드 복구: ErrorCode enum 병합 오류(enum constant not expected here) 해소 — 전 도메인 코드(C/M/A/CP/N/B/I)를 한 목록으로 정리
  • 누락 기능 통합: feat/notice-api·feat/member-self-service를 머지해 dev에 빠져 있던 기능을 반영
    • 즐겨찾기(북마크) · 백오피스 캠페인 관리(ROLE_ADMIN) · 최근 본 공고 · 비밀번호 재설정
  • 충돌 해소: Member(createAdmin + updateProfile/changePassword 공존), SecurityConfig(공개 경로 통합: password/notices/campaigns + admin hasRole)
  • PageResponse 일원화 마무리: dev는 이미 common/response/PageResponse로 통일돼 있어, 통합된 bookmark/admin/recentview의 잔여 campaign/dto/response/PageResponse import를 common으로 교체
  • 테스트 격리 복구: 도메인 통합으로 H2를 공유하는 통합 테스트들이 FK 누수로 깨지던 문제를, 각 테스트 전 전체 테이블을 비우는 DatabaseCleaner + 자동 감지 DatabaseCleanupExtension(테스트 클래스 무수정)으로 해결

✅ PR 유형

  • Bug Fix
  • Refactor

🧪 테스트 내용

  • 로컬 테스트 완료 — compileJava + compileTestJava + 전체 테스트 스위트 BUILD SUCCESSFUL (모든 도메인 통합 테스트 통과)

🙋🏻 참고 사항

🔗 관련 이슈

resolved: #9

Bumnote and others added 13 commits June 27, 2026 21:36
마이페이지/목록 화면에서 사용할 캠페인 즐겨찾기 기능을 구현한다.

- 즐겨찾기 추가(POST)·삭제(DELETE)·ID 목록 조회(GET /ids)·캠페인 목록 조회(GET) 엔드포인트 추가
- 모든 엔드포인트는 인증 필요(@AuthenticationPrincipal Long memberId), 경로는 /api/me/bookmarks
- Bookmark 엔티티에 정적 팩토리 create(Member, Campaign) 추가
- 즐겨찾기 목록은 최신순 정렬, createdAt 동률 시 id를 2차 키로 둬 순서를 안정화
- 중복 추가는 사전 존재 검사로 409(B001) 처리하고, 동시 요청 레이스는 DB unique 제약
  (uk_bookmark_member_campaign)을 DbConstraint에 매핑해 500이 아닌 409로 변환
- ErrorCode에 BOOKMARK_ALREADY_EXISTS(B001), BOOKMARK_NOT_FOUND(B002) 추가

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
백오피스 API를 위한 관리자 권한 인가 토대를 추가한다.

- /api/admin/** 경로를 hasRole(ADMIN)으로 보호 (JWT가 담은 ROLE_ADMIN 권한 기반)
- 권한 부족(인증됐으나 USER) 요청을 ApiResult 포맷 403으로 응답하는 RestAccessDeniedHandler 추가,
  SecurityConfig의 accessDeniedHandler로 연결
- ErrorCode에 ACCESS_DENIED(A004) 추가
- 관리자 계정 생성을 위한 Member.createAdmin 정적 팩토리 추가

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
관리자가 캠페인(공고)을 등록·수정·삭제·조회하는 백오피스 API를 추가한다.
프런트 AdminRecruitments 화면에 대응하며, 모든 엔드포인트는 ROLE_ADMIN 전용이다.

- /api/admin/campaigns 목록(상태 무관 전체, 최신순)·단건·등록(201)·수정(PUT)·삭제 엔드포인트
- Campaign 엔티티에 update(...) 도메인 메서드 추가(식별자/조회수/생성시각 보존, Setter 미사용)
- CampaignCreateRequest(toEntity, status 미지정 시 OPEN)·CampaignUpdateRequest(전체 수정) record DTO
- 목록 정렬은 createdAt 동률 시 id를 2차 키로 안정화하고, 잘못된 page/size는 방어적으로 보정
- AdminCampaignControllerDocs로 Swagger 문서 분리

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
비밀번호 찾기 화면(ForgotPassword)이 사용할 비로그인 재설정 흐름을 추가한다.
기존 이메일 인증 메커니즘을 재사용하되, 가입 여부 검사를 반대로 적용한다.

- POST /api/password/email/code : 가입된 이메일로 재설정 인증 코드 발송(미가입 404)
- POST /api/password/email/verify : 인증 코드 확인(기존 verify 재사용)
- POST /api/password/reset : 인증 완료된 계정의 비밀번호를 새 값으로 변경
- /api/password/** 를 공개 엔드포인트로 허용
- 보안: 재설정 성공 시 인증 상태를 1회용으로 소비(EmailVerificationStore.deleteVerified 추가)하고,
  탈취 대응을 위해 해당 회원의 리프레시 토큰을 폐기

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
마이페이지 '최근에 본 공고' 탭이 사용할 열람 기록 API를 추가한다.

- POST /api/me/recent-views : 캠페인 열람 기록(이미 있으면 열람 시각만 갱신, 멱등)
- GET /api/me/recent-views/ids : 최근 열람 캠페인 ID 목록(최신순, 상한 50)
- GET /api/me/recent-views : 최근 열람 캠페인 목록(최신순 페이징, CampaignResponse)
- RecentView 엔티티(member+campaign 유니크)와 정적 팩토리 create, 열람 시각 갱신 touch
- viewedAt 동률 시 id로 안정 정렬, fetch join + countQuery로 페이징 정확성 확보
- 잘못된 page/size/limit는 방어적으로 보정

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
[#9] feat: 즐겨찾기(북마크) API 구현
[#9] feat: 백오피스 캠페인 관리 API 구현
[#9] feat: 비밀번호 재설정 API (비로그인)
[#9] feat: 최근 본 공고(RecentView) API
# Conflicts:
#	src/main/java/kr/co/bookpool/app/member/entity/Member.java
#	src/main/java/kr/co/bookpool/common/exception/ErrorCode.java
…로 교체

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
# Conflicts:
#	src/main/java/kr/co/bookpool/common/config/SecurityConfig.java
여러 도메인이 한 앱으로 통합되면서, 컨텍스트 캐싱으로 H2를 공유하는 통합 테스트들이
서로의 잔여 자식 행(bookmark/recent_view 등) 때문에 member 삭제 시 FK 위반으로 실패했다.

- DatabaseCleaner: 참조 무결성을 끄고 전체 테이블을 truncate 하는 테스트 유틸 추가
- DatabaseCleanupExtension: ServiceLoader 자동 감지로 모든 통합 테스트 각 실행 전 DB를 비움
  (테스트 클래스 수정 없이 전역 적용, 비-Spring 테스트는 무시)
- 통합으로 삭제된 campaign PageResponse를 참조하던 bookmark/admin/recentview 테스트의
  import를 common/response/PageResponse로 교체

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

Test Results

88 tests  +38   88 ✅ +38   29s ⏱️ +10s
13 suites + 4    0 💤 ± 0 
13 files   + 4    0 ❌ ± 0 

Results for commit a3c9822. ± Comparison against base commit ebc4709.

@Bumnote Bumnote self-assigned this Jun 28, 2026
@Bumnote
Bumnote requested a review from pug9483 June 28, 2026 06:32
@Bumnote Bumnote added feature 새로운 기능 추가 bug 버그 수정 및 오류 대응 test 테스트 추가 및 테스트 코드 개선 labels Jun 28, 2026
@Bumnote
Bumnote merged commit 30b5b4f into dev Jun 28, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug 버그 수정 및 오류 대응 feature 새로운 기능 추가 test 테스트 추가 및 테스트 코드 개선

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature] API 구현

1 participant