Personal Photo Archive

eat — 매일의 맛 기록

수년간 매일 찍은 1,000장+ 음식 사진을 EXIF 촬영 시각·GPS만으로 갤러리·타임라인·지도에 자동 배치하는 개인 푸드 포토 블로그.

개인기간 2주기여도 100%2026-072026-08
핵심 지표: 사진 1,000장+ EXIF 자동 정리 · 외부 API 키 0개로 로컬 풀 동작
엔지니어링 역할
Fullstack
Personal Photo Archive
eat — 매일의 맛 기록
WEB
#Web#Frontend#Backend#Personal

개요

사진이 주인공이라 글은 거의 없다. 관리자가 사진을 대량으로 올리면 EXIF에서 시각·좌표를 뽑아 자동 태깅하고, 틴더식 리뷰 큐에서 장소 추천·코멘트·가격·평점만 붙여 발행한다. 로컬 개발은 SQLite 파일 DB + 로컬 디스크 미디어 + 키리스 지도 타일로 외부 API 키가 하나도 필요 없고, Turso·R2·카카오/네이버 장소 검색은 .env 값만 바꾸면 켜진다.

내가 한 작업

  • Next.js 16 App Router + Drizzle/libSQL 스키마 · 측정 기반 사진 쿼리 인덱스
  • exifr 서버/클라이언트 분리 — 초기 EXIF 청크 95.9KB → 71.9KB
  • R2 직접 스테이지드 업로드 · 미발행 원본 보호 · 25MB/60MP 입력 상한
  • 관리자 변경 전부 trusted-origin 검사 · 스트리밍 JSON 한도 · 보안 헤더
  • 동의 게이트 GA4 · 브랜드 에러/빈 상태 · 접근성 패스

주요 기능

  • 9:16 세로 사진 4열 무한 스크롤 갤러리 · 평점 필터 · 라이트박스
  • 인스타 스토리 보관함식 연·월 타임라인
  • MapLibre GL + supercluster 사진 썸네일 마커 지도
  • 비공개 관리자 — 대량 업로드 → EXIF 자동 태깅 → 리뷰 큐 → 일괄 장소 지정·발행
  • 카카오/네이버 장소 검색 어댑터 + Nominatim 폴백 · 7일 캐시
  • 동적 OG 이미지 · 사이트맵 이미지 · RSS · JSON-LD · IndexNow · llms.txt

핵심 포인트

  • EXIF 시각·GPS만으로 갤러리 / 연·월 타임라인 / 클러스터 지도 자동 구성
  • 업로드 시 sharp로 thumb·md·lg WebP + 블러 플레이스홀더 생성
  • 외부 키 0개로 로컬 풀 동작 — SQLite · 로컬 미디어 · 키리스 타일
  • 113 테스트(24 파일) · 프로덕션 의존성 취약점 0

타임라인

2026-072026-08
역할: 풀스택 단독 개발
기여도: 100%
협업: 개인

기술 스택

</>Next.js 16 · Drizzle + SQLite · sharp · exifr · MapLibre

Next.js 16React 19TypeScriptTailwind CSS 4Drizzle ORMSQLite (libSQL)sharpexifrMapLibre GLsuperclusterjoseVitest