diff --git a/build.gradle b/build.gradle index 247d5b1..95f0711 100644 --- a/build.gradle +++ b/build.gradle @@ -92,6 +92,7 @@ clean { } tasks.withType(JavaCompile).configureEach { options.annotationProcessorGeneratedSourcesDirectory = file(generatedSrcDir) + options.encoding = 'UTF-8' } jib { diff --git a/ddl/schema_entity.sql b/ddl/schema_entity.sql index 1d89584..c637e50 100644 --- a/ddl/schema_entity.sql +++ b/ddl/schema_entity.sql @@ -1,291 +1,491 @@ - - create table st_common_code ( - sort_order integer not null, - use_flag boolean not null, - created_at timestamp(6) not null, - created_oid bigint, - oid bigint not null, - updated_at timestamp(6) not null, - updated_oid bigint, - code varchar(50) not null unique, - group_code varchar(50) not null, - parent_code varchar(50), - character_ref1 varchar(100), - character_ref2 varchar(100), - character_ref3 varchar(100), - character_ref4 varchar(100), - character_ref5 varchar(100), - name varchar(100) not null, - description varchar(500), - created_id varchar(255), - updated_id varchar(255), - primary key (oid) - ); - - comment on column st_common_code.sort_order is - '정렬 순번'; - - comment on column st_common_code.use_flag is - '사용 여부'; - - comment on column st_common_code.created_at is - '생성일시'; - - comment on column st_common_code.created_oid is - '생성자 OID'; - - comment on column st_common_code.oid is - 'OID'; - - comment on column st_common_code.updated_at is - '수정일시'; - - comment on column st_common_code.updated_oid is - '수정자 OID'; - - comment on column st_common_code.code is - '코드'; - - comment on column st_common_code.group_code is - '그룹 코드'; - - comment on column st_common_code.parent_code is - '부모 코드'; - - comment on column st_common_code.character_ref1 is - '문자 참조1'; - - comment on column st_common_code.character_ref2 is - '문자 참조2'; - - comment on column st_common_code.character_ref3 is - '문자 참조3'; - - comment on column st_common_code.character_ref4 is - '문자 참조4'; - - comment on column st_common_code.character_ref5 is - '문자 참조5'; - - comment on column st_common_code.name is - '코드명'; - - comment on column st_common_code.description is - '설명'; - - comment on column st_common_code.created_id is - '생성자 ID'; - - comment on column st_common_code.updated_id is - '수정자 ID'; - - create table st_common_group_code ( - sort_order integer not null, - use_flag boolean not null, - created_at timestamp(6) not null, - created_oid bigint, - oid bigint not null, - updated_at timestamp(6) not null, - updated_oid bigint, - code varchar(50) not null unique, - character_ref1_title varchar(100), - character_ref2_title varchar(100), - character_ref3_title varchar(100), - character_ref4_title varchar(100), - character_ref5_title varchar(100), - name varchar(100) not null, - created_id varchar(255), - updated_id varchar(255), - primary key (oid) - ); - - comment on column st_common_group_code.sort_order is - '정렬 순번'; - - comment on column st_common_group_code.use_flag is - '사용 여부'; - - comment on column st_common_group_code.created_at is - '생성일시'; - - comment on column st_common_group_code.created_oid is - '생성자 OID'; - - comment on column st_common_group_code.oid is - 'OID'; - - comment on column st_common_group_code.updated_at is - '수정일시'; - - comment on column st_common_group_code.updated_oid is - '수정자 OID'; - - comment on column st_common_group_code.code is - '코드'; - - comment on column st_common_group_code.character_ref1_title is - '문자 참조 타이틀1'; - - comment on column st_common_group_code.character_ref2_title is - '문자 참조 타이틀2'; - - comment on column st_common_group_code.character_ref3_title is - '문자 참조 타이틀3'; - - comment on column st_common_group_code.character_ref4_title is - '문자 참조 타이틀4'; - - comment on column st_common_group_code.character_ref5_title is - '문자 참조 타이틀5'; - - comment on column st_common_group_code.name is - '코드명'; - - comment on column st_common_group_code.created_id is - '생성자 ID'; - - comment on column st_common_group_code.updated_id is - '수정자 ID'; - - create table st_file ( - use_flag boolean not null, - created_at timestamp(6) not null, - created_oid bigint, - file_size bigint not null, - group_oid bigint, - oid bigint not null, - updated_at timestamp(6) not null, - updated_oid bigint, - content_type varchar(255) not null, - created_id varchar(255), - description varchar(255), - file_path varchar(255) not null, - original_file_name varchar(255) not null, - stored_file_name varchar(255) not null, - updated_id varchar(255), - primary key (oid) - ); - - comment on column st_file.use_flag is - '사용 여부'; - - comment on column st_file.created_at is - '생성일시'; - - comment on column st_file.created_oid is - '생성자 OID'; - - comment on column st_file.file_size is - '파일 크기'; - - comment on column st_file.group_oid is - '그룹 OID'; - - comment on column st_file.oid is - 'OID'; - - comment on column st_file.updated_at is - '수정일시'; - - comment on column st_file.updated_oid is - '수정자 OID'; - - comment on column st_file.content_type is - '콘텐츠 타입'; - - comment on column st_file.created_id is - '생성자 ID'; - - comment on column st_file.description is - '설명'; - - comment on column st_file.file_path is - '파일 경로'; - - comment on column st_file.original_file_name is - '원본 파일명'; - - comment on column st_file.stored_file_name is - '저장 파일명'; - - comment on column st_file.updated_id is - '수정자 ID'; - - create table st_member ( - use_flag boolean not null, - created_at timestamp(6) not null, - created_oid bigint, - last_login_at timestamp(6), - oid bigint not null, - updated_at timestamp(6) not null, - updated_oid bigint, - login_ip varchar(45), - name varchar(100) not null, - password varchar(100) not null, - user_id varchar(100) not null, - refresh_token varchar(1024), - created_id varchar(255), - email varchar(255) not null, - updated_id varchar(255), - primary key (oid) - ); - - comment on column st_member.use_flag is - '사용 여부'; - - comment on column st_member.created_at is - '생성일시'; - - comment on column st_member.created_oid is - '생성자 OID'; - - comment on column st_member.last_login_at is - '마지막 로그인 일시'; - - comment on column st_member.oid is - 'OID'; - - comment on column st_member.updated_at is - '수정일시'; - - comment on column st_member.updated_oid is - '수정자 OID'; - - comment on column st_member.login_ip is - '로그인 IP'; - - comment on column st_member.name is - '이름'; - - comment on column st_member.password is - '비밀번호'; - - comment on column st_member.user_id is - '사용자 ID'; - - comment on column st_member.refresh_token is - '리프레시 토큰'; - - comment on column st_member.created_id is - '생성자 ID'; - - comment on column st_member.email is - '이메일'; - - comment on column st_member.updated_id is - '수정자 ID'; - - create index idx_common_code_code - on st_common_code (code); - - create index idx_common_code_group_code - on st_common_code (group_code); - - create index idx_common_code_parent_code - on st_common_code (parent_code); - - create index idx_common_group_code_code - on st_common_group_code (code); - - create index idx_member_user_id - on st_member (user_id); + + create table st_auth_group ( + created_at timestamp(6) not null, + created_oid bigint, + oid bigint not null, + updated_at timestamp(6) not null, + updated_oid bigint, + name varchar(100), + created_id varchar(255), + updated_id varchar(255), + primary key (oid) + ); + + comment on column st_auth_group.created_at is + '생성일시'; + + comment on column st_auth_group.created_oid is + '생성자 OID'; + + comment on column st_auth_group.oid is + 'OID'; + + comment on column st_auth_group.updated_at is + '수정일시'; + + comment on column st_auth_group.updated_oid is + '수정자 OID'; + + comment on column st_auth_group.name is + '권한 그룹명'; + + comment on column st_auth_group.created_id is + '생성자 ID'; + + comment on column st_auth_group.updated_id is + '수정자 ID'; + + create table st_auth_group_resource ( + auth_group_oid bigint, + created_at timestamp(6) not null, + created_oid bigint, + oid bigint not null, + resource_oid bigint, + updated_at timestamp(6) not null, + updated_oid bigint, + created_id varchar(255), + updated_id varchar(255), + primary key (oid) + ); + + comment on column st_auth_group_resource.auth_group_oid is + '권한 그룹 OID'; + + comment on column st_auth_group_resource.created_at is + '생성일시'; + + comment on column st_auth_group_resource.created_oid is + '생성자 OID'; + + comment on column st_auth_group_resource.oid is + 'OID'; + + comment on column st_auth_group_resource.resource_oid is + '리소스 OID'; + + comment on column st_auth_group_resource.updated_at is + '수정일시'; + + comment on column st_auth_group_resource.updated_oid is + '수정자 OID'; + + comment on column st_auth_group_resource.created_id is + '생성자 ID'; + + comment on column st_auth_group_resource.updated_id is + '수정자 ID'; + + create table st_common_code ( + sort_order integer not null, + use_flag boolean not null, + created_at timestamp(6) not null, + created_oid bigint, + oid bigint not null, + updated_at timestamp(6) not null, + updated_oid bigint, + code varchar(50) not null unique, + group_code varchar(50) not null, + parent_code varchar(50), + character_ref1 varchar(100), + character_ref2 varchar(100), + character_ref3 varchar(100), + character_ref4 varchar(100), + character_ref5 varchar(100), + name varchar(100) not null, + description varchar(500), + created_id varchar(255), + updated_id varchar(255), + primary key (oid) + ); + + comment on column st_common_code.sort_order is + '정렬 순번'; + + comment on column st_common_code.use_flag is + '사용 여부'; + + comment on column st_common_code.created_at is + '생성일시'; + + comment on column st_common_code.created_oid is + '생성자 OID'; + + comment on column st_common_code.oid is + 'OID'; + + comment on column st_common_code.updated_at is + '수정일시'; + + comment on column st_common_code.updated_oid is + '수정자 OID'; + + comment on column st_common_code.code is + '코드'; + + comment on column st_common_code.group_code is + '그룹 코드'; + + comment on column st_common_code.parent_code is + '부모 코드'; + + comment on column st_common_code.character_ref1 is + '문자 참조1'; + + comment on column st_common_code.character_ref2 is + '문자 참조2'; + + comment on column st_common_code.character_ref3 is + '문자 참조3'; + + comment on column st_common_code.character_ref4 is + '문자 참조4'; + + comment on column st_common_code.character_ref5 is + '문자 참조5'; + + comment on column st_common_code.name is + '코드명'; + + comment on column st_common_code.description is + '설명'; + + comment on column st_common_code.created_id is + '생성자 ID'; + + comment on column st_common_code.updated_id is + '수정자 ID'; + + create table st_common_group_code ( + sort_order integer not null, + use_flag boolean not null, + created_at timestamp(6) not null, + created_oid bigint, + oid bigint not null, + updated_at timestamp(6) not null, + updated_oid bigint, + code varchar(50) not null unique, + character_ref1_title varchar(100), + character_ref2_title varchar(100), + character_ref3_title varchar(100), + character_ref4_title varchar(100), + character_ref5_title varchar(100), + name varchar(100) not null, + created_id varchar(255), + updated_id varchar(255), + primary key (oid) + ); + + comment on column st_common_group_code.sort_order is + '정렬 순번'; + + comment on column st_common_group_code.use_flag is + '사용 여부'; + + comment on column st_common_group_code.created_at is + '생성일시'; + + comment on column st_common_group_code.created_oid is + '생성자 OID'; + + comment on column st_common_group_code.oid is + 'OID'; + + comment on column st_common_group_code.updated_at is + '수정일시'; + + comment on column st_common_group_code.updated_oid is + '수정자 OID'; + + comment on column st_common_group_code.code is + '코드'; + + comment on column st_common_group_code.character_ref1_title is + '문자 참조 타이틀1'; + + comment on column st_common_group_code.character_ref2_title is + '문자 참조 타이틀2'; + + comment on column st_common_group_code.character_ref3_title is + '문자 참조 타이틀3'; + + comment on column st_common_group_code.character_ref4_title is + '문자 참조 타이틀4'; + + comment on column st_common_group_code.character_ref5_title is + '문자 참조 타이틀5'; + + comment on column st_common_group_code.name is + '코드명'; + + comment on column st_common_group_code.created_id is + '생성자 ID'; + + comment on column st_common_group_code.updated_id is + '수정자 ID'; + + create table st_file ( + use_flag boolean not null, + created_at timestamp(6) not null, + created_oid bigint, + file_size bigint not null, + group_oid bigint, + oid bigint not null, + updated_at timestamp(6) not null, + updated_oid bigint, + content_type varchar(255) not null, + created_id varchar(255), + description varchar(255), + file_path varchar(255) not null, + original_file_name varchar(255) not null, + stored_file_name varchar(255) not null, + updated_id varchar(255), + primary key (oid) + ); + + comment on column st_file.use_flag is + '사용 여부'; + + comment on column st_file.created_at is + '생성일시'; + + comment on column st_file.created_oid is + '생성자 OID'; + + comment on column st_file.file_size is + '파일 크기'; + + comment on column st_file.group_oid is + '그룹 OID'; + + comment on column st_file.oid is + 'OID'; + + comment on column st_file.updated_at is + '수정일시'; + + comment on column st_file.updated_oid is + '수정자 OID'; + + comment on column st_file.content_type is + '콘텐츠 타입'; + + comment on column st_file.created_id is + '생성자 ID'; + + comment on column st_file.description is + '설명'; + + comment on column st_file.file_path is + '파일 경로'; + + comment on column st_file.original_file_name is + '원본 파일명'; + + comment on column st_file.stored_file_name is + '저장 파일명'; + + comment on column st_file.updated_id is + '수정자 ID'; + + create table st_member ( + use_flag boolean not null, + created_at timestamp(6) not null, + created_oid bigint, + last_login_at timestamp(6), + oid bigint not null, + updated_at timestamp(6) not null, + updated_oid bigint, + login_ip varchar(45), + name varchar(100) not null, + password varchar(100) not null, + user_id varchar(100) not null, + refresh_token varchar(1024), + created_id varchar(255), + email varchar(255) not null, + updated_id varchar(255), + primary key (oid) + ); + + comment on column st_member.use_flag is + '사용 여부'; + + comment on column st_member.created_at is + '생성일시'; + + comment on column st_member.created_oid is + '생성자 OID'; + + comment on column st_member.last_login_at is + '마지막 로그인 일시'; + + comment on column st_member.oid is + 'OID'; + + comment on column st_member.updated_at is + '수정일시'; + + comment on column st_member.updated_oid is + '수정자 OID'; + + comment on column st_member.login_ip is + '로그인 IP'; + + comment on column st_member.name is + '이름'; + + comment on column st_member.password is + '비밀번호'; + + comment on column st_member.user_id is + '사용자 ID'; + + comment on column st_member.refresh_token is + '리프레시 토큰'; + + comment on column st_member.created_id is + '생성자 ID'; + + comment on column st_member.email is + '이메일'; + + comment on column st_member.updated_id is + '수정자 ID'; + + create table st_member_auth_group ( + auth_group_oid bigint, + created_at timestamp(6) not null, + created_oid bigint, + member_oid bigint, + oid bigint not null, + updated_at timestamp(6) not null, + updated_oid bigint, + created_id varchar(255), + updated_id varchar(255), + primary key (oid) + ); + + comment on column st_member_auth_group.auth_group_oid is + '권한 그룹 OID'; + + comment on column st_member_auth_group.created_at is + '생성일시'; + + comment on column st_member_auth_group.created_oid is + '생성자 OID'; + + comment on column st_member_auth_group.member_oid is + '사용자 OID'; + + comment on column st_member_auth_group.oid is + 'OID'; + + comment on column st_member_auth_group.updated_at is + '수정일시'; + + comment on column st_member_auth_group.updated_oid is + '수정자 OID'; + + comment on column st_member_auth_group.created_id is + '생성자 ID'; + + comment on column st_member_auth_group.updated_id is + '수정자 ID'; + + create table st_resource ( + menu_yn boolean, + sort_order integer, + created_at timestamp(6) not null, + created_oid bigint, + oid bigint not null, + parent_code bigint, + updated_at timestamp(6) not null, + updated_oid bigint, + type varchar(50), + code varchar(100), + name varchar(100), + path varchar(100), + created_id varchar(255), + description varchar(255), + updated_id varchar(255), + primary key (oid) + ); + + comment on column st_resource.menu_yn is + '메뉴여부'; + + comment on column st_resource.sort_order is + '정렬 순서'; + + comment on column st_resource.created_at is + '생성일시'; + + comment on column st_resource.created_oid is + '생성자 OID'; + + comment on column st_resource.oid is + 'OID'; + + comment on column st_resource.parent_code is + '부모 코드'; + + comment on column st_resource.updated_at is + '수정일시'; + + comment on column st_resource.updated_oid is + '수정자 OID'; + + comment on column st_resource.type is + '리소스 유형(메뉴, 페이지, 컴포넌트)'; + + comment on column st_resource.code is + '코드'; + + comment on column st_resource.name is + '리소스명'; + + comment on column st_resource.path is + '주소'; + + comment on column st_resource.created_id is + '생성자 ID'; + + comment on column st_resource.description is + '설명'; + + comment on column st_resource.updated_id is + '수정자 ID'; + + create index idx_common_code_code + on st_common_code (code); + + create index idx_common_code_group_code + on st_common_code (group_code); + + create index idx_common_code_parent_code + on st_common_code (parent_code); + + create index idx_common_group_code_code + on st_common_group_code (code); + + create index idx_member_user_id + on st_member (user_id); + + alter table if exists st_auth_group_resource + add constraint FKqw6aih072qipjh1r88f0dbfd6 + foreign key (auth_group_oid) + references st_auth_group; + + alter table if exists st_auth_group_resource + add constraint FKrvq0ta0bwef2kt6ahklo7f3k4 + foreign key (resource_oid) + references st_resource; + + alter table if exists st_member_auth_group + add constraint FKob027cxsjfyvewjb8xp6hjkbm + foreign key (auth_group_oid) + references st_auth_group; + + alter table if exists st_member_auth_group + add constraint FKqew1t81hap15dmn78p8xhunhj + foreign key (member_oid) + references st_member; diff --git a/jpa-curd-0.0.1.vsix b/jpa-curd-0.0.1.vsix index fd32c07..093b2db 100644 Binary files a/jpa-curd-0.0.1.vsix and b/jpa-curd-0.0.1.vsix differ diff --git a/jpa-curd.zip b/jpa-curd.zip new file mode 100644 index 0000000..b2dbc3a Binary files /dev/null and b/jpa-curd.zip differ diff --git a/src/main/java/com/bio/bio_backend/domain/base/authgroup/controller/AuthGroupController.java b/src/main/java/com/bio/bio_backend/domain/base/authgroup/controller/AuthGroupController.java new file mode 100644 index 0000000..3f63e31 --- /dev/null +++ b/src/main/java/com/bio/bio_backend/domain/base/authgroup/controller/AuthGroupController.java @@ -0,0 +1,45 @@ +package com.bio.bio_backend.domain.base.authgroup.controller; + +import com.bio.bio_backend.domain.base.authgroup.dto.AuthGroupDto; +import com.bio.bio_backend.domain.base.authgroup.service.AuthGroupService; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.*; +import lombok.extern.slf4j.Slf4j; +import io.swagger.v3.oas.annotations.tags.Tag; + +import java.util.List; + +@RestController +@RequestMapping("/auth_group") +@RequiredArgsConstructor +@Tag(name = "AuthGroup", description = "") +@Slf4j +public class AuthGroupController { + + private final AuthGroupService authGroupService; + + @PostMapping("/create") + public AuthGroupDto create(@RequestBody AuthGroupDto authGroupDto) { + return authGroupService.create(authGroupDto); + } + + @GetMapping("/{id}") + public AuthGroupDto getById(@PathVariable Long id) { + return authGroupService.getById(id); + } + + @GetMapping + public List getAll() { + return authGroupService.getAll(); + } + + @PutMapping("/{id}") + public AuthGroupDto update(@PathVariable Long id, @RequestBody AuthGroupDto dto) { + return authGroupService.update(id, dto); + } + + @DeleteMapping("/{id}") + public void delete(@PathVariable Long id) { + authGroupService.delete(id); + } +} diff --git a/src/main/java/com/bio/bio_backend/domain/base/authgroup/dto/AuthGroupDto.java b/src/main/java/com/bio/bio_backend/domain/base/authgroup/dto/AuthGroupDto.java new file mode 100644 index 0000000..2ac5dc5 --- /dev/null +++ b/src/main/java/com/bio/bio_backend/domain/base/authgroup/dto/AuthGroupDto.java @@ -0,0 +1,14 @@ +package com.bio.bio_backend.domain.base.authgroup.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class AuthGroupDto { + private String name; +} diff --git a/src/main/java/com/bio/bio_backend/domain/base/authgroup/entity/AuthGroup.java b/src/main/java/com/bio/bio_backend/domain/base/authgroup/entity/AuthGroup.java new file mode 100644 index 0000000..3cd7d45 --- /dev/null +++ b/src/main/java/com/bio/bio_backend/domain/base/authgroup/entity/AuthGroup.java @@ -0,0 +1,27 @@ +package com.bio.bio_backend.domain.base.authgroup.entity; + +import com.bio.bio_backend.global.constants.AppConstants; +import com.bio.bio_backend.global.entity.BaseEntity; + +import jakarta.persistence.*; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +import org.hibernate.annotations.Comment; + +@Entity +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@Table(name = AppConstants.TABLE_PREFIX + "auth_group") +public class AuthGroup extends BaseEntity { + + @Column(name = "name", length = 100) + @Comment("권한 그룹명") + private String name; +} diff --git a/src/main/java/com/bio/bio_backend/domain/base/authgroup/mapper/AuthGroupMapper.java b/src/main/java/com/bio/bio_backend/domain/base/authgroup/mapper/AuthGroupMapper.java new file mode 100644 index 0000000..0765937 --- /dev/null +++ b/src/main/java/com/bio/bio_backend/domain/base/authgroup/mapper/AuthGroupMapper.java @@ -0,0 +1,13 @@ +package com.bio.bio_backend.domain.base.authgroup.mapper; + +import com.bio.bio_backend.global.config.GlobalMapperConfig; +import com.bio.bio_backend.domain.base.authgroup.entity.AuthGroup; +import com.bio.bio_backend.domain.base.authgroup.dto.AuthGroupDto; +import org.mapstruct.Mapper; + +@Mapper(config = GlobalMapperConfig.class) +public interface AuthGroupMapper { + AuthGroup toEntity(AuthGroupDto dto); + + AuthGroupDto toDto(AuthGroup entity); +} diff --git a/src/main/java/com/bio/bio_backend/domain/base/authgroup/repository/AuthGroupRepository.java b/src/main/java/com/bio/bio_backend/domain/base/authgroup/repository/AuthGroupRepository.java new file mode 100644 index 0000000..06a6793 --- /dev/null +++ b/src/main/java/com/bio/bio_backend/domain/base/authgroup/repository/AuthGroupRepository.java @@ -0,0 +1,9 @@ +package com.bio.bio_backend.domain.base.authgroup.repository; + +import com.bio.bio_backend.domain.base.authgroup.entity.AuthGroup; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface AuthGroupRepository extends JpaRepository, AuthGroupRepositoryCustom { +} diff --git a/src/main/java/com/bio/bio_backend/domain/base/authgroup/repository/AuthGroupRepositoryCustom.java b/src/main/java/com/bio/bio_backend/domain/base/authgroup/repository/AuthGroupRepositoryCustom.java new file mode 100644 index 0000000..179a72d --- /dev/null +++ b/src/main/java/com/bio/bio_backend/domain/base/authgroup/repository/AuthGroupRepositoryCustom.java @@ -0,0 +1,12 @@ +package com.bio.bio_backend.domain.base.authgroup.repository; + +import com.bio.bio_backend.domain.base.authgroup.entity.AuthGroup; +import java.util.Optional; + +/** + * QueryDSL을 활용한 커스텀 쿼리 메서드들을 정의하는 인터페이스 + * 복잡한 쿼리나 동적 쿼리가 필요한 경우 이 인터페이스를 구현하여 사용합니다. + */ +public interface AuthGroupRepositoryCustom { + +} diff --git a/src/main/java/com/bio/bio_backend/domain/base/authgroup/repository/AuthGroupRepositoryImpl.java b/src/main/java/com/bio/bio_backend/domain/base/authgroup/repository/AuthGroupRepositoryImpl.java new file mode 100644 index 0000000..28f852a --- /dev/null +++ b/src/main/java/com/bio/bio_backend/domain/base/authgroup/repository/AuthGroupRepositoryImpl.java @@ -0,0 +1,26 @@ +package com.bio.bio_backend.domain.base.authgroup.repository; + +import com.bio.bio_backend.domain.base.authgroup.entity.AuthGroup; +import com.bio.bio_backend.domain.base.authgroup.entity.QAuthGroup; +import com.querydsl.jpa.impl.JPAQueryFactory; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Repository; + +import java.util.Optional; + +/** + * QueryDSL을 활용하여 AuthGroupRepositoryCustom 인터페이스를 구현하는 클래스 + * 복잡한 쿼리나 동적 쿼리를 QueryDSL로 작성하여 성능과 가독성을 향상시킵니다. + */ +@Repository +@RequiredArgsConstructor +public class AuthGroupRepositoryImpl implements AuthGroupRepositoryCustom { + + private final JPAQueryFactory queryFactory; + + /** + * QAuthGroup 인스턴스를 생성하여 쿼리에서 사용합니다. + * QueryDSL의 Q클래스를 통해 타입 안전한 쿼리 작성이 가능합니다. + */ + private final QAuthGroup authGroup = QAuthGroup.authGroup; +} diff --git a/src/main/java/com/bio/bio_backend/domain/base/authgroup/service/AuthGroupService.java b/src/main/java/com/bio/bio_backend/domain/base/authgroup/service/AuthGroupService.java new file mode 100644 index 0000000..4a3f1d9 --- /dev/null +++ b/src/main/java/com/bio/bio_backend/domain/base/authgroup/service/AuthGroupService.java @@ -0,0 +1,16 @@ +package com.bio.bio_backend.domain.base.authgroup.service; + +import com.bio.bio_backend.domain.base.authgroup.dto.AuthGroupDto; +import java.util.List; + +public interface AuthGroupService { + AuthGroupDto create(AuthGroupDto dto); + + AuthGroupDto getById(Long id); + + List getAll(); + + AuthGroupDto update(Long id, AuthGroupDto dto); + + void delete(Long id); +} diff --git a/src/main/java/com/bio/bio_backend/domain/base/authgroup/service/AuthGroupServiceImpl.java b/src/main/java/com/bio/bio_backend/domain/base/authgroup/service/AuthGroupServiceImpl.java new file mode 100644 index 0000000..8fa135c --- /dev/null +++ b/src/main/java/com/bio/bio_backend/domain/base/authgroup/service/AuthGroupServiceImpl.java @@ -0,0 +1,54 @@ +package com.bio.bio_backend.domain.base.authgroup.service; + +import com.bio.bio_backend.domain.base.authgroup.dto.AuthGroupDto; +import com.bio.bio_backend.domain.base.authgroup.entity.AuthGroup; +import com.bio.bio_backend.domain.base.authgroup.repository.AuthGroupRepository; +import com.bio.bio_backend.domain.base.authgroup.mapper.AuthGroupMapper; +import org.springframework.stereotype.Service; +import lombok.RequiredArgsConstructor; + +import java.util.List; +import java.util.stream.Collectors; +import lombok.extern.slf4j.Slf4j; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +@Slf4j +@Transactional(readOnly = true) +public class AuthGroupServiceImpl implements AuthGroupService { + + private final AuthGroupRepository repository; + private final AuthGroupMapper mapper; + + @Override + @Transactional + public AuthGroupDto create(AuthGroupDto dto) { + AuthGroup entity = mapper.toEntity(dto); + return mapper.toDto(repository.save(entity)); + } + + @Override + public AuthGroupDto getById(Long id) { + return repository.findById(id).map(mapper::toDto).orElse(null); + } + + @Override + public List getAll() { + return repository.findAll().stream().map(mapper::toDto).collect(Collectors.toList()); + } + + @Override + @Transactional + public AuthGroupDto update(Long id, AuthGroupDto dto) { + AuthGroup entity = repository.findById(id).orElseThrow(); + // TODO: update fields + return mapper.toDto(repository.save(entity)); + } + + @Override + @Transactional + public void delete(Long id) { + repository.deleteById(id); + } +} diff --git a/src/main/java/com/bio/bio_backend/domain/base/authgroupresource/controller/AuthGroupResourceController.java b/src/main/java/com/bio/bio_backend/domain/base/authgroupresource/controller/AuthGroupResourceController.java new file mode 100644 index 0000000..4ebbe79 --- /dev/null +++ b/src/main/java/com/bio/bio_backend/domain/base/authgroupresource/controller/AuthGroupResourceController.java @@ -0,0 +1,51 @@ +package com.bio.bio_backend.domain.base.authgroupresource.controller; + +import com.bio.bio_backend.domain.base.authgroupresource.dto.AuthGroupResourceDto; +import com.bio.bio_backend.domain.base.authgroupresource.dto.ReplaceAuthGroupResourcesRequest; +import com.bio.bio_backend.domain.base.authgroupresource.service.AuthGroupResourceService; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.*; +import lombok.extern.slf4j.Slf4j; +import io.swagger.v3.oas.annotations.tags.Tag; + +import java.util.List; + +@RestController +@RequestMapping("/auth_group_resource") +@RequiredArgsConstructor +@Tag(name = "AuthGroupResource", description = "") +@Slf4j +public class AuthGroupResourceController { + + private final AuthGroupResourceService service; + + @PostMapping("/create") + public AuthGroupResourceDto create(@RequestBody AuthGroupResourceDto dto) { + return service.create(dto); + } + + @GetMapping("/{id}") + public AuthGroupResourceDto getById(@PathVariable Long id) { + return service.getById(id); + } + + @GetMapping + public List getAll() { + return service.getAll(); + } + + @PutMapping("/{id}") + public AuthGroupResourceDto update(@PathVariable Long id, @RequestBody AuthGroupResourceDto dto) { + return service.update(id, dto); + } + + @DeleteMapping("/{id}") + public void delete(@PathVariable Long id) { + service.delete(id); + } + + @PostMapping("/replace") + public void replaceAuthGroupResources(@RequestBody ReplaceAuthGroupResourcesRequest request) { + service.replaceAuthGroupResources(request.getAuthGroupOid(), request.getResourceOids()); + } +} diff --git a/src/main/java/com/bio/bio_backend/domain/base/authgroupresource/dto/AuthGroupResourceDto.java b/src/main/java/com/bio/bio_backend/domain/base/authgroupresource/dto/AuthGroupResourceDto.java new file mode 100644 index 0000000..47a2596 --- /dev/null +++ b/src/main/java/com/bio/bio_backend/domain/base/authgroupresource/dto/AuthGroupResourceDto.java @@ -0,0 +1,18 @@ +package com.bio.bio_backend.domain.base.authgroupresource.dto; + +import com.bio.bio_backend.domain.base.authgroup.entity.AuthGroup; +import com.bio.bio_backend.domain.base.resource.entity.Resource; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class AuthGroupResourceDto { + private AuthGroup authGroupOid; + private Resource resourceOid; +} diff --git a/src/main/java/com/bio/bio_backend/domain/base/authgroupresource/dto/ReplaceAuthGroupResourcesRequest.java b/src/main/java/com/bio/bio_backend/domain/base/authgroupresource/dto/ReplaceAuthGroupResourcesRequest.java new file mode 100644 index 0000000..20a7c4c --- /dev/null +++ b/src/main/java/com/bio/bio_backend/domain/base/authgroupresource/dto/ReplaceAuthGroupResourcesRequest.java @@ -0,0 +1,12 @@ +package com.bio.bio_backend.domain.base.authgroupresource.dto; + +import java.util.List; + +import lombok.Data; + +@Data +public class ReplaceAuthGroupResourcesRequest { + private Long authGroupOid; + private List resourceOids; +} + diff --git a/src/main/java/com/bio/bio_backend/domain/base/authgroupresource/entity/AuthGroupResource.java b/src/main/java/com/bio/bio_backend/domain/base/authgroupresource/entity/AuthGroupResource.java new file mode 100644 index 0000000..f1e4681 --- /dev/null +++ b/src/main/java/com/bio/bio_backend/domain/base/authgroupresource/entity/AuthGroupResource.java @@ -0,0 +1,36 @@ +package com.bio.bio_backend.domain.base.authgroupresource.entity; + +import com.bio.bio_backend.domain.base.authgroup.entity.AuthGroup; +import com.bio.bio_backend.domain.base.resource.entity.Resource; +import com.bio.bio_backend.global.constants.AppConstants; +import com.bio.bio_backend.global.entity.BaseEntity; + +import jakarta.persistence.*; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +import org.hibernate.annotations.Comment; + +@Entity +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@Table(name = AppConstants.TABLE_PREFIX + "auth_group_resource") + +public class AuthGroupResource extends BaseEntity { + + @JoinColumn(name = "auth_group_oid") + @ManyToOne(fetch = FetchType.LAZY) + @Comment("권한 그룹 OID") + private AuthGroup authGroupOid; + + @JoinColumn(name = "resource_oid") + @ManyToOne(fetch = FetchType.LAZY) + @Comment("리소스 OID") + private Resource resourceOid; +} diff --git a/src/main/java/com/bio/bio_backend/domain/base/authgroupresource/mapper/AuthGroupResourceMapper.java b/src/main/java/com/bio/bio_backend/domain/base/authgroupresource/mapper/AuthGroupResourceMapper.java new file mode 100644 index 0000000..5d4948f --- /dev/null +++ b/src/main/java/com/bio/bio_backend/domain/base/authgroupresource/mapper/AuthGroupResourceMapper.java @@ -0,0 +1,13 @@ +package com.bio.bio_backend.domain.base.authgroupresource.mapper; + +import com.bio.bio_backend.global.config.GlobalMapperConfig; +import com.bio.bio_backend.domain.base.authgroupresource.entity.AuthGroupResource; +import com.bio.bio_backend.domain.base.authgroupresource.dto.AuthGroupResourceDto; +import org.mapstruct.Mapper; + +@Mapper(config = GlobalMapperConfig.class) +public interface AuthGroupResourceMapper { + AuthGroupResource toEntity(AuthGroupResourceDto dto); + + AuthGroupResourceDto toDto(AuthGroupResource entity); +} diff --git a/src/main/java/com/bio/bio_backend/domain/base/authgroupresource/repository/AuthGroupResourceRepository.java b/src/main/java/com/bio/bio_backend/domain/base/authgroupresource/repository/AuthGroupResourceRepository.java new file mode 100644 index 0000000..4755935 --- /dev/null +++ b/src/main/java/com/bio/bio_backend/domain/base/authgroupresource/repository/AuthGroupResourceRepository.java @@ -0,0 +1,17 @@ +package com.bio.bio_backend.domain.base.authgroupresource.repository; + +import com.bio.bio_backend.domain.base.authgroupresource.entity.AuthGroupResource; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Modifying; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; +import org.springframework.stereotype.Repository; + +@Repository +public interface AuthGroupResourceRepository + extends JpaRepository, AuthGroupResourceRepositoryCustom { + + @Modifying + @Query("delete from AuthGroupResource agr where agr.authGroupOid.oid = :authGroupOid") + void deleteByAuthGroupOid(@Param("authGroupOid") Long authGroupOid); +} diff --git a/src/main/java/com/bio/bio_backend/domain/base/authgroupresource/repository/AuthGroupResourceRepositoryCustom.java b/src/main/java/com/bio/bio_backend/domain/base/authgroupresource/repository/AuthGroupResourceRepositoryCustom.java new file mode 100644 index 0000000..ee4eb1e --- /dev/null +++ b/src/main/java/com/bio/bio_backend/domain/base/authgroupresource/repository/AuthGroupResourceRepositoryCustom.java @@ -0,0 +1,12 @@ +package com.bio.bio_backend.domain.base.authgroupresource.repository; + +import com.bio.bio_backend.domain.base.authgroupresource.entity.AuthGroupResource; +import java.util.Optional; + +/** + * QueryDSL을 활용한 커스텀 쿼리 메서드들을 정의하는 인터페이스 + * 복잡한 쿼리나 동적 쿼리가 필요한 경우 이 인터페이스를 구현하여 사용합니다. + */ +public interface AuthGroupResourceRepositoryCustom { + +} diff --git a/src/main/java/com/bio/bio_backend/domain/base/authgroupresource/repository/AuthGroupResourceRepositoryImpl.java b/src/main/java/com/bio/bio_backend/domain/base/authgroupresource/repository/AuthGroupResourceRepositoryImpl.java new file mode 100644 index 0000000..84b5c10 --- /dev/null +++ b/src/main/java/com/bio/bio_backend/domain/base/authgroupresource/repository/AuthGroupResourceRepositoryImpl.java @@ -0,0 +1,26 @@ +package com.bio.bio_backend.domain.base.authgroupresource.repository; + +import com.bio.bio_backend.domain.base.authgroupresource.entity.AuthGroupResource; +import com.bio.bio_backend.domain.base.authgroupresource.entity.QAuthGroupResource; +import com.querydsl.jpa.impl.JPAQueryFactory; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Repository; + +import java.util.Optional; + +/** + * QueryDSL을 활용하여 AuthGroupResourceRepositoryCustom 인터페이스를 구현하는 클래스 + * 복잡한 쿼리나 동적 쿼리를 QueryDSL로 작성하여 성능과 가독성을 향상시킵니다. + */ +@Repository +@RequiredArgsConstructor +public class AuthGroupResourceRepositoryImpl implements AuthGroupResourceRepositoryCustom { + + private final JPAQueryFactory queryFactory; + + /** + * QAuthGroupResource 인스턴스를 생성하여 쿼리에서 사용합니다. + * QueryDSL의 Q클래스를 통해 타입 안전한 쿼리 작성이 가능합니다. + */ + private final QAuthGroupResource authGroupResource = QAuthGroupResource.authGroupResource; +} diff --git a/src/main/java/com/bio/bio_backend/domain/base/authgroupresource/service/AuthGroupResourceService.java b/src/main/java/com/bio/bio_backend/domain/base/authgroupresource/service/AuthGroupResourceService.java new file mode 100644 index 0000000..7abf05f --- /dev/null +++ b/src/main/java/com/bio/bio_backend/domain/base/authgroupresource/service/AuthGroupResourceService.java @@ -0,0 +1,21 @@ +package com.bio.bio_backend.domain.base.authgroupresource.service; + +import com.bio.bio_backend.domain.base.authgroupresource.dto.AuthGroupResourceDto; +import java.util.List; + +public interface AuthGroupResourceService { + AuthGroupResourceDto create(AuthGroupResourceDto dto); + + AuthGroupResourceDto getById(Long id); + + List getAll(); + + AuthGroupResourceDto update(Long id, AuthGroupResourceDto dto); + + void delete(Long id); + + /** + * 특정 authGroupOid의 기존 매핑을 모두 삭제하고, 전달된 resourceOid 목록으로 재등록 + */ + void replaceAuthGroupResources(Long authGroupOid, List resourceOids); +} diff --git a/src/main/java/com/bio/bio_backend/domain/base/authgroupresource/service/AuthGroupResourceServiceImpl.java b/src/main/java/com/bio/bio_backend/domain/base/authgroupresource/service/AuthGroupResourceServiceImpl.java new file mode 100644 index 0000000..3bc6b43 --- /dev/null +++ b/src/main/java/com/bio/bio_backend/domain/base/authgroupresource/service/AuthGroupResourceServiceImpl.java @@ -0,0 +1,80 @@ +package com.bio.bio_backend.domain.base.authgroupresource.service; + +import com.bio.bio_backend.domain.base.authgroupresource.dto.AuthGroupResourceDto; +import com.bio.bio_backend.domain.base.authgroupresource.entity.AuthGroupResource; +import com.bio.bio_backend.domain.base.authgroupresource.repository.AuthGroupResourceRepository; +import com.bio.bio_backend.domain.base.authgroupresource.mapper.AuthGroupResourceMapper; +import org.springframework.stereotype.Service; +import lombok.RequiredArgsConstructor; + +import java.util.List; +import java.util.stream.Collectors; +import lombok.extern.slf4j.Slf4j; +import org.springframework.transaction.annotation.Transactional; +import com.bio.bio_backend.domain.base.authgroup.entity.AuthGroup; +import com.bio.bio_backend.domain.base.resource.entity.Resource; + +@Service +@RequiredArgsConstructor +@Slf4j +@Transactional(readOnly = true) +public class AuthGroupResourceServiceImpl implements AuthGroupResourceService { + + private final AuthGroupResourceRepository repository; + private final AuthGroupResourceMapper mapper; + + @Override + @Transactional + public AuthGroupResourceDto create(AuthGroupResourceDto dto) { + AuthGroupResource entity = mapper.toEntity(dto); + return mapper.toDto(repository.save(entity)); + } + + @Override + public AuthGroupResourceDto getById(Long id) { + return repository.findById(id).map(mapper::toDto).orElse(null); + } + + @Override + public List getAll() { + return repository.findAll().stream().map(mapper::toDto).collect(Collectors.toList()); + } + + @Override + @Transactional + public AuthGroupResourceDto update(Long id, AuthGroupResourceDto dto) { + AuthGroupResource entity = repository.findById(id).orElseThrow(); + // TODO: update fields + return mapper.toDto(repository.save(entity)); + } + + @Override + @Transactional + public void delete(Long id) { + repository.deleteById(id); + } + + @Override + @Transactional + public void replaceAuthGroupResources(Long authGroupOid, List resourceOids) { + repository.deleteByAuthGroupOid(authGroupOid); + + if (resourceOids == null || resourceOids.isEmpty()) { + return; + } + + AuthGroup groupRef = new AuthGroup(); + groupRef.setOid(authGroupOid); + + for (Long resourceOid : resourceOids) { + Resource resourceRef = new Resource(); + resourceRef.setOid(resourceOid); + + AuthGroupResource entity = AuthGroupResource.builder() + .authGroupOid(groupRef) + .resourceOid(resourceRef) + .build(); + repository.save(entity); + } + } +} diff --git a/src/main/java/com/bio/bio_backend/domain/base/memberauthgroup/controller/MemberAuthGroupController.java b/src/main/java/com/bio/bio_backend/domain/base/memberauthgroup/controller/MemberAuthGroupController.java new file mode 100644 index 0000000..c8168e2 --- /dev/null +++ b/src/main/java/com/bio/bio_backend/domain/base/memberauthgroup/controller/MemberAuthGroupController.java @@ -0,0 +1,51 @@ +package com.bio.bio_backend.domain.base.memberauthgroup.controller; + +import com.bio.bio_backend.domain.base.memberauthgroup.dto.MemberAuthGroupDto; +import com.bio.bio_backend.domain.base.memberauthgroup.dto.ReplaceMemberAuthGroupsRequest; +import com.bio.bio_backend.domain.base.memberauthgroup.service.MemberAuthGroupService; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.*; +import lombok.extern.slf4j.Slf4j; +import io.swagger.v3.oas.annotations.tags.Tag; + +import java.util.List; + +@RestController +@RequestMapping("/member_auth_group") +@RequiredArgsConstructor +@Tag(name = "MemberAuthGroup", description = "") +@Slf4j +public class MemberAuthGroupController { + + private final MemberAuthGroupService service; + + @PostMapping + public MemberAuthGroupDto create(@RequestBody MemberAuthGroupDto dto) { + return service.create(dto); + } + + @GetMapping("/{id}") + public MemberAuthGroupDto getById(@PathVariable Long id) { + return service.getById(id); + } + + @GetMapping + public List getAll() { + return service.getAll(); + } + + @PutMapping("/{id}") + public MemberAuthGroupDto update(@PathVariable Long id, @RequestBody MemberAuthGroupDto dto) { + return service.update(id, dto); + } + + @DeleteMapping("/{id}") + public void delete(@PathVariable Long id) { + service.delete(id); + } + + @PostMapping("/replace") + public void replaceMemberAuthGroups(@RequestBody ReplaceMemberAuthGroupsRequest request) { + service.replaceMemberAuthGroups(request.getMemberOid(), request.getAuthGroupOids()); + } +} diff --git a/src/main/java/com/bio/bio_backend/domain/base/memberauthgroup/dto/MemberAuthGroupDto.java b/src/main/java/com/bio/bio_backend/domain/base/memberauthgroup/dto/MemberAuthGroupDto.java new file mode 100644 index 0000000..758c5da --- /dev/null +++ b/src/main/java/com/bio/bio_backend/domain/base/memberauthgroup/dto/MemberAuthGroupDto.java @@ -0,0 +1,18 @@ +package com.bio.bio_backend.domain.base.memberauthgroup.dto; + +import com.bio.bio_backend.domain.base.authgroup.entity.AuthGroup; +import com.bio.bio_backend.domain.base.member.entity.Member; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class MemberAuthGroupDto { + private Member memberOid; + private AuthGroup authGroupOid; +} diff --git a/src/main/java/com/bio/bio_backend/domain/base/memberauthgroup/dto/ReplaceMemberAuthGroupsRequest.java b/src/main/java/com/bio/bio_backend/domain/base/memberauthgroup/dto/ReplaceMemberAuthGroupsRequest.java new file mode 100644 index 0000000..29e1a26 --- /dev/null +++ b/src/main/java/com/bio/bio_backend/domain/base/memberauthgroup/dto/ReplaceMemberAuthGroupsRequest.java @@ -0,0 +1,12 @@ +package com.bio.bio_backend.domain.base.memberauthgroup.dto; + +import java.util.List; + +import lombok.Data; + +@Data +public class ReplaceMemberAuthGroupsRequest { + private Long memberOid; + private List authGroupOids; +} + diff --git a/src/main/java/com/bio/bio_backend/domain/base/memberauthgroup/entity/MemberAuthGroup.java b/src/main/java/com/bio/bio_backend/domain/base/memberauthgroup/entity/MemberAuthGroup.java new file mode 100644 index 0000000..fdffb65 --- /dev/null +++ b/src/main/java/com/bio/bio_backend/domain/base/memberauthgroup/entity/MemberAuthGroup.java @@ -0,0 +1,35 @@ +package com.bio.bio_backend.domain.base.memberauthgroup.entity; + +import com.bio.bio_backend.domain.base.authgroup.entity.AuthGroup; +import com.bio.bio_backend.domain.base.member.entity.Member; +import com.bio.bio_backend.global.constants.AppConstants; +import com.bio.bio_backend.global.entity.BaseEntity; + +import jakarta.persistence.*; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +import org.hibernate.annotations.Comment; + +@Entity +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@Table(name = AppConstants.TABLE_PREFIX + "member_auth_group") +public class MemberAuthGroup extends BaseEntity { + + @Comment("사용자 OID") + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "member_oid") + private Member memberOid; + + @Comment("권한 그룹 OID") + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "auth_group_oid") + private AuthGroup authGroupOid; +} diff --git a/src/main/java/com/bio/bio_backend/domain/base/memberauthgroup/mapper/MemberAuthGroupMapper.java b/src/main/java/com/bio/bio_backend/domain/base/memberauthgroup/mapper/MemberAuthGroupMapper.java new file mode 100644 index 0000000..d601797 --- /dev/null +++ b/src/main/java/com/bio/bio_backend/domain/base/memberauthgroup/mapper/MemberAuthGroupMapper.java @@ -0,0 +1,13 @@ +package com.bio.bio_backend.domain.base.memberauthgroup.mapper; + +import com.bio.bio_backend.global.config.GlobalMapperConfig; +import com.bio.bio_backend.domain.base.memberauthgroup.entity.MemberAuthGroup; +import com.bio.bio_backend.domain.base.memberauthgroup.dto.MemberAuthGroupDto; +import org.mapstruct.Mapper; + +@Mapper(config = GlobalMapperConfig.class) +public interface MemberAuthGroupMapper { + MemberAuthGroup toEntity(MemberAuthGroupDto dto); + + MemberAuthGroupDto toDto(MemberAuthGroup entity); +} diff --git a/src/main/java/com/bio/bio_backend/domain/base/memberauthgroup/repository/MemberAuthGroupRepository.java b/src/main/java/com/bio/bio_backend/domain/base/memberauthgroup/repository/MemberAuthGroupRepository.java new file mode 100644 index 0000000..a4f2398 --- /dev/null +++ b/src/main/java/com/bio/bio_backend/domain/base/memberauthgroup/repository/MemberAuthGroupRepository.java @@ -0,0 +1,17 @@ +package com.bio.bio_backend.domain.base.memberauthgroup.repository; + +import com.bio.bio_backend.domain.base.memberauthgroup.entity.MemberAuthGroup; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Modifying; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; +import org.springframework.stereotype.Repository; + +@Repository +public interface MemberAuthGroupRepository + extends JpaRepository, MemberAuthGroupRepositoryCustom { + + @Modifying + @Query("delete from MemberAuthGroup mag where mag.memberOid.oid = :memberOid") + void deleteByMemberOid(@Param("memberOid") Long memberOid); +} diff --git a/src/main/java/com/bio/bio_backend/domain/base/memberauthgroup/repository/MemberAuthGroupRepositoryCustom.java b/src/main/java/com/bio/bio_backend/domain/base/memberauthgroup/repository/MemberAuthGroupRepositoryCustom.java new file mode 100644 index 0000000..66214ea --- /dev/null +++ b/src/main/java/com/bio/bio_backend/domain/base/memberauthgroup/repository/MemberAuthGroupRepositoryCustom.java @@ -0,0 +1,9 @@ +package com.bio.bio_backend.domain.base.memberauthgroup.repository; + +/** + * QueryDSL을 활용한 커스텀 쿼리 메서드들을 정의하는 인터페이스 + * 복잡한 쿼리나 동적 쿼리가 필요한 경우 이 인터페이스를 구현하여 사용합니다. + */ +public interface MemberAuthGroupRepositoryCustom { + +} diff --git a/src/main/java/com/bio/bio_backend/domain/base/memberauthgroup/repository/MemberAuthGroupRepositoryImpl.java b/src/main/java/com/bio/bio_backend/domain/base/memberauthgroup/repository/MemberAuthGroupRepositoryImpl.java new file mode 100644 index 0000000..d8181db --- /dev/null +++ b/src/main/java/com/bio/bio_backend/domain/base/memberauthgroup/repository/MemberAuthGroupRepositoryImpl.java @@ -0,0 +1,24 @@ +package com.bio.bio_backend.domain.base.memberauthgroup.repository; + +import com.bio.bio_backend.domain.base.memberauthgroup.entity.QMemberAuthGroup; +import com.querydsl.jpa.impl.JPAQueryFactory; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Repository; + + +/** + * QueryDSL을 활용하여 MemberAuthGroupRepositoryCustom 인터페이스를 구현하는 클래스 + * 복잡한 쿼리나 동적 쿼리를 QueryDSL로 작성하여 성능과 가독성을 향상시킵니다. + */ +@Repository +@RequiredArgsConstructor +public class MemberAuthGroupRepositoryImpl implements MemberAuthGroupRepositoryCustom { + + private final JPAQueryFactory queryFactory; + + /** + * QMemberAuthGroup 인스턴스를 생성하여 쿼리에서 사용합니다. + * QueryDSL의 Q클래스를 통해 타입 안전한 쿼리 작성이 가능합니다. + */ + private final QMemberAuthGroup memberAuthGroup = QMemberAuthGroup.memberAuthGroup; +} diff --git a/src/main/java/com/bio/bio_backend/domain/base/memberauthgroup/service/MemberAuthGroupService.java b/src/main/java/com/bio/bio_backend/domain/base/memberauthgroup/service/MemberAuthGroupService.java new file mode 100644 index 0000000..f172b48 --- /dev/null +++ b/src/main/java/com/bio/bio_backend/domain/base/memberauthgroup/service/MemberAuthGroupService.java @@ -0,0 +1,21 @@ +package com.bio.bio_backend.domain.base.memberauthgroup.service; + +import com.bio.bio_backend.domain.base.memberauthgroup.dto.MemberAuthGroupDto; +import java.util.List; + +public interface MemberAuthGroupService { + MemberAuthGroupDto create(MemberAuthGroupDto dto); + + MemberAuthGroupDto getById(Long id); + + List getAll(); + + MemberAuthGroupDto update(Long id, MemberAuthGroupDto dto); + + void delete(Long id); + + /** + * 특정 memberOid의 기존 매핑을 모두 삭제하고, 전달된 authGroupOid 목록으로 재등록 + */ + void replaceMemberAuthGroups(Long memberOid, List authGroupOids); +} diff --git a/src/main/java/com/bio/bio_backend/domain/base/memberauthgroup/service/MemberAuthGroupServiceImpl.java b/src/main/java/com/bio/bio_backend/domain/base/memberauthgroup/service/MemberAuthGroupServiceImpl.java new file mode 100644 index 0000000..c0135a6 --- /dev/null +++ b/src/main/java/com/bio/bio_backend/domain/base/memberauthgroup/service/MemberAuthGroupServiceImpl.java @@ -0,0 +1,80 @@ +package com.bio.bio_backend.domain.base.memberauthgroup.service; + +import com.bio.bio_backend.domain.base.memberauthgroup.dto.MemberAuthGroupDto; +import com.bio.bio_backend.domain.base.memberauthgroup.entity.MemberAuthGroup; +import com.bio.bio_backend.domain.base.memberauthgroup.repository.MemberAuthGroupRepository; +import com.bio.bio_backend.domain.base.memberauthgroup.mapper.MemberAuthGroupMapper; +import org.springframework.stereotype.Service; +import lombok.RequiredArgsConstructor; + +import java.util.List; +import java.util.stream.Collectors; +import lombok.extern.slf4j.Slf4j; +import org.springframework.transaction.annotation.Transactional; +import com.bio.bio_backend.domain.base.authgroup.entity.AuthGroup; +import com.bio.bio_backend.domain.base.member.entity.Member; + +@Service +@RequiredArgsConstructor +@Slf4j +@Transactional(readOnly = true) +public class MemberAuthGroupServiceImpl implements MemberAuthGroupService { + + private final MemberAuthGroupRepository repository; + private final MemberAuthGroupMapper mapper; + + @Override + @Transactional + public MemberAuthGroupDto create(MemberAuthGroupDto dto) { + MemberAuthGroup entity = mapper.toEntity(dto); + return mapper.toDto(repository.save(entity)); + } + + @Override + public MemberAuthGroupDto getById(Long id) { + return repository.findById(id).map(mapper::toDto).orElse(null); + } + + @Override + public List getAll() { + return repository.findAll().stream().map(mapper::toDto).collect(Collectors.toList()); + } + + @Override + @Transactional + public MemberAuthGroupDto update(Long id, MemberAuthGroupDto dto) { + MemberAuthGroup entity = repository.findById(id).orElseThrow(); + // TODO: update fields + return mapper.toDto(repository.save(entity)); + } + + @Override + @Transactional + public void delete(Long id) { + repository.deleteById(id); + } + + @Override + @Transactional + public void replaceMemberAuthGroups(Long memberOid, List authGroupOids) { + repository.deleteByMemberOid(memberOid); + + if (authGroupOids == null || authGroupOids.isEmpty()) { + return; + } + + Member memberRef = new Member(); + memberRef.setOid(memberOid); + + for (Long groupOid : authGroupOids) { + AuthGroup groupRef = new AuthGroup(); + groupRef.setOid(groupOid); + + MemberAuthGroup entity = MemberAuthGroup.builder() + .memberOid(memberRef) + .authGroupOid(groupRef) + .build(); + repository.save(entity); + } + } +} diff --git a/src/main/java/com/bio/bio_backend/domain/base/resource/controller/ResourceController.java b/src/main/java/com/bio/bio_backend/domain/base/resource/controller/ResourceController.java new file mode 100644 index 0000000..c989a3a --- /dev/null +++ b/src/main/java/com/bio/bio_backend/domain/base/resource/controller/ResourceController.java @@ -0,0 +1,50 @@ +package com.bio.bio_backend.domain.base.resource.controller; + +import com.bio.bio_backend.domain.base.resource.dto.ResourceDto; +import com.bio.bio_backend.domain.base.resource.service.ResourceService; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.*; +import lombok.extern.slf4j.Slf4j; +import io.swagger.v3.oas.annotations.tags.Tag; + +import java.util.List; + +@RestController +@RequestMapping("/resource") +@RequiredArgsConstructor +@Tag(name = "Resource", description = "") +@Slf4j +public class ResourceController { + + private final ResourceService service; + + @PostMapping("") + public ResourceDto create(@RequestBody ResourceDto dto) { + return service.createResource(dto); + } + + @PostMapping("/list") + public List createList(@RequestBody List list) { + return service.createResourceList(list); + } + + @GetMapping("/{id}") + public ResourceDto getById(@PathVariable Long id) { + return service.getById(id); + } + + @GetMapping + public List getAll() { + return service.getAll(); + } + + @PutMapping("/{id}") + public ResourceDto update(@PathVariable Long id, @RequestBody ResourceDto dto) { + return service.update(id, dto); + } + + @DeleteMapping("/{id}") + public void delete(@PathVariable Long id) { + service.delete(id); + } +} diff --git a/src/main/java/com/bio/bio_backend/domain/base/resource/dto/ResourceDto.java b/src/main/java/com/bio/bio_backend/domain/base/resource/dto/ResourceDto.java new file mode 100644 index 0000000..3c9f604 --- /dev/null +++ b/src/main/java/com/bio/bio_backend/domain/base/resource/dto/ResourceDto.java @@ -0,0 +1,21 @@ +package com.bio.bio_backend.domain.base.resource.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class ResourceDto { + private String code; + private String name; + private long parentCode; + private String type; + private String path; + private int sortOrder; + private String description; + private boolean menuYn; +} diff --git a/src/main/java/com/bio/bio_backend/domain/base/resource/entity/Resource.java b/src/main/java/com/bio/bio_backend/domain/base/resource/entity/Resource.java new file mode 100644 index 0000000..058cb12 --- /dev/null +++ b/src/main/java/com/bio/bio_backend/domain/base/resource/entity/Resource.java @@ -0,0 +1,56 @@ +package com.bio.bio_backend.domain.base.resource.entity; + +import com.bio.bio_backend.global.constants.AppConstants; +import com.bio.bio_backend.global.entity.BaseEntity; + +import jakarta.persistence.*; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +import org.hibernate.annotations.Comment; + +@Entity +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@Table(name = AppConstants.TABLE_PREFIX + "resource") +public class Resource extends BaseEntity { + + @Column(name = "code", length = 100) + @Comment("코드") + private String code; + + @Column(name = "name", length = 100) + @Comment("리소스명") + private String name; + + @Column(name = "parent_code") + @Comment("부모 코드") + private long parentCode; + + @Column(name = "type", length = 50) + @Comment("리소스 유형(메뉴, 페이지, 컴포넌트)") + private String type; + + @Column(name = "path", length = 100) + @Comment("주소") + private String path; + + @Column(name = "sort_order") + @Comment("정렬 순서") + private int sortOrder; + + @Column(name = "description", length = 255) + @Comment("설명") + private String description; + + @Column(name = "menu_yn") + @Comment("메뉴여부") + private boolean menuYn; + +} diff --git a/src/main/java/com/bio/bio_backend/domain/base/resource/mapper/ResourceMapper.java b/src/main/java/com/bio/bio_backend/domain/base/resource/mapper/ResourceMapper.java new file mode 100644 index 0000000..f6aa653 --- /dev/null +++ b/src/main/java/com/bio/bio_backend/domain/base/resource/mapper/ResourceMapper.java @@ -0,0 +1,13 @@ +package com.bio.bio_backend.domain.base.resource.mapper; + +import com.bio.bio_backend.global.config.GlobalMapperConfig; +import com.bio.bio_backend.domain.base.resource.entity.Resource; +import com.bio.bio_backend.domain.base.resource.dto.ResourceDto; +import org.mapstruct.Mapper; + +@Mapper(config = GlobalMapperConfig.class) +public interface ResourceMapper { + Resource toEntity(ResourceDto dto); + + ResourceDto toDto(Resource entity); +} diff --git a/src/main/java/com/bio/bio_backend/domain/base/resource/repository/ResourceRepository.java b/src/main/java/com/bio/bio_backend/domain/base/resource/repository/ResourceRepository.java new file mode 100644 index 0000000..ba8c0a4 --- /dev/null +++ b/src/main/java/com/bio/bio_backend/domain/base/resource/repository/ResourceRepository.java @@ -0,0 +1,9 @@ +package com.bio.bio_backend.domain.base.resource.repository; + +import com.bio.bio_backend.domain.base.resource.entity.Resource; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface ResourceRepository extends JpaRepository, ResourceRepositoryCustom { +} diff --git a/src/main/java/com/bio/bio_backend/domain/base/resource/repository/ResourceRepositoryCustom.java b/src/main/java/com/bio/bio_backend/domain/base/resource/repository/ResourceRepositoryCustom.java new file mode 100644 index 0000000..13b814b --- /dev/null +++ b/src/main/java/com/bio/bio_backend/domain/base/resource/repository/ResourceRepositoryCustom.java @@ -0,0 +1,15 @@ +package com.bio.bio_backend.domain.base.resource.repository; + +import com.bio.bio_backend.domain.base.resource.entity.Resource; + +import java.util.List; + +/** + * QueryDSL을 활용한 커스텀 쿼리 메서드들을 정의하는 인터페이스 + * 복잡한 쿼리나 동적 쿼리가 필요한 경우 이 인터페이스를 구현하여 사용합니다. + */ +public interface ResourceRepositoryCustom { + + List findResourcesByMemberId(Long memberOId); + +} diff --git a/src/main/java/com/bio/bio_backend/domain/base/resource/repository/ResourceRepositoryImpl.java b/src/main/java/com/bio/bio_backend/domain/base/resource/repository/ResourceRepositoryImpl.java new file mode 100644 index 0000000..27f83e3 --- /dev/null +++ b/src/main/java/com/bio/bio_backend/domain/base/resource/repository/ResourceRepositoryImpl.java @@ -0,0 +1,47 @@ +package com.bio.bio_backend.domain.base.resource.repository; + +import com.bio.bio_backend.domain.base.resource.entity.Resource; +import com.bio.bio_backend.domain.base.authgroup.entity.QAuthGroup; +import com.bio.bio_backend.domain.base.authgroupresource.entity.QAuthGroupResource; +import com.bio.bio_backend.domain.base.memberauthgroup.entity.QMemberAuthGroup; +import com.bio.bio_backend.domain.base.resource.entity.QResource; +import com.querydsl.jpa.impl.JPAQueryFactory; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Repository; + +import java.util.List; + +/** + * QueryDSL을 활용하여 ResourceRepositoryCustom 인터페이스를 구현하는 클래스 + * 복잡한 쿼리나 동적 쿼리를 QueryDSL로 작성하여 성능과 가독성을 향상시킵니다. + */ +@Repository +@RequiredArgsConstructor +public class ResourceRepositoryImpl implements ResourceRepositoryCustom { + + private final JPAQueryFactory queryFactory; + + /** + * QResource 인스턴스를 생성하여 쿼리에서 사용합니다. + * QueryDSL의 Q클래스를 통해 타입 안전한 쿼리 작성이 가능합니다. + */ + // private final QMember member = QMember.member; + private final QMemberAuthGroup memberAuthGroup = QMemberAuthGroup.memberAuthGroup; + private final QAuthGroup authGroup = QAuthGroup.authGroup; + private final QAuthGroupResource authGroupResource = QAuthGroupResource.authGroupResource; + private final QResource resource = QResource.resource; + + @Override + public List findResourcesByMemberId(Long memberOId) { + return queryFactory + .select(resource).distinct() + .from(resource) + // join(연결할 Q-Type).on(연결 조건) 형태로 명시적 조인 + .join(authGroupResource).on(authGroupResource.resourceOid.eq(resource)) + .join(authGroup).on(authGroupResource.authGroupOid.eq(authGroup)) + .join(memberAuthGroup).on(memberAuthGroup.authGroupOid.eq(authGroup)) + // 최종적으로 Member ID로 필터링 + .where(memberAuthGroup.memberOid.oid.eq(memberOId)) + .fetch(); + } +} diff --git a/src/main/java/com/bio/bio_backend/domain/base/resource/service/ResourceService.java b/src/main/java/com/bio/bio_backend/domain/base/resource/service/ResourceService.java new file mode 100644 index 0000000..0bccc4e --- /dev/null +++ b/src/main/java/com/bio/bio_backend/domain/base/resource/service/ResourceService.java @@ -0,0 +1,18 @@ +package com.bio.bio_backend.domain.base.resource.service; + +import com.bio.bio_backend.domain.base.resource.dto.ResourceDto; +import java.util.List; + +public interface ResourceService { + ResourceDto createResource(ResourceDto dto); + + List createResourceList(List list); + + ResourceDto getById(Long id); + + List getAll(); + + ResourceDto update(Long id, ResourceDto dto); + + void delete(Long id); +} diff --git a/src/main/java/com/bio/bio_backend/domain/base/resource/service/ResourceServiceImpl.java b/src/main/java/com/bio/bio_backend/domain/base/resource/service/ResourceServiceImpl.java new file mode 100644 index 0000000..f62c6c7 --- /dev/null +++ b/src/main/java/com/bio/bio_backend/domain/base/resource/service/ResourceServiceImpl.java @@ -0,0 +1,79 @@ +package com.bio.bio_backend.domain.base.resource.service; + +import com.bio.bio_backend.domain.base.resource.dto.ResourceDto; +import com.bio.bio_backend.domain.base.resource.entity.Resource; +import com.bio.bio_backend.domain.base.resource.repository.ResourceRepository; +import com.bio.bio_backend.domain.base.resource.mapper.ResourceMapper; +import org.springframework.stereotype.Service; +import lombok.RequiredArgsConstructor; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; +import lombok.extern.slf4j.Slf4j; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +@Slf4j +@Transactional(readOnly = true) +public class ResourceServiceImpl implements ResourceService { + + private final ResourceRepository repository; + private final ResourceMapper mapper; + + @Override + @Transactional + public ResourceDto createResource(ResourceDto dto) { + try { + Resource entity = mapper.toEntity(dto); + return mapper.toDto(repository.save(entity)); + } catch (Exception e) { + return null; + } + } + + @Transactional + @Override + public List createResourceList(List list) { + + List resultList = new ArrayList<>(); + + for (ResourceDto dto : list) { + try { + Resource entity = mapper.toEntity(dto); + resultList.add(mapper.toDto(repository.save(entity))); + } catch (Exception e) { + ResourceDto resultDto = null; + resultList.add(resultDto); + } + } + + return resultList; + } + + @Override + public ResourceDto getById(Long id) { + return repository.findById(id).map(mapper::toDto).orElse(null); + } + + @Override + public List getAll() { + return repository.findAll().stream().map(mapper::toDto).collect(Collectors.toList()); + } + + @Override + @Transactional + public ResourceDto update(Long id, ResourceDto dto) { + Resource entity = repository.findById(id).orElseThrow(); + // TODO: update fields + return mapper.toDto(repository.save(entity)); + } + + @Override + @Transactional + public void delete(Long id) { + repository.deleteById(id); + } + +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index ccdff03..10bfee1 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -49,6 +49,7 @@ spring.jpa.properties.hibernate.order_updates=true spring.jpa.properties.javax.persistence.schema-generation.scripts.action=create spring.jpa.properties.javax.persistence.schema-generation.scripts.create-target=ddl/schema_entity.sql spring.jpa.properties.hibernate.hbm2ddl.schema-generation.script.append=false +spring.jpa.properties.hibernate.hbm2ddl.charset_name=UTF-8 # ======================================== # 로그 레벨 설정