단감의 개발일지

단펫 5월 첫주 회고 | 봄 산책 추천을 늦봄용으로 다시 짠 이유 | 1인 개발 근황

단감이:) 2026. 5. 6. 20:00

5월 첫주는 단펫(DanPet)에 가장 변화가 많은 한 주였습니다. 사용자 한 분의 "아직도 봄 산책 추천이 뜨던데요?" 한 마디에서 시작해서, 헤더 모바일 가시성 버그, SSO 아바타 노출, 모바일 앱 설치 유도 배너, 그리고 Flutter 안드로이드 앱의 카카오맵 마운트까지. 한 주 안에 꽤 많은 결을 동시에 만지게 되어 정리할 겸 적어둡니다.

👋 오늘의 개발 근황

단감(Dangam)이라는 1인 프로젝트의 한 갈래로 단펫이라는 반려동물 산책지수 서비스를 운영하고 있습니다. 이번 주는 그 단펫에 5일간 8건의 변경이 들어간 좀 빠듯한 한 주였습니다. 한 명이 만들고 운영하는 서비스다 보니 사용자 피드백 한 줄이 다음 작업의 우선순위를 그대로 정합니다.

🎯 이 프로젝트는 무엇인가

단펫은 "오늘 우리 강아지 산책 가도 될까?"를 지수로 알려주는 서비스입니다. 기상청 관측 자료, 도시공원 데이터베이스, 그리고 견종·체중·나이 같은 반려견 프로필을 조합해서 공원별 산책지수를 계산해 보여줍니다. 모기·자외선·아스팔트 온도 같은 변수까지 반영해서 "지금은 좀 위험" 같은 직관적인 메시지를 띄우는 것이 특징입니다. 산책지수 점수가 높은 공원을 지도에서 확인하고, 즐겨찾기에 추가해 매일 빠르게 점검할 수 있도록 설계했습니다.

🛠️ 이번 주 뭐가 바뀌었나

이번 주 가장 큰 변경은 시즌 분기를 다시 짠 것입니다. 봄 산책 추천 팝업이 5월에도 "벚꽃길 공원" 메시지를 띄우고 있다는 사용자 제보를 받고 보니, 3~5월을 한 덩어리로 묶어둔 것이 원인이었습니다. 시즌을 5단계(초봄·늦봄·여름·가을·겨울)로 재편하고 늦봄(5월) 콘텐츠를 새로 작성했습니다. 모기·진드기 본격 시기, 자외선, 단두종 한낮 자제, 아스팔트 온도 손등 5초 테스트 같은 5월에 정말 필요한 정보로 바꿨습니다. 닫기 버튼은 시즌별로 dismiss 키를 분리해서, 시즌이 바뀌면 자연스럽게 다시 한 번 노출되도록 했습니다.

모바일 헤더에는 꽤 큰 버그가 있었습니다. "display: none"이 잘못 들어가 있어서 모바일 사용자는 로그인 버튼이 통째로 안 보였습니다. 한참 동안 모바일에서 로그인 자체를 못 했던 셈이라 가장 먼저 고쳤습니다. 같은 김에 모바일 사이드바가 60px만 보여서 "공원 79개 랭킹"이라는 카운트도 안 보이던 문제를 160px로 늘려, 첫 카드 미리보기까지 노출되도록 다듬었습니다.

그리고 SSO 프로필 사진을 헤더와 마이페이지에 표시하기 시작했습니다. 단감의 단오스(danAuth) SSO가 구글·카카오 로그인 시 picture 필드를 자동으로 받아오고 있었는데, 정작 단펫 프론트는 닉네임 첫 글자만 그리고 있어서 사용자 입장에선 "내 프로필 사진은 어디 갔지?" 싶었을 겁니다. 32×32 원형 아바타와 마이페이지 카드를 모두 손봤습니다. 동시에 모바일에서 웹으로 접속한 안드로이드 사용자에게 앱 설치를 유도하는 배너도 새로 만들었습니다. 출시 전이라 지금은 "단펫 앱 출시 임박" 모드로 돌고, Play Store 등록 후에 환경변수만 한 줄 추가하면 자동으로 정식 모드로 바뀌도록 설계했습니다.

인프라 쪽으로는 deploy.yml의 nginx CSP 헤더가 잠재적 회귀 위험을 안고 있던 것을 표준 스니펫으로 전환했습니다. 직접 add_header로 박혀있던 한 줄을 단감 공용 csp-dangam-sso.conf 스니펫 include로 바꾸고, 다음 main push에서 SSO /auth/me fetch가 차단되는 일을 영구적으로 막았습니다. 동시에 모든 단감 서비스의 deploy.yml을 자동으로 점검하는 lint 스크립트도 추가했습니다.

안드로이드 앱 쪽에서는 Flutter Phase B 작업을 통째로 정리했습니다. parks_screen을 ListView 중심에서 KakaoMap + 하단 드래그 시트 패턴으로 전면 재설계하고, 마커 색상을 산책지수 5단계로 분리, 마커 클릭 시 시트 자동 펼침까지 마쳤습니다. 카카오맵 플러그인 버전을 0.2에서 0.4로 올리는 과정에서 Kotlin 컴파일러가 cross-drive 환경에서 에러를 내는 문제도 만나서 회피책을 적용했습니다.

📸 화면으로 보는 변화

💭 만들면서 느낀 점

이번 주에 가장 강하게 느낀 것은 "한 사용자의 한 줄 피드백이 가진 무게"입니다. "봄 산책 추천이 아직 뜨던데요?" 한 마디가 시즌 분기 자체를 다시 짜게 만들었고, 그 작업을 하다 보니 dismiss 정책의 허술함도 같이 드러났습니다. 한 줄 피드백이 결국 시즌 시스템 전체를 다시 정비하는 계기가 된 셈입니다. 1인 개발자에게 사용자 메시지는 "품질 검사관 한 분" 정도의 가치가 있는 것 같습니다.

또 하나는 "같은 김에 묶어 처리하는 효율"입니다. 봄 팝업 작업을 위해 SeasonalPopup 코드를 열어둔 김에 모바일 footer 버튼 stretch도 같이 했고, 헤더 모바일 버그를 잡는 김에 닉네임 표기·아바타 사이즈·앱 설치 배너까지 한 번에 정리했습니다. 따로따로 했다면 5일이 아니라 9~10일 걸렸을 작업이라 한 번에 묶는 호흡이 1인 개발에서는 더 중요해진다는 걸 다시 한번 확인했습니다.

마지막으로, deploy.yml CSP 회귀 같은 인프라 위험은 한 번 잡을 때 "다음 사람이 같은 함정에 빠지지 않도록" lint까지 같이 만들어두는 게 시간을 절약합니다. 이번에 추가한 check_deploy_csp.py 한 파일이 앞으로 1년 동안 같은 사고를 막아줄 거라고 생각하면 잘 쓴 1시간이었습니다.

🔗 직접 써보기

단펫은 5월 첫주 변경이 모두 운영에 반영되어 있습니다. 모바일에서 접속하면 새로 만든 앱 설치 배너도 만나볼 수 있고, 5월 늦봄 시즌 팝업도 다시 한 번 노출됩니다. DanPet 바로가기에서 우리 강아지를 등록하고 가까운 공원의 산책지수를 확인해보세요. 사용하면서 "이건 좀 더 이렇게 하면 좋겠다" 싶은 게 있으면 의견 남겨주시면 다음 한 주 작업 우선순위에 바로 반영됩니다.

반응형