Skip to content

Feat/week3#30

Open
PHJ2000 wants to merge 5 commits intoApptiveDev:박재홍from
PHJ2000:main
Open

Feat/week3#30
PHJ2000 wants to merge 5 commits intoApptiveDev:박재홍from
PHJ2000:main

Conversation

@PHJ2000
Copy link
Copy Markdown

@PHJ2000 PHJ2000 commented Nov 21, 2025

변경점 👍

  • Member 도메인 추가
    • Member 엔티티 / MemberRepository / MemberService / MemberController 구현
    • 멤버 생성 / 단건 조회 / 검색(GET /members?q=) 기능 추가
  • 게시글·댓글 작성자(Member) 연동
    • Post, Comment 엔티티에 author(Member) 연관관계 추가
    • PostCreateRequest, CommentCreateRequestmemberId 필드 추가
    • PostService, CommentService에서 생성 시 memberIdMember 조회 후 author 설정
  • 멤버별 게시글·댓글·좋아요 조회 기능 추가
    • GET /members/{memberId}/posts : 해당 멤버가 작성한 게시글 목록 조회
    • GET /members/{memberId}/comments : 해당 멤버가 작성한 댓글 목록 조회
    • GET /members/{memberId}/likes : 해당 멤버가 좋아요한 게시글 목록 조회
    • PostRepository, CommentRepository, PostLikeRepository에 member 기준 조회 메서드 추가
  • 게시글 좋아요 도메인 및 API 추가
    • PostLike 엔티티 / PostLikeRepository / PostLikeService / PostLikeController 구현
    • POST /posts/{postId}/likes : 좋아요 추가
    • DELETE /posts/{postId}/likes : 좋아요 취소
    • GET /posts/{postId}/likes/count : 게시글 좋아요 수 조회
  • 팔로우 도메인 및 API 추가
    • Follow 엔티티 / FollowRepository / FollowService / FollowController 구현
    • POST /members/{memberId}/follow/{targetId} : 팔로우
    • DELETE /members/{memberId}/follow/{targetId} : 언팔로우
    • GET /members/{memberId}/followers : 팔로워 목록 조회
    • GET /members/{memberId}/followings : 팔로잉 목록 조회

버그 해결 💊

  • 서비스 메서드 시그니처와 컨트롤러 호출부 불일치로 인해 발생하던 컴파일 에러 수정
    • PostServicefindAll, findById 메서드 추가 및 사용하도록 정리
    • CommentServicelist 메서드 추가 및 컨트롤러와 일치하도록 시그니처 정리

테스트 💻

