프로덕트

아티클

전체 보기
이승현

이승현

우리가 쓰려고 만든 공유가계부, 우리

안녕하세요. 스터디 그룹 코드드림을 운영하고 있는 이승현입니다.

예전에 '농실농실'이라는 메이커로그를 작성한 이후, 오랜만에 새로운 앱을 출시하게 되었습니다.

최근 결혼을 준비하면서 여자친구의 소개로 공유 가계부 앱을 처음 사용해 보게 되었습니다. 꾸준히 사용하다 보니 서로의 지출 내역을 확인할 수 있어 우리가 어디에 소비를 많이 하는지 알 수 있다는 점이 특히 유용했습니다.

하지만 사용하던 앱은 반복적으로 등장하는 광고 때문에 지출과 수입을 등록할 때 불편함이 있었습니다. 특히 전면 리워드 광고나 스킵이 불가능한 광고가 사용 경험을 방해했는데요. 이를 해결하려면 유료 결제를 해야 했습니다.

그러다 문득, "차라리 직접 만들어볼까?" 하는 생각이 들었습니다. 그리고 "우리가 쓰려고 만든 공유 가계부, 우리"라는 이름과 함께 본격적으로 프로젝트를 시작하게 되었습니다.


1. 기획

먼저 기능 기획과 DB 설계를 진행했습니다.

모든 기획과 설계는 카페24 호스팅 서비스를 기준으로, 최소한의 비용으로 최대한의 효율을 낼 수 있도록 고민하며 진행했습니다.

기능

1. 회원가입

  • 최소한의 정보만 저장: 닉네임, 이메일, 비밀번호

  • 비밀번호 찾기 시 이메일 인증 활용

  • 카카오 로그인, 애플 로그인 지원 (애플 로그인은 앱스토어 배포를 위해 추가)

2. 가계부

  • 수입/지출 등록 가능, 등록되는 정보는 최소화

3. 공유 기능

  • 회원 간 가계부 공유 가능 (원하지 않는 경우도 고려)

  • 개인 사용도 가능해야 함

4. 일정

  • 단순한 가계부 기능뿐만 아니라 일정을 추가하면 좋을 것 같아 포함

  • 일정 역시 최소한의 정보만 등록 가능하도록 구성

5. 통계

  • 회원별 지출 데이터를 바탕으로 매주/매월 사용 금액 제공

6. 알림

  • 가계부 및 일정 등록 시 푸시 알림 제공

이 기획을 바탕으로 ERD를 설계했습니다.
초기 ERD이며, 기능이 하나둘 추가되면서 일부 수정되었습니다.

스크린샷 2025-02-20 오후 1.54.58.png

테이블은 크게 4가지로 구성했습니다.

  • 회원

    • 회원정보, 푸쉬, 메일인증체크 등

  • 공유

    • 회원별 하나의 공유코드를 가질 수 있으며, 코드를 통해 각 회원의 가계부와 일정을 공유합니다.

  • 가계부

    • 수입/지출에 필요한 결제구분, 수입(지출)구분은 코드화하여 별도 관리했습니다.

  • 일정

    • 가계부와는 성격이 다른 점을 고려해 테이블을 분리시켰습니다.

2. 개발

'우리'에 사용된 기술은 다음과 같습니다.

백엔드

  • Spring Boot

  • Spring Security

  • Java 17

  • MariaDB

  • Gradle

프론트엔드

  • Flutter 3.27.1

  • Dart

  • Riverpod

인프라

  • Tomcat JSP 호스팅 비즈니스

개인적으로 Flutter가 없었다면 앱 개발을 하지 못했을지도 모릅니다...😅

Riverpod을 이용한 상태 관리와 Android/iOS 배포가 어렵지 않았던 점 덕분에, 백엔드를 주로 다루는 저도 부담 없이 앱 개발에 도전할 수 있었습니다.

앱의 주요 기능은 각 기능별 API를 구현한 후 테스트를 거쳐 개발했으며, 부가 기능으로 푸시 알림과 이메일 인증을 추가했습니다.

주요기능

  • 기능별 API 구현

    스크린샷 2025-02-20 오후 2.44.31.png

    각 API에는 CLIENT_SECRET와 같은 호출 키와 값을 정의하여 무분별한 API 호출을 방지하고, 인증이 필요한 API는 JWT 토큰을 통해 인증 처리를 했습니다.

부가기능

  • 앱 푸쉬

앱 푸쉬는 Firebase Admin SDK를 사용했습니다. 가계부/일정 등록시에 공유 계정으로 푸쉬가 발송됩니다.

