# Admin Dashboard 코드 리팩토링 및 버그 수정

**날짜**: 2025-12-25
**작성자**: Auto
**관련 파일**: `admin-dashboard/backend/admin_routes.py`, `admin-dashboard/backend/routers/system.py`, `admin-dashboard/backend/services/system_service.py`, `admin-dashboard/backend/routers/admin_static.py`, `admin-dashboard/frontend/app.js`, `admin-dashboard/frontend/modules/diary.js`

---

## 문제 상황

### 1. Monolithic 코드 구조
- `admin_routes.py`: 1053줄 (FastAPI 원칙 위반: 300줄 이하 권장)
- `app.js`: 1360줄 (React 원칙 위반: 1000줄 이상 리팩토링 필수)
- UI + API + State + Events 모두 혼재

### 2. 로그인 오류
- `app.js:938`: 문자열 결합 문법 오류로 인한 "Invalid or unexpected token" 에러
- 로그인 기능 완전 불가

### 3. 일기 API 경로 매칭 문제
- FastAPI 동적 경로 `/diary/{target_date}`가 `/diary/list`의 "list"를 날짜로 파싱
- 422 Unprocessable Entity 에러 발생

### 4. Gateway 프록시 호환성 문제
- Nginx → Gateway(8100) → 백엔드(8000) 프록시 체인에서 404 에러
- Gateway가 `/api/`를 제거하고 `/admin/diary/list`로 전달하지만 해당 경로 미등록

---

## 해결 방안

### 1. 백엔드 모듈 분리
- **파일**: `admin_routes.py:95-158` → `routers/system.py`, `services/system_service.py`
- 시스템 관리 로직을 router → service 계층으로 분리
- `admin_routes.py`: 1053줄 → 96줄 (인증만 남김)

### 2. 정적 파일 서빙 구조 변경
- **파일**: `routers/admin_static.py` 생성
- Nginx 의존도 감소: FastAPI에서 직접 정적 파일 서빙
- `main.py`에서 라우터 등록 순서 명시 (API 경로 우선, 정적 파일 마지막)

### 3. 프론트엔드 모듈화
- **파일**: `modules/diary.js` 생성
- 일기 관련 로직 분리 (loadDiaryList, loadDiary, renderDiaryList 등)
- `app.js`: 1360줄 → 1132줄

### 4. 로그인 오류 수정
- **파일**: `app.js:938`
- 문자열 결합 문법 오류 수정 (명시적 `+` 연산자 사용)

### 5. 경로 매칭 문제 해결
- **파일**: `routers/system.py:467-488`
- `/diary/list` → `/diaries`로 변경하여 동적 경로와 충돌 방지
- 경로 정의 순서 명시: `/diaries`가 `/diary/{target_date}`보다 먼저 정의

### 6. Gateway 프록시 호환성 확보
- **파일**: `admin_routes.py:99-155`
- `/admin/api/diary/list`와 `/admin/diary/list` 경로 모두 등록
- Gateway가 `/api/`를 제거해도 정상 동작하도록 이중 경로 지원

---

## 구현 완료

- 커밋: `ac96e2a` (2025-12-25)
- TDD 방식으로 진행 (Red → Green → Refactor)
- 브라우저 테스트 완료 (Playwright)
- 통합 검증 완료 (curl)

---

## 교훈

### 리팩토링 시 기존 경로 호환성 유지
- Gateway 프록시 체인에서 경로 변환 발생 (`/admin/api/*` → `/admin/*`)
- 기존 경로와 프록시 경로 모두 등록하여 호환성 확보 필요
- 교훈: 프록시 환경에서는 경로 변환을 고려한 이중 경로 등록 필수

### FastAPI 경로 매칭 순서
- 동적 경로(`{target_date}`)가 구체적 경로(`list`)보다 먼저 매칭될 수 있음
- 구체적 경로를 먼저 정의하거나 경로명 변경으로 충돌 방지
- 교훈: 동적 경로 사용 시 구체적 경로와의 충돌 검토 필수

### 모듈 분리 시 원칙 준수
- FastAPI 구조 원칙: router → service → repository 계층 분리
- React 구조 원칙: 300줄 이상 분리, 1000줄 이상 리팩토링 필수
- 교훈: 원칙 문서(`311_FastAPI_구조_원칙.md`, `313_React_구조_원칙.md`) 참조하여 일관성 유지

---

## 참고

- 계획 문서: `journey/plans/251225_admin_dashboard_code_refactoring.md`
- 원칙 문서: `300_architecture/311_FastAPI_구조_원칙.md`, `300_architecture/313_React_구조_원칙.md`

