2차 팀 프로젝트 : BookBox (팀 회의)

도서 대여/예약 앱 플랫폼 : 협업
SHIN's avatar
Oct 21, 2024
2차 팀 프로젝트 : BookBox (팀 회의)
 
프로젝트 전 설계 및 기획 단계
기획
  1. 기존 앱 모방(적절한 앱)
  1. 기능/화면 정리
Front
  1. 그림 그리기
  1. 데이터 바인딩
BackEnd
  1. Table 설계
  1. API 문서 → Mock(가짜) (Mock데이터를 뿌리기 위한 서버 구축)
Mock
{ "status" : "msg" : "body" : [ {title: 제목, id:1, username:shin } ] }
  1. jar 파일 생성 후 굽기
핵심(필요)기능
유저
💡
  1. 회원가입
    1. SMS & Email : 추후 Push 알림을 위해 추가
검색(필터링) → 제목, 저자, 출판사 등
검색 화면
💡
최근 검색어 및 카테고리(?)
검색 후 화면
💡
  1. 14 권 → 숫자 부분
  1. 도서 표지
  1. 도서 제목
  1. 저자
  1. 출판사
도서 상세정보
💡
  1. 도서 표지
  1. 카테고리
  1. 도서명
  1. 저자
  1. 출판사 및 출간일자
  1. 줄거리 (소개)
  1. 대여 (대여 부분에서 다룸)
