koriweb 8a8c10248c Initial commit: AI Photo Organizer (Electron + face-api)
Local-first photo organizer that auto-sorts images by face recognition
and EXIF capture date.

- Electron app with 3-process split: Main (Node) / UI Renderer (React) /
  hidden Inference Renderer (face-api + WebGL)
- Core pipeline: scan -> face match + EXIF -> path build -> atomic move/copy
- Move = copy -> verify -> delete; auto-rename on filename collision
- 1st-registered profile = move, others = copy; unmatched -> [미정]/YYYY/MM
- EXIF date with mtime fallback
- Vitest unit tests (pathBuilder / fileOps / concurrency) all green
- electron-builder config for Windows (nsis) + macOS (dmg)
- Docs: PRD / DECISIONS / ARCHITECTURE

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 13:36:40 +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순위 인물에게는 복사)
    • 매칭 인물이 없으면 출력/[미정]/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%