OEM 프로젝트 당시 제출한 발표 정리본 (아래 파일)
1-1. 팀명 : 비트바이트
팀장 : 김지혜
팀원 : 김주희, 이다영, 이서원, 김태진
1-2. 프로젝트명 : OEM(오늘 에러 무엇?)
1-3. 프로젝트의 목적 또는 기능
개발자들이 각자 발생한 오늘의 에러를 공유하여
나중에 같은 상황이 발생하였을 때 참고할 수 있는 레퍼런스들을 만드는 것이 목적 (에러 백과 사전)
1-4. 나의 프로젝트 진행
2023.06.26~2023.07.03
2023년 6월 26일 월요일 : S.A. 작성 / 작업 나누기 / 프로젝트용 깃 레포지토리 생성 / 프리티어rc, 리셋css파일 미리 생성
2023년 6월 27일 화요일 : 댓글 CRUD 백엔드 / 프론트 엔드
2023년 6월 28일 수요일 : 상세페이지, 로그인 페이지 프론트엔드
2023년 6월 29일 목요일 : 뉴스피드, 인덱스 프론트엔드/ 좋아요, 검색 기능 구현
2023년 6월 30일 금요일 : 로그인 페이지 이메일 인증 관련 프론트엔드
2023년 7월 2일 일요일 2시 : 회의 및 과제 제출
1-5. 프로젝트 운영 방식
1. 9:00 ~ 21:00 백엔드 구현에 집중한다. OK
2. 이 외에 시간이 되는 분은 프론트엔드 구현에 힘쓴다. OK
3. 10:00 ~ 11:00 회의 및 진행상황 점검 시간 유동적으로 진행함
4. api 호출은 thunderclient로 실행 OK
5. 브랜치는 기능별로 나누기 OK
1-6. 브랜치 나누기
- 백엔드 브랜치
main : 배포용
search : 검색
login : 로그인
likes : 좋아요
posts : 게시글
comments : 댓글
profile : 마이페이지
newsfeed : 뉴스피드
email : 이메일 인증
signup : 회원가입
- 프론트엔드 브랜치
css
frontend
1-7. 역할 분담
김지혜 : 뉴스피드, 로그인페이지 프론트엔드
이다영 : 댓글 CRUD 백엔드 / 상세페이지, 메인페이지, 로그인페이지, 뉴스피드 프론트엔드 / 텍스트 에디터 / 좋아요 / 검색
김태진 : 프로필페이지 백엔드, 프론트엔드
이서원 : 게시글 CRUD 백엔드 / 좋아요 / 검색, 발표
김주희 : 회원가입, 로그인, 이메일 인증 백엔드
1-8. 팀 규칙
1. 커밋 메시지 한글로 작성하기 ex. git commit -m "내용 한글로 작성" OK
2. 상황/문제/오류 보고를 수시로 하기 OK
3. 자바스크립트 함수, 변수명은 카멜케이스 ex. let camelCase, const newsFeed OK
4. 상수(변하지 않는 변수)는 const로 선언하기 OK
5. var 사용금지 OK
6. 의견이 달라도 상대방을 먼저 이해하기 (원활한 의사소통) OK
7. 각자 역할에 최선을 다하기 (어려우면 빠르게 물어보기) OK
2. 초기 자료들
2-1. 와이어프레임
2-2. ERD
2-3. API 명세서
2-4. S. A.
2-5. 튜터 님의 S.A. 피드백
"이전에 다영님이 채널에 올려주신것을 프로젝트로 진행하는것 이군요. 이렇게 필요한것을 직접 생각해서 만들어 보는것 너무 좋고 도움도 많이 될것 같습니다.
프론트가 하루만에 될수 있을지가 조금 걱정이 되긴 합니다. 프론트는 예쁘지 않아도 되지만 조금 촉박해 보이긴 해요. (이외의 시간이라고 작성되어 있지만..)
브랜치는 이후에 gitflow 같은것을 참고 해 보는것도 좋을거 같아요
와이어프레임 예쁘게 잘 만든것 같습니다. ""OEM (오늘 에러 무엇)""이란 아이디어가 매우 좋다고 생각했는데요. 이렇게 에러를 작성해두는것은 이후에 비슷한 에러를 만났을때
좀더 빠르게 찾아보고 적용해 보고 싶은 니즈가 있기때문에 만들어지는 것이라고 생각해요. 그래서 검색에 대해서 조금더 기능을 붙여보면 어떨까 합니다. 예를 들면
태그 기능을 넣어서 태그로 검색이 가능하게끔 한다던가요.erd
Posts/Comments 에 사용자의 nickname 이 들어가는데요 만약 사용자의 닉네임이 변경되어도 글작성자 닉네임은 이전것으로 두시려는 의도이실까요?
이런 프로젝트류는 게시글 삭제를 진짜로 db 에서 삭제하는것 보단 soft delete 라는 방식으로 삭제되었는지 정보는 DB 에 넣어서 해보시는것도 좋을거 같아요.api url 에서 restAPI 로 조금더 고민 해보시면 좋을듯 합니다
예를 들면
/api/userFeeds
/api/langFeeds
보단
/api/feeds?user_id={}
/api/feeds?lang={}이런식으로 두는것이 좋아보이고, 이렇게 해서 user_id 와 lang 을 동시에 검색할수 있도록 구현하면 좋을듯 합니다.
전반적으로 깔끔하게 SA 를 잘 구성하셨습니다."
3. 프로젝트 기능 구현
3-1. 필수 기능
- 사용자 인증 기능 : 회원 가입, 로그인 (비밀번호 암호화), 이메일 인증
- 프로필 : 이름, 한 줄 소개 (수정 가능)
- 게시글 CRUD 기능 : CRUD시 새로고침, 텍스트 에디터, 좋아요
- 뉴스피드페이지 : 전체 뉴스피드, 사용자별 뉴스피드, 언어별 뉴스피드, 검색
3-2. 추가 기능
- 댓글 CRUD : 새로고침
- 좋아요 기능 : 게시글에 좋아요
- 이메일 인증 : 인증번호 발송
4. 내가 구현한 주요 기능
댓글 CRUD
query로 postId를 받아서 조회, 생성
query로 commentId를 받아서 수정, 삭제
댓글 수정 시 get으로 받은 이미 작성된 content를 value에 미리 로드해 둠
좋아요
- 좋아요를 클릭하면 로컬스토리지에 liked : postId
liked : postId 가 있다면 /likes API 호출
postId를 사용함으로서 게시글 별 좋아요 누르기/ 취소 가능
단, 직전 좋아요만 가능
- 좋아요를 다시 클릭하면 로컬 스토리지에 liked:0
liked : 0이 있다면 /unlikes API 호출
- 좋아요를 클릭하였을 때 postId에 해당하는 userId가 로그인한 user Id와 같으면
좋아요가 되지 않고 alert("본인의 게시글은 좋아요 할 수 없습니다.")
검색
- 검색어와 content가 일치하면 post의 값을 반환한다.
5. 어려웠던 부분
- 태그로 검색 : 마이그레이션부터 막혀서 진행하지 못하였다.
- status를 프론트에서 받아오기 : 잘 되지 않아 JSON으로 받은 메시지 내용을 이용하였다.
- 프론트엔드 : 텍스트 에디터 추가
문제
텍스트 에디터 추가 시 추가하는 부분의 값이 null이 나오면서 실행되지 않음.
시도
본문의 버튼을 innerHTML로 붙일 때 id를 fetch를 통해 받아온 postId를 넣어주게 되어 있음.
fetch를 기다리느라 페이지 생성이 늦어져서 그런 것 같음.
setTimeout을 통해 텍스트 에디터를 페이지가 로드되고 1초 뒤에 실행되게 함.
해결
잘 됨.
function editorload() {
setTimeout(
() =>
ClassicEditor.create(document.querySelector('.editor'), {
licenseKey: '',
})
.then(editor => {
window.editor = editor;
})
.catch(error => {
console.error('Oops, something went wrong!');
console.error(
'Please, report the following error on https://github.com/ckeditor/ckeditor5/issues with the build id and the error stack trace:',
);
console.warn('Build id: m5b6f09wom88-nohdljl880ze');
console.error(error);
}),
1000,
);
}
editorload();
알게 된 점
실행 시점에서 fetch를 받거나 시간이 오래 걸리는 작업을 하는 것들은 늦게 실행된다.
눈에는 잘 안 보이지만 컴퓨터 기준 늦은 것이다.
그러므로 setTimeout등을 적절히 활용하여 순서를 정해 준다.
5. 깃허브 주소
https://github.com/gajigaji04/Newspeed_team_5-
6. 나의 소감
협업을 하는 능력이 조금씩 갖추어져 가는 것 같다.
git 사용법에 대해 조금 감을 잡을 수 있었고, 행복했다.
프론트엔드와 백엔드 연결을 미흡하게나마 할 수 있게 되었다.
이번 프로젝트는 처음 진행할 때는 완성할 수 있을까 걱정이 많이 되어서 프론트엔드를 만들다가 심장을 졸였지만
결국 완성하게 되어 행복하고 기뻤다.
팀원들을 잘 만나서 마음 고생하지 않고 행복하게 한 것 같다.
100번째 커밋!
7. 팀원들의 소감 및 KPT 회고
- 조장: 김지혜
부족한 점을 팀원분들과 보충해나가는 과정에서 많은 것을 배울 수 있어서 보람찼습니다! - 조원: 김주희
오류 발생시 팀원들이 도와주었기 때문에 빠른 시간 내에 해결할 수 있었다고 생각합니다! 라이브러리를 익히거나 코드 정리를 하는데도 많은 도움이 되었습니다. - 조원: 김태진
너무 잘하고, 좋은 팀원들과 함께해서 재밌고 편안한 프로젝트였습니다. - 조원: 이서원
더 노력해서 다른 팀원분들처럼 더 많이 파고들고 공부하여 추가적인 기능도 구현할 수 있는 개발자가 되고 싶습니다.
8-1. 튜터 님의 프로젝트 리뷰
https://github.com/gajigaji04/Newspeed_team_5-/issues/48
## 기능 과 이후 고도화 하면 좋을 것
- 이메일 인증은 회원가입 도중에 하는것보다, 회원가입 완료 후 이메일에 인증할수 있는 링크를 넣어서 클릭 하면 회원가입이 완료되도록 하면 좀더 자연 스러울것 같습니다.
- 비밀번호 입력은 `input = "password"` 를 사용하여 화면에 보여지는것을 방지 해야합니다.
- 글 작성시 언어는 사용자가 직접 인력보단 선택하도록 하는것이 좋습니다. java / 자바 두개는 다르게 검색될것이며, 오타등 여러 가지 사용성을 저해하는 요인이 됩니다.
- 닉네임 체크는 회원가입시 별도 버튼을 나두는게 좋습니다 (이메일 인증처럼)
- 이전에 언급한것처럼 이후에 태그형으로 검색 가능하도록 발전 시켜 보면 좋겠습니다.
- 내가 좋아요 한 게시물만 모아보는 기능이 있으면 좋더 좋을것 같습니다
- 이후에 cookie 는 백엔드에서 사용하지 않도록 하면 좋겠습니다.
- 여러가지 복합적 조건으로 게시글을 검색할수 있도록 하면 좋겠습니다.
## 코드
https://github.com/gajigaji04/Newspeed_team_5-/blob/c5f302fb9b496b0bad5e8f7adb22c39b855c244e/routes/users.route.js#L21C1-L25C7
이런 기능은 별도 함수로 구현하면 좋습니다.
https://github.com/gajigaji04/Newspeed_team_5-/blob/c5f302fb9b496b0bad5e8f7adb22c39b855c244e/routes/users.route.js#L29C1-L43C1
https://github.com/gajigaji04/Newspeed_team_5-/blob/c5f302fb9b496b0bad5e8f7adb22c39b855c244e/routes/users.route.js#L122C1-L126C6
- email 이 요청에 없다면 그 아래 로직은 전부 실행 될 필요가 없습니다.
- 유효성 검증의 위치를 조정 해보시길 권합니다. isExistEmail 가 true 이면 그 이후의 로직들은 실행될 필요가 없습니다. 등..
https://github.com/gajigaji04/Newspeed_team_5-/blob/c5f302fb9b496b0bad5e8f7adb22c39b855c244e/routes/users.route.js#L60C1-L69C8
https://github.com/gajigaji04/Newspeed_team_5-/blob/c5f302fb9b496b0bad5e8f7adb22c39b855c244e/routes/users.route.js#L82C1-L87C1
- 이렇게 인증번호를 jwt 로 만들어서 cookie 로 생성하면, 이메일 인증을 안해도 브라우저 쿠키값을 확인하면 인증번호를 알수 있습니다.
- 보안에 큰 문제가 생깁니다.
https://github.com/gajigaji04/Newspeed_team_5-/blob/c5f302fb9b496b0bad5e8f7adb22c39b855c244e/routes/users.route.js#L90C1-L95C2
- 404 는 요청에 해당하는 결과가 없음을 의미합니다. 이 부분은 사용자가 잘못된 코드를 넣은것입니다. 인증 오류 혹은 잘못된 접근 코드를 넣는게 적당해 보입니다.
https://github.com/gajigaji04/Newspeed_team_5-/blob/c5f302fb9b496b0bad5e8f7adb22c39b855c244e/routes/users.route.js#L129C1-L152C6
- else 문을 반복적으로 써야할 이유가 있을까요?
https://github.com/gajigaji04/Newspeed_team_5-/blob/c5f302fb9b496b0bad5e8f7adb22c39b855c244e/routes/users.route.js#L169
https://github.com/gajigaji04/Newspeed_team_5-/blob/c5f302fb9b496b0bad5e8f7adb22c39b855c244e/middlewares/auth-middleware.js#L5
- 백엔드 API 에서
https://github.com/gajigaji04/Newspeed_team_5-/blame/c5f302fb9b496b0bad5e8f7adb22c39b855c244e/middlewares/auth-middleware.js#L7
- 로그인 토큰을 백엔드에서
https://github.com/gajigaji04/Newspeed_team_5-/blob/c5f302fb9b496b0bad5e8f7adb22c39b855c244e/routes/profile.route.js#L12
- 미들웨어에서 이미 로그인 여부 확인하는데 처리로직에 중복으로 들어갈 필요는 없습니다.
https://github.com/gajigaji04/Newspeed_team_5-/blob/c5f302fb9b496b0bad5e8f7adb22c39b855c244e/middlewares/auth-middleware.js#L24
- 이렇게 유저를 한번더 DB 에서 조회하는 이유를 설명해 주세요. (JWT 의 장점이 무엇인지 공부해 보세요)
https://github.com/gajigaji04/Newspeed_team_5-/blob/c5f302fb9b496b0bad5e8f7adb22c39b855c244e/routes/profile.route.js#L18
https://github.com/gajigaji04/Newspeed_team_5-/blob/c5f302fb9b496b0bad5e8f7adb22c39b855c244e/routes/profile.route.js#L62C1-L68C1
- 미들웨어에서 이미 검색된 사용자를 locals 에 넣었는데 또 조회하는 이유가 있나요?
https://github.com/gajigaji04/Newspeed_team_5-/blob/c5f302fb9b496b0bad5e8f7adb22c39b855c244e/routes/profile.route.js#L43C1-L47C6
- 아직 작성한 게시글이 없다고 해서 에러는 아니지 않을까 합니다.
https://github.com/gajigaji04/Newspeed_team_5-/blob/c5f302fb9b496b0bad5e8f7adb22c39b855c244e/routes/posts.route.js#L10
- restAPI 에 따라 posts/:id 가 맞지 않을까요?
https://github.com/gajigaji04/Newspeed_team_5-/blob/c5f302fb9b496b0bad5e8f7adb22c39b855c244e/routes/posts.route.js#L12
- 조회한 게시글이 존재 하지 않을때 유효성 체크 해야합니다
https://github.com/gajigaji04/Newspeed_team_5-/blob/c5f302fb9b496b0bad5e8f7adb22c39b855c244e/routes/posts.route.js#L37
- else 가 불필요해 보입니다.
https://github.com/gajigaji04/Newspeed_team_5-/blob/c5f302fb9b496b0bad5e8f7adb22c39b855c244e/routes/posts.route.js#L72
https://github.com/gajigaji04/Newspeed_team_5-/blob/c5f302fb9b496b0bad5e8f7adb22c39b855c244e/routes/posts.route.js#L101
- 이미 위에서 사용자의 게시물임을 확인했는데 and.조건이 필요할 이유가 있을까요?
https://github.com/gajigaji04/Newspeed_team_5-/blob/c5f302fb9b496b0bad5e8f7adb22c39b855c244e/routes/newsfeeds.route.js#L19
https://github.com/gajigaji04/Newspeed_team_5-/blob/c5f302fb9b496b0bad5e8f7adb22c39b855c244e/routes/newsfeeds.route.js#L51
- 게시글이 없다고 에러로 보이진 않습니다.
https://github.com/gajigaji04/Newspeed_team_5-/blob/c5f302fb9b496b0bad5e8f7adb22c39b855c244e/routes/newsfeeds.route.js#L15
- DB 의 인덱스를 한번 공부해보시면 좋겠습니다. 인덱스로 잡혀있지 않는 컬럼으로 검색 정렬시 퍼모먼스가 떨어질수 있습니다. 이경우는 ID 로 조회해도 좋을듯 합니다.
https://github.com/gajigaji04/Newspeed_team_5-/blob/c5f302fb9b496b0bad5e8f7adb22c39b855c244e/routes/likes.route.js#L8
- 이런 경우에 userId 를 검색 조건에 넣어서 결과가 있는지 없는지 보는게 좋지 않을까 합니다. (내가 내글은 좋아요를 못하도록 막은 이유가 있나요?)
https://github.com/gajigaji04/Newspeed_team_5-/blob/c5f302fb9b496b0bad5e8f7adb22c39b855c244e/routes/likes.route.js#L6
https://github.com/gajigaji04/Newspeed_team_5-/blob/c5f302fb9b496b0bad5e8f7adb22c39b855c244e/routes/likes.route.js#L26
- 좋아요/좋아요취소 API. 를 제가 썬더클라이언트로 계속 호출하면 문제가 되지 않을까요?
- 좋아요가 마이너스 숫자로 될수도 있을듯 합니다.
https://github.com/gajigaji04/Newspeed_team_5-/blob/c5f302fb9b496b0bad5e8f7adb22c39b855c244e/routes/comments.route.js#L11
- 게시글이 존재 하지 않을때 검증을 먼저하는것이 가독성에 좋습니다.
## 코드 총정리
- 코드 실행 순서를 이해하시고 유효성 검증의 위치등을 고민해서 불필요한 로직이 실행되는것을 방지 해보면 좋겠습니다.
- else / else if 가 불필요한 부분이 많습니다.
- 사용자 검증에 대해 조금더 고민 해보시면 좋겠습니다.
- restAPI 의 restful 을 한번 공부해보시면 좋겠습니다.
- 반복되는 문제코드는 전부 작성하지 않았으니 리뷰와 비슷한 문제가 있는 코드를 전체로 한번 체크 해보시면 좋겠습니다.
- SA 때 드린 코멘트가 거의 반영이 안된 부분은 조금 아쉽습니다.
- 그럼에도 불구하고 아이디어와 노력해주신 부분은 매우 좋습니다. 고생하셨습니다.
8-2. 프로젝트 리뷰 검토 후 질문
📌 튜터 님께 질문할 내용
- 이메일 인증은 회원가입 도중에 하는것보다, 회원가입 완료 후 이메일에 인증할수 있는 링크를 넣어서 클릭 하면 회원가입이 완료되도록 하면 좀더 자연스러울것 같습니다.
: 이 과정에서 생기는 유령 아이디의 처리 방법이 궁금합니다! 개발자가 수동으로 주기적으로 삭제하여야 하나요? 아니면 유령 데이터를 일정 주기로 삭제하는 프로그램을 설계하는 게 좋을 것 같은데 아직 어렵게 느껴집니다...
- 이런 경우에 userId 를 검색 조건에 넣어서 결과가 있는지 없는지 보는게 좋지 않을까 합니다. (내가 내글은 좋아요를 못하도록 막은 이유가 있나요?)
: 발제에 자신의 글에는 좋아요를 하지 말라고 나와 있어 진행하였습니다!
- 데이터 생성시 중요시 해야 하는 부분 form tag vs json
: script를 send안에 넣지 말라고 하셔서 json을 이용하려 하는데 이전에 배운 symantic 이 기억납니다. 데이터 입력 시에는 form 태그를 활용하는 것이 좋다고 들었는데 저희는 백엔드 기준이니 json을 넣는 것이 역시 좋을까요? form태그로 정보를 받고도 response를 띄워 줄 수 있는 방법이 아직 어렵게 느껴집니다.
- 상기 내용은 튜터 님을 뵐 수 있는대로 다같이 시간을 비워서 직접 질문 드리기로 하였습니다. TEAM OEM.
8-3. 튜터 님 답변
- 회원 가입을 쉽게 해야 진입률이 높아짐
- 이메일 인증 천천히 해도 됨
- 링크를 클릭하면 회원가입이 완료되도록
- 실제로 유령 회원의 비율은 그렇게 높지 않다.
- 실무에서는 자신의 글에 좋아요 금지
- 안 해도 됨 코드만 복잡해짐
- Form fetch 같이 쓸 수 있다!
- Return false 하면 페이지 이동이 안 됨
정성스러운 프로젝트 리뷰 감사합니다!
덕분에 많이 배우고 발전할 수 있을 것 같습니다!
항상 감사드리고 고맙습니다 튜터 님~
TEAM OEM 올림.
'내일 배움 캠프 > OEM' 카테고리의 다른 글
OEM 프로젝트 Day5 (0) | 2023.06.30 |
---|---|
OEM 프로젝트 Day4 (0) | 2023.06.29 |
OEM 프로젝트 Day3 (0) | 2023.06.28 |
OEM 프로젝트 Day 1 (0) | 2023.06.26 |