Skip to content

GreatLaboratory/vacation-management-service

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

14 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

기능 명세

  • 사용자 모델과 로그인 시스템이 필요합니다.
    • 가입 기능은 없어도 괜찮습니다.
  • 사용자에게는 매년 15일의 연차가 부여됩니다.
  • 사용자는 연차/반차(0.5일)/반반차(0.25일)에 해당하는 휴가를 신청할 수 있습니다.
  • 휴가 신청시 시작일, 종료일(반차/반반차의 경우는 필요없음), 사용 일수, 코멘트(선택 항목)를 입력합니다.
    • 휴가 신청시 남은 연차를 표시합니다.
    • 연차를 모두 사용한 경우 휴가를 신청할 수 없습니다.
    • 추가 기능: 사용 일수를 입력하는 대신 시작일, 종료일을 가지고 공휴일을 제외하고 계산해도 됩니다.
  • 아직 시작하지 않은 휴가는 취소할 수 있습니다.

개발스택

  • typescript
  • nodejs
  • mongodb

진행순서

  1. erd 다이어그램 그려서 db구조 짜기
  2. 개발해야하는 기능 정리
  3. 개발 시작

db구조

  • users

    • _id
    • email
    • password
    • vacationDays
    • loginDate
    • createdAt
  • applies

    • _id
    • applier
    • days
    • startDate
    • endDate
    • comment
    • createdAt

개발해야하는 기능 정리

  1. 로그인, 로그아웃
    • 이메일, 비밀번호로 구현
    • 세션처리
  2. 입사년도 기준으로 매년 15일 연차 부여하기
    • 자동으로 1년이 지나면 x+=15
  3. 휴가 신청하기
    • 신청항목 -> 연차 / 반차 / 반반차
    • 신청 시 입력 내용 -> 시작일, 종료일, 사용일수(notnull), 코멘트
    • 신청 시 남은 일수 차감
    • 신청 시 남은 일수가 0이면 신청 불가
    • 신청 시 공휴일은 제외 후 남은 일수 처리
  4. 휴가 취소하기
    • 시작일자가 현재보다 이전일 경우에만 취소가능

3/22

  • 구현
    • 사용자 등록
    • 로그인
    • 로그아웃
    • 세션 처리
  • 문제점
    • 비밀번호 암호화 과정에서의 에러 (임시로 암호화 없이 입력한 raw password로 구현)
    • bcrypt-nodejs deprecated -> bcrypt로 이전해야함 (알 수 없는 에러...)
  • 앞으로의 진행방향
    • 일단 주요 기능은 휴가신청이니 이 문제점은 최종 구현단계에서 해결하자
    • 현재는 로그인을 했으면 session에 user정보가 저장되므로 코드상에서 req.user을 사용가능하므로
    • req.user을 토대로 로그인된 사용자의 휴가신청기능을 개발하자

3/23

  • 구현
    • 휴가 신청
      • 신청 시 신청 일수와 시작날짜는 notNull, 댓글과 종료날짜는 allowNull
      • 신청 일수는 연차 / 반차 / 반반차로 제한 (이외는 신청 불가)
      • 신청 시 남은 휴가일수가 0이하이면 신청 불가
      • 신청 시 신청일수가 남은 일수를 초과하면 신청 불가
      • 신청 날짜가 현재보다 과거이면 신청 불가
      • 연차일 경우 휴가 종료날짜 필수입력
      • 반차 / 반반차일 경우 휴가 종료 날짜는 삭제
      • 신청하기
      • 신청 시 남은 휴가일수에서 차감
    • 휴가 취소
      • 로그인 된 사용자가 본인이 아닌 타인의 휴가신청 내역을 취소할 권한 제한
      • 이미 시작된 휴가는 취소 불가
      • 취소하기
  • 문제점
    • 휴가 신청 시 신청일수와 시작날짜, 종료날짜 중 어떤 필드를 기준으로 하여 주말, 공휴일과 같은 요소들을 제어할지 고민해야한다.
    • apply모델의 내장함수인 isValidatedDate메소드의 리턴값을 객체로 지정해서 알아보기 쉽게 isValid, message를 요소로 사용하고 싶은데 뜻대로 되지 않는다. 현재는 배열로 리턴해놓았지만 추후에 방법을 찾아 객체로 리턴하는 방법을 찾아야할 듯
  • 앞으로의 진행방향
    • 비밀번호 암호화 모듈 적용
    • 입사일 기준 매년 15일의 연차 부여
    • 휴가 신청 -> 주말, 공휴일 제외시키는 이슈
    • 로그인된 사용자의 정보 조회
    • 로그인된 사용자의 휴가 사용 목록 조회

3/24

  • 구현
    • 로그인된 사용자의 정보 조회
    • 로그인된 사용자의 휴가 사용 목록 조회
    • 휴가 신청 -> 신청일수와 신청날짜(시작, 종료) 비교 검증 (+ 주말 제외)
      • 발생할 수 있는 아래의 시나리오 에러에 대한 대처 완료
        • 반차 또는 반반차를 주말날짜에 신청했을 때
        • 연차일 경우 주중의 신청일수와 신청날짜의 차이일수가 다를 때
        • 연차일 경우 신청날짜의 차이일수에서 주말을 제외한 일수와 신청일수가 다를 때
  • 앞으로의 진행방향
    • 비밀번호 암호화 모듈 적용
    • 입사일 기준 매년 15일의 연차 부여
    • 휴가 신청 -> 공휴일 제외시키는 이슈

3/25

  • 구현
    • 입사일 기준 n주년인 날에 첫 로그인 시 15일의 연차 부여 (users collection에 loginDate필드 추가)
  • 문제점
    • 입사 n주년인 당일에 로그인을 안하면 연차가 부여되지 않는다.
    • 연차가 자동으로 부여되는 시점이 n주년째 입사일 00시가 되어야한다. (로그인과 같은 특정 api요청 시점이 아니라)
  • 최종적으로 남은 개발과제
    • mongodb event scheduler인 agenda.js를 도입해서 입사 n주년이라는 이벤트 시점15일 연차부여라는 이벤트 내용을 추가해야한다.
    • 비밀번호 암호화 모듈 적용
    • 휴가 신청 -> 공휴일 제외시키는 이슈

3/26

  • 구현
    • 비밀번호 암호화 모듈 적용
      • 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

사용 시나리오

  • 휴가 신청

    1. 회원가입 -> POST /user/create
    {
        "email": "[email protected]",
        "password": "test"
    }
    1. 로그인 -> POST /user/login
    {
        "email": "[email protected]",
        "password": "test"
    }
    1. 사용자의 남은 휴가일수 조회하기 -> GET /user
    2. 사용자의 휴가 사용내역 조회하기 -> GET /apply/list
    3. 휴가 신청하기 -> POST /apply
    {
        "days": 5,
        "startDate": "2020-01-06",
        "endDate": "2020-01-10"
    }
    1. 로그아웃 -> GET /user/logout
  • 휴가 취소

    1. 로그인 -> POST /user/login
    {
        "email": "[email protected]",
        "password": "test"
    }
    1. 사용자의 휴가 사용내역 조회하기 -> GET /apply/list
    2. 휴가 취소하기 -> DELETE /apply/:id
    3. 로그아웃 -> 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를 통해 그때 그때 확인했다. 제대로 된 테스트코드를 작성하지 못해서 아쉬웠다.