# MongolCar 프로젝트 통합 진행 보고서 > 마지막 업데이트: 2025-12-07 --- ## 목차 1. [프로젝트 개요](#1-프로젝트-개요) 2. [서버 인프라](#2-서버-인프라) 3. [MongolCar 플랫폼](#3-mongolcar-플랫폼) 4. [Carmodoo Agent](#4-carmodoo-agent) 5. [Grantech 사이트](#5-grantech-사이트) 6. [파일 서버](#6-파일-서버) 7. [작업 일지](#7-작업-일지) 8. [해결된 기술적 이슈](#8-해결된-기술적-이슈) 9. [TODO 목록](#9-todo-목록) 10. [계정 정보](#10-계정-정보) 11. [명령어 참고](#11-명령어-참고) --- ## 1. 프로젝트 개요 몽골 중고차 수출 플랫폼 (MongolCar) 개발 프로젝트 - 한국 중고차 딜러 시스템(카모두)에서 차량 데이터 추출 - 몽골 바이어에게 차량 정보 제공 - 수출 프로세스 관리 (컨테이너, 선적, 통관 등) - 다국어 지원 (한국어, 영어, 몽골어, 러시아어) - CC 코인 시스템 (차량 상세정보 조회용) --- ## 2. 서버 인프라 ### 2.1 서버 구성 | 서버 | IP | CPU | RAM | SSD | 역할 | 상태 | |------|-----|-----|-----|-----|------|------| | Server1 | 192.168.0.201 | Ryzen 7700 | 64GB | 2TB | Master (DB, Proxy, Monitoring) | ✅ 완료 | | Server2 | 192.168.0.202 | Ryzen 7700 | 64GB | 1TB | MongolCar (autonetsellcar.com) | ✅ 완료 | | Server3 | 192.168.0.203 | Ryzen 7700 | 64GB | 1TB + 10TB HDD | Grantech, 파일서버 | ✅ 완료 | ### 2.2 운영 사이트 | 도메인 | 용도 | 서버 | 상태 | |--------|------|------|------| | https://autonetsellcar.com | 몽골 중고차 수출 플랫폼 | Server2 | ✅ | | http://grantech.kr | Grantech 기업 사이트 | Server3 | ✅ | | http://api.grantech.kr | Grantech API | Server3 | ✅ | | http://cloud.grantech.kr | Nextcloud 파일 서버 | Server3 | ✅ | ### 2.3 Server1 (Master) 설치된 서비스 | 서비스 | 포트 | 용도 | 접속 URL | |--------|------|------|----------| | Nginx Proxy Manager | 80, 443, 81 | 리버스 프록시, SSL | http://192.168.0.201:81 | | PostgreSQL | 5432 | 데이터베이스 | - | | Redis | 6379 | 캐시/세션 | - | | Portainer | 9000 | Docker 관리 | http://192.168.0.201:9000 | | Prometheus | 9090 | 메트릭 수집 | http://192.168.0.201:9090 | | Grafana | 3100 | 모니터링 대시보드 | http://192.168.0.201:3100 | ### 2.4 생성된 데이터베이스 - `mongolcar` - MongolCar 서비스용 - `grantech` - Grantech 서비스용 - `cylinx` - Cylinx 서비스용 ### 2.5 네트워크 구성 ``` 공인 IP: 59.14.158.123 도메인: grantech.kr (기존), autonetsellcar.com (신규) SSH 포트포워딩: - grantech.kr:201 → 192.168.0.201:22 (Server1) - grantech.kr:202 → 192.168.0.202:22 (Server2) - grantech.kr:203 → 192.168.0.203:22 (Server3) 웹 포트포워딩: - 80 → 192.168.0.201:80 - 443 → 192.168.0.201:443 - 81 → 192.168.0.201:81 ``` --- ## 3. MongolCar 플랫폼 ### 3.1 기술 스택 **Backend:** - Python 3.11 - FastAPI - SQLAlchemy (ORM) - Pydantic (검증) - SQLite (개발) / PostgreSQL (운영) **Frontend:** - Next.js 14 (App Router) - TypeScript - Tailwind CSS - Zustand (상태관리) - Axios (HTTP 클라이언트) ### 3.2 주요 기능 #### 다국어 지원 (i18n) - 한국어 (ko) - 영어 (en) - 몽골어 (mn) - 러시아어 (ru) #### CC 코인 시스템 - 신규 가입 시 3 CC 무료 지급 - 1 USDC = 10 CC - 차량 상세정보 조회: 1 CC - 무료 미리보기: 사진 2장 #### 차량 요청 검색 기능 (2025-12-07 구현) 카모두 스타일 확장 필터: - 제조사 - 모델 - 등급(그레이드) - 연식 (시작 ~ 종료) - 주행거리 (만km 단위) - 가격 (만원 단위) - 연료 (가솔린, 디젤, 하이브리드, 전기, LPG) - 변속기 (자동, 수동, 세미오토, CVT) 검색 시 10초 대기 + 진행률 표시 후 결과 표시 #### 가격 마진 계산 - 한국 딜러 마진: 5% - 몽골 딜러 마진: 5% (한국 마진 적용 후) - 총 마크업: 약 10.25% ### 3.3 API 엔드포인트 ``` GET /api/cars/ # 차량 목록 GET /api/cars/{id} # 차량 상세 POST /api/cars/ # 차량 등록 PUT /api/cars/{id} # 차량 수정 DELETE /api/cars/{id} # 차량 삭제 GET /api/cars/makers/ # 제조사 목록 GET /api/cars/models/ # 모델 목록 POST /api/auth/register # 회원가입 POST /api/auth/login # 로그인 GET /api/auth/me # 내 정보 POST /api/inquiries/ # 문의 등록 GET /api/inquiries/ # 문의 목록 GET /api/carmodoo/makers # 카모두 제조사 목록 GET /api/carmodoo/models/{code} # 카모두 모델 목록 GET /api/carmodoo/grades # 등급 목록 GET /api/carmodoo/request-search # 차량 요청 검색 (마진 포함) GET /api/cc/balance # CC 잔액 조회 POST /api/cc/purchase-view # 차량 상세정보 구매 GET /api/cc/check-view/{car_id} # 구매 여부 확인 GET /api/hero-banners # 히어로 배너 목록 GET /api/translations # 번역 데이터 ``` ### 3.4 페이지 구성 ``` / # 홈페이지 (히어로 슬라이더, 최신 차량) /cars # 차량 목록 (필터, 페이지네이션) /cars/[id] # 차량 상세 (CC 결제 시스템) /request # 차량 요청 검색 (확장 필터) /login # 로그인 /register # 회원가입 /admin # 관리자 대시보드 /admin/cars # 차량 관리 /admin/hero-banners # 히어로 배너 관리 /admin/translations # 번역 관리 ``` ### 3.5 데이터베이스 모델 - User (사용자) - cc_balance 포함 - CarMaker (제조사) - CarModel (모델) - Car (차량) - CarImage (차량 이미지) - CarOption (차량 옵션) - CarView (구매한 차량 조회 기록) - Inquiry (문의) - HeroBanner (히어로 배너) - Translation (번역) --- ## 4. Carmodoo Agent ### 4.1 프로젝트 구조 ``` agent/ ├── config.yaml # 설정 파일 ├── .env # 환경 변수 (로그인 정보) ├── requirements.txt # Python 의존성 ├── run_agent.py # 실행 스크립트 ├── src/ │ ├── config.py # 설정 관리 │ ├── logger.py # 로깅 설정 │ ├── carmodoo_client.py # 카모두 API 클라이언트 (핵심) │ ├── api_client.py # MongolCar 서버 API 클라이언트 │ ├── agent.py # 메인 에이전트 클래스 │ └── main.py # CLI 엔트리포인트 ├── data/ │ └── makers.json # 제조사/모델 데이터 (154개 제조사) └── logs/ # 로그 파일 ``` ### 4.2 구현된 기능 1. **로그인**: 카모두 딜러 시스템 인증 2. **제조사/모델 조회**: 154개 제조사, 각 제조사별 모델 목록 3. **차량 상세 조회**: 암호화 키 기반 차량 정보 조회 4. **이미지 다운로드**: 차량 이미지 일괄 다운로드 5. **세션 유지**: 자동 세션 갱신 ### 4.3 카모두 API 엔드포인트 | 엔드포인트 | 용도 | |-----------|------| | `POST /member/login_ok.html` | 로그인 | | `POST /common/ajax/sessionHold.html` | 세션 유지 | | `GET /common/ajax/AutoDBCode.html` | 제조사/모델 코드 | | `GET /common/ajax/AutoDBProc.html` | 차량 목록 | | `GET /common/ajax/AutoDB.html` | 차량 상세 | | `GET /data/__carPhoto/{path}` | 차량 이미지 | ### 4.4 이미지 URL 패턴 ``` http://dealer.carmodoo.com/data/__carPhoto/{3자리}/{3자리}/{3자리}/cmcar_{순번}.jpg 예: 차량번호 6320434 → /006/320/434/cmcar_0.jpg ``` ### 4.5 CLI 명령어 ```bash # 연결 테스트 python run_agent.py test # 제조사/모델 목록 가져오기 python run_agent.py fetch-makers -o ./data/makers.json # 차량 상세 정보 조회 python run_agent.py get-detail "ENCRYPTED_KEY" # 차량 이미지 다운로드 python run_agent.py download-images 6320434 -o ./downloads --max 20 # 에이전트 실행 (서버 연동) python run_agent.py run ``` --- ## 5. Grantech 사이트 ### 5.1 Server3 설정 - **운영체제**: Ubuntu 22.04.5 Server - **호스트명**: server3 ### 5.2 설치된 서비스 | 서비스 | 포트 | 용도 | |--------|------|------| | Grantech Frontend | 3001 | Next.js 웹사이트 | | Grantech Backend | 8001 | FastAPI REST API | ### 5.3 접속 URL | 서비스 | URL | |--------|-----| | Grantech 웹사이트 | http://grantech.kr | | Grantech API | http://api.grantech.kr | | Grantech Admin | http://grantech.kr/admin/login | --- ## 6. 파일 서버 ### 6.1 아키텍처 ``` Server3 (192.168.0.203) - 파일 서버 │ ├── 10TB HDD (/dev/sda1 - XFS) │ Mount: /data │ ├── /data/share (공용폴더, 777 권한) │ └── /data/damon (개인폴더, 700 권한) │ ├── Samba (Port 445) │ ├── \\192.168.0.203\share (공용) │ └── \\192.168.0.203\damon (개인) │ └── Nextcloud (Docker - Port 8080) └── cloud.grantech.kr ``` ### 6.2 접속 정보 | 서비스 | 접속 방법 | 사용자 | |--------|-----------|--------| | Samba 공용 | \\192.168.0.203\share | damon, grantech_YWJ | | Samba 개인 | \\192.168.0.203\damon | damon만 | | Nextcloud | http://cloud.grantech.kr | admin | ### 6.3 네트워크 드라이브 매핑 | 드라이브 | 경로 | 용도 | |----------|------|------| | X: | \\192.168.0.203\share | 공용 파일 | | Y: | \\192.168.0.203\damon | 개인 파일 | --- ## 7. 작업 일지 ### 2025-11-27 - 카모두 API 역공학 분석 완료 - Python Agent 개발 완료 - 제조사 154개, 모델 목록 동기화 성공 ### 2025-11-28 - Server1 (Master) Docker 환경 구축 - PostgreSQL, Redis, Nginx Proxy Manager 설치 - Server2 MongolCar Backend 배포 ### 2025-11-29 - MongolCar Frontend (Next.js) 개발 - Carmodoo Agent 연동 - 공유기 포트포워딩 설정 - autonetsellcar.com DNS 설정 및 SSL 인증서 발급 ### 2025-12-05 - Server3 환경 구축 및 Grantech 사이트 배포 - 파일 서버 구축 (10TB HDD, Samba, Nextcloud) - Grantech Admin 로그인 문제 해결 - CORS 설정 및 API 연동 ### 2025-12-06 ~ 2025-12-07 - MongolCar 다국어 지원 (EN, MN, RU, KO) - CC 코인 시스템 구현 - 히어로 배너 관리 기능 - 차량 요청 검색 기능 (카모두 스타일 확장 필터) - 가격 마진 계산 (한국 5% + 몽골 5%) - 데이터베이스 마이그레이션 (cc_balance, car_views 테이블) ### 2025-12-07 (추가 작업) **문제 발견 및 해결: 카모두 API 페이징 이슈** #### 문제 상황 - 사용자 보고: "기아 K5 전체등급 21~22년 1만~5만Km 검색하면 카모두에서는 수백건이 나오는데 여기서는 2건 나오네" - 캐시에 K5 차량이 42건만 저장됨 (실제로는 수백 건 존재) #### 원인 분석 1. 카모두 API `_inc_carListPhoto.html` 엔드포인트가 `sf_page` 파라미터를 무시 2. 모든 페이지에서 동일한 50건만 반환 (중복된 차량 ID) 3. `page_size=100` 요청해도 50건만 응답 #### 해결책: 연도별 분할 검색 (Year-Segmented Fetching) - `carmodoo.py`에 `search_cars_by_year_segment()` 메서드 추가 - 2010년부터 현재까지 연도별로 개별 검색 - 중복 제거 후 병합 - `cache_service.py`에서 새 방식 사용 #### 결과 비교 | 항목 | 이전 | 현재 | 개선율 | |------|------|------|--------| | K5 전체 캐시 | 42건 | **769건** | **18배** | | 2021-2022년 검색 | 2건 | **90건** | **45배** | | 2021-2022년 + 1만-5만Km | 2건 | **28건** | **14배** | #### 수정된 파일 - `backend/app/api/carmodoo.py` - `search_cars_by_year_segment()` 메서드 추가 - `backend/app/services/cache_service.py` - `fetch_all_cars_for_cache()` 연도별 분할 사용 #### 테스트 스크립트 생성 - `test_carmodoo_pagination.py` - 페이징 문제 검증 - `test_year_segmented.py` - 연도별 분할 검색 테스트 --- ## 8. 해결된 기술적 이슈 ### 인프라 관련 | 이슈 | 해결 방법 | |------|-----------| | DNS 해결 실패 | netplan에 nameservers 추가 (8.8.8.8, 8.8.4.4) | | Grafana 재시작 반복 | 데이터 디렉토리 권한 수정 (472:472) | | Prometheus 재시작 반복 | 데이터 디렉토리 권한 수정 (65534:65534) | | DB 비밀번호 @ 문자 | URL 파싱 문제로 @ 제거 | | Docker ContainerConfig 오류 | --remove-orphans와 system prune | | 헤어핀 NAT 미지원 | hosts 파일에 내부 IP 매핑 | ### 백엔드 관련 | 이슈 | 해결 방법 | |------|-----------| | email-validator 누락 | requirements.txt에 추가 | | XML 파싱 인코딩 오류 | _clean_xml_bytes() 메서드 추가 | | no such column: users.cc_balance | ALTER TABLE로 컬럼 추가 | | 카모두 API 페이징 미작동 | 연도별 분할 검색으로 우회 | | 가격 필터 키 불일치 | `price` vs `original_price` 둘 다 체크 | ### 프론트엔드 관련 | 이슈 | 해결 방법 | |------|-----------| | package-lock.json 누락 | npm ci → npm install 변경 | | Windows 콘솔 한글 출력 | UTF-8 출력 래퍼 추가 | | CORS 에러 | Backend CORS_ORIGINS에 도메인 추가 | | 포트 충돌 | 기존 프로세스 종료 후 재시작 | --- ## 8.1 교훈 및 주의사항 ### 외부 API 연동 시 주의사항 1. **API 문서를 맹신하지 말 것** - 카모두 API의 `sf_page` 파라미터가 실제로는 작동하지 않음 - 항상 실제 응답을 검증하고 테스트해야 함 2. **중복 데이터 검증 필수** - 페이지네이션 결과가 중복될 수 있음 (같은 차량 ID 반복) - `set()`를 사용해 중복 제거 필수 3. **대안 전략 마련** - 페이징이 안 되면 다른 조건(연도, 가격대 등)으로 분할 검색 - Rate limiting 고려 (0.3초 딜레이 적용) ### 캐싱 시스템 주의사항 1. **캐시 키 설계** - 제조사+모델 조합으로 고유 키 생성 (`maker_code_model_code`) - 필터 조건은 캐시 후 메모리에서 적용 2. **캐시 갱신 트리거** - TTL 만료 시 자동 삭제 (2시간) - 신규 검색 시 캐시 Miss → 전체 데이터 수집 3. **동시 요청 처리** - asyncio.Lock으로 동일 캐시 키에 대한 중복 요청 병합 - Event로 완료 대기 처리 ### 필터링 시 주의사항 1. **키 이름 불일치 문제** - 원본 데이터: `price` - 변환 후 데이터: `original_price` - 둘 다 체크하도록 구현: `c.get('price') or c.get('original_price')` 2. **값 매핑 필요** - 연료: 프론트엔드 '가솔린' → 카모두 '휘발유' - 변속기: 프론트엔드 '자동' → 카모두 '오토' --- ## 9. TODO 목록 ### 긴급 (즉시 수행) - [x] 백엔드 서버 재시작 (새 API 반영) ✅ 2025-12-07 완료 - [x] 차량 요청 검색 기능 테스트 ✅ 2025-12-07 완료 - [x] 카모두 API 페이징 이슈 해결 ✅ 2025-12-07 완료 ### 단기 (이번 주) - [ ] grantech.kr SSL 인증서 발급 - [ ] api.grantech.kr SSL 인증서 발급 - [ ] cloud.grantech.kr SSL 인증서 발급 - [ ] api.autonetsellcar.com Proxy Host 추가 - [ ] 백업 스크립트 설정 ### 중기 (이번 달) - [ ] cylinx.kr 배포 - [ ] 서비스 자동 시작 설정 (systemd) - [ ] 차량 검색 결과에서 실제 카모두 API 연동 - [ ] CC 코인 결제 시스템 완성 - [ ] 차량 상세정보 잠금/해제 UI 완성 ### 장기 (다음 달) - [ ] 다중 소스 지원 (다른 중고차 플랫폼) - [ ] 자동화 시스템 (주기적 데이터 동기화) - [ ] 견적서 자동 생성 - [ ] 수출 비용 계산기 - [ ] 환율 연동 --- ## 10. 계정 정보 ### Server1 서비스 | 서비스 | 계정 | 비고 | |--------|------|------| | Nginx Proxy Manager | 설정한 이메일/비밀번호 | 첫 로그인시 변경 | | Portainer | 설정한 계정 | 첫 접속시 생성 | | Grafana | admin / .env의 GRAFANA_PASSWORD | | | PostgreSQL | admin / roskfl1122 | | | Redis | roskfl@1122 (비밀번호만) | | ### MongolCar | 항목 | 값 | |------|-----| | Admin Email | admin@example.com | | Admin Password | admin123 | ### Grantech | 항목 | 값 | |------|-----| | Admin Username | admin | | Admin Password | grantech2024 | ### Carmodoo | 항목 | 값 | |------|-----| | User ID | 01033315258 | | Password | alskfl@1122 | --- ## 11. 명령어 참고 ### Server1 관리 ```bash cd ~/master && docker-compose ps # 컨테이너 상태 docker logs postgres-primary # 로그 확인 docker-compose restart # 재시작 docker exec -it postgres-primary psql -U admin -d mongolcar # DB 접속 ``` ### Server2 관리 ```bash cd ~/mongolcar && docker-compose ps # 컨테이너 상태 docker logs mongolcar-backend # Backend 로그 docker-compose restart backend # Backend 재시작 docker-compose build backend && docker-compose up -d backend # 재빌드 ``` ### Server3 관리 ```bash ps aux | grep -E "npm|uvicorn" # 프로세스 확인 sudo netstat -tlnp | grep 3001 # 포트 확인 sudo kill -9 # 프로세스 종료 nohup sh -c 'PORT=3001 npm start' > ~/logs/frontend.log 2>&1 & # Frontend 시작 ``` ### Windows 로컬 개발 ```bash # Backend 시작 cd D:\Workspace\claudeCode\AutonetSellCar.com\backend python -m uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload # Frontend 시작 cd D:\Workspace\claudeCode\AutonetSellCar.com\frontend npm run dev ``` ### 파일 전송 ```bash scp -r D:\Workspace\claudeCode\AutonetSellCar.com\backend damon@192.168.0.202:~/mongolcar/ ``` --- ## 12. Windows 로컬 파일 위치 ``` D:\Workspace\claudeCode\AutonetSellCar.com\ ├── backend/ # FastAPI Backend ├── frontend/ # Next.js Frontend ├── agent/ # Carmodoo 연동 에이전트 ├── _legacy_agent/ # 원본 분석 스크립트 (백업) ├── PROGRESS_ReadMe.md # 이 파일 (통합 진행 보고서) ├── mongol-car-platform-plan.md # 전체 프로젝트 계획 └── SERVER_INFRASTRUCTURE_PLAN.md # 서버 인프라 계획 ``` --- *Generated by Claude Code - Last updated: 2025-12-07*