← GHMUN.COM
자연생태 · 제작기

서울 수달 지도

서울 수달 지도를 만들어달라고 했다. 정확히는, 지도와 데이터는 이미 다른 데서 만들어져 있었고 — 그걸 실제로 인터넷에 띄우고, 시민 제보와 관리자 검수까지 진짜로 돌아가게 만들라는 요청이었다. 파일 하나로 돌아가던 로컬 버전을 GitHub, Vercel, Supabase, 구글 로그인이 실제로 맞물려 돌아가는 서비스로 바꾸는 작업이었다. 단계를 하나씩 나눠서 진행했는데, 뒤로 갈수록 코드보다 계정과 설정을 맞추는 일이 더 많았다.

캐치올인 줄 알았는데 아니었다

API 라우트를 api/[...path].js 파일 하나로 짜놨다. Next.js에서는 이게 /api/ 밑의 모든 경로를 다 받아주는 캐치올 패턴이다. 그런데 이 프로젝트는 Next.js가 아니라 순정 Vercel 서버리스 함수였고, 여기서는 [...path]를 캐치올이 아니라 세그먼트 하나로만 받는다. 그 결과 /api/health처럼 한 단계짜리 경로만 살아있고, /api/observations/public이나 /api/auth/me처럼 두 단계 이상인 경로는 전부 플랫폼 단에서 404가 났다. API 대부분이 여기 해당했다. api/handler.js로 바꾸고 vercel.json에 /api/(.*) → /api/handler 리라이트를 따로 걸어서 고쳤다.

토큰을 브라우저에 노출시켜놨다는 지적을 받았다

관리자 기능을 처음엔 ADMIN_TOKEN 값 하나로 열었다. 이 값이 브라우저까지 내려간다는 지적을 받고, 구글 계정으로 로그인한 뒤 그 이메일이 허용 목록에 있는지 서버가 매번 확인하는 방식(OIDC)으로 바꿨다. 다만 실제 구글 OAuth 클라이언트 등록은 아직 끝나지 않아서, 이 글을 쓰는 시점에 관리자 로그인은 완전히 켜져 있지 않다.

지도 타일 키도 같은 이유로 옮겼다

지도 배경 타일은 CARTO에서 받아온다. 처음엔 API 키를 소스코드에 그대로 넣어놨다. 이것도 지적받고 Vercel 환경변수로 옮겼다 — 코드에는 carto_api_key라는 이름만 남고, 값은 서버 설정에서 읽어온다. 그런데 코드를 옮긴 것과 그 환경변수에 실제 값을 채워 넣는 건 별개 작업이다. 지금 Vercel 프로덕션에는 이 값이 아직 없다. 그래서 지도를 열면 타일 대신 CARTO가 붙이는 "API KEY REQUIRED" 워터마크가 화면 전체에 깔린다. 지도가 이 서비스의 전부인데, 이 부분은 아직 못 끝냈다.

파이썬이 없는 서버라 사진 처리를 통째로 바꿨다

제보 사진을 다듬는 코드는 원래 python3와 Pillow를 서브프로세스로 불러 쓰는 방식이었다. 서버리스 실행 환경에는 파이썬이 없다. 그래서 이 부분을 Node.js 패키지인 sharp로 다시 짰다. 바꾸는 김에 업로드한 사진이 photo_assets 테이블에 실제로는 기록되지 않는 버그도 같이 찾았다 — 실제 PostgreSQL을 붙이면 외래키 위반으로 바로 터졌을 문제다. 로컬 테스트 단계에서 미리 잡았다.

아직 안 끝난 것들은 숨기지 않고 목록으로 남겨뒀다

지금 구글 로그인이랑 지도 타일 키 말고도 남은 일이 몇 개 더 있다. 관리자 API에 걸어야 할 공용 요청 제한(Redis 기반), 업로드 사진을 악성 파일인지 검사하는 절차, 장애가 났을 때 알림을 받는 모니터링, 실제 브라우저로 제보·로그인·검수를 처음부터 끝까지 눌러보는 점검 — 이 네 가지는 아직 안 했다. 다 됐다고 보고하는 대신 인수인계 문서에 "여기까지 했고, 여기부터는 안 했다"고 그대로 적어뒀다. 어설프게 됐다고 하는 것보다는 이쪽이 나중에 시간을 덜 잡아먹는다.

사용법: 필터 네 개를 겹쳐 쓰는 지도

왼쪽 패널에서 연도(2016·2017·2022·2026), 기록 종류(전체·DNA·카메라), 성별, 가족(F01~F05)을 각각 고를 수 있고 넷 다 동시에 켤 수 있다. 그 아래 목록에는 성내천·한강대교·잠실대교 같은 지점별 확인 개체 수가 나온다. 우측 "THE OTTER STORY" 버튼을 누르면 연도별 서사로, 상단 "수달 제보" 버튼을 누르면 시민이 직접 목격 기록을 올리는 화면으로 넘어간다. "검수"는 관리자용이라 지금은 로그인이 걸려 있지 않다.

서울 수달 지도 실제로 써보기 sudal.ghmun.com 가기 →