image-compressed.webp

서비스 보기 · GitHub

<aside>

상품을 고르고 주문하는 화면부터 관리자 운영까지 직접 만든 패션 쇼핑몰입니다.

주문이 확정될 때 가격·재고·쿠폰·포인트를 서버에서 다시 확인하는 데 중점을 두었습니다.

</aside>

왜 만들었나요?

쇼핑몰은 주문 화면을 만드는 것만으로 끝나지 않습니다. 고객이 보는 상품 정보와 실제 주문·재고 정보가 맞아야 하고, 관리자는 상품과 주문을 이어서 처리할 수 있어야 합니다. 이 흐름을 직접 구현하기 위해 STYNA를 만들었습니다.

맡은 일

2025.08부터 진행 중인 개인 프로젝트로, 기획·디자인·개발을 모두 맡았습니다. 상품 목록과 상세, 장바구니, 주문서, 주문 완료 화면을 만들고 관리자 상품·주문 관리까지 연결했습니다.

화면은 Next.js와 TypeScript, 데이터와 로그인·서버 처리는 Firebase를 사용했습니다. 화면에서만 필요한 상태와 서버에서 받아오는 데이터를 나누고, 서버 데이터는 TanStack Query로 관리했습니다.

주요 화면

image.png

상품 목록 카테고리와 필터를 통한 상품 탐색

image.png

상품 상세 옵션과 수량을 선택하는 화면

image.png

장바구니 및 주문서 배송지, 쿠폰, 포인트를 적용하는 주문 화면

image.png

주문 완료 완료된 주문 정보 확인

image.png

상품 관리 상품 등록과 수정

image.png

주문 관리 주문 확인과 상태 변경

문제를 해결한 과정

1. 화면의 주문 정보를 서버에서 다시 확인

주문서를 보고 있는 동안 상품 가격이나 재고가 달라질 수 있습니다. 그래서 화면이 보낸 값을 그대로 저장하지 않고, 서버 함수인 Firebase Functions에서 가격·배송비·쿠폰·포인트 조건을 다시 확인했습니다.

주문 생성과 재고 차감은 함께 성공하거나 함께 취소되는 묶음 처리인 Transaction으로 구성했습니다. 주문 취소 시에는 재고·쿠폰·포인트를 복구하도록 연결했습니다.

2. 관리자 화면과 실제 변경 권한을 따로 확인

관리자 메뉴를 숨겨도 화면을 거치지 않은 데이터 변경 요청은 들어올 수 있습니다. 로그인 사용자와 관리자 여부를 확인하고, 데이터 접근 규칙과 서버 함수에서도 권한을 다시 검사했습니다. 주문 상태 변경 이력도 저장했습니다.

3. 새 이미지와 기존 이미지를 같은 기준으로 관리

상품·카테고리·이벤트 이미지를 업로드하기 전에 WebP 형식으로 변환했습니다. 이미지 종류별로 저장 경로와 권한을 나누고, 기존 이미지도 변환한 뒤 데이터에 저장된 주소를 교체했습니다.