refactor(api): Controller→Service 분리 + 매직 스트링 Enum 교체 (리뷰 2단계)

5개 Controller가 Mapper를 직접 주입하던 패턴 제거하고 Service 레이어 신설.

신규 Service:
- InsuranceCompanyService, ProductService, RuleService, ReceiveService, RoleService
- 변경 메서드 @Transactional, 조회 @Transactional(readOnly=true) 적용

Controller 정리:
- 5개 Controller에서 Mapper 직접 주입 제거 → Service 경유
- RoleController의 Controller-level @Transactional은 Service로 이전

매직 스트링 → Enum (1단계 산출물 적용):
- AgentService/ContractService — AgentStatus, ContractStatus
- SettleService 4곳 — SettleStatus
- LedgerService 3곳 — ApproveStatus

OrganizationSaveReq 적용:
- OrganizationController create/update 입력을 OrganizationVO → OrganizationSaveReq
  로 변경, 클라이언트의 감사 필드 직접 주입 차단

원래 3단계로 분류했던 @DataChangeLog 17곳 보강도 2단계에서 함께 처리:
- ProductController DELETE
- RuleController override/chargeback/exception 8곳
- ReceiveController profiles/mapping/errors 6곳
- RoleController DELETE + savePermissions (권한 일괄변경)

