관광데이터 활용 공모전 지원기 3편, 배포와 제출, 그리고 느낀 점
배포 전 스트레스 테스트 리포트를 다시 읽으며 우선순위를 바꾼 과정, 1차 심사용 기능설명서를 만들고 고친 과정, 혼자 관광데이터 활용 공모전을 준비하며 느낀 점을 정리한 마지막 편이에요.
서비스를 다 만들어갈 즈음 스트레스 테스트를 돌렸어요. 리포트는 동시 접속 500명, 언론에 노출됐을 때를 걱정하고 있었습니다. 그런데 다시 생각해보니 마감 18일 전에 그런 상황은 오지 않아요. 실제로 일어날 일은 심사위원 몇 명이 URL을 처음 여는 순간이었습니다. 관광데이터 활용 공모전 준비의 마지막 구간은 이 관점 전환에서 시작됐어요.
이 글은 반려동물 동반 판정 서비스 PetOK을 공모전에 내기까지의 기록 중 마지막 편이에요. 1편에서는 지원 계기와 기획 단계의 고충을, 2편에서는 차별화와 사용자 연구, 개발 최적화를 다뤘습니다. 이번에는 배포 전 테스트, 1차 심사 서류 작업과 제출, 그리고 혼자 준비하면서 느낀 점을 정리할게요.
배포 전 테스트, 심사위원의 첫 접속을 기준으로
스트레스 테스트 리포트를 다시 읽으면서 기준을 바꿨어요. “동시 500명을 버틸 수 있나”가 아니라 “심사위원이 처음 열었을 때 답답하지 않은가”로요. 그 기준으로 숫자를 다시 보니 꽤 아팠습니다. 접속자가 0명인 상태에서 첫 화면이 1,020ms, 서울 지역 지도 첫 로딩이 1,681ms, 줌아웃 한 번에 2,375ms였어요. 병목은 처리량이 아니라 지연과 응답 크기였습니다.
서버 자원은 오히려 여유가 있었어요. 2 vCPU 서버에 앱 7개가 같이 돌고 있었지만 메모리는 2.1GB 정도 남아 있었고, PetOK API 프로세스는 131MB를 쓰고 있었습니다. 그러니 서버를 하나 더 파는 건 답이 아니었어요. 응답 크기를 줄이고 캐시를 제대로 먹이는 쪽이 먼저였고, 그 작업은 2편에서 자세히 썼습니다.
리포트가 놓치고 있던 위험도 정리했어요. 지도 API 호출 한도를 확인한 적이 없었고, 앱 프로세스가 하나라 죽으면 접속자 전원이 에러를 보는 구조였고, 지도 API 요청 로그가 꺼져 있어서 심사 중 문제가 생겨도 원인을 볼 수 없는 상태였어요. DB 백업, 상태 확인용 엔드포인트, 프로세스 모니터링 같은 항목도 체크리스트에 올렸습니다. 개발용으로 쓰던 관리형 DB의 무료 사용량도 걸렸어요. 상시 켜두는 설정이면 마감 전에 한도를 다 써서 개발 DB가 멈출 수 있는 페이스였거든요. 성능 문제보다 마감 주에 개발 환경이 멈추는 게 훨씬 치명적이라, 한도 리셋 날짜부터 확인했습니다. 지도 API 키도 운영 도메인에서만 쓰이게 제한이 걸려 있는지 다시 봤어요. 막상 하나씩 확인해보니 상당수는 이미 처리돼 있거나 지금 단계에서는 필요 없는 것들이라, 티켓 목록을 과감하게 줄였어요.
시간 배분에도 선을 그었어요. 남은 18일 중 성능과 인프라에는 5일 이상 쓰지 않기로 했습니다. 관광데이터 활용 공모전 구현 부문 공고문의 배점표를 다시 보면 1차 심사는 구현성, 기획력, 데이터 활용, 발전성이고 응답 속도는 구현성 안의 구동 안정성 정도에 걸려요. 점수는 조건 해석의 정확도와 완성도에서 나오니까, 인프라는 “답답하지 않을 정도”에서 끊는 게 맞다고 판단했습니다. 싱가포르 리전 이전을 마감 전에 보류한 것도 같은 이유였어요.
테스트 항목 중 기능 쪽으로 제일 신경 쓴 건 회귀 테스트였어요. 응답을 가볍게 만들려고 지도 목록 쿼리에서 사용자 제보 집계를 빼는 작업이 있었는데, 이 자리가 예전에 버그가 났던 곳이었거든요. 실내 동반 거절 제보를 넣었는데도 지도 핀이 초록으로 남아 있던 버그였습니다. 그래서 제보로 판정이 바뀐 장소가 지도에서도 바뀐 색으로 보이는지 확인하는 테스트를 통과 조건으로 걸었어요. 속도를 얻으려다 판정이 틀리면 이 서비스는 존재 이유가 없으니까요.
캐시를 켤 때도 함정이 하나 있었어요. 비로그인 사용자는 기본 프로필(소형견 한 마리) 기준으로 판정을 보는데, 이 경우만 공용 캐시를 쓰게 하고, 반려동물 프로필을 직접 등록한 사용자의 응답은 캐시하지 않게 나눴습니다. 이걸 잘못 걸면 대형견 보호자가 소형견 기준 판정을 보게 돼요. 지도가 초록이라 믿고 갔는데 입장을 거절당하는, 이 서비스가 막겠다던 바로 그 상황이 만들어지는 거죠. 같은 요청을 짧은 시간 안에 반복해서 원본 서버를 두드리는 경우를 막으려고, IP 단위 요청 제한은 앱이 아니라 nginx 단에 두는 것으로 정리했습니다.

