Files
sb-backend/src/main/java/com/sb/web/admin/service/MemberAdminService.java
T
ByungCheolandClaude Opus 4.8 6256d3e63d feat: 멤버십(무료/유료) 게이팅 — 백엔드
- member.plan(FREE/PREMIUM) 컬럼 추가 + SessionUser/MemberResponse 노출
- auth_session 백업에 plan 저장(세션 복원 시 유료 상태 유지)
- 관리자 회원 plan 변경 API (PUT /api/admin/members/{id}/plan)
- PremiumInterceptor 로 유료 전용 경로 차단(통계/예산/고정지출/태그/OCR/투자/카드알림/백업)
  · 관리자는 플랜과 무관하게 허용, 무료 회원은 403 PREMIUM_REQUIRED
- WebConfigTest: 유료 경로 등록 회귀 가드 추가

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-28 11:02:19 +09:00

75 lines
2.6 KiB
Java

package com.sb.web.admin.service;
import com.sb.web.auth.domain.Member;
import com.sb.web.auth.dto.MemberAdminResponse;
import com.sb.web.auth.mapper.MemberMapper;
import com.sb.web.common.exception.ApiException;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
/**
* 관리자용 회원 관리 서비스. (목록/역할/상태/삭제)
* 본인 계정에 대한 역할·상태·삭제는 잠금 방지를 위해 차단한다.
*/
@Service
@RequiredArgsConstructor
public class MemberAdminService {
private final MemberMapper memberMapper;
public List<MemberAdminResponse> list() {
return memberMapper.findAll().stream().map(MemberAdminResponse::from).toList();
}
@Transactional
public MemberAdminResponse updateRole(Long targetId, String role, Long currentAdminId) {
Member target = mustFind(targetId);
if (targetId.equals(currentAdminId)) {
throw new ApiException(HttpStatus.BAD_REQUEST, "본인의 역할은 변경할 수 없습니다.");
}
memberMapper.updateRole(targetId, role);
target.setRole(role);
return MemberAdminResponse.from(target);
}
@Transactional
public MemberAdminResponse updatePlan(Long targetId, String plan, Long currentAdminId) {
Member target = mustFind(targetId);
memberMapper.updatePlan(targetId, plan);
target.setPlan(plan);
return MemberAdminResponse.from(target);
}
@Transactional
public MemberAdminResponse updateStatus(Long targetId, String status, Long currentAdminId) {
Member target = mustFind(targetId);
if (targetId.equals(currentAdminId)) {
throw new ApiException(HttpStatus.BAD_REQUEST, "본인의 상태는 변경할 수 없습니다.");
}
memberMapper.updateStatus(targetId, status);
target.setStatus(status);
return MemberAdminResponse.from(target);
}
@Transactional
public void delete(Long targetId, Long currentAdminId) {
mustFind(targetId);
if (targetId.equals(currentAdminId)) {
throw new ApiException(HttpStatus.BAD_REQUEST, "본인 계정은 삭제할 수 없습니다.");
}
memberMapper.deleteById(targetId);
}
private Member mustFind(Long id) {
Member m = memberMapper.findById(id);
if (m == null) {
throw new ApiException(HttpStatus.NOT_FOUND, "회원을 찾을 수 없습니다.");
}
return m;
}
}