Skip to content

[FEAT/#361] 백오피스 관리자, 제휴 관리 기능#363

Open
eeeeeaaan wants to merge 5 commits into
developfrom
feat/#361-sh-backoffice
Open

[FEAT/#361] 백오피스 관리자, 제휴 관리 기능#363
eeeeeaaan wants to merge 5 commits into
developfrom
feat/#361-sh-backoffice

Conversation

@eeeeeaaan

@eeeeeaaan eeeeeaaan commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

#️⃣연관된 이슈

#361

📝작업 내용

  • 백오피스용 학생회(Admin) 계정 CRUD API 추가 (임의 생성/조회/수정/삭제)
  • 백오피스용 제휴 계약서(Paper) 관리 API 추가 (임의 생성, 옵션/굿즈 내용 추가, 승인/거부/만료 처리, 페이징 조회)
  • 백오피스용 제휴(Partnership) 조회 API 추가 (전체/학생회별/가게별 페이징 조회)
  • 위 API들에 @BackofficeAudited 어노테이션 적용하여 감사 로그 기록
  • 관련 Repository 메서드 추가 (findByStore_IdAndIsActivated 등)
  • BackofficePaperService, BackofficePartnershipServiceImpl 관련 단위 테스트 작성

🔎코드 설명

  • BackofficeAdminController/Service: 인감·전화번호 없이 백오피스에서 임의로 학생회 계정을 생성/수정/삭제할 수 있도록 함
  • BackofficePaperController/Service: 계약서를 먼저 빈 상태로 생성한 뒤, 옵션/굿즈 내용을 별도 API로 추가하는 2단계 플로우로 설계
  • BackofficePartnershipController/ServiceImpl: 조회 전용 API로, ACTIVE 상태인 제휴만 필터링해서 반환

💬고민사항 및 리뷰 요구사항

  • deleteAdmin에서 하드 삭제 방식이 맞는지 (감사 로그와의 정합성 관련) 의견 부탁드립니다
  • Paper 상태 전이(승인/거부/만료) 시 현재 상태에 대한 검증 없이 무조건 상태를 바꾸는데, 상태 검증 로직이 필요한지 확인 부탁드립니다

비고

@eeeeeaaan eeeeeaaan changed the title Feat/#361 sh backoffice [FEAT/#361] 백오피스 관리자, 제휴 관리 기능 Jun 26, 2026
@eeeeeaaan eeeeeaaan added the ✨ feature New feature or request label Jul 6, 2026
@eeeeeaaan eeeeeaaan linked an issue Jul 6, 2026 that may be closed by this pull request
@2ghrms

2ghrms commented Jul 7, 2026

Copy link
Copy Markdown
Member

혹시 PR 내용 좀 작성 부탁드려도 될까용? @eeeeeaaan

ㄴ네

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

굳이 이렇게 따로 만든 이유는 기존에 제휴 생성은 권한으로 막혀있어서 backoffice에서는 따로 권한이나 인증 절차 없이 가능하게 하려고

public void deleteAdmin(Long adminId) {
Member member = memberRepository.findById(adminId)
.orElseThrow(() -> new CustomAuthException(ErrorStatus.NO_SUCH_MEMBER));
memberRepository.delete(member);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

제휴가 있는 학생회 계정을 삭제하려고 하면 cascade가 안 걸려 있어서 500 터질 것 같아여

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

음.. 그러면 임의의 학생회 계정을 삭제하는 기능을 넣는게 맞을까요? 제휴 뿐만 아니라 채팅방 등등 여러 테이블에서 adminId 를 가지고 있는데 이것들도 역시 삭제시에 문제가 될 것 같아서요. (아니면 softDelete 등의 대안도 있다고 생각하긴 한데 무슨 의미가 있는지는... 잘 모르겠음)

return WritePartnershipResponseDTO.of(paper, contentsWithGoods, goodsBatches);
}

private List<WritePartnershipResponseDTO> buildPartnershipDTOs(List<Paper> papers) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

buildPartnershipDTOs 메서드가 PartnershipServiceImpl, BackofficePartnershipServiceImpl에도 똑같이 있어서 유틸화해서 쓰면 좋을 것 같긴 해요 근데 우리 이런거 유틸화를 했었나..?

private final BackofficeAdminService backofficeAdminService;

@Operation(summary = "모든 학생회 계정 조회 API", description = "시스템에 등록된 모든 학생회(Admin) 계정 목록을 조회합니다.")
@GetMapping

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

스웨거 양식 컨벤션을 백오피스에도 동일하게 사용해줍시다

List<Paper> findByPartner_IdAndIsActivated(Long partnerId, ActivationStatus status, Sort sort);
Page<Paper> findByPartner_IdAndIsActivated(Long partnerId, ActivationStatus status, Pageable pageable);
long countByStore_Id(Long storeId);
Page<Paper> findByStore_IdAndIsActivated(Long storeId, ActivationStatus status, Pageable pageable);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

여기서 파라미터는 ActivationStatus인데, 메소드에는 IsActivated로 나타내주고 있어서 메소드에도 ActivationStatus로 넣어주는건 어떨까요?

.orElseThrow(() -> new CustomAuthException(ErrorStatus.NO_SUCH_MEMBER));
Store store = storeRepository.findById(req.storeId())
.orElseThrow(() -> new CustomAuthException(ErrorStatus.NO_SUCH_MEMBER)); // 가게 없을 시 예외

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

여기서는 CustomAuthException보다는 DatabaseException이나 다른 커스텀 예외 클래스를 사용하는 게 좋아보입니다

Paper paper = paperRepository.findById(paperId)
.orElseThrow(() -> new CustomAuthException(ErrorStatus.NO_SUCH_MEMBER));

paper.setIsActivated(ActivationStatus.ACTIVE);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

여기서 상태 전이 순서를 보장하기 위해서 승인된 계약서를 다시 승인시에 예외를 발생시키는 것이 좋아보입니다

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

Labels

✨ feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEAT/#361] 백오피스 API (관리자, 제휴)

3 participants