feat: admin settings (accounts, system, notification, audit)

This commit is contained in:
pray4skylark
2026-06-02 16:51:51 +09:00
parent f5899aec46
commit 016b7475f7
10 changed files with 1594 additions and 13 deletions
@@ -0,0 +1,62 @@
package com.srsystem.controller;
import com.srsystem.entity.SystemConfig;
import com.srsystem.repository.SystemConfigRepository;
import com.srsystem.dto.ApiResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping("/api/v1/admin/config")
@PreAuthorize("hasRole('ADMIN')")
@RequiredArgsConstructor
public class SystemConfigController {
private final SystemConfigRepository repository;
@GetMapping
public ApiResponse<List<SystemConfig>> getAll() {
return ApiResponse.ok(repository.findAll());
}
@GetMapping("/{key}")
public ApiResponse<SystemConfig> getByKey(@PathVariable String key) {
return repository.findByConfigKey(key)
.map(ApiResponse::ok)
.orElse(ApiResponse.error("설정을 찾을 수 없습니다: " + key));
}
@PutMapping("/{key}")
public ApiResponse<SystemConfig> update(@PathVariable String key, @RequestBody Map<String, String> body) {
String value = body.get("configValue");
if (value == null) {
return ApiResponse.error("configValue가 필요합니다.");
}
SystemConfig config = repository.findByConfigKey(key).orElse(null);
if (config == null) {
config = SystemConfig.builder().configKey(key).createdAt(LocalDateTime.now()).build();
}
config.setConfigValue(value);
config.setUpdatedAt(LocalDateTime.now());
return ApiResponse.ok(repository.save(config));
}
@PutMapping("/batch")
public ApiResponse<List<SystemConfig>> batchUpdate(@RequestBody Map<String, String> entries) {
entries.forEach((k, v) -> {
SystemConfig config = repository.findByConfigKey(k).orElse(null);
if (config == null) {
config = SystemConfig.builder().configKey(k).createdAt(LocalDateTime.now()).build();
}
config.setConfigValue(v);
config.setUpdatedAt(LocalDateTime.now());
repository.save(config);
});
return ApiResponse.ok(repository.findAll());
}
}
@@ -0,0 +1,36 @@
package com.srsystem.entity;
import jakarta.persistence.*;
import lombok.*;
import java.time.LocalDateTime;
@Entity
@Table(name = "tb_system_config")
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class SystemConfig {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seq_system_config")
@SequenceGenerator(name = "seq_system_config", allocationSize = 50)
@Column(name = "config_id")
private Long configId;
@Column(name = "config_key", nullable = false, unique = true, length = 100)
private String configKey;
@Column(name = "config_value", columnDefinition = "TEXT")
private String configValue;
@Column(name = "description", length = 255)
private String description;
@Column(name = "created_at", updatable = false)
private LocalDateTime createdAt;
@Column(name = "updated_at")
private LocalDateTime updatedAt;
}
@@ -0,0 +1,9 @@
package com.srsystem.repository;
import com.srsystem.entity.SystemConfig;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.Optional;
public interface SystemConfigRepository extends JpaRepository<SystemConfig, Long> {
Optional<SystemConfig> findByConfigKey(String configKey);
}
@@ -0,0 +1,21 @@
CREATE TABLE tb_system_config (
config_id BIGSERIAL PRIMARY KEY,
config_key VARCHAR(100) NOT NULL UNIQUE,
config_value TEXT,
description VARCHAR(255),
created_at TIMESTAMP,
updated_at TIMESTAMP
);
INSERT INTO tb_system_config (config_key, config_value, description) VALUES
('sla_check_interval', '3600000', 'SLA 체크 간격 (ms)'),
('sla_excluded_statuses', 'RESOLVED,CLOSED', 'SLA 제외 티켓 상태'),
('parking_enabled', 'false', 'Parking 모드 활성화 여부'),
('parking_weekday_start', '20:00', 'Parking 시작 시간'),
('parking_weekday_end', '08:00', 'Parking 종료 시간'),
('parking_weekends', 'true', '주말 Parking 적용'),
('jwt_access_expiration', '3600000', 'Access Token 만료 시간 (ms)'),
('jwt_refresh_expiration', '604800000', 'Refresh Token 만료 시간 (ms)'),
('notification_slack_enabled', 'false', 'Slack 알림 활성화'),
('notification_email_enabled', 'false', 'Email 알림 활성화'),
('file_upload_max_size', '10485760', '파일 업로드 최대 크기 (bytes)');