배포 직전에 챙긴 행정과 정책
기술 말고도 챙길 게 있었어요. 제일 컸던 건 공사 데이터를 제 서버 DB에 저장해서 써도 되는지에 대한 승인이었습니다. 8월 5일에 신청서를 보냈는데 한 달 가까이 답이 없었어요. 9월 초에 다시 메일을 보냈더니 다음 날 승인됐다는 회신이 왔습니다. 이 승인이 없었으면 지도 서비스 구조 자체가 성립하지 않았을 거라, 회신을 받고 나서야 마음 놓고 배포 준비를 할 수 있었어요.
승인을 받은 뒤에는 출처 표기를 정리했어요. 사이트 하단 푸터에 공사 데이터 출처를 “ⓒ한국관광공사”로 넣고, 데이터 갱신 시점 같은 안내 문구도 같이 다듬었습니다. 공공데이터포털 운영 계정 신청서도 이 시점에 작성했어요. 개발 단계에서 쓰던 계정 그대로 심사를 맞으면 나중에 서비스로 운영할 때 다시 손봐야 하니까요.
정책도 하나 크게 바꿨어요. 원래 “갈 수 없음” 장소를 지도 핀에서 숨기는 방향이었는데, 배포 전 측정 중에 이게 문제라는 걸 알게 됐습니다. 사용자는 보통 인스타나 블로그에서 장소를 먼저 보고 PetOK에서 “거기 되나”를 확인해요. 그런데 갈 수 없는 곳이 지도에 없으면 “아직 등록 안 된 곳”과 “가면 안 되는 곳”이 똑같은 빈자리로 보입니다. 빈 데이터와 거절을 섞지 않는다는 원칙을 지도에서 어기고 있었던 거죠. 그래서 전면 노출로 바꿨고, 지도에 뜨는 장소가 2,647곳에서 약 4,139곳으로 늘었어요.
당시 /impact 패널에서 실측한 규모는 이랬습니다.
| 데이터 출처 | 전체 | 확인 필요 비율 | 갈 수 없음 |
|---|---|---|---|
| 반려동물 동반여행 API | 1,048곳 | 31.8% | 18곳 |
| 고캠핑 | 3,101곳 | 16.3% | 1,474곳 |
| 합계 | 4,149곳 | 838곳 | 1,492곳 |
갈 수 없음의 대부분이 고캠핑 쪽에서 나왔어요. 캠핑장은 반려동물 동반 불가를 명시한 곳이 많아서, 이걸 숨기면 지도에서 캠핑장 1,474곳이 그냥 사라지는 셈이었습니다. 빨간 핀이 너무 많아져서 화면이 시끄러워질까 걱정했는데, 빨간 핀은 채도를 한 단계 낮춰서 그리고, “갈 수 없음” 필터 칩을 추가해서 기본은 켜두되 끌 수 있게 했어요. 왼쪽 목록의 집계 칩에도 갈 수 없음 개수를 같이 보여주게 했고요. 전국 단위로 줌아웃했을 때는 개별 핀 대신 서버에서 미리 묶은 집계를 내려주는 방향으로 응답 크기 목표를 60KB 이하로 잡았습니다.
관광데이터 활용 공모전 1차 심사 서류 만들기
1차 심사 자료는 기능설명서 양식(PPTX)과 한국관광 콘텐츠랩 입력 항목이었어요. 공고문에는 지정과제 해시태그와 연관된 기능 구현 내용으로 기능설명서를 요청할 예정이라는 안내가 처음부터 있었고, 저는 기획 초반부터 이걸 메모해 뒀습니다. 그래서 문서 작업이 개발 이후의 새 일이 아니라 지금까지 만든 걸 정리하는 일이 될 수 있었어요.
해시태그는 다섯 개로 잡았어요. #조건 해석, #헛걸음 방지, #현장 검증, #데이터 투명성, #공공데이터 환류. 예시에 있던 태그 중 두 개를 가져오고 나머지는 PetOK의 차별화 지점에서 직접 뽑았습니다. 태그마다 연결되는 기능을 하나씩 짝지어서 설명하는 구조로 짰어요. 조건 해석은 반려동물 프로필과 장소 조건을 대조해 네 단계로 판정하고 공사 원문을 같이 보여주는 기능, 헛걸음 방지는 확인 필요와 갈 수 없음을 숨기지 않고 지도에 띄우는 정책, 현장 검증은 증거 등급별로 무게가 다른 제보 구조, 데이터 투명성은 /impact 페이지의 산식 공개와 판정 변경 이력, 공공데이터 환류는 사용자 제보를 공사 스키마 그대로 모아 돌려주는 흐름이에요. 태그 하나에 기능 하나가 정확히 걸리니까, 심사위원이 어떤 태그를 보든 실제 화면으로 바로 확인할 수 있게 하려고 했습니다. 양식 초안은 Claude가 13장으로 채우게 했어요. 기능 설명 문구와 구조는 AI에게 맡기되, 실제 서비스 화면을 넣어야 하는 자리는 빨간 별표로 비워두게 했습니다. 거기에 제가 직접 화면을 캡처해서 넣고 문구를 손봤어요.
다 채운 문서를 다시 넘겨서 최종 검토를 한 번 더 돌렸는데, 여기서 고친 게 네 가지였어요.
제일 큰 수정은 “관리자 검수”라는 표현이었어요. 초안에는 사용자가 새 장소를 제보하면 PetOK이 검수해서 지도에 올리는 것처럼 써 있었습니다. 실제 구조는 달라요. PetOK은 제보를 직접 승인하지 않습니다. 제보는 공사 반려동물 동반여행 API와 똑같은 필드 구조로 큐에 모이고, 이걸 공사에 데이터 개선 제안으로 넘겨요. 공사가 검증해서 API에 올리면 야간 동기화로 지도에 자동 반영되는 흐름입니다. 같은 스키마로 모으니까 공사 입장에서는 검증하고 적재만 하면 된다는 점, 이걸 차별화 포인트로 하나 더 추가했어요.
나머지는 숫자와 표현이었어요. 데이터 투명성 항목에 “최근 변경 20건 표시”라고 써 있던 걸 “이력이 없으면 없다고 표시”로 바꿨습니다. 실서버에 변경 이력이 아직 쌓이지 않았는데 20건을 보여준다고 쓸 수는 없었으니까요. 그리고 고캠핑 장소 수를 초안의 3,101곳에서 실서버 /impact 화면에 찍힌 3,128곳으로 맞췄어요. 캡처와 본문 숫자가 다르면 심사위원은 그 문서 전체를 의심하게 됩니다.

사용자 데이터 0은 약점일까
제출 직전에 제일 흔들렸던 지점이에요. 실서버에 실제 사용자의 방문 기록이나 제보가 비어 있었거든요. AI는 시드 데이터를 채우는 전략을 계속 권했습니다. 운영자가 직접 현장을 확인해서 채우자, 특정 지역부터 전화로 확인해서 채우자는 식으로요.
제가 정리한 답은 이랬어요. 이건 베타 사용자 없이 공모전용으로 만든 서비스고, 서비스의 본체인 약 4,150곳의 판정과 조건 구조화는 이미 다 채워져 있다. 커뮤니티 데이터가 0인 건 탈락 사유가 아니다. 오히려 /impact 페이지가 0을 0이라고 보여주는 게 이 서비스가 내세우는 정직성과 맞는다. 그리고 전국 단위 공모전에서 광주 한 동네만 전화로 채우는 시드는 의미가 없다. AI도 이 논리를 듣고 방향을 바꿨어요.
공모전을 준비하는 분들이 자주 하는 오해가 이거라고 생각해요. 사용자 수나 리뷰 수가 있어야 완성된 서비스처럼 보인다는 생각이요. 공고문을 보면 1차 심사 대상은 공사 OpenAPI를 활용해서 개발 완료된 완성 서비스로 한정돼 있고, 배점은 구현성, 기획력, 데이터 활용, 발전성이에요. 사용자 수를 직접 보는 항목은 없습니다. 숫자를 억지로 만들어서 보여주는 순간, 판정을 정직하게 하겠다는 서비스의 주장 자체가 무너진다고 봤어요.
제출, 그리고 지금
관광데이터 활용 공모전 1차 심사 마감은 9월 21일 월요일 16시였어요. 저는 9월 16일에 제출을 끝냈습니다. 공고문에 마감 직전에는 접속자가 몰려 시스템 오류가 날 수 있고 그 불이익은 지원자 책임이라고 적혀 있어서, 처음부터 며칠 여유를 두고 내는 걸 목표로 잡았어요. 1차 서류 제출 때는 최종 팀원 정보를 반드시 입력해야 한다는 조건도 있었는데, 저는 1인이라 이 부분은 간단했습니다.

