Files
AutonetSellCar/CLAUDE.md
AutonetSellCar Deploy 1f0dcb1ddb Initial commit: AutonetSellCar platform with deployment system
- Frontend: Next.js 14 with TypeScript
- Backend: FastAPI with SQLAlchemy
- Agent: Carmodoo sync agent
- Deployment: Docker Compose based staging/production setup
- Scripts: Automated deployment with rollback support

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-30 13:24:39 +09:00

22 KiB

AutonetSellCar.com 개발 가이드

이 문서는 Claude Code 세션에서 반드시 읽고 참고해야 하는 중요한 정보입니다.


1. 프로젝트 구조

AutonetSellCar.com/
├── backend/                    # FastAPI 백엔드
│   ├── app/
│   │   ├── api/               # API 라우터
│   │   ├── models/            # SQLAlchemy 모델
│   │   ├── services/          # 비즈니스 로직
│   │   └── database.py        # DB 연결
│   ├── uploads/               # 업로드 파일 저장
│   │   └── performance_checks/ # 성능점검표 PDF
│   ├── autonet.db             # ★ 실제 사용하는 DB (이것만 사용!)
│   └── venv/                  # Python 가상환경
├── frontend/                  # Next.js 프론트엔드
│   └── src/
│       ├── app/               # 페이지
│       └── lib/api.ts         # API 함수
└── restart-dev.bat            # 개발 서버 재시작 스크립트

2. 중요: DB 파일 관리

★★★ 반드시 확인 ★★★

실제 사용하는 DB 파일: backend/autonet.db (이것만!)

과거에 테스트용으로 생성된 빈 DB 파일들이 있을 수 있습니다:

  • autonet.db (루트) - 사용하지 않음
  • autonetsellcar.db - 사용하지 않음
  • car_platform.db - 사용하지 않음

이런 파일들이 발견되면 삭제해야 합니다.

# DB 파일 확인 스크립트
from pathlib import Path
base = Path(r'D:\Workspace\claudeCode\AutonetSellCar.com')
for db in base.rglob('*.db'):
    if 'venv' not in str(db) and 'node_modules' not in str(db):
        print(f"{db}: {db.stat().st_size / 1024:.1f} KB")

3. 성능점검표 PDF 시스템

3.1 PDF 생성 흐름

  1. 관리자가 Carmodoo에서 차량 검색
  2. 차량 가져오기(import) 시 check_num (성능점검번호) 추출
  3. capture_performance_check_pdf() 함수로 PDF 캡처 시도
  4. 성공 시 car_performance_checks.pdf_path에 경로 저장
  5. 프론트엔드에서 pdf_path가 있으면 PDF 보기 버튼 표시

3.2 PDF 버튼이 안 보이는 경우

원인: pdf_path가 NULL인 경우

해결 방법:

  1. 관리자 > Hero Banners 페이지에서 "PDF 재시도" 버튼 클릭
  2. 또는 API 직접 호출: POST /api/carmodoo/admin/retry-all-failed-pdfs

3.3 PDF 관련 파일들

  • backend/app/services/pdf_service.py - PDF 캡처 로직 (3회 자동 재시도)
  • backend/app/api/carmodoo.py - PDF 관련 API 엔드포인트
  • frontend/src/app/cars/[id]/page.tsx - PDF 보기 버튼 (라인 605 근처)
// PDF 버튼 표시 조건 (page.tsx)
{performanceCheck.data?.pdf_path && (
  // PDF 버튼 렌더링
)}

4. check_num (성능점검번호) 처리

4.1 check_num 추출 위치

Carmodoo HTML에서 checkNum주석 처리된 부분에 있음:

<!-- ... checkNum=9830018360 ... -->

4.2 파싱 로직 (carmodoo.py)

# 전체 row HTML에서 checkNum 추출 (주석 포함)
row_html = etree.tostring(row, encoding='unicode')
check_match = re.search(r'checkNum=(\d+)', row_html)
if check_match:
    check_num = check_match.group(1)

4.3 check_num 관련 모델/인터페이스

백엔드 (carmodoo.py):

