- 사용자 모델과 로그인 시스템이 필요합니다.
- 가입 기능은 없어도 괜찮습니다.
- 사용자에게는 매년 15일의 연차가 부여됩니다.
- 사용자는 연차/반차(0.5일)/반반차(0.25일)에 해당하는 휴가를 신청할 수 있습니다.
- 휴가 신청시 시작일, 종료일(반차/반반차의 경우는 필요없음), 사용 일수, 코멘트(선택 항목)를 입력합니다.
- 휴가 신청시 남은 연차를 표시합니다.
- 연차를 모두 사용한 경우 휴가를 신청할 수 없습니다.
- 추가 기능: 사용 일수를 입력하는 대신 시작일, 종료일을 가지고 공휴일을 제외하고 계산해도 됩니다.
- 아직 시작하지 않은 휴가는 취소할 수 있습니다.
- typescript
- nodejs
- mongodb
- erd 다이어그램 그려서 db구조 짜기
- 개발해야하는 기능 정리
- 개발 시작
-
users
- _id
- password
- vacationDays
- loginDate
- createdAt
-
applies
- _id
- applier
- days
- startDate
- endDate
- comment
- createdAt
- 로그인, 로그아웃
- 이메일, 비밀번호로 구현
- 세션처리
- 입사년도 기준으로 매년 15일 연차 부여하기
- 자동으로 1년이 지나면 x+=15
- 휴가 신청하기
- 신청항목 -> 연차 / 반차 / 반반차
- 신청 시 입력 내용 -> 시작일, 종료일, 사용일수(notnull), 코멘트
- 신청 시 남은 일수 차감
- 신청 시 남은 일수가 0이면 신청 불가
- 신청 시 공휴일은 제외 후 남은 일수 처리
- 휴가 취소하기
- 시작일자가 현재보다 이전일 경우에만 취소가능
- 구현
- 사용자 등록
- 로그인
- 로그아웃
- 세션 처리
- 문제점
- 비밀번호 암호화 과정에서의 에러 (임시로 암호화 없이 입력한 raw password로 구현)
- bcrypt-nodejs deprecated -> bcrypt로 이전해야함 (알 수 없는 에러...)
- 앞으로의 진행방향
- 일단 주요 기능은 휴가신청이니 이 문제점은 최종 구현단계에서 해결하자
- 현재는 로그인을 했으면 session에 user정보가 저장되므로 코드상에서 req.user을 사용가능하므로
- req.user을 토대로 로그인된 사용자의 휴가신청기능을 개발하자
- 구현
- 휴가 신청
- 신청 시 신청 일수와 시작날짜는 notNull, 댓글과 종료날짜는 allowNull
- 신청 일수는 연차 / 반차 / 반반차로 제한 (이외는 신청 불가)
- 신청 시 남은 휴가일수가 0이하이면 신청 불가
- 신청 시 신청일수가 남은 일수를 초과하면 신청 불가
- 신청 날짜가 현재보다 과거이면 신청 불가
- 연차일 경우 휴가 종료날짜 필수입력
- 반차 / 반반차일 경우 휴가 종료 날짜는 삭제
- 신청하기
- 신청 시 남은 휴가일수에서 차감
- 휴가 취소
- 로그인 된 사용자가 본인이 아닌 타인의 휴가신청 내역을 취소할 권한 제한
- 이미 시작된 휴가는 취소 불가
- 취소하기
- 휴가 신청
- 문제점
- 휴가 신청 시 신청일수와 시작날짜, 종료날짜 중 어떤 필드를 기준으로 하여 주말, 공휴일과 같은 요소들을 제어할지 고민해야한다.
- apply모델의 내장함수인 isValidatedDate메소드의 리턴값을 객체로 지정해서 알아보기 쉽게 isValid, message를 요소로 사용하고 싶은데 뜻대로 되지 않는다. 현재는 배열로 리턴해놓았지만 추후에 방법을 찾아 객체로 리턴하는 방법을 찾아야할 듯
- 앞으로의 진행방향
- 비밀번호 암호화 모듈 적용
- 입사일 기준 매년 15일의 연차 부여
- 휴가 신청 -> 주말, 공휴일 제외시키는 이슈
- 로그인된 사용자의 정보 조회
- 로그인된 사용자의 휴가 사용 목록 조회
- 구현
- 로그인된 사용자의 정보 조회
- 로그인된 사용자의 휴가 사용 목록 조회
- 휴가 신청 -> 신청일수와 신청날짜(시작, 종료) 비교 검증 (+ 주말 제외)
- 발생할 수 있는 아래의 시나리오 에러에 대한 대처 완료
- 반차 또는 반반차를 주말날짜에 신청했을 때
- 연차일 경우 주중의 신청일수와 신청날짜의 차이일수가 다를 때
- 연차일 경우 신청날짜의 차이일수에서 주말을 제외한 일수와 신청일수가 다를 때
- 발생할 수 있는 아래의 시나리오 에러에 대한 대처 완료
- 앞으로의 진행방향
- 비밀번호 암호화 모듈 적용
- 입사일 기준 매년 15일의 연차 부여
- 휴가 신청 -> 공휴일 제외시키는 이슈
- 구현
- 입사일 기준 n주년인 날에 첫 로그인 시 15일의 연차 부여 (users collection에 loginDate필드 추가)
- 문제점
- 입사 n주년인 당일에 로그인을 안하면 연차가 부여되지 않는다.
- 연차가 자동으로 부여되는 시점이 n주년째 입사일 00시가 되어야한다. (로그인과 같은 특정 api요청 시점이 아니라)
- 최종적으로 남은 개발과제
- mongodb event scheduler인 agenda.js를 도입해서 입사 n주년이라는 이벤트 시점과 15일 연차부여라는 이벤트 내용을 추가해야한다.
- 비밀번호 암호화 모듈 적용
- 휴가 신청 -> 공휴일 제외시키는 이슈
- 구현
- 비밀번호 암호화 모듈 적용
- npm i -g windows-build-tools (관리자권한)
- npm i [email protected]
- npm i -D @types/bcrypt
- 모듈 설치 이후 스키마의 pre - save 훅에서 회원가입 시 입력한 비밀번호를 암호화하고 로그인할 때 입력한 비밀번호를 암호화한 해시값을 비교
- 결과적으로 db엔 암호화된 비밀번호가 저장되고, 서버 통신간에도 암호화된 문자열값이 오고감.
- 비밀번호 암호화 모듈 적용
- 구현하지 못한 개발 과제
- mongodb event scheduler인 agenda.js를 도입해서 입사 n주년이라는 이벤트 시점과 15일 연차부여라는 이벤트 내용을 다루는 이벤트 핸들링
- 휴가 신청 시 공휴일을 제외한 계산 프로세스
$ git clone https://github.com/croquiscom-recruit/201912_onlinetest_GreatLaboratory.git
$ cd ./request-vacation
$ npm install
$ npm run build
$ npm start
-
휴가 신청
- 회원가입 -> POST /user/create
{ "email": "[email protected]", "password": "test" }
- 로그인 -> POST /user/login
{ "email": "[email protected]", "password": "test" }
- 사용자의 남은 휴가일수 조회하기 -> GET /user
- 사용자의 휴가 사용내역 조회하기 -> GET /apply/list
- 휴가 신청하기 -> POST /apply
{ "days": 5, "startDate": "2020-01-06", "endDate": "2020-01-10" }
- 로그아웃 -> GET /user/logout
-
휴가 취소
- 로그인 -> POST /user/login
{ "email": "[email protected]", "password": "test" }
- 사용자의 휴가 사용내역 조회하기 -> GET /apply/list
- 휴가 취소하기 -> DELETE /apply/:id
- 로그아웃 -> GET /user/logout
-
개발 전
- 평소에 익숙히 쓰던 java(spring)로 개발할까 싶었지만, 새롭게 관심을 가진 백엔드 기술스택이 typscript - nodejs - mongodb이어서 공부와 개발을 동시에 진행하게 되었다.
-
개발 후
- 새로운 기술을 사용한다는게 굉장히 어려우면서도 흥미로웠다. 특히 NoSQL의 방식이 기존 RDBMS와는 생각을 달리 해야할 점이 많아 익숙치않았다. 하지만 이내 적응했고 특히 필드추가의 자유로움, static method의 사용 등이 너무나 편리했고 typescript와 잘 어울리는 db라는 생각이 들었다.
- typescript로 개발을 처음 해보는데 굉장히 만족스럽다. 이젠 javascript만을 사용하여 타입체크 없이 쌩(?)으로 개발하면 너무 불안할 것 같다.
- 처음 써보는 모듈(bcrypt, moment, mongoose 등등)의 공식 레퍼런스를 읽고 사용방법과 parameters의 예제 등을 꼼꼼히 정리하고 테스트하는 과정이 재밌었다.
- 처음 계획은 mocha를 통한 테스트 코드까지 개발하는 것이었으나 시간부족으로 각 요청에서 테스트가 필요한 부분을 console.log(), postman, mongodb compass를 통해 그때 그때 확인했다. 제대로 된 테스트코드를 작성하지 못해서 아쉬웠다.