Code Monkey home page Code Monkey logo

bespoke's Introduction

  1. .env.example 파일 복사 후 .env 를 만든다. smtp 는 설정하지 않아도 된다. (단, smtp 설정하지 않으면 회원가입 안됨)
  2. docker-compose.yml 을 실행한다. docker-compose up -d 로 디태치 모드로 실행한다. 실행이 안되면 port 문제일 확률이 높으므로 포트를 확인하자.
  3. 서버 실행 시 시드 데이터 주입됨.

bespoke's People

Contributors

simian114 avatar namssanghyeok avatar

Watchers

 avatar

bespoke's Issues

백오피스 개발(추후 개발하자)

  • 유저 관리
  • 게시글 관리
  • 광고 관리
    • 싸구려 광고는 절라 싫다.
    • 돈 안되도 좋으니 광고 서비스? 를 개발해본다. 설계를 제대로 해보자.
  • 공지 관리
    • 신기능 추가 될 때마다 공지 게시글 만들어서 진행하면 될듯
  • 신고 관리
  • 건의사항 관리

Envelope 변경하기

as-is

  • ResponseEntity 를 return 해야지만 Envelope 이 동작한다.
  • ResponseEntity 를 return 해야하는 이유는 그래야지만 status 상태를 보고 결정할 수 있기 때문에 그럼.

to-be

  • 그냥 객체 return 하게 만들자.
  • Envelope annotation 에 statusCode 필드를 생성
  • 만약 성공시 200 status code가 아니라면 Envelope annotation 의 statusCode Field 에 값 넣기

결과는 실패. 아래처럼 return type 을 LoginResponseDto 로 하면 exception 이 발생해버림. 따라서 해당 이슈는 종료.

    @PostMapping("/login")
    public LoginResponseDto login(@Valid @RequestBody LoginRequestDto requestDto) {
        LoginResponseDto login = authUseCase.login(requestDto);

        return login;
    }

querydsl 추가

  • querydsl 패키지 추가
  • 테스트 코드 작성

실제 사용은 아직 없으므로, 테스트까지만 추가한다.

로그인에 OAuth2 붙이기

OAuth2 는 공식 오픈 한 이후 작업한다. 검증받고 뭐하고 뭐하고 그런거 귀찮다.
Spring security oauth2 client 패키지를 사용해서 구조적으로 구현한다.

google / github / naver 를 최우선으로 개발하고 이후 가능하면 meta / kakao 를 개발한다.

  • google

  • github

  • naver

  • meta

  • kakao

좋아요수 / 조회수 등 count 관리

count 관리를 어떻게 할 것인가...

  • 필드를 만들어야한다.
    • 필드를 만들지 않고, 매번 요청할 때 마다 count 를 세는건 좋지 않다.
    • 좋아요를 누르면 이벤트가 쏴지고, 해당 이벤트에서 count 를 증가시킨다.
    • 좋아요를 해제해도 이벤트가 쏴지고 해당 이벤트에서 count 를 감소시킨다.

정리.

  • 일반적인 count 는 액션이 일어나면 바로 증가시킨다.
  • 조회수 같은 경우는 캐싱을 통해 일정 수 이상이 될 경우에만 업데이트를 하도록 한다.

user

  • 팔로워
  • 팔로우
  • 좋아요한 게시글

post (조회수, 댓글은 나중에)

  • 좋아요

유저 팔로우

  • 팔로우 테이블 설계
  • 팔로우 기능 구현
  • 팔로우 시 이벤트
    • 누군가가 나를 팔로우 하면 알림을 받을 수 있어야 한다.
    • 현재 알림 관련 로직이 없으므로, 이벤트 타입 & 컨슈머만 만들것.
    • 언팔 이벤트는 없음.

서비스

팔로우 한 유저가 글을 작성하면, 알림을 받을 수 있다.

  • SSE 알림

Envelope 수정 -> page 타입

page 타입의 response 인 경우, 해당 어노테이션을 이용해 적절히 필터링할것. 현재 너무 많은 정보가 노출됨.

  • Envelope 어노테이션에 type 추가. normal, page 타입
  • 핸들링 하는 곳 수정. page 타입인 경우 필요한 정보만 걸러서 return

RefreshToken

  • token 테이블 설계
  • token 테이블 db 구현
  • access token 의 만료 시간 30분으로 설정
  • refresh token 의 만료 시간 한달로 설정
  • access token 만료 되었을 경우에 대한 처리 어떻게 할지..
  • [ ]

s3 테이블 설계 및 개발

  • s3 버킷 생성
  • bespoke 프로젝트에 연동
    • 개발용 / 배포용 두 개 생성
  • s3 테이블 설계
  • 게시글 & 유저 프로필 이미지와 연동. 어떻게 이미지 올릴지 생각해보기

LoginUser어노테이션 수정

현재 컨트롤러에서는 LoginUser 라는 어노테이션을 통해 유저 정보를 가지고 온다.

그리고 가져온 정보를 바로 UseCase 에 사용하게 된다.

문제는 controller layer -> application layer 에 전달되는 user 가 영속성으로 관리되는 user 인지, jwt 에서 최소한의 정보만 가지고 온 유저인지를 모른다는 것.

따라서 사용하는 argument resolver 에 따라 jwt user 를 그냥 사용할지, 아니면 full 유저를 사용할지 결정하게 하자.

팔로우 조건 수정

팔로우의 대상이 되는 유저는 반드시 active 유저여야한다.

이메일 미인증 또는 밴 된 유저는 팔로우 될 수 없다.

  • UserFollowService 클래스에 조건 메서드 생성

querydsl 을 이용한 동적 쿼리

  • 어드민 컨트롤러에 유저 리스트 조회 생성
  • query dsl 패키지 설치
  • query dsl 패키지 설정
  • repository impl 에 query dsl 적용

redis 연결 및 user 데이터 redis 연결

  • 레디스 도커 컴포즈
  • spring boot 도커 설정
  • redis 관련 코드 작성
  • user 정보 get redis 적용
    • user serialize 어떻게 할지..
  • redis 메모리 넘칠 시 오래 된 캐시 데이터부터 삭제하는 설정 해야함

JWT 이용한 유저 로그인

  • UserDetails 구현
  • UserDetailsService 구현
  • JWT 로직 구현
  • Login controller 구현
  • JwtAuthenticationFilter
  • 401 / 403 예외 핸들링

프론트 구성

프론트 프레임워크는 사용하지 않는다.
스프링의 ssr 을 사용한다.

  • thymeleaf
  • npm
  • bulma css
  • htmx
  • fontawesome v5
  • surreal js

쿠키 방식으로 로그인 변경

  • 메인 레이아웃
    • 헤더
    • 푸터
    • 로그인
    • 로그아웃
    • 회원가입
  • 유저 블로그 레이아웃
    • 헤더
      • 헤더의 중간에 카테고리가 드롭다운 형태로 있어야함.
    • 푸터
  • 유저 블로그 페이지 레이아웃

refactor

따로 이슈 만들기 애매한것들.

LogTrace 로그의 포맷 변경

기본 로그 포맷까지 더하면 너무 길다. logTrace 의 로그만 좀 짧게 해주고 싶은데 방법이 없을까?

게시글

  • 게시글은 제목과 설명 그리고 내용을 가진다.
    • 설명은 미리보기 등에서 사용될 수 있다.
  • 게시글에는 좋아요를 할 수 있다.
  • 게시글은 조회수를 가진다.
    • 매번 조회할 때 마다 조회수를 올리는 건 좋지않음.
    • 방법 찾아보기.
    • 게시글 조회 시 GetPost 이벤트를 발생시키고, 비동기적으로 조회수를 상승시키는건 어떨까?
    • chatgpt 에서 제시: 조회수를 필드와 redis 에서 관리하는데 우선은 redis 의 값만 증가시키고 일정시간이후에 모아서 적용
  • 게시글은 cover image 를 가진다.
  • 게시글은 댓글을 작성할 수 있어야한다.
  • 게시글에는 여러 이미지 / 영상 등을 첨부할 수 있어야 한다.
    • s3 기능을 구현해야한다.

  • post 스키마
  • post 객체 구현
  • post use case 작성
  • post search 구현
  • post 작성 시 이벤트
    • 나를 follow 하고 있는 유저한테 알림을 보내줘야함.
    • [ ]

  • 좋아요는 다른 이슈에서 구현

event 관련 코드 리팩토링

  • application layer 에서는 인터페이스를 사용해서 이벤트 send
  • infrastructure 에서 consumer / publisher 구현체 구현

role 구현

  • db 설계
  • domain model 작성
  • entity 에 구현
  • spring security 연동

