# 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`