지금은 결과를 기다리는 중이에요. 공고문 기준으로 구현 부문은 1차 심사 상위 3개 팀이 최종 PT 심사를 보고, 여기서 웹·앱 개발 부문 상위 5개 팀과 통합 심사로 대상을 뽑아요. 최종 발표는 10월 28일로 안내받았습니다. 심사 기간이라 제출한 서비스는 손댈 수 없어서, 그동안은 공모전 이후의 운영 계획을 정리하고 있어요. 1차를 통과하면 그때부터는 짧은 PT 발표 안에 이 서비스가 같은 데이터로 왜 다른 답을 내는지 어떻게 압축해서 보여줄지가 다음 과제가 될 것 같습니다.
혼자 관광데이터 활용 공모전을 준비하며 느낀 점
공모전이 끝나도 PetOK은 접지 않을 생각이에요. 실제 서비스로 운영할 계획이고, 판정 쪽에는 정해진 선택지 중 하나를 신뢰도와 함께 돌려주는 판정 특화 AI를 붙여볼까 검토하고 있습니다. 신뢰도가 낮으면 “확인 필요”로 보내는 구조라, 지금까지 지켜온 원칙과도 잘 맞아요.
일정으로 보면 7월 말 예비심사와 OT를 지나, 8월 초에 API 실사와 로컬 저장 신청, 8월 말에 차별화 재설계, 9월 초에 배포 전 테스트, 9월 16일에 제출까지 7주 남짓이었어요. 혼자서 기획, 데이터 조사, 개발, 인프라, 문서를 다 하기에는 빠듯한 시간이었습니다. 그래도 끝까지 갈 수 있었던 건 매 단계마다 “지금 이걸 하면 심사 점수나 사용자 경험 중 하나라도 실제로 좋아지나”를 물었기 때문이라고 생각해요. 둘 다 아니면 아무리 멋져 보여도 뺐습니다.
돌아보면 이번 관광데이터 활용 공모전에서 제일 많이 한 일은 만드는 것보다 덜어내는 판단이었어요. AI는 아이디어를 끝없이 내줍니다. 그중 무엇을 버릴지는 결국 사람이 정해야 했고, 그 기준이 흔들리지 않게 원칙을 문서로 박아두는 게 1인 개발에서 제일 중요한 작업이었어요. 데이터는 비어 있으면 비어 있다고 말한다, 사용자 요청 경로에서 외부 API를 부르지 않는다, 숫자는 실서버 화면과 맞춘다. 이런 문장들이 기획서보다 오래 일했습니다.
또 하나는 AI와 일하는 방식이에요. AI가 낸 초안이 사실과 다를 때 바로잡을 수 있는 사람은 서비스를 만든 저밖에 없었어요. “관리자 검수”처럼 그럴듯하지만 틀린 문장은 AI가 스스로 찾아내지 못합니다. 문서와 코드는 AI가 빨리 써주지만, 그게 맞는지 판단하는 책임은 끝까지 제 쪽에 남아 있더라고요.
결과가 어떻게 나오든 이번 과정으로 제 서비스 하나가 실제로 돌아가고 있다는 게 제일 큰 수확이에요. 1차 결과가 나오면 그 이야기도 이어서 정리하겠습니다.