Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/dawwson/budget-keeper-be
[ Budget Keeper ] 예산 관리 및 추천 서비스 RESTful API 서버 💸
https://github.com/dawwson/budget-keeper-be
aws-ec2 aws-rds docker jest jwt nestjs nodejs postgresql typeorm typescript
Last synced: about 2 months ago
JSON representation
[ Budget Keeper ] 예산 관리 및 추천 서비스 RESTful API 서버 💸
- Host: GitHub
- URL: https://github.com/dawwson/budget-keeper-be
- Owner: dawwson
- Created: 2023-11-09T04:20:32.000Z (about 1 year ago)
- Default Branch: main
- Last Pushed: 2024-09-08T13:16:59.000Z (4 months ago)
- Last Synced: 2024-09-08T14:40:41.189Z (4 months ago)
- Topics: aws-ec2, aws-rds, docker, jest, jwt, nestjs, nodejs, postgresql, typeorm, typescript
- Language: TypeScript
- Homepage:
- Size: 340 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
Budget Keeper
Introduction
Budget Keeper
는 사용자들이 개인 재무를 관리하고 지출을 추적하는 데 도움을 주는 서비스입니다.
월별로 예산을 설정하고 카테고리별로 지출 내역을 관리함으로써 사용자들의 재무 목표를 달성할 수 있습니다.
Skills
## Table of Contents
- [Installation](#installation)
- [Directory](#directory)
- [ERD](#erd)
- [REST API](#rest-api)
- [Convention](#convention)
- [Architecture](#architecture)
- [Deployment Structure](#deployment-structure)
- [TIL & Retrospective](#til--retrospective)
- [Test Result](#test-result)
## Installation
```bash!
> npm install # 패키지 설치
> npm run start:db # 도커로 데이터베이스 실행
> npm run start:dev # 개발버전 앱 실행
> npm run seed:dev # 카테고리 데이터 생성
```
## Directory
폴더 구조 보기
src
├── api # API 요청이 들어오는 Controller가 포함된 모듈
│ ├── auth # 인증 모듈(/auth)
│ │ ├── dto
│ │ ├── service
│ │ └── strategy
│ ├── budget # 예산 모듈(/budgets)
│ │ ├── dto
│ │ └── service
│ ├── category # 카테고리 모듈(/categories)
│ │ ├── dto
│ │ └── service
│ └── expense # 지출 모듈(/expenses)
│ ├── dto
│ ├── enum
│ ├── guard
│ └── service
├── config # 환경 변수 설정 관련
├── database
│ └── seeding # DB seeding 관련
├── entity
└── shared # 여러 모듈에 걸쳐서 쓰이는 파일
├── enum
├── guard
└── interface
test
├── e2e # e2e 테스트 파일
├── in-memory-testing # 인 메모리 DB 테스트 관련 파일
└── jest-e2e.json
## ERD
![budget-keeper erd](https://github.com/dawwson/budget-keeper-be/assets/45624238/755f0bc3-fdac-469c-b748-15518095318c)테이블 설계 의도 보기
사용자, 예산, 카테고리의 관계
- 사용자는 여러 예산을 설정할 수 있습니다.
- 한 번 예산을 설정할 때 카테고리별 예산을 지정할 수 있으므로 예산과 카테고리는 다대다 관계입니다.
- 다대다 관계는 확장성과 유지보수 문제로 일반적으로 잘 사용하지 않으므로 중간 테이블
budget_category
을 두어 일대다, 다대일로 풀어냈습니다. - 사용자 : 예산 =
1:N
- 예산 : 예산-카테고리 =
1:N
- 예산-카테고리 : 카테고리 =
N:1
사용자, 지출, 카테고리의 관계
- 사용자는 여러 지출을 등록할 수 있으므로 일대다 관계입니다.
- 한 번 지출을 등록할 때 한 개의 카테고리를 지정할 수 있으므로 다대일 관계입니다.
- 사용자 : 지출 =
1:N
- 지출 : 카테고리 =
N:1
## REST API
[자세한 내용은 GitHub Wiki로 이동! 🏃🏻♀️💨](https://github.com/dawwson/budget-keeper-be/wiki/1%EF%B8%8F%E2%83%A3-REST-API-%EB%AC%B8%EC%84%9C)
| Method | URL | Description | Authorization | Completed |
| :---: | --- | --- | :---: | :---: |
| `POST` | `/auth/sign-up` | 회원가입 | X | ✅ |
| `POST` | `/auth/sign-in` | 로그인 | X | ✅ |
| `GET` | `/categories` | 카테고리 목록 조회 | O | ✅ |
| `PUT` | `/budgets/{year}/{month}` | 월별 예산 설정 | O | ✅ |
| `GET` | `/budgets/{year}/{month}/recommendation` | 월별 예산 추천 | O | ✅ |
| `POST` | `/expenses` | 지출 생성 | O | ✅ |
| `PATCH` | `/expenses/{id}` | 지출 수정 | O | ✅ |
| `GET` | `/expenses/{id}` | 지출 상세 조회 | O | ✅ |
| `GET` | `/expenses` | 지출 목록 조회 | O | ✅ |
| `DELETE` | `/expenses/{id}` | 지출 삭제 | O | ✅ |
| `GET` | `/expenses/statistics` | 지출 통계 | O | ✅ |
## Convention
[자세한 내용은 GitHub Wiki로 이동! 🏃🏻♀️💨](https://github.com/dawwson/budget-keeper-be/wiki/2%EF%B8%8F%E2%83%A3-%EC%BB%A8%EB%B2%A4%EC%85%98)
## Architecture
아키텍쳐 설계 의도 보기
1. Custom Repository를 사용하지 않습니다.
-
TypeORM
0.3 버전부터@EntityRepository()
데코레이터가deprecated
됨에 따라 여러 기술 블로그에서Custom Repository
만드는 방법을 소개하고 있습니다. 하지만 따라서 적용하지 않은 이유는 다음과 같습니다. - 이미
ORM
에서 제공하는 메서드를 한 번 더 추상화하게 되어, 요구사항이 늘어날수록 유지보수가 어려워진다고 느꼈습니다. - 향후
ORM
의 교체를 고려하여 서비스 레이어에서의ORM
에 대한 의존성을 줄이기 위해 분리한다 하더라도, 현실적으로 한 번 정해진ORM
시스템을 교체하기는 어렵다고 생각했습니다.ORM
마다 모델링 방법부터도 매우 다르기 때문입니다. -
Custom Repository
의 단위 테스트가 어려워집니다.Repository
를 분리하게 되면 테스트의 목적은TypeORM
의 메소드가 잘 동작하는지 확인하는 것에 그치게 됩니다. - 대신
NestJS
에서 제공하는@InjectRepository()
를 사용하여Repository Pattern
을 사용합니다. - 참고 자료
2. Service 계층 규칙
-
Service
계층에서는 여러Repository
를 주입받을 수 있습니다. -
Repository
는Service
에만 주입될 수 있습니다. -
Service
가 아닌 다른Provider
에서 데이터베이스 접근이 필요할 경우,Repository
를 주입받아서 외부로 노출하는Provider
를 생성합니다.(함께 팀 프로젝트를 했던 @kangssu님의 아이디어를 좀 더 구체화시켰습니다 👍)
- 해당
Provider
의 클래스명은{자원명}Lib
로 지정합니다. - 핵심 비즈니스 로직이 담긴
Service
와 코드를 분리하고, 상위 레벨로 만들어서 데이터베이스 커넥션을 추상화하기 위함입니다.
- 해당
3. DTO는 어디서 변환하는가?
-
clas-transformer
에서 제공하는 객체 매핑 데코레이터 및 함수를 활용합니다. -
Controller
➡️Service
- 요청
DTO
클래스의 함수에서 변환합니다 - 함수명은
to{서비스_DTO_이름}()
으로 지정합니다. -
Entity
➡️Response
- 응답
DTO
클래스의static
함수에서 변환합니다 - 함수명은
of()
로 지정합니다. - 참고 자료
## Deployment Structure
- 로컬 개발 환경에서 프로덕션 환경변수를 설정하여 `Docker`기반으로 빌드합니다.
- `Docker Hub`에 빌드한 이미지를 업로드합니다.
- `EC2`에서 이미지를 내려받아서 실행합니다.
- `EC2`와 `RDS`는 동일한 `VPC` 내에서 다른 보안 그룹으로 설정하여 통신합니다.
## TIL & Retrospective
[자세한 내용은 GitHub Wiki로 이동! 🏃🏻♀️💨](https://github.com/dawwson/budget-keeper-be/wiki/3%EF%B8%8F%E2%83%A3-%08TIL-&-Retrospective)
- [[NestJS] in-memory 데이터베이스로 테스트 코드 작성하기(with pg-mem)](https://github.com/dawwson/budget-keeper-be/wiki/3%EF%B8%8F%E2%83%A3-%08TIL-&-Retrospective#-in-memory-%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4%EB%A1%9C-%ED%85%8C%EC%8A%A4%ED%8A%B8-%EC%BD%94%EB%93%9C-%EC%9E%91%EC%84%B1%ED%95%98%EA%B8%B0with-pg-mem)
- [[Docker] 빌드 스테이지와 실행 스테이지 나누기](https://github.com/dawwson/budget-keeper-be/wiki/3%EF%B8%8F%E2%83%A3-%08TIL-&-Retrospective#-%EB%B9%8C%EB%93%9C-%EC%8A%A4%ED%85%8C%EC%9D%B4%EC%A7%80%EC%99%80-%EC%8B%A4%ED%96%89-%EC%8A%A4%ED%85%8C%EC%9D%B4%EC%A7%80-%EB%82%98%EB%88%84%EA%B8%B0)
- [[AWS] EC2 & RDS 환경 설정 방법](https://github.com/dawwson/budget-keeper-be/wiki/3%EF%B8%8F%E2%83%A3-%08TIL-&-Retrospective#1-6-aws)
## Test Result
- E2E 테스트 결과