본문으로 건너뛰기
DEVKBS
작업 원장
019Dpectrum2025.04 – 2025.10운영 중

GOLDIE 금 거래 앱 (사용자)

집에 있는 금을 매장에 가지 않고 파는 흐름 전체

기간
2025.04 – 2025.10
분류
플랫폼
역할
프론트엔드 전담
구성
프론트엔드 1(전담) · 백엔드 1 · Flutter 1
사이트 방문
  • 모바일 화면1080 × 2340
  • 모바일 화면1080 × 2340
  • 모바일 화면1080 × 2340

01개요

금을 팔려면 보통 매장에 직접 가야 하고, 그 자리에서 제시받은 금액을 그대로 받아들이게 됩니다. GOLDIE는 이 과정을 비대면으로 옮긴 서비스입니다. 사용자는 시세를 먼저 확인하고, 예상 금액을 계산해 보고, 접수 후 물건을 보내고, 감정 결과를 확인한 뒤 정산을 받습니다.

네이티브 앱 안에서 도는 웹뷰 형태였고, 프론트엔드는 내가 혼자 맡았습니다. 로그인·본인인증·결제·실시간 채팅처럼 보통 여러 사람이 나눠 맡는 영역을 전부 다뤄야 했다는 점이 이 프로젝트의 성격을 결정했습니다.

가장 신경 쓴 것은 '돈이 걸린 화면의 신뢰감'이었습니다. 금액이 화면마다 다르게 보이거나, 새로고침했더니 숫자가 달라지거나, 접수 중간에 뒤로 가기를 눌렀더니 입력이 날아가면 사용자는 서비스 자체를 의심하게 됩니다. 계산 로직을 한 곳으로 모으고, 단계별 입력을 URL과 스토어에 나눠 남긴 이유입니다.

미성년자 거래 제한 같은 규제 요건도 화면 설계에 직접 영향을 줬습니다. 본인인증에서 받은 생년월일을 기준으로 특정 기능 자체를 막아야 했는데, 이런 제약은 나중에 붙이면 화면 곳곳에 조건문이 흩어집니다.

02기술 결정

문제가 무엇이었고, 무엇을 골랐고, 그래서 어떻게 됐는지.

  1. 결정 01

    금액 계산은 화면이 아니라 한 개의 순수 함수에서

    문제
    예상 금액은 시세 조회 화면, 접수 폼 요약, 마지막 확인 화면 세 곳에 나타납니다. 각 화면에서 계산하면 반올림 처리 하나만 달라도 숫자가 어긋납니다.
    선택
    중량·순도·시세·수수료를 받아 금액을 돌려주는 순수 함수를 만들고 화면은 그 결과만 그리게 했습니다. 반올림 규칙과 최소 단위를 함수 안에 가두고 Vitest로 고정했습니다.
    결과
    세 화면의 숫자가 항상 일치합니다. 정책이 바뀌었을 때도 함수 하나와 그 테스트만 고치면 되어 반영이 빨랐습니다.
  2. 결정 02

    다단계 접수 폼의 상태를 URL과 스토어로 나눈다

    문제
    접수는 단계가 여럿이고 중간에 사진 촬영·주소 검색 같은 이탈이 끼어듭니다. 상태를 메모리에만 두면 돌아왔을 때 처음부터 다시 해야 합니다.
    선택
    현재 단계는 search params로, 입력 값은 세션 단위 스토어로 나눠 저장했습니다. 뒤로 가기는 단계 이동으로 자연스럽게 동작하고, 새로고침해도 값이 남습니다.
    결과
    중간 이탈 후 복귀가 가능해졌습니다. 특정 단계를 링크로 지목해 QA 하기도 쉬워져서 검수 과정도 빨라졌습니다.
  3. 결정 03

    연령 제한은 화면이 아니라 세션에서 판단한다

    문제
    미성년자는 일부 거래 기능을 쓸 수 없습니다. 이 조건을 버튼마다 확인하면 새 화면이 생길 때 빠뜨리기 쉽고, 빠뜨린 사실도 눈에 띄지 않습니다.
    선택
    본인인증 결과에서 나온 생년월일을 세션 정보에 담아, 제한 여부를 로그인 시점에 한 번 계산해 두고 화면은 그 플래그만 읽게 했습니다.
    결과
    새 기능을 붙일 때 제한 조건을 다시 구현할 필요가 없어졌습니다. 규제 요건이 화면 수만큼 흩어지는 것을 막았습니다.
  4. 결정 04

    재사용 컴포넌트는 Storybook에서 먼저 만든다

    문제
    혼자 만드는 프로젝트에서는 컴포넌트가 특정 화면에 붙은 채로 자라기 쉽습니다. 나중에 다른 화면에서 쓰려고 하면 그 화면의 사정이 함께 딸려 옵니다.
    선택
    공통 UI는 화면과 분리해 Storybook에서 상태별로 먼저 만들고, 화면에서는 조립만 하게 했습니다.
    결과
    빈 상태·에러·로딩처럼 실제로는 잘 확인하지 않게 되는 상태를 개발 중에 계속 눈으로 보게 됐습니다. 디자이너와 화면 없이도 컴포넌트 단위로 이야기할 수 있게 된 것도 컸습니다.

03주요 기능

  • 실시간 시세와 차트

    금 시세를 실시간으로 받아 Recharts로 추이를 시각화.

  • 예상 견적 챗봇

    시세를 기준으로 예상 금액을 대화형으로 안내하는 견적 흐름.

  • 소셜·일반 로그인

    네이버·카카오·구글·애플 소셜 로그인과 일반 회원가입을 Auth.js로 구축.

  • 본인인증과 연령 제한

    PASS 본인인증을 연동하고 생년월일 기준으로 미성년 기능 제한을 적용.

  • 1:1 실시간 채팅

    Firebase Realtime Database로 사업자와 사용자 간 채팅을 구현.

  • 실시간 배송 추적

    Sweet Tracker API를 연동해 접수한 물건의 배송 상태를 확인.

  • 결제 연동

    포트원(PortOne) 결제를 붙여 정산·결제 흐름을 처리.

  • 진행 상태 추적

    접수 → 수거 → 감정 → 정산까지 현재 위치를 타임라인으로 표시.

04회고

돈이 걸린 화면에서는 기능보다 신뢰가 먼저입니다. 숫자가 한 번이라도 어긋나 보이면, 그 뒤에 아무리 좋은 기능을 붙여도 사용자는 처음의 의심을 기억합니다. 계산을 한 곳에 모으고 테스트로 못 박아 두는 건 그 뒤로 그냥 기본이 됐습니다.

혼자 전담한다는 것은 자유롭다는 뜻이 아니라, 내가 세운 규칙을 지적해 줄 사람이 없다는 뜻이었습니다. Storybook과 테스트를 도입한 것은 결국 미래의 나에게 리뷰를 맡기는 장치였다고 생각합니다.

다단계 폼은 처음부터 '중간에 나갔다 돌아온다'를 전제로 설계해야 합니다. 나중에 붙이려면 각 단계가 이미 서로를 참조하고 있어서 되돌리기가 어렵습니다.