# 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 <PID>                        # 프로세스 종료
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*