2개 role 구현

  • user
  • role

한명의 유저는 여러 role 을 가질 수 있다.

회원가입 시 이메일 검증 로직 추가

  • 구글 SMTP 등록
  • 설정 & env 파일
  • 회원 가입 시 3분 짜리 token 발급 후 이메일 전송
  • 이메일의 링크 누르면 완료
    • 링크는 /email-validation?code=xxxxxxx 형태로 등록.
  • email validation 컨트롤러 추가. code 로 받은 token 값을 이용해 token db 에서 찾은 후 인증 완료

user 에 status 추가

상태는

  • INACTIVE (이메일 미인증)
  • ACTIVE (일반)

정지는

  • banned_until 필드를 생성.

  • sql 문 수정

  • 도메인 모델 수정

  • UserPrincipal 에서 status / deletedAt / banned_until 여부에 따라 false 되도록 수정

  • 로그인 테스트

알림 서비스 (우선순위 높음)

알림 테이블 (Notification)

  • 식별자 -> notification_id
  • 알림 확인 -> check (boolean)
  • 알림 종류 -> type (게시글 / 댓글 / 팔로우 / ...)

알림 서비스

  • 누군가 내 게시글에 댓글을 달면 알림을 받을 수 있음
  • 누군가 내 게시글을 좋아요 누르면 알림을 받을 수 있음
  • 누군가 내 댓글을 좋아요 누르면 알림을 받을 수 있음
  • 누군가 나를 팔로우 하면 알림을 받을 수 있음

알림을 어떤 방식으로 받을건가?

  • getNotification 을 하면 알림 리스트를 받아올 수 있음
  • 상세 조회를 하면 알림 알림이 봤다고 체크되어야함
    • 상세 조회를 해야지만 알림을 봤다고 처리해야하나..? 그냥 리스트 자체에서 호출하면 처리해도 되지 않을까?
      • 생각해봤는데 이렇게 되면 구현이 어려울거같음. 상세 조회 시 읽음 처리를 하는 걸로.

  • 알림 페이지를 따로 만들지 않고 할 수는 없을까?
  • 그냥 알림 페이지를 만드는게 가장 쉬운 방법인거같다.
  • 아주 심플하게 만들것!

--- 이건 알림 서비스가 정말 구현되면 그 이후에...
실시간 알림

  • 실시간 알림은 SSE 가 연결이 되어야지만 가능e

신고 (우선순위 낮음)

신고 테이블 (Report)

  • 식별자 -> report_id
  • 신고 대상 타입 -> ref_type
  • 신고 대상 식별자 id -> ref_id
  • 신고 내용 -> contents (string)

게시글 신고

  • 게시글 신고를 할 수 있어야함
  • 일정 수 이상 신고(5회정도로 하면 될듯) 된 게시글은 post 의 상태를 block 으로 돌림
    • 신고 처리 이후에 post 의 신고 된 횟수 세고 뭐 이런 동작은 해당 쓰레드에서 하지 않고, 비동기로 해야함.

유저 신고 (일단 보류)

백오피스

  • 신고 리스트를 볼 수 있어야함
  • 타입 / 시간 등 으로 정렬, 분류가 가능해야함

redis 캐싱 전략 세우고 적용

캐싱 전략에 대해 처음에는 레파지토리 레이어에서 진행하면 되겠다고 생각했음.

하지만, 정말 캐싱이 필요한 건 클라이언트가 요청한 정보 그 자체라는 생각이 들었다.

지금처럼 레파지토리에서 캐싱을 하게 되면, 그 요구도 물론 충족되지만, 쓸데없이 모든 레이어를 뚫고 오는게 좋지 않다는 판단을 했다.

따라서 캐싱은 usecase 에서 진행하도록 한다.

그리고 entity 는 캐싱의 대상이 아니다. 캐싱은 dto 를 대상으로 한다. 이유는 dto 는 serialize 로 만들기 상대적으로 쉽기 때문이다.


  • 게시글 디테일 페이지
    • 게시글 디테일 페이지는 조회수 / 좋아요수 등...?
    • 게시글 dto 가 캐싱의 대상이 된다. 이 캐싱은 약 5분간 진행되게 한다.
  • 게시글 좋아요 여부 캐싱
    • 게시글 좋아요 여부는
  • 게시글 리스트는 5분 캐싱을 그냥 때려버린다.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.