class CarmodooSearchResultItem(BaseModel):
    # ... 기타 필드 ...
    check_num: Optional[str] = None  # 성능점검번호

프론트엔드 (api.ts):

export interface CarmodooSearchResult {
  // ... 기타 필드 ...
  check_num?: string;  // 성능점검번호
}

5. 서버 재시작 관련

5.1 uvicorn 캐시 문제

증상: 코드 수정 후에도 API 스키마에 변경사항이 반영되지 않음

원인:

  • --reload 옵션이 있어도 일부 변경사항이 적용되지 않는 경우 있음
  • __pycache__ 캐시 문제

해결 방법:

# 1. __pycache__ 삭제
Get-ChildItem -Path 'backend' -Recurse -Directory -Filter '__pycache__' | Remove-Item -Recurse -Force

# 2. 서버 완전 재시작
# 방법 A: restart-dev.bat 실행
# 방법 B: 수동으로 uvicorn 프로세스 종료 후 재시작

5.2 포트 확인

netstat -ano | findstr :8000
netstat -ano | findstr :3000

6. 관리자 기능

6.1 Hero Banners 페이지 (/admin/hero-banners)

차량 검색 필터:

  • 제조사, 모델, 등급
  • 연식 (From ~ To)
  • 연료, 배기량, 주행거리

PDF 관리:

  • "PDF 재시도" 버튼 - PDF 없는 모든 차량에 대해 PDF 재생성

6.2 관리자 API 엔드포인트

엔드포인트 설명
GET /api/carmodoo/admin/pdf-failures PDF 생성 실패 목록
POST /api/carmodoo/admin/retry-all-failed-pdfs 전체 PDF 재시도
POST /api/carmodoo/regenerate-pdf/{car_id} 특정 차량 PDF 재생성

7. 자주 발생하는 문제와 해결

7.1 "PDF 버튼이 안 보여요"

체크리스트:

  1. 로그인 상태 확인 (로그인 사용자만 PDF 접근 가능)
  2. DB에서 해당 차량의 pdf_path 확인
    SELECT car_id, check_number, pdf_path FROM car_performance_checks WHERE car_id = ?;
    
  3. pdf_path가 NULL이면 → PDF 재생성 필요
  4. PDF 파일이 실제로 존재하는지 확인: backend/uploads/performance_checks/

7.2 "코드 수정했는데 적용이 안 돼요"

  1. __pycache__ 삭제
  2. uvicorn 서버 완전 재시작
  3. 브라우저 캐시 클리어 (Ctrl+Shift+R)

7.3 "검색 결과가 안 나와요"

  1. 캐시 만료 확인: carmodoo_search_cache 테이블
  2. 제조사/모델 코드 확인 (예: 기아=2, K5=38)
  3. 연도 범위 확인

8. 개발 환경 시작

# 방법 1: 배치 파일 사용
restart-dev.bat

# 방법 2: 수동 시작
# 터미널 1 (백엔드)
cd backend
venv\Scripts\activate
python -m uvicorn app.main:app --reload --host 0.0.0.0 --port 8000

# 터미널 2 (프론트엔드)
cd frontend
npm run dev

9. 유용한 디버깅 명령어

# DB 상태 확인
import sqlite3
conn = sqlite3.connect('backend/autonet.db')
cursor = conn.cursor()

# 성능점검 데이터 확인
cursor.execute('SELECT car_id, check_number, pdf_path FROM car_performance_checks')
for row in cursor.fetchall():
    print(row)

# PDF 파일 존재 확인
from pathlib import Path
pdf_dir = Path('backend/uploads/performance_checks')
for pdf in pdf_dir.glob('*.pdf'):
    print(f"{pdf.name}: {pdf.stat().st_size / 1024:.1f} KB")

10. 환율 시스템

10.1 개요

한국수출입은행 API에서 실시간 환율을 가져와 모든 가격 표시에 적용합니다.

  • 갱신 주기: 매일 11:30 AM (한국수출입은행 고시 시간)
  • 캐싱: 30분간 캐시 유지
  • 폴백: API 실패 시 기본값 사용

10.2 환율 API 엔드포인트

엔드포인트 설명
GET /api/exchange-rate 전체 환율 정보 (상세)
GET /api/exchange-rate/simple 간단한 환율 정보 (USD, EUR, JPY 등)

응답 예시 (/api/exchange-rate/simple):

{
  "USD": {"rate": 1483.4, "symbol": "$", "name": "미국 달러"},
  "EUR": {"rate": 1749.74, "symbol": "€", "name": "유로"},
  "JPY": {"rate": 9.5001, "symbol": "¥", "name": "일본 옌"}
}

10.3 프론트엔드 환율 Store

파일: frontend/src/lib/exchangeRateStore.ts

// 환율 가져오기
const store = useExchangeRateStore.getState();
const usdRate = store.rates.USD?.rate || 1483;  // 폴백 값

// KRW → USD 변환
const usdAmount = krwAmount / usdRate;

// USD → KRW 변환
const krwAmount = usdAmount * usdRate;

기본값 (API 실패 시):

통화 rate (1 단위당 KRW)
USD 1483
EUR 1750
JPY 9.5
CNY 203
MNT 0.43
RUB 14.5

10.4 환율 적용 파일들

파일 용도
frontend/src/lib/exchangeRateStore.ts Zustand 환율 스토어
frontend/src/lib/i18n.ts formatPriceWithCurrency() 함수
frontend/src/app/exchange-rate/page.tsx 환율 정보 페이지
frontend/src/app/cost/page.tsx 비용 계산기
frontend/src/components/SearchFilters.tsx 검색 필터 가격 표시
frontend/src/app/admin/purchased/page.tsx 구매 차량 관리

10.5 주의사항

하드코딩된 환율 사용 금지!

// 잘못된 예
const usd = krwAmount * 0.00069;  // 하드코딩 X
const krw = usdAmount * 1333;     // 하드코딩 X

// 올바른 예
const usdRate = useExchangeRateStore.getState().rates.USD?.rate || 1483;
const usd = krwAmount / usdRate;
const krw = usdAmount * usdRate;

10.6 환율 디버깅

# API 테스트
curl http://localhost:8000/api/exchange-rate/simple

# DB 환율 데이터 확인
sqlite3 backend/autonet.db "SELECT * FROM exchange_rates ORDER BY updated_at DESC LIMIT 5;"

11. 다국어 번역 시스템

11.1 개요

차량 정보(차량명, 연료, 변속기, 색상 등)를 사용자 선택 언어로 번역합니다.

  • 지원 언어: 한국어(ko), 영어(en), 몽골어(mn), 러시아어(ru)
  • 기본값: 해당 언어 번역이 없으면 영어(en)로 대체

11.2 번역 관련 파일들

파일 역할
frontend/src/lib/i18n.ts 정적 번역 사전 (CAR_TRANSLATIONS), translateCarName() 함수
frontend/src/lib/useTranslate.ts translate() 훅 - API + 정적 번역 폴백

11.3 CAR_TRANSLATIONS 구조

const CAR_TRANSLATIONS: Record<string, Record<string, string>> = {
  // 연료 타입
  '휘발유': { ko: '휘발유', en: 'Gasoline', mn: 'Бензин', ru: 'Бензин' },
  '경유': { ko: '경유', en: 'Diesel', mn: 'Дизель', ru: 'Дизель' },

  // 변속기
  '오토': { ko: '오토', en: 'Auto', mn: 'Авто', ru: 'Авто' },
  '수동': { ko: '수동', en: 'Manual', mn: 'Механик', ru: 'Механика' },

  // 제조사
  'KG모빌리티(쌍용)': { ko: 'KG모빌리티(쌍용)', en: 'KG Mobility (SsangYong)', ... },

  // 모델
  '렉스턴 스포츠': { ko: '렉스턴 스포츠', en: 'Rexton Sports', ... },

  // 색상
  '흰색': { ko: '흰색', en: 'White', mn: 'Цагаан', ru: 'Белый' },
};

11.4 번역 함수 사용법

방법 1: useTranslate (권장)

import { useTranslate } from '@/lib/useTranslate';

