분석 및 시나리오
사용자
- 회원가입을 할 수 있다.
- 로그인할 수 있다.
- 로그아웃할 수 있다.
- 회원 탈퇴를 할 수 있다.
초대
- 다른 사용자를 초대할 수 있다.
- 초대를 받은 사용자는 초대를 거절/수락할 수 있다.
- 초대를 거절하면 초대 테이블에서 해당 entity가 삭제된다.
- 초대를 수락하면 초대 테이블에서 해당 entity가 삭제되고 보드_사용자 테이블에 참여자로 등록된다.
보드
- 칼럼들의 집합체
- 보드는 다음과 같은 속성을 갖고 있다.
- id, 이름, 생성자, 배경 색상, 설명
- 노션 페이지같은 느낌
- 사용자가 생성할 수 있다.
- 생성한 사용자(주인)가 다른 사용자(초대받은 사람)를 초대할 수 있다.
- 하나의 보드에 여러 명의 사용자가 존재한다.
- 보드에 속한 사용자들은 보드를 수정/초대할 수 있다.
- 보드에 속한 사용자들은 나갈 수 있다.
- 생성자만 보드를 삭제할 수 있다.
컬럼
- 카드들의 집합체
- 특정 보드에 속한 사용자만 생성할 수 있다.
- 컬럼 속성
- id,이름, 순서
- 컬럼은 보드에 속한 누구나 생성/수정/삭제가 가능하다.
카드
- 카드 속성
- id, 제목, 내용, 칼럼, 색상, 마감일, (체크리스트, 작업자 리스트)
- 카드는 보드에 속한 누구나 조회/생성/수정/삭제가 가능하다.
- 조회
- 해당 보드에 속한 사용자는 해당 보드의 모든 카드를 볼 수 있다.
- 보드 기준으로 카드를 조회할 수 있다.
- 칼럼 기준으로 카드를 조회할 수 있다.
- 칼럼에 속한 카드들은 순서가 정해져있다.
- 하나의 카드는 제목과 내용, 댓글, 체크리스트, 작업자 목록이 존재한다.
- 생성
- 제목과 함께 카드를 생성할 수 있다.
- 나머지는 빈 내용이다.
- 위치는 항상 해당 칼럼의 맨 마지막에 생성된다.
- 수정
- 내용을 수정할 수 있다.
- 댓글을 달 수 있다.
- 하나의 카드에는 여러 개의 댓글이 존재한다.
- 작업자를 설정해줄 수 있다.
- 하나의 카드에는 여러 명의 작업자를 정할 수 있다.
- 보드 내에서 카드를 옮길 수 있다.
- 특정 카드를 다른 카드의 위 또는 아래로 옮길 수 있다.
- /api/v1/cards/{cardId}/to/{toCardId}/[above|below]
- 카드가 없는 빈 칼럼으로 옮길 수 있다.
- /api/v1/cards/{cardId}/to/columns/{toColumnId}
- 서도 다른 칼럼으로도 위와 같은 api로 옮길 수 있다.
- 단, 다른 보드의 칼럼으로는 옮길 수 없다.
- 특정 카드를 다른 카드의 위 또는 아래로 옮길 수 있다.
- 삭제
- 해당 보드에 속한 사용자는 해당 보드의 카드를 삭제할 수 있다.
- 작성자가 아니여도 삭제할 수 있다.
- 조회
- 고급 기능
- 카드 내에 체크리스트가 존재한다.
- 체크리스트 생성 URI를 통해 할 일 입력
- 체크리스트 수정을 통해 입력한 할일의 완료/취소 체크 가능
- 체크리스트의 진행도가 존재한다.(진행 퍼센트를 응답으로 반환)
- 첨부 파일을 업/다운로드를 할 수 있다.
알림 기능
- 카드에 대한 상태변경에 대해 해당 보드의 참여자한테 알림을 보낸다.
- 카드가 생성/수정/삭제 되었을 때 알림을 보낸다.
- 카드가 다른 칼럼으로 이동됐을 때도 알람을 보낸다.
- 카드에 댓글이 달렸을 때 알람을 보낸다.
- 각 상태변경에 해당하는 메서드가 실행될 때 스프링 이벤트 퍼블리셔는 이벤트를 발행한다.
- 이벤트 리스너는 이벤트를 받아 이벤트의 정보를 통해 notification과 userNotification을 저장한다.
- notification은 카드에 변경을 일으킨 당사자의 아이디,해당카드가 속한 보드아이디,변경타입,변경메시지,알림이 저장되는 시간(카드가 변경된 시간)로 구성
- userNotification은 알림이 생성된시점의 보드 참여자와 알림의 아이디,알림의 상태(UNREAD)로 구성(저장될 때, 한번에 보드 참여자의 수만큼 동일한 아이디의 알림으로 필드가 생성될듯?)
- 보드의 참여자는 알림을 조회할 수 있다.
- 조회하면 해당 보드 참여자의 아이디를 지닌 필드의 UNREAD가 READ로 변경
- 카드가 생성/수정/삭제 되었을 때 알림을 보낸다.
API 명세
Domain | 기능 | method | url | request | response | error response |
User | 회원가입 | POST | /api/v1/users/signup | { "email" : " email@dot.com", "nickname" : "닉2", "password" : "passpass", "passwordCheck" : "passpass" } |
{ "status": 201, "message": "회원가입 성공", "data": null} | { "status": 400, "message": "이미 존재하는 이메일입니다.", "data": null } , { "status": 400, "message": "잘못된 입력값", "data": [ { "field": "email", "message": "must be a well-formed email address" } ] } |
User | 로그인 | POST | /api/v1/users/login | { "email" : " email@dot.com", "password" : "passpass" } |
{ "status": 200, "message": "로그인 성공", "data": null} | { "status": 400, "message": "이메일 또는 패스워드를 확인해주세요.", "data": null } |
User | 로그아웃 | PUT | /api/v1/users/logout | { "status": 200, "message": "로그아웃 성공", "data": null} | ||
User | 마이페이지 | GET | /api/v1/users/me | { "status": 200, "message": "마이페이지 조회 성공", "data": { "email": " email2@dot.com", "nickname": "닉2", "myBoards": [ { "id": 1, "name": "이름", "color": "색깔" }, { "id": 2, "name": "이름2", "color": "색깔2" } ] } } |
||
User | 회원정보 수정 | PUT | /api/v1/users/edit | { "nickname" : "minisun4", "password" : "passpass" } |
{ "status": 200, "message": "개인정보 업데이트", "data": null} | { "status": 400, "message": "비밀번호가 일치하지 않습니다.", "data": null} |
User | 비밀번호 수정 | PUT | /api/v1/users/pw | { "newPassword" : "minisun2", "newPasswordCheck" : "minisun2", "password" : "passpass" } |
{ "status": 200, "message": "비밀번호 업데이트", "data": null} | { "status": 400, "message": "비밀번호가 일치하지 않습니다.", "data": null} |
User | 회원탈퇴 | DELETE | /api/v1/users/withdraw | { "status": 200, "message": "회원 탈퇴 성공", "data": null} | ||
Board | 메인페이지 | GET | /api/v1/boards | { "status": 200, "message": "메인 페이지", "data": [ { "id": 1, "name": "이름", "color": "색깔" }, { "id": 2, "name": "이름2", "color": "색깔2" } ] } |
||
Board | 보드 생성 | POST | /api/v1/boards | { "name" : "보드보드", "color" : "색상색상" } |
||
Board | 보드 수정 | PUT | /api/v1/boards/{boardId} | { "name" : "보드보드", "color" : "색상색상" } |
||
Board | 보드 삭제 | DELETE | /api/v1/boards/{boardId} | |||
Section | 컬럼 생성 | POST | /api/v1/sections | { "name" : 칼럼이름" } |
||
Section | 컬럼 이름 수정 | PUT | /api/v1/sections/{sectionId} | { "name" : 칼럼이름" } |
||
Section | 컬럼 삭제 | DELETE | /api/v1/sections/{sectionId} | |||
Section | 컬럼 순서 이동 | PUT | /api/v1/sections/{sectionId} | |||
Card | 카드 단일 조회 | GET | /api/v1/cards/{cardId} | { "status": 200, "message": "카드 조회", "data": { "id": 1, "title": "123", "content": null, "color": null, "deadline": null, "checkList": […], "rate": 33.333336, "comments": […] } } |
||
Card | 보드 기준 카드 조회 | GET | /api/v1/boards/{boardId}/cards | [ { "id": "id", "title": "title", "color": "color", }, … ] |
||
Card | 칼럼 기준 카드 조회 | GET | /api/v1/sections/{sectionId}/cards | [ { "id": "id", "title": "title", "color": "color", }, … ] |
||
Card | 카드 생성 | POST | /api/v1/boards/{boardId}/sections/{sectionId}/cards | { "title": "제목" } |
{ "status": 201, "message": "카드 생성", "data": null} | |
Card | 카드 수정 | PUT | /api/v1/cards/{cardId} | { "title": "제목2", "content": "내용2", "color": "색상2", "deadline": "2024-01-02T16:08:22.256Z" } |
{ "status": 200, "message": "카드 수정", "data": null} | |
Card | 카드 이동 | PUT | /api/v1/cards/{fromCardId}/to/{toCardId}/[previous|next] | { "status": 200, "message": "카드 위치 변경", "data": null} | ||
Card | 카드 이동(빈 칼럼으로 이동) | PUT | /api/v1/cards/{cardId}/to/sections/{toSectionId} | { "status": 200, "message": "카드 위치 변경", "data": null} | ||
Card | 카드 삭제 | DELETE | /api/v1/cards/{cardId} | |||
Card | 카드 작업자 추가 | POST | /api/v1/cards/{cardId}/workers | |||
Card | 카드 작업자 삭제 | DELETE | /api/v1/cards/{cardId}/workers/{workerId} | |||
CheckList | 체크리스트 생성 | POST | /api/v1/cards/{cardId}/checklist | { ”description”:”1번째 할일” } |
||
CheckList | 체크리스트 수정 | PUT | /api/v1/cards/{cardId}/checklist | { ”checkSign”:”true” } { ”checkSign”:”false” } |
||
CheckList | 체크리스트 삭제 | DELETE | /api/v1/cards/{cardId}/checklist | |||
File | 첨부파일 생성 | POST | /api/v1/cards/{cardId} | |||
File | 첨부파일 수정 | PUT | /api/v1/cards/{cardId} | |||
File | 첨부파일 삭제 | DELETE | /api/v1/cards/{cardId} | |||
Invitation | 보드에 초대 | POST | /api/v1/boards/{boardId}/invite/{userId} | { "status": 201, "message": "successfully invited user", "data": null} | { "status": 400, "message": "이미 초대된 사용자입니다.", "data": null} | |
Invitation | 보드에 초대 취소 | DELETE | /api/v1/boards/{boardId}/cancel/{userId} | { "status": 200, "message": "초대 취소 성공", "data": null} | { "status": 404, "message": "초대가 존재하지 않습니다.", "data": null} | |
Invitation | 초대 목록 조회 | GET | /api/v1/invitations | { "status": 200, "message": "내가 받은/보낸 초대 조회 성공", "data": { "receivedInvitations": [ { "boardId": 1, "boardname": "보드이름", "senderId": 1, "senderNick": "닉2" } ], "sentInvitations": [ { "boardId": 2, "boardname": "보드이름", "receiverId": 1, "receiverNick": "닉2" } ] } } |
||
Invitation | 초대 거절 | PUT | /api/v1/boards/{boardId}/reject | { "status": 200, "message": "초대 거절 성공", "data": null} |
{ "status": 404, "message": "초대가 존재하지 않습니다.", "data": null} | |
Invitation | 초대 수락 | PUT | /api/v1/boards/{boardId}/approve | { "status": 200, "message": "초대 수락 성공", "data": { "email": " email@dot.com", "boardId": 1, "role": "PARTICIPANT" } } |
{ "status": 404, "message": "초대가 존재하지 않습니다.", "data": null} | |
Comment | 댓글 작성 | POST | /api/v1/cards/{cardId}/comments | { "content":"도대체 무슨 오류야--??"} | { "status": 201, "message": "save_comment", "data": null} | |
Comment | 댓글 수정 | PUT | /api/v1/comments/{commentId} | { "content":"도대체 무슨 오류임?"} | { "status": 200, "message": "update_comment", "data": null} | |
Comment | 댓글 삭제 | DELETE | /api/v1/comments/{commentId} | { "status": 200, "message": "delete_comment", "data": null} | ||
Event | 이벤트 조회 | GET | /api/v1/notification/{boardId} | "status": 200, "message": "알림 조회", "data": [ { "fieldName": "CREATED", "fieldContent": "user1 회원에 의해 string2 BOARD에서 카드가 생성되었습니다.", "createdAt": "2024-01-03T14:11:13.24057" }, { "fieldName": "UPDATED", "fieldContent": "user1 회원에 의해 string2 BOARD에서 카드가 수정되었습니다.", "createdAt": "2024-01-03T14:12:43.226851" }, { "fieldName": "DELETED", "fieldContent": "user1 회원에 의해 string2 BOARD에서 카드가 삭제되었습니다.", "createdAt": "2024-01-03T14:12:51.445727" }, { "fieldName": "ADD_COMMENTS", "fieldContent": "user1 회원에 의해 string2 BOARD에서 카드에 댓글이 작성되었습니다.", "createdAt": "2024-01-03T14:13:02.103208" } ] } |
나는 User랑 Invitaion을 맡았다!
ERD
와이어프레임
설계하면서 생각한 점 :
프로젝트를 통해 배운 점 :
User domain 개발일지
Invitation domain 개발일지
'Developing > Journal' 카테고리의 다른 글
깃허브 프로필 꾸며보기!! (0) | 2024.02.09 |
---|---|
[팀프로젝트][모아요이츠] Post domain 개발일지 (1) | 2024.01.09 |
[내일배움캠프][팀프로젝트]햇살마켓 프로그램 개발일지 (0) | 2023.12.05 |
[내일배움캠프][Spring Team Project]뉴스피드 프로젝트 개발일지 (0) | 2023.11.27 |
크롬에서 백그라운드에 재생되고있는 미디어 뒤로 감기, 앞으로 감기, 정지/재생하기 (0) | 2023.11.10 |