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

merge: 4주차 작업 master에 반영 #25

Merged
merged 27 commits into from
Sep 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
7109400
refactor: 3주차 피드백 반영
Sep 23, 2024
f3aa28c
feat: 내일기 서비스로직 회원 연결
Sep 23, 2024
5e3a677
feat: 200 응답 시 사용할 수 있는 메서드 추가
peeerr Sep 25, 2024
89bd8c8
feat: 회원 검색 API 구현
peeerr Sep 25, 2024
0012494
feat: 내 정보 API 구현
peeerr Sep 25, 2024
7070da9
feat: 특정 회원 정보 조회 API 구현
peeerr Sep 25, 2024
2518643
chore: 환경별 설정파일 분리
peeerr Sep 25, 2024
fccd197
feat: 회원 정보 수정 API 구현
peeerr Sep 25, 2024
e958451
refactor: 생성자를 사용한 방식에서 빈 등록 방식으로 변경
peeerr Sep 25, 2024
6aaf51c
feat: weekly 브랜치 PR 시 자동 CI 테스트 워크플로우 추가
peeerr Sep 25, 2024
80a6276
test: 회원 관련 API 컨트롤러 테스트
peeerr Sep 26, 2024
b0e3d5d
test: 회원 서비스 테스트
peeerr Sep 26, 2024
eca8e38
test: 회원 리파지토리 테스트
peeerr Sep 26, 2024
b6b97d2
test: 페이징 유틸 클래스 테스트
peeerr Sep 26, 2024
7484ef9
chore: swagger 의존성 추가
peeerr Sep 26, 2024
0ae2cf0
feat: swagger 접근 허용 설정
peeerr Sep 26, 2024
0aa036d
fix: 권한이 없어 테스트 결과 보고에 실패하는 문제 해결
peeerr Sep 26, 2024
e81a183
fix: H2-console 대시보드 보이지 않는 오류 수정
Sep 27, 2024
160a0e7
feat: 날짜 필터링 디폴트 오늘 날짜로 변경
Sep 27, 2024
66bd22c
feat: 친구 엔티티 추가
Sep 27, 2024
3cc63fa
feat: 친구API 추가
Sep 27, 2024
ab55440
feat: 친구 일기API 구현
Sep 27, 2024
7c69c7e
Merge pull request #21 from HyeJiJUN11/feature/18-friendAPI
peeerr Sep 27, 2024
b994bce
Merge pull request #20 from kakao-tech-campus-2nd-step3/feature/19-me…
peeerr Sep 27, 2024
0ec083d
fix: 중복 enum 제거
peeerr Sep 27, 2024
f8fab12
feat: weekly 브랜치 merge 시에도 자동 배포 트리거
peeerr Sep 27, 2024
5a8889f
Merge pull request #24 from kakao-tech-campus-2nd-step3/fix/22-enum
peeerr Sep 27, 2024
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
@@ -1,9 +1,10 @@
name: master 브랜치 자동 배포
name: master 브랜치 merge 시 CI/CD 파이프라인

on:
push:
branches:
- 'master'
- 'weekly/**'

jobs:
deploy:
Expand All @@ -19,6 +20,15 @@ jobs:
distribution: 'corretto'
java-version: '21'

- name: AWS S3 관련 정보를 설정 파일에 주입
uses: microsoft/variable-substitution@v1
with:
files: ./src/main/resources/application-prod.yml
env:
aws.s3.bucket: ${{ secrets.AWS_S3_BUCKET }}
aws.s3.accessKey: ${{ secrets.AWS_S3_ACCESS_KEY }}
aws.s3.secretKey: ${{ secrets.AWS_S3_SECRET_KEY }}

- name: 빌드로 테스트 수행 및 Jar 파일 생성
run: |
chmod +x ./gradlew
Expand Down
51 changes: 51 additions & 0 deletions .github/workflows/pr_weekly_ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
name: weekly 브랜치 PR에 대한 CI 테스트

on:
pull_request:
branches:
- 'weekly/**'