function Component() {
  const { translate } = useTranslate();
  return <span>{translate(car.fuel)}</span>;  // '휘발유' → 'Gasoline'
}

방법 2: translateCarName 함수 (직접 호출)

import { translateCarName } from '@/lib/i18n';

const translatedFuel = translateCarName(car.fuel, language);  // '경유' → 'Diesel'

11.5 새 번역 추가하기

CAR_TRANSLATIONS에 새 항목 추가:

'새로운용어': { ko: '새로운용어', en: 'New Term', mn: 'Шинэ нэр', ru: 'Новый термин' },

주의: 긴 문자열을 먼저 매칭하기 위해 SORTED_CAR_KEYS가 자동으로 정렬됨

11.6 번역이 안 되는 경우

  1. CAR_TRANSLATIONS에 해당 용어가 없음 → 새 항목 추가
  2. 프론트엔드 리빌드 필요npm run dev 재시작 또는 .next 폴더 삭제
  3. translate() 함수 미사용 → 페이지에서 직접 값 출력 중 (수정 필요)
  4. localStorage에 'ko' 언어 저장됨 → 일반 유저는 한국어 선택 불가지만 localStorage에 남아있으면 번역 스킵됨
    • LanguageSelector.tsx에서 자동으로 영어로 리셋하도록 수정됨

11.7 언어 선택 제한

  • 관리자(is_admin=true): 한국어, 영어, 몽골어, 러시아어 모두 선택 가능
  • 일반 유저: 영어, 몽골어, 러시아어만 선택 가능 (한국어 숨김)
  • 파일: frontend/src/components/LanguageSelector.tsx

12. CC (Car Credit) 시스템

12.1 CC란?

  • 플랫폼 내 가상 화폐
  • 차량 추천 서비스에 사용 (1 CC = N대 추천, 관리자 설정 가능)
  • 신규 가입 시 1 CC 지급
  • 관리자 설정: /admin/settings에서 Cars per CC 값으로 1 CC당 추천 대수 조절 가능 (기본값: 3대)

12.2 CC 충전 패키지

충전 금액 받는 CC 추천 가능 차량 (기본 3대/CC) 할인율
$10 10 CC 30대 -
$27 30 CC 90대 10%
$40 50 CC 150대 20%

참고: 추천 가능 차량 수는 관리자 설정의 Cars per CC 값에 따라 변동됩니다.

12.3 결제 수단

수단 대상 처리 방식
Stripe 몽골 사용자 Visa/Mastercard 자동 결제
몽골 파트너 계좌 러시아 사용자 수동 충전 요청 → 관리자 승인

12.4 Stripe 설정

환경변수 (backend/.env):

STRIPE_SECRET_KEY=sk_test_...      # Stripe 비밀키
STRIPE_PUBLISHABLE_KEY=pk_test_... # Stripe 공개키
STRIPE_WEBHOOK_SECRET=whsec_...    # Webhook 시크릿
STRIPE_SUCCESS_URL=https://yourdomain.com/cc/success
STRIPE_CANCEL_URL=https://yourdomain.com/cc

API 엔드포인트:

엔드포인트 설명
GET /api/cc/packages CC 패키지 목록
POST /api/cc/create-checkout-session Stripe 결제 세션 생성
POST /api/cc/webhook Stripe Webhook 수신
GET /api/cc/checkout-success 결제 완료 확인
POST /api/cc/manual-request 수동 충전 요청 (러시아용)

Stripe Webhook 설정:

  1. Stripe Dashboard → Webhooks
  2. 엔드포인트 추가: https://yourdomain.com/api/cc/webhook
  3. 이벤트 선택: checkout.session.completed, checkout.session.expired

12.5 CC vs 차량 열람

중요: CC는 추천 서비스에만 사용됩니다!

기능 필요 조건
차량 정보 열람 (이미지, 딜러, 성능점검표) 로그인만 하면 무료
배너 차량 열람 비로그인도 무료
차량 추천 서비스 CC 필요 (1 CC = N대, 설정에 따름)

13. 상세사양조회 시스템 (AUTOBEGINS)

13.1 개요

Carmodoo 딜러 포탈의 AUTOBEGINS 서비스를 통해 차량번호 기반 상세사양을 조회합니다.

  • 데이터 소스: AUTOBEGINS (api.autobegins.com) via Carmodoo iframe
  • 조회 방식: Playwright 브라우저 자동화
  • 저장 시점: 배너 등록(import) 시 자동 저장

13.2 조회 가능 정보

카테고리 정보
기본 정보 제조사, 모델명, 등급, 연식
엔진/구동 배기량, 연료, 변속기, 구동방식
성능 최대출력, 최대토크, 연비
차체 차체형식, 도어수, 승차정원, 전장/전폭/전고/휠베이스
옵션 안전옵션, 편의옵션, 외장옵션, 내장옵션
가격 출고가, 기본가, 옵션가

13.3 관련 파일

파일 역할
backend/app/services/spec_service.py Playwright 기반 사양 조회
backend/app/models/car_specification.py CarSpecification 모델
backend/app/api/carmodoo.py /specifications/{car_number}, /car/{car_id}/specifications API

13.4 딜러 상세설명 (dealer_description)

  • cars.dealer_description 컬럼에 저장
  • Carmodoo 상세페이지에서 딜러가 작성한 설명 추출
  • 차량 상세 페이지에서 amber 배경으로 표시 (로그인 사용자)

추출 방식 (2024-12-25 개선):

  1. 검색 결과에서 car_key 추출 (dealerCarviewPopup('...') 패턴)
  2. dealerCarView.html?key=<car_key> URL로 상세 페이지 접근
  3. <div class="carViewMemoWrap"><h3>상세설명</h3><div class="memo">...</div></div> 파싱
# carmodoo.py - 딜러 설명 추출 (car_key 기반)
async def get_car_detail(self, car_no: str, car_key: str = "") -> dict:
    if car_key:
        url = f"{CARMODOO_BASE_URL}/car/dealerCarView.html"
        params = {"key": car_key, "tabStart": "1"}
        # EUC-KR 디코딩 후 상세설명 추출
        # <div class="carViewMemoWrap">...<div class="memo">설명</div></div>

관련 필드:

  • CarmodooSearchResultItem.car_key - 검색 결과에 포함
  • AdminSearchResultItem.car_key - 관리자 검색 결과에 포함
  • ImportCarRequest.car_key - Import 요청에 포함

14. Quote Request 시스템 (차량 추천 요청)

14.1 개요

사용자가 원하는 차량 조건을 입력하면 관리자가 맞춤 차량을 추천해주는 서비스입니다.

  • 비용: 1 CC per request
  • 응답 시간: 24시간 이내 추천
  • 페이지: /vehicle-request

14.2 요청 조건

필드 필수 설명
제조사 기아, 현대 등
모델 K5, 소나타 등
등급 - 선택 사항
연식 범위 - 2020 ~ 2024
주행거리 - 만km 단위
연료 - 휘발유, 경유, 하이브리드 등
배기량 - 1000cc ~ 5000cc

14.3 CC 결제 흐름

  1. 사용자가 조건 입력
  2. 제출 시 CC 잔액 확인 (1 CC 필요)
  3. 잔액 부족 시 /cc 페이지로 안내
  4. CC 차감 후 요청 생성
  5. vehicle_requests.cc_paid 컬럼에 기록

14.4 관련 파일

파일 역할
backend/app/api/vehicle_requests.py 요청 생성 API (CC 차감)
backend/app/models/vehicle_request.py VehicleRequest 모델 (cc_paid 컬럼)
frontend/src/app/vehicle-request/page.tsx 요청 폼 UI (CC 안내)

15. 현지딜러 시스템

15.1 딜러 등급 및 수수료

몽골 마진(5%)에서 딜러 수수료 지급:

등급 조건 수수료율
일반 (Standard) 기본 3.0%
실버 (Silver) 10건+ 판매 3.5%
골드 (Gold) 30건+ 판매 4.0%
플래티넘 (Platinum) 100건+ 판매 4.5%

15.2 레퍼럴 시스템

  • 딜러가 고객에게 추천 코드 제공
  • 고객이 차량 구매 시 딜러에게 수수료 지급
  • 1단계 직접 추천만 인정 (다단계 아님)

