diff --git a/src/main/java/com/sb/web/account/controller/RecurringController.java b/src/main/java/com/sb/web/account/controller/RecurringController.java index 2a42458..1f6c28c 100644 --- a/src/main/java/com/sb/web/account/controller/RecurringController.java +++ b/src/main/java/com/sb/web/account/controller/RecurringController.java @@ -34,7 +34,9 @@ public class RecurringController { public ResponseEntity create( @Valid @RequestBody RecurringRequest req, @RequestAttribute(AuthInterceptor.CURRENT_MEMBER) SessionUser current) { - return ResponseEntity.status(HttpStatus.CREATED).body(recurringService.create(req, current.getId())); + boolean premium = "ADMIN".equals(current.getRole()) || "PREMIUM".equals(current.getPlan()); + return ResponseEntity.status(HttpStatus.CREATED) + .body(recurringService.create(req, current.getId(), premium)); } @PutMapping("/{id}") diff --git a/src/main/java/com/sb/web/account/mapper/RecurringMapper.java b/src/main/java/com/sb/web/account/mapper/RecurringMapper.java index 163e619..c812729 100644 --- a/src/main/java/com/sb/web/account/mapper/RecurringMapper.java +++ b/src/main/java/com/sb/web/account/mapper/RecurringMapper.java @@ -15,6 +15,9 @@ public interface RecurringMapper { List findByMember(@Param("memberId") Long memberId); + /** 회원의 정기 거래 개수 (무료 회원 등록 한도 판정용) */ + int countByMember(@Param("memberId") Long memberId); + /** 활성 규칙 (자동 생성용) */ List findActiveByMember(@Param("memberId") Long memberId); diff --git a/src/main/java/com/sb/web/account/service/BackupService.java b/src/main/java/com/sb/web/account/service/BackupService.java index f32e929..f47d1b5 100644 --- a/src/main/java/com/sb/web/account/service/BackupService.java +++ b/src/main/java/com/sb/web/account/service/BackupService.java @@ -153,7 +153,8 @@ public class BackupService { rr.setStartDate(r.getStartDate()); rr.setEndDate(r.getEndDate()); rr.setActive(r.getActive() == null || r.getActive()); - recurringService.create(rr, memberId); + // 복원은 본인 데이터 복구이므로 무료 한도 미적용 + recurringService.create(rr, memberId, true); } } diff --git a/src/main/java/com/sb/web/account/service/RecurringService.java b/src/main/java/com/sb/web/account/service/RecurringService.java index 1fa63e8..2f449c9 100644 --- a/src/main/java/com/sb/web/account/service/RecurringService.java +++ b/src/main/java/com/sb/web/account/service/RecurringService.java @@ -30,8 +30,15 @@ public class RecurringService { return recurringMapper.findByMember(memberId).stream().map(this::toResponse).toList(); } + // 무료 회원 고정지출 등록 한도(써보고 → 결제 유도). 유료·관리자는 무제한. + public static final int FREE_RECURRING_LIMIT = 2; + @Transactional - public RecurringResponse create(RecurringRequest req, Long memberId) { + public RecurringResponse create(RecurringRequest req, Long memberId, boolean premium) { + if (!premium && recurringMapper.countByMember(memberId) >= FREE_RECURRING_LIMIT) { + throw new ApiException(HttpStatus.BAD_REQUEST, + "무료 회원은 고정 지출을 " + FREE_RECURRING_LIMIT + "개까지 등록할 수 있어요. 유료로 업그레이드하면 무제한이에요."); + } Recurring r = toEntity(req); r.setMemberId(memberId); recurringMapper.insert(r); diff --git a/src/main/java/com/sb/web/common/config/WebConfig.java b/src/main/java/com/sb/web/common/config/WebConfig.java index a2754ff..1da8afe 100644 --- a/src/main/java/com/sb/web/common/config/WebConfig.java +++ b/src/main/java/com/sb/web/common/config/WebConfig.java @@ -42,7 +42,6 @@ public class WebConfig implements WebMvcConfigurer { "/api/account/ai-comment", "/api/account/networth/trend", "/api/account/budgets", "/api/account/budgets/**", - "/api/account/recurrings", "/api/account/recurrings/**", "/api/account/ocr", "/api/account/ocr/**", "/api/account/invest", "/api/account/invest/**", "/api/account/tags", "/api/account/tags/**", diff --git a/src/main/resources/mapper/RecurringMapper.xml b/src/main/resources/mapper/RecurringMapper.xml index 08b5c7f..357c60d 100644 --- a/src/main/resources/mapper/RecurringMapper.xml +++ b/src/main/resources/mapper/RecurringMapper.xml @@ -78,4 +78,8 @@ UPDATE recurring SET last_run_date = #{lastRunDate} WHERE id = #{id} + +