안드로이드 · 웹 · 토스 미니앱 · 위치 기반 기록

피그노트 — 장소에 남긴 추억을 먹고 자라는 피그

사진과 메시지를 장소에 포스트잇처럼 붙여 두면, 그 자리에 실제로 가야만 열립니다. 기록하고 발견할수록 캐릭터 '피그'가 자라고, 같은 Flutter 코드가 안드로이드 앱·웹·토스 미니앱 세 곳으로 함께 나갑니다.

피그노트 지도·포스트잇 상세·피그룸 화면
왼쪽부터 지도(주변 포스트잇 찾기) — 발견한 포스트잇 — 피그룸(성장)

서비스 소개

피그노트는 장소에 묶인 메시지를 다룹니다. 사진 한 장과 짧은 글, 스티커를 지금 서 있는 자리에 붙여 두면 그 좌표에 포스트잇이 남습니다. 다른 사람은 링크를 눌러서가 아니라 그 자리에 실제로 걸어 들어가야 내용을 볼 수 있습니다. 열람 반경은 남긴 사람이 30~500m 사이에서 정하고, 반경 밖에서는 작성자와 장소 이름, 잠긴 상태만 보입니다.

여기에 시간이 한 겹 더 붙습니다. 타임캡슐을 걸면 정해둔 시각 전에는 반경 안에 있어도 열리지 않고, 공개 포스트잇은 기본 30일이 지나면 지도에서 사라집니다. 공개 범위는 전체 공개·친구 공개·나만 보기 세 가지이고, 답장 포스트잇을 허용할지도 글마다 고를 수 있습니다.

혼자 쓰면 장소에 붙이는 일기가 되고, 친구를 맺으면 같은 동네에 서로 쪽지를 숨겨 두는 놀이가 됩니다. 친구는 앱이 발급한 친구 코드로 상호 승인해야 맺어지고, 차단과 신고 기능도 갖췄습니다.

기록하면 피그가 자랍니다

앱을 계속 쓰게 만드는 장치는 랭킹이 아니라 캐릭터입니다. 포스트잇을 남기면 20 XP, 처음 가 본 장소면 15 XP가 더 붙고, 남의 포스트잇을 발견하면 10 XP, 반응과 댓글은 5 XP, 날마다 이어 기록하면 10 XP가 더해집니다. 이 경험치를 피그가 '추억'으로 받아먹고 자랍니다.

레벨은 30단계까지 있고, 몸은 아기 피그 → 통통 피그 → 여행 피그 → 추억 수집가 → 마스터 다섯 단계로 바뀝니다. 레벨이 하나 오를 때마다 눈에 보이는 변화가 반드시 하나씩 생기도록 만들었습니다 — 발밑에 추억 조각이 쌓이거나, 몸에 표식이 생기거나, 모자·가방·안경 같은 옷장 아이템이 해금됩니다. 5·10·20·30 레벨에서는 조각들이 모여 다음 단계의 실루엣을 예고하는 전환 연출이 들어갑니다. 배지는 7종이고, 피그가 사는 방도 성장에 따라 함께 꾸며집니다.

사물 앵커 — 카메라로 찾는 포스트잇

좌표만으로는 "이 골목 어딘가"까지가 한계입니다. 그래서 사물로 숨기기를 넣었습니다. 글을 쓸 때 그 자리의 사물을 카메라로 찍어 두면(갤러리 선택은 막습니다 — 지금 이곳의 사물이어야 하니까요), 읽는 사람은 반경 안에 들어온 뒤 같은 사물을 카메라로 비춰야 잠금이 풀립니다. 힌트는 30자까지 남길 수 있습니다.

판정은 앱이 아니라 서버가 합니다. 사물 사진은 Vertex AI multimodalembedding@001로 512차원 임베딩을 떠서 저장하고, 발견 시도 때 올라온 사진과의 코사인 유사도가 임계값을 넘어야 열립니다. 임베딩 리전은 서울(asia-northeast3)이라 사진이 국외로 나가지 않고, 열람자가 찍은 스캔 사진은 판정 직후 지웁니다.

안드로이드에서는 여기에 ARCore 이미지 추적을 얹어, 카메라 화면 위에서 사물을 인식하면 메시지가 그 자리에 떠오르도록 만들었습니다. ARCore가 없는 기기와 웹·토스에서는 1.5초 간격 실시간 스캔으로 같은 판정 경로를 탑니다. 처음부터 AR로 만들지 않은 이유도 여기 있습니다 — 세 타깃에서 같은 동작이 나와야 했고, ARCore는 안드로이드 전용, WebXR은 토스 웹뷰에서 보장되지 않기 때문입니다.

세 타깃이 한 몸입니다

같은 Flutter 코드가 안드로이드 APK · 웹(Firebase Hosting) · 토스 미니앱 세 곳으로 나갑니다. 한 타깃만 고치면 사용자마다 다른 앱을 쓰게 되므로, 릴리스는 세 타깃을 같은 버전으로 한 번에 내보내는 것을 규칙으로 두었습니다.

차이가 나는 지점은 플랫폼 분기 파일로 격리했습니다. 지도는 안드로이드에서 네이버 지도를 쓰고, 이 SDK가 웹을 지원하지 않아 웹 빌드는 OpenStreetMap 타일로 대체합니다. 토스 미니앱에서는 앱인토스 SDK가 위치와 공유를 대신 처리하고 구글 로그인 버튼을 숨깁니다. 계정은 기기 ID로 만드는 익명 계정이 기본이고, 구글 계정을 연결하거나 기기 연결 코드를 쓰면 토스·안드로이드·웹의 기록과 피그가 한 계정으로 묶입니다.

기술적 접근

백엔드는 Fastify와 Prisma로 짜서 GCP Cloud Run에 올렸고, 데이터베이스는 클라우드가 아니라 집에 둔 홈랩 PostgreSQL을 씁니다. Cloud Run 컨테이너에 cloudflared 사이드카를 붙여 Cloudflare 터널로 접속하는 구조입니다. 업로드된 사진은 GCS 버킷에 두고, 열람 권한이 확인된 사용자에게만 짧은 유효기간의 서명 URL로 내려보냅니다.

위치는 앱을 쓰는 동안에만 받고 백그라운드 추적은 하지 않습니다. 지도에 그리는 좌표는 약 30m 격자로 흐려서 표시하고, 실시간 위치는 누구에게도 공개하지 않습니다. 사진은 올리기 전에 EXIF의 GPS 메타데이터를 지웁니다. 반경 안에 들어왔는지는 앱이 아니라 서버가 다시 검증합니다 — 클라이언트가 보낸 좌표를 그대로 믿으면 앉은 자리에서 남의 포스트잇을 열 수 있기 때문입니다.

서버에 닿지 못하면 앱은 로컬 저장소만으로 계속 동작하고, 연결이 돌아오면 기기 ID로 자동 로그인해 동기화합니다. 화면 회귀는 골든 테스트로 잡는데, 시각이 흔들리면 골든도 흔들리므로 화면에 보이는 시각 계산은 DateTime.now() 대신 고정할 수 있는 appNow()를 거치도록 통일했습니다.

주요 기능

edit_location_alt 장소에 포스트잇 — 사진·글·스티커, 열람 반경 30~500m, 답장 허용 선택
lock_open_right 반경 안에 들어가야 열림 — 잠긴 사유(반경 밖·위치 없음·타임캡슐)를 구분해 안내
center_focus_strong 사물 앵커 — 카메라로 같은 사물을 비춰야 열리는 숨기기, 안드로이드는 ARCore 오버레이
hourglass_top 타임캡슐 · 만료 — 정해둔 시각 전엔 열리지 않고, 공개 글은 기본 30일 뒤 사라짐
pets 피그 성장 — XP·30레벨·5단계 키프레임, 옷장 아이템과 배지 7종, 피그룸 꾸미기
group 친구 코드 · 상호 승인 — 친구 공개 범위, 차단·신고, 감정 스티커 반응 5종과 댓글
blur_on 좌표 흐림 30m 격자 — 실시간 위치 비공개, 백그라운드 위치 미사용, 사진 EXIF 제거
devices 세 타깃 한 계정 — 안드로이드·웹·토스 미니앱을 구글 계정이나 연결 코드로 묶기

화면 갤러리

화면은 로그인하지 않고 위치 권한도 주지 않은 상태에서 캡처한 것이라, 잠긴 포스트잇과 위치 안내 문구가 함께 보입니다.

약관 및 정책

피그노트는 위치와 사진을 다루는 앱이라, 무엇을 받고 무엇을 받지 않는지 문서로 분명히 두었습니다.

피그노트 앱 아이콘
피그노트
org.j2w2.pignote

프로젝트 정보

분류 위치 기반 소셜 기록 앱
타깃 안드로이드 앱 · 웹 · 토스 미니앱
권한 위치(앱 사용 중에만) · 카메라(사물 앵커)
Flutter, Dart, Riverpod, go_router
지도 네이버 지도(모바일), OpenStreetMap(웹)
Backend Node.js, Fastify, Prisma, PostgreSQL
Infra GCP Cloud Run, GCS, Cloudflare 터널, Firebase Hosting
주요 기술
Vertex AI 임베딩 ARCore Apps-in-Toss SDK 골든 테스트