jobs:
ci:
runs-on: ubuntu-latest

permissions:
checks: write
pull-requests: write

steps:
- name: 프로젝트 코드를 CI 서버로 옮겨오기
uses: actions/checkout@v4

- name: JDK 21 설치
uses: actions/setup-java@v4
with:
distribution: 'corretto'
java-version: '21'

- name: AWS S3 관련 정보를 설정 파일에 주입
uses: microsoft/variable-substitution@v1
with:
files: ./src/main/resources/application-prod.yml
env:
aws.s3.bucket: ${{ secrets.AWS_S3_BUCKET }}
aws.s3.accessKey: ${{ secrets.AWS_S3_ACCESS_KEY }}
aws.s3.secretKey: ${{ secrets.AWS_S3_SECRET_KEY }}

- name: 빌드 테스트 수행
run: |
chmod +x ./gradlew
./gradlew clean build

- name: 테스트 수행 결과 보고
uses: EnricoMi/publish-unit-test-result-action@v2
if: always()
with:
files: '**/build/test-results/test/TEST-*.xml'

- name: 테스트 실패 시, 실패한 코드 라인에 코멘트 자동 등록
uses: mikepenz/action-junit-report@v3
if: always()
with:
report_paths: '**/build/test-results/test/TEST-*.xml'
token: ${{ github.token }}
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ build/
!**/src/main/**/build/
!**/src/test/**/build/

application-dev.yml

### STS ###
.apt_generated
.classpath
Expand Down
3 changes: 3 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-validation'

implementation 'com.amazonaws:aws-java-sdk-s3:1.12.657'
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.6.0'

implementation 'io.jsonwebtoken:jjwt-api:0.12.6'
runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.12.6'
runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.12.6'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.potatocake.everymoment.config;

import org.springframework.boot.context.properties.ConfigurationProperties;

@ConfigurationProperties(prefix = "aws.s3")
public record AwsS3Properties(
String accessKey,
String secretKey,
String region,
String bucket
) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.HeadersConfigurer.FrameOptionsConfig;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
Expand All @@ -39,9 +40,13 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
.formLogin(auth -> auth.disable())
.httpBasic(auth -> auth.disable());

http
.headers(header -> header.frameOptions(FrameOptionsConfig::sameOrigin));

http
.authorizeHttpRequests(auth -> auth
.requestMatchers("/api/members/login", "/h2-console/**", "/error").permitAll()
.requestMatchers("/api/members/login", "/h2-console/**", "/error", "/favicon.ico").permitAll()
.requestMatchers("/swagger-resources/**", "/swagger-ui/**", "/v3/api-docs/**").permitAll()
.anyRequest().authenticated());

http
Expand Down
Empty file.
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
package com.potatocake.everymoment.controller;

import com.potatocake.everymoment.dto.SuccessResponse;
import com.potatocake.everymoment.dto.request.DiaryAutoRequest;
import com.potatocake.everymoment.dto.request.DiaryManualRequest;
import com.potatocake.everymoment.dto.request.DiaryAutoCreateRequest;
import com.potatocake.everymoment.dto.request.DiaryFilterRequest;
import com.potatocake.everymoment.dto.request.DiaryManualCreateRequest;
import com.potatocake.everymoment.dto.response.FriendDiariesResponse;
import com.potatocake.everymoment.dto.response.FriendDiaryResponse;
import com.potatocake.everymoment.dto.response.MyDiariesResponse;
import com.potatocake.everymoment.dto.response.MyDiaryResponse;
import com.potatocake.everymoment.dto.response.NotificationResponse;
import com.potatocake.everymoment.service.DiaryService;
import com.potatocake.everymoment.service.FriendDiaryService;
import java.time.LocalDate;
import lombok.RequiredArgsConstructor;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
Expand All @@ -21,46 +26,42 @@
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RequiredArgsConstructor
@RestController
@RequestMapping("api/diaries")
@RequestMapping("/api/diaries")
public class DiaryController {

private final DiaryService diaryService;

public DiaryController(DiaryService diaryService) {
this.diaryService = diaryService;
}
private final FriendDiaryService friendDiaryService;

//자동 일기 작성
@PostMapping("/auto")
public ResponseEntity<SuccessResponse<NotificationResponse>> createDiaryAuto(
@RequestBody DiaryAutoRequest diaryAutoRequest) {
NotificationResponse notificationResponse = diaryService.createDiaryAuto(diaryAutoRequest);
@RequestBody DiaryAutoCreateRequest diaryAutoCreateRequest) {
NotificationResponse notificationResponse = diaryService.createDiaryAuto(diaryAutoCreateRequest);
SuccessResponse<NotificationResponse> response = SuccessResponse.<NotificationResponse>builder()
.code(HttpStatus.OK.value())
.message("success")
.info(notificationResponse)
.build();

return ResponseEntity.ok(response);
}

//수기 일기 작성
@PostMapping("/manual")
public ResponseEntity<SuccessResponse<Void>> createDiaryManual(
@RequestBody DiaryManualRequest diaryManualRequest) {
diaryService.createDiaryManual(diaryManualRequest);
@RequestBody DiaryManualCreateRequest diaryManualCreateRequest) {
diaryService.createDiaryManual(diaryManualCreateRequest);
SuccessResponse<Void> response = SuccessResponse.<Void>builder()
.code(HttpStatus.OK.value())
.message("success")
.info(null)
.build();

return ResponseEntity.ok(response);
}

//내 일기 전체 조회(타임라인)
@GetMapping("my")
@GetMapping("/my")
public ResponseEntity<SuccessResponse<MyDiariesResponse>> getMyDiaries(
@RequestParam(required = false) String keyword,
@RequestParam(required = false) String emoji,
Expand All @@ -72,14 +73,24 @@ public ResponseEntity<SuccessResponse<MyDiariesResponse>> getMyDiaries(
@RequestParam(defaultValue = "0") int key,
@RequestParam(defaultValue = "10") int size
) {
MyDiariesResponse myDiariesResponse = diaryService.getMyDiaries(keyword, emoji, category, date, from, until,
bookmark, key, size);
DiaryFilterRequest diaryFilterRequest = DiaryFilterRequest.builder()
.keyword(keyword)
.emoji(emoji)
.category(category)
.date(date)
.from(from)
.until(until)
.bookmark(bookmark)
.key(key)
.size(size)
.build();

MyDiariesResponse myDiariesResponse = diaryService.getMyDiaries(diaryFilterRequest);
SuccessResponse<MyDiariesResponse> response = SuccessResponse.<MyDiariesResponse>builder()
.code(HttpStatus.OK.value())
.message("success")
.info(myDiariesResponse)
.build();

return ResponseEntity.ok(response);
}

Expand All @@ -92,15 +103,14 @@ public ResponseEntity<SuccessResponse<MyDiaryResponse>> getMyDiary(@PathVariable
.message("success")
.info(myDiaryResponse)
.build();

return ResponseEntity.ok(response);
}

//일기 수정
@PatchMapping("/{id}")
public ResponseEntity<SuccessResponse<Void>> updateDiary(@PathVariable Long id,
@RequestBody DiaryManualRequest diaryManualRequest) {
diaryService.updateDiary(id, diaryManualRequest);
@RequestBody DiaryManualCreateRequest diaryManualCreateRequest) {
diaryService.updateDiary(id, diaryManualCreateRequest);
SuccessResponse<Void> response = SuccessResponse.<Void>builder()
.code(HttpStatus.OK.value())
.message("success")
Expand Down Expand Up @@ -144,4 +154,50 @@ public ResponseEntity<SuccessResponse<Void>> togglePrivacy(@PathVariable Long id
.build();
return ResponseEntity.ok(response);
}

//전체 친구 일기 조회
@GetMapping("/friend")
public ResponseEntity<SuccessResponse<FriendDiariesResponse>> getFriendDiaries(
@RequestParam(required = false) String keyword,
@RequestParam(required = false) String emoji,
@RequestParam(required = false) Long category,
@RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate date,
@RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate from,
@RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate until,
@RequestParam(required = false) Boolean bookmark,
@RequestParam(defaultValue = "0") int key,
@RequestParam(defaultValue = "10") int size
) {
DiaryFilterRequest diaryFilterRequest = DiaryFilterRequest.builder()
.keyword(keyword)
.emoji(emoji)
.category(category)
.date(date)
.from(from)
.until(until)
.bookmark(bookmark)
.key(key)
.size(size)
.build();

FriendDiariesResponse diaries = friendDiaryService.getFriendDiaries(diaryFilterRequest);
SuccessResponse<FriendDiariesResponse> response = SuccessResponse.<FriendDiariesResponse>builder()
.code(HttpStatus.OK.value())
.message("success")
.info(diaries)
.build();
return ResponseEntity.ok(response);
}

//친구 일기 상제 조회
@GetMapping("/friend/{id}")
public ResponseEntity<SuccessResponse<FriendDiaryResponse>> getFriendDiary(@PathVariable Long id) {
FriendDiaryResponse diary = friendDiaryService.getFriendDiary(id);
SuccessResponse<FriendDiaryResponse> response = SuccessResponse.<FriendDiaryResponse>builder()
.code(HttpStatus.OK.value())
.message("success")
.info(diary)
.build();
return ResponseEntity.ok(response);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package com.potatocake.everymoment.controller;

import com.potatocake.everymoment.dto.SuccessResponse;
import com.potatocake.everymoment.dto.response.FriendListResponse;
import com.potatocake.everymoment.dto.response.OneFriendDiariesResponse;
import com.potatocake.everymoment.service.FriendService;
import java.time.LocalDate;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("api/friends")
public class FriendController {
private final FriendService friendService;

public FriendController(FriendService friendService) {
this.friendService = friendService;
}

//특정 친구 일기 전체 조회
@GetMapping("/{id}/diaries")
public ResponseEntity<SuccessResponse<OneFriendDiariesResponse>> getOneFriendDiaries(
@PathVariable Long id,
@RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate date,
@RequestParam(defaultValue = "0") int key,
@RequestParam(defaultValue = "10") int size) {
OneFriendDiariesResponse diaries = friendService.OneFriendDiariesResponse(id, date, key, size);
SuccessResponse<OneFriendDiariesResponse> response = SuccessResponse.<OneFriendDiariesResponse>builder()
.code(HttpStatus.OK.value())
.message("success")
.info(diaries)
.build();
return ResponseEntity.ok(response);
}

//내 친구 목록 조회
@GetMapping("/friends")
public ResponseEntity<SuccessResponse<FriendListResponse>> getFriendList(
@RequestParam(required = false) String nickname,
@RequestParam(required = false) String email,
@RequestParam(defaultValue = "0") int key,
@RequestParam(defaultValue = "10") int size) {
FriendListResponse friendList = friendService.getFriendList(nickname, email, key, size);
SuccessResponse<FriendListResponse> response = SuccessResponse.<FriendListResponse>builder()
.code(HttpStatus.OK.value())
.message("success")
.info(friendList)
.build();
return ResponseEntity.ok(response);
}

//내 친구 삭제
@DeleteMapping("/{id}")
public ResponseEntity<SuccessResponse<Void>> deleteFriend(@PathVariable Long id) {
friendService.deleteFriend(id);
SuccessResponse<Void> response = SuccessResponse.<Void>builder()
.code(HttpStatus.OK.value())
.message("success")
.info(null)
.build();
return ResponseEntity.ok(response);
}

//친한 친구 설정
@PatchMapping("/{id}/bookmark")
public ResponseEntity<SuccessResponse<Void>> toggleCloseFriend(@PathVariable Long id) {
friendService.toggleCloseFriend(id);
SuccessResponse<Void> response = SuccessResponse.<Void>builder()
.code(HttpStatus.OK.value())
.message("success")
.info(null)
.build();
return ResponseEntity.ok(response);
}
}
Loading
Loading