From 20d6743c1752c3e3838862535511669e7c9e2dfa Mon Sep 17 00:00:00 2001 From: htlee Date: Wed, 8 Apr 2026 10:52:36 +0900 Subject: [PATCH] =?UTF-8?q?feat(backend):=20Role.colorHex=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20+=20V017=20migration?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - auth_role.color_hex VARCHAR(7) 컬럼 추가 (Flyway V017) - 빌트인 5개 역할 기본 색상 시드 (ADMIN/OPERATOR/ANALYST/FIELD/VIEWER) - Role 엔티티 + RoleCreate/UpdateRequest DTO + RoleManagementService - PermTreeController 응답에 colorHex 필드 포함 --- .../kcg/permission/PermTreeController.java | 19 ++++++++++--------- .../main/java/gc/mda/kcg/permission/Role.java | 4 ++++ .../kcg/permission/RoleManagementService.java | 2 ++ .../kcg/permission/dto/RoleCreateRequest.java | 1 + .../kcg/permission/dto/RoleUpdateRequest.java | 1 + .../db/migration/V017__role_color_hex.sql | 18 ++++++++++++++++++ 6 files changed, 36 insertions(+), 9 deletions(-) create mode 100644 backend/src/main/resources/db/migration/V017__role_color_hex.sql diff --git a/backend/src/main/java/gc/mda/kcg/permission/PermTreeController.java b/backend/src/main/java/gc/mda/kcg/permission/PermTreeController.java index 1e1df65..8736262 100644 --- a/backend/src/main/java/gc/mda/kcg/permission/PermTreeController.java +++ b/backend/src/main/java/gc/mda/kcg/permission/PermTreeController.java @@ -47,15 +47,16 @@ public class PermTreeController { List roles = roleRepository.findAllByOrderByRoleSnAsc(); return roles.stream().>map(r -> { List perms = permRepository.findByRoleSn(r.getRoleSn()); - return Map.of( - "roleSn", r.getRoleSn(), - "roleCd", r.getRoleCd(), - "roleNm", r.getRoleNm(), - "roleDc", r.getRoleDc() == null ? "" : r.getRoleDc(), - "dfltYn", r.getDfltYn(), - "builtinYn", r.getBuiltinYn(), - "permissions", perms - ); + java.util.Map result = new java.util.LinkedHashMap<>(); + result.put("roleSn", r.getRoleSn()); + result.put("roleCd", r.getRoleCd()); + result.put("roleNm", r.getRoleNm()); + result.put("roleDc", r.getRoleDc() == null ? "" : r.getRoleDc()); + result.put("colorHex", r.getColorHex()); + result.put("dfltYn", r.getDfltYn()); + result.put("builtinYn", r.getBuiltinYn()); + result.put("permissions", perms); + return result; }).toList(); } diff --git a/backend/src/main/java/gc/mda/kcg/permission/Role.java b/backend/src/main/java/gc/mda/kcg/permission/Role.java index c8e22de..90b42d2 100644 --- a/backend/src/main/java/gc/mda/kcg/permission/Role.java +++ b/backend/src/main/java/gc/mda/kcg/permission/Role.java @@ -28,6 +28,10 @@ public class Role { @Column(name = "role_dc", columnDefinition = "text") private String roleDc; + /** 역할 UI 표기 색상 (#RRGGBB). NULL 가능 — 프론트가 기본 팔레트 사용. */ + @Column(name = "color_hex", length = 7) + private String colorHex; + @Column(name = "dflt_yn", nullable = false, length = 1) private String dfltYn; diff --git a/backend/src/main/java/gc/mda/kcg/permission/RoleManagementService.java b/backend/src/main/java/gc/mda/kcg/permission/RoleManagementService.java index 57f867b..d4e6a95 100644 --- a/backend/src/main/java/gc/mda/kcg/permission/RoleManagementService.java +++ b/backend/src/main/java/gc/mda/kcg/permission/RoleManagementService.java @@ -38,6 +38,7 @@ public class RoleManagementService { .roleCd(req.roleCd().toUpperCase()) .roleNm(req.roleNm()) .roleDc(req.roleDc()) + .colorHex(req.colorHex()) .dfltYn("Y".equalsIgnoreCase(req.dfltYn()) ? "Y" : "N") .builtinYn("N") .build(); @@ -70,6 +71,7 @@ public class RoleManagementService { } if (req.roleNm() != null) role.setRoleNm(req.roleNm()); if (req.roleDc() != null) role.setRoleDc(req.roleDc()); + if (req.colorHex() != null) role.setColorHex(req.colorHex()); if (req.dfltYn() != null) role.setDfltYn("Y".equalsIgnoreCase(req.dfltYn()) ? "Y" : "N"); return roleRepository.save(role); } diff --git a/backend/src/main/java/gc/mda/kcg/permission/dto/RoleCreateRequest.java b/backend/src/main/java/gc/mda/kcg/permission/dto/RoleCreateRequest.java index 600c750..f8e2d1b 100644 --- a/backend/src/main/java/gc/mda/kcg/permission/dto/RoleCreateRequest.java +++ b/backend/src/main/java/gc/mda/kcg/permission/dto/RoleCreateRequest.java @@ -6,5 +6,6 @@ public record RoleCreateRequest( @NotBlank String roleCd, @NotBlank String roleNm, String roleDc, + String colorHex, String dfltYn ) {} diff --git a/backend/src/main/java/gc/mda/kcg/permission/dto/RoleUpdateRequest.java b/backend/src/main/java/gc/mda/kcg/permission/dto/RoleUpdateRequest.java index 999908d..d932dc8 100644 --- a/backend/src/main/java/gc/mda/kcg/permission/dto/RoleUpdateRequest.java +++ b/backend/src/main/java/gc/mda/kcg/permission/dto/RoleUpdateRequest.java @@ -3,5 +3,6 @@ package gc.mda.kcg.permission.dto; public record RoleUpdateRequest( String roleNm, String roleDc, + String colorHex, String dfltYn ) {} diff --git a/backend/src/main/resources/db/migration/V017__role_color_hex.sql b/backend/src/main/resources/db/migration/V017__role_color_hex.sql new file mode 100644 index 0000000..a5214a1 --- /dev/null +++ b/backend/src/main/resources/db/migration/V017__role_color_hex.sql @@ -0,0 +1,18 @@ +-- ============================================================================ +-- V017: auth_role.color_hex 컬럼 추가 +-- ============================================================================ +-- 역할별 UI 표기 색상을 DB에서 관리. +-- 프론트엔드는 RoleResponse.colorHex로 받아 ColorPicker 카탈로그에 적용. +-- ---------------------------------------------------------------------------- + +ALTER TABLE kcg.auth_role + ADD COLUMN IF NOT EXISTS color_hex VARCHAR(7); + +COMMENT ON COLUMN kcg.auth_role.color_hex IS '역할 표기 색상 (#RRGGBB hex). NULL이면 프론트 기본 팔레트에서 결정.'; + +-- 빌트인 5개 역할의 기본 색상 (기존 프론트 ROLE_COLORS 정책과 매칭) +UPDATE kcg.auth_role SET color_hex = '#ef4444' WHERE role_cd = 'ADMIN'; +UPDATE kcg.auth_role SET color_hex = '#3b82f6' WHERE role_cd = 'OPERATOR'; +UPDATE kcg.auth_role SET color_hex = '#a855f7' WHERE role_cd = 'ANALYST'; +UPDATE kcg.auth_role SET color_hex = '#22c55e' WHERE role_cd = 'FIELD'; +UPDATE kcg.auth_role SET color_hex = '#eab308' WHERE role_cd = 'VIEWER';