package com.gcsc.guide.service; import com.gcsc.guide.dto.RoleResponse; import com.gcsc.guide.entity.Role; import com.gcsc.guide.entity.RoleUrlPattern; import com.gcsc.guide.exception.BusinessException; import com.gcsc.guide.exception.ResourceNotFoundException; import com.gcsc.guide.repository.RoleRepository; import com.gcsc.guide.repository.RoleUrlPatternRepository; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.List; @Service @RequiredArgsConstructor public class RoleService { private final RoleRepository roleRepository; private final RoleUrlPatternRepository roleUrlPatternRepository; @Transactional(readOnly = true) public List getRoles() { return roleRepository.findAllWithUrlPatterns().stream() .map(RoleResponse::from) .toList(); } @Transactional public RoleResponse createRole(String name, String description) { roleRepository.findByName(name).ifPresent(r -> { throw new BusinessException("이미 존재하는 롤 이름입니다: " + name); }); Role role = new Role(name, description); return RoleResponse.from(roleRepository.save(role)); } @Transactional public RoleResponse updateRole(Long roleId, String name, String description) { Role role = findRoleById(roleId); roleRepository.findByName(name) .filter(r -> !r.getId().equals(roleId)) .ifPresent(r -> { throw new BusinessException("이미 존재하는 롤 이름입니다: " + name); }); role.update(name, description); return RoleResponse.from(roleRepository.save(role)); } @Transactional public void deleteRole(Long roleId) { if (!roleRepository.existsById(roleId)) { throw new ResourceNotFoundException("롤", roleId); } roleRepository.deleteById(roleId); } @Transactional(readOnly = true) public List getPermissions(Long roleId) { Role role = roleRepository.findByIdWithUrlPatterns(roleId) .orElseThrow(() -> new ResourceNotFoundException("롤", roleId)); return role.getUrlPatterns().stream() .map(RoleUrlPattern::getUrlPattern) .toList(); } @Transactional public RoleResponse addPermission(Long roleId, String urlPattern) { Role role = roleRepository.findByIdWithUrlPatterns(roleId) .orElseThrow(() -> new ResourceNotFoundException("롤", roleId)); role.getUrlPatterns().add(new RoleUrlPattern(role, urlPattern)); return RoleResponse.from(roleRepository.save(role)); } @Transactional public void deletePermission(Long permissionId) { if (!roleUrlPatternRepository.existsById(permissionId)) { throw new ResourceNotFoundException("권한", permissionId); } roleUrlPatternRepository.deleteById(permissionId); } private Role findRoleById(Long roleId) { return roleRepository.findById(roleId) .orElseThrow(() -> new ResourceNotFoundException("롤", roleId)); } }