미해결로 남은 매직 스트링(다음 단계):
- AuthService "LOCKED"/"RETIRED"/"ACTIVE" — UserStatus Enum 미구현
- LedgerService:71 "NEW" — LedgerStatus Enum 미구현
This commit is contained in:
GA Pro
2026-05-12 23:13:40 +09:00
parent 5e58a54128
commit a8f0b6edf9
16 changed files with 500 additions and 113 deletions
@@ -5,7 +5,9 @@ import com.ga.common.annotation.DataChangeLog;
import com.ga.common.annotation.RequirePermission;
import com.ga.common.model.ApiResponse;
import com.ga.core.vo.org.OrganizationResp;
import com.ga.core.vo.org.OrganizationSaveReq;
import com.ga.core.vo.org.OrganizationVO;
import jakarta.validation.Valid;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
@@ -43,15 +45,15 @@ public class OrganizationController {
@PostMapping
@RequirePermission(menu = "ORG_TREE", perm = "CREATE")
@DataChangeLog(menu = "ORG_TREE", table = "organization")
public ApiResponse<Long> create(@RequestBody OrganizationVO vo) {
return ApiResponse.ok(service.create(vo));
public ApiResponse<Long> create(@Valid @RequestBody OrganizationSaveReq req) {
return ApiResponse.ok(service.create(req));
}
@PutMapping("/{orgId}")
@RequirePermission(menu = "ORG_TREE", perm = "UPDATE")
@DataChangeLog(menu = "ORG_TREE", table = "organization")
public ApiResponse<Void> update(@PathVariable Long orgId, @RequestBody OrganizationVO vo) {
service.update(orgId, vo);
public ApiResponse<Void> update(@PathVariable Long orgId, @Valid @RequestBody OrganizationSaveReq req) {
service.update(orgId, req);
return ApiResponse.ok();
}
@@ -1,9 +1,9 @@
package com.ga.api.controller.product;
import com.ga.api.service.product.InsuranceCompanyService;
import com.ga.common.annotation.DataChangeLog;
import com.ga.common.annotation.RequirePermission;
import com.ga.common.model.ApiResponse;
import com.ga.core.mapper.product.InsuranceCompanyMapper;
import com.ga.core.vo.product.InsuranceCompanyVO;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
@@ -17,34 +17,32 @@ import java.util.List;
@RequiredArgsConstructor
public class CompanyController {
private final InsuranceCompanyMapper mapper;
private final InsuranceCompanyService companyService;
@GetMapping
@RequirePermission(menu = "COMPANY", perm = "READ")
public ApiResponse<List<InsuranceCompanyVO>> list(@RequestParam(required = false, defaultValue = "false") boolean activeOnly) {
return ApiResponse.ok(activeOnly ? mapper.selectActive() : mapper.selectAll());
return ApiResponse.ok(companyService.list(activeOnly));
}
@GetMapping("/{companyId}")
@RequirePermission(menu = "COMPANY", perm = "READ")
public ApiResponse<InsuranceCompanyVO> detail(@PathVariable Long companyId) {
return ApiResponse.ok(mapper.selectById(companyId));
return ApiResponse.ok(companyService.detail(companyId));
}
@PostMapping
@RequirePermission(menu = "COMPANY", perm = "CREATE")
@DataChangeLog(menu = "COMPANY", table = "insurance_company")
public ApiResponse<Long> create(@RequestBody InsuranceCompanyVO vo) {
mapper.insert(vo);
return ApiResponse.ok(vo.getCompanyId());
return ApiResponse.ok(companyService.create(vo));
}
@PutMapping("/{companyId}")
@RequirePermission(menu = "COMPANY", perm = "UPDATE")
@DataChangeLog(menu = "COMPANY", table = "insurance_company")
public ApiResponse<Void> update(@PathVariable Long companyId, @RequestBody InsuranceCompanyVO vo) {
vo.setCompanyId(companyId);
mapper.update(vo);
companyService.update(companyId, vo);
return ApiResponse.ok();
}
}
@@ -1,11 +1,9 @@
package com.ga.api.controller.product;
import com.ga.api.service.product.ProductService;
import com.ga.common.annotation.DataChangeLog;
import com.ga.common.annotation.RequirePermission;
import com.ga.common.exception.BizException;
import com.ga.common.exception.ErrorCode;
import com.ga.common.model.ApiResponse;
import com.ga.core.mapper.product.ProductMapper;
import com.ga.core.vo.product.ProductResp;
import com.ga.core.vo.product.ProductVO;
import io.swagger.v3.oas.annotations.tags.Tag;
@@ -20,7 +18,7 @@ import java.util.List;
@RequiredArgsConstructor
public class ProductController {
private final ProductMapper mapper;
private final ProductService productService;
@GetMapping
@RequirePermission(menu = "PRODUCT", perm = "READ")
@@ -28,41 +26,35 @@ public class ProductController {
@RequestParam(required = false) String insuranceType,
@RequestParam(required = false) String keyword,
@RequestParam(required = false) String isActive) {
return ApiResponse.ok(mapper.selectList(companyId, insuranceType, keyword, isActive));
return ApiResponse.ok(productService.list(companyId, insuranceType, keyword, isActive));
}
@GetMapping("/{productId}")
@RequirePermission(menu = "PRODUCT", perm = "READ")
public ApiResponse<ProductResp> detail(@PathVariable Long productId) {
ProductResp r = mapper.selectDetailById(productId);
if (r == null) throw new BizException(ErrorCode.NOT_FOUND);
return ApiResponse.ok(r);
return ApiResponse.ok(productService.detail(productId));
}
@PostMapping
@RequirePermission(menu = "PRODUCT", perm = "CREATE")
@DataChangeLog(menu = "PRODUCT", table = "product")
public ApiResponse<Long> create(@RequestBody ProductVO vo) {
if (mapper.existsByCode(vo.getCompanyId(), vo.getProductCode()) > 0) {
throw new BizException(ErrorCode.DUPLICATE_DATA);
}
mapper.insert(vo);
return ApiResponse.ok(vo.getProductId());
return ApiResponse.ok(productService.create(vo));
}
@PutMapping("/{productId}")
@RequirePermission(menu = "PRODUCT", perm = "UPDATE")
@DataChangeLog(menu = "PRODUCT", table = "product")
public ApiResponse<Void> update(@PathVariable Long productId, @RequestBody ProductVO vo) {
vo.setProductId(productId);
mapper.update(vo);
productService.update(productId, vo);
return ApiResponse.ok();
}
@DeleteMapping("/{productId}")
@RequirePermission(menu = "PRODUCT", perm = "DELETE")
@DataChangeLog(menu = "PRODUCT", table = "product")
public ApiResponse<Void> delete(@PathVariable Long productId) {
mapper.deleteById(productId);
productService.delete(productId);
return ApiResponse.ok();
}
}
@@ -1,8 +1,9 @@
package com.ga.api.controller.receive;
import com.ga.api.service.receive.ReceiveService;
import com.ga.common.annotation.DataChangeLog;
import com.ga.common.annotation.RequirePermission;
import com.ga.common.model.ApiResponse;
import com.ga.core.mapper.receive.ReceiveMapper;
import com.ga.core.vo.receive.*;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
@@ -17,21 +18,20 @@ import java.util.Map;
@RequiredArgsConstructor
public class ReceiveController {
private final ReceiveMapper mapper;
private final ReceiveService receiveService;
// 보험사 프로파일
@GetMapping("/profiles")
@RequirePermission(menu = "RECEIVE_MAPPING", perm = "READ")
public ApiResponse<List<CompanyProfileVO>> profiles() {
return ApiResponse.ok(mapper.selectAllProfiles());
return ApiResponse.ok(receiveService.listProfiles());
}
@PutMapping("/profiles/{companyCode}")
@RequirePermission(menu = "RECEIVE_MAPPING", perm = "UPDATE")
@DataChangeLog(menu = "RECEIVE_MAPPING", table = "company_profile")
public ApiResponse<Void> updateProfile(@PathVariable String companyCode, @RequestBody CompanyProfileVO vo) {
vo.setCompanyCode(companyCode);
if (mapper.selectProfile(companyCode) == null) mapper.insertProfile(vo);
else mapper.updateProfile(vo);
receiveService.saveProfile(companyCode, vo);
return ApiResponse.ok();
}
@@ -40,29 +40,29 @@ public class ReceiveController {
@RequirePermission(menu = "RECEIVE_MAPPING", perm = "READ")
public ApiResponse<List<CompanyFieldMappingVO>> fields(@PathVariable String companyCode,
@RequestParam(required = false) String targetTable) {
return ApiResponse.ok(mapper.selectFieldMappings(companyCode, targetTable));
return ApiResponse.ok(receiveService.listFields(companyCode, targetTable));
}
@PostMapping("/mapping/{companyCode}/fields")
@RequirePermission(menu = "RECEIVE_MAPPING", perm = "CREATE")
@DataChangeLog(menu = "RECEIVE_MAPPING", table = "company_field_mapping")
public ApiResponse<Long> createField(@PathVariable String companyCode, @RequestBody CompanyFieldMappingVO vo) {
vo.setCompanyCode(companyCode);
mapper.insertFieldMapping(vo);
return ApiResponse.ok(vo.getMappingId());
return ApiResponse.ok(receiveService.createField(companyCode, vo));
}
@PutMapping("/mapping/fields/{mappingId}")
@RequirePermission(menu = "RECEIVE_MAPPING", perm = "UPDATE")
@DataChangeLog(menu = "RECEIVE_MAPPING", table = "company_field_mapping")
public ApiResponse<Void> updateField(@PathVariable Long mappingId, @RequestBody CompanyFieldMappingVO vo) {
vo.setMappingId(mappingId);
mapper.updateFieldMapping(vo);
receiveService.updateField(mappingId, vo);
return ApiResponse.ok();
}
@DeleteMapping("/mapping/fields/{mappingId}")
@RequirePermission(menu = "RECEIVE_MAPPING", perm = "DELETE")
@DataChangeLog(menu = "RECEIVE_MAPPING", table = "company_field_mapping")
public ApiResponse<Void> deleteField(@PathVariable Long mappingId) {
mapper.deleteFieldMapping(mappingId);
receiveService.deleteField(mappingId);
return ApiResponse.ok();
}
@@ -71,15 +71,14 @@ public class ReceiveController {
@RequirePermission(menu = "RECEIVE_MAPPING", perm = "READ")
public ApiResponse<List<CodeMappingVO>> codes(@PathVariable String companyCode,
@RequestParam(required = false) String codeType) {
return ApiResponse.ok(mapper.selectCodeMappings(companyCode, codeType));
return ApiResponse.ok(receiveService.listCodes(companyCode, codeType));
}
@PostMapping("/mapping/{companyCode}/codes")
@RequirePermission(menu = "RECEIVE_MAPPING", perm = "CREATE")
@DataChangeLog(menu = "RECEIVE_MAPPING", table = "code_mapping")
public ApiResponse<Long> createCode(@PathVariable String companyCode, @RequestBody CodeMappingVO vo) {
vo.setCompanyCode(companyCode);
mapper.insertCodeMapping(vo);
return ApiResponse.ok(vo.getCodeId());
return ApiResponse.ok(receiveService.createCode(companyCode, vo));
}
// 원본 데이터 + 에러
@@ -88,23 +87,23 @@ public class ReceiveController {
public ApiResponse<List<RawCommissionDataVO>> rawList(@RequestParam(required = false) String companyCode,
@RequestParam(required = false) String settleMonth,
@RequestParam(required = false) String parseStatus) {
return ApiResponse.ok(mapper.selectRawList(companyCode, settleMonth, parseStatus));
return ApiResponse.ok(receiveService.listRaw(companyCode, settleMonth, parseStatus));
}
@GetMapping("/errors")
@RequirePermission(menu = "RECEIVE_DATA", perm = "READ")
public ApiResponse<List<ParseErrorLogVO>> errors(@RequestParam(required = false) String companyCode,
@RequestParam(required = false) String resolveStatus) {
return ApiResponse.ok(mapper.selectErrors(companyCode, resolveStatus));
return ApiResponse.ok(receiveService.listErrors(companyCode, resolveStatus));
}
@PutMapping("/errors/{errorId}/resolve")
@RequirePermission(menu = "RECEIVE_DATA", perm = "UPDATE")
@DataChangeLog(menu = "RECEIVE_DATA", table = "parse_error_log")
public ApiResponse<Void> resolveError(@PathVariable Long errorId, @RequestBody Map<String, String> body) {
mapper.resolveError(errorId,
receiveService.resolveError(errorId,
body.getOrDefault("status", "RESOLVED"),
body.get("note"),
com.ga.common.util.SecurityUtil.getCurrentUserId());
body.get("note"));
return ApiResponse.ok();
}
}
@@ -1,9 +1,9 @@
package com.ga.api.controller.rule;
import com.ga.api.service.rule.RuleService;
import com.ga.common.annotation.DataChangeLog;
import com.ga.common.annotation.RequirePermission;
import com.ga.common.model.ApiResponse;
import com.ga.core.mapper.rule.RuleMapper;
import com.ga.core.vo.rule.*;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
@@ -17,37 +17,36 @@ import java.util.List;
@RequiredArgsConstructor
public class RuleController {
private final RuleMapper mapper;
private final RuleService ruleService;
// ========== commission_rate ==========
@GetMapping("/commission-rates")
@RequirePermission(menu = "RULE_COMMISSION", perm = "READ")
public ApiResponse<List<CommissionRateVO>> listCommissionRates(@RequestParam(required = false) Long productId,
@RequestParam(required = false) Integer year) {
return ApiResponse.ok(mapper.selectCommissionRates(productId, year));
return ApiResponse.ok(ruleService.listCommissionRates(productId, year));
}
@PostMapping("/commission-rates")
@RequirePermission(menu = "RULE_COMMISSION", perm = "CREATE")
@DataChangeLog(menu = "RULE_COMMISSION", table = "commission_rate")
public ApiResponse<Long> createCommissionRate(@RequestBody CommissionRateVO vo) {
mapper.insertCommissionRate(vo);
return ApiResponse.ok(vo.getRateId());
return ApiResponse.ok(ruleService.createCommissionRate(vo));
}
@PutMapping("/commission-rates/{rateId}")
@RequirePermission(menu = "RULE_COMMISSION", perm = "UPDATE")
@DataChangeLog(menu = "RULE_COMMISSION", table = "commission_rate")
public ApiResponse<Void> updateCommissionRate(@PathVariable Long rateId, @RequestBody CommissionRateVO vo) {
vo.setRateId(rateId);
mapper.updateCommissionRate(vo);
ruleService.updateCommissionRate(rateId, vo);
return ApiResponse.ok();
}
@DeleteMapping("/commission-rates/{rateId}")
@RequirePermission(menu = "RULE_COMMISSION", perm = "DELETE")
@DataChangeLog(menu = "RULE_COMMISSION", table = "commission_rate")
public ApiResponse<Void> deleteCommissionRate(@PathVariable Long rateId) {
mapper.deleteCommissionRate(rateId);
ruleService.deleteCommissionRate(rateId);
return ApiResponse.ok();
}
@@ -56,30 +55,29 @@ public class RuleController {
@RequirePermission(menu = "RULE_PAYOUT", perm = "READ")
public ApiResponse<List<PayoutRuleVO>> listPayoutRules(@RequestParam(required = false) Long gradeId,
@RequestParam(required = false) String insuranceType) {
return ApiResponse.ok(mapper.selectPayoutRules(gradeId, insuranceType));
return ApiResponse.ok(ruleService.listPayoutRules(gradeId, insuranceType));
}
@PostMapping("/payout")
@RequirePermission(menu = "RULE_PAYOUT", perm = "CREATE")
@DataChangeLog(menu = "RULE_PAYOUT", table = "payout_rule")
public ApiResponse<Long> createPayoutRule(@RequestBody PayoutRuleVO vo) {
mapper.insertPayoutRule(vo);
return ApiResponse.ok(vo.getRuleId());
return ApiResponse.ok(ruleService.createPayoutRule(vo));
}
@PutMapping("/payout/{ruleId}")
@RequirePermission(menu = "RULE_PAYOUT", perm = "UPDATE")
@DataChangeLog(menu = "RULE_PAYOUT", table = "payout_rule")
public ApiResponse<Void> updatePayoutRule(@PathVariable Long ruleId, @RequestBody PayoutRuleVO vo) {
vo.setRuleId(ruleId);
mapper.updatePayoutRule(vo);
ruleService.updatePayoutRule(ruleId, vo);
return ApiResponse.ok();
}
@DeleteMapping("/payout/{ruleId}")
@RequirePermission(menu = "RULE_PAYOUT", perm = "DELETE")
@DataChangeLog(menu = "RULE_PAYOUT", table = "payout_rule")
public ApiResponse<Void> deletePayoutRule(@PathVariable Long ruleId) {
mapper.deletePayoutRule(ruleId);
ruleService.deletePayoutRule(ruleId);
return ApiResponse.ok();
}
@@ -87,28 +85,29 @@ public class RuleController {
@GetMapping("/override")
@RequirePermission(menu = "RULE_OVERRIDE", perm = "READ")
public ApiResponse<List<OverrideRuleVO>> listOverrideRules() {
return ApiResponse.ok(mapper.selectOverrideRules());
return ApiResponse.ok(ruleService.listOverrideRules());
}
@PostMapping("/override")
@RequirePermission(menu = "RULE_OVERRIDE", perm = "CREATE")
@DataChangeLog(menu = "RULE_OVERRIDE", table = "override_rule")
public ApiResponse<Long> createOverrideRule(@RequestBody OverrideRuleVO vo) {
mapper.insertOverrideRule(vo);
return ApiResponse.ok(vo.getOverrideId());
return ApiResponse.ok(ruleService.createOverrideRule(vo));
}
@PutMapping("/override/{overrideId}")
@RequirePermission(menu = "RULE_OVERRIDE", perm = "UPDATE")
@DataChangeLog(menu = "RULE_OVERRIDE", table = "override_rule")
public ApiResponse<Void> updateOverrideRule(@PathVariable Long overrideId, @RequestBody OverrideRuleVO vo) {
vo.setOverrideId(overrideId);
mapper.updateOverrideRule(vo);
ruleService.updateOverrideRule(overrideId, vo);
return ApiResponse.ok();
}
@DeleteMapping("/override/{overrideId}")
@RequirePermission(menu = "RULE_OVERRIDE", perm = "DELETE")
@DataChangeLog(menu = "RULE_OVERRIDE", table = "override_rule")
public ApiResponse<Void> deleteOverrideRule(@PathVariable Long overrideId) {
mapper.deleteOverrideRule(overrideId);
ruleService.deleteOverrideRule(overrideId);
return ApiResponse.ok();
}
@@ -116,28 +115,29 @@ public class RuleController {
@GetMapping("/chargeback")
@RequirePermission(menu = "RULE_CHARGEBACK", perm = "READ")
public ApiResponse<List<ChargebackRuleVO>> listChargebackRules(@RequestParam(required = false) String companyCode) {
return ApiResponse.ok(mapper.selectChargebackRules(companyCode));
return ApiResponse.ok(ruleService.listChargebackRules(companyCode));
}
@PostMapping("/chargeback")
@RequirePermission(menu = "RULE_CHARGEBACK", perm = "CREATE")
@DataChangeLog(menu = "RULE_CHARGEBACK", table = "chargeback_rule")
public ApiResponse<Long> createChargebackRule(@RequestBody ChargebackRuleVO vo) {
mapper.insertChargebackRule(vo);
return ApiResponse.ok(vo.getCbRuleId());
return ApiResponse.ok(ruleService.createChargebackRule(vo));
}
@PutMapping("/chargeback/{cbRuleId}")
@RequirePermission(menu = "RULE_CHARGEBACK", perm = "UPDATE")
@DataChangeLog(menu = "RULE_CHARGEBACK", table = "chargeback_rule")
public ApiResponse<Void> updateChargebackRule(@PathVariable Long cbRuleId, @RequestBody ChargebackRuleVO vo) {
vo.setCbRuleId(cbRuleId);
mapper.updateChargebackRule(vo);
ruleService.updateChargebackRule(cbRuleId, vo);
return ApiResponse.ok();
}
@DeleteMapping("/chargeback/{cbRuleId}")
@RequirePermission(menu = "RULE_CHARGEBACK", perm = "DELETE")
@DataChangeLog(menu = "RULE_CHARGEBACK", table = "chargeback_rule")
public ApiResponse<Void> deleteChargebackRule(@PathVariable Long cbRuleId) {
mapper.deleteChargebackRule(cbRuleId);
ruleService.deleteChargebackRule(cbRuleId);
return ApiResponse.ok();
}
@@ -145,22 +145,23 @@ public class RuleController {
@GetMapping("/exception-codes")
@RequirePermission(menu = "RULE_EXCEPTION", perm = "READ")
public ApiResponse<List<ExceptionTypeCodeVO>> listExceptionCodes() {
return ApiResponse.ok(mapper.selectExceptionCodes());
return ApiResponse.ok(ruleService.listExceptionCodes());
}
@PostMapping("/exception-codes")
@RequirePermission(menu = "RULE_EXCEPTION", perm = "CREATE")
@DataChangeLog(menu = "RULE_EXCEPTION", table = "exception_type_code")
public ApiResponse<Void> createExceptionCode(@RequestBody ExceptionTypeCodeVO vo) {
mapper.insertExceptionCode(vo);
ruleService.createExceptionCode(vo);
return ApiResponse.ok();
}
@PutMapping("/exception-codes/{exceptionCode}")
@RequirePermission(menu = "RULE_EXCEPTION", perm = "UPDATE")
@DataChangeLog(menu = "RULE_EXCEPTION", table = "exception_type_code")
public ApiResponse<Void> updateExceptionCode(@PathVariable String exceptionCode,
@RequestBody ExceptionTypeCodeVO vo) {
vo.setExceptionCode(exceptionCode);
mapper.updateExceptionCode(vo);
ruleService.updateExceptionCode(exceptionCode, vo);
return ApiResponse.ok();
}
}
@@ -1,13 +1,12 @@
package com.ga.api.controller.system;
import com.ga.api.service.system.RoleService;
import com.ga.common.annotation.DataChangeLog;
import com.ga.common.annotation.RequirePermission;
import com.ga.common.model.ApiResponse;
import com.ga.core.mapper.user.RoleMapper;
import com.ga.core.vo.user.RoleVO;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@@ -19,63 +18,55 @@ import java.util.Map;
@RequiredArgsConstructor
public class RoleController {
private final RoleMapper mapper;
private final RoleService roleService;
@GetMapping
@RequirePermission(menu = "SYSTEM_ROLE", perm = "READ")
public ApiResponse<List<RoleVO>> list() {
return ApiResponse.ok(mapper.selectAll());
return ApiResponse.ok(roleService.list());
}
@GetMapping("/{roleId}")
@RequirePermission(menu = "SYSTEM_ROLE", perm = "READ")
public ApiResponse<RoleVO> detail(@PathVariable Long roleId) {
return ApiResponse.ok(mapper.selectById(roleId));
return ApiResponse.ok(roleService.detail(roleId));
}
@GetMapping("/{roleId}/permissions")
@RequirePermission(menu = "SYSTEM_ROLE", perm = "READ")
public ApiResponse<List<Map<String, Object>>> permissions(@PathVariable Long roleId) {
return ApiResponse.ok(mapper.selectRolePermissions(roleId));
return ApiResponse.ok(roleService.permissions(roleId));
}
@PostMapping
@RequirePermission(menu = "SYSTEM_ROLE", perm = "CREATE")
@DataChangeLog(menu = "SYSTEM_ROLE", table = "role")
public ApiResponse<Long> create(@RequestBody RoleVO vo) {
mapper.insert(vo);
return ApiResponse.ok(vo.getRoleId());
return ApiResponse.ok(roleService.create(vo));
}
@PutMapping("/{roleId}")
@RequirePermission(menu = "SYSTEM_ROLE", perm = "UPDATE")
@DataChangeLog(menu = "SYSTEM_ROLE", table = "role")
public ApiResponse<Void> update(@PathVariable Long roleId, @RequestBody RoleVO vo) {
vo.setRoleId(roleId);
mapper.update(vo);
roleService.update(roleId, vo);
return ApiResponse.ok();
}
@DeleteMapping("/{roleId}")
@RequirePermission(menu = "SYSTEM_ROLE", perm = "DELETE")
@DataChangeLog(menu = "SYSTEM_ROLE", table = "role")
public ApiResponse<Void> delete(@PathVariable Long roleId) {
mapper.deleteById(roleId);
roleService.delete(roleId);
return ApiResponse.ok();
}
/** 권한 매트릭스 일괄 저장 */
@PutMapping("/{roleId}/permissions")
@RequirePermission(menu = "SYSTEM_ROLE", perm = "UPDATE")
@Transactional
@DataChangeLog(menu = "SYSTEM_ROLE", table = "role_permission")
public ApiResponse<Void> savePermissions(@PathVariable Long roleId,
@RequestBody List<Map<String, Object>> permissions) {
mapper.deleteRolePermissions(roleId);
for (Map<String, Object> p : permissions) {
Long menuId = ((Number) p.get("menuId")).longValue();
String permCode = (String) p.get("permCode");
String isGranted = (String) p.getOrDefault("isGranted", "Y");
mapper.insertRolePermission(roleId, menuId, permCode, isGranted);
}
roleService.savePermissions(roleId, permissions);
return ApiResponse.ok();
}
}
@@ -8,6 +8,7 @@ import com.ga.core.mapper.ledger.ExceptionLedgerMapper;
import com.ga.core.mapper.ledger.MaintainLedgerMapper;
import com.ga.core.mapper.ledger.RecruitLedgerMapper;
import com.ga.core.vo.ledger.*;
import com.ga.core.vo.ledger.ApproveStatus;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -67,15 +68,15 @@ public class LedgerService {
vo.setRecurringYn(req.getRecurringYn());
vo.setRecurringMonths(req.getRecurringMonths());
vo.setRecurringLeft(req.getRecurringMonths());
vo.setApproveStatus("PENDING");
vo.setStatus("NEW");
vo.setApproveStatus(ApproveStatus.PENDING.name());
vo.setStatus("NEW"); // ExceptionLedger 전용 초기 상태 — ApproveStatus에 없음
exceptionMapper.insert(vo);
return vo.getLedgerId();
}
@Transactional
public void approveException(Long ledgerId, String status) {
if (!"APPROVED".equals(status) && !"REJECTED".equals(status)) {
if (!ApproveStatus.APPROVED.name().equals(status) && !ApproveStatus.REJECTED.name().equals(status)) {
throw new BizException(ErrorCode.INVALID_PARAMETER, "status는 APPROVED/REJECTED만 가능합니다");
}
Long approverId = SecurityUtil.getCurrentUserId();
@@ -6,6 +6,7 @@ import com.ga.common.exception.ErrorCode;
import com.ga.common.model.PageResponse;
import com.ga.core.mapper.org.AgentMapper;
import com.ga.core.vo.org.*;
import com.ga.core.vo.org.AgentStatus;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -34,7 +35,7 @@ public class AgentService {
throw new BizException(ErrorCode.DUPLICATE_DATA, "이미 등록된 사번입니다");
}
AgentVO vo = toVO(req, null);
vo.setStatus("ACTIVE");
vo.setStatus(AgentStatus.ACTIVE.name());
mapper.insert(vo);
// 입사 이력 기록
AgentOrgHistoryVO h = new AgentOrgHistoryVO();
@@ -4,6 +4,7 @@ import com.ga.common.exception.BizException;
import com.ga.common.exception.ErrorCode;
import com.ga.core.mapper.org.OrganizationMapper;
import com.ga.core.vo.org.OrganizationResp;
import com.ga.core.vo.org.OrganizationSaveReq;
import com.ga.core.vo.org.OrganizationVO;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
@@ -33,18 +34,33 @@ public class OrganizationService {
}
@Transactional
public Long create(OrganizationVO vo) {
public Long create(OrganizationSaveReq req) {
OrganizationVO vo = toVO(req, null);
mapper.insert(vo);
return vo.getOrgId();
}
@Transactional
public void update(Long orgId, OrganizationVO vo) {
public void update(Long orgId, OrganizationSaveReq req) {
get(orgId);
vo.setOrgId(orgId);
OrganizationVO vo = toVO(req, orgId);
mapper.update(vo);
}
private OrganizationVO toVO(OrganizationSaveReq req, Long orgId) {
OrganizationVO vo = new OrganizationVO();
vo.setOrgId(orgId);
vo.setOrgName(req.getOrgName());
vo.setParentOrgId(req.getParentOrgId());
vo.setOrgType(req.getOrgType());
vo.setOrgLevel(req.getOrgLevel());
vo.setRegion(req.getRegion());
vo.setEffectiveFrom(req.getEffectiveFrom());
vo.setEffectiveTo(req.getEffectiveTo());
vo.setIsActive(req.getIsActive());
return vo;
}
@Transactional
public void delete(Long orgId) {
if (mapper.countChildren(orgId) > 0) {
@@ -7,6 +7,7 @@ import com.ga.core.mapper.product.ContractMapper;
import com.ga.core.vo.product.ContractResp;
import com.ga.core.vo.product.ContractSaveReq;
import com.ga.core.vo.product.ContractSearchParam;
import com.ga.core.vo.product.ContractStatus;
import com.ga.core.vo.product.ContractVO;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
@@ -44,7 +45,7 @@ public class ContractService {
vo.setPayCycle(req.getPayCycle());
vo.setPayPeriod(req.getPayPeriod());
vo.setCoveragePeriod(req.getCoveragePeriod());
vo.setStatus("ACTIVE");
vo.setStatus(ContractStatus.ACTIVE.name());
vo.setContractDate(req.getContractDate());
vo.setEffectiveDate(req.getEffectiveDate());
mapper.insert(vo);
@@ -0,0 +1,43 @@
package com.ga.api.service.product;
import com.ga.common.exception.BizException;
import com.ga.common.exception.ErrorCode;
import com.ga.core.mapper.product.InsuranceCompanyMapper;
import com.ga.core.vo.product.InsuranceCompanyVO;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Service
@RequiredArgsConstructor
public class InsuranceCompanyService {
private final InsuranceCompanyMapper mapper;
@Transactional(readOnly = true)
public List<InsuranceCompanyVO> list(boolean activeOnly) {
return activeOnly ? mapper.selectActive() : mapper.selectAll();
}
@Transactional(readOnly = true)
public InsuranceCompanyVO detail(Long companyId) {
InsuranceCompanyVO vo = mapper.selectById(companyId);
if (vo == null) throw new BizException(ErrorCode.NOT_FOUND);
return vo;
}
@Transactional
public Long create(InsuranceCompanyVO vo) {
mapper.insert(vo);
return vo.getCompanyId();
}
@Transactional
public void update(Long companyId, InsuranceCompanyVO vo) {
if (mapper.selectById(companyId) == null) throw new BizException(ErrorCode.NOT_FOUND);
vo.setCompanyId(companyId);
mapper.update(vo);
}
}
@@ -0,0 +1,53 @@
package com.ga.api.service.product;
import com.ga.common.exception.BizException;
import com.ga.common.exception.ErrorCode;
import com.ga.core.mapper.product.ProductMapper;
import com.ga.core.vo.product.ProductResp;
import com.ga.core.vo.product.ProductVO;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Service
@RequiredArgsConstructor
public class ProductService {
private final ProductMapper mapper;
@Transactional(readOnly = true)
public List<ProductResp> list(Long companyId, String insuranceType, String keyword, String isActive) {
return mapper.selectList(companyId, insuranceType, keyword, isActive);
}
@Transactional(readOnly = true)
public ProductResp detail(Long productId) {
ProductResp r = mapper.selectDetailById(productId);
if (r == null) throw new BizException(ErrorCode.NOT_FOUND);
return r;
}
@Transactional
public Long create(ProductVO vo) {
if (mapper.existsByCode(vo.getCompanyId(), vo.getProductCode()) > 0) {
throw new BizException(ErrorCode.DUPLICATE_DATA);
}
mapper.insert(vo);
return vo.getProductId();
}
@Transactional
public void update(Long productId, ProductVO vo) {
if (mapper.selectById(productId) == null) throw new BizException(ErrorCode.NOT_FOUND);
vo.setProductId(productId);
mapper.update(vo);
}
@Transactional
public void delete(Long productId) {
if (mapper.selectById(productId) == null) throw new BizException(ErrorCode.NOT_FOUND);
mapper.deleteById(productId);
}
}
@@ -0,0 +1,87 @@
package com.ga.api.service.receive;
import com.ga.common.util.SecurityUtil;
import com.ga.core.mapper.receive.ReceiveMapper;
import com.ga.core.vo.receive.*;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Service
@RequiredArgsConstructor
public class ReceiveService {
private final ReceiveMapper mapper;
// === company_profile ===
@Transactional(readOnly = true)
public List<CompanyProfileVO> listProfiles() {
return mapper.selectAllProfiles();
}
@Transactional
public void saveProfile(String companyCode, CompanyProfileVO vo) {
vo.setCompanyCode(companyCode);
if (mapper.selectProfile(companyCode) == null) mapper.insertProfile(vo);
else mapper.updateProfile(vo);
}
// === field_mapping ===
@Transactional(readOnly = true)
public List<CompanyFieldMappingVO> listFields(String companyCode, String targetTable) {
return mapper.selectFieldMappings(companyCode, targetTable);
}
@Transactional
public Long createField(String companyCode, CompanyFieldMappingVO vo) {
vo.setCompanyCode(companyCode);
mapper.insertFieldMapping(vo);
return vo.getMappingId();
}
@Transactional
public void updateField(Long mappingId, CompanyFieldMappingVO vo) {
vo.setMappingId(mappingId);
mapper.updateFieldMapping(vo);
}
@Transactional
public void deleteField(Long mappingId) {
mapper.deleteFieldMapping(mappingId);
}
// === code_mapping ===
@Transactional(readOnly = true)
public List<CodeMappingVO> listCodes(String companyCode, String codeType) {
return mapper.selectCodeMappings(companyCode, codeType);
}
@Transactional
public Long createCode(String companyCode, CodeMappingVO vo) {
vo.setCompanyCode(companyCode);
mapper.insertCodeMapping(vo);
return vo.getCodeId();
}
// === raw + errors ===
@Transactional(readOnly = true)
public List<RawCommissionDataVO> listRaw(String companyCode, String settleMonth, String parseStatus) {
return mapper.selectRawList(companyCode, settleMonth, parseStatus);
}
@Transactional(readOnly = true)
public List<ParseErrorLogVO> listErrors(String companyCode, String resolveStatus) {
return mapper.selectErrors(companyCode, resolveStatus);
}
@Transactional
public void resolveError(Long errorId, String status, String note) {
mapper.resolveError(errorId, status, note, SecurityUtil.getCurrentUserId());
}
}
@@ -0,0 +1,135 @@
package com.ga.api.service.rule;
import com.ga.common.exception.BizException;
import com.ga.common.exception.ErrorCode;
import com.ga.core.mapper.rule.RuleMapper;
import com.ga.core.vo.rule.*;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Service
@RequiredArgsConstructor
public class RuleService {
private final RuleMapper mapper;
// === commission_rate ===
@Transactional(readOnly = true)
public List<CommissionRateVO> listCommissionRates(Long productId, Integer year) {
return mapper.selectCommissionRates(productId, year);
}
@Transactional
public Long createCommissionRate(CommissionRateVO vo) {
mapper.insertCommissionRate(vo);
return vo.getRateId();
}
@Transactional
public void updateCommissionRate(Long rateId, CommissionRateVO vo) {
vo.setRateId(rateId);
mapper.updateCommissionRate(vo);
}
@Transactional
public void deleteCommissionRate(Long rateId) {
mapper.deleteCommissionRate(rateId);
}
// === payout_rule ===
@Transactional(readOnly = true)
public List<PayoutRuleVO> listPayoutRules(Long gradeId, String insuranceType) {
return mapper.selectPayoutRules(gradeId, insuranceType);
}
@Transactional
public Long createPayoutRule(PayoutRuleVO vo) {
mapper.insertPayoutRule(vo);
return vo.getRuleId();
}
@Transactional
public void updatePayoutRule(Long ruleId, PayoutRuleVO vo) {
vo.setRuleId(ruleId);
mapper.updatePayoutRule(vo);
}
@Transactional
public void deletePayoutRule(Long ruleId) {
mapper.deletePayoutRule(ruleId);
}
// === override_rule ===
@Transactional(readOnly = true)
public List<OverrideRuleVO> listOverrideRules() {
return mapper.selectOverrideRules();
}
@Transactional
public Long createOverrideRule(OverrideRuleVO vo) {
mapper.insertOverrideRule(vo);
return vo.getOverrideId();
}
@Transactional
public void updateOverrideRule(Long overrideId, OverrideRuleVO vo) {
vo.setOverrideId(overrideId);
mapper.updateOverrideRule(vo);
}
@Transactional
public void deleteOverrideRule(Long overrideId) {
mapper.deleteOverrideRule(overrideId);
}
// === chargeback_rule ===
@Transactional(readOnly = true)
public List<ChargebackRuleVO> listChargebackRules(String companyCode) {
return mapper.selectChargebackRules(companyCode);
}
@Transactional
public Long createChargebackRule(ChargebackRuleVO vo) {
mapper.insertChargebackRule(vo);
return vo.getCbRuleId();
}
@Transactional
public void updateChargebackRule(Long cbRuleId, ChargebackRuleVO vo) {
vo.setCbRuleId(cbRuleId);
mapper.updateChargebackRule(vo);
}
@Transactional
public void deleteChargebackRule(Long cbRuleId) {
mapper.deleteChargebackRule(cbRuleId);
}
// === exception_type_code ===
@Transactional(readOnly = true)
public List<ExceptionTypeCodeVO> listExceptionCodes() {
return mapper.selectExceptionCodes();
}
@Transactional
public void createExceptionCode(ExceptionTypeCodeVO vo) {
if (mapper.selectExceptionCode(vo.getExceptionCode()) != null) {
throw new BizException(ErrorCode.DUPLICATE_DATA);
}
mapper.insertExceptionCode(vo);
}
@Transactional
public void updateExceptionCode(String exceptionCode, ExceptionTypeCodeVO vo) {
vo.setExceptionCode(exceptionCode);
mapper.updateExceptionCode(vo);
}
}
@@ -8,6 +8,7 @@ import com.ga.core.mapper.settle.SettleMasterMapper;
import com.ga.core.vo.settle.SettleMasterResp;
import com.ga.core.vo.settle.SettleMasterVO;
import com.ga.core.vo.settle.SettleSearchParam;
import com.ga.core.vo.settle.SettleStatus;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -44,17 +45,17 @@ public class SettleService {
public void confirm(Long settleId) {
SettleMasterVO vo = masterMapper.selectById(settleId);
if (vo == null) throw new BizException(ErrorCode.NOT_FOUND);
if ("CONFIRMED".equals(vo.getStatus()) || "PAID".equals(vo.getStatus())) {
if (SettleStatus.CONFIRMED.name().equals(vo.getStatus()) || SettleStatus.PAID.name().equals(vo.getStatus())) {
throw new BizException(ErrorCode.ALREADY_CONFIRMED);
}
masterMapper.updateStatus(settleId, "CONFIRMED", SecurityUtil.getCurrentUserId());
masterMapper.updateStatus(settleId, SettleStatus.CONFIRMED.name(), SecurityUtil.getCurrentUserId());
}
@Transactional
public void hold(Long settleId, String reason) {
SettleMasterVO vo = masterMapper.selectById(settleId);
if (vo == null) throw new BizException(ErrorCode.NOT_FOUND);
if ("PAID".equals(vo.getStatus())) {
if (SettleStatus.PAID.name().equals(vo.getStatus())) {
throw new BizException(ErrorCode.NOT_PERMITTED, "지급완료된 정산은 보류할 수 없습니다");
}
masterMapper.updateHold(settleId, reason);
@@ -64,9 +65,9 @@ public class SettleService {
public void release(Long settleId) {
SettleMasterVO vo = masterMapper.selectById(settleId);
if (vo == null) throw new BizException(ErrorCode.NOT_FOUND);
if (!"HOLD".equals(vo.getStatus())) {
if (!SettleStatus.HOLD.name().equals(vo.getStatus())) {
throw new BizException(ErrorCode.INVALID_STATUS, "보류 상태가 아닙니다");
}
masterMapper.updateStatus(settleId, "CALCULATED", SecurityUtil.getCurrentUserId());
masterMapper.updateStatus(settleId, SettleStatus.CALCULATED.name(), SecurityUtil.getCurrentUserId());
}
}
@@ -0,0 +1,66 @@
package com.ga.api.service.system;
import com.ga.common.exception.BizException;
import com.ga.common.exception.ErrorCode;
import com.ga.core.mapper.user.RoleMapper;
import com.ga.core.vo.user.RoleVO;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.Map;
@Service
@RequiredArgsConstructor
public class RoleService {
private final RoleMapper mapper;
@Transactional(readOnly = true)
public List<RoleVO> list() {
return mapper.selectAll();
}
@Transactional(readOnly = true)
public RoleVO detail(Long roleId) {
RoleVO vo = mapper.selectById(roleId);
if (vo == null) throw new BizException(ErrorCode.NOT_FOUND);
return vo;
}
@Transactional(readOnly = true)
public List<Map<String, Object>> permissions(Long roleId) {
return mapper.selectRolePermissions(roleId);
}
@Transactional
public Long create(RoleVO vo) {
mapper.insert(vo);
return vo.getRoleId();
}
@Transactional
public void update(Long roleId, RoleVO vo) {
if (mapper.selectById(roleId) == null) throw new BizException(ErrorCode.NOT_FOUND);
vo.setRoleId(roleId);
mapper.update(vo);
}
@Transactional
public void delete(Long roleId) {
if (mapper.selectById(roleId) == null) throw new BizException(ErrorCode.NOT_FOUND);
mapper.deleteById(roleId);
}
@Transactional
public void savePermissions(Long roleId, List<Map<String, Object>> permissions) {
mapper.deleteRolePermissions(roleId);
for (Map<String, Object> p : permissions) {
Long menuId = ((Number) p.get("menuId")).longValue();
String permCode = (String) p.get("permCode");
String isGranted = (String) p.getOrDefault("isGranted", "Y");
mapper.insertRolePermission(roleId, menuId, permCode, isGranted);
}
}
}