다음 시나리오를 기준으로 로컬에서 수동 테스트 수행했습니다. (localhost:8080)

  • 멤버 생성 및 조회

    • POST /members 로 멤버 2명(user1, user2) 생성
    • 응답 id 기준으로 GET /members/{id}GET /members?q=user 호출해 검색 동작 확인
  • 게시글 생성 및 멤버별 게시글 조회

    • POST /posts 요청 시 body에 memberId(user1) 포함하여 게시글 생성
    • GET /members/{memberId}/posts 호출 시 해당 멤버가 작성한 게시글만 조회되는지 확인
  • 댓글 생성 및 멤버별 댓글 조회

    • POST /posts/{postId}/comments 요청 시 memberId(user2) 포함하여 댓글 생성
    • GET /members/{memberId}/comments 호출 시 해당 멤버가 작성한 댓글만 조회되는지 확인
  • 게시글 좋아요 및 멤버별 좋아요 조회

    • POST /posts/{postId}/likes 로 user2가 게시글 좋아요
    • GET /posts/{postId}/likes/count 으로 좋아요 수가 1 증가했는지 확인
    • GET /members/{memberId}/likes 로 user2가 좋아요한 게시글 목록 조회 확인
  • 팔로우/언팔로우

    • POST /members/{followerId}/follow/{targetId} 로 user2 → user1 팔로우
    • GET /members/1/followers, GET /members/2/followings 로 관계 반영 여부 확인
    • DELETE /members/{followerId}/follow/{targetId} 이후 다시 조회해 언팔로우 처리 확인

    4주차 내용도 같이 올립니다.

    변경점 👍

  • JWT 기반 인증/인가 도입

    • Spring Security 및 jjwt 의존성 추가
    • application.yml에 H2 / JPA / JWT 설정 추가
  • 회원 도메인 확장

    • Member 엔티티에 password 필드 추가 및 username unique 제약 설정
    • MemberRepositoryfindByUsername, existsByUsername 메서드 추가
    • 회원가입용 DTO(MemberCreateRequest)에 password 필드 추가
    • MemberService.create()에서 아이디 중복 체크 및 비밀번호 BCrypt 인코딩 후 저장
  • 인증 API 추가

    • POST /auth/signup : 회원가입 엔드포인트 추가 (AuthController)
    • POST /auth/login : 로그인 + JWT Access Token 발급 엔드포인트 추가
    • 로그인 실패 시 401 응답 반환
  • JWT 인프라 구성

    • JwtTokenProvider : 토큰 생성/검증 및 Authentication 생성
    • JwtAuthenticationFilter : Authorization: Bearer ... 헤더에서 토큰 추출 후 SecurityContext에 인증 정보 주입
    • SecurityConfig :
      • /auth/**, /h2-console/**, 모든 GET 요청은 허용
      • 모든 POST / PUT / DELETE 요청은 인증 필요
      • 세션 stateless, 폼 로그인/HTTP Basic 비활성화
      • BCrypt PasswordEncoder 빈 등록

버그 해결 💊

  • 별도 버그 수정 없음

테스트 💻

  • 로컬 환경에서 ./gradlew bootRun으로 서버 기동
  • PowerShell Invoke-RestMethod를 사용해 다음 시나리오 수동 검증
    • POST /auth/signup
      • username, password, nickname, bio로 회원가입 요청
      • 응답으로 생성된 회원의 id, username 확인
    • POST /auth/login
      • 방금 가입한 계정으로 로그인 요청
      • 응답으로 accessToken, tokenType, memberId, username 수신 확인
    • POST /posts
      • 로그인 응답의 accessTokenAuthorization: Bearer {token} 헤더에 설정
      • 본문에 memberId, title, content를 담아 게시글 생성 요청
      • 응답으로 생성된 게시글의 id, title, content 확인
    • GET /posts
      • 토큰 없이 호출해 직전에 생성한 게시글이 목록에 노출되는지 확인

@PHJ2000 PHJ2000 self-assigned this Nov 21, 2025
Copy link
Copy Markdown
Member

@Neibce Neibce left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

수고하셨습니다 다 잘 구현해주셨네요! 코멘트 몇 개 달아뒀으니 확인해보시면 될 거 같습니다
무조건 코멘트 대로 고치는 게 좋다는 건 아니고, 참고 정도로 보시면 될 거 같습니다..!

enabled: true

jwt:
secret: zwKNCyglJK435Wj0ylqi/KF5xubUPnzYOQj8Jkl9QWxea4xj100mCRA9tNXjldjvDaQWo9neQCutSAjNd+N4uw==
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

지금은 문제 없지만, 실제 서비스 개발 시에는 보안 문제로 인해 jwt secret을 깃에 올리지 않고, 환경변수 등으로 관리해야 합니다!

Comment on lines +38 to +43
Post created = svc.create(
req.memberId(),
req.title(),
req.content()
);
return PostResponse.from(created);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

인증/인가까지 시큐리티로 잘 구현해주신 거 같은데, 이 부분에도 로그인된 유저를 자동으로 가져오도록 해보면 좋을 거 같습니다

Comment on lines +47 to +57
@PutMapping("/{id}")
public PostResponse update(@PathVariable Long id, @Valid @RequestBody PostUpdateRequest req) {
Post updated = svc.update(id, req.title(), req.content());
return PostResponse.from(updated);
}

@ResponseStatus(HttpStatus.NO_CONTENT)
@DeleteMapping("/{id}")
public void delete(@PathVariable Long id) {
svc.delete(id);
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

수정, 삭제에도 자신이 쓴 게시글인지 검증하는 로직을 한번 추가해보시면 좋을 거 같습니다

/** PostController.list 에서 쓰는 메서드 */
@Transactional(readOnly = true)
public List<Post> findAll() {
return postRepository.findAll();
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

postRepository.findAll() 호출 후, 필터링을 하도록 구현하셨는데, 이럴 경우 일단 DB에서 모든 데이터를 가져온 뒤 필터링을 진행하기 때문에 데이터가 많을 경우 자원 소모가 심하고 OOM 발생 가능성도 있어 보입니다..!


public interface PostRepository extends JpaRepository<Post, Long> {

List<Post> findByAuthorIdOrderByIdDesc(Long memberId);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 부분에서 n+1 문제가 발생할 거 같은데, n+1 문제와 해결방법에 대해 알아보시면 좋을 거 같습니다!

Comment on lines +5 to +10
public record MemberCreateRequest(
@NotBlank String username,
@NotBlank String password,
String nickname,
String bio
) {}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

여기에 vaildation을 좀 더 걸어보는 것도 좋을 거 같습니다

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants