# 몽골 중고차 수출 플랫폼 개발 계획서 ## 📋 프로젝트 개요 | 항목 | 내용 | |------|------| | **프로젝트명** | MongolCar - 몽골 중고차 수출 플랫폼 | | **목적** | 한국 중고차를 몽골 고객에게 실시간 검색/판매하는 B2C 플랫폼 | | **대상 고객** | 몽골, 러시아, 카자흐스탄 등 중앙아시아 고객 | | **개발 기간** | 8~10주 | | **개발 도구** | Claude Code | --- ## 🏗️ 시스템 아키텍처 ``` ┌─────────────────────────────────────────────────────────────────────────────┐ │ 전체 시스템 구성도 │ └─────────────────────────────────────────────────────────────────────────────┘ ┌─────────────────────────────────────┐ │ 몽골/러시아 사용자 (웹브라우저) │ │ - 차량 검색 (차종/연식/마일리지) │ │ - 상세보기 (포인트 차감) │ │ - 실시간 채팅 (AI 번역) │ └──────────────────┬──────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────────────────┐ │ 우분투 웹서버 (Ryzen 7700, 32GB) │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │ │ │ Next.js │ │ Node.js │ │ Socket.io │ │ Claude API │ │ │ │ Frontend │ │ API Server │ │ 실시간채팅 │ │ 번역+FAQ 챗봇 │ │ │ │ (다국어) │ │ │ │ │ │ │ │ │ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────────────┘ │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────────────────────┐ │ │ │ Nginx │ │ Redis │ │ 이미지 저장소 │ │ │ │ Reverse │ │ Cache │ │ /var/www/car-images/ │ │ │ │ Proxy │ │ Session │ │ 1000대 × 20장 = ~10GB │ │ │ └─────────────┘ └─────────────┘ └─────────────────────────────────────┘ │ └─────────────────────────────────────┬───────────────────────────────────────┘ │ ┌─────────────────┴─────────────────┐ │ 내부 네트워크 │ └─────────────────┬─────────────────┘ │ ┌─────────────────────────────┴─────────────────────────────┐ │ │ ▼ ▼ ┌───────────────────────────────────┐ ┌───────────────────────────────────┐ │ 우분투 DB서버 (Ryzen 7700, 32GB) │ │ Windows PC (사무실) │ │ ┌─────────────────────────────┐ │ │ ┌─────────────────────────────┐ │ │ │ PostgreSQL 16 │ │ │ │ 카모두 프로그램 │ │ │ │ - vehicles (차량정보) │ │ │ │ (GGKucar.exe) │ │ │ │ - users (회원) │ │ │ └──────────────┬──────────────┘ │ │ │ - payments (결제) │ │ │ │ │ │ │ - chat_messages (채팅) │ │ │ ┌──────────────▼──────────────┐ │ │ │ - view_history (열람기록) │ │ │ │ Python 자동화 에이전트 │ │ │ └─────────────────────────────┘ │ │ │ - pywinauto (UI 제어) │ │ │ ┌─────────────────────────────┐ │ │ │ - API Client (서버 통신) │ │ │ │ 백업 스토리지 (10TB) │ │ │ │ - 이미지 추출/업로드 │ │ │ └─────────────────────────────┘ │ │ └─────────────────────────────┘ │ └───────────────────────────────────┘ └───────────────────────────────────┘ ``` --- ## 🖥️ 서버 인프라 ### 서버 1: 웹서버 | 항목 | 사양 | |------|------| | **CPU** | AMD Ryzen 7 7700 | | **RAM** | 32GB (64GB 중 할당) | | **스토리지** | SSD (OS + 앱) + HDD 10TB 일부 | | **OS** | Ubuntu 22.04 LTS | **설치 서비스:** - Nginx (리버스 프록시, SSL) - Node.js 20 LTS - Next.js 14 - Redis 7 - PM2 ### 서버 2: DB서버 | 항목 | 사양 | |------|------| | **CPU** | AMD Ryzen 7 7700 | | **RAM** | 32GB (64GB 중 할당) | | **스토리지** | SSD (DB) + HDD 10TB (백업) | | **OS** | Ubuntu 22.04 LTS | **설치 서비스:** - PostgreSQL 16 - 자동 백업 스크립트 --- ## 💻 기술 스택 ### Frontend | 기술 | 버전 | 용도 | |------|------|------| | Next.js | 14.x | React 프레임워크, SSR | | TypeScript | 5.x | 타입 안전성 | | Tailwind CSS | 3.x | 스타일링 | | next-intl | latest | 다국어 (mn/en/ru/ko) | | Socket.io-client | 4.x | 실시간 채팅 | | React Query | 5.x | 서버 상태 관리 | | Zustand | 4.x | 클라이언트 상태 관리 | ### Backend | 기술 | 버전 | 용도 | |------|------|------| | Node.js | 20 LTS | 런타임 | | Express.js | 4.x | API 서버 | | TypeScript | 5.x | 타입 안전성 | | Socket.io | 4.x | 실시간 통신 | | Prisma | 5.x | ORM | | Redis | 7.x | 캐시, 세션, 큐 | | Bull | 4.x | 작업 큐 | ### Database | 기술 | 버전 | 용도 | |------|------|------| | PostgreSQL | 16.x | 메인 데이터베이스 | ### External APIs | 서비스 | 용도 | |--------|------| | Claude API (Anthropic) | 번역 + FAQ 챗봇 | | NOWPayments | USDT/USDC 결제 | | ExchangeRate API | 환율 조회 | ### Windows Agent | 기술 | 버전 | 용도 | |------|------|------| | Python | 3.11+ | 에이전트 개발 | | pywinauto | 0.6.8+ | UI 자동화 | | aiohttp | 3.x | 비동기 HTTP | | Pillow | 10.x | 이미지 처리 | --- ## 📁 프로젝트 구조 ``` mongol-car-platform/ ├── README.md ├── docker-compose.yml ├── .env.example │ ├── apps/ │ ├── web/ # Next.js 프론트엔드 │ │ ├── package.json │ │ ├── next.config.js │ │ ├── tailwind.config.js │ │ ├── tsconfig.json │ │ │ │ │ ├── public/ │ │ │ ├── locales/ # 다국어 파일 │ │ │ │ ├── mn/ # 몽골어 │ │ │ │ ├── en/ # 영어 │ │ │ │ ├── ru/ # 러시아어 │ │ │ │ └── ko/ # 한국어 │ │ │ └── images/ │ │ │ │ │ ├── src/ │ │ │ ├── app/ # App Router │ │ │ │ ├── [locale]/ │ │ │ │ │ ├── layout.tsx │ │ │ │ │ ├── page.tsx # 메인 (검색) │ │ │ │ │ ├── vehicles/ │ │ │ │ │ │ ├── page.tsx # 검색 결과 │ │ │ │ │ │ └── [id]/ │ │ │ │ │ │ └── page.tsx # 차량 상세 │ │ │ │ │ ├── auth/ │ │ │ │ │ │ ├── login/page.tsx │ │ │ │ │ │ └── register/page.tsx │ │ │ │ │ ├── mypage/ │ │ │ │ │ │ ├── page.tsx # 마이페이지 │ │ │ │ │ │ ├── points/page.tsx # 포인트 내역 │ │ │ │ │ │ ├── history/page.tsx # 열람 기록 │ │ │ │ │ │ ├── orders/page.tsx # 주문 내역 │ │ │ │ │ │ └── tracking/ │ │ │ │ │ │ ├── page.tsx # 내차찾기 목록 │ │ │ │ │ │ └── [orderId]/ │ │ │ │ │ │ └── page.tsx # 상세 추적 │ │ │ │ │ ├── payment/ │ │ │ │ │ │ ├── page.tsx # 충전 페이지 │ │ │ │ │ │ ├── success/page.tsx │ │ │ │ │ │ └── cancel/page.tsx │ │ │ │ │ └── chat/ │ │ │ │ │ └── [roomId]/page.tsx # 채팅방 │ │ │ │ └── api/ # API Routes (필요시) │ │ │ │ │ │ │ ├── components/ │ │ │ │ ├── common/ │ │ │ │ │ ├── Header.tsx │ │ │ │ │ ├── Footer.tsx │ │ │ │ │ ├── LanguageSwitcher.tsx │ │ │ │ │ └── Loading.tsx │ │ │ │ ├── vehicles/ │ │ │ │ │ ├── SearchForm.tsx │ │ │ │ │ ├── VehicleCard.tsx │ │ │ │ │ ├── VehicleList.tsx │ │ │ │ │ ├── VehicleDetail.tsx │ │ │ │ │ └── ImageGallery.tsx │ │ │ │ ├── chat/ │ │ │ │ │ ├── ChatWindow.tsx │ │ │ │ │ ├── MessageList.tsx │ │ │ │ │ └── MessageInput.tsx │ │ │ │ ├── payment/ │ │ │ │ │ ├── PaymentModal.tsx │ │ │ │ │ ├── CryptoSelector.tsx │ │ │ │ │ └── QRCodeDisplay.tsx │ │ │ │ ├── order/ │ │ │ │ │ ├── OrderSummary.tsx │ │ │ │ │ ├── FeeBreakdown.tsx # 수수료 상세 내역 │ │ │ │ │ └── OrderHistory.tsx │ │ │ │ └── tracking/ │ │ │ │ ├── TrackingMap.tsx # 지도 컴포넌트 │ │ │ │ ├── TrackingStatus.tsx # 현재 상태 표시 │ │ │ │ ├── TrackingTimeline.tsx # 배송 이력 타임라인 │ │ │ │ └── EstimatedArrival.tsx # 예상 도착일 │ │ │ │ │ │ │ ├── hooks/ │ │ │ │ ├── useAuth.ts │ │ │ │ ├── useVehicles.ts │ │ │ │ ├── useChat.ts │ │ │ │ ├── usePayment.ts │ │ │ │ ├── useOrder.ts │ │ │ │ └── useTracking.ts │ │ │ │ │ │ │ ├── lib/ │ │ │ │ ├── api.ts # API 클라이언트 │ │ │ │ ├── socket.ts # Socket.io 클라이언트 │ │ │ │ └── utils.ts │ │ │ │ │ │ │ ├── stores/ │ │ │ │ ├── authStore.ts │ │ │ │ └── chatStore.ts │ │ │ │ │ │ │ └── types/ │ │ │ ├── vehicle.ts │ │ │ ├── user.ts │ │ │ ├── payment.ts │ │ │ ├── order.ts │ │ │ ├── fee.ts │ │ │ └── tracking.ts │ │ │ │ │ └── messages/ # next-intl 메시지 │ │ ├── mn.json │ │ ├── en.json │ │ ├── ru.json │ │ └── ko.json │ │ │ └── api/ # Node.js 백엔드 │ ├── package.json │ ├── tsconfig.json │ │ │ └── src/ │ ├── index.ts # 엔트리포인트 │ ├── app.ts # Express 앱 │ │ │ ├── config/ │ │ ├── database.ts │ │ ├── redis.ts │ │ └── env.ts │ │ │ ├── routes/ │ │ ├── index.ts │ │ ├── auth.routes.ts │ │ ├── vehicles.routes.ts │ │ ├── payment.routes.ts │ │ ├── chat.routes.ts │ │ ├── order.routes.ts # 주문 관련 │ │ ├── tracking.routes.ts # 배송 추적 │ │ ├── fee.routes.ts # 수수료 관련 │ │ ├── container.routes.ts # 컨테이너 관리 (관리자) │ │ └── agent.routes.ts # Windows 에이전트용 │ │ │ ├── controllers/ │ │ ├── auth.controller.ts │ │ ├── vehicles.controller.ts │ │ ├── payment.controller.ts │ │ ├── chat.controller.ts │ │ ├── order.controller.ts │ │ ├── tracking.controller.ts │ │ ├── fee.controller.ts │ │ ├── container.controller.ts │ │ └── agent.controller.ts │ │ │ ├── services/ │ │ ├── auth.service.ts │ │ ├── vehicles.service.ts │ │ ├── payment.service.ts │ │ ├── translation.service.ts # Claude API │ │ ├── chat.service.ts │ │ ├── order.service.ts │ │ ├── tracking.service.ts │ │ ├── fee.service.ts # 수수료 계산 로직 │ │ ├── container.service.ts # 컨테이너 적재 로직 │ │ └── nowpayments.service.ts │ │ │ ├── middleware/ │ │ ├── auth.middleware.ts │ │ ├── rateLimit.middleware.ts │ │ └── error.middleware.ts │ │ │ ├── socket/ │ │ ├── index.ts # Socket.io 설정 │ │ └── chat.handler.ts # 채팅 이벤트 핸들러 │ │ │ ├── jobs/ │ │ └── searchQueue.ts # Bull 큐 │ │ │ └── types/ │ └── index.ts │ ├── packages/ │ └── database/ # Prisma 스키마 (공유) │ ├── package.json │ ├── prisma/ │ │ ├── schema.prisma │ │ └── migrations/ │ └── src/ │ └── index.ts # Prisma Client export │ ├── agent/ # Windows 자동화 에이전트 │ ├── requirements.txt │ ├── config.yaml │ │ │ ├── src/ │ │ ├── main.py # 엔트리포인트 │ │ ├── carmodoo_agent.py # 카모두 자동화 │ │ ├── api_client.py # 서버 API 클라이언트 │ │ ├── image_handler.py # 이미지 추출/업로드 │ │ └── utils.py │ │ │ └── tests/ │ └── test_agent.py │ ├── database/ # DB 스키마 및 시드 │ ├── schema.sql # PostgreSQL 스키마 │ ├── seed.sql # 초기 데이터 │ └── backup.sh # 백업 스크립트 │ ├── deploy/ # 배포 설정 │ ├── nginx/ │ │ └── default.conf │ ├── systemd/ │ │ ├── api.service │ │ └── web.service │ └── scripts/ │ ├── setup-server.sh # 서버 초기 설정 │ └── deploy.sh # 배포 스크립트 │ └── docs/ # 문서 ├── API.md # API 문서 ├── DEPLOYMENT.md # 배포 가이드 └── AGENT.md # 에이전트 설정 가이드 ``` --- ## 🗄️ 데이터베이스 스키마 ### ERD 개요 ``` ┌─────────────┐ ┌─────────────┐ ┌─────────────────┐ │ users │────<│view_history │>────│ vehicles │ └─────────────┘ └─────────────┘ └─────────────────┘ │ │ │◀───────────[referred_by] │ │ │ │ ┌─────────────┐ │ └───────────<│ payments │ │ │ └─────────────┘ │ │ │ │ │ ┌─────────────┐ │ │ │point_history│ │ │ └─────────────┘ │ │ │ │ ┌─────────────┐ │ └───────────<│ chat_rooms │>────────────┘ │ └─────────────┘ │ │ │ ┌─────────────┐ │ │chat_messages│ │ └─────────────┘ │ │ ┌──────────────────┐ └───────────<│dealer_commissions│ (현지딜러 수수료) └──────────────────┘ ``` ### 주요 테이블 ```sql -- 1. 사용자 (users) CREATE TABLE users ( id SERIAL PRIMARY KEY, email VARCHAR(255) UNIQUE NOT NULL, password_hash VARCHAR(255) NOT NULL, name VARCHAR(100), phone VARCHAR(20), country VARCHAR(50) DEFAULT 'MN', language VARCHAR(10) DEFAULT 'mn', -- 회원 유형 user_type VARCHAR(20) DEFAULT 'customer', -- 'customer', 'local_dealer', 'admin' -- 현지딜러 추천 시스템 (1단계 직접 추천) referred_by INTEGER REFERENCES users(id), -- 추천인 (현지딜러) referral_code VARCHAR(20) UNIQUE, -- 본인의 추천 코드 (딜러용) free_views_remaining INTEGER DEFAULT 3, point_balance DECIMAL(12,2) DEFAULT 0, status VARCHAR(20) DEFAULT 'active', created_at TIMESTAMP DEFAULT NOW(), updated_at TIMESTAMP DEFAULT NOW() ); -- 1-1. 회원 유형 (user_types) - 참조 테이블 CREATE TABLE user_types ( code VARCHAR(20) PRIMARY KEY, name_ko VARCHAR(50) NOT NULL, name_en VARCHAR(50) NOT NULL, name_mn VARCHAR(50), description TEXT, can_refer_customers BOOLEAN DEFAULT false, -- 고객 추천 가능 여부 commission_rate DECIMAL(4,2) DEFAULT 0, -- 기본 수수료율 (%) created_at TIMESTAMP DEFAULT NOW() ); INSERT INTO user_types (code, name_ko, name_en, name_mn, description, can_refer_customers, commission_rate) VALUES ('customer', '일반고객', 'Customer', 'Хэрэглэгч', '일반 구매 고객', false, 0), ('local_dealer', '현지딜러', 'Local Dealer', 'Орон нутгийн дилер', '몽골 현지 딜러 (고객 추천 가능)', true, 3.5), ('admin', '관리자', 'Administrator', 'Админ', '시스템 관리자', false, 0); -- 1-2. 현지딜러 정보 (dealer_profiles) CREATE TABLE dealer_profiles ( id SERIAL PRIMARY KEY, user_id INTEGER UNIQUE REFERENCES users(id) ON DELETE CASCADE, -- 사업자 정보 business_name VARCHAR(200), -- 상호명 business_registration_no VARCHAR(50), -- 사업자등록번호 business_address TEXT, -- 사업장 주소 business_phone VARCHAR(30), -- 사업장 전화번호 -- 딜러 등급 및 수수료 dealer_grade VARCHAR(20) DEFAULT 'standard', -- 'standard', 'silver', 'gold', 'platinum' commission_rate DECIMAL(4,2) DEFAULT 3.5, -- 개별 수수료율 (기본 3.5%) -- 은행 정보 (수수료 지급용) bank_name VARCHAR(100), bank_account_number VARCHAR(50), bank_account_holder VARCHAR(100), -- 활동 통계 total_referrals INTEGER DEFAULT 0, -- 총 추천 고객 수 total_sales_count INTEGER DEFAULT 0, -- 총 판매 건수 total_commission_earned DECIMAL(14,2) DEFAULT 0, -- 총 수령 수수료 -- 상태 verification_status VARCHAR(20) DEFAULT 'pending', -- 'pending', 'verified', 'rejected' verified_at TIMESTAMP, notes TEXT, created_at TIMESTAMP DEFAULT NOW(), updated_at TIMESTAMP DEFAULT NOW() ); -- 1-3. 딜러 등급 (dealer_grades) CREATE TABLE dealer_grades ( code VARCHAR(20) PRIMARY KEY, name_ko VARCHAR(50) NOT NULL, name_en VARCHAR(50) NOT NULL, name_mn VARCHAR(50), min_sales_count INTEGER DEFAULT 0, -- 승급 조건: 최소 판매 건수 commission_rate DECIMAL(4,2) NOT NULL, -- 등급별 수수료율 benefits TEXT, -- 혜택 설명 sort_order INTEGER DEFAULT 0, created_at TIMESTAMP DEFAULT NOW() ); INSERT INTO dealer_grades (code, name_ko, name_en, name_mn, min_sales_count, commission_rate, benefits, sort_order) VALUES ('standard', '일반', 'Standard', 'Стандарт', 0, 3.0, '기본 수수료율 적용', 1), ('silver', '실버', 'Silver', 'Мөнгө', 10, 3.5, '수수료율 0.5% 상향', 2), ('gold', '골드', 'Gold', 'Алт', 30, 4.0, '수수료율 1.0% 상향, 우선 배정', 3), ('platinum', '플래티넘', 'Platinum', 'Платин', 100, 4.5, '수수료율 1.5% 상향, 전담 매니저', 4); -- 2. 차량 (vehicles) CREATE TABLE vehicles ( id SERIAL PRIMARY KEY, source_id VARCHAR(100) UNIQUE, make VARCHAR(50) NOT NULL, model VARCHAR(100) NOT NULL, year INTEGER NOT NULL, mileage INTEGER, price DECIMAL(14,2), fuel_type VARCHAR(20), transmission VARCHAR(20), color VARCHAR(30), engine_cc INTEGER, options JSONB DEFAULT '{}', inspection_data JSONB DEFAULT '{}', accident_history JSONB DEFAULT '[]', status VARCHAR(20) DEFAULT 'active', view_count INTEGER DEFAULT 0, created_at TIMESTAMP DEFAULT NOW() ); -- 3. 차량 이미지 (vehicle_images) CREATE TABLE vehicle_images ( id SERIAL PRIMARY KEY, vehicle_id INTEGER REFERENCES vehicles(id) ON DELETE CASCADE, image_url VARCHAR(500) NOT NULL, thumbnail_url VARCHAR(500), image_type VARCHAR(30), sort_order INTEGER DEFAULT 0, created_at TIMESTAMP DEFAULT NOW() ); -- 4. 열람 기록 (view_history) CREATE TABLE view_history ( id SERIAL PRIMARY KEY, user_id INTEGER REFERENCES users(id), vehicle_id INTEGER REFERENCES vehicles(id), is_free BOOLEAN DEFAULT false, points_used DECIMAL(10,2) DEFAULT 0, viewed_at TIMESTAMP DEFAULT NOW(), UNIQUE(user_id, vehicle_id) ); -- 5. 결제 (payments) CREATE TABLE payments ( id SERIAL PRIMARY KEY, user_id INTEGER REFERENCES users(id), payment_id VARCHAR(100) UNIQUE, payment_type VARCHAR(20), amount_krw DECIMAL(12,2), amount_crypto DECIMAL(20,8), crypto_type VARCHAR(20), pay_address VARCHAR(200), tx_hash VARCHAR(100), points_added DECIMAL(12,2), status VARCHAR(20) DEFAULT 'pending', created_at TIMESTAMP DEFAULT NOW(), confirmed_at TIMESTAMP ); -- 6. 포인트 이력 (point_history) CREATE TABLE point_history ( id SERIAL PRIMARY KEY, user_id INTEGER REFERENCES users(id), amount DECIMAL(12,2) NOT NULL, type VARCHAR(20), description VARCHAR(200), balance_after DECIMAL(12,2), created_at TIMESTAMP DEFAULT NOW() ); -- 7. 채팅방 (chat_rooms) CREATE TABLE chat_rooms ( id SERIAL PRIMARY KEY, vehicle_id INTEGER REFERENCES vehicles(id), customer_id INTEGER REFERENCES users(id), dealer_id VARCHAR(50), status VARCHAR(20) DEFAULT 'active', last_message_at TIMESTAMP, created_at TIMESTAMP DEFAULT NOW() ); -- 8. 채팅 메시지 (chat_messages) CREATE TABLE chat_messages ( id BIGSERIAL PRIMARY KEY, room_id INTEGER REFERENCES chat_rooms(id), sender_id VARCHAR(50) NOT NULL, sender_type VARCHAR(20), original_text TEXT NOT NULL, original_language VARCHAR(10), translations JSONB DEFAULT '{}', is_faq_response BOOLEAN DEFAULT false, created_at TIMESTAMP DEFAULT NOW() ); -- 9. 검색 요청 큐 (search_requests) CREATE TABLE search_requests ( id SERIAL PRIMARY KEY, user_id INTEGER REFERENCES users(id), criteria JSONB NOT NULL, status VARCHAR(20) DEFAULT 'pending', result_count INTEGER, created_at TIMESTAMP DEFAULT NOW(), processed_at TIMESTAMP ); -- 10. 차량 크기 분류 (vehicle_size_types) CREATE TABLE vehicle_size_types ( id SERIAL PRIMARY KEY, code VARCHAR(20) UNIQUE NOT NULL, -- 'compact', 'midsize' name_ko VARCHAR(50) NOT NULL, name_en VARCHAR(50) NOT NULL, name_mn VARCHAR(50), max_per_container INTEGER NOT NULL, -- 컨테이너당 최대 적재 수량 created_at TIMESTAMP DEFAULT NOW() ); -- 초기 데이터 INSERT INTO vehicle_size_types (code, name_ko, name_en, name_mn, max_per_container) VALUES ('compact', '소형차', 'Compact Car', 'Жижиг машин', 4), ('midsize', '중형차', 'Midsize Car', 'Дунд машин', 2); -- 11. 수수료 항목 마스터 (fee_types) CREATE TABLE fee_types ( id SERIAL PRIMARY KEY, code VARCHAR(50) UNIQUE NOT NULL, category VARCHAR(30) NOT NULL, -- 'vehicle', 'container', 'terminal' name_ko VARCHAR(100) NOT NULL, name_en VARCHAR(100) NOT NULL, name_mn VARCHAR(100), calculation_type VARCHAR(20) NOT NULL, -- 'fixed', 'percentage', 'per_day', 'per_container', 'per_car' default_amount DECIMAL(14,2), percentage_rate DECIMAL(5,2), -- 퍼센트 계산 시 사용 is_shared BOOLEAN DEFAULT false, -- 컨테이너 비용 분담 여부 sort_order INTEGER DEFAULT 0, is_active BOOLEAN DEFAULT true, created_at TIMESTAMP DEFAULT NOW() ); -- 수수료 항목 초기 데이터 -- 차량별 비용 (vehicle) INSERT INTO fee_types (code, category, name_ko, name_en, calculation_type, default_amount, percentage_rate, is_shared, sort_order) VALUES ('performance_inspection', 'vehicle', '성능점검보험료', 'Performance inspection fee', 'fixed', 100000, NULL, false, 1), ('sales_fee', 'vehicle', '매도세', 'Sales fee', 'fixed', 440000, NULL, false, 2), ('brokerage_commission', 'vehicle', '매매알선수수료', 'Brokerage commission', 'fixed', 250000, NULL, false, 3), ('registration_tax', 'vehicle', '취등록세', 'Registration tax', 'fixed', 50000, NULL, false, 4), ('expiration_cost', 'vehicle', '말소', 'Expiration cost', 'fixed', 50000, NULL, false, 5), ('domestic_transport', 'vehicle', '국내 운송료', 'Domestic transportation charges', 'fixed', 160000, NULL, false, 6), ('yard_fee', 'vehicle', '야드비', 'Yard fee', 'per_day', 20000, NULL, false, 7), ('export_license', 'vehicle', '수출면장발급', 'Issuance of export exemption', 'fixed', 45000, NULL, false, 8), ('korean_margin', 'vehicle', '한국 마진', 'Korean Margin', 'percentage', NULL, 5.00, false, 9), ('mongolian_margin', 'vehicle', '몽골 마진', 'Mongolian Margin', 'percentage', NULL, 5.00, false, 10), -- 컨테이너 비용 (분담, container) ('shipping_cost', 'container', '운송비(기차 4주)', 'Shipping Cost (Train 4weeks)', 'per_container', 5220000, NULL, true, 11), ('shoring', 'container', '쇼링(컨테이너작업)', 'Shoring', 'per_container', 600000, NULL, true, 12), -- 터미널 비용 (분담, terminal) ('thc', 'terminal', '터미널 조작비용', 'THC(Terminal Handling Charge)', 'per_container', 190000, NULL, true, 13), ('wharfage', 'terminal', '부두하역료', 'Wharfage', 'per_container', 8400, NULL, true, 14), ('seal_fee', 'terminal', '컨테이너 실 비용', 'Seal Fee', 'per_container', 10000, NULL, true, 15), ('document_fee', 'terminal', '서류수수료', 'Document fee', 'per_container', 50000, NULL, true, 16); -- 12. 주문 (orders) CREATE TABLE orders ( id SERIAL PRIMARY KEY, order_number VARCHAR(50) UNIQUE NOT NULL, -- ORD-20241127-0001 user_id INTEGER REFERENCES users(id), vehicle_id INTEGER REFERENCES vehicles(id), vehicle_size_type_id INTEGER REFERENCES vehicle_size_types(id), vehicle_price DECIMAL(14,2) NOT NULL, -- 차량가액 total_fees DECIMAL(14,2) NOT NULL, -- 총 수수료 total_amount DECIMAL(14,2) NOT NULL, -- 총 결제금액 status VARCHAR(30) DEFAULT 'pending', -- pending, paid, processing, shipping, customs, delivered, cancelled payment_status VARCHAR(20) DEFAULT 'unpaid', -- unpaid, partial, paid notes TEXT, created_at TIMESTAMP DEFAULT NOW(), updated_at TIMESTAMP DEFAULT NOW() ); -- 13. 주문 수수료 상세 (order_fees) CREATE TABLE order_fees ( id SERIAL PRIMARY KEY, order_id INTEGER REFERENCES orders(id) ON DELETE CASCADE, fee_type_id INTEGER REFERENCES fee_types(id), fee_code VARCHAR(50) NOT NULL, fee_name_ko VARCHAR(100) NOT NULL, fee_name_en VARCHAR(100) NOT NULL, calculation_type VARCHAR(20) NOT NULL, base_amount DECIMAL(14,2), -- 기준 금액 quantity INTEGER DEFAULT 1, -- 일수 등 calculated_amount DECIMAL(14,2) NOT NULL, -- 최종 계산된 금액 is_shared BOOLEAN DEFAULT false, share_count INTEGER DEFAULT 1, -- 분담 차량 수 notes VARCHAR(200), created_at TIMESTAMP DEFAULT NOW() ); -- 14. 컨테이너 (containers) CREATE TABLE containers ( id SERIAL PRIMARY KEY, container_number VARCHAR(50) UNIQUE, -- CNTR-20241127-001 container_type VARCHAR(20) DEFAULT '40ft', -- 20ft, 40ft max_compact_cars INTEGER DEFAULT 4, -- 소형차 최대 적재량 max_midsize_cars INTEGER DEFAULT 2, -- 중형차 최대 적재량 (중형 4대 불가 규칙) current_compact_count INTEGER DEFAULT 0, current_midsize_count INTEGER DEFAULT 0, status VARCHAR(20) DEFAULT 'loading', -- loading, sealed, in_transit, arrived, cleared -- 출발/도착 정보 departure_port VARCHAR(100), -- 부산항 arrival_port VARCHAR(100), -- 울란바타르 -- 일정 estimated_departure_date DATE, actual_departure_date DATE, estimated_arrival_date DATE, actual_arrival_date DATE, -- 비용 정보 (컨테이너 비용은 적재된 차량들이 분담) shipping_cost DECIMAL(14,2), shoring_cost DECIMAL(14,2), terminal_cost DECIMAL(14,2), total_shared_cost DECIMAL(14,2), created_at TIMESTAMP DEFAULT NOW(), updated_at TIMESTAMP DEFAULT NOW() ); -- 15. 컨테이너-차량 매핑 (container_vehicles) CREATE TABLE container_vehicles ( id SERIAL PRIMARY KEY, container_id INTEGER REFERENCES containers(id) ON DELETE CASCADE, order_id INTEGER REFERENCES orders(id), vehicle_id INTEGER REFERENCES vehicles(id), vehicle_size_type VARCHAR(20) NOT NULL, -- 'compact', 'midsize' shared_cost_amount DECIMAL(14,2), -- 분담된 비용 loaded_at TIMESTAMP DEFAULT NOW() ); -- 16. 배송 추적 (shipment_tracking) CREATE TABLE shipment_tracking ( id SERIAL PRIMARY KEY, order_id INTEGER REFERENCES orders(id), container_id INTEGER REFERENCES containers(id), -- 위치 정보 current_location VARCHAR(200), latitude DECIMAL(10, 7), longitude DECIMAL(10, 7), location_type VARCHAR(30), -- 'port', 'railway', 'customs', 'warehouse', 'delivered' -- 상태 status VARCHAR(30) NOT NULL, -- preparing, departed_korea, in_transit, arrived_mongolia, customs_clearance, delivered status_detail VARCHAR(200), -- 예상 일정 estimated_arrival_date DATE, estimated_arrival_days INTEGER, -- 남은 예상 일수 -- 통관 정보 customs_status VARCHAR(30), -- pending, in_progress, cleared customs_document_number VARCHAR(100), updated_at TIMESTAMP DEFAULT NOW(), created_at TIMESTAMP DEFAULT NOW() ); -- 17. 배송 이력 (shipment_history) CREATE TABLE shipment_history ( id SERIAL PRIMARY KEY, order_id INTEGER REFERENCES orders(id), container_id INTEGER REFERENCES containers(id), status VARCHAR(30) NOT NULL, location VARCHAR(200), latitude DECIMAL(10, 7), longitude DECIMAL(10, 7), description_ko VARCHAR(300), description_en VARCHAR(300), description_mn VARCHAR(300), event_time TIMESTAMP DEFAULT NOW(), created_at TIMESTAMP DEFAULT NOW() ); -- 배송 상태 코드 참조 테이블 (shipment_status_codes) CREATE TABLE shipment_status_codes ( code VARCHAR(30) PRIMARY KEY, name_ko VARCHAR(100) NOT NULL, name_en VARCHAR(100) NOT NULL, name_mn VARCHAR(100), sort_order INTEGER, icon VARCHAR(50) -- 프론트엔드 아이콘 매핑용 ); INSERT INTO shipment_status_codes (code, name_ko, name_en, name_mn, sort_order, icon) VALUES ('preparing', '출고 준비 중', 'Preparing for shipment', 'Тээвэрлэлтэнд бэлтгэж байна', 1, 'package'), ('loaded', '컨테이너 적재 완료', 'Loaded into container', 'Чингэлэг ачигдсан', 2, 'truck'), ('departed_korea', '한국 출발', 'Departed from Korea', 'Солонгосоос гарсан', 3, 'ship'), ('in_transit_rail', '기차 운송 중', 'In transit (Rail)', 'Тээвэрлэж байна (Төмөр зам)', 4, 'train'), ('arrived_mongolia', '몽골 도착', 'Arrived in Mongolia', 'Монголд ирсэн', 5, 'flag'), ('customs_clearance', '통관 진행 중', 'Customs clearance in progress', 'Гаалийн бүрдүүлэлт хийгдэж байна', 6, 'clipboard'), ('customs_cleared', '통관 완료', 'Customs cleared', 'Гаалийн бүрдүүлэлт дууссан', 7, 'check'), ('ready_for_pickup', '인수 대기', 'Ready for pickup', 'Авахад бэлэн', 8, 'warehouse'), ('delivered', '인도 완료', 'Delivered', 'Хүргэгдсэн', 9, 'check-circle'); -- ===================================================== -- 현지딜러 수수료 시스템 (1단계 직접 추천 구조) -- ===================================================== -- 18. 딜러 수수료 내역 (dealer_commissions) CREATE TABLE dealer_commissions ( id SERIAL PRIMARY KEY, dealer_id INTEGER REFERENCES users(id), -- 현지딜러 (수수료 수령자) order_id INTEGER REFERENCES orders(id), -- 연결된 주문 customer_id INTEGER REFERENCES users(id), -- 추천받은 고객 -- 수수료 계산 vehicle_price DECIMAL(14,2) NOT NULL, -- 차량가액 mongolian_margin_rate DECIMAL(4,2) NOT NULL, -- 몽골 마진율 (전체 5%) dealer_commission_rate DECIMAL(4,2) NOT NULL, -- 딜러 수수료율 (3~4.5%) platform_rate DECIMAL(4,2) NOT NULL, -- 플랫폼 수수료율 (0.5~2%) dealer_commission_amount DECIMAL(14,2) NOT NULL, -- 딜러 수수료 금액 platform_amount DECIMAL(14,2) NOT NULL, -- 플랫폼 수수료 금액 -- 지급 정보 status VARCHAR(20) DEFAULT 'pending', -- 'pending', 'approved', 'paid', 'cancelled' payment_method VARCHAR(30), -- 'bank_transfer', 'crypto' payment_reference VARCHAR(100), -- 송금 참조번호 paid_at TIMESTAMP, notes TEXT, created_at TIMESTAMP DEFAULT NOW(), updated_at TIMESTAMP DEFAULT NOW() ); -- 19. 딜러 수수료 정산 (dealer_payouts) CREATE TABLE dealer_payouts ( id SERIAL PRIMARY KEY, dealer_id INTEGER REFERENCES users(id), payout_number VARCHAR(50) UNIQUE, -- PAY-20241127-001 -- 정산 기간 period_start DATE NOT NULL, period_end DATE NOT NULL, -- 정산 금액 total_orders INTEGER DEFAULT 0, -- 해당 기간 주문 건수 total_commission DECIMAL(14,2) NOT NULL, -- 총 수수료 deductions DECIMAL(14,2) DEFAULT 0, -- 공제액 (있을 경우) net_amount DECIMAL(14,2) NOT NULL, -- 실 지급액 -- 지급 정보 payment_method VARCHAR(30) NOT NULL, -- 'bank_transfer', 'crypto' bank_name VARCHAR(100), bank_account_number VARCHAR(50), payment_reference VARCHAR(100), status VARCHAR(20) DEFAULT 'pending', -- 'pending', 'processing', 'completed', 'failed' processed_at TIMESTAMP, completed_at TIMESTAMP, notes TEXT, created_at TIMESTAMP DEFAULT NOW() ); -- 20. 추천 코드 사용 이력 (referral_history) CREATE TABLE referral_history ( id SERIAL PRIMARY KEY, referral_code VARCHAR(20) NOT NULL, dealer_id INTEGER REFERENCES users(id), -- 코드 소유자 (딜러) customer_id INTEGER REFERENCES users(id), -- 코드 사용자 (고객) used_at TIMESTAMP DEFAULT NOW(), ip_address VARCHAR(50), user_agent TEXT ); ``` --- ## 🔌 API 명세 ### 인증 API | Method | Endpoint | 설명 | |--------|----------|------| | POST | `/api/auth/register` | 회원가입 | | POST | `/api/auth/login` | 로그인 | | POST | `/api/auth/logout` | 로그아웃 | | GET | `/api/auth/me` | 현재 사용자 정보 | | PUT | `/api/auth/profile` | 프로필 수정 | ### 차량 API | Method | Endpoint | 설명 | |--------|----------|------| | POST | `/api/vehicles/search` | 차량 검색 요청 | | GET | `/api/vehicles/search/:requestId` | 검색 결과 조회 | | GET | `/api/vehicles/:id` | 차량 상세 (포인트 차감) | | GET | `/api/vehicles/:id/preview` | 차량 미리보기 (무료) | ### 결제 API | Method | Endpoint | 설명 | |--------|----------|------| | POST | `/api/payment/card` | 카드 결제 생성 | | POST | `/api/payment/direct` | 직접 전송 주소 생성 | | POST | `/api/payment/webhook` | NOWPayments 웹훅 | | GET | `/api/payment/history` | 결제 내역 | ### 채팅 API | Method | Endpoint | 설명 | |--------|----------|------| | POST | `/api/chat/rooms` | 채팅방 생성 | | GET | `/api/chat/rooms` | 채팅방 목록 | | GET | `/api/chat/rooms/:id/messages` | 메시지 조회 | ### 주문/배송 API | Method | Endpoint | 설명 | |--------|----------|------| | POST | `/api/orders` | 주문 생성 | | GET | `/api/orders` | 내 주문 목록 | | GET | `/api/orders/:id` | 주문 상세 (수수료 내역 포함) | | GET | `/api/orders/:id/fees` | 주문 수수료 상세 조회 | | GET | `/api/tracking/:orderId` | 내차 위치 추적 | | GET | `/api/tracking/:orderId/history` | 배송 이력 조회 | ### 수수료 API | Method | Endpoint | 설명 | |--------|----------|------| | GET | `/api/fees` | 수수료 항목 목록 | | POST | `/api/fees/calculate` | 수수료 계산 (견적) | ### 컨테이너 API (관리자용) | Method | Endpoint | 설명 | |--------|----------|------| | POST | `/api/admin/containers` | 컨테이너 생성 | | POST | `/api/admin/containers/:id/vehicles` | 차량 적재 | | PUT | `/api/admin/containers/:id/status` | 컨테이너 상태 업데이트 | | PUT | `/api/admin/tracking/:orderId` | 배송 추적 정보 업데이트 | ### 현지딜러 API | Method | Endpoint | 설명 | |--------|----------|------| | POST | `/api/dealer/register` | 딜러 등록 신청 | | GET | `/api/dealer/profile` | 딜러 프로필 조회 | | PUT | `/api/dealer/profile` | 딜러 프로필 수정 | | GET | `/api/dealer/referrals` | 추천 고객 목록 | | GET | `/api/dealer/commissions` | 수수료 내역 조회 | | GET | `/api/dealer/commissions/summary` | 수수료 요약 (대시보드) | | GET | `/api/dealer/payouts` | 정산 내역 조회 | | POST | `/api/referral/apply` | 추천 코드 적용 (고객용) | | GET | `/api/referral/validate/:code` | 추천 코드 유효성 검증 | ### 딜러 관리 API (관리자용) | Method | Endpoint | 설명 | |--------|----------|------| | GET | `/api/admin/dealers` | 딜러 목록 조회 | | PUT | `/api/admin/dealers/:id/verify` | 딜러 승인/거부 | | PUT | `/api/admin/dealers/:id/grade` | 딜러 등급 변경 | | POST | `/api/admin/payouts` | 정산 처리 | | GET | `/api/admin/commissions/report` | 수수료 리포트 | ### 에이전트 API (내부용) | Method | Endpoint | 설명 | |--------|----------|------| | GET | `/api/agent/pending-searches` | 대기 중인 검색 요청 | | POST | `/api/agent/search-results` | 검색 결과 전송 | | POST | `/api/agent/vehicle-detail` | 차량 상세 정보 전송 | | POST | `/api/agent/upload-images` | 이미지 업로드 | --- ## 👥 현지딜러 시스템 (1단계 직접 추천 구조) ### 시스템 개요 ``` ┌─────────────────────────────────────────────────────────────────────────┐ │ 1단계 직접 추천 구조 │ ├─────────────────────────────────────────────────────────────────────────┤ │ │ │ ┌─────────────────────────────────────────────────────────────┐ │ │ │ 플랫폼 운영사 │ │ │ │ (한국 마진 5% 수령) │ │ │ └─────────────────────────────────────────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌─────────────────────────────────────────────────────────────┐ │ │ │ 몽골 마진 5% │ │ │ │ │ │ │ │ │ ┌─────────────────┴─────────────────┐ │ │ │ │ ▼ ▼ │ │ │ │ ┌──────────────┐ ┌──────────────┐ │ │ │ │ │ 현지딜러 몫 │ │ 플랫폼 몫 │ │ │ │ │ │ 3~4.5% │ │ 0.5~2% │ │ │ │ │ └──────────────┘ └──────────────┘ │ │ │ └─────────────────────────────────────────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌─────────────────────────────────────────────────────────────┐ │ │ │ 현지딜러 │ │ │ │ • 고객에게 추천 코드 제공 │ │ │ │ • 고객이 차량 구매 시 수수료 수령 │ │ │ │ • 등급에 따라 수수료율 차등 │ │ │ └──────────────────────┬──────────────────────────────────────┘ │ │ │ │ │ ┌───────────────┼───────────────┐ │ │ ▼ ▼ ▼ │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ │ 고객 A │ │ 고객 B │ │ 고객 C │ │ │ └──────────┘ └──────────┘ └──────────┘ │ │ │ │ ✅ 핵심 규칙: │ │ • 딜러가 직접 추천한 고객만 수수료 지급 (1단계만) │ │ • 고객이 다시 다른 고객을 추천해도 원래 딜러에게 수수료 없음 │ │ • 다단계 구조 아님 → 법적 문제 없음 │ └─────────────────────────────────────────────────────────────────────────┘ ``` ### 회원 유형 | 유형 | 설명 | 추천 가능 | 수수료 수령 | |------|------|----------|------------| | **일반고객 (customer)** | 차량 구매 고객 | ❌ | ❌ | | **현지딜러 (local_dealer)** | 몽골 현지 딜러 | ✅ | ✅ | | **관리자 (admin)** | 시스템 관리자 | ❌ | ❌ | ### 현지딜러 등급 및 수수료율 | 등급 | 조건 | 수수료율 | 혜택 | |------|------|---------|------| | **일반 (Standard)** | 기본 | 3.0% | 기본 수수료율 적용 | | **실버 (Silver)** | 10건 이상 판매 | 3.5% | 수수료율 0.5%p 상향 | | **골드 (Gold)** | 30건 이상 판매 | 4.0% | 수수료율 1.0%p 상향, 우선 배정 | | **플래티넘 (Platinum)** | 100건 이상 판매 | 4.5% | 수수료율 1.5%p 상향, 전담 매니저 | ### 수수료 계산 예시 ``` 차량가: ₩25,000,000 몽골 마진 (5%): ₩1,250,000 ┌─────────────────────────────────────────────────────────────┐ │ 딜러 등급별 수수료 배분 │ ├─────────────────┬─────────────┬─────────────┬───────────────┤ │ 딜러 등급 │ 딜러 수수료 │ 플랫폼 몫 │ 합계 (5%) │ ├─────────────────┼─────────────┼─────────────┼───────────────┤ │ 일반 (3.0%) │ ₩750,000 │ ₩500,000 │ ₩1,250,000 │ │ 실버 (3.5%) │ ₩875,000 │ ₩375,000 │ ₩1,250,000 │ │ 골드 (4.0%) │ ₩1,000,000 │ ₩250,000 │ ₩1,250,000 │ │ 플래티넘 (4.5%) │ ₩1,125,000 │ ₩125,000 │ ₩1,250,000 │ └─────────────────┴─────────────┴─────────────┴───────────────┘ ※ 추천인 없는 직접 구매 시: 플랫폼이 5% 전액 수령 ``` ### 추천 시스템 플로우 ``` 1. 딜러 등록 ┌──────────────────────────────────────────────────────────┐ │ 현지딜러 신청 → 서류 심사 → 승인 → 추천 코드 발급 │ │ │ │ 예: 추천코드 "DEALER-ABC123" │ └──────────────────────────────────────────────────────────┘ 2. 고객 추천 ┌──────────────────────────────────────────────────────────┐ │ 딜러가 고객에게 추천 코드 제공 │ │ ↓ │ │ 고객이 회원가입 시 추천 코드 입력 │ │ ↓ │ │ 고객 계정에 referred_by = 딜러 ID 저장 │ └──────────────────────────────────────────────────────────┘ 3. 차량 구매 ┌──────────────────────────────────────────────────────────┐ │ 고객이 차량 구매 완료 │ │ ↓ │ │ 시스템이 고객의 추천인(딜러) 확인 │ │ ↓ │ │ 딜러 수수료 자동 계산 및 기록 │ │ ↓ │ │ 월별/주별 정산 후 딜러에게 지급 │ └──────────────────────────────────────────────────────────┘ ``` ### 딜러 대시보드 기능 ``` ┌─────────────────────────────────────────────────────────────┐ │ 딜러 대시보드 (My Dashboard) │ ├─────────────────────────────────────────────────────────────┤ │ │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │ │ 추천 고객 │ │ 이번달 판매 │ │ 총 수수료 │ │ │ │ 127명 │ │ 5건 │ │ ₩4,750,000 │ │ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │ │ │ 내 등급: 🥇 골드 (다음 등급까지 8건) │ │ 수수료율: 4.0% │ │ 추천 코드: DEALER-ABC123 [복사] │ │ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ 최근 수수료 내역 │ │ │ │ ────────────────────────────────────────────────── │ │ │ │ 2024.11.25 소나타 DN8 ₩1,000,000 지급완료 │ │ │ │ 2024.11.20 아반떼 CN7 ₩800,000 지급완료 │ │ │ │ 2024.11.15 K5 DL3 ₩950,000 지급대기 │ │ │ └─────────────────────────────────────────────────────┘ │ │ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ 내 추천 고객 목록 │ │ │ │ ────────────────────────────────────────────────── │ │ │ │ 바트수흐 bat***@email.com 가입일: 2024.11.01 │ │ │ │ 엥흐바야르 enk***@email.com 가입일: 2024.10.15 │ │ │ │ ... │ │ │ └─────────────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────┘ ``` ### 정산 주기 | 구분 | 주기 | 최소 지급액 | 지급일 | |------|------|-----------|--------| | **일반 정산** | 월 1회 | ₩100,000 | 매월 10일 | | **VIP 정산** | 주 1회 | ₩500,000 | 매주 금요일 | --- ## 🚚 수수료 체계 및 비용 구조 ### 차량별 비용 (1대 기준) | 내역 | Detail | 단가 | 계산 방식 | |------|--------|------|----------| | 차량가액 | Vehicle value | 변동 | 차량별 상이 | | 성능점검보험료 | Performance inspection fee | ₩100,000 | 고정 | | 매도세 | Sales fee | ₩440,000 | 고정 | | 매매알선수수료 | Brokerage commission | ₩250,000 | 고정 | | 취등록세 | Registration tax | ₩50,000 | 고정 | | 말소 | Expiration cost | ₩50,000 | 고정 | | 국내 운송료 | Domestic transportation charges | ₩160,000 | 고정 | | 야드비 | Yard fee (₩20,000/일) | ₩60,000~ | 일수 × 20,000 | | 수출면장발급 | Issuance of export exemption | ₩45,000 | 고정 | | 한국 마진 | Korean Margin (5%) | 차량가 × 5% | 퍼센트 | | 몽골 마진 | Mongolian Margin (5%) | 차량가 × 5% | 퍼센트 | ### 컨테이너 비용 (4대 분담) | 내역 | Detail | 컨테이너당 | 차량당(4대 분담) | |------|--------|-----------|----------------| | 운송비(기차 4주) | Shipping Cost (Train 4weeks) | ₩5,220,000 | ₩1,305,000 | | 쇼링(컨테이너작업) | Shoring | ₩600,000 | ₩150,000 | ### 터미널 비용 (4대 분담) | 내역 | Detail | 컨테이너당 | 차량당(4대 분담) | |------|--------|-----------|----------------| | 터미널 조작비용 | THC (Terminal Handling Charge) | ₩190,000 | ₩47,500 | | 부두하역료 | Wharfage | ₩8,400 | ₩2,100 | | 컨테이너 실 비용 | Seal Fee | ₩10,000 | ₩2,500 | | 서류수수료 | Document fee | ₩50,000 | ₩12,500 | ### 비용 계산 예시 (차량가 ₩25,000,000 기준) ``` 차량별 비용 소계: ₩28,655,000 - 차량가액: ₩25,000,000 - 성능점검보험료: ₩100,000 - 매도세: ₩440,000 - 매매알선수수료: ₩250,000 - 취등록세: ₩50,000 - 말소: ₩50,000 - 국내 운송료: ₩160,000 - 야드비(3일): ₩60,000 - 수출면장발급: ₩45,000 - 한국 마진(5%): ₩1,250,000 - 몽골 마진(5%): ₩1,250,000 컨테이너 분담 비용 소계 (4대 분담시): ₩1,519,600 - 운송비 분담: ₩1,305,000 - 쇼링 분담: ₩150,000 - THC 분담: ₩47,500 - 부두하역료 분담: ₩2,100 - Seal Fee 분담: ₩2,500 - 서류수수료 분담: ₩12,500 총계: ₩30,174,600 ``` --- ## 🚢 컨테이너 적재 규칙 ### 차량 크기 분류 | 분류 | 예시 차종 | 컨테이너당 최대 | |------|----------|----------------| | **소형차 (Compact)** | 모닝, 스파크, 레이, i10, i20 등 | 4대 | | **중형차 (Midsize)** | 아반떼, K3, 소나타, K5, 싼타페 등 | 2대 | ### 적재 조합 규칙 1대의 컨테이너(40ft)에 다음 조합만 가능: | 조합 | 소형차 | 중형차 | 총 차량 수 | 가능 여부 | |------|--------|--------|-----------|----------| | A | 4대 | 0대 | 4대 | ✅ 가능 | | B | 2대 | 2대 | 4대 | ✅ 가능 | | C | 0대 | 2대 | 2대 | ✅ 가능 | | D | 3대 | 1대 | 4대 | ✅ 가능 | | E | 1대 | 2대 | 3대 | ✅ 가능 | | F | 0대 | 4대 | 4대 | ❌ **불가능** | > **중요**: 중형차 4대 조합은 물리적 공간 제약으로 불가능합니다. ### 비용 분담 계산 컨테이너 공유 비용은 적재된 차량 수로 균등 분담: ``` 분담 비용 = 컨테이너 총 비용 ÷ 적재 차량 수 예시: - 4대 적재시: ₩6,078,400 ÷ 4 = ₩1,519,600/대 - 3대 적재시: ₩6,078,400 ÷ 3 = ₩2,026,133/대 - 2대 적재시: ₩6,078,400 ÷ 2 = ₩3,039,200/대 ``` --- ## 📍 내차찾기 (Vehicle Tracking) ### 기능 개요 차량 구매 고객이 자신의 차량 배송 현황을 실시간으로 확인할 수 있는 서비스 ### 주요 기능 1. **지도 표시** - 한국 → 몽골 운송 경로 시각화 - 현재 차량 위치 마커 표시 - 주요 경유지 표시 (부산항, 중국 경유, 울란바타르) 2. **배송 상태 추적** - 단계별 진행 상황 표시 - 예상 도착일 표시 - 잔여 일수 카운트다운 3. **배송 이력** - 타임라인 형태의 상세 이력 - 각 단계별 날짜/시간 - 다국어 설명 (몽골어/영어/러시아어/한국어) ### 배송 상태 단계 ``` 1. 출고 준비 중 (Preparing for shipment) ↓ 2. 컨테이너 적재 완료 (Loaded into container) ↓ 3. 한국 출발 (Departed from Korea) ↓ 4. 기차 운송 중 (In transit - Rail) [약 4주 소요] ↓ 5. 몽골 도착 (Arrived in Mongolia) ↓ 6. 통관 진행 중 (Customs clearance in progress) ↓ 7. 통관 완료 (Customs cleared) ↓ 8. 인수 대기 (Ready for pickup) ↓ 9. 인도 완료 (Delivered) ``` ### 운송 경로 (예상 소요 시간) ``` 부산항 → (기차 4주) → 중국 경유 → 울란바타르 - 총 예상 소요 기간: 28~35일 - 통관 소요 기간: 3~7일 (추가) ``` ### UI/UX 설계 ``` ┌─────────────────────────────────────────────────────────────┐ │ 내 차 찾기 (Track My Vehicle) │ ├─────────────────────────────────────────────────────────────┤ │ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ │ │ │ │ [ 지도 영역 ] │ │ │ │ │ │ │ │ 부산 ●━━━━━━━●━━━━━🚗━━━━━━━━━━━━● 울란바타르 │ │ │ │ 중국 │ │ │ │ │ │ │ └─────────────────────────────────────────────────────┘ │ │ │ │ 현재 상태: 🚂 기차 운송 중 │ │ 예상 도착일: 2024년 12월 25일 (D-18) │ │ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ 배송 이력 │ │ │ │ ───────────────────────────────────────────────── │ │ │ │ ✅ 2024.11.20 출고 준비 완료 │ │ │ │ ✅ 2024.11.22 컨테이너 적재 완료 │ │ │ │ ✅ 2024.11.25 한국 출발 (부산항) │ │ │ │ 🔵 2024.11.27 기차 운송 중 (현재) │ │ │ │ ⭕ 예정 몽골 도착 │ │ │ │ ⭕ 예정 통관 진행 │ │ │ │ ⭕ 예정 인도 완료 │ │ │ └─────────────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────┘ ``` ### 프론트엔드 구조 ``` apps/web/src/app/[locale]/ └── mypage/ └── tracking/ ├── page.tsx # 내 차량 목록 └── [orderId]/ └── page.tsx # 상세 추적 페이지 apps/web/src/components/ └── tracking/ ├── TrackingMap.tsx # 지도 컴포넌트 ├── TrackingStatus.tsx # 현재 상태 표시 ├── TrackingTimeline.tsx # 배송 이력 타임라인 └── EstimatedArrival.tsx # 예상 도착일 표시 ``` ### 지도 서비스 옵션 | 서비스 | 장점 | 단점 | |--------|------|------| | **Leaflet + OpenStreetMap** | 무료, 커스터마이징 가능 | 기본 스타일 제한 | | **Mapbox** | 고품질, 커스터마이징 | 유료 (월 50,000뷰 무료) | | **Google Maps** | 신뢰성, 정확도 | 비용, 몽골 지역 상세도 낮음 | > **권장**: Leaflet + OpenStreetMap (무료 + 충분한 기능) --- ## 💰 과금 시스템 (CC 코인 기반) ### 🪙 CC (AutonetSellCar Coin) 시스템 | 항목 | 내용 | |------|------| | **기준 화폐** | USDC (Solana 네트워크) | | **내부 화폐** | CC (AutonetSellCar Coin) | | **환율** | 1 USDC = 10 CC | | **신규 가입 보너스** | 3 CC 무상 지급 | | **차량 정보 열람** | 1대당 1 CC | ### 📸 차량 정보 공개 정책 | 구분 | 비회원/무료 | CC 결제 후 | |------|-------------|------------| | **대표 이미지** | 2장만 공개 | 전체 공개 | | **상세 이미지** | 🔒 블러 처리 | ✅ 전체 공개 | | **차량 성능표** | 🔒 접근 불가 | ✅ 열람 가능 | | **연락처** | 🔒 비공개 | ✅ DamonHong +82-10-3331-5258 | | **상세 옵션** | 🔒 비공개 | ✅ 공개 | ``` ┌─────────────────────────────────────────────────────────────────┐ │ 차량 상세 페이지 구조 │ ├─────────────────────────────────────────────────────────────────┤ │ ┌─────────────────────────────────────────────────────────┐ │ │ │ [대표이미지 1] [대표이미지 2] [🔒 블러] [🔒 블러] │ │ │ │ 무료로 볼 수 있는 사진 │ │ │ └─────────────────────────────────────────────────────────┘ │ │ │ │ ┌─────────────────────────────────────────────────────────┐ │ │ │ 기본 정보 (무료 공개) │ │ │ │ • 차량명: 기아 K5 2024년형 │ │ │ │ • 연식: 2024년 7월 │ │ │ │ • 주행거리: 14,605 km │ │ │ │ • 가격: $28,500 USDC │ │ │ └─────────────────────────────────────────────────────────┘ │ │ │ │ ┌─────────────────────────────────────────────────────────┐ │ │ │ 🔒 상세 정보 열람하기 (1 CC 필요) │ │ │ │ │ │ │ │ ┌──────────────────────────────────────────────────┐ │ │ │ │ │ [1 CC로 상세 정보 열람하기] │ │ │ │ │ │ │ │ │ │ │ │ 포함 내용: │ │ │ │ │ │ ✓ 전체 사진 (20장) │ │ │ │ │ │ ✓ 차량 성능표 │ │ │ │ │ │ ✓ 상세 옵션 목록 │ │ │ │ │ │ ✓ 연락처 (DamonHong +82-10-3331-5258) │ │ │ │ │ └──────────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────────┘ ``` ### 💳 결제 방식 | 방식 | 설명 | 수수료 | 구현 우선순위 | |------|------|--------|---------------| | **카드 결제** | Visa/Mastercard → USDC 자동 변환 | ~3% | Phase 1 | | **Solana USDC 전송** | 사용자 지갑에서 직접 전송 | <$0.01 | Phase 1 | | **Phantom Wallet 연동** | 원클릭 결제 | <$0.01 | Phase 2 | | **TRC-20 USDT** | Tron 네트워크 (레거시 지원) | ~1 USDT | Phase 3 | ### 💼 사용자 지갑 시스템 ``` ┌─────────────────────────────────────────────────────────────────┐ │ 사용자 지갑 구조 │ ├─────────────────────────────────────────────────────────────────┤ │ │ │ ┌─────────────────────────────────────────────────────────┐ │ │ │ 사용자 계정 (users 테이블) │ │ │ │ ├── user_id: 12345 │ │ │ │ ├── email: user@example.com │ │ │ │ ├── cc_balance: 23 CC (현재 보유 코인) │ │ │ │ └── solana_wallet_address: "ABC123..." │ │ │ └─────────────────────────────────────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌─────────────────────────────────────────────────────────┐ │ │ │ 플랫폼 Solana 지갑 (수신 전용) │ │ │ │ ├── 주소: "PLATFORM_WALLET_ADDRESS..." │ │ │ │ ├── USDC 수신 → 자동 CC 변환 (1 USDC = 10 CC) │ │ │ │ └── 관리자만 출금 가능 │ │ │ └─────────────────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────────┘ ``` ### 📊 CC 거래 내역 관리 ```sql -- cc_transactions 테이블 CREATE TABLE cc_transactions ( id SERIAL PRIMARY KEY, user_id INTEGER REFERENCES users(id), type VARCHAR(20) NOT NULL, -- 'purchase', 'spend', 'bonus', 'refund' amount INTEGER NOT NULL, -- CC 금액 (양수: 획득, 음수: 사용) balance_after INTEGER NOT NULL, -- 거래 후 잔액 reference_type VARCHAR(50), -- 'car_view', 'usdc_payment', 'card_payment', 'signup_bonus' reference_id VARCHAR(100), -- 관련 ID (차량 ID, 결제 ID 등) usdc_amount DECIMAL(12,2), -- USDC 결제 시 금액 tx_hash VARCHAR(100), -- Solana 트랜잭션 해시 (USDC 결제 시) created_at TIMESTAMP DEFAULT NOW() ); -- 차량 열람 기록 CREATE TABLE car_views ( id SERIAL PRIMARY KEY, user_id INTEGER REFERENCES users(id), car_id INTEGER REFERENCES cars(id), cc_spent INTEGER DEFAULT 1, viewed_at TIMESTAMP DEFAULT NOW(), UNIQUE(user_id, car_id) -- 동일 차량 중복 결제 방지 ); ``` ### 💰 가격 정책 > **CC 사용 기준**: 1 CC = 10대 차량 추천 받을 수 있음 | 충전 금액 (USD) | 받는 CC | 추천 가능 차량 | 할인율 | |-----------------|---------|----------------|--------| | $10 | 10 CC | 100대 | - | | $27 | 30 CC | 300대 | 10% 할인 | | $40 | 50 CC | 500대 | 20% 할인 | ※ 결제 수단: Stripe (Visa/Mastercard), 몽골 파트너 계좌 (러시아 사용자) --- ## 🔐 Solana USDC 지갑 통합 계획 ### Phase 1: 기본 지갑 시스템 #### 1.1 플랫폼 수신 지갑 생성 ``` ┌─────────────────────────────────────────────────────────────────┐ │ 플랫폼 지갑 아키텍처 │ ├─────────────────────────────────────────────────────────────────┤ │ │ │ [플랫폼 메인 지갑] │ │ ├── 주소: 공개 (사용자가 입금할 주소) │ │ ├── 비밀키: 서버에서 안전하게 관리 (환경변수/Vault) │ │ ├── 용도: USDC 수신 전용 │ │ └── 모니터링: Webhook으로 입금 감지 │ │ │ │ [관리자 출금 지갑] │ │ ├── 주소: 비공개 │ │ ├── 비밀키: 콜드 스토리지 / 하드웨어 지갑 │ │ └── 용도: 수익금 출금 │ │ │ └─────────────────────────────────────────────────────────────────┘ ``` #### 1.2 USDC 입금 감지 시스템 ```python # Solana USDC 입금 감지 서비스 class SolanaPaymentService: def __init__(self): self.rpc_url = "https://api.mainnet-beta.solana.com" self.usdc_mint = "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v" # USDC SPL Token self.platform_wallet = os.getenv("PLATFORM_WALLET_ADDRESS") async def monitor_deposits(self): """Webhook 또는 폴링으로 입금 감지""" # 1. 새 USDC 전송 감지 # 2. 메모 필드에서 user_id 추출 # 3. CC 크레딧 자동 지급 # 4. 트랜잭션 기록 저장 pass async def credit_user(self, user_id: int, usdc_amount: float, tx_hash: str): """USDC 입금 시 CC 자동 지급""" cc_amount = int(usdc_amount * 10) # 1 USDC = 10 CC # DB에 CC 잔액 업데이트 및 거래 기록 pass ``` #### 1.3 입금 프로세스 (사용자 관점) ``` 1. 사용자가 "CC 충전하기" 클릭 2. 입금 안내 페이지 표시: - 플랫폼 Solana 지갑 주소 - 메모(Memo): USER_12345 (사용자 식별용) - QR 코드 (Solana Pay 호환) 3. 사용자가 Phantom/Solflare 등에서 USDC 전송 4. 서버가 입금 감지 (1-5초 내) 5. 자동으로 CC 잔액 증가 6. 푸시 알림 또는 화면 갱신 ``` ### Phase 2: Phantom Wallet 연동 (원클릭 결제) #### 2.1 Solana Pay 통합 ```typescript // Solana Pay를 이용한 원클릭 결제 import { createQR, encodeURL, TransactionRequestURL } from '@solana/pay'; const createPaymentRequest = (userId: string, usdcAmount: number) => { const url: TransactionRequestURL = { recipient: PLATFORM_WALLET, amount: new BigNumber(usdcAmount), splToken: USDC_MINT, reference: generateReference(), label: 'MongolCar CC 충전', message: `${usdcAmount} USDC → ${usdcAmount * 10} CC`, memo: `USER_${userId}`, }; return encodeURL(url); }; ``` #### 2.2 Phantom Wallet Connect ```typescript // Phantom 지갑 연결 const connectPhantom = async () => { if (window.solana?.isPhantom) { const response = await window.solana.connect(); const publicKey = response.publicKey.toString(); // 사용자 계정에 지갑 주소 연결 await api.linkWallet(publicKey); } }; // 원클릭 USDC 결제 const payWithPhantom = async (usdcAmount: number) => { const transaction = await buildUSDCTransferTx(usdcAmount); const signedTx = await window.solana.signTransaction(transaction); const txHash = await connection.sendRawTransaction(signedTx.serialize()); return txHash; }; ``` ### Phase 3: 카드 결제 통합 #### 3.1 결제 게이트웨이 옵션 | 서비스 | 특징 | 수수료 | 지원 통화 | |--------|------|--------|-----------| | **Stripe** | 글로벌, 안정적 | 2.9% + $0.30 | USD, EUR, KRW | | **MoonPay** | 암호화폐 특화 | 4.5% | USDC 직접 구매 | | **Transak** | 암호화폐 특화 | 3-5% | USDC 직접 구매 | | **KG이니시스** | 한국 결제 | 3.3% | KRW | #### 3.2 카드 → USDC 변환 플로우 ``` 1. 사용자가 충전 금액 선택 (예: $10) 2. Stripe/MoonPay 결제 창 열림 3. 카드 결제 완료 4. 서버에서 결제 확인 5. CC 잔액 자동 증가 (100 CC) 6. 완료 알림 ``` ### 📁 필요한 DB 스키마 추가 ```sql -- 사용자 테이블 확장 ALTER TABLE users ADD COLUMN cc_balance INTEGER DEFAULT 0; ALTER TABLE users ADD COLUMN solana_wallet_address VARCHAR(44); ALTER TABLE users ADD COLUMN linked_wallet_verified BOOLEAN DEFAULT FALSE; -- USDC 결제 기록 CREATE TABLE usdc_payments ( id SERIAL PRIMARY KEY, user_id INTEGER REFERENCES users(id), tx_hash VARCHAR(100) UNIQUE NOT NULL, from_wallet VARCHAR(44) NOT NULL, usdc_amount DECIMAL(12,6) NOT NULL, cc_credited INTEGER NOT NULL, bonus_cc INTEGER DEFAULT 0, status VARCHAR(20) DEFAULT 'confirmed', -- pending, confirmed, failed confirmed_at TIMESTAMP, created_at TIMESTAMP DEFAULT NOW() ); -- 카드 결제 기록 CREATE TABLE card_payments ( id SERIAL PRIMARY KEY, user_id INTEGER REFERENCES users(id), payment_provider VARCHAR(20) NOT NULL, -- stripe, moonpay, transak provider_payment_id VARCHAR(100) UNIQUE, amount_usd DECIMAL(10,2) NOT NULL, cc_credited INTEGER NOT NULL, bonus_cc INTEGER DEFAULT 0, status VARCHAR(20) DEFAULT 'pending', completed_at TIMESTAMP, created_at TIMESTAMP DEFAULT NOW() ); ``` ### 🛠️ 구현 우선순위 | 순서 | 기능 | 예상 기간 | 설명 | |------|------|-----------|------| | 1 | CC 시스템 기본 구조 | 1주 | users 테이블 확장, cc_transactions 테이블, 잔액 관리 API | | 2 | 차량 상세 열람 잠금 | 1주 | 사진 블러 처리, 상세 정보 잠금, CC 차감 로직 | | 3 | 관리자 CC 수동 지급 | 2일 | 테스트/프로모션용 수동 지급 기능 | | 4 | Solana 지갑 생성 | 3일 | 플랫폼 수신 지갑 생성, 주소 공개 | | 5 | USDC 입금 감지 | 1주 | Solana RPC 모니터링, 자동 CC 지급 | | 6 | Phantom Wallet 연동 | 1주 | 지갑 연결, Solana Pay QR 생성 | | 7 | 카드 결제 (Stripe) | 1주 | 결제 위젯, 웹훅 처리 | | 8 | MoonPay/Transak 통합 | 1주 | 암호화폐 직접 구매 옵션 | --- ## 🌐 다국어 지원 ### 지원 언어 | 코드 | 언어 | 용도 | |------|------|------| | `mn` | 몽골어 (Монгол) | 기본 언어 | | `en` | 영어 (English) | 국제 | | `ru` | 러시아어 (Русский) | 러시아, 중앙아시아 | | `ko` | 한국어 | 관리자, 딜러 | ### 번역 대상 - UI 텍스트 (정적) - 차량 정보 (동적 - AI 번역) - 채팅 메시지 (실시간 - Claude API) - FAQ 응답 (사전 번역 + AI) --- ## 💬 AI 채팅 시스템 ### 기능 1. **실시간 번역**: 몽골어 ↔ 한국어 양방향 2. **FAQ 자동 응답**: 딜러 부재 시 AI가 응답 3. **맥락 인식**: 문의 중인 차량 정보 반영 ### FAQ 카테고리 | 카테고리 | 예시 질문 | |----------|-----------| | `shipping` | 배송 기간, 방법 | | `payment` | 결제 방법, 환불 | | `document` | 필요 서류, 관세 | | `vehicle` | 차량 상태, 옵션 | | `general` | 영업시간, 연락처 | --- ## 🔧 개발 단계별 작업 ### Phase 1: 인프라 구축 (1주) **목표**: 서버 환경 설정 및 기본 인프라 구축 ```bash # 작업 목록 □ 우분투 서버 2대 OS 설치 및 기본 설정 □ PostgreSQL 16 설치 및 설정 □ Redis 7 설치 □ Nginx 설치 및 SSL 설정 □ Node.js 20 LTS 설치 □ PM2 설치 □ 방화벽 설정 □ SSH 키 기반 인증 설정 □ 서버 간 내부 네트워크 설정 □ 데이터베이스 스키마 생성 ``` **Claude Code 명령 예시**: ``` 서버 초기 설정 스크립트 작성해줘 (deploy/scripts/setup-server.sh) - PostgreSQL 16 설치 - Redis 7 설치 - Nginx 설치 - Node.js 20 설치 - PM2 전역 설치 - 기본 보안 설정 ``` --- ### Phase 2: Windows 에이전트 (2~3주) ⭐ 핵심 **목표**: 카모두 프로그램 자동화 ```bash # 작업 목록 □ 카모두 프로그램 UI 구조 분석 (Inspect.exe) □ Python 에이전트 기본 구조 개발 □ 프로그램 연결 기능 □ 차량 검색 자동화 □ 검색 결과 추출 □ 상세 정보 추출 □ 이미지 추출 (20장) □ API 클라이언트 연동 □ 에러 처리 및 재시도 로직 □ 로깅 시스템 □ Windows 서비스로 등록 ``` **Claude Code 명령 예시**: ``` 카모두 프로그램 자동화 에이전트 개발해줘 (agent/src/) - pywinauto 기반 - 검색 조건: 제조사, 모델, 연식, 마일리지, 가격 - 결과 추출: 기본 정보 + 상세 정보 + 이미지 20장 - 비동기 처리 (asyncio) - API 서버와 통신 ``` --- ### Phase 3: 백엔드 API (2주) **목표**: REST API 서버 개발 ```bash # 작업 목록 □ Express.js 프로젝트 설정 □ Prisma 스키마 및 마이그레이션 □ 인증 API (회원가입/로그인/JWT) □ 차량 검색 API □ 차량 상세 조회 API (포인트 차감) □ 결제 API (카드/직접전송) □ NOWPayments 웹훅 처리 □ 포인트 관리 API □ 채팅 API □ 에이전트 통신 API □ Bull 큐 (검색 요청 처리) □ 에러 핸들링 □ API 문서화 (Swagger) ``` **Claude Code 명령 예시**: ``` Express.js 백엔드 API 개발해줘 (apps/api/src/) - TypeScript 기반 - Prisma ORM - JWT 인증 - 차량 검색/조회 API - 결제 API (NOWPayments 연동) - Socket.io 채팅 ``` --- ### Phase 4: 프론트엔드 (2주) **목표**: Next.js 웹 애플리케이션 개발 ```bash # 작업 목록 □ Next.js 14 프로젝트 설정 □ 다국어 설정 (next-intl) □ 레이아웃 및 공통 컴포넌트 □ 메인 페이지 (차량 검색 폼) □ 검색 결과 페이지 □ 차량 상세 페이지 □ 이미지 갤러리 □ 회원가입/로그인 페이지 □ 마이페이지 (포인트, 열람기록) □ 결제 페이지 (카드/직접전송) □ QR 코드 표시 □ 반응형 디자인 □ 로딩/에러 상태 처리 ``` **Claude Code 명령 예시**: ``` Next.js 14 프론트엔드 개발해줘 (apps/web/src/) - App Router 사용 - TypeScript - Tailwind CSS - 다국어 (몽골어/영어/러시아어/한국어) - 차량 검색/목록/상세 페이지 - 결제 모달 (USDT/USDC) ``` --- ### Phase 5: 채팅 + 결제 통합 (1~2주) **목표**: 실시간 채팅 및 결제 시스템 완성 ```bash # 작업 목록 □ Socket.io 서버 설정 □ 채팅방 생성/입장 □ 실시간 메시지 전송 □ Claude API 번역 연동 □ FAQ 자동 응답 로직 □ 채팅 UI 컴포넌트 □ 결제 플로우 테스트 □ 웹훅 테스트 □ 포인트 충전 확인 ``` **Claude Code 명령 예시**: ``` 실시간 번역 채팅 시스템 개발해줘 - Socket.io 기반 - Claude API로 몽골어↔한국어 번역 - FAQ 자동 응답 - 채팅 UI 컴포넌트 ``` --- ### Phase 6: 테스트 및 배포 (1주) **목표**: 전체 시스템 테스트 및 프로덕션 배포 ```bash # 작업 목록 □ 단위 테스트 작성 □ 통합 테스트 □ E2E 테스트 (검색→결제→열람) □ 성능 테스트 □ 보안 점검 □ SSL 인증서 적용 □ PM2 설정 □ Nginx 설정 최적화 □ 모니터링 설정 □ 백업 스크립트 설정 □ 프로덕션 배포 □ DNS 설정 ``` **Claude Code 명령 예시**: ``` 배포 스크립트 작성해줘 (deploy/) - Nginx 설정 - PM2 ecosystem 설정 - systemd 서비스 파일 - 자동 배포 스크립트 ``` --- ## ⚙️ 환경 변수 ### 웹서버 (.env) ```env # 서버 NODE_ENV=production PORT=4000 FRONTEND_URL=https://your-domain.com API_BASE_URL=https://your-domain.com/api # 데이터베이스 DATABASE_URL=postgresql://user:password@db-server:5432/mongolcar # Redis REDIS_URL=redis://localhost:6379 # JWT JWT_SECRET=your-jwt-secret-key JWT_EXPIRES_IN=7d # Claude API CLAUDE_API_KEY=your-claude-api-key # NOWPayments NOWPAYMENTS_API_KEY=your-nowpayments-api-key NOWPAYMENTS_IPN_SECRET=your-ipn-secret # 에이전트 AGENT_API_KEY=your-agent-api-key # 이미지 저장 IMAGE_STORAGE_PATH=/var/www/car-images IMAGE_BASE_URL=https://your-domain.com/images ``` ### Windows 에이전트 (config.yaml) ```yaml api: base_url: https://your-domain.com/api api_key: your-agent-api-key carmodoo: process_name: GGKucar search_timeout: 30 detail_timeout: 10 polling: interval: 5 # 초 logging: level: INFO file: agent.log ``` --- ## 🚀 Claude Code 개발 시작 명령 ### 1. 프로젝트 초기화 ``` 몽골 중고차 수출 플랫폼 프로젝트 초기화해줘 - monorepo 구조 (apps/web, apps/api, packages/database, agent) - TypeScript 설정 - ESLint, Prettier 설정 - 기본 README 작성 ``` ### 2. 데이터베이스 설정 ``` PostgreSQL 데이터베이스 스키마 작성해줘 (database/schema.sql) - 위 계획서의 테이블 구조 기반 - 인덱스 포함 - 초기 데이터 시드 파일도 작성 ``` ### 3. 백엔드 개발 ``` Express.js API 서버 개발 시작해줘 (apps/api/) - 먼저 프로젝트 구조 설정 - 인증 API부터 시작 - Prisma 스키마 작성 ``` ### 4. 프론트엔드 개발 ``` Next.js 14 프론트엔드 개발 시작해줘 (apps/web/) - App Router 사용 - 다국어 설정 (next-intl) - 메인 페이지 (차량 검색) 먼저 개발 ``` ### 5. 에이전트 개발 ``` 카모두 자동화 에이전트 개발해줘 (agent/) - Python 프로젝트 구조 설정 - pywinauto 기반 UI 자동화 - 검색 및 데이터 추출 기능 ``` --- ## 📝 참고사항 ### 카모두 프로그램 정보 - **개발사**: (주)이엠아이앤씨 - **용도**: 경기도자동차매매사업조합 딜러 전용 - **기술**: .NET Assembly (WinForms/WPF 추정) - **파일**: GGKucar.exe (64KB, 런처) ### 주요 외부 서비스 | 서비스 | 용도 | 링크 | |--------|------|------| | NOWPayments | 암호화폐 결제 | https://nowpayments.io | | Anthropic Claude | AI 번역/챗봇 | https://anthropic.com | | ExchangeRate API | 환율 조회 | https://exchangerate-api.com | --- ## 📞 문의사항 ### 대표 연락처 (모든 딜러 연락처 통일) - **담당자**: DamonHong - **전화**: +82-10-3331-5258 ### 개발 진행 중 추가 정보가 필요한 사항: 1. **카모두 프로그램 UI 스크린샷** - 자동화 개발에 필요 2. **도메인 및 SSL 인증서** - 배포 시 필요 3. **NOWPayments 계정** - 결제 테스트에 필요 4. **Claude API 키** - 번역/챗봇 개발에 필요 --- ## 🔍 카모두 API 분석 (Reverse Engineering) ### 개요 Fiddler를 통해 캡처한 카모두 프로그램(GGKucar.exe)의 네트워크 트래픽 분석 결과입니다. ### 기본 정보 | 항목 | 내용 | |------|------| | **도메인** | dealer.carmodoo.com (메인), ck.carmodoo.com (성능점검) | | **프로토콜** | HTTPS (TLS 1.2/1.3) | | **인증 방식** | 세션 기반 (PHPSESSID 쿠키) | | **서버** | Apache/2.4.6 (CentOS), PHP/5.4.16 | | **인코딩** | EUC-KR | ### 인증 API #### 1. 로그인 ```http POST https://dealer.carmodoo.com/member/login_ok.html Content-Type: application/x-www-form-urlencoded prevURL=&id={전화번호}&passwd={비밀번호}&idSave=Y&button=LOGIN ``` **응답**: ```html ``` **인증 쿠키**: `PHPSESSID`, `idSave` #### 2. 세션 유지 ```http POST https://dealer.carmodoo.com/common/ajax/sessionHold.html X-Requested-With: XMLHttpRequest Cookie: PHPSESSID={세션ID} ``` ### 차량 데이터 API #### 1. 제조사/모델 코드 조회 (AutoDBCode.html) **초기 데이터 로드**: ```http GET https://dealer.carmodoo.com/common/ajax/AutoDBCode.html?mode=getCarInit&ctl=car ``` **제조사별 모델 목록**: ```http GET https://dealer.carmodoo.com/common/ajax/AutoDBCode.html?mode=getCarModelInit&ctl=car&company={제조사ID} ``` **모델별 세부 모델**: ```http GET https://dealer.carmodoo.com/common/ajax/AutoDBCode.html?mode=getCarModel&ctl=car&company={제조사ID}&c_nameInit={모델ID} ``` **세부 모델별 연식**: ```http GET https://dealer.carmodoo.com/common/ajax/AutoDBCode.html?mode=getCarYear&ctl=car&c_name={모델코드} ``` **시리즈 조회**: ```http GET https://dealer.carmodoo.com/common/ajax/AutoDBCode.html?mode=getCarSeries&ctl=car&c_name={모델코드} ``` **세부사양 조회**: ```http GET https://dealer.carmodoo.com/common/ajax/AutoDBCode.html?mode=getCarSdetail&ctl=car&series={시리즈코드} ``` **응답 형식** (XML): ```xml car 5 1 c_bmNo ... ``` **주요 제조사 코드**: | 코드 | 제조사 | |------|--------| | 5 | 현대 | | 2 | 기아 | | 1 | 쌍용 | | 3 | 르노 | | 67 | BMW | | 68 | 벤츠 | | 70 | 아우디 | #### 2. 차량 목록 조회 (AutoDBProc.html) **관심 차량 조회**: ```http GET https://dealer.carmodoo.com/common/ajax/AutoDBProc.html?mode=getInterest&iStr={차량번호들!구분} ``` 예시: `iStr=6290623!6290630!6290644!...` **응답**: `Y|` (관심등록 여부) **관심 차량 추가**: ```http POST https://dealer.carmodoo.com/common/ajax/AutoDBProc.html Content-Type: application/x-www-form-urlencoded mode=addInterest&c_no={차량번호}&memo={메모} ``` **관심 차량 삭제**: ```http GET https://dealer.carmodoo.com/common/ajax/AutoDBProc.html?mode=delInterest&c_no={차량번호} ``` #### 3. 차량 상세 조회 (AutoDB.html) ```http GET https://dealer.carmodoo.com/common/ajax/AutoDB.html?mode=view&key={암호화된키} ``` **key 파라미터**: Base64 인코딩된 암호화 문자열 예시: `U1VqWHNxc2FOaDY0LzAyYUtaRDdibTdQZnc4cXZ4dXh6czVyelJjdHRHcz0` **응답 형식** (XML): ```xml 6320434 1 2828 2020년형 기아 K5 DL3 2.0 가솔린 차량 제목 오토 가솔린 45000 흰색 12가3456 25000000 2020년 06월 2020 6 1998 0 0 메모 내용 1#5#12#34#... /data/__carPhoto/006/320/434/cmcar_0.jpg /data/__carPhoto/006/320/434/cmcar_0.jpg|cmcar_1.jpg|... 썸네일 경로들 123456789 성능점검 URL ggkucar 딜러명 010-1234-5678 매매상사명 031-123-4567 ``` #### 4. 차량 상세 페이지 (HTML) ```http GET http://dealer.carmodoo.com/car/dealerCarView.html?key={암호화된키}&tabStart=1 ``` ### 이미지 URL 패턴 **원본 이미지**: ``` http://dealer.carmodoo.com/data/__carPhoto/{3자리}/{3자리}/{3자리}/cmcar_{순번}.jpg ``` **썸네일 이미지**: ``` http://dealer.carmodoo.com/data/__carPhoto/{3자리}/{3자리}/{3자리}/cmcar_{순번}.jpg__THUM ``` **URL 구조 설명**: - 차량번호 6320434의 경우: `/006/320/434/` - 첫 번째 이미지: `cmcar_0.jpg` - 두 번째 이미지: `cmcar_1.jpg` ### 성능점검 API ```http GET https://ck.carmodoo.com/carCheck/carmodooPrint.do?checkNum={성능점검번호} ``` ### 시세 조회 API ```http GET https://dealer.carmodoo.com/common/ajax/SiseDB.html?mode=getSiseData&ctl={구분}&company={제조사코드}&c_name={모델코드} ``` ### Python 에이전트 구현 참고 ```python import aiohttp import asyncio from urllib.parse import urlencode class CarmodooClient: BASE_URL = "https://dealer.carmodoo.com" def __init__(self): self.session = None self.cookies = {} async def login(self, user_id: str, password: str) -> bool: """로그인 및 세션 쿠키 획득""" async with aiohttp.ClientSession() as session: data = { 'prevURL': '', 'id': user_id, 'passwd': password, 'idSave': 'Y', 'button': 'LOGIN' } async with session.post( f"{self.BASE_URL}/member/login_ok.html", data=data, headers={'Content-Type': 'application/x-www-form-urlencoded'} ) as resp: if resp.status == 200: self.cookies = {c.key: c.value for c in session.cookie_jar} return 'goMain' in await resp.text() return False async def get_car_makers(self) -> list: """제조사 목록 조회""" params = {'mode': 'getCarInit', 'ctl': 'car'} async with aiohttp.ClientSession(cookies=self.cookies) as session: async with session.get( f"{self.BASE_URL}/common/ajax/AutoDBCode.html", params=params ) as resp: # XML 파싱 후 반환 pass async def get_car_detail(self, key: str) -> dict: """차량 상세 정보 조회""" params = {'mode': 'view', 'key': key} async with aiohttp.ClientSession(cookies=self.cookies) as session: async with session.get( f"{self.BASE_URL}/common/ajax/AutoDB.html", params=params ) as resp: # XML 파싱 후 반환 pass async def download_image(self, car_no: int, index: int) -> bytes: """차량 이미지 다운로드""" # 차량번호를 3자리씩 분할 path = f"{car_no:09d}" folder = f"{path[0:3]}/{path[3:6]}/{path[6:9]}" url = f"{self.BASE_URL}/data/__carPhoto/{folder}/cmcar_{index}.jpg" async with aiohttp.ClientSession(cookies=self.cookies) as session: async with session.get(url) as resp: if resp.status == 200: return await resp.read() return None ``` ### 주요 데이터 필드 매핑 | carmodoo 필드 | 의미 | DB 필드 | |---------------|------|---------| | c_no / no | 차량 고유번호 | source_id | | carName | 차량명 (풀네임) | - | | c_bmNo | 제조사 코드 | make | | c_boNo | 모델 코드 | model | | c_year | 연식 | year | | c_mileage | 주행거리 | mileage | | dPrice | 판매가격 | price | | c_fuel | 연료 | fuel_type | | c_gearbox | 변속기 | transmission | | c_colorName | 색상 | color | | c_displacement | 배기량 | engine_cc | | c_options | 옵션 (#구분) | options | | c_checkNum | 성능점검번호 | inspection_data | | c_seize | 압류 건수 | - | | c_collateral | 저당 건수 | - | ### 보안 고려사항 1. **HTTPS 필수**: 모든 요청은 HTTPS로 전송 2. **세션 관리**: PHPSESSID 쿠키 유지 필요 3. **Rate Limiting**: 과도한 요청 시 차단 가능성 4. **인코딩**: EUC-KR → UTF-8 변환 필요 --- ## 구현 완료 기능 (2024-12-25) ### 상세사양조회 시스템 차량번호 기반으로 AUTOBEGINS 서비스에서 상세사양을 조회하는 시스템이 구현되었습니다. **주요 기능**: - Playwright 브라우저 자동화로 Carmodoo 딜러 포탈의 AUTOBEGINS iframe 접근 - 차량번호 입력 → 상세사양 파싱 → DB 저장 - 배너 등록(import) 시 자동 사양 조회 **조회 가능 정보**: | 카테고리 | 정보 | |----------|------| | 기본 정보 | 제조사, 모델명, 등급, 연식 | | 엔진/구동 | 배기량, 연료, 변속기, 구동방식 | | 성능 | 최대출력, 최대토크, 연비 | | 차체 | 차체형식, 도어수, 승차정원, 전장/전폭/전고/휠베이스 | | 가격 | 출고가, 기본가, 옵션가 | **관련 파일**: - `backend/app/services/spec_service.py` - 사양 조회 로직 - `backend/app/models/car_specification.py` - CarSpecification 모델 - `backend/app/api/carmodoo.py` - API 엔드포인트 ### 딜러 상세설명 Carmodoo 상세페이지에서 딜러가 작성한 설명을 추출하여 저장합니다. **추출 방식** (2024-12-25 업데이트): 1. 차량 검색 결과에서 `dealerCarviewPopup('암호화키')` JavaScript 호출 패턴을 파싱하여 `car_key` 추출 2. `dealerCarView.html?key=&tabStart=1` URL로 딜러 상세페이지 조회 3. `

