diff --git a/get-p-api/src/main/java/es/princip/getp/api/controller/project/command/AssignmentPeopleController.java b/get-p-api/src/main/java/es/princip/getp/api/controller/project/command/AssignmentPeopleController.java new file mode 100644 index 00000000..4551189a --- /dev/null +++ b/get-p-api/src/main/java/es/princip/getp/api/controller/project/command/AssignmentPeopleController.java @@ -0,0 +1,48 @@ +package es.princip.getp.api.controller.project.command; + +import es.princip.getp.api.controller.project.command.dto.request.AssignmentPeopleRequest; +import es.princip.getp.api.support.dto.ApiResponse; +import es.princip.getp.api.support.dto.ApiResponse.ApiSuccessResult; +import es.princip.getp.application.auth.service.PrincipalDetails; +import es.princip.getp.application.project.assign.dto.command.AssignmentPeopleCommand; +import es.princip.getp.application.project.assign.dto.response.AssignmentPeopleResponse; +import es.princip.getp.application.project.assign.port.in.AssignmentPeopleUseCase; +import es.princip.getp.domain.member.model.MemberId; +import es.princip.getp.domain.project.commission.model.ProjectId; +import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.security.core.annotation.AuthenticationPrincipal; +import org.springframework.web.bind.annotation.*; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/projects") +public class AssignmentPeopleController { + private final AssignmentPeopleUseCase confirmationProjectUseCase; + private final ProjectCommandMapper projectCommandMapper; + + /** + * 확정자 할당 + * + * @param request 프로젝트 확정자 할당 요청 + * @param principalDetails 로그인한 사용자 정보 + * @param projectId 프로젝트 ID + */ + @PostMapping("/{projectId}/assignment") + @PreAuthorize("hasRole('CLIENT') and isAuthenticated()") + public ResponseEntity> assignmentPeople( + @RequestBody @Valid final AssignmentPeopleRequest request, + @AuthenticationPrincipal final PrincipalDetails principalDetails, + @PathVariable Long projectId + ) { + final MemberId memberId = principalDetails.getMember().getId(); + final ProjectId pid = new ProjectId(projectId); + final AssignmentPeopleCommand command = projectCommandMapper.mapToCommand(memberId, pid, request); + final Long confirmationId = confirmationProjectUseCase.assign(command).getValue(); + final AssignmentPeopleResponse response = new AssignmentPeopleResponse(confirmationId); + return ApiResponse.success(HttpStatus.CREATED, response); + } +} \ No newline at end of file diff --git a/get-p-api/src/main/java/es/princip/getp/api/controller/project/command/ProjectCommandMapper.java b/get-p-api/src/main/java/es/princip/getp/api/controller/project/command/ProjectCommandMapper.java index b330f01d..82413a66 100644 --- a/get-p-api/src/main/java/es/princip/getp/api/controller/project/command/ProjectCommandMapper.java +++ b/get-p-api/src/main/java/es/princip/getp/api/controller/project/command/ProjectCommandMapper.java @@ -8,6 +8,7 @@ import es.princip.getp.application.project.apply.dto.command.ApplyProjectAsIndividualCommand; import es.princip.getp.application.project.apply.dto.command.ApplyProjectAsTeamCommand; import es.princip.getp.application.project.apply.dto.command.ApplyProjectCommand; +import es.princip.getp.application.project.assign.dto.command.AssignmentPeopleCommand; import es.princip.getp.application.project.commission.dto.command.CommissionProjectCommand; import es.princip.getp.application.project.meeting.dto.command.ScheduleMeetingCommand; import es.princip.getp.domain.common.model.AttachmentFile; @@ -25,9 +26,9 @@ abstract class ProjectCommandMapper { ApplyProjectCommand mapToCommand( - Member member, - ProjectId projectId, - ApplyProjectRequest request + Member member, + ProjectId projectId, + ApplyProjectRequest request ) { if (request instanceof ApplyProjectAsIndividualRequest req) { return mapToCommand(member, projectId, req); @@ -42,9 +43,9 @@ ApplyProjectCommand mapToCommand( @Mapping(source = "request.description", target = "description") @Mapping(source = "request.attachmentFiles", target = "attachmentFiles") protected abstract ApplyProjectAsIndividualCommand mapToCommand( - Member member, - ProjectId projectId, - ApplyProjectAsIndividualRequest request + Member member, + ProjectId projectId, + ApplyProjectAsIndividualRequest request ); @Mapping(source = "request.expectedDuration", target = "expectedDuration") @@ -52,22 +53,29 @@ protected abstract ApplyProjectAsIndividualCommand mapToCommand( @Mapping(source = "request.attachmentFiles", target = "attachmentFiles") @Mapping(source = "request.teammates", target = "teammates") protected abstract ApplyProjectAsTeamCommand mapToCommand( - Member member, - ProjectId projectId, - ApplyProjectAsTeamRequest request + Member member, + ProjectId projectId, + ApplyProjectAsTeamRequest request ); protected abstract AttachmentFile mapToAttachmentFile(URL url); abstract CommissionProjectCommand mapToCommand( - MemberId memberId, - CommissionProjectRequest request + MemberId memberId, + CommissionProjectRequest request ); @Mapping(source = "request.applicantId", target = "applicantId.value") abstract ScheduleMeetingCommand mapToCommand( - MemberId memberId, - ProjectId projectId, - ScheduleMeetingRequest request + MemberId memberId, + ProjectId projectId, + ScheduleMeetingRequest request + ); + + @Mapping(source = "request.applicantId", target = "applicantId.value") + abstract AssignmentPeopleCommand mapToCommand( + MemberId memberId, + ProjectId projectId, + AssignmentPeopleRequest request ); } diff --git a/get-p-api/src/main/java/es/princip/getp/api/controller/project/command/dto/request/AssignmentPeopleRequest.java b/get-p-api/src/main/java/es/princip/getp/api/controller/project/command/dto/request/AssignmentPeopleRequest.java new file mode 100644 index 00000000..6d925295 --- /dev/null +++ b/get-p-api/src/main/java/es/princip/getp/api/controller/project/command/dto/request/AssignmentPeopleRequest.java @@ -0,0 +1,6 @@ +package es.princip.getp.api.controller.project.command.dto.request; + +public record AssignmentPeopleRequest( + Long applicantId +) { +} diff --git a/get-p-api/src/test/java/es/princip/getp/api/controller/project/command/AssignmentPeopleControllerTest.java b/get-p-api/src/test/java/es/princip/getp/api/controller/project/command/AssignmentPeopleControllerTest.java new file mode 100644 index 00000000..dc3429e7 --- /dev/null +++ b/get-p-api/src/test/java/es/princip/getp/api/controller/project/command/AssignmentPeopleControllerTest.java @@ -0,0 +1,72 @@ +package es.princip.getp.api.controller.project.command; + +import com.epages.restdocs.apispec.ResourceSnippetParameters; +import com.epages.restdocs.apispec.Schema; +import es.princip.getp.api.controller.project.command.dto.request.AssignmentPeopleRequest; +import es.princip.getp.api.security.annotation.WithCustomMockUser; +import es.princip.getp.api.support.ControllerTest; +import es.princip.getp.application.project.assign.dto.command.AssignmentPeopleCommand; +import es.princip.getp.application.project.assign.port.in.AssignmentPeopleUseCase; +import es.princip.getp.domain.member.model.MemberType; +import es.princip.getp.domain.project.commission.model.ProjectId; +import es.princip.getp.domain.project.confirmation.model.AssignmentPeopleId; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.web.servlet.ResultActions; + +import static com.epages.restdocs.apispec.MockMvcRestDocumentationWrapper.document; +import static es.princip.getp.api.controller.project.command.description.ConfirmProjectRequestDescription.confirmProjectRequestDescription; +import static es.princip.getp.api.controller.project.command.description.ConfirmProjectResponseDescription.confirmProjectResponseDescription; +import static es.princip.getp.api.controller.project.command.fixture.AssignmentPeopleRequestFixture.assignmentPeopleRequest; +import static es.princip.getp.api.docs.HeaderDescriptorHelper.authorizationHeaderDescription; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.BDDMockito.given; +import static org.springframework.restdocs.headers.HeaderDocumentation.requestHeaders; +import static org.springframework.restdocs.payload.PayloadDocumentation.requestFields; +import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields; +import static org.springframework.restdocs.request.RequestDocumentation.parameterWithName; +import static org.springframework.restdocs.request.RequestDocumentation.pathParameters; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +class AssignmentPeopleControllerTest extends ControllerTest { + + @Autowired private AssignmentPeopleUseCase assignmentPeopleUseCase; + + @Nested + class 프로젝트_확정 { + private final ProjectId projectId = new ProjectId(1L); + private final AssignmentPeopleId assignmentPeopleId = new AssignmentPeopleId(1L); + + private ResultActions perform(final AssignmentPeopleRequest request) throws Exception { + return mockMvc.perform(post("/projects/{projectId}/assignment", projectId.getValue()) + .header("Authorization", "Bearer ${ACCESS_TOKEN}") + .content(objectMapper.writeValueAsString(request))); + } + + @Test + @WithCustomMockUser(memberType = MemberType.ROLE_CLIENT) + void 의뢰자는_지원자를_확정할_수_있다() throws Exception { + final AssignmentPeopleRequest request = assignmentPeopleRequest(); + given(assignmentPeopleUseCase.assign(any(AssignmentPeopleCommand.class))) + .willReturn(assignmentPeopleId); + + perform(request) + .andExpect(status().isCreated()) + .andDo(document("project/assignment", + ResourceSnippetParameters.builder() + .tag("프로젝트 지원자 확정") + .description("의뢰자는 지원자를 확정할 수 있다.") + .summary("프로젝트 확정") + .requestSchema(Schema.schema("AssignmentPeopleRequest")) + .responseSchema(Schema.schema("AssignmentPeopleResponse")), + requestHeaders(authorizationHeaderDescription()), + pathParameters(parameterWithName("projectId").description("프로젝트 ID")), + requestFields(confirmProjectRequestDescription()), + responseFields(confirmProjectResponseDescription()) + )) + .andDo(print()); + } + } +} \ No newline at end of file diff --git a/get-p-api/src/test/java/es/princip/getp/api/controller/project/command/description/ConfirmProjectRequestDescription.java b/get-p-api/src/test/java/es/princip/getp/api/controller/project/command/description/ConfirmProjectRequestDescription.java new file mode 100644 index 00000000..42e46f39 --- /dev/null +++ b/get-p-api/src/test/java/es/princip/getp/api/controller/project/command/description/ConfirmProjectRequestDescription.java @@ -0,0 +1,16 @@ +package es.princip.getp.api.controller.project.command.description; + +import es.princip.getp.api.controller.project.command.dto.request.AssignmentPeopleRequest; +import org.springframework.restdocs.payload.FieldDescriptor; + +import static es.princip.getp.api.docs.ConstraintDescriptor.fieldWithConstraint; + +public class ConfirmProjectRequestDescription { + + public static FieldDescriptor[] confirmProjectRequestDescription() { + final Class clazz = AssignmentPeopleRequest.class; + return new FieldDescriptor[] { + fieldWithConstraint("applicantId", clazz).description("지원자 ID") + }; + } +} diff --git a/get-p-api/src/test/java/es/princip/getp/api/controller/project/command/description/ConfirmProjectResponseDescription.java b/get-p-api/src/test/java/es/princip/getp/api/controller/project/command/description/ConfirmProjectResponseDescription.java new file mode 100644 index 00000000..40d45bc4 --- /dev/null +++ b/get-p-api/src/test/java/es/princip/getp/api/controller/project/command/description/ConfirmProjectResponseDescription.java @@ -0,0 +1,15 @@ +package es.princip.getp.api.controller.project.command.description; + +import org.springframework.restdocs.payload.FieldDescriptor; + +import static es.princip.getp.api.docs.StatusFieldDescriptor.statusField; +import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath; + +public class ConfirmProjectResponseDescription { + public static FieldDescriptor[] confirmProjectResponseDescription() { + return new FieldDescriptor[] { + statusField(), + fieldWithPath("data.assignmentId").description("할당 ID"), + }; + } +} diff --git a/get-p-api/src/test/java/es/princip/getp/api/controller/project/command/fixture/AssignmentPeopleRequestFixture.java b/get-p-api/src/test/java/es/princip/getp/api/controller/project/command/fixture/AssignmentPeopleRequestFixture.java new file mode 100644 index 00000000..8a78b912 --- /dev/null +++ b/get-p-api/src/test/java/es/princip/getp/api/controller/project/command/fixture/AssignmentPeopleRequestFixture.java @@ -0,0 +1,9 @@ +package es.princip.getp.api.controller.project.command.fixture; + +import es.princip.getp.api.controller.project.command.dto.request.AssignmentPeopleRequest; + +public class AssignmentPeopleRequestFixture { + public static AssignmentPeopleRequest assignmentPeopleRequest() { + return new AssignmentPeopleRequest(1L); + } +} diff --git a/get-p-application/src/main/java/es/princip/getp/application/project/apply/port/out/LoadProjectApplicantPort.java b/get-p-application/src/main/java/es/princip/getp/application/project/apply/port/out/LoadProjectApplicantPort.java index fe0afe7d..69136883 100644 --- a/get-p-application/src/main/java/es/princip/getp/application/project/apply/port/out/LoadProjectApplicantPort.java +++ b/get-p-application/src/main/java/es/princip/getp/application/project/apply/port/out/LoadProjectApplicantPort.java @@ -1,9 +1,13 @@ package es.princip.getp.application.project.apply.port.out; +import es.princip.getp.domain.people.model.PeopleId; import es.princip.getp.domain.project.apply.model.ProjectApplication; import es.princip.getp.domain.project.apply.model.ProjectApplicationId; +import es.princip.getp.domain.project.commission.model.ProjectId; public interface LoadProjectApplicantPort { ProjectApplication loadBy(ProjectApplicationId applicationId); + + ProjectApplication loadBy(ProjectId projectId, PeopleId peopleId); } diff --git a/get-p-application/src/main/java/es/princip/getp/application/project/assign/AssignmentPeopleService.java b/get-p-application/src/main/java/es/princip/getp/application/project/assign/AssignmentPeopleService.java new file mode 100644 index 00000000..105401d5 --- /dev/null +++ b/get-p-application/src/main/java/es/princip/getp/application/project/assign/AssignmentPeopleService.java @@ -0,0 +1,84 @@ +package es.princip.getp.application.project.assign; + +import es.princip.getp.application.client.port.out.LoadClientPort; +import es.princip.getp.application.people.port.out.LoadPeoplePort; +import es.princip.getp.application.project.apply.port.out.CheckProjectApplicationPort; +import es.princip.getp.application.project.apply.port.out.LoadProjectApplicantPort; +import es.princip.getp.application.project.apply.port.out.UpdateProjectApplicantPort; +import es.princip.getp.application.project.assign.dto.command.AssignmentPeopleCommand; +import es.princip.getp.application.project.commission.port.out.LoadProjectPort; +import es.princip.getp.application.project.assign.port.in.AssignmentPeopleUseCase; +import es.princip.getp.application.project.assign.port.out.SaveAssignmentPeoplePort; +import es.princip.getp.application.project.meeting.exception.NotApplicantException; +import es.princip.getp.application.project.meeting.exception.NotClientOfProjectException; +import es.princip.getp.domain.client.model.Client; +import es.princip.getp.domain.people.model.People; +import es.princip.getp.domain.people.model.PeopleId; +import es.princip.getp.domain.project.apply.model.ProjectApplication; +import es.princip.getp.domain.project.commission.model.Project; +import es.princip.getp.domain.project.commission.model.ProjectId; +import es.princip.getp.domain.project.confirmation.model.AssignmentPeople; +import es.princip.getp.domain.project.confirmation.model.AssignmentPeopleId; +import es.princip.getp.domain.project.confirmation.service.AssignPeople; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Slf4j +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class AssignmentPeopleService implements AssignmentPeopleUseCase { + + private final SaveAssignmentPeoplePort saveProjectConfirmationPort; + private final UpdateProjectApplicantPort updateProjectApplicantPort; + private final LoadProjectApplicantPort loadProjectApplicantPort; + private final LoadPeoplePort loadPeoplePort; + private final LoadClientPort loadClientPort; + private final LoadProjectPort loadProjectPort; + + private final CheckProjectApplicationPort checkProjectApplicationPort; + + private final AssignPeople assignPeople; + + /** + * 진행자 할당 + * @param command 진행자 할당 명령 + * @return ProjectConfirmation ID + */ + @Transactional + public AssignmentPeopleId assign(AssignmentPeopleCommand command) { + Client client = loadClientPort.loadBy(command.memberId()); + Project project = loadProjectPort.loadBy(command.projectId()); + + checkPeopleIsApplicant(command.applicantId(), command.projectId()); + checkClientOfProject(client, project); + + final People people = loadPeoplePort.loadBy(command.applicantId()); + final ProjectApplication projectApplication = loadProjectApplicantPort.loadBy(command.projectId(), command.applicantId()); + + final AssignmentPeople projectConfirmation = assignPeople.confirm(project, people, projectApplication); + projectApplicationConfirm(projectApplication); + + AssignmentPeopleId id = new AssignmentPeopleId(saveProjectConfirmationPort.save(projectConfirmation)); + return id; + } + + private void checkClientOfProject(final Client client, final Project project) { + if (!project.isClient(client)) { + throw new NotClientOfProjectException(); + } + } + + private void checkPeopleIsApplicant(final PeopleId applicantId, final ProjectId projectId) { + if (!checkProjectApplicationPort.existsBy(applicantId, projectId)) { + throw new NotApplicantException(); + } + } + + private void projectApplicationConfirm(ProjectApplication projectApplication) { + projectApplication.confirm(); + updateProjectApplicantPort.update(projectApplication); + } +} diff --git a/get-p-application/src/main/java/es/princip/getp/application/project/assign/dto/command/AssignmentPeopleCommand.java b/get-p-application/src/main/java/es/princip/getp/application/project/assign/dto/command/AssignmentPeopleCommand.java new file mode 100644 index 00000000..da2303a7 --- /dev/null +++ b/get-p-application/src/main/java/es/princip/getp/application/project/assign/dto/command/AssignmentPeopleCommand.java @@ -0,0 +1,11 @@ +package es.princip.getp.application.project.assign.dto.command; + +import es.princip.getp.domain.member.model.MemberId; +import es.princip.getp.domain.people.model.PeopleId; +import es.princip.getp.domain.project.commission.model.ProjectId; + +public record AssignmentPeopleCommand( + MemberId memberId, + ProjectId projectId, + PeopleId applicantId +) {} diff --git a/get-p-application/src/main/java/es/princip/getp/application/project/assign/dto/response/AssignmentPeopleResponse.java b/get-p-application/src/main/java/es/princip/getp/application/project/assign/dto/response/AssignmentPeopleResponse.java new file mode 100644 index 00000000..824bdb93 --- /dev/null +++ b/get-p-application/src/main/java/es/princip/getp/application/project/assign/dto/response/AssignmentPeopleResponse.java @@ -0,0 +1,6 @@ +package es.princip.getp.application.project.assign.dto.response; + +public record AssignmentPeopleResponse( + Long assignmentId +) { +} \ No newline at end of file diff --git a/get-p-application/src/main/java/es/princip/getp/application/project/assign/port/in/AssignmentPeopleUseCase.java b/get-p-application/src/main/java/es/princip/getp/application/project/assign/port/in/AssignmentPeopleUseCase.java new file mode 100644 index 00000000..b80bab73 --- /dev/null +++ b/get-p-application/src/main/java/es/princip/getp/application/project/assign/port/in/AssignmentPeopleUseCase.java @@ -0,0 +1,8 @@ +package es.princip.getp.application.project.assign.port.in; + +import es.princip.getp.application.project.assign.dto.command.AssignmentPeopleCommand; +import es.princip.getp.domain.project.confirmation.model.AssignmentPeopleId; + +public interface AssignmentPeopleUseCase { + AssignmentPeopleId assign(AssignmentPeopleCommand command); +} diff --git a/get-p-application/src/main/java/es/princip/getp/application/project/assign/port/out/SaveAssignmentPeoplePort.java b/get-p-application/src/main/java/es/princip/getp/application/project/assign/port/out/SaveAssignmentPeoplePort.java new file mode 100644 index 00000000..151db7dd --- /dev/null +++ b/get-p-application/src/main/java/es/princip/getp/application/project/assign/port/out/SaveAssignmentPeoplePort.java @@ -0,0 +1,7 @@ +package es.princip.getp.application.project.assign.port.out; + +import es.princip.getp.domain.project.confirmation.model.AssignmentPeople; + +public interface SaveAssignmentPeoplePort { + Long save(AssignmentPeople projectConfirmation); +} diff --git a/get-p-application/src/main/java/es/princip/getp/application/project/meeting/ProjectMeetingService.java b/get-p-application/src/main/java/es/princip/getp/application/project/meeting/ProjectMeetingService.java index fce04014..47369989 100644 --- a/get-p-application/src/main/java/es/princip/getp/application/project/meeting/ProjectMeetingService.java +++ b/get-p-application/src/main/java/es/princip/getp/application/project/meeting/ProjectMeetingService.java @@ -3,6 +3,8 @@ import es.princip.getp.application.client.port.out.LoadClientPort; import es.princip.getp.application.people.port.out.LoadPeoplePort; import es.princip.getp.application.project.apply.port.out.CheckProjectApplicationPort; +import es.princip.getp.application.project.apply.port.out.LoadProjectApplicantPort; +import es.princip.getp.application.project.apply.port.out.UpdateProjectApplicantPort; import es.princip.getp.application.project.commission.port.out.LoadProjectPort; import es.princip.getp.application.project.meeting.dto.command.ScheduleMeetingCommand; import es.princip.getp.application.project.meeting.exception.NotApplicantException; @@ -11,9 +13,11 @@ import es.princip.getp.domain.client.model.Client; import es.princip.getp.domain.people.model.People; import es.princip.getp.domain.people.model.PeopleId; +import es.princip.getp.domain.project.apply.model.ProjectApplication; import es.princip.getp.domain.project.commission.model.Project; import es.princip.getp.domain.project.commission.model.ProjectId; import es.princip.getp.domain.project.meeting.model.ProjectMeeting; +import es.princip.getp.domain.project.meeting.service.ProjectMeetingScheduler; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -25,11 +29,15 @@ public class ProjectMeetingService { private final LoadClientPort loadClientPort; private final LoadPeoplePort loadPeoplePort; + private final LoadProjectApplicantPort loadProjectApplicantPort; private final LoadProjectPort loadProjectPort; + private final UpdateProjectApplicantPort updateProjectApplicantPort; private final CheckProjectApplicationPort checkProjectApplicationPort; private final SaveProjectMeetingPort saveProjectMeetingPort; + private final ProjectMeetingScheduler projectMeetingScheduler; + private final MeetingSender meetingSender; /** @@ -41,22 +49,26 @@ public class ProjectMeetingService { @Transactional public Long scheduleMeeting(final ScheduleMeetingCommand command) { final People people = loadPeoplePort.loadBy(command.applicantId()); - final Project project = loadProjectPort.loadBy(command.projectId()); + final ProjectApplication projectApplication = loadProjectApplicantPort.loadBy(command.projectId(), command.applicantId()); final Client client = loadClientPort.loadBy(command.memberId()); + final Project project = loadProjectPort.loadBy(projectApplication.getProjectId()); checkClientOfProject(client, project); - checkPeopleIsApplicant(command.applicantId(), command.projectId()); + checkPeopleIsApplicant(command.applicantId(), projectApplication.getProjectId()); - final ProjectMeeting projectMeeting = ProjectMeeting.builder() - .projectId(command.projectId()) - .applicantId(command.applicantId()) - .location(command.location()) - .schedule(command.schedule()) - .phoneNumber(command.phoneNumber()) - .description(command.description()) - .build(); + final ProjectMeeting projectMeeting = projectMeetingScheduler.schedule( + project, + people, + projectApplication, + command.location(), + command.schedule(), + command.phoneNumber(), + command.description() + ); + projectApplicationMeetingComplete(projectApplication); final Long meetingId = saveProjectMeetingPort.save(projectMeeting); + meetingSender.send(people, project, projectMeeting); return meetingId; @@ -73,4 +85,9 @@ private void checkPeopleIsApplicant(final PeopleId applicantId, final ProjectId throw new NotApplicantException(); } } + + private void projectApplicationMeetingComplete(ProjectApplication projectApplication) { + projectApplication.meetingComplete(); + updateProjectApplicantPort.update(projectApplication); + } } diff --git a/get-p-domain/src/main/java/es/princip/getp/domain/project/apply/model/ProjectApplication.java b/get-p-domain/src/main/java/es/princip/getp/domain/project/apply/model/ProjectApplication.java index a98fcc4c..9a27cc12 100644 --- a/get-p-domain/src/main/java/es/princip/getp/domain/project/apply/model/ProjectApplication.java +++ b/get-p-domain/src/main/java/es/princip/getp/domain/project/apply/model/ProjectApplication.java @@ -54,4 +54,16 @@ public boolean isApplicant(final PeopleId peopleId) { public boolean isCompleted() { return this.status == ProjectApplicationStatus.COMPLETED; } + + public boolean isMeetingCompleted() { + return this.status == ProjectApplicationStatus.MEETING_COMPLETED; + } + + public void meetingComplete() { + this.status = ProjectApplicationStatus.MEETING_COMPLETED; + } + + public void confirm() { + this.status = ProjectApplicationStatus.ACCEPTED; + } } diff --git a/get-p-domain/src/main/java/es/princip/getp/domain/project/apply/model/ProjectApplicationStatus.java b/get-p-domain/src/main/java/es/princip/getp/domain/project/apply/model/ProjectApplicationStatus.java index 3d9f2d0a..4e10f6ad 100644 --- a/get-p-domain/src/main/java/es/princip/getp/domain/project/apply/model/ProjectApplicationStatus.java +++ b/get-p-domain/src/main/java/es/princip/getp/domain/project/apply/model/ProjectApplicationStatus.java @@ -3,7 +3,6 @@ public enum ProjectApplicationStatus { PENDING_TEAM_APPROVAL, // 팀원 승인 대기 COMPLETED, // 지원 완료 - WAITING_MEETING, // 미팅 준비 MEETING_COMPLETED, // 미팅 완료 ACCEPTED, // 확정 CLOSED // 모집 마감 diff --git a/get-p-domain/src/main/java/es/princip/getp/domain/project/confirmation/exception/NotCompletedProjectMeetingException.java b/get-p-domain/src/main/java/es/princip/getp/domain/project/confirmation/exception/NotCompletedProjectMeetingException.java new file mode 100644 index 00000000..99bd50ca --- /dev/null +++ b/get-p-domain/src/main/java/es/princip/getp/domain/project/confirmation/exception/NotCompletedProjectMeetingException.java @@ -0,0 +1,14 @@ +package es.princip.getp.domain.project.confirmation.exception; + +import es.princip.getp.domain.support.DomainLogicException; +import es.princip.getp.domain.support.ErrorDescription; + +public class NotCompletedProjectMeetingException extends DomainLogicException { + + private static final String code = "NOT_COMPLETED_PROJECT_MEETING"; + private static final String message = "미팅이 완료되지 않은 프로젝트는 확정할 수 없습니다."; + + public NotCompletedProjectMeetingException() { + super(ErrorDescription.of(code, message)); + } +} diff --git a/get-p-domain/src/main/java/es/princip/getp/domain/project/confirmation/model/AssignmentPeople.java b/get-p-domain/src/main/java/es/princip/getp/domain/project/confirmation/model/AssignmentPeople.java new file mode 100644 index 00000000..428c842e --- /dev/null +++ b/get-p-domain/src/main/java/es/princip/getp/domain/project/confirmation/model/AssignmentPeople.java @@ -0,0 +1,33 @@ +package es.princip.getp.domain.project.confirmation.model; + +import es.princip.getp.domain.people.model.PeopleId; +import es.princip.getp.domain.project.commission.model.ProjectId; +import es.princip.getp.domain.support.BaseEntity; +import jakarta.validation.constraints.NotNull; +import lombok.Builder; +import lombok.Getter; + +import java.time.LocalDateTime; + +@Getter +public class AssignmentPeople extends BaseEntity { + + private AssignmentPeopleId assignmentPeopleId; + @NotNull private ProjectId projectId; + @NotNull private PeopleId applicantId; + + @Builder + public AssignmentPeople( + final ProjectId projectId, + final PeopleId applicantId, + final LocalDateTime createdAt, + final LocalDateTime updatedAt + ) { + super(createdAt, updatedAt); + + this.projectId = projectId; + this.applicantId = applicantId; + + validate(); + } +} diff --git a/get-p-domain/src/main/java/es/princip/getp/domain/project/confirmation/model/AssignmentPeopleId.java b/get-p-domain/src/main/java/es/princip/getp/domain/project/confirmation/model/AssignmentPeopleId.java new file mode 100644 index 00000000..d1dda072 --- /dev/null +++ b/get-p-domain/src/main/java/es/princip/getp/domain/project/confirmation/model/AssignmentPeopleId.java @@ -0,0 +1,19 @@ +package es.princip.getp.domain.project.confirmation.model; + +import es.princip.getp.domain.support.BaseModel; +import jakarta.validation.constraints.NotNull; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.ToString; + +@Getter +@ToString +@EqualsAndHashCode(callSuper = false) +public class AssignmentPeopleId extends BaseModel { + + @NotNull private final Long value; + + public AssignmentPeopleId(final Long value) { + this.value = value; + } +} diff --git a/get-p-domain/src/main/java/es/princip/getp/domain/project/confirmation/service/AssignPeople.java b/get-p-domain/src/main/java/es/princip/getp/domain/project/confirmation/service/AssignPeople.java new file mode 100644 index 00000000..6804bb96 --- /dev/null +++ b/get-p-domain/src/main/java/es/princip/getp/domain/project/confirmation/service/AssignPeople.java @@ -0,0 +1,28 @@ +package es.princip.getp.domain.project.confirmation.service; + +import es.princip.getp.domain.people.model.People; +import es.princip.getp.domain.project.apply.model.ProjectApplication; +import es.princip.getp.domain.project.commission.model.Project; +import es.princip.getp.domain.project.confirmation.exception.NotCompletedProjectMeetingException; +import es.princip.getp.domain.project.confirmation.model.AssignmentPeople; +import org.springframework.stereotype.Component; + + +@Component +public class AssignPeople { + + public AssignmentPeople confirm( + final Project project, + final People people, + final ProjectApplication projectApplication + ) { + if (!projectApplication.isMeetingCompleted()) { + throw new NotCompletedProjectMeetingException(); + } + + return AssignmentPeople.builder() + .applicantId(people.getId()) + .projectId(project.getId()) + .build(); + } +} diff --git a/get-p-domain/src/main/java/es/princip/getp/domain/project/meeting/exception/NotConfirmedProjectException.java b/get-p-domain/src/main/java/es/princip/getp/domain/project/meeting/exception/NotConfirmedProjectException.java new file mode 100644 index 00000000..373221f5 --- /dev/null +++ b/get-p-domain/src/main/java/es/princip/getp/domain/project/meeting/exception/NotConfirmedProjectException.java @@ -0,0 +1,14 @@ +package es.princip.getp.domain.project.meeting.exception; + +import es.princip.getp.domain.support.DomainLogicException; +import es.princip.getp.domain.support.ErrorDescription; + +public class NotConfirmedProjectException extends DomainLogicException { + + private static final String code = "NOT_CONFIRMED_PROJECT"; + private static final String message = "미팅이 완료되지 않은 프로젝트는 확정할 수 없습니다."; + + public NotConfirmedProjectException() { + super(ErrorDescription.of(code, message)); + } +} diff --git a/get-p-domain/src/main/java/es/princip/getp/domain/project/meeting/service/ProjectMeetingScheduler.java b/get-p-domain/src/main/java/es/princip/getp/domain/project/meeting/service/ProjectMeetingScheduler.java new file mode 100644 index 00000000..813eb657 --- /dev/null +++ b/get-p-domain/src/main/java/es/princip/getp/domain/project/meeting/service/ProjectMeetingScheduler.java @@ -0,0 +1,36 @@ +package es.princip.getp.domain.project.meeting.service; + +import es.princip.getp.domain.common.model.MeetingSchedule; +import es.princip.getp.domain.common.model.PhoneNumber; +import es.princip.getp.domain.people.model.People; +import es.princip.getp.domain.project.apply.model.ProjectApplication; +import es.princip.getp.domain.project.commission.model.Project; +import es.princip.getp.domain.project.meeting.exception.NotConfirmedProjectException; +import es.princip.getp.domain.project.meeting.model.ProjectMeeting; +import org.springframework.stereotype.Component; + +@Component +public class ProjectMeetingScheduler { + public ProjectMeeting schedule( + final Project project, + final People applicant, + final ProjectApplication projectApplication, + final String location, + final MeetingSchedule schedule, + final PhoneNumber phoneNumber, + final String description + ) { + if (!projectApplication.isCompleted()) { + throw new NotConfirmedProjectException(); + } + + return ProjectMeeting.builder() + .projectId(project.getId()) + .applicantId(applicant.getId()) + .location(location) + .schedule(schedule) + .phoneNumber(phoneNumber) + .description(description) + .build(); + } +} diff --git a/get-p-domain/src/test/java/es/princip/getp/domain/project/confirmation/service/AssignPeopleTest.java b/get-p-domain/src/test/java/es/princip/getp/domain/project/confirmation/service/AssignPeopleTest.java new file mode 100644 index 00000000..8310669e --- /dev/null +++ b/get-p-domain/src/test/java/es/princip/getp/domain/project/confirmation/service/AssignPeopleTest.java @@ -0,0 +1,60 @@ +package es.princip.getp.domain.project.confirmation.service; + +import es.princip.getp.domain.client.model.ClientId; +import es.princip.getp.domain.member.model.MemberId; +import es.princip.getp.domain.people.model.People; +import es.princip.getp.domain.people.model.PeopleId; +import es.princip.getp.domain.project.apply.model.ProjectApplication; +import es.princip.getp.domain.project.apply.model.ProjectApplicationStatus; +import es.princip.getp.domain.project.commission.model.Project; +import es.princip.getp.domain.project.commission.model.ProjectId; +import es.princip.getp.domain.project.confirmation.exception.NotCompletedProjectMeetingException; +import es.princip.getp.domain.project.confirmation.model.AssignmentPeople; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; + +import static es.princip.getp.domain.project.commission.model.ProjectStatus.APPLICATION_OPENED; +import static es.princip.getp.fixture.people.PeopleFixture.people; +import static es.princip.getp.fixture.project.ProjectApplicationFixture.individualProjectApplication; +import static es.princip.getp.fixture.project.ProjectFixture.project; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.spy; + +@ExtendWith(MockitoExtension.class) +class AssignPeopleTest { + + private final AssignPeople assignPeople = new AssignPeople(); + private final ClientId clientId = new ClientId(1L); + + @Test + void 지원자는_미팅완료를_하면_확정_지원자가_될_수_있다() { + final People applicant = spy(people(new MemberId(1L))); + given(applicant.getId()).willReturn(new PeopleId(1L)); + final Project project = spy(project(new ClientId(1L), APPLICATION_OPENED)); + given(project.getId()).willReturn(new ProjectId(1L)); + final ProjectApplication application = spy(individualProjectApplication( + applicant.getId(), project.getId(), ProjectApplicationStatus.MEETING_COMPLETED + )); + + AssignmentPeople projectConfirmation = assignPeople.confirm(project, applicant, application); + + assertThat(projectConfirmation).isNotNull(); + } + + @Test + void 지원자는_미팅완료를_하지않으면_확정_지원자가_될_수_없다() { + final People applicant = spy(people(new MemberId(1L))); + given(applicant.getId()).willReturn(new PeopleId(1L)); + final Project project = spy(project(new ClientId(1L), APPLICATION_OPENED)); + given(project.getId()).willReturn(new ProjectId(1L)); + final ProjectApplication application = spy(individualProjectApplication( + applicant.getId(), project.getId(), ProjectApplicationStatus.COMPLETED + )); + + Assertions.assertThatThrownBy(() -> assignPeople.confirm(project, applicant, application)) + .isInstanceOf(NotCompletedProjectMeetingException.class); + } +} \ No newline at end of file diff --git a/get-p-domain/src/testFixtures/java/es/princip/getp/fixture/project/ProjectApplicationFixture.java b/get-p-domain/src/testFixtures/java/es/princip/getp/fixture/project/ProjectApplicationFixture.java index 93d2a779..46d8a4f8 100644 --- a/get-p-domain/src/testFixtures/java/es/princip/getp/fixture/project/ProjectApplicationFixture.java +++ b/get-p-domain/src/testFixtures/java/es/princip/getp/fixture/project/ProjectApplicationFixture.java @@ -47,6 +47,18 @@ public static ProjectApplication individualProjectApplication( .build(); } + public static ProjectApplication individualProjectApplication( + final PeopleId peopleId, + final ProjectId projectId, + final ProjectApplicationStatus status + ) { + return individualBuilder() + .applicantId(peopleId) + .projectId(projectId) + .status(status) + .build(); + } + public static ProjectApplication individualProjectApplication( final ProjectApplicationId applicationId, final PeopleId peopleId, diff --git a/get-p-persistence/src/main/java/es/princip/getp/persistence/adapter/project/ProjectPersistenceMapper.java b/get-p-persistence/src/main/java/es/princip/getp/persistence/adapter/project/ProjectPersistenceMapper.java index b635c976..c318edc1 100644 --- a/get-p-persistence/src/main/java/es/princip/getp/persistence/adapter/project/ProjectPersistenceMapper.java +++ b/get-p-persistence/src/main/java/es/princip/getp/persistence/adapter/project/ProjectPersistenceMapper.java @@ -3,7 +3,7 @@ import es.princip.getp.domain.project.commission.model.Project; import es.princip.getp.persistence.adapter.common.mapper.AttachmentFilePersistenceMapper; import es.princip.getp.persistence.adapter.common.mapper.HashtagPersistenceMapper; -import es.princip.getp.persistence.adapter.project.commission.ProjectJpaEntity; +import es.princip.getp.persistence.adapter.project.commission.model.ProjectJpaEntity; import org.mapstruct.InheritInverseConfiguration; import org.mapstruct.Mapper; import org.mapstruct.Mapping; diff --git a/get-p-persistence/src/main/java/es/princip/getp/persistence/adapter/project/ProjectQueryMapper.java b/get-p-persistence/src/main/java/es/princip/getp/persistence/adapter/project/ProjectQueryMapper.java index 86a3c56d..1437d043 100644 --- a/get-p-persistence/src/main/java/es/princip/getp/persistence/adapter/project/ProjectQueryMapper.java +++ b/get-p-persistence/src/main/java/es/princip/getp/persistence/adapter/project/ProjectQueryMapper.java @@ -3,7 +3,7 @@ import es.princip.getp.application.project.commission.dto.response.ProjectClientResponse; import es.princip.getp.application.project.commission.dto.response.ProjectDetailResponse; import es.princip.getp.persistence.adapter.common.mapper.DurationPersistenceMapper; -import es.princip.getp.persistence.adapter.project.commission.ProjectJpaEntity; +import es.princip.getp.persistence.adapter.project.commission.model.ProjectJpaEntity; import org.mapstruct.Mapper; import org.mapstruct.Mapping; diff --git a/get-p-persistence/src/main/java/es/princip/getp/persistence/adapter/project/apply/ProjectApplicationJpaRepository.java b/get-p-persistence/src/main/java/es/princip/getp/persistence/adapter/project/apply/ProjectApplicationJpaRepository.java index bdc1668a..9dc5e64c 100644 --- a/get-p-persistence/src/main/java/es/princip/getp/persistence/adapter/project/apply/ProjectApplicationJpaRepository.java +++ b/get-p-persistence/src/main/java/es/princip/getp/persistence/adapter/project/apply/ProjectApplicationJpaRepository.java @@ -1,11 +1,16 @@ package es.princip.getp.persistence.adapter.project.apply; +import es.princip.getp.domain.project.apply.model.ProjectApplication; import es.princip.getp.persistence.adapter.project.apply.model.ProjectApplicationJpaEntity; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; +import java.util.Optional; + @Repository interface ProjectApplicationJpaRepository extends JpaRepository { boolean existsByApplicantIdAndProjectId(Long applicantId, Long projectId); + + Optional findByProjectIdAndApplicantId(Long projectId, Long applicantId); } \ No newline at end of file diff --git a/get-p-persistence/src/main/java/es/princip/getp/persistence/adapter/project/apply/ProjectApplicationPersistenceAdapter.java b/get-p-persistence/src/main/java/es/princip/getp/persistence/adapter/project/apply/ProjectApplicationPersistenceAdapter.java index 60e14bd4..ef9a26b5 100644 --- a/get-p-persistence/src/main/java/es/princip/getp/persistence/adapter/project/apply/ProjectApplicationPersistenceAdapter.java +++ b/get-p-persistence/src/main/java/es/princip/getp/persistence/adapter/project/apply/ProjectApplicationPersistenceAdapter.java @@ -55,6 +55,13 @@ public ProjectApplication loadBy(final ProjectApplicationId applicationId) { return mapper.mapToDomain(jpaEntity); } + @Override + public ProjectApplication loadBy(final ProjectId projectId, final PeopleId applicantId) { + final ProjectApplicationJpaEntity jpaEntity = repository.findByProjectIdAndApplicantId(projectId.getValue(), applicantId.getValue()) + .orElseThrow(NotFoundProjectApplicationException::new); + return mapper.mapToDomain(jpaEntity); + } + @Override public void update(final ProjectApplication application) { final Long applicationId = application.getId().getValue(); diff --git a/get-p-persistence/src/main/java/es/princip/getp/persistence/adapter/project/assign/AssignmentPeopleJpaRepository.java b/get-p-persistence/src/main/java/es/princip/getp/persistence/adapter/project/assign/AssignmentPeopleJpaRepository.java new file mode 100644 index 00000000..99f7f903 --- /dev/null +++ b/get-p-persistence/src/main/java/es/princip/getp/persistence/adapter/project/assign/AssignmentPeopleJpaRepository.java @@ -0,0 +1,7 @@ +package es.princip.getp.persistence.adapter.project.assign; + +import es.princip.getp.persistence.adapter.project.assign.model.AssignmentPeopleJpaEntity; +import org.springframework.data.jpa.repository.JpaRepository; + +interface AssignmentPeopleJpaRepository extends JpaRepository { +} diff --git a/get-p-persistence/src/main/java/es/princip/getp/persistence/adapter/project/assign/AssignmentPeoplePersistenceAdapter.java b/get-p-persistence/src/main/java/es/princip/getp/persistence/adapter/project/assign/AssignmentPeoplePersistenceAdapter.java new file mode 100644 index 00000000..00821eba --- /dev/null +++ b/get-p-persistence/src/main/java/es/princip/getp/persistence/adapter/project/assign/AssignmentPeoplePersistenceAdapter.java @@ -0,0 +1,22 @@ +package es.princip.getp.persistence.adapter.project.assign; + +import es.princip.getp.application.project.assign.port.out.SaveAssignmentPeoplePort; +import es.princip.getp.domain.project.confirmation.model.AssignmentPeople; +import es.princip.getp.persistence.adapter.project.assign.model.AssignmentPeopleJpaEntity; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Repository; + +@Repository +@RequiredArgsConstructor +class AssignmentPeoplePersistenceAdapter implements + SaveAssignmentPeoplePort { + + private final AssignmentPeopleJpaRepository jpaRepository; + private final AssignmentPeoplePersistenceMapper mapper; + + @Override + public Long save(final AssignmentPeople assignmentPeople) { + final AssignmentPeopleJpaEntity jpaEntity = mapper.mapToJpa(assignmentPeople); + return jpaRepository.save(jpaEntity).getId(); + } +} diff --git a/get-p-persistence/src/main/java/es/princip/getp/persistence/adapter/project/assign/AssignmentPeoplePersistenceMapper.java b/get-p-persistence/src/main/java/es/princip/getp/persistence/adapter/project/assign/AssignmentPeoplePersistenceMapper.java new file mode 100644 index 00000000..5c5cd5be --- /dev/null +++ b/get-p-persistence/src/main/java/es/princip/getp/persistence/adapter/project/assign/AssignmentPeoplePersistenceMapper.java @@ -0,0 +1,18 @@ +package es.princip.getp.persistence.adapter.project.assign; + +import es.princip.getp.domain.project.confirmation.model.AssignmentPeople; +import es.princip.getp.persistence.adapter.project.assign.model.AssignmentPeopleJpaEntity; +import org.mapstruct.InheritInverseConfiguration; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; + +@Mapper(componentModel = "spring") +public interface AssignmentPeoplePersistenceMapper { + + @Mapping(source = "projectId", target = "projectId.value") + @Mapping(source = "applicantId", target = "applicantId.value") + AssignmentPeople mapToDomain(AssignmentPeopleJpaEntity assignmentPeopleJpaEntity); + + @InheritInverseConfiguration + AssignmentPeopleJpaEntity mapToJpa(AssignmentPeople assignmentPeople); +} diff --git a/get-p-persistence/src/main/java/es/princip/getp/persistence/adapter/project/assign/model/AssignmentPeopleJpaEntity.java b/get-p-persistence/src/main/java/es/princip/getp/persistence/adapter/project/assign/model/AssignmentPeopleJpaEntity.java new file mode 100644 index 00000000..65e6a234 --- /dev/null +++ b/get-p-persistence/src/main/java/es/princip/getp/persistence/adapter/project/assign/model/AssignmentPeopleJpaEntity.java @@ -0,0 +1,25 @@ +package es.princip.getp.persistence.adapter.project.assign.model; + +import es.princip.getp.persistence.adapter.BaseTimeJpaEntity; +import jakarta.persistence.*; +import lombok.*; + +@Getter +@Entity +@Builder +@AllArgsConstructor +@Table(name = "assignment_people") +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class AssignmentPeopleJpaEntity extends BaseTimeJpaEntity { + @Id + @Column(name = "assignment_people_id") + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(name = "project_id") + private Long projectId; + + @Column(name = "people_id") + private Long applicantId; +} + \ No newline at end of file diff --git a/get-p-persistence/src/main/java/es/princip/getp/persistence/adapter/project/commission/FindProjectAdapter.java b/get-p-persistence/src/main/java/es/princip/getp/persistence/adapter/project/commission/FindProjectAdapter.java index 3b59baeb..4457302e 100644 --- a/get-p-persistence/src/main/java/es/princip/getp/persistence/adapter/project/commission/FindProjectAdapter.java +++ b/get-p-persistence/src/main/java/es/princip/getp/persistence/adapter/project/commission/FindProjectAdapter.java @@ -4,15 +4,15 @@ import com.querydsl.core.types.OrderSpecifier; import com.querydsl.core.types.dsl.BooleanExpression; import com.querydsl.jpa.impl.JPAQuery; -import es.princip.getp.application.project.commission.dto.response.ProjectCardResponse; -import es.princip.getp.application.project.commission.dto.response.ProjectClientResponse; -import es.princip.getp.application.project.commission.dto.response.ProjectDetailResponse; import es.princip.getp.application.client.port.out.ClientQuery; import es.princip.getp.application.like.project.port.out.CheckProjectLikePort; import es.princip.getp.application.like.project.port.out.CountProjectLikePort; import es.princip.getp.application.project.apply.port.out.CountProjectApplicationPort; import es.princip.getp.application.project.commission.dto.command.ProjectSearchFilter; import es.princip.getp.application.project.commission.dto.command.ProjectSearchOrder; +import es.princip.getp.application.project.commission.dto.response.ProjectCardResponse; +import es.princip.getp.application.project.commission.dto.response.ProjectClientResponse; +import es.princip.getp.application.project.commission.dto.response.ProjectDetailResponse; import es.princip.getp.application.project.commission.exception.NotFoundProjectException; import es.princip.getp.application.project.commission.port.out.FindProjectPort; import es.princip.getp.domain.client.model.ClientId; @@ -28,6 +28,8 @@ import es.princip.getp.persistence.adapter.project.ProjectPersistenceMapper; import es.princip.getp.persistence.adapter.project.ProjectQueryMapper; import es.princip.getp.persistence.adapter.project.apply.model.QProjectApplicationJpaEntity; +import es.princip.getp.persistence.adapter.project.commission.model.ProjectJpaEntity; +import es.princip.getp.persistence.adapter.project.commission.model.QProjectJpaEntity; import es.princip.getp.persistence.support.QueryDslSupport; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; diff --git a/get-p-persistence/src/main/java/es/princip/getp/persistence/adapter/project/commission/ProjectJpaRepository.java b/get-p-persistence/src/main/java/es/princip/getp/persistence/adapter/project/commission/ProjectJpaRepository.java index 102fdfdd..c0e1b79a 100644 --- a/get-p-persistence/src/main/java/es/princip/getp/persistence/adapter/project/commission/ProjectJpaRepository.java +++ b/get-p-persistence/src/main/java/es/princip/getp/persistence/adapter/project/commission/ProjectJpaRepository.java @@ -1,5 +1,6 @@ package es.princip.getp.persistence.adapter.project.commission; +import es.princip.getp.persistence.adapter.project.commission.model.ProjectJpaEntity; import org.springframework.data.jpa.repository.JpaRepository; interface ProjectJpaRepository extends JpaRepository { diff --git a/get-p-persistence/src/main/java/es/princip/getp/persistence/adapter/project/commission/ProjectPersistenceAdapter.java b/get-p-persistence/src/main/java/es/princip/getp/persistence/adapter/project/commission/ProjectPersistenceAdapter.java index 68256212..412e17af 100644 --- a/get-p-persistence/src/main/java/es/princip/getp/persistence/adapter/project/commission/ProjectPersistenceAdapter.java +++ b/get-p-persistence/src/main/java/es/princip/getp/persistence/adapter/project/commission/ProjectPersistenceAdapter.java @@ -7,6 +7,7 @@ import es.princip.getp.domain.project.commission.model.Project; import es.princip.getp.domain.project.commission.model.ProjectId; import es.princip.getp.persistence.adapter.project.ProjectPersistenceMapper; +import es.princip.getp.persistence.adapter.project.commission.model.ProjectJpaEntity; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Repository; diff --git a/get-p-persistence/src/main/java/es/princip/getp/persistence/adapter/project/commission/ProjectJpaEntity.java b/get-p-persistence/src/main/java/es/princip/getp/persistence/adapter/project/commission/model/ProjectJpaEntity.java similarity index 97% rename from get-p-persistence/src/main/java/es/princip/getp/persistence/adapter/project/commission/ProjectJpaEntity.java rename to get-p-persistence/src/main/java/es/princip/getp/persistence/adapter/project/commission/model/ProjectJpaEntity.java index 348bebc7..de4bbb3c 100644 --- a/get-p-persistence/src/main/java/es/princip/getp/persistence/adapter/project/commission/ProjectJpaEntity.java +++ b/get-p-persistence/src/main/java/es/princip/getp/persistence/adapter/project/commission/model/ProjectJpaEntity.java @@ -1,4 +1,4 @@ -package es.princip.getp.persistence.adapter.project.commission; +package es.princip.getp.persistence.adapter.project.commission.model; import es.princip.getp.domain.project.commission.model.MeetingType; import es.princip.getp.domain.project.commission.model.ProjectCategory; diff --git a/get-p-persistence/src/main/resources/db/migration/V10__add_assignment_people__table.sql b/get-p-persistence/src/main/resources/db/migration/V10__add_assignment_people__table.sql new file mode 100644 index 00000000..45793325 --- /dev/null +++ b/get-p-persistence/src/main/resources/db/migration/V10__add_assignment_people__table.sql @@ -0,0 +1,9 @@ +create table assignment_people +( + assignment_people_id bigint auto_increment, + project_id bigint null, + people_id bigint null, + created_at timestamp null, + updated_at timestamp null, + primary key (assignment_people_id) +); diff --git a/get-p-persistence/src/test/java/es/princip/getp/persistence/adapter/project/commission/ProjectDataLoader.java b/get-p-persistence/src/test/java/es/princip/getp/persistence/adapter/project/commission/ProjectDataLoader.java index 293ba024..b8fabb34 100644 --- a/get-p-persistence/src/test/java/es/princip/getp/persistence/adapter/project/commission/ProjectDataLoader.java +++ b/get-p-persistence/src/test/java/es/princip/getp/persistence/adapter/project/commission/ProjectDataLoader.java @@ -4,6 +4,7 @@ import es.princip.getp.domain.project.commission.model.ProjectCategory; import es.princip.getp.domain.project.commission.model.ProjectStatus; import es.princip.getp.persistence.adapter.common.DurationJpaVO; +import es.princip.getp.persistence.adapter.project.commission.model.ProjectJpaEntity; import es.princip.getp.persistence.support.DataLoader; import jakarta.persistence.EntityManager; import lombok.RequiredArgsConstructor;