안녕하세요, 단감입니다. 이번 주 개발 근황은 사이드 프로젝트로 운영하는 "DanPet(단펫)" 이야기입니다. 한 동안 "산책지수" 기능을 정착시키느라 새벽 시간을 다 쏟았는데, 이번 주말 드디어 "다중 반려견 동시 표시"라는 한 토막을 끝냈습니다. 1인 개발자라 그런지 작은 기능 하나도 풀스택을 다 건드려야 해서, 끝나면 보람이 큽니다.
👋 오늘의 개발 근황
DanPet은 "우리 강아지에게 가장 좋은 산책 장소가 어디인지"를 지도 위에서 한눈에 보여주는 사이트입니다. 제가 본가에 강아지가 있고, 처가에도 강아지가 있다 보니 한쪽 강아지에게는 좋은 공원이 다른 쪽 강아지에게는 너무 더울 수 있더라고요. 그래서 "등록된 반려견 모두에게 동시에 점수를 보여주자"는 결심으로 한 주를 보냈습니다.
🎯 이 프로젝트는 무엇인가
DanPet은 부산을 중심으로 약 17,950개의 도시공원·근린공원·도보 코스에 대해 "반려견 산책 적합도"를 1~100점으로 매겨 보여주는 서비스입니다. 점수는 그 시점의 실측 기상(기온·체감온도·지면온도·미세먼지)과 공원 자체 특성(잔디 비율·그늘·경사·반려동물 정책)을 결합해 산출합니다. 또 사용자가 본인의 강아지(견종·크기·나이·건강 태그)를 등록하면 그 강아지에게 맞춰 점수를 보정해 줍니다. "우리 강아지에게는 이 공원이 좋아"가 한 줄로 답이 나오는 게 목표예요.
🛠️ 이번 주 뭐가 바뀌었나
한 주 동안 본격적으로 풀스택을 건드린 변경은 아래 정도였습니다.
- 다중 반려견 동시 표시 — 펫 토글로 한 마리씩 보지 않고, 등록된 모든 활성 반려견의 점수를 한 카드 안에 동시에 보여주는 UX로 재설계했습니다. 지도 마커는 "가장 낮은 점수" 기준으로 색을 칠해 "한 마리에게라도 위험하면 빨강"이라는 보수적 직관을 만들었습니다.
- 백엔드 응답 모델 단일화 — 세 엔드포인트(목록·공원 풀·상세)의 응답을 모두 personalized_pets 배열·personalized_min·personalized_max 형태로 통일했습니다. N+1을 피하려고 견종 일괄 SELECT, 기상 스냅샷 1회 조회로 최적화했습니다.
- 마커 클릭 race condition 방어 — 빠르게 두 마커를 연속 클릭하면 늦게 도착한 응답이 화면을 덮어쓰던 잠재 버그를 stale guard로 막았습니다. 진단을 잘못 하고 race condition으로 오해했었는데, 사용자분이 정확히 "v-if 우선순위 때문에 두 번 눌러야 한다"고 짚어주셔서 진짜 원인을 찾을 수 있었습니다.
- 17,950개 공원 산책지수 일괄 산출 — urban_parks 테이블 전체에 대해 산책지수를 한 번에 계산해 캐시 테이블(urban_park_index)에 저장했습니다. 이후 지도 줌·이동 시에도 BBOX 조회만으로 즉시 응답이 가도록 만들었습니다.
- DB 책임 분리 원칙 정립 — "외부 API 한 번만 호출하면 똑같이 다시 만들 수 있는가?"라는 한 줄 기준으로, 수집(dancollect)과 가공(서비스 DB)을 분리하는 원칙을 정리했습니다. 이번 주 작업의 절반은 사실 이 원칙을 어긴 옛 테이블을 정리하는 작업이었습니다.
📸 화면으로 보는 변화
💭 만들면서 느낀 점
1인 개발이 어려운 건 "기술이 어렵다"가 아니라 "우선순위가 어렵다"는 점이라는 걸 다시 느낀 한 주였습니다. 새 기능을 추가할까, 옛 코드를 정리할까를 매일 저울질해야 합니다. 이번 주에는 "옛 코드를 정리해야 새 기능이 가벼워진다"는 방향으로 시간을 더 썼고, 지나고 보니 그 결정이 맞았던 것 같아요. 마커 클릭 버그를 처음에 race condition으로 오진했던 일도 좋은 교훈이었습니다. 사용자가 본 그대로의 증상을 가장 단순하게 가설로 잡아야 하는데, 제가 "기술적으로 그럴듯한" 가설로 먼저 갔던 거죠. 1인 개발자에게 가장 좋은 QA는 결국 사용자분 한 분 한 분의 피드백이라는 걸 다시 배웠습니다.
🔗 직접 써보기
위치 기반이라 부산 중심으로 데이터가 가장 풍부합니다. 부산이 아니더라도 도시공원이 등록된 지역이라면 동작합니다. 반려견을 등록하면 등록된 모든 강아지의 점수가 동시에 표시되니, 본가·처가 강아지를 같이 등록해 보면 차이를 가장 체감하실 수 있을 거예요. 사용해 보시고 "이 점이 어색하다", "이 기능이 있으면 좋겠다" 같은 피드백 주시면, 다음 주 개발 근황에 그대로 반영해서 들고 오겠습니다.