- Entity: LoginHistory, PageView, Issue, IssueComment 추가 - Repository: 각 엔티티별 JpaRepository 추가 - Service: UserService, RoleService, ActivityService, IssueService - Admin API: 사용자 관리 7개, 롤/권한 관리 7개, 통계 1개 엔드포인트 - Activity API: 페이지뷰 기록, 로그인 이력 조회 - Issue API: CRUD + 코멘트, 프로젝트/위치/Gitea 링크 지원 - Exception: GlobalExceptionHandler, ResourceNotFoundException, BusinessException - AuthController: 로그인 시 LoginHistory 기록 추가 - Dockerfile 추가 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
89 lines
3.2 KiB
Java
89 lines
3.2 KiB
Java
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<RoleResponse> 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<String> 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));
|
|
}
|
|
}
|