정산 시스템 회고

손연주·2022년 6월 19일
2

개발자로서 또 나의 첫 회사에서 맡은 첫번째 프로젝트를 마무리하는 시점에서 회고록을 작성해보려고 한다. 진짜 길고 길었다.. 어렵기도 어려웠다.


목차

  1. Trigger 및 기존 배경 이해
  2. 기획 요구사항
  3. 개발 로직
  4. 어려웠던 점
  5. 해결 방법
  6. 개선해야될 점 및 느낀점

1. Trigger 및 기존 배경 이해

우선 어떤 일을 하는 회사인지 잠깐 알아보자면, 이전 포스트에도 서술한 적이 있지만, 클라이언트의 요구 사항에 따라 데이터를 수집하고 또는 제공받은 데이터를 가공하여 전달하는 서비스를 하고 있다. 인력을 투입해 2차적으로 가공된 데이터를 검수한다. 이때 해당 프로젝트(Subtask)를 생성하고 프로젝트 안에서 데이터work(작업물)를 올려 작업Job(work의 실제 작업들)을 할 수 있다. + 작업 리뷰가 반려될 수도 있어 하나의 work에 여러개의 Job이 존재할 수 있다.

우리는 이 작업건들에 대해서 작업자들에게 정산을 해주는데, 이전에는 하나의 프로젝트가 끝나야만 정산을 진행했고 프로젝트의 기간에 따라서 (2~3개월의 프로젝트면 그 기간동안 작업자들은 급여를 받을 수 없다.) 정산일이 그만큼 미뤄지곤 했다. 따라서 중간 정산과 정산 기능 확대를 위해 해당 정산 프로젝트를 진행한다.

2. 기획 요구사항

  1. 각 프로젝트 별로 정산값 excel로 export하여 다운로드 할 수 있게 처리
  2. 사람 별로 각 프로젝트에서 얼마씩 정산을 받았는지 전체 확인을 할 수 있는 기능 필요
  3. 중간 정산을 한번 진행하고 향후 초기화되어 정산을 다시 진행할 수 있게 하는 기능 필요
  4. 작업단가 중간에 변경했을 때에 이를 반영할 수 있는 기능 필요

3. 개발

Step 1 : 프로젝트 별로 정산 데이터 excel로 export

해당 프로젝트에 참여한 유저(worker)들의 정산값을 엑셀로 다운받을 수 있게 한다. 정산 확인에 필요한 유저 정보(Id, name, email, profit)subtaskId, 그리고 정산한 날을 나타내는 pay_day을 받아 일별로 나타낸다.

Exceljs를 이용해 excel파일 추출하기

Result

Step 2 : 사람 별로 각 프로젝트에서 얼마씩 정산을 받았는지 전체 확인

유저를 조회해 참여한 프로젝트 별로 정산받은 가격이 얼마인지 나타낸다. Profit 테이블에서 유저의 Id로 값들을 조회해 프로젝트 별로 Group화를 하여 각 프로젝트에서 정산받은 값들을 더하여 결과를 나타낸다.

Result

[
  {
    userId: 888,
    subtaskId: 125,
    name: 'user1',
    email: 'user1@google.com',
    workerProfit: 580,
    reviewerprofit: 1029
  },
  {
    userId: 888,
    subtaskId: 126,
    name: 'user1',
    email: 'user1@google.com',
    workerProfit: 2304,
    reviewerprofit: 249391
  }
]

Step 3 : 중간 정산을 한번 진행하고 향후 초기화되어 정산을 다시 진행할 수 있게 하는 기능 필요

이 프로젝트를 시작하게된 주요 목적인 중간 정산 파트이다.

이전에는 하나의 프로젝트가 끝나야만 정산을 진행했고, 프로젝트의 기간에 따라서 (2~3개월의 프로젝트면 그 기간동안 작업자들은 급여를 받을 수 없다.) 정산일이 그만큼 미뤄지곤 했다. 따라서 중간 정산을 위하여 Step3을 진행한다.

현재 회사에서는 Job(하나의 작업)의 상태에 따라 Stage를 두고 있다. 유저가 Job을 할당 받았을 때, 작업을 시작했을 때, 작업을 완료했을 때, 완료한 작업을 reviewer에게 review 받았을 때(이때 여기서 confirm과 reject로 나뉘어진다.), 최종적으로 작업이 끝나 Job이 완료됐을 때를 나타내는 Stage가 있다.

