Personal Photo Archive

eat — 매일의 맛 기록

A personal food-photo blog that files 1,000+ photos taken daily over the years into a gallery, a timeline, and a map using nothing but EXIF time and GPS.

PersonalDuration 2wContribution 100%2026-072026-08
Key Metric: 1,000+ photos organized by EXIF alone · fully working locally with zero API keys
Engineering Role
Fullstack
Personal Photo Archive
eat — 매일의 맛 기록
WEB
#Web#Frontend#Backend#Personal

Overview

The photos are the point, so there is almost no writing. The admin bulk-uploads, EXIF fills in time and coordinates automatically, and a Tinder-style review queue only adds a suggested place, a comment, a price, and a rating before publishing. Local development needs zero external API keys — a SQLite file, local disk media, and keyless map tiles — and Turso, R2, and Kakao/Naver place search switch on with .env values alone.

My Work

  • Next.js 16 App Router + Drizzle/libSQL schema · measured photo-query indexes
  • exifr split between server and client — initial EXIF chunk 95.9 KB → 71.9 KB
  • Direct staged uploads to R2 · unpublished originals protected · 25 MB / 60 MP input limits
  • Trusted-origin checks on every admin mutation · streamed JSON limits · security headers
  • Consent-gated GA4 · branded error and empty states · accessibility pass

Features

  • 4-column 9:16 infinite-scroll gallery · rating filter · lightbox
  • Year-month timeline modeled on the Instagram story archive
  • MapLibre GL + supercluster map with photo-thumbnail markers
  • Private admin — bulk upload → EXIF auto-tagging → review queue → batch assign + publish
  • Kakao / Naver place-search adapters with Nominatim fallback · 7-day cache
  • Dynamic OG images · sitemap images · RSS · JSON-LD · IndexNow · llms.txt

Highlights

  • Gallery / year-month timeline / clustered map built from EXIF time and GPS only
  • sharp generates thumb, md, lg WebP variants plus a blur placeholder on upload
  • Fully working locally with zero external keys — SQLite, local media, keyless tiles
  • 113 tests across 24 files · zero known production-dependency vulnerabilities

Timeline

2026-072026-08
Role: Full-stack, solo
Contribution: 100%
Collaboration: Personal

Tech Stack

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

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