Skip to content

Commit

Permalink
merge(develop -> staging) : 구현한 API 반영
Browse files Browse the repository at this point in the history
[🧬 merge] develop -> staging
  • Loading branch information
jsoonworld authored Feb 27, 2025
2 parents 366625c + 3ee91cc commit 9130ad5
Show file tree
Hide file tree
Showing 311 changed files with 12,737 additions and 498 deletions.
7 changes: 7 additions & 0 deletions .github/workflows/DOCKER-CD-PROD.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,13 @@ jobs:
echo "${{ secrets.AWS_CONFIG_YML }}" > ./aws-config.yml
working-directory: ${{ env.working-directory }}

- name: oauth-config.yml 생성
run: |
cd ./src/main/resources
touch ./oauth-config.yml
echo "${{ secrets.PROD_OAUTH_CONFIG_YML }}" > ./oauth-config.yml
working-directory: ${{ env.working-directory }}

- name: 빌드
run: |
chmod +x gradlew
Expand Down
7 changes: 7 additions & 0 deletions .github/workflows/DOCKER-CD-STAGING.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,13 @@ jobs:
echo "${{ secrets.AWS_CONFIG_YML }}" > ./aws-config.yml
working-directory: ${{ env.working-directory }}

- name: oauth-config.yml 생성
run: |
cd ./src/main/resources
touch ./oauth-config.yml
echo "${{ secrets.STAGING_OAUTH_CONFIG_YML }}" > ./oauth-config.yml
working-directory: ${{ env.working-directory }}

- name: 빌드
run: |
chmod +x gradlew
Expand Down
16 changes: 16 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,14 @@ repositories {
mavenCentral()
}

ext {
set('queryDslVersion', "5.0.0")
}

dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.testng:testng:7.1.0'
compileOnly 'org.projectlombok:lombok'
runtimeOnly 'org.postgresql:postgresql'
annotationProcessor 'org.projectlombok:lombok'
Expand All @@ -38,6 +43,17 @@ dependencies {

// Actuator
implementation 'org.springframework.boot:spring-boot-starter-actuator'

// JWT
implementation 'io.jsonwebtoken:jjwt-api:0.12.6'
runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.12.6'
runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.12.6'

// QueryDSL
implementation "com.querydsl:querydsl-jpa:${queryDslVersion}:jakarta"
annotationProcessor "com.querydsl:querydsl-apt:${queryDslVersion}:jakarta"
annotationProcessor "jakarta.annotation:jakarta.annotation-api"
annotationProcessor "jakarta.persistence:jakarta.persistence-api"
}

tasks.named('test') {
Expand Down
2 changes: 0 additions & 2 deletions src/main/java/org/noostak/NoostakApplication.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,11 @@

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;

@SpringBootApplication
public class NoostakApplication {

public static void main(String[] args) {
SpringApplication.run(NoostakApplication.class, args);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package org.noostak.appointment.api;

import lombok.RequiredArgsConstructor;
import org.noostak.appointment.application.AppointmentService;
import org.noostak.appointment.dto.request.AppointmentCreateRequest;
import org.noostak.appointment.dto.response.recommendation.AppointmentRecommendedOptionsResponse;
import org.noostak.global.success.SuccessResponse;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import static org.noostak.appointment.common.success.AppointmentSuccessCode.APPOINTMENT_CREATED;

@RestController
@RequestMapping("/api/v1")
@RequiredArgsConstructor
public class AppointmentController {

private final AppointmentService appointmentService;

// TODO : GROUP 으로 이동
@PostMapping("/groups/{groupId}/appointments")
public ResponseEntity<SuccessResponse> createAppointment(
// @AuthenticationPrincipal Long memberId,
@PathVariable(name = "groupId") Long groupId,
@RequestBody AppointmentCreateRequest request
) {
Long memberId = 1L;
appointmentService.createAppointment(memberId, groupId, request);
return ResponseEntity.ok(SuccessResponse.of(APPOINTMENT_CREATED));
}

@GetMapping("/appointments/{appointmentId}/recommended-options")
public ResponseEntity<SuccessResponse<AppointmentRecommendedOptionsResponse>> getRecommendedAppointmentOptions(
@PathVariable(name = "appointmentId") Long appointmentId
) {
Long memberId = 1L;
AppointmentRecommendedOptionsResponse response = appointmentService.getRecommendedAppointmentOptions(memberId, appointmentId);
return ResponseEntity.ok(SuccessResponse.of(APPOINTMENT_CREATED, response));
}
}
29 changes: 29 additions & 0 deletions src/main/java/org/noostak/appointment/api/CalendarController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package org.noostak.appointment.api;


import lombok.RequiredArgsConstructor;
import org.noostak.appointment.application.CalendarService;
import org.noostak.appointment.common.success.CalendarSuccessCode;
import org.noostak.appointment.dto.calendar.CalendarResponse;
import org.noostak.global.success.SuccessResponse;
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.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequiredArgsConstructor
public class CalendarController {

private final CalendarService calendarService;
@GetMapping("/api/v1/groups/{groupId}/appointments/calendar")
public ResponseEntity<SuccessResponse> getCalendar(
@PathVariable Long groupId,
@RequestParam int year,
@RequestParam int month
){
CalendarResponse response = calendarService.getCalendarViewByGroupId(groupId, year, month);
return ResponseEntity.ok(SuccessResponse.of(CalendarSuccessCode.CALENDAR_CREATED,response));
}
}
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package org.noostak.appointment.application;

import lombok.RequiredArgsConstructor;
import org.noostak.appointment.application.create.AppointmentCreateService;
import org.noostak.appointment.application.recommendation.AppointmentRecommendedOptionService;
import org.noostak.appointment.dto.request.AppointmentCreateRequest;
import org.noostak.appointment.dto.response.recommendation.AppointmentRecommendedOptionsResponse;
import org.springframework.stereotype.Service;

@Service
@RequiredArgsConstructor
public class AppointmentService {
private final AppointmentCreateService appointmentCreateService;
private final AppointmentRecommendedOptionService appointmentRecommendedOptionService;

public void createAppointment(Long memberId, Long groupId, AppointmentCreateRequest request) {
appointmentCreateService.createAppointment(memberId, groupId, request);
}

public AppointmentRecommendedOptionsResponse getRecommendedAppointmentOptions(Long memberId, Long appointmentId) {
return appointmentRecommendedOptionService.getRecommendedAppointmentOptions(memberId, appointmentId);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package org.noostak.appointment.application;

import org.noostak.appointment.dto.calendar.CalendarResponse;

public interface CalendarService{
CalendarResponse getCalendarViewByGroupId(Long groupId, int year, int month);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
package org.noostak.appointment.application;


import lombok.RequiredArgsConstructor;
import org.noostak.appointment.domain.Appointment;
import org.noostak.appointment.domain.AppointmentRepository;
import org.noostak.appointment.domain.vo.AppointmentStatus;
import org.noostak.appointment.dto.calendar.CalendarResponse;
import org.noostak.appointment.dto.calendar.MonthAppointment;
import org.noostak.appointment.dto.calendar.MonthAppointments;
import org.noostak.appointmentoption.common.exception.AppointmentOptionErrorCode;
import org.noostak.appointmentoption.common.exception.AppointmentOptionException;
import org.noostak.appointmentoption.domain.AppointmentOption;
import org.noostak.appointmentoption.domain.AppointmentOptionRepository;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;

@Service
@RequiredArgsConstructor
public class CalendarServiceImpl implements CalendarService {

private final AppointmentRepository appointmentRepository;
private final AppointmentOptionRepository appointmentOptionRepository;


@Override
public CalendarResponse getCalendarViewByGroupId(Long groupId, int year, int month) {

List<Appointment> appointmentList =
appointmentRepository.findAllByGroupIdConfirmed(AppointmentStatus.CONFIRMED, groupId);

// 이번 달의 캘린더 정보 목록 불러오기
ArrayList<MonthAppointments> currentMonthAppointments =
getMonthAppointments(appointmentList, year, month);

// 이전 달의 캘린더 정보 목록 불러오기
ArrayList<MonthAppointments> previousMonthAppointments =
getPreviousMonthAppointments(appointmentList, year, month);

return CalendarResponse.of(year, month, currentMonthAppointments, previousMonthAppointments);
}

private ArrayList<MonthAppointments> getPreviousMonthAppointments(List<Appointment> appointmentList, int year, int month) {
LocalDate firstDate = LocalDate.of(year, month, 1);
int weekNumber = firstDate.getDayOfWeek().getValue();
LocalDate previousDate = firstDate.minusDays(weekNumber);

return getMonthAppointments(appointmentList, firstDate, previousDate);
}

private ArrayList<MonthAppointments> getMonthAppointments(List<Appointment> appointmentList, LocalDate firstDate, LocalDate previousDate) {
HashMap<Integer, ArrayList<MonthAppointment>> previousMonthAppointmentMapper =
getMonthAppointmentsMapper(appointmentList, firstDate, previousDate);

return getMonthAppointments(previousMonthAppointmentMapper);
}

private ArrayList<MonthAppointments> getMonthAppointments(List<Appointment> appointmentList, int year, int month) {
HashMap<Integer, ArrayList<MonthAppointment>> currentMonthAppointmentMapper =
getMonthAppointmentsMapper(appointmentList, year, month);

return getMonthAppointments(currentMonthAppointmentMapper);
}

private HashMap<Integer, ArrayList<MonthAppointment>>
getMonthAppointmentsMapper(List<Appointment> appointmentList, LocalDate firstDate, LocalDate previousDate) {
HashMap<Integer, ArrayList<MonthAppointment>> previousMonthAppointmentMapper = new HashMap<>();

for (Appointment appointment : appointmentList) {
AppointmentOption previousMonthAppointmentOption
= getAppointmentConfirmed(firstDate, previousDate, appointment);

int day = previousMonthAppointmentOption.getDayOfMonth();

ArrayList<MonthAppointment> dayOfOptions =
previousMonthAppointmentMapper.getOrDefault(day, new ArrayList<>());

MonthAppointment previousMonthAppointment =
MonthAppointment.from(appointment, previousMonthAppointmentOption);

dayOfOptions.add(previousMonthAppointment);

previousMonthAppointmentMapper.put(day, dayOfOptions);
}
return previousMonthAppointmentMapper;
}

private HashMap<Integer, ArrayList<MonthAppointment>>
getMonthAppointmentsMapper(List<Appointment> appointmentList, int year, int month) {
HashMap<Integer, ArrayList<MonthAppointment>> monthAppointmentMapper = new HashMap<>();

for (Appointment appointment : appointmentList) {

AppointmentOption appointmentOption =
getAppointmentConfirmed(appointment, year, month);

int day = appointmentOption.getDayOfMonth();

ArrayList<MonthAppointment> dayOfOptions = monthAppointmentMapper.getOrDefault(day, new ArrayList<>());

MonthAppointment monthAppointment = MonthAppointment.from(appointment, appointmentOption);
dayOfOptions.add(monthAppointment);

monthAppointmentMapper.put(day, dayOfOptions);
}

return monthAppointmentMapper;
}

private ArrayList<MonthAppointments> getMonthAppointments
(HashMap<Integer, ArrayList<MonthAppointment>> monthAppointmentMapper) {
ArrayList<MonthAppointments> currentMonthAppointments = new ArrayList<>();

for (int day : monthAppointmentMapper.keySet()) {
ArrayList<MonthAppointment> appointmentOptions = monthAppointmentMapper.get(day);
MonthAppointments monthAppointments = new MonthAppointments(day, appointmentOptions);

currentMonthAppointments.add(monthAppointments);
Collections.sort(appointmentOptions);
}

return currentMonthAppointments;
}

private AppointmentOption getAppointmentConfirmed(Appointment appointment, int year, int month) {
return appointmentOptionRepository
.findByAppointmentConfirmedYearAndMonth(appointment.getId(), year, month)
.orElseThrow(() -> new AppointmentOptionException(AppointmentOptionErrorCode.APPOINTMENT_OPTION_NOT_FOUND));
}

private AppointmentOption getAppointmentConfirmed(LocalDate firstDate, LocalDate previousDate, Appointment appointment) {
return appointmentOptionRepository
.findByAppointmentConfirmedBetweenDate(appointment.getId(), previousDate, firstDate)
.orElseThrow(() -> new AppointmentOptionException(AppointmentOptionErrorCode.APPOINTMENT_OPTION_NOT_FOUND));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package org.noostak.appointment.application.create;

import org.noostak.appointment.dto.request.AppointmentCreateRequest;

public interface AppointmentCreateService {
void createAppointment(Long memberId, Long groupId, AppointmentCreateRequest request);
}
Loading

0 comments on commit 9130ad5

Please sign in to comment.