이 때 여러 기기에 푸쉬기능을 사용했는데 오류가 하나 있었습니다. 알고보니 해당 메소드가 deprecated 된 상태 였습니다.

// firebase-admin 9.2.0 
FirebaseMessaging.getInstance().sendEachForMulticast(message);                

// firebase-admin 8.1.0
FirebaseMessaging.getInstance().sendMulticast(message);
  • 이메일 인증

    • 비밀번호 분실시에는 Gmail 인증번호를 통해 재설정이 가능합니다.

여기까지 프로젝트 기획부터 개발까지의 간략한 내용을 정리해봤습니다.
처음 계획에는 없던 프로젝트였지만, 어제 배포를 마치고 여자친구와 함께 사용해 보니 뿌듯함을 느낍니다. 이런 점이 개발자의 큰 장점이 아닐까 싶습니다 😅

플레이스토어와 앱스토어에서 만나보실 수 있습니다.

오늘 아침에 확인해 보니 신규 회원 9명이 가입해 주셨더군요.
공유 가계부가 필요하신 분들이라면 한 번 사용해보시고, 피드백을 주시면 감사하겠습니다.

끝까지 읽어주셔서 감사합니다 :)


[플레이스토어]

[앱스토어]

3
0
이승현

이승현

농산물 실시간 경매 가격 조회앱 출시기 - 농실농실

안녕하세요. 스터디 그룹 코드드림을 운영하고 있는 이승현입니다.

최근 개발된 앱들이 있어 디스콰이엇에 소개도 할겸 프로덕트를 올려봤는데, 메이커로그 제안을 받아 이렇게 글을 작성하게 되었습니다. 뉴스레터에 소개까지 해주신다니 감사한 일입니다 :)

메이커로그는 처음이라 어떻게 쓰면 좋을지 모르겠지만 앱 홍보가 될 수 있도록 열심히 작성해봤습니다. 재밌게 읽어봐 주세요.


코드드림을 소개합니다

코드드림은 백엔드(1)/프론트엔드(1)/모바일앱(1) 개발자로 이루어진 스터디 그룹입니다. 좋은 코드로 서비스를 만들어 드립니다라는 의미에서 CODEDREAM으로 이름을 지었습니다. 그룹 팀원들의 공통된 고민이 읽기 쉽고 효율적인 코드를 작성하는 부분으로 일치했기 때문입니다.

저희는 작년 9월을 시작으로 퇴근 후에 각자 공부한 것을 공유하고, 글도 쓰고 개발도 해보면서 스터디 모임을 갖고 있습니다.

프로젝트성 개발은 보통 '이거 재밌을 것 같은데, 한번 만들어볼까?'라는 생각에서 시작되는 것 같습니다. 그리고 프로젝트의 모든 디자인은 @진가영 님이 작업하고 있습니다. 저희 팀의 만능 엔터테이너..⭐️

1. 기획

지인을 통해 프로젝트 플랫폼에서 프로젝트 의뢰 내용을 전달받았습니다. 블루베리 농가에서 의뢰한 내용으로 농산물 실시간 경락가 조회 서비스 개발에 관한 것이었습니다. 처음에는 회사에서 진행되고 있는 프로젝트로 시간이 없었습니다.

얼마 후 여유가 생겨 퇴근 후에 함께 관련 내용을 조사해봤습니다.

데이터를 가져올 OpenAPI(도매시장 통합홈페이지)가 있는 것을 확인했으며, 기존에 앱들이 있지만 광고가 많아 사용하기 힘들 정도였습니다.(버튼 클릭시 특정 카운트수를 충족하면 전면에 영상 광고가 노출되는 형태) 그래서 저희는 광고 없이 앱을 출시하기로 했습니다.

필요한 기능들을 정리해보니 다음과 같았습니다.

  • 실시간 경매 가격 조회

  • 정산 가격 조회

  • 정산 가격 통계 조회(기간별로 조회가 가능하도록)

  • 품종 조회 및 최근 검색어 저장

'OpenAPI도 있는데 우리가 한번 만들어볼까?'

그렇게 프로젝트가 시작되었습니다.

플랫폼은 웹과 모바일앱을 같이 개발하기로 결정했습니다.

웹은 모바일 친화적인 UI로 구성하고, 모바일앱은 네이티브로 결정했습니다. 처음 회의에서는 웹 뷰도 언급되었지만 웹 뷰와 네이티브의 사용성 차이를 느끼고 있던 탓에 분리하는 것이 좋겠다는 의견이었습니다.

2. 개발

