-
간식 대장
Snack은 쿠팡, 네이버 쇼핑 등 다양한 온라인 플랫폼에서 이루어진 간식 구매 내역을 통합 관리할 수 있는 원스톱 솔루션입니다.
구매처와 상관없이, 간식 품목, 수량, 금액 등의 정보를 일괄적으로 등록 및 관리할 수 있어,
산발적으로 흩어진 데이터를 체계적으로 정리할 수 있습니다.
또한, 비용 분석 리포트, 기간별 통계, 품목별 정렬 등의 기능을 통해 기업은 간식 운영에 대한 인사이트를 확보하고,
불필요한 지출을 줄이며 합리적인 소비 패턴을 도출할 수 있습니다.
복잡한 총무 업무를 줄이고, 기업 복지 운영의 효율성을 극대화하는 도구, 바로 Snack입니다.
| AI 챗봇 도우미 | 결제 모듈 | 모바일 구매 내역 확인 | 상품 상세와 담기 |
|---|---|---|---|
![]() |
![]() |
![]() |
![]() |
| 스낵 예산 관리 | 찜하기 해제 기능 | 카테고리 정렬 둘러보기 | 회원 관리 모바일 |
![]() |
![]() |
![]() |
![]() |
| 팀장 | 부팀장 | 팀원 | 팀원 | 팀원 | 팀원 |
|---|---|---|---|---|---|
|
이태빈 |
이지수 |
김우주 |
김홍섭 |
장원빈 |
조성빈 |
src/
├── controllers/ # 요청 처리 및 응답 반환
├── services/ # 비즈니스 로직 처리
├── repositories/ # 데이터 접근 계층 (Prisma)
├── routes/ # API 라우팅 정의
├── middlewares/ # 미들웨어 (인증, 에러 처리 등)
├── dtos/ # 데이터 전송 객체
├── types/ # TypeScript 타입 정의
├── config/ # 설정 파일 (Swagger 등)
├── utils/ # 유틸리티 함수 (S3, 날짜 처리 등)
├── cron/ # 정기 작업 스케줄러 (월별 예산 자동 생성)
├── lib/ # 외부 라이브러리 설정 (Prisma 등)
├── test/ # 단위 테스트
└── integration-test/ # 통합 테스트
1. 인증 및 사용자 관리
- 회원가입, 로그인, 로그아웃, 토큰 갱신
- JWT 기반 인증, 쿠키 사용, 비밀번호 암호화, 권한(ADMIN, USER, SUPER_ADMIN) 관리
- 유저 정보 조회/수정/삭제
- 프로필 조회, 비밀번호 변경, 소프트 삭제(탈퇴), 권한 변경, 회사별 유저 목록 조회
2. 회사(Company) 관리
- 회사 정보 관리
- 회사 정보(이름 등) 수정, 회사별 유저 관리, 최고관리자 권한에서만 접근 가능
3. 예산(Budget) 관리
- 월별 예산 및 지출 현황 조회/수정
- 회사별 월 예산, 이번달/저번달/올해/작년 지출액 등 통계 제공
- 최고관리자/관리자 권한에 따라 예산 수정 가능
- 매월 자동 예산 생성(크론 작업)
4. 상품(Product) 관리
- 상품 등록/수정/삭제/조회
- 상품 카테고리(대분류/소분류) 관리, 이미지 업로드, 인기순/최신순/가격순 정렬
- 상품 상세 조회, 내 상품 목록, 전체 상품 목록, 소프트 삭제 및 강제 삭제(관리자)
- 찜하기(즐겨찾기)
- 상품 찜/찜 해제, 내 찜 목록 조회
5. 장바구니(Cart) 기능
- 장바구니 담기/삭제/조회
- 여러 상품을 장바구니에 담고, 주문 전까지 관리
6. 주문(Order) 및 결제(Payment)
- 주문 요청/승인/반려/조회
- 장바구니 상품 주문, 관리자/최고관리자 승인/반려, 주문 내역 및 상세 조회
- 결제 처리 및 취소
- 외부 결제 API 연동(예: Toss Payments), 결제 승인/취소, 결제 내역 관리
7. 초대(Invite) 및 권한 관리
- 유저 초대 및 권한 부여
- 이메일 초대, 만료/사용 여부 관리, 초대 수락 시 권한 자동 부여
8. 기타
- Swagger API 문서 제공
/api-docs에서 전체 API 문서 확인 가능- Redis 캐시 및 무효화
- 상품/예산 등 주요 데이터 캐싱, 변경 시 캐시 무효화
- 테스트 및 시드 데이터
- Jest 기반 테스트, Prisma 시드 스크립트로 더미 데이터 생성
1. 문제점 (Problem)
초기 시스템은 cartItem (장바구니)과 orderedItem (주문 상품) 테이블로 구성되어 있었습니다. 이 구조는 orderedItem이 상품 정보(예: 상품 가격, 이름)를 직접 저장하지 않고, cartItem 또는 상품 테이블에 의존하는 방식이었습니다.
문제는 결제 후 상품 정보가 변경될 경우였습니다.
예를 들어, 상품의 가격이 인상되면 이미 결제가 완료된 orderedItem의 가격 정보도 함께 변경되어, 실제 결제 금액과 영수증에 기록되어야 할 금액이 일치하지 않는 데이터 무결성 오류가 발생했습니다. 이는 영수증의 신뢰성을 떨어뜨리는 심각한 논리적 오류였습니다.
2. 해결 과정 (Solution)
이러한 데이터 무결성 문제를 해결하기 위해 orderedItem 테이블을 제거하고 receipt (영수증) 테이블을 새로 도입했습니다.
새로운 receipt 테이블은 결제 시점의 모든 상품 정보를 JSON 또는 문자열 데이터 타입으로 직접 저장하는 방식으로 설계했습니다.
orderedItem테이블 삭제: 영수증과 주문 상품 정보의 논리적 오류를 유발했던 기존 테이블을 제거하여 문제를 원천적으로 차단했습니다.receipt테이블 생성: 결제 시점의 '스냅샷'을 보존하기 위한 테이블을 새로 만들었습니다.- 상품 정보 직접 저장:
receipt테이블에 상품의 이름, 가격, 수량 등 결제 당시의 모든 정보를 데이터 형식 그대로 저장하여, 원본 상품 정보가 변경되더라도 영수증 데이터에는 영향을 주지 않도록 했습니다.
3. 결과 및 배운 점 (Result & Learnings)
결과: 새로운 receipt 테이블 도입을 통해 데이터의 무결성(Integrity) 문제를 성공적으로 해결했습니다. 이제 영수증은 결제 시점의 정확한 정보를 안전하게 보존하며, 원본 상품 데이터의 변경으로부터 독립적인 구조를 갖게 되었습니다.
배운 점:
- 영수증과 같이 시간에 따라 변하지 않아야 하는 데이터는 외부 테이블에 의존하기보다, 해당 시점의 정보를 직접 저장하는 것이 중요합니다.
- 데이터베이스 스키마 설계 시, 비즈니스 로직의 '스냅샷'을 보존해야 하는 요구사항을 미리 파악하는 것이 데이터 무결성 오류를 예방하는 데 필수적입니다.
- 이번 경험을 통해 결제 시스템의 핵심은 영수증 데이터의 불변성을 보장하는 데 있다는 것을 깨달았고, 향후 이와 유사한 설계를 진행할 때 이 원칙을 적용할 것입니다.











