Skip to content

chrisYang256/8percent-assignment

 
 

Repository files navigation

header



원티드x위코드 백엔드 프리온보딩 과제 4.


[Assignment] 과제 제출 기업정보





Members


이름 Github 담당 기능
👨🏻‍🎤 김주현 kjhabc2002 DB data control, DB load test, AWS / Docker 배포
👰🏻‍♂️ 이다빈 thisisempty DB data control, DB load test, AWS / Docker 배포
👶🏻 구본욱 qhsdnr0 DB data control, DB load test, AWS / Docker 배포
🥷 김지훈 kimfa123 입금/출금 view, unit test, README 작성
🦹🏻‍♂️ 문승준 palza4dev 거래내역 view, unit test, postman api, README 작성
👨🏻‍🦳 양가현 chrisyang256 회원가입/로그인 view, unit test, README 작성

ㅤ👪 공동작업: DB Modeling




사용 기술


PythonDjangoSQLiteAWSDockerPostmanGitHub




과제 내용


ㅤ아래 요구사항에 맞춰 상품관리 Restfull API를 개발합니다.


▶︎ 필수 포함사항

  • READ.ME 작성
    • 프로젝트 빌드, 자세한 실행 방법 명시
    • 구현 방법과 이유에 대한 간략한 설명
    • 완료된 시스템이 배포된 서버의 주소
    • Swagger나 Postman을 통한 API 테스트할때 필요한 상세 방법
    • 해당 과제를 진행하면서 회고 내용 블로그 포스팅
  • Swagger나 Postman을 이용하여 API 테스트 가능하도록 구현

▶︎ 개발 요구사항

✔️ API 목록

  • 거래내역 조회 API
  • 입금 API
  • 출금 API

✔️ 주요 고려 사항은 다음과 같습니다.

  • 계좌의 잔액을 별도로 관리해야 하며, 계좌의 잔액과 거래내역의 잔액의 무결성의 보장
  • DB를 설계 할때 각 칼럼의 타입과 제약

✔️ 구현하지 않아도 되는 부분은 다음과 같습니다.

  • 문제와 관련되지 않은 부가적인 정보. 예를 들어 사용자 테이블의 이메일, 주소, 성별 등
  • 프론트앤드 관련 부분

✔️ 제약사항은 다음과 같습니다.

  • (8퍼센트가 직접 로컬에서 실행하여 테스트를 원하는 경우를 위해) 테스트의 편의성을 위해 mysql, postgresql 대신 sqllite를 사용해 주세요.

✔️ 거래내역 조회 API

  • 아래와 같은 조회 화면에서 사용되는 API를 고려하시면 됩니다.

    image 0


✔️ 거래내역 API는 다음을 만족해야 합니다.

  • 계좌의 소유주만 요청 할 수 있어야 합니다.
  • 거래일시에 대한 필터링이 가능해야 합니다.
  • 출금, 입금만 선택해서 필터링을 할 수 있어야 합니다.
  • Pagination이 필요 합니다.
  • 다음 사항이 응답에 포함되어야 합니다.
    • 거래일시
    • 거래금액
    • 잔액
    • 거래종류 (출금/입금)
    • 적요

✔️ 입금 API

  • 계좌의 소유주만 요청 할 수 있어야 합니다.

✔️ 출금 API

  • 계좌의 소유주만 요청 할 수 있어야 합니다.
  • 계좌의 잔액내에서만 출금 할 수 있어야 합니다. 잔액을 넘어선 출금 요청에 대해서는 적절한 에러처리가 되어야 합니다.

✔️ 구현 시 가산점 부여 사항

  • Unit test의 구현
  • Functional Test 의 구현 (입금, 조회, 출금에 대한 시나리오 테스트)
  • 거래내역이 1억건을 넘어갈 때에 대한 고려
    • 이를 고려하여 어떤 설계를 추가하셨는지를 README에 남겨 주세요.



모델링


스크린샷 2021-11-12 오후 6 41 39




구현 기능


▶︎ 회원가입/로그인

  • 신규 회원가입과 동시에 계좌가 개설되도록 설계하였습니다.
  • 이에 따라 회원가입 시 users, account table에 각각 동시에 row가 입력되며 account table이 생성되지 않을 경우를 고려하여 transaction 처리를 하였습니다.
  • 회원가입 시 유일한 수로 이루어진 고유 계좌번호 부여
    • account_number 함수에서 생성된 계좌번호는 생성 후 즉시 리턴되지 않습니다.
    • Account table을 조회하여 동일한 값의 계좌번호가 존재하지 않을 때 까지 재귀함수를 통해 생성/조회를 반복한 후 값을 최종 리턴하므로 계좌번호의 중복을 차단하도록 구현하였습니다.
def account_number():
    def numbers():
        number = random.randint(1000, 9999)
        return number

    account_number = f'{numbers()}-{numbers()}-{numbers()}-{numbers()}'
    
    if not Account.objects.filter(number=account_number).exists():
        return account_number

    return account_number()

# 리턴값 예시: '9197-6853-7204-1115'

▶︎ 설치 및 실행 방법

