From 7f45de7a89b43d4e1ba4a4b1e15c95da2ffeb855 Mon Sep 17 00:00:00 2001 From: AutonetSellCar Deploy Date: Thu, 1 Jan 2026 09:41:18 +0900 Subject: [PATCH] Add configurable CC cost for banner vehicle PDF/description view MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add cc_per_banner_view setting to system_settings (default 0.1 CC) - Update car detail page to use dynamic CC value from settings - Add CC per Banner View field in admin settings page - Replace hardcoded 0.1 CC with configurable value ๐Ÿค– Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- backend/app/api/cc.py | 10 ++++++++-- backend/app/api/settings.py | 1 + backend/app/models/settings.py | 1 + backend/app/schemas/settings.py | 2 ++ frontend/src/app/admin/settings/page.tsx | 19 +++++++++++++++++++ frontend/src/app/cars/[id]/page.tsx | 16 +++++++++------- 6 files changed, 40 insertions(+), 9 deletions(-) diff --git a/backend/app/api/cc.py b/backend/app/api/cc.py index e2f3393..f4ff8a6 100644 --- a/backend/app/api/cc.py +++ b/backend/app/api/cc.py @@ -146,7 +146,12 @@ def check_car_view( } -PERFORMANCE_CHECK_COST = 0.1 # 0.1 CC for performance check view +def get_performance_check_cost(db: Session) -> float: + """Get performance check cost from system settings""" + system_settings = db.query(SystemSettings).first() + if system_settings and system_settings.cc_per_banner_view is not None: + return system_settings.cc_per_banner_view + return 0.1 # Default fallback @router.post("/purchase-performance-check") @@ -155,8 +160,9 @@ async def purchase_performance_check_view( current_user: User = Depends(get_current_user), db: Session = Depends(get_db) ): - """Purchase access to view performance check (costs 0.1 CC)""" + """Purchase access to view performance check (costs CC based on system settings)""" car_id = request.car_id + PERFORMANCE_CHECK_COST = get_performance_check_cost(db) # Check if car exists car = db.query(Car).filter(Car.id == car_id).first() diff --git a/backend/app/api/settings.py b/backend/app/api/settings.py index 6ee57b7..5263d7d 100644 --- a/backend/app/api/settings.py +++ b/backend/app/api/settings.py @@ -26,6 +26,7 @@ def get_or_create_settings(db: Session) -> SystemSettings: cc_per_usdc=1, # 1 USD = 1 CC cc_per_view=1, # ์ฐจ๋Ÿ‰ ์ƒ์„ธ ์กฐํšŒ ์‹œ 1 CC cars_per_cc=3, # 1 CC = 3 recommended vehicles per request + cc_per_banner_view=0.1, # ๋ฐฐ๋„ˆ ์ฐจ๋Ÿ‰ PDF/์ƒ์„ธ ๋ณด๊ธฐ ๋น„์šฉ cc_signup_bonus=3, # 3 CC free on signup cache_ttl_hours=2, container_logistics_usd=3600, diff --git a/backend/app/models/settings.py b/backend/app/models/settings.py index 4d6186a..92b8b28 100644 --- a/backend/app/models/settings.py +++ b/backend/app/models/settings.py @@ -21,6 +21,7 @@ class SystemSettings(Base): cc_per_view = Column(Integer, default=1) # ์ฐจ๋Ÿ‰ ์ƒ์„ธ ์กฐํšŒ ์‹œ 1 CC cc_signup_bonus = Column(Integer, default=3) # ์‹ ๊ทœ ๊ฐ€์ž… ์‹œ 3 CC cars_per_cc = Column(Integer, default=3) # 1 CC๋‹น ์ถ”์ฒœ ์ฐจ๋Ÿ‰ ์ˆ˜ (๊ธฐ๋ณธ 3๋Œ€) + cc_per_banner_view = Column(Float, default=0.1) # ๋ฐฐ๋„ˆ ์ฐจ๋Ÿ‰ PDF/์ƒ์„ธ ๋ณด๊ธฐ ๋น„์šฉ (๊ธฐ๋ณธ 0.1 CC) # ์บ์‹œ TTL (์‹œ๊ฐ„) cache_ttl_hours = Column(Integer, default=2) diff --git a/backend/app/schemas/settings.py b/backend/app/schemas/settings.py index 93d3267..77405a4 100644 --- a/backend/app/schemas/settings.py +++ b/backend/app/schemas/settings.py @@ -12,6 +12,7 @@ class SystemSettingsUpdate(BaseModel): cc_per_view: Optional[int] = None cc_signup_bonus: Optional[int] = None cars_per_cc: Optional[int] = None + cc_per_banner_view: Optional[float] = None cache_ttl_hours: Optional[int] = None container_logistics_usd: Optional[int] = None shoring_cost_usd: Optional[int] = None @@ -32,6 +33,7 @@ class SystemSettingsResponse(BaseModel): cc_per_view: int cc_signup_bonus: int cars_per_cc: int + cc_per_banner_view: float = 0.1 cache_ttl_hours: int container_logistics_usd: int shoring_cost_usd: int diff --git a/frontend/src/app/admin/settings/page.tsx b/frontend/src/app/admin/settings/page.tsx index 98085ed..ee87b70 100644 --- a/frontend/src/app/admin/settings/page.tsx +++ b/frontend/src/app/admin/settings/page.tsx @@ -11,6 +11,7 @@ interface SystemSettings { cc_per_view: number; cc_signup_bonus: number; cars_per_cc: number; + cc_per_banner_view: number; cache_ttl_hours: number; container_logistics_usd: number; shoring_cost_usd: number; @@ -56,6 +57,7 @@ export default function SettingsPage() { cc_per_view: 1, cc_signup_bonus: 3, cars_per_cc: 3, + cc_per_banner_view: 0.1, cache_ttl_hours: 2, container_logistics_usd: 3600, shoring_cost_usd: 300, @@ -85,6 +87,7 @@ export default function SettingsPage() { cc_per_view: data.cc_per_view, cc_signup_bonus: data.cc_signup_bonus, cars_per_cc: data.cars_per_cc || 3, + cc_per_banner_view: data.cc_per_banner_view ?? 0.1, cache_ttl_hours: data.cache_ttl_hours, container_logistics_usd: data.container_logistics_usd || 3600, shoring_cost_usd: data.shoring_cost_usd || 300, @@ -372,6 +375,22 @@ export default function SettingsPage() { />

