Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: 운영진 관리 기능 구현 완료 #648

Merged
merged 16 commits into from
Jan 4, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public class ApplicationRequestDto {
private String contact;

@NotNull(message = "{notNull.application.email}")
@Schema(description = "이메일", example = "clab.coreteam@gamil.com", required = true)
@Schema(description = "이메일", example = "clab.coreteam@gmail.com", required = true)
private String email;

@NotNull(message = "{notNull.application.department}")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package page.clab.api.domain.memberManagement.executive.adapter.in.web;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import page.clab.api.domain.memberManagement.executive.application.dto.request.ExecutiveRequestDto;
import page.clab.api.domain.memberManagement.executive.application.port.in.RegisterExecutiveUseCase;
import page.clab.api.global.common.dto.ApiResponse;

@RestController
@RequestMapping("/api/v1/executive")
@RequiredArgsConstructor
@Tag(name = "Member Management - Executive", description = "운영진")
public class ExecutiveRegisterController {

private final RegisterExecutiveUseCase registerExecutiveUseCase;

@Operation(summary = "[A] 운영진 등록", description = "ROLE_ADMIN 이상의 권한이 필요함")
@PreAuthorize("hasRole('ADMIN')")
@PostMapping("")
public ApiResponse<String> registerExecutive(
@Valid @RequestBody ExecutiveRequestDto requestDto
) {
String id = registerExecutiveUseCase.registerExecutive(requestDto);
return ApiResponse.success(id);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package page.clab.api.domain.memberManagement.executive.adapter.in.web;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import page.clab.api.domain.memberManagement.executive.application.port.in.RemoveExecutiveUseCase;
import page.clab.api.global.common.dto.ApiResponse;

@RestController
@RequestMapping("/api/v1/executive")
@RequiredArgsConstructor
@Tag(name = "Member Management - Executive", description = "운영진")
public class ExecutiveRemoveController {

private final RemoveExecutiveUseCase removeExecutiveUseCase;

@Operation(summary = "[A] 운영진 정보 삭제", description = "ROLE_ADMIN 이상의 권한이 필요함")
@PreAuthorize("hasRole('ADMIN')")
@DeleteMapping("/{executiveId}")
public ApiResponse<String> removeMember(
@PathVariable(name = "executiveId") String executiveId
) {
String id = removeExecutiveUseCase.removeExecutive(executiveId);
return ApiResponse.success(id);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package page.clab.api.domain.memberManagement.executive.adapter.in.web;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import java.util.List;
import lombok.RequiredArgsConstructor;
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;
import page.clab.api.domain.memberManagement.executive.application.dto.response.ExecutiveResponseDto;
import page.clab.api.domain.memberManagement.executive.application.port.in.RetrieveExecutiveUseCase;
import page.clab.api.global.common.dto.ApiResponse;

@RestController
@RequestMapping("/api/v1/executive")
@RequiredArgsConstructor
@Tag(name = "Member Management - Executive", description = "운영진")
public class ExecutiveRetrievalController {

private final RetrieveExecutiveUseCase retrieveExecutiveUseCase;

@Operation(summary = "[G] 운영진 정보 조회", description = "ROLE_GUEST 이상의 권한이 필요함")
@PreAuthorize("hasRole('GUEST')")
@GetMapping("")
public ApiResponse<List<ExecutiveResponseDto>> retrieveExecutives() {
List<ExecutiveResponseDto> executives = retrieveExecutiveUseCase.retrieveExecutives();
return ApiResponse.success(executives);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package page.clab.api.domain.memberManagement.executive.adapter.in.web;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import page.clab.api.domain.memberManagement.executive.application.dto.request.ExecutiveUpdateRequestDto;
import page.clab.api.domain.memberManagement.executive.application.port.in.UpdateExecutiveUseCase;
import page.clab.api.global.common.dto.ApiResponse;

@RestController
@RequestMapping("/api/v1/executive")
@RequiredArgsConstructor
@Tag(name = "Member Management - Executive", description = "운영진")
public class ExecutiveUpdateController {

private final UpdateExecutiveUseCase updateExecutiveUseCase;

@Operation(summary = "[A] 운영진 정보 수정", description = "ROLE_ADMIN 이상의 권한이 필요함")
@PreAuthorize("hasRole('ADMIN')")
@PatchMapping("/{executiveId}")
public ApiResponse<String> updateExecutive(
@PathVariable(name = "executiveId") String executiveId,
@RequestBody ExecutiveUpdateRequestDto requestDto
) {
String id = updateExecutiveUseCase.updateExecutive(executiveId, requestDto);
return ApiResponse.success(id);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package page.clab.api.domain.memberManagement.executive.adapter.out.persistence;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.Size;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.hibernate.annotations.SQLDelete;
import org.hibernate.annotations.SQLRestriction;
import page.clab.api.global.common.domain.BaseEntity;

@Entity
@Table(name = "executive")
@Getter
@Setter
@Builder
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor(access = AccessLevel.PRIVATE)
@SQLDelete(sql = "UPDATE executive SET is_deleted = true WHERE id = ?")
@SQLRestriction("is_deleted = false")
public class ExecutiveJpaEntity extends BaseEntity {

@Id
@Column(nullable = false, updatable = false, unique = true)
@Size(min = 9, max = 9, message = "{size.executive.id}")
private String id;

@Column(nullable = false)
@Size(min = 1, max = 10, message = "{size.executive.name}")
private String name;

@Column(nullable = false)
@Email(message = "{email.executive.email}")
@Size(min = 1, message = "{size.executive.email}")
private String email;

@Column(nullable = false)
private String interests;

private String imageUrl;

@Column(name = "is_deleted", nullable = false)
private Boolean isDeleted;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package page.clab.api.domain.memberManagement.executive.adapter.out.persistence;

import org.mapstruct.Mapper;
import page.clab.api.domain.memberManagement.executive.domain.Executive;

@Mapper(componentModel = "spring")
public interface ExecutiveMapper {

ExecutiveJpaEntity toEntity(Executive executive);

Executive toDomain(ExecutiveJpaEntity jpaEntity);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package page.clab.api.domain.memberManagement.executive.adapter.out.persistence;

import java.util.List;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import page.clab.api.domain.memberManagement.executive.application.port.out.RegisterExecutivePort;
import page.clab.api.domain.memberManagement.executive.application.port.out.RetrieveExecutivePort;
import page.clab.api.domain.memberManagement.executive.application.port.out.UpdateExecutivePort;
import page.clab.api.domain.memberManagement.executive.domain.Executive;
import page.clab.api.global.exception.NotFoundException;

@Component
@RequiredArgsConstructor
public class ExecutivePersistenceAdapter implements
RegisterExecutivePort,
RetrieveExecutivePort,
UpdateExecutivePort {

private final ExecutiveMapper executiveMapper;
private final ExecutiveRepository executiveRepository;

@Override
public Executive save(Executive executive) {
ExecutiveJpaEntity jpaEntity = executiveMapper.toEntity(executive);
ExecutiveJpaEntity savedEntity = executiveRepository.save(jpaEntity);
return executiveMapper.toDomain(savedEntity);
}

@Override
public Executive update(Executive executive) {
ExecutiveJpaEntity jpaEntity = executiveMapper.toEntity(executive);
ExecutiveJpaEntity savedEntity = executiveRepository.save(jpaEntity);
return executiveMapper.toDomain(savedEntity);
}

@Override
public List<Executive> findAll() {
List<ExecutiveJpaEntity> jpaEntities = executiveRepository.findAll();
return jpaEntities.stream()
.map(executiveMapper::toDomain)
.collect(Collectors.toList());
}

@Override
public Executive getById(String executiveId) {
ExecutiveJpaEntity jpaEntity = executiveRepository.findById(executiveId)
.orElseThrow(() -> new NotFoundException("[Executive] id: " + executiveId + "에 해당하는 운영진이 존재하지 않습니다."));
return executiveMapper.toDomain(jpaEntity);
}

@Override
public Boolean existsById(String executiveId) {
return executiveRepository.existsById(executiveId);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package page.clab.api.domain.memberManagement.executive.adapter.out.persistence;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface ExecutiveRepository extends JpaRepository<ExecutiveJpaEntity, String> {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package page.clab.api.domain.memberManagement.executive.application.dto.mapper;

import org.springframework.stereotype.Component;
import page.clab.api.domain.memberManagement.executive.application.dto.request.ExecutiveRequestDto;
import page.clab.api.domain.memberManagement.executive.application.dto.response.ExecutiveResponseDto;
import page.clab.api.domain.memberManagement.executive.domain.Executive;

@Component
public class ExecutiveDtoMapper {

public Executive fromDto(ExecutiveRequestDto requestDto) {
return Executive.builder()
.id(requestDto.getExecutiveId())
.name(requestDto.getName())
.email(requestDto.getEmail())
.interests(requestDto.getInterests())
.imageUrl(requestDto.getImageUrl())
.isDeleted(false)
.build();
}

public ExecutiveResponseDto toDto(Executive executive, String position) {
return ExecutiveResponseDto.builder()
.executiveId(executive.getId())
.name(executive.getName())
.email(executive.getEmail())
.interests(executive.getInterests())
.position(position)
.imageUrl(executive.getImageUrl())
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package page.clab.api.domain.memberManagement.executive.application.dto.request;

import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class ExecutiveRequestDto {

@NotNull(message = "{notNull.executive.executiveId}")
@Schema(description = "학번", example = "202310000")
private String executiveId;

@NotNull(message = "{notNull.executive.name}")
@Schema(description = "이름", example = "홍길동")
private String name;

@NotNull(message = "{notNull.executive.email}")
@Schema(description = "이메일", example = "[email protected]")
private String email;

@NotNull(message = "{notNull.executive.interests}")
@Schema(description = "분야", example = "Back-End")
private String interests;

@Schema(description = "프로필 이미지", example = "https://www.clab.page/assets/dongmin-860f3a1e.jpeg")
private String imageUrl;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package page.clab.api.domain.memberManagement.executive.application.dto.request;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class ExecutiveUpdateRequestDto {

@Schema(description = "이름", example = "홍길동")
private String name;

@Schema(description = "이메일", example = "[email protected]")
private String email;

@Schema(description = "분야", example = "Back-End")
private String interests;

@Schema(description = "프로필 이미지", example = "https://www.clab.page/assets/dongmin-860f3a1e.jpeg")
private String imageUrl;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package page.clab.api.domain.memberManagement.executive.application.dto.response;

import lombok.Builder;
import lombok.Getter;

@Getter
@Builder
public class ExecutiveResponseDto {

private String executiveId;
private String name;
private String email;
private String interests;
private String position;
private String imageUrl;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package page.clab.api.domain.memberManagement.executive.application.exception;

public class ExecutiveRegistrationException extends RuntimeException {

public ExecutiveRegistrationException(String message) {
super(message);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package page.clab.api.domain.memberManagement.executive.application.port.in;

import page.clab.api.domain.memberManagement.executive.application.dto.request.ExecutiveRequestDto;

public interface RegisterExecutiveUseCase {
String registerExecutive(ExecutiveRequestDto requestDto);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package page.clab.api.domain.memberManagement.executive.application.port.in;

public interface RemoveExecutiveUseCase {
String removeExecutive(String executiveId);
}
Loading
Loading