아직까지는 정산을 진행한다고 해서 Stage를 전환하지 않고 있다. 따라서 정산 완료를 나타낼 수 있는 Stage를 하나 추가하여 정산 진행을 완료했을 때 완료 Stage로 변경하는 로직을 추가하여 정산 완료와 미완료를 구분해준다.

정산을 한 번 진행했다면, 정산 완료 Stage로 update해주고 다음 정산 때에 정산 완료 Stage를 제외한 Stage에서만 진행한다.

Step 4 : 작업단가 중간에 변경했을 때에 이를 반영할 수 있는 기능 필요

1. 요구 사항 : Job table에 작업 단가 Column을 만들어서 단가 정보를 저장한다. 정산시 Job의 작업 단가 정보를 통해 입력하도록 처리한다. 이렇게 되면 나중에 Job을 통해 변경된 단가를 추적할 수 있어진다.

2. 이전 로직 : Subtask(프로젝트) 테이블 안에 작업 단가가 저장되어 있어 그 값을 불러와 정산했다. 정산을 할 때 SubtaskId로 하기 때문에 그 안에 Job이 몇 개든 정산이 됐든 안 됐든 Job의 맨 처음부터 불러와 재정산을 한 값을 return 한다.

하나의 프로젝트에 100개의 Job이 있고 50개의 Job이 정산이 완료된 후 작업 단가가 바뀌었다고 가정해보자. 그리고 작업자들이 10개의 작업을 더 완료하여 총 60개의 Job이 마무리된 상태다. 여기서 문제는, 중간 정산 기능이 없었기 때문에 변경된 작업 단가로 (이미 정산 완료된 50개의 Job을 무시한 채) 작업이 완료된 총 60개의 Job에 대해서 정산을 진행한다. 즉 이전에 50개의 Job을 작업한 작업자들에 대해서 잘못된 정산값을 지불하는 것이다.

3. 현재 로직 : 작업 단가 변경 추적을 위해서, 정산 시점에 Subtask의 단가를 가져와 Job의 테이블에 단가를 저장하고 그 단가로 계산을 한다. 이때 물론 Step3을 통해서 이미 정산이 완료된 50건의 이전 Job은 예외처리를 하고 정산을하게 된다.

요구사항대로 로직을 처리했지만 마무리하고 보니 완벽한 처리(?)는 아니었다고 생각한다. 우선 Stage를 통해서 정산이 완료된 것들을 제외하여 작업 완료가 된 건만 정산을 진행한다면 Subtask의 단가가 변경되어 있어도 이전 로직과 같은 잘못된 계산을 하지 않게 된다. 그렇게 되면 작업 단가 변경 추적을 위해 수많은 Job들의 각 컬럼에 단가를 굳이 또 저장하는 건 불필요하다고 생각된다. 애초에 작업 단가 Table을 만들었다면 단가 입력, 변경 그리고 값(가격) 변경시 추적이 용이하여 어느 시점엔 얼마로 계산을 해줬는지 파악이 편했을 것 같다는 생각이 든다. 또는 Profit 테이블에 단가 컬럼을 만들어 계산 시점의 단가를 가져와 저장을 하는 방법이 있을 수 있겠다. 그래서 단가별로 Group화를 하여 보여준다든가. 하지만 이를 위해 테이블까지 만드는 게 과연 효율적인가 생각해 보면 잘 모르겠다. 디비 과부화 문제도 있을 것 같다(근데 또 이런 작은 테이블로 인해 과부화가 생길지는 모르겠다). 공부가 더 필요한 부분이다.

그리고 현재 RDBMS를 사용하고 있는데 json 타입의 coulmn이 있다. 초기에 이렇게 개발한 데에는 분명히 이유가 있겠지만 아직 잘 모르겠다. 이렇게 사용한다고도 하더라. 개발의 효율성을 위함일까. . . Json in database 읽어보면 좋을듯

4. 어려웠던 점

5. 개선점 및 느낀점

// 계속 작성중...

profile
할 수 있다는 생각이 정말 나를 할 수 있게 만들어준다.

3개의 댓글

comment-user-thumbnail
2022년 7월 31일

언젠간 이 노력도 정산받겠죠??

1개의 답글