프로젝트에 사용한 프레임워크는 다음과 같습니다. 코드드림의 프로젝트는 대부분 아래 기술들을 사용하고 있습니다. 검색어 저장에는 쿠키(Next.js)와 sqflite(Flutter)를 사용했습니다.

  • 웹 : Next.js

  • 모바일앱 : Flutter

  • API 서버 : Spring Boot

API 서버는 개발 초기 계획에 없었지만 프로덕트 출시 단계에서 추가됐습니다. 이유는 아래 출시에서 이어서 이야기해보겠습니다.

웹은 프론트 개발자인 @진가영님이 담당했고, 모바일앱은 백엔드 개발자겸 모바일을 서브로 하고 있는 제가 담당했습니다. 아쉽게도 모바일앱 개발자 @이지현님이 회사 프로젝트로 일정 맞추기가 힘들어 이번 프로젝트에 참여하지 못했습니다.

이번 프로젝트에서는 각자 기존에 사용하지 않았던 기능들을 사용해보기로 했습니다.


[웹]

  • Context API로 전역 상태 관리하기

  • React Hook 제작하여 사용하기(검색, 달력등)

  • 검색에 debounce사용으로 성능 개선하기

[모바일앱]

  • 페이지 이동에 go_router 사용하기

  • Riverpod으로 상태 관리하기

  • StatefulWidget 대신 ConsumerStatefulWidget 사용해보기

웹 개발이 먼저 진행됐고 웹 디자인을 베이스로 앱 개발을 진행했습니다. 이후에 앱 디자인은 수정을 거쳐 현재의 앱 화면이 완성되었습니다.

(웹 실제 화면)

(모바일앱 실제 화면)

0529153342260768.jpg

3. 출시

약 2~3주의 개발 기간이 지난 후 테스트를 거쳐 운영 배포를 하게 되었습니다. 그 과정에서 예상치 못한 변수가 생겼습니다. OpenAPI 운영 신청시에 신청 아이피라는 것이 있는데 개발 단계에서는 문제가 없지만 운영 단계에서는 아이피가 다르면 API 오류가 발생했습니다.

개발 단계에서는 API 트래픽이 100건으로 제한됩니다. 운영 단계에서는 트래픽이 100만건으로 허용되어 반드시 승인을 받아야 했습니다.

image.png문제는 모바일앱에서 다이렉트로 API를 호출하는 구조로 개발이 되어서 모바일앱의 신청 아이피를 입력할 수 없는 상황이었습니다. 또 웹은 Vercel 배포를 이용하다보니 고정 IP 사용이 불가능했습니다.

image.png

혹시나 다른 방법이 있을까 싶어 문의를 남겨봤지만 API 서버가 필요하다는 확답을 받았습니다😅

[한국농수산식품유통공사 도매시장부 답변]

image.png

서둘러 API 서버를 만들었습니다. Spring Boot/Java/Gradle 환경으로 프로젝트를 셋팅하고 각 조회 API에 사용될 RestController를 만들어 OpenAPI를 호출&반환하도록 했습니다. (기존에 사용하고 있는 구조의 변경이 필요없도록)

서버 호스팅이 필요했고 CAFE24의 비즈니스 모델이 적합해보였습니다. 하루에 1.5GB 웹 트래픽이 허용되어 주기적으로 트래픽을 모니터링해보면서 사용해보기로 했습니다.

image.png이후 부여받은 아이피로 운영 신청을 하자 정상적으로 API 호출이 가능해졌습니다.

4.모니터링

서비스 운영에 필요한 모니터링도 적용했습니다.

@진가영 님의 권유로 Sentry.io 서비스를 처음 사용해봤는데 도입하기도 어렵지 않고, 무엇보다 무료로 사용이 가능했습니다.

규모가 작은 서비스에서 사용하기 좋은 것 같아 웹/모바일앱에 모두 적용해두었습니다. 오류 발생시 Sentry.captionException을 통해 아래와 같이 메일을 받아볼 수 있습니다.

image.png

이렇게 또 하나의 프로젝트가 종료되었습니다.

앞으로 통계 데이터를 활용한 기능들을 추가해볼 예정입니다.

현재(2024.05.29 기준) 앱 사용자가 많지 않지만 기존 앱의 불편함을 해소하고자 만들어봤기 때문에 홍보가 잘되어 많은 사용자가 생겼으면 좋겠습니다.

출시된 앱은 아래에서 확인하실 수 있습니다 😄

image.pngimage.png

끝까지 읽어주셔서 감사합니다.


[웹]

[앱스토어]

[플레이스토어]

1
1

포스트

아직 포스트가 없습니다.