저장소(Repository) 운영 전략
웹 서비스의 기획 변경에 유연하게 대응하면서도, 무거운 AI 파이프라인 연구가 웹 개발 속도를 저해하지 않도록 웹(풀스택)과 AI (코어) 저장소를 완벽히 분리하여 운영합니다.
- 웹 풀스택 모노레포 (
lumipet-reid-web)- 프론트엔드(React)와 백엔드(FastAPI)를 하나의 저장소 내 최상위 폴더로 구성
- 단일 커밋/PR 추적 : API 스키마 변경 시 백엔드와 프론트엔드가 동시에 수정되므로 버전 관리 및 히스토리 파악 용이
- 자동화 스크립트 공유 : 백엔드의 OpenAPI 명세를 프론트엔드의 TypeScript 타입으로 즉각 동기화 가능
- AI 코어 독립 저장소 (
lumipet-reid)- 기존에 작성된
ReIdPredictor,ByteTrack등 무거운 파이프라인 코드는 별도 저장소로 유지 - 릴리스 주기 분리 : 웹 서비스 기획 변경과 무관하게 AI 모델 성능 개선 및 실험(wildlife-tools 연동 등) 진행
- 모바일 확장성 : 향후 Android 앱(
lumipet-android)에서 TFLite 모델을 가져갈 때 종속성 꼬임 방지
- 기존에 작성된
- 로컬 패키지 연동 방식 (
pip install -e)- 웹 백엔드 환경에서 AI 코어 저장소를
pip패키지 형태로 가볍게 참조 Submodule방식이 유발하는 버전 충돌 문제를 배제하고 파이썬 생태계 표준 방식 채택
- 웹 백엔드 환경에서 AI 코어 저장소를
graph TD
subgraph Web_Monorepo ["lumipet-reid-web (웹 서비스 주기)"]
BE[Backend: FastAPI]
FE[Frontend: React + Vite]
BE <-->|OpenAPI Type Sync| FE
end
subgraph AI_Core ["lumipet-reid (AI 연구 주기)"]
Core[Re-ID Pipeline \n Megadescriptor, YOLO]
end
subgraph Mobile ["lumipet-android (앱 배포 주기)"]
App[Android App]
end
Core -.->|pip install -e| BE
Core -.->|TFLite Export| App
기술 스택 및 핵심 설계 원칙
FastAPI 백엔드는 도메인 기능별로 코드를 응집시키고 모델 로딩 병목을 해소하며, React 프론트엔드는 서버 상태와 클라이언트 상태를 철저히 분리하여 설계합니다.
- Backend (FastAPI)
- 도메인(Feature) 중심 디렉토리 설계 :
routers,models같은 기술적 분류를 지양하고detection,reid,media등 기능 단위로 폴더 분리 - 모델 로딩 최적화 :
Lifespan컨텍스트 매니저를 사용하여 FastAPI 앱 가동 시 단 한 번만 VRAM에 AI 모델(BasePredictor) 적재 - 비동기/논블로킹 처리 : PyTorch/ONNX의 무거운 동기(Sync) 추론 연산이 이벤트 루프를 막지 않도록
run_in_executor스레드풀 또는BackgroundTasks활용
- 도메인(Feature) 중심 디렉토리 설계 :
- Frontend (React + Vite)
- Feature 기반 컴포넌트 구조 : 백엔드와 동일하게 UI 코드도 도메인 단위로 응집 (
bulletproof-react패턴 적용) - 상태 관리 분리 :
- 서버 상태 :
TanStack Query (React Query)를 활용하여 영상 로딩 상태, 캐싱, 서버 응답 에러 관리 전담 - UI 상태 : 설정 패널 조작, 모달 창 제어 등은
Zustand또는 기본useState사용
- 서버 상태 :
- Feature 기반 컴포넌트 구조 : 백엔드와 동일하게 UI 코드도 도메인 단위로 응집 (
- BE-FE 브릿지 통신
- OpenAPI 타입 동기화 파이프라인 :
openapi-typescript-codegen등 도구를 활용해 Pydantic 모델을 TypeScript 인터페이스로 자동 변환 - 백엔드 스키마 변경 시 프론트엔드 빌드 에러를 유발하여 런타임 사고(화면 렌더링 실패) 원천 차단
- OpenAPI 타입 동기화 파이프라인 :
전체 디렉토리 트리 프로토타입
잦은 기획 변경을 고려하여 처음부터 모든 폴더를 만들지 않고(YAGNI 원칙), 작동하는 최소 단위(MVP) 구성 후 점진적으로 도메인을 확장합니다.
lumipet-reid-web/ (Monorepo Root)
├── README.md
├── docker-compose.yml # 로컬 테스트용 통합 실행 컨테이너 설정
│
├── backend/ # FastAPI 백엔드
│ ├── requirements.txt # (또는 pyproject.toml)
│ └── src/
│ ├── ai/ # ← AI 실행 전담 계층 (HTTP 개념 없음, 순수 Python)
│ │ ├── engine.py # 외부 lumipet_reid 패키지의
│ │ │ # 모델 로드/싱글턴 관리, GPU 디바이스 배치
│ │ ├── inference.py # detect(), extract_embedding(), match()
│ │ │ # 등 순수 함수형 인터페이스
│ │ └── config.py # 가중치 경로, threshold 등 AI 전용 설정값
│ ├── main.py # Lifespan 모델 로딩 및 라우터 통합
│ ├── core/ # 앱 전역 설정, lifespan(ai.engine 로드 호출 지점), 로깅
│ ├── media/ # 도메인 1: 입출력 영상/이미지 파일 관리
│ │ ├── router.py
│ │ ├── service.py
│ │ └── schemas.py
│ │
│ └── reid/ # 도메인 2: Re-ID 추론 로직
│ ├── router.py
│ ├── service.py # run_in_executor 비동기 처리,
│ │ # ai.inference 호출 + 매칭 임계값 등 "제품 로직" 처리
│ └── schemas.py
│
└── frontend/ # React + Vite 프론트엔드
├── package.json
├── openapi.json # 백엔드에서 추출된 API 명세서
└── src/
├── App.tsx
├── api/ # 자동 생성된 TS 클라이언트 코드
├── components/ # 공통 UI 컴포넌트 (버튼, 모달 등)
└── features/ # 도메인별 컴포넌트 및 로직
├── upload/ # 영상 업로드 기능
└── viewer/ # BBox 오버레이 및 결과 캔버스 렌더링
C
Contents
