6dce580846
Feature work on top of the initial organizer: - Videos: .mp4/.mov/.avi/.mkv/.webm/.m4v sorted into output/Movie/YYYY/MM - Profiles: reference-image thumbnail cards via a secure photoai-media:// protocol (serves only registered reference images); per-thumbnail delete; add via click, drag & drop, or paste (Ctrl+V) using webUtils.getPathForFile + a byte-based addReferenceData path for clipboard images - Presets: local person library (max 5) saved to userData; one-click apply into active profiles; reusing stored descriptors (no recompute) - Theme: dark/light with dark default (Tailwind class strategy) - i18n: ko/en table-based localization; first-run onboarding to pick language + theme; English-neutral "Unsorted" folder (was [미정]) - App menu: File/Edit/View/Window/Help, localized; Help opens a detailed, theme-aware user guide window - UI: History block scrolls internally (no whole-window scroll); threshold/concurrency tooltips; generic example name - Settings persisted to userData/settings.json; menu + renderer kept in sync - Docs: NextGen Photo AI feasibility review + Phase 0/1 roadmap All typecheck/tests (12) /build green; boot smoke verified. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2.9 KiB
2.9 KiB
AI Photo Organizer
얼굴 인식 + 촬영일(EXIF) 기준으로 사진을 로컬에서 자동 정리하는 Electron 데스크톱 앱. 클라우드 업로드 없이 내 PC 안에서만 동작한다.
기획·설계 문서: docs/PRD.md · docs/DECISIONS.md · docs/ARCHITECTURE.md
동작 방식
- 인물 프로필(최대 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.app이undefined가 된다. 실행 전 변수를 해제하라:- PowerShell:
Remove-Item Env:\ELECTRON_RUN_AS_NODE - bash:
unset ELECTRON_RUN_AS_NODE
- PowerShell:
폴더 구조
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/ 기획·설계 문서