Files
AutonetSellCar Deploy c9fd7611a7 feat: Add banner toggle and soldout tracking to Cars page
- Add is_banner, soldout fields to Car model
- Add banner toggle API (POST /hero-banners/admin/toggle/{car_id})
- Add soldout APIs (POST/DELETE /cars/{car_id}/soldout)
- Add nightly soldout checker in agent (runs at 3:00 AM)
- Update Local Cars UI with banner checkbox and status column
- Remove hero-banners admin page (functionality moved to Cars page)
- Banner cars sorted to top with purple background
- Soldout cars displayed with gray overlay

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-31 12:50:40 +09:00

113 lines
4.6 KiB
Python

from sqlalchemy import Column, Integer, String, BigInteger, Boolean, ForeignKey, DateTime, Text, DECIMAL
from sqlalchemy.orm import relationship
from sqlalchemy.sql import func
from ..database import Base
class CarMaker(Base):
__tablename__ = "car_makers"
id = Column(Integer, primary_key=True, index=True)
code = Column(String(10), unique=True, nullable=False, index=True)
name = Column(String(100), nullable=False)
name_en = Column(String(100))
created_at = Column(DateTime(timezone=True), server_default=func.now())
models = relationship("CarModel", back_populates="maker")
cars = relationship("Car", back_populates="maker")
class CarModel(Base):
__tablename__ = "car_models"
id = Column(Integer, primary_key=True, index=True)
code = Column(String(10), nullable=False, index=True)
maker_id = Column(Integer, ForeignKey("car_makers.id"), nullable=False)
name = Column(String(100), nullable=False)
name_en = Column(String(100))
maker = relationship("CarMaker", back_populates="models")
cars = relationship("Car", back_populates="model")
class Car(Base):
__tablename__ = "cars"
id = Column(Integer, primary_key=True, index=True)
source = Column(String(50), nullable=False, default="carmodoo")
source_id = Column(String(50), nullable=False, index=True)
source_key = Column(Text)
maker_id = Column(Integer, ForeignKey("car_makers.id"))
model_id = Column(Integer, ForeignKey("car_models.id"))
car_name = Column(String(200))
year = Column(Integer, index=True)
month = Column(Integer)
mileage = Column(Integer)
price_krw = Column(BigInteger, index=True)
margin_krw = Column(BigInteger, default=0) # Korean margin amount in KRW
margin_mn = Column(BigInteger, default=0) # Mongolian margin amount in KRW
price_usd = Column(DECIMAL(12, 2))
is_displayed = Column(Boolean, default=False, index=True) # Show to users
is_banner = Column(Boolean, default=False, index=True) # Registered as hero banner
soldout = Column(Boolean, default=False, index=True) # Sold to another buyer (checked nightly vs Carmodoo)
fuel = Column(String(20))
transmission = Column(String(20))
color = Column(String(50))
displacement = Column(Integer)
car_number = Column(String(20))
seize_count = Column(Integer, default=0)
collateral_count = Column(Integer, default=0)
check_num = Column(String(50))
dealer_name = Column(String(100))
dealer_phone = Column(String(50))
shop_name = Column(String(100))
dealer_description = Column(Text) # 딜러가 작성한 차량 상세설명 (한국어 원문)
dealer_description_en = Column(Text) # 영어 번역
dealer_description_mn = Column(Text) # 몽골어 번역
dealer_description_ru = Column(Text) # 러시아어 번역
memo = Column(Text)
status = Column(String(20), default="active", index=True)
created_at = Column(DateTime(timezone=True), server_default=func.now())
updated_at = Column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now())
synced_at = Column(DateTime(timezone=True))
maker = relationship("CarMaker", back_populates="cars")
model = relationship("CarModel", back_populates="cars")
images = relationship("CarImage", back_populates="car", cascade="all, delete-orphan")
options = relationship("CarOption", back_populates="car", cascade="all, delete-orphan")
# inquiries relationship disabled due to schema mismatch - use raw SQL for inquiry operations
# inquiries = relationship("Inquiry", back_populates="car")
views = relationship("CarView", back_populates="car", cascade="all, delete-orphan")
performance_check = relationship("CarPerformanceCheck", back_populates="car", uselist=False, cascade="all, delete-orphan")
specification = relationship("CarSpecification", back_populates="car", uselist=False, cascade="all, delete-orphan")
class CarImage(Base):
__tablename__ = "car_images"
id = Column(Integer, primary_key=True, index=True)
car_id = Column(Integer, ForeignKey("cars.id", ondelete="CASCADE"), nullable=False)
url = Column(String(500))
local_path = Column(String(500))
is_main = Column(Boolean, default=False)
sort_order = Column(Integer, default=0)
car = relationship("Car", back_populates="images")
class CarOption(Base):
__tablename__ = "car_options"
id = Column(Integer, primary_key=True, index=True)
car_id = Column(Integer, ForeignKey("cars.id", ondelete="CASCADE"), nullable=False)
option_name = Column(String(100))
car = relationship("Car", back_populates="options")