- Local 개발 및 테스트 용

  1. 해당 프로젝트를 clone하고, 프로젝트 폴더로 이동한다.
git clone https://github.com/kooted-pre-onboarding/8percent-assignment.git
cd 8percent-assignment
  1. 가상 환경을 생성하고 프로젝트에 사용한 python package를 설치한다
conda create -n "8percent" python=3.8
conda activate 8percent
  1. docker 환경 설정 파일을 생성하고 다음을 작성한다.
touch .env
vi .env
EIGHTPERCENT_SECRET_KEY=SECRET_KEY
EIGHTPERCENT_ALGORITHM=HS256
  1. 다음 명령어로 서버를 실행시킨다
docker-compose -f docker-compose.yml up 

4-1. 백그라운드로 실행하고싶을 시 -d옵션을 추가한다.

docker-compose -f docker-compose.yml up -d

- 배포용

  1. 해당 프로젝트를 clone하고, 프로젝트 폴더로 이동한다.
git clone https://github.com/kooted-pre-onboarding/8percent-assignment.git
cd 8percent-assignment
  1. 가상 환경을 생성하고 프로젝트에 사용한 python package를 설치한다
conda create -n "8percent" python=3.8
conda activate 8percent
  1. docker 환경 설정 파일을 생성하고 다음을 작성한다.
touch .env
vi .env
EIGHTPERCENT_SECRET_KEY=SECRET_KEY
EIGHTPERCENT_ALGORITHM=HS256
  1. 다음 명령어로 서버를 실행시킨다
sudo docker-compse -f docker-compose-deploy.yml up

4-1. 백그라운드로 실행하고싶을 시 -d옵션을 추가한다.

sudo docker-compse -f docker-compose-deploy.yml up -d



▶︎ 거래 내역이 1억건을 넘어갈 때에 대한 고려

  • 저희는 대량 데이터 처리 시 데이터 조회를 문제요소로 판단하여 문제 해결을 위한 방법으로 Database indexing을 활용하고자 하였습니다.
class Transaction(models.Model):
    amount                    = models.PositiveIntegerField()
    balance_after_transaction = models.PositiveIntegerField()
    sum_up                    = models.CharField(max_length=100)
    account                   = models.ForeignKey(Account, on_delete=models.CASCADE)
    transaction_type          = models.ForeignKey(TransactionType, on_delete=models.CASCADE)
    created_at                = models.DateTimeField(auto_now_add=True)

    class Meta:
        db_table = 'transactions'
        indexes = [
            models.Index(fields=['account_id'])
        ]
  • 하지만 테스트 결과 pagination만으로도 조회 성능에는 문제가 되지 않는 상황이라고 판단하였습니다.
  • 시행착오 끝에 저희가 내린 결론은 한 테이블에 너무 많은 데이터가 누적되는 것이 문제라고 판단하였습니다.
  • 결론적으로 구현한 사항은 아니지만 "database table partitioning을 활용한 방안이 더 적합하지 않았을까?" 라는 결론을 내렸습니다.

테스트 결과는 Postman loadtest 문서 링크에서 확인 가능합니다.

API Document & Test


  1. Postman API 문서 링크로 접속해 우측 상단의 Run in Postman 버튼을 클릭합니다.

  2. 개인 Workspace로 Import 합니다.

  3. hostname 환경변수를 deploy로 선택합니다.

  4. 배포 주소 13.125.45.93:8000 를 확인합니다.

  5. API 문서 예시를 참고해 Request를 보냅니다.




폴더 구조


├── __pycache__
├── accounts
│   ├── __init__.py
│   ├── __pycache__
│   ├── admin.py
│   ├── apps.py
│   ├── migrations
│   │   ├── 0001_initial.py
│   │   ├── __init__.py
│   │   └── __pycache__
│   ├── models.py
│   ├── tests.py
│   ├── urls.py
│   ├── utils.py
│   └── views.py
├── core
│   ├── __init__.py
│   ├── __pycache__
│   ├── admin.py
│   ├── apps.py
│   ├── migrations
│   │   ├── __init__.py
│   │   └── __pycache__
│   ├── models.py
│   ├── tests.py
│   └── views.py
├── db.sqlite3
├── dbuploader.py
├── deploy.Dockerfile
├── docker-compose-deploy.yml
├── docker-compose.yml
├── eightpercent
│   ├── __init__.py
│   ├── __pycache__
│   ├── asgi.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── local.Dockerfile
├── manage.py
├── pull_request_template.md
├── requirements.txt
└── transactions
    ├── __init__.py
    ├── __pycache__
    ├── admin.py
    ├── apps.py
    ├── migrations
    │   ├── 0001_initial.py
    │   ├── __init__.py
    │   └── __pycache__
    ├── models.py
    ├── tests.py
    ├── urls.py
    └── views.py



Reference

이 프로젝트는 원티드x위코드 백엔드 프리온보딩 과제 일환으로 8percent에서 출제한 과제를 기반으로 만들었습니다.

About

Wecode x Wanted Pre-onboarding Assignment #4

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Python 98.8%
  • Dockerfile 1.2%