소개
지난 주의 사례게시글은 LLM wiki와 관련된 것이었는데, 계속 진행하다보니 회사 업무 내용으로 치우치며 외부 공개가 어려워졌습니다. 급히 사례게시글을 위한 주제를 찾았고, 평소 반려견과 산책하며 불편을 느끼던 배변수거함 정보를 표시해주는 앱을 만들어 보게 되었습니다. '이게 스터디 주제인 인터페이스 개발과 무슨 상관이지?' 라는 생 각도 잠시 들었지만, 인터페이스라는 것이 결국 넓은 의미로는 '접점'을 뜻하는 것이고 저와 반려견 배변수거함 간의 접점을 만들어 주는 것이 결국 이 앱이라고 생각하니 '못 할 건 또 뭔가' 하는 생각이 들었습니다. 그러니 양해해주세요. ㅎㅎ
진행 방법
처음에는 터미널로 클로드 코드와 단순 ideation을 시작했습니다. 최우선으로 '공공데이터, 앱 형태, 불편 해소, 누군가의 생계와 관련 없을 것' 등 여러가지 기준을 정했고, 개발에 대한 지식이 전무한 저를 위해 개발 관련 내용은 클로드 코드에게 일임한 채 건전한 논의(가스라이팅, 윽박지름)가 오갔습니다.
하지만 어느 순간 Git과 Supabase에 가입하고, 클로드 코드가 만든 웹페이지에 연결할 네이버 Maps의 API key를 따오는 저를 보며 단순 ideation 차원을 넘은 것 같아 멈추기로 결심하고 터미널을 종료했습니다. 별다른 저장 없이요. 그래서 첫 세팅까지의 프롬프트가 전혀 남아있지 않습니다.
이후의 작업은 기존에 사용 중이던 hermes(codex 모델)와, vscode에 클로드코드 확장을 연결해 진행 중입니다. 이전의 실수를 교훈삼아 히스토리 관련 md를 남기고 있고, 아직도 뭔지 잘 모르겠지만 hermes가 하라고 해서 '그럼 네가 해'라고 시킨 git commit까지 하며 말이죠.
현재는 역시 뭔지 정확히 모르는 ngrok으로 모바일에서도 접속할 수 있는 로컬 웹페이지를 만들었고, 여러 지자체에 흩어져있는 배변수거함 주소를 geocoding으로 위도와 경도 정보로 변환해 마커로 표시해 둔 상태입니다.
파란색 점이 있는 도시 지도
사용한 도구는 대략 아래와 같습니다. 사실 몇몇 도구는 클로드 코드와 hermes가 시키는 대로만 해서, 정확히 무엇인지 아직도 잘 모릅니다.
Claude Code
초반 ideation, 기본 앱 구성, 일부 기능 구현에 사용했습니다. 다만 초반 세션을 닫아버리며 기록이 날아갔습니다.Hermes / Codex
이후 코드 확인, 문제 원인 파악, 수정, 테스트, lint, build, git 커밋, 개발 히스토리 문서 업데이트를 순차적으로 진행하는 데 사용했습니다.Next.js
지도 화면, 마커, 상세 패널, 관리자 업로드 화면 등을 구현했습니다.Supabase
배변수거함 위치 데이터, 사용자 제보, 사진, 댓글, 확인/신고 정보를 저장하는 데 사용했습니다.Naver Maps API
지도 표시, 마커 표시, 주소 기반 geocoding, 길찾기 연결에 사용했습니다.ngrok
로컬에서 만든 웹페이지를 모바일에서 확인하기 위해 사용했습니다.
그리고 아래는 그 세부 과정입니다.
세부 진행 과정
처음에는 공공데이터 몇 개를 지도에 표시하는 수준이었습니다. 이후에는 “실제로 쓸 수 있는 지도앱처럼 보이려면 무엇이 필요할까?”를 기준으로 하나씩 개선했습니다.
공공데이터 수집과 geocoding
처음에는 공공데이터를 받아오면 바로 지도에 찍을 수 있을 줄 알았습니다. 그런데 실제로는 그렇지 않았습니다. 어떤 데이터는 위도와 경도가 있었지만, 많은 데이터는 주소만 있었습니다. 지도에 마커를 표시하려면 주소를 위도와 경도로 바꿔야 했고, 이 과정에서 Naver Geocoding API를 사용했습니다. 최종적으로는 여러 지자체의 데이터를 모아 전처리했고, 주소 기반 데이터를 좌표로 변환해 Supabase에 반영했습니다. 결과는 다음과 같았습니다.
원본 데이터: 810행 기존 좌표 데이터: 21개 지오코딩 성공: 587개 최종 업로드 후보: 608개 Supabase 반영: 608개이 과정에서 느낀 점은, 공공데이터는 “가져오는 것”보다 “쓸 수 있게 만드는 것”이 훨씬 어렵다는 점이었습니다.
지도와 마커가 안 뜨는 문제
중간에 지도와 마커가 제대로 뜨지 않는 문제도 있었습니다. 특히 Naver Maps API 설정이 생각보다 까다로웠습니다. 로컬에서는 되는 것처럼 보여도, 모바일이나 ngrok 주소에서는 지도가 안 뜨는 경우가 있었습니다. 이때 단순히 “지도 안 떠요”라고 하기보다, 현재 상태를 짧게 나눠서 AI에게 전달했습니다. 실제로 남아 있는 프롬프트 일부는 아래와 같습니다.
지금 모바일로는 접속이 안 되는데..window.naver → undefined이 짧은 문장만 보면 조금 성의 없어 보이지만, 실제로는 중요한 단서였습니다.
window.naver가 undefined라는 것은 Naver Maps SDK가 제대로 로드되지 않았을 가능성을 뜻했기 때문입니다. 이후에는 Hermes가 코드와 설정을 확인하면서 아래 항목들을 나눠 확인했습니다.Naver Maps SDK가 정상 로드되는지
API 응답이 정상인지
Naver Cloud Console에 서비스 URL이 등록되어 있는지
ngrok URL이 반영되어 있는지
dev server가 외부 접속을 허용하는지
모바일 화면에서 지도 컨테이너 높이가 정상인지
이 과정에서 “로컬에서 보인다”와 “사용자 기기에서 보인다”는 완전히 다른 문제라는 것을 배웠습니다.
마커 608개 표시 문제
Supabase에 공공데이터 608개를 반영하고 나니 또 다른 문제가 생겼습니다. 지도에 마커를 많이 찍을 수는 있었지만, 화면이 복잡해졌습니다. 단순히 데이터가 많다고 좋은 인터페이스가 되는 것은 아니었습니다. 처음에는 현재 화면 기준으로 최대 250개까지만 마커를 표시하도록 제한했습니다.
현재 화면 n개 / 전체 608개 확대하면 n개 더 보여요이런 식으로 안내를 붙였습니다. 하지만 지도를 축소해서 전체 분포를 보고 싶을 때는 250개 제한이 조금 어색했습니다. 사용자는 “어디에 데이터가 많이 몰려 있는지”도 보고 싶을 수 있기 때문입니다. 그래서 이후에는 클러스터링을 적용했습니다. 가까운 마커끼리는 숫자 원형 마커로 묶고, 지도를 확대하면 개별 마커로 풀리도록 했습니다.
클러스터 색상까지 맞추기
클러스터링을 적용한 뒤에도 작은 문제가 있었습니다. 공공데이터 개별 마커는 파란색이고, 사용자 등록 마커는 초록색이었는데, 처음 적용된 클러스터 색상이 초록색 계열이었습니다. 그러면 사용자가 “이게 사용자 등록 데이터 묶음인가?”라고 오해할 수 있었습니다. 그래서 클러스터 색상도 공공데이터 마커와 같은 파란색 계열로 바꿨습니다. 최종 의미는 이렇게 정리했습니다. (2/5)
파란 핀 = 공공데이터 개별 수거함 파란 숫자 원 = 공공데이터 묶음/클러스터 초록 핀 = 사용자 등록 수거함작은 색상 변경이지만, 지도 인터페이스에서는 이런 시각적 약속이 중요하다는 것을 알게 됐습니다.
사용한 프롬프트 전문
초반 Claude Code 세션은 실수로 닫아버려서 첫 세팅까지의 프롬프트는 남아 있지 않습니다. 이후 VS Code의 Claude Code 확장과 Hermes에서 진행한 프롬프트 중 일부는 남아 있습니다. 아래는 이번 작업 흐름을 잘 보여주는 실제 프롬프트 일부입니다.
이전 세션을 그냥 종료해서 맥락이 끊겼어.. 공공데이터 자동 싱크되는 걸로 잘 못 말했다가, CSV 업로드 하는 걸로 바꾸는 상태였어. 그 작업을 막 끝낸 것 같아. 공공데이터 자료를 업로드하고 싶어.이 프롬프트는 기능 구현보다 먼저, 끊 긴 맥락을 복구하는 요청이었습니다. 어디까지 했는지, 어떤 방향으로 바뀌었는지, 현재 파일과 설정이 어떤 상태인지 다시 확인해야 했습니다.
토큰 설정 다 했어. 그 단계는 일단 제외하고, 히스토리 관련해서는 네가 무슨 말을 하는지 내가 비개발자라 잘 모르겠다. 그래서 결론적으로 어떻다는거야? 앱 개발 히스토리 확인이 가능하다는거야?이 부분은 비개발자 입장에서 꽤 중요했습니다. AI가 git, commit 같은 말을 해도 저는 그게 정확히 뭔지 잘 몰랐습니다. 그래서 결국 “결론적으로 확인 가능한 거야?”라고 다시 물었고, 이후에는 Markdown 개발 히스토리와 git 커밋을 함께 남기기 시작했습니다.
일단 업로드까지 했어. 이렇게 뜨네 [스크린샷 첨부] 파주시 7개 완료래공공데이터 CSV 업로드 중 오류가 있었고, 이후 파주시 데이터가 반영된 것을 확인하는 과정입니다. 이때도 AI가 오류 원인을 확인하고, 중복 좌표 처리 등 필요한 수정을 이어갔습니다.
ㅇㅇ 잘 보이는데 가독성을 위해 핀 이미지를 좀 바꿔야겠다 - 공공데이터 : /pin_blue.png - 사용자 등록 : /pin_yellow.png이 프롬프트는 지도 인터페이스에서 데이터 출처를 어떻게 구분할지에 대한 요청이었습니다. 단순 기능보다 사용자가 정보를 어떻게 이해할지가 더 중요해지는 지점이었습니다.
배경이 투명하게 안 됐는데. 일단 넘어가자. 이 거 모바일에서 보려면 어떻게 해?완벽하게 해결되지 않은 문제는 잠시 넘기고, 실제 사용 환경인 모바일 테스트로 넘어간 장면입니다. 개인적으로는 이것도 중요한 판단이었다고 생각합니다. 모든 것을 완벽히 고치기보다, 지금 확인해야 할 사용자 경험을 먼저 본 것입니다.
보안 이슈는 없어? 그래 수정해줘. 그런데 댓글 사진 삭제 RLS도 마찬가지 이슈 아니야?MVP라고 해도 외부에 공개하려면 보안 점검이 필요했습니다. 특히 Supabase RLS, Storage 정책, 댓글 사진 삭제 권한 같은 부분을 확인했습니다.
앞으로 하는 모든 작업에서, 개발 관련 작업은 각 단계마다 깃 커밋을 찍고 싶은데 어떻게 하면 될까?이 요청 이후에는 단순히 코드를 고치는 것에서 끝나지 않고, 작업 단계마다 git 커밋과 개발 기록을 남기는 흐름으로 바뀌었습니다. 이번 작업에서 가장 많이 쓴 방식은 결국 아래와 같습니다.
1. 지금 보이는 증상 2. 이미 확인한 것 3. 안 되는 범위 4. 다음에 확인하고 싶은 것긴 프롬프트를 멋지게 쓰는 것보다, 실제 화면에서 관찰한 문제를 짧게 전달하는 방식이 더 효과적이었습니다.
결과와 배운 점
이번 작업의 결과는 다음과 같습니다.
공공데이터 608개 Supabase 반영
주소 기반 데이터 geocoding 적용
화면 기준 마커 표시 개선
250개 제한 방식 적용 후 클러스터링으로 개선
클러스터 색상을 공공데이터 파란 마커와 맞춤
테스트 32개 통과
lint 오류 0개
build 성공
작업별 git 커밋 및 개발 히스토리 문서 업데이트가장 크게 배운 점은 인터페이스 개발은 화면을 만드는 것에서 끝나지 않는다는 점이었습니다. 처음에는 “지도에 마커를 찍으면 되는 것 아닌가?”라고 생각했습니다. 하지만 실제로는 마커가 너무 많으면 보기 어렵고, 색상이 의미와 맞지 않으면 헷갈리고, 모바일에서 안 뜨면 아무 소용이 없었습니다. 지도, 마커, 클러스터, 색상, 현재 위치, 길찾기 버튼은 각각 작은 요소처럼 보이지만, 사용자는 그것을 하나의 흐름으로 경험합니다.
내 위치 확인
→ 주변 수거함 확인
→ 마커 클릭
→ 상세 정보 확인
→ 길찾기
→ 필요하면 제보이 흐름이 자연스러워야 비로소 인터페이스가 의미를 가진다는 걸 느꼈습니다. 나만의 꿀팁은 AI에게 “전체를 다 만들어줘”라고 하기보다, 실제 화면에서 생긴 문제를 기준으로 짧게 묻는 것입니다. 예를 들면 이런 식입니다.
마커가 너무 많아서 보기가 어렵다.
화면을 축소해도 마커가 최대 250개씩만 나오니 전체 분포를 알 수가 없네?
화면 축소하면 근처에 있는 마커들끼리 묶어서 숫자로 표시하도록 바꿀 수 있을까?이렇게 작게 나누면 AI가 원인을 확인하고, 코드를 수정하고, 테스트까지 이어가기가 훨씬 쉬웠습니다. 또 하나의 꿀팁은 AI에게 검증과 기록까지 맡기는 것입니다. 코드만 수정하면 나중에 “어디까지 했더라?”가 되기 쉽습니다. 그래서 이번에는 작업 후마다 아래 루틴을 돌렸습니다.
수정
→ 테스트
→ lint
→ build
→ git 커밋
→ 개발 히스토리 업데이트비개발자 입장에서는 git도 낯설었지만, “작업 저장 지점”이라고 생각하니 조금 이해가 됐습니다.
과정 중에 어떤 시행착오를 겪었나요?
첫 번째 시행착오는 주제 선정이었습니다. 원래는 LLM wiki 관련 내용을 사례게시글로 쓰려고 했지만, 점점 회사 업무 내용과 가까워졌습니다. 외부 공개가 어려워졌고, 급히 다른 주제를 찾아야 했습니다. 그 과정에서 평소 불편했던 반려견 배변수거함 위치 문제가 떠올랐습니다.
두 번 째 시행착오는 Claude Code 세션을 저장 없이 종료한 것입니다. 초반 ideation과 기본 세팅을 꽤 진행했는데, 세션을 닫아버리면서 프롬프트와 맥락이 거의 사라졌습니다. 이후에는 프로젝트 폴더, 남은 코드, Supabase 상태, 개발 히스토리 문서를 보며 다시 맥락을 복구해야 했습니다.
세 번째 시행착오는 공공데이터 전처리였습니다. 공공데이터는 그냥 가져오면 바로 쓸 수 있을 줄 알았습니다. 그런데 좌표가 없는 데이터가 많았고, 주소를 위도·경도로 바꾸는 geocoding 과정이 필요했습니다. 일부는 주소가 없거나 변환에 실패하기도 했습니다.
네 번째 시행착오는 지도 표시 문제였습니다. 로컬에서는 보이는데 모바일에서는 안 보이거나, ngrok 주소에서 지도가 비어 보이는 문제가 있었습니다. 이때는 Naver Maps API 권한, 서비스 URL 등록, SDK 로딩 상태, dev server 설정 등을 하나씩 확인해야 했습니다.
다섯 번째 시행착오는 마커 UX 문제였습니다. 608개 데이터를 지도에 올리고 나니, 데이터가 많다는 것이 곧 좋은 화면을 뜻하지는 않는다는 걸 알게 됐습니다. 처음에는 250개 제한을 적용했지만, 이후에는 클러스터링이 더 자연스럽다고 판단했습니다.
도움이 필요한 부분이 있나요?
비개발자로서 처음 시도하는 작업이다보니, 모든 것이 새롭고 알아야 할 것이 많은 상태입니다. 어떤 도움이든 감사하게 받겠습니다.
앞으로의 계획이 있다면 들려주세요.
앞으로는 아래 방향으로 조금씩 개선해보고 싶습니다.
실제 모바일 산책 상황에서 사용성 테스트
현재 위치 기준 가까운 배변수거함 보기 개선
공공데이터와 사용자 제보의 신뢰도 표시
사용자 등록 / 사진 제보 흐름 단순화
외부 공유 전 Supabase RLS, Storage 정책, rate limit 재점검
다른 지자체 데이터 추가 수집 및 정규화
그리고 개발 방식도 계속 유지해보려고 합니다. 앞으로는 기능 하나를 수정할 때마다 아래 흐름을 반복하고 싶습니다.
작은 수정
→ 테스트
→ lint
→ build
→ git 커밋
→ 개발 기록 업데이트이번 사례를 통해 AI가 단순히 코드를 만들어주는 도구가 아니라, 문제를 나눠서 해결하고 그 과정을 기록하게 도와주는 협업 파트너가 될 수 있다는 걸 느꼈습니다.