16. 딜러 설명 번역 시스템

16.1 개요

딜러 설명(dealer_description)을 Azure Translator API를 사용하여 다국어로 번역합니다.

  • 번역 API: Microsoft Azure Translator (한국어 → 영어/몽골어/러시아어 직접 지원)
  • 무료 한도: 월 200만 글자
  • 저장 시점: Import 시 자동 번역, 관리자가 확인 후 배너/추천 전송

16.2 DB 필드

컬럼 설명
cars.dealer_description 한국어 원문
cars.dealer_description_en 영어 번역
cars.dealer_description_mn 몽골어 번역
cars.dealer_description_ru 러시아어 번역

16.3 환경 변수

# Azure Translator API
AZURE_TRANSLATOR_KEY=your_api_key
AZURE_TRANSLATOR_REGION=koreacentral

16.4 관련 파일

파일 역할
backend/app/services/translation_service.py Azure Translator 연동
backend/app/api/carmodoo.py 번역 관리 API 엔드포인트
frontend/src/app/admin/dealer-translations/page.tsx 관리자 번역 확인/수정 UI
frontend/src/app/cars/[id]/page.tsx 사용자 페이지 번역 표시

16.5 관리자 API 엔드포인트

엔드포인트 설명
GET /api/carmodoo/car/{car_id}/translations 차량 번역 조회
PUT /api/carmodoo/car/{car_id}/translations 차량 번역 수정
POST /api/carmodoo/car/{car_id}/translations/regenerate 번역 재생성
GET /api/carmodoo/admin/untranslated-cars 미번역 차량 목록
POST /api/carmodoo/admin/translate-all-pending 일괄 번역

16.6 번역 흐름

Import 시 자동 번역 (Azure API)
       ↓
관리자 확인 (/admin/dealer-translations)
       ↓
필요시 수정 또는 재번역
       ↓
배너 등록 / 추천 전송
       ↓
사용자 페이지에서 한국어 원문 + 선택언어 번역 표시

17. 변경 이력

날짜 변경 내용
2024-12-27 딜러 설명 번역 시스템 추가: Azure Translator API 연동, 한국어→영어/몽골어/러시아어 직접 번역
2024-12-27 관리자 번역 관리 페이지 추가 (/admin/dealer-translations)
2024-12-27 DB 스키마 확장: dealer_description_en/mn/ru 컬럼 추가
2024-12-25 딜러 상세설명 추출 방식 개선: car_key 기반 dealerCarView.html 사용 (기존 carPopView.html 404 문제 해결)
2024-12-25 검색 결과에 car_key 필드 추가 (CarmodooSearchResultItem, AdminSearchResultItem)
2024-12-25 Import 시 car_key 전달하여 딜러 설명 자동 추출
2024-12-25 상세사양조회 시스템 추가 (AUTOBEGINS, spec_service.py, CarSpecification 모델)
2024-12-25 딜러 상세설명 필드 추가 (cars.dealer_description)
2024-12-25 Quote Request 1CC 결제 시스템 추가 (vehicle_requests.cc_paid)
2024-12-25 CC당 추천 대수 관리자 설정 추가 (cars_per_cc, 기본값 3대)
2024-12-25 차량 검색 시 연료 조건 필터링 버그 수정
2024-12-24 Stripe 결제 연동 (CC 충전 패키지, Checkout Session, Webhook)
2024-12-24 CC 시스템 변경 (추천 서비스 기반, 차량열람 무료화)
2024-12-24 언어 자동 리셋 버그 수정 (localStorage 'ko' 문제)
2024-12-24 다국어 번역 시스템 개선 (연료/변속기/색상/차량명)
2024-12-24 환율 시스템 동적 적용 (하드코딩 제거, API 연동)
2024-12-24 PDF 재시도 로직 추가 (3회 자동 재시도)
2024-12-24 빈 DB 파일 정리
2024-12-24 관리자 PDF 재시도 UI/API 추가
2024-12-24 Hero Banners 검색에 주행거리 필터 추가

이 문서는 새 세션 시작 시 반드시 읽어주세요!