Skip to content

Commit

Permalink
Feature: 특정 프로젝트 상세 정보 반환 기능 구현 (#100)
Browse files Browse the repository at this point in the history
* feat: 특정 프로젝트 상세 정보 반환 기능 구현

- 프로젝트 더보기 페이지에 반환할 정보
- 이름, 소개글, 깃허브 링크, 비헨스 링크, 프로젝트 링크, 기수, 사진 목록, 멤버 목록

* refactor: 코드 명확성 및 일관성 개선

- 일관된 트랜잭션 관리를 위해 getProjectDetail 클래스에 @transactional 어노테이션을 적용했습니다.

- ProjectDetailResponse에서 generationNumber도 반환되게 수정

- 코드 일관성을 위해 project 관련 repository 메소드 호출 방식 변경
  • Loading branch information
yunhacandy authored Aug 16, 2024
1 parent caba409 commit be377fb
Show file tree
Hide file tree
Showing 9 changed files with 171 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package org.cotato.csquiz.api.project.controller;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.cotato.csquiz.api.project.dto.ProjectDetailResponse;
import org.cotato.csquiz.domain.generation.service.ProjectService;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@Tag(name = "프로젝트 API")
@RestController
@RequiredArgsConstructor
@RequestMapping("/v2/api/projects")
public class ProjectController {

private final ProjectService projectService;

@Operation(summary = "특정 프로젝트 상세 정보 조회 API")
@GetMapping("/{projectId}")
public ResponseEntity<ProjectDetailResponse> getProjectDetail(@PathVariable("projectId") Long projectId) {
return ResponseEntity.ok().body(projectService.getProjectDetail(projectId));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package org.cotato.csquiz.api.project.dto;

import java.util.List;
import org.cotato.csquiz.domain.generation.entity.Project;
import org.cotato.csquiz.domain.generation.entity.ProjectImage;
import org.cotato.csquiz.domain.generation.entity.ProjectMember;

public record ProjectDetailResponse(
Long projectId,
String name,
String introduction,
String githubUrl,
String behanceUrl,
String projectUrl,
Long generationId,
Integer generationNumber,
List<ProjectImageInfoResponse> imageInfos,
List<ProjectMemberInfoResponse> memberInfos
) {
public static ProjectDetailResponse of(Project project, Integer generationNumber, List<ProjectImage> projectImages, List<ProjectMember> projectMembers){
return new ProjectDetailResponse(
project.getId(),
project.getName(),
project.getIntroduction(),
project.getGithubUrl(),
project.getBehanceUrl(),
project.getProjectUrl(),
project.getGenerationId(),
generationNumber,
projectImages.stream()
.map(ProjectImageInfoResponse::from)
.toList(),
projectMembers.stream()
.map(ProjectMemberInfoResponse::from)
.toList()
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package org.cotato.csquiz.api.project.dto;

import org.cotato.csquiz.domain.generation.entity.ProjectImage;
import org.cotato.csquiz.domain.generation.enums.ProjectImageType;

public record ProjectImageInfoResponse(
Long imageId,
String imageUrl,
ProjectImageType projectImageType
) {
public static ProjectImageInfoResponse from(ProjectImage projectImage) {
return new ProjectImageInfoResponse(
projectImage.getId(),
projectImage.getS3Info().getUrl(),
projectImage.getProjectImageType()
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package org.cotato.csquiz.api.project.dto;

import org.cotato.csquiz.domain.auth.enums.MemberPosition;
import org.cotato.csquiz.domain.generation.entity.ProjectMember;

public record ProjectMemberInfoResponse(
Long memberId,
String name,
MemberPosition memberPosition
) {
public static ProjectMemberInfoResponse from(ProjectMember projectMember) {
return new ProjectMemberInfoResponse(
projectMember.getId(),
projectMember.getName(),
projectMember.getMemberPosition()
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,14 @@
import java.util.Optional;
import org.cotato.csquiz.domain.generation.entity.Generation;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

public interface GenerationRepository extends JpaRepository<Generation, Long> {
Optional<Generation> findByNumber(int number);

List<Generation> findByNumberGreaterThanEqual(int generationNumber);

@Query("SELECT g.number FROM Generation g WHERE g.id = :generationId")
Integer findGenerationNumberByGenerationId(@Param("generationId") Long generationId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package org.cotato.csquiz.domain.generation.repository;

import java.util.List;
import org.cotato.csquiz.domain.generation.entity.ProjectImage;
import org.springframework.data.jpa.repository.JpaRepository;

public interface ProjectImageRepository extends JpaRepository<ProjectImage, Long> {
List<ProjectImage> findByProjectId(Long projectId);
List<ProjectImage> findAllByProjectId(Long projectId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package org.cotato.csquiz.domain.generation.repository;

import java.util.List;
import org.cotato.csquiz.domain.generation.entity.ProjectMember;
import org.springframework.data.jpa.repository.JpaRepository;

public interface ProjectMemberRepository extends JpaRepository<ProjectMember, Long> {
List<ProjectMember> findAllByProjectId(Long projectId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package org.cotato.csquiz.domain.generation.repository;

import org.cotato.csquiz.domain.generation.entity.Project;
import org.springframework.data.jpa.repository.JpaRepository;

public interface ProjectRepository extends JpaRepository<Project, Long>{
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package org.cotato.csquiz.domain.generation.service;

import jakarta.persistence.EntityNotFoundException;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.cotato.csquiz.api.project.dto.ProjectDetailResponse;
import org.cotato.csquiz.domain.generation.entity.Project;
import org.cotato.csquiz.domain.generation.entity.ProjectImage;
import org.cotato.csquiz.domain.generation.entity.ProjectMember;
import org.cotato.csquiz.domain.generation.repository.GenerationRepository;
import org.cotato.csquiz.domain.generation.repository.ProjectImageRepository;
import org.cotato.csquiz.domain.generation.repository.ProjectMemberRepository;
import org.cotato.csquiz.domain.generation.repository.ProjectRepository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Transactional(readOnly = true)
@RequiredArgsConstructor
public class ProjectService {

private final ProjectRepository projectRepository;
private final ProjectImageRepository projectImageRepository;
private final ProjectMemberRepository projectMemberRepository;
private final GenerationRepository generationRepository;

@Transactional
public ProjectDetailResponse getProjectDetail(Long projectId) {

Project project = projectRepository.findById(projectId)
.orElseThrow(() -> new EntityNotFoundException("찾으려는 프로젝트가 존재하지 않습니다."));

List<ProjectImage> images = projectImageRepository.findAllByProjectId(projectId);
List<ProjectMember> members = projectMemberRepository.findAllByProjectId(projectId);
Integer generationNumber = generationRepository.findGenerationNumberByGenerationId(project.getGenerationId());

return ProjectDetailResponse.of(project, generationNumber, images, members);
}
}

0 comments on commit be377fb

Please sign in to comment.