상세설명

...
` HTML 구조에서 설명 추출 4. `cars.dealer_description` 컬럼에 저장 **주의**: 이전의 `carPopView.html`은 더 이상 작동하지 않음 (404 반환) **관련 코드**: - `carmodoo.py: _parse_car_list_html()` - car_key 추출 (dealerCarviewPopup 패턴) - `carmodoo.py: get_car_detail()` - dealerCarView.html에서 상세설명 파싱 - 차량 상세 페이지에서 amber 배경으로 표시 (로그인 사용자만) ### Quote Request 1CC 결제 차량 추천 요청 시 1 CC가 차감되도록 구현되었습니다. **흐름**: 1. 사용자가 `/vehicle-request` 페이지에서 조건 입력 2. 제출 시 CC 잔액 확인 (1 CC 필요) 3. 잔액 부족 시 `/cc` 충전 페이지로 안내 4. CC 차감 후 요청 생성 **관련 파일**: - `backend/app/api/vehicle_requests.py` - CC 차감 로직 - `backend/app/models/vehicle_request.py` - cc_paid 컬럼 - `frontend/src/app/vehicle-request/page.tsx` - UI (CC 잔액 표시, 비용 안내) --- *마지막 업데이트: 2024년 12월 25일* --- ## 변경 이력 | 날짜 | 변경 내용 | |------|----------| | 2024-12-25 | 딜러 상세설명 추출 방식 변경 (carPopView.html → dealerCarView.html + car_key) | | 2024-12-25 | car_key 필드 추가 (CarmodooSearchResultItem, AdminSearchResultItem, ImportCarRequest) | | 2024-12-25 | 프론트엔드 api.ts, hero-banners/page.tsx에 car_key 연동 |