대여
대여 전
대여하기
💡
  • 책 재고 O → 대여와 동시에 현재시간기준 +7일
    예약하기
    💡
    • 책 재고 X → 예약하기 누를 시 현재 예약 순번에 따라 카운트
    • 앞선 예약자가 순서가 되어서 대여가 되거나 예약 취소 시 바로 뒤 예약자 순번 업데이트
    1. 첫 번째 예약 순번일 때, 기존 대여자가 반납 시 알림 없이 해당 예약자의 서재에 자동으로 등록(대여)?
    1. 대여 가능하다는 Push 알림 전송 후 제한 시간? (제한 시간내에 대여 안할 시 자동으로 다음 예약 순번에게 넘김) → V2 정도의 기능
    대여 후
    반납 후
    💡
    1. 대여자가 없을 시 한 번 더 대여 가능?
    1. 누군가 대여중일 때 예약 순번에 따라 동등하게 권한 제공(대여를 위한 예약)
    1. 잘못 반납 했을 경우 → 제한 시간내에 반납 취소 가능 V2
    (대여중일 때) 상세페이지에서의 읽기
    💡
    1. 읽기 버튼 클릭 시 내 서재로 이동 후 뷰어로?
    1. 해당 상세페이지에서 바로 뷰어로 이동?
      1. → b 전제에서 뷰어 종료 시 내 서재 페이지 or 상세 페이지
    예약
    상단의 대여부분 참조
    하단 Nav
    💡
    1. 도서 표지, (카테고리?), 도서명, 저자
    1. 도서 표지, 도서명, 대여자 & 예약자 표시
    검색
    💡
    최근 검색어 및 카테고리(?) → 카테고리를 여기 넣을지, 메인홈에 출력할지
    내 서재 or 보관함
    💡
    • 대여내역, 예약내역 → 마이페이지는 설정 탭에서 확인 가능
    설정
    내 정보
    아이디 username 로그아웃
    비밀번호 변경
    내서재 설정
    💡
    • 다운로드 관련 (인코딩 부분)
    앱 정보
    발표 스크립트

    1. 이런 주제의 앱이다

    💡
    • 도서를 사용자들에게 대여 및 예약 시스템을 제공하는 앱 플랫폼
    • 특히 이 프로젝트는 대여 반납 예약에 초점을 둬서 ~
     

    2. 기술 스택

    💡
    1. Spring Boot
    1. Jpa
    1. H2
    1. Git
    1. Notion
     

    3. 시연 영상

     

    4. ERD

    💡
    • 첫 페이지에는 전체 테이블 삽입
      • 전체 테이블은 이렇다. 이 테이블들 중 4개의 테이블에 대한 고민이 있었는데 ~
    • 이후 페이지부터 프로젝트의 핵심 테이블 확대
      • 이 테이블을 만들 때 어떤 고민이 있었고, 어떻게 해결했다
     
    💡
    1. Book 테이블
      1. 도서 재고를 따로 관리하지 않고 대여수와 예약수로만 처리하는 방식에 대한 고민
      2. 일반적으로는 재고로 관리하지만, 이 시스템에서는 물리적 재고가 아닌 전자 도서임을 고려해서 대여 여부와 예약만으로 상태를 관리하도록 설계
    1. Lend 테이블
      1. 대여 일자와 반납 일자를 자동으로 관리하고, 반납일이 지나면 자동으로 반납 상태로 변경되는 기능을 고려
      2. 또한 대여 연장 기능도 반영 → date와 status 필드를 통해 대여와 반납 상태를 자동으로 관리하도록 설정
    1. Reservation 테이블
      1. 예약 순번을 시퀀스로 지정하여 대여자가 반납을 함과 동시에 첫 번째 순서로 예약한 예약자에게 자동으로 대여가 됨
      2. 두 번째 예약자의 순번도 자동으로 첫 번째 순번으로 업데이트 되게 함으로써 대여와 예약간 매끄러운 진행에 초점을 둠
     
    정규화
    💡
    1. Book_tb (도서 테이블)
      1. 관계
        1. Book_tb 는 Lend_tb 및 Reservation_tb와 연관
        2. 각 도서는 한 번에 한 명의 대여자에게만 대여될 수 있으며(lend_statu로 관리), 동시에 ㅊ최대 3명의 예약자만 가능하게 제한되어 있습니다
      2. 설명
        1. 하나의 도서에 대해 다수의 예약이 있을 수 있지만 한 번에 하나의 대여만 가능
        2. 즉 1:1 관계로 Lend_tb와 연결되고, 도서에 대해 다수의 예약을 처리할 수 있도록 1관계로 Reservation_tb와 연결
          • Book_tb : Lend_tb = 1:1
          • Book_tb : Reservation_tb = 1:N
    1. Lend_tb (대여 테이블)
      1. 관계
        1. 대여 테이블은 한 명의 사용자와 한 권의 도서에 대해 1:1 관계를 유지
        2. 각 대여는 도서의 고유한 상태를 나타내며, 이 상태는 반납 여부와 대여 기간에 따라 달라짐
      2. 설명
        1. 대여 테이블에서 반납 상태(return_status)와 연장 상태(extend_status)를 관리하여 대여의 진행 상태를 기록
        2. Lend_tb는 Reservation_tb와 간접적인 관계를 가짐
        3. 반납 시 예약자 중 가장 빠른 순번의 예약자가 자동으로 대여를 받는 구조를 통해 대여와 예약간의 흐름을 매끄럽게 처리
    1. Reservation_tb (예약 테이블)
      1. 관계
        1. Reservation_tb는 한 명의 사용자와 하나의 도서에 대해 1 관계를 가짐
        2. 즉 한 권의 도서에 대해 여러 사용자가 예약을 걸 수 있으며, 각 사용자는 자신이 예약한 도서만 예약 가능
     
     

    5. Front-End / Back-End

    5-1. 서버쪽을 진행하면서 기존 SSR과 뭐가 달랐나?
    💡
    • SSR 방식으로 개발을 진행했을 땐 서버에서 HTML을 생성하고 SEO(검색엔진 최적화)에 유리했으며 상태관리가 비교적 단순
    • 하지만 사용자가 페이지를 이동할 때마다 서버에서 새로운 뷰를 받아야해서 페이지 전환이 다소 느림
    • 즉 이번에 진행했던 RestAPI 방식은 API 호출을 통해 데이터만 전달하여 빠른 서버 구축 및 테스트가 용이 했다. 그리고 프론트측의 요청사항에 대해 빠른 업데이트가 가능했음
     

    JWT vs Session 비교

    💡
    1. 세션 방식의 한계
      1. 세션을 이용한 인증 방식에서는 httpOnly 쿠키를 사용하여 브라우저에서 크르비트로 쿠키에 접근할 수 없도록 막음
      2. 이 방식은 보안에 좋지만 앱과 같은 환경에서는 쿠키가 제대로 동작하지 않거나 사용이 불편할 수 있음
      3. 그에 비해 JWT는 앱에서도 쉽게 사용 가능한 장점
    1. 인증 서버 통합
      1. JWT를 사용하면 여러 시스템 간에 인증을 통합 가능.
      2. Ex) 중앙에서 인증 서버를 만들어 발급한 JWT를 여러 서비스에서 동일하게 사용하여 인증 처리 가능 → 시스템이 분산되어 있어서 쉽게 확장 가능
    1. Stateless 구조
      1. JWT는 stateless 구조를 지원
      2. 즉 서버가 별도로 세션 상태를 저장하거나 관리할 필요 없음
      3. 세션 기반 인증은 서버에서 상태를 저장해서 세션 저장소(Redis, DB등)를 따로 마련해야 함
      4. 하지만 JWT는 토큰 자체에 사용자의 인증 정보가 포함되어 있어서 필요 없음 → 서부 부담 줄어들고 확장성 좋음
    1. 전자 서명 방식
      1. JWT는 전자 서명 방식을 사용하여 서버가 토큰을 발급하고, 클라이언트는 그 토큰을 가지고 인증을 처리함
      2. 서버는 그 토큰을 검증하여 사용자를 인증할 수 있기 때문에 별도의 세션을 저장하거나 관리할 필요가 없으며 처리 속도와 보안이 더 간편
     
    정리
    💡
    • 세션 방식은 쿠키 기반이고 앱 환경에서 불편할 수 있지만, JWT는 앱에서도 쉽게 접근 가능
    • 여러 시스템에서 인증을 통합할 수 있으며, 상태 저장을 하지 않기 때문에 서버 부담이 적음
    • JWT 전자 서명된 토큰을 사용해 인증을 처리하므로 세션 저장소가 필요 없고 관리가 간편
     
     
    5-2. Front
    💡
    • MVVM 패턴 (사용한걸 얘기하는게 아닌, 사용해서 뭐가 좋았는지)
    • MVVM 패턴을 사용해서 개발을 진행하니 view와 모델간 의존성을 줄이고, view model을 통해 상호작용을 하여 코드가 명확하고 요지보수가 용이한 단점
    • RiverPod으로 상태관리를 했을 때, 여러 컴포넌트에서 동일한 상태를 쉽게 공유 가능했고 stateNotifier나 provider와 같은 다양한 상태관리 방법을 통해 상황에 맞게 사용할 수 있는 장점
     

    6. 느낀점

    💡
    • 개발 기간이 짧아서 아쉬웠다
    • 처음으로 Front와 Back을 완전 구분해서 개발을 진행해보니 ~
    • 역할 분담이 명확해져서 ~
     
     
     
    팀 컨벤션
     
    2차 프로젝트 협업 연습한다 생각하고 즐거운 코딩 해보아요.
     
    Git Flow
     
    커밋 메시지
    commit 메시지 작성시 뒤에 footer는 생략하고 type에 머릿말 통일
    feat: 로그인 기능 추가
    notion image
    브랜치 이름
    branch 이름 : 도메인/기능 ex) user/join 단어간 결합은 kebab-case 사용(하이픈 연결) ex) book/new-lend
    git 이슈 남기기
    중요도 표시할 때 ⭐  이거 복사해서 1~3단계로 표시 고고고
     
    PR요청 순서
    💡
    간단한 흐름 요약
    내 브랜치 commitdev로 이동 후 최신 dev 받기내 브랜치로 와서 git rebase dev
    -> 내 브랜치에서 작업내용과 최신 dev 합짐git add . 하고 commit (충돌 났으면 잡고 git add . 하고 commit 후 git rebase --continue)깃헙가서 pr요청
    오른쪽이 내 브랜치, 왼쪽이 dev[기본값])reviewer정해서 요청
     
    다 만들었당 ㅎㅎ 이제 합쳐야징! 순서는? 1. 본인이 작업하던 브랜치(abc)에서 일단 커밋(최신 상태 보존) : git commit -m "msg" 2. dev 브랜치로 이동 : git checkout dev (dev 브랜치가 없다면 git checkout -b dev 명령으로 dev 브랜치를 만들면서 dev로 이동) 3. dev에서 최신 dev를 내려 받기 : git pull origin dev 4. 본인이 작업하던 브랜치 abc로 돌아 오기 : git checkout abc 5. 본인이 작업하던 브랜치 abc에서 최신 dev를 합친다 : git rebase dev 5-1. 오류가 있다면 오류 잡고 git add . -> git rebase --continue 오류 남았으면 잡고
    다시 git add . → git rebase --continue 오류 다 잡혔으면 -> git commit -m "msg" 6. 본인이 작업하던 브랜치 abc에서 dev를 합쳤으니 push한다. : git push origin abc 7. 본인이 작업하던 브랜치 abc에서 작업한 것을 dev와 합치고 push까지 했으니 github 이동->클릭 8. 위에 7번을 클릭하고 travel 리파지토리에서 상단 Pull requests -> 우측 New pull request 9. 왼쪽에 dev(default값), 오른쪽에 작업하던 브랜치 compare:abc선택 후 create pull request 10. 우측에 reviewer를 정해준다.(기본 KimSoapSoap, 부재시 다른 확인 가능하신 분 선택) --병합 완료와 그 다음 진행-- 11. merge되면 다른 사람 기다리면서 블로그 정리등 하다가 다같이 한 번씩 올려서 다시 시작할 때 dev로 이동해서 최신 dev 내려받음. git checkout dev -> git pull origin dev 12. 최신 dev 내려 받았으면 새로운 브랜치를 만들면서 이동 git checkout -b abc2 13. 새로운 브랜치 abc2에서 다음 기능 개발. -> 이후 1번부터 반복 --아래는 10번에서 reviewer가 된다면 reviewer의 역할-- 14. reviewer는 pr요청 들어온 거 눌러서 Commits와 File Changed 확인하고 우측에 Review changes 눌러서 Comment : 승인없이 코멘트만//Approve: 승인. 15. 승인하고 나서 올린 거 보면 Merge pull request 누르면 Confirm merge가 나온다. 이걸 누르면 merge 완료


     
     
    Repository
    JpaRepository 인터페이스 구현해서 사용
    클래스명
    파스칼 표기법(PascalCase) : 첫 글자 대문자 + 이후 camelCase BoardController, BoardService, UserRepository BoardResponse 내부에 DTO클래스는 DTO를 끝에 ex) detailDTO
     
    테스트 클래스명 & 테스트 메서드명
    테스트 클래스 : 파스칼 표기법(PascalCase) + 끝에 Test ContentRepository -> ContentRepositoryTest 테스트 메서드 : 카멜 표기법(camelCase) + 끝에 _test() //given //when //then(혹은 //eye)
    엔티티 테이블명&필드명
    //엔티티 테이블 이름은 엔티티 클래스 이름끝에 _tb @Table(name = "user_tb") public class User { //필드는 카멜 표기법(camelCase) 사용 private String userId; private String userName; }
    메서드 명 & 함수명
    동사 + 명사 ex) findAll(), findById(), deleteReply()
     
    생성자 주입
    클래스에 @RequiredArgsConstructor 붙이고 주입할 멤버변수에 final 붙이기
     
    엔티티에는 가능하면 Setter 빼기
    예를 들면 User 엔티티에 Setter를 넣어서 username을 변경하는 것이 아니라 username은 상태이므로 상태는 setter가 아닌 기능을 통해 변경. changeName같은 메서드를 넣어놓고 이 기능을 통해 상태를 변경 //User엔티티 내부의 changeName 메서드 public void changeName(String username) { this.username = username; }
     
     
     
    패키지 구조
    A.B.C global -config -interceptor -error -util ... 엔티티1 -Entity -EntityController -EntityService -EntityRepository -EntityResponse -EntityRequest 엔티티2 . .
    URI 전략
    URI전략 계층 구조상 상위를 컬렉션으로 보고 복수단어 사용 (member -> members // order -> orders) 주소에는 camelCase를 사용하지 않으므로 필요시 하이픈 연결 (joinForm -> join-form) • 회원 목록 조회(GET): /members • 회원 등록(POST) : /members • 회원 조회(GET) : /members/{id} • 회원 수정(PUT) : /members/{id} • 회원 삭제(DELETE) : /members/{id} • 회원 등록 폼(GET) : /members/new • 회원 수정 폼(GET) : /members/{id}/edit
     
     
    API 문서
     
    💡
    Swagger 사용 취소 ㅇ0ㅇ → Spring REST Docs 사용할 거임
     
     
     
     
     
    백엔드 & 프론트엔드 기능 구현 회의
    💡
    적어놨다고 모두 구현할 예정은 아니고 일단 그럴듯 한 기능 모두 적어 놓은것입니다. 본인이 담당하게 된 기능 담당자 칸에 태그 등록해 주시고 블로깅과 포폴을 위해 개발 하며 기록할 수 있도록 합니다.👍
     
     
     
     
     
    DB 설계 : ER-Diagram

    초기

    notion image
     

    최종

    notion image
     

    상세 테이블 목록

    Book_tb

    notion image

    Category_tb

    notion image

    Favorite_tb

    notion image

    User_tb

    notion image

    Reservation_tb

    notion image

    Lend_tb

    notion image

    Comment_tb

    notion image

    Report_tb

    notion image

    Admin_tb

    notion image
     
    프로젝트 참고사항

    특징

    대여, 예약 시스템 특징
    • 대여중인 도서를 누군가 예약하면 해당 도서는 연장이 불가능
    (우선 책당 한 권만 대여가능하게 하는데 가능하면 여러 권 가능하게 시도)
    • 반납일자는 대여 순간의 정확한 시간과 상관없이 +7일
    →만약 10일 15시에 대여하면 반납 기한은 17일 24시까지
    • 대여 기한이 지나면 자동으로 반납이 된다.
    • 반납된 도서에 예약이 걸려있다면, 그 해당 도서는 반납 시 자동으로 예약자에게 대여가 된다.
      • → scheduled 스케줄링으로 걸어두기
        → Quart 라이브러리 사용하면 스케줄 설정할 수 있음 ( 신민재 도움 )
    • 로컬 시간 확인하기 (되면)
     
     

    책 카테고리 번호

    categoryId // categoryName 112011 소설 170 경제경영 336 자기계발 656 인문학 798 사회과학 74 역사 55889 에세이 987 과학 2913 잡지 1230 가정/요리 517 예술/대중문화 55890 건강/취미 1196 여행 13789 유아 1108 어린이 1137 청소년 2551 만화 2105 고전 1383 자격증/수험 1322 외국어 8257 대학교재/전문서적
     
     
     
     
     
     
     
     
     
     
    인증키
    ttbpoksal_k1706001
    알라딘 도서 카테고리
     
     
    더미 정보 가져온 방법 (1)
     
     
    추가 및 수정 사항

    User테이블

    수정 사항
    user테이블에 nick 추가됨
    → 리뷰 달 때 아이디 대신에 nick넣기 위함
    → ERD수정완료
    notion image
     
    하고 VARCHAR2(40)이라고 적혀 있어서 뭔지 몰라서 일단 VARCHAR(40)으로 변경하기는 했는데 상관 없을까요?
     
    VARCHAR2는 Oracle에서만 사용하는 데이터 타입!
     

     
     
    관리자 페이지 버튼을 상세페이지의 예쁜 버튼으로 변경
     
     

     

    Like 엔티티

    notion image
     
    ⇒ likeStatus ( 좋아요 여부 ) 제거
     

     

    Book 테이블

     
    notion image
     
    → 즐겨찾기 많은 순 정렬 기능 구현을 위해 column 추가
     
    → 하기로 했나요 ?
     
    → db에만 추가됨. 엔티티에는 아직 추가안함!
     
     
    Share article

    SHIN