Free CC for new users

+ +
+ + setFormData(prev => ({ ...prev, cc_per_banner_view: parseFloat(e.target.value) || 0.1 }))} + className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary-500 focus:border-primary-500" + /> +

๋ฐฐ๋„ˆ ์ฐจ๋Ÿ‰ PDF/์ƒ์„ธ ์ •๋ณด ์—ด๋žŒ ๋น„์šฉ (๊ธฐ๋ณธ๊ฐ’: 0.1 CC)

+
diff --git a/frontend/src/app/cars/[id]/page.tsx b/frontend/src/app/cars/[id]/page.tsx index 1b67734..6ea927f 100644 --- a/frontend/src/app/cars/[id]/page.tsx +++ b/frontend/src/app/cars/[id]/page.tsx @@ -53,18 +53,20 @@ export default function CarDetailPage() { // System settings const [showDealerCommentSetting, setShowDealerCommentSetting] = useState(true); + const [ccPerBannerView, setCcPerBannerView] = useState(0.1); useEffect(() => { if (params.id) { loadCar(Number(params.id)); } - // Fetch system settings for dealer comment visibility + // Fetch system settings for dealer comment visibility and CC cost const fetchSettings = async () => { try { const response = await fetch(`${API_BASE_URL}/api/settings/`); if (response.ok) { const data = await response.json(); setShowDealerCommentSetting(data.show_dealer_comment ?? true); + setCcPerBannerView(data.cc_per_banner_view ?? 0.1); } } catch (error) { console.error('Failed to fetch settings:', error); @@ -172,7 +174,7 @@ export default function CarDetailPage() { return; } - if (ccBalance < 0.1) { + if (ccBalance < ccPerBannerView) { alert(t.insufficientCC); return; } @@ -356,7 +358,7 @@ export default function CarDetailPage() {

{t.promotedVehicle}

-

{t.promotedVehicleDesc}

+

{t.promotedVehicleDesc.replace('0.1', String(ccPerBannerView))}

@@ -915,7 +917,7 @@ export default function CarDetailPage() {
- 0.1 CC + {ccPerBannerView} CC