feat: 감사 로그 API 연동, 직원 상세 모달 내 비상연락처 관리 및 프로필 링크 추가, 목록 수정 버튼 제거

This commit is contained in:
pray4skylark
2026-09-30 18:11:14 +09:00
parent e6fbd40ac1
commit df950f258d
5 changed files with 388 additions and 70 deletions
@@ -0,0 +1,37 @@
package com.srsystem.controller;
import com.srsystem.dto.ApiResponse;
import com.srsystem.dto.AuditLogResponse;
import com.srsystem.service.AuditLogService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.web.PageableDefault;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@Tag(name = "Audit Log", description = "감사 로그 조회 API")
@RestController
@RequestMapping("/api/v1/audit-logs")
@RequiredArgsConstructor
@SecurityRequirement(name = "bearerAuth")
public class AuditLogController {
private final AuditLogService auditLogService;
@Operation(summary = "감사 로그 목록 조회", description = "개인정보 열람 및 감사 로그 내역을 조회합니다 (ADMIN전용)")
@PreAuthorize("hasRole('ADMIN')")
@GetMapping
public ResponseEntity<ApiResponse<Page<AuditLogResponse>>> getAuditLogs(
@PageableDefault(size = 50, sort = "createdAt", direction = Sort.Direction.DESC) Pageable pageable) {
Page<AuditLogResponse> logs = auditLogService.getAuditLogs(pageable);
return ResponseEntity.ok(ApiResponse.ok(logs));
}
}
@@ -0,0 +1,16 @@
package com.srsystem.dto;
import java.time.LocalDateTime;
public record AuditLogResponse(
Long id,
String action,
String targetType,
Long targetId,
String targetName,
Long actorId,
String actorName,
String reason,
String ipAddress,
LocalDateTime createdAt
) {}
@@ -0,0 +1,51 @@
package com.srsystem.service;
import com.srsystem.dto.AuditLogResponse;
import com.srsystem.entity.AuditLog;
import com.srsystem.entity.Employee;
import com.srsystem.repository.AuditLogRepository;
import com.srsystem.repository.EmployeeRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class AuditLogService {
private final AuditLogRepository auditLogRepository;
private final EmployeeRepository employeeRepository;
public Page<AuditLogResponse> getAuditLogs(Pageable pageable) {
Page<AuditLog> logPage = auditLogRepository.findAll(pageable);
// Fetch employee names for actorId and targetId
Set<Long> empIds = logPage.getContent().stream()
.flatMap(log -> java.util.stream.Stream.of(log.getActorId(), log.getTargetId()))
.filter(java.util.Objects::nonNull)
.collect(Collectors.toSet());
Map<Long, String> empNameMap = employeeRepository.findAllById(empIds).stream()
.collect(Collectors.toMap(Employee::getEmpId, Employee::getName));
return logPage.map(log -> new AuditLogResponse(
log.getId(),
log.getAction(),
log.getTargetType(),
log.getTargetId(),
log.getTargetId() != null ? empNameMap.getOrDefault(log.getTargetId(), "Emp #" + log.getTargetId()) : null,
log.getActorId(),
log.getActorId() != null ? empNameMap.getOrDefault(log.getActorId(), "Emp #" + log.getActorId()) : null,
log.getReason(),
log.getIpAddress(),
log.getCreatedAt()
));
}
}