koriweb d2546f9cbf Library workspace upgrades: darkroom viewer, mosaic, geotagging, file explorer
- darkroom-style fullscreen viewer: left info panel, rating/color-label toolbar,
  bottom filmstrip, keyboard nav (Esc / arrows), placeholder on load failure
- thumbnail density slider (contact-sheet) + photo mosaic generator (target -> tiles)
- lighttable-style hover info preview (no click needed)
- map drag & drop geotagging (saved to index only; originals untouched)
- file explorer: parallel drive scan + timeout, create/delete(trash)/move folders;
  index reparent on move and cleanup on delete (single source of truth)
- library: photos-before-videos ordering; drag range select/deselect;
  native image drag disabled so sweep-select works
- responsive sidebar font scaling; no-wrap filter labels; media protocol CORS + video Range

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 14:47:26 +09:00

AI Photo Organizer

얼굴 인식 + 촬영일(EXIF) 기준으로 사진을 로컬에서 자동 정리하는 Electron 데스크톱 앱. 클라우드 업로드 없이 내 PC 안에서만 동작한다.

기획·설계 문서: docs/PRD.md · docs/DECISIONS.md · docs/ARCHITECTURE.md

동작 방식

  1. 인물 프로필(최대 3명)과 참조 얼굴 사진을 등록한다.
  2. 정리할 폴더(소스)와 결과 폴더(출력)를 고른다.
  3. [정리 시작] → 각 사진을 스캔해
    • 얼굴이 매칭되면 출력/<인물>/YYYY/MM/이동(2·3순위 인물에게는 복사)
    • 매칭 인물이 없으면 출력/Unsorted/YYYY/MM/ 로 이동
    • 영상 파일(.mp4 .mov .avi .mkv .webm .m4v)은 얼굴인식 없이 출력/Movie/YYYY/MM/ 로 이동
    • EXIF 촬영일이 없으면 파일 수정일로 대체

데이터 안전: 이동은 복사 → 무결성 검증 → 원본 삭제 순서로 수행하고, 파일명 충돌 시 _1, _2 로 자동 리네임한다(덮어쓰기 없음).

기술 스택

Electron 33 · electron-vite · React 18 + TypeScript · Zustand · Tailwind · @vladmandic/face-api (WebGL) · exifr · electron-builder

3개 프로세스로 분리된 구조:

  • Main (Node): 스캔 / EXIF / 파일 이동·복사 / 오케스트레이션
  • UI Renderer (React): 화면 — 무거운 연산 없음
  • Inference Renderer (숨김 창): face-api 얼굴 인식 전담

개발

npm install
npm run models:download   # 최초 1회 — 모델 가중치 받기
npm run dev               # 개발 실행 (HMR)

검증 / 빌드

npm run typecheck         # 타입체크 (node + web)
npm test                  # 순수 로직 단위 테스트 (Vitest)
npm run dist:all          # Windows(nsis) + macOS(dmg) 인스톨러 빌드

macOS 타깃은 macOS 호스트에서 빌드해야 코드사이닝/공증이 가능하다(미서명 dmg는 어디서나 생성 가능).

트러블슈팅

  • TypeError: Cannot read properties of undefined (reading 'whenReady') 로 부팅 즉시 크래시하면, 환경에 ELECTRON_RUN_AS_NODE=1 이 설정된 것이다. 이 변수가 있으면 Electron 바이너리가 일반 Node로 동작해 electron.appundefined 가 된다. 실행 전 변수를 해제하라:
    • PowerShell: Remove-Item Env:\ELECTRON_RUN_AS_NODE
    • bash: unset ELECTRON_RUN_AS_NODE

폴더 구조

src/
  main/        Main 프로세스 (scanner, exif, fileOps, orchestrator, ...)
  preload/     contextBridge (UI용 index, 추론창용 inference)
  renderer/    React UI
  inference/   숨김 추론 창 (faceEngine, imageLoader)
  shared/      공유 타입/상수
models/        face-api 가중치 (download 스크립트로 채움)
tests/         Vitest 단위 테스트
docs/          기획·설계 문서
S
Description
사진정리 프로그램
Readme 421 KiB
Languages
TypeScript 97%
JavaScript 2.2%
CSS 0.6%
HTML 0.2%