[fix] negodata/backend: 시각 컬럼 timestamptz 전환 + naive 변환 제거

- models.py: created_at/updated_at/last_accessed_at/start_time/end_time/bid_at
  DateTime → DateTime(timezone=True)
- quotation_service: tz-aware 입력을 naive 로 깎던 _naive_utc 제거(컬럼이 tz-aware라 불필요),
  start_time/end_time 직접 사용. negosium_db 는 UTC 고정.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Mina Choi 2026-06-26 15:06:37 +09:00
parent aed8364b40
commit 0c6a002e29
2 changed files with 9 additions and 18 deletions

View File

@ -27,8 +27,8 @@ class _DBTypeMixin:
# ERD 공통 컬럼
class MainTableMixin(_DBTypeMixin):
created_at = Column(DateTime, nullable=False, server_default=_utc_now_sql())
updated_at = Column(DateTime, nullable=False, server_default=_utc_now_sql(), onupdate=_utc_now_sql())
created_at = Column(DateTime(timezone=True), nullable=False, server_default=_utc_now_sql())
updated_at = Column(DateTime(timezone=True), nullable=False, server_default=_utc_now_sql(), onupdate=_utc_now_sql())
deleted = Column(Boolean, nullable=False, server_default=text("false"), default=False)
@ -60,7 +60,7 @@ class users(MainTableMixin, MAIN_BASE):
name = Column(String(50), nullable=True)
email = Column(String(255), nullable=True)
contact_number = Column(String(20), nullable=True)
last_accessed_at = Column(DateTime, nullable=False, server_default=_utc_now_sql())
last_accessed_at = Column(DateTime(timezone=True), nullable=False, server_default=_utc_now_sql())
status = Column(SmallInteger, nullable=False, default=UserStatus.ACTIVE.value)
role = Column(SmallInteger, nullable=False, default=UserRole.USER.value)
@ -191,8 +191,8 @@ class quotations(MainTableMixin, MAIN_BASE):
type = Column(SmallInteger, nullable=False) # QuotationType: 1=renego(1:1) / 2=requote(1:N)
round = Column(Integer, nullable=False, default=1) # 재견적 진행 시 증가
status = Column(SmallInteger, nullable=False) # 진행 상태 코드
start_time = Column(DateTime, nullable=False)
end_time = Column(DateTime, nullable=False)
start_time = Column(DateTime(timezone=True), nullable=False)
end_time = Column(DateTime(timezone=True), nullable=False)
manager_name = Column(String(50), nullable=True)
manager_email = Column(String(255), nullable=True)
@ -222,8 +222,8 @@ class sessions(MainTableMixin, MAIN_BASE):
target_price = Column(BigInteger, nullable=False) # 목표가(원)
status = Column(SmallInteger, nullable=False) # SessionStatus 코드
bid_price = Column(BigInteger, nullable=True) # 입찰가(원)
bid_at = Column(DateTime, nullable=True) # 입찰 시각
end_time = Column(DateTime, nullable=False) # 세션 종료 시각
bid_at = Column(DateTime(timezone=True), nullable=True) # 입찰 시각
end_time = Column(DateTime(timezone=True), nullable=False) # 세션 종료 시각
reject_reason = Column(String(255), nullable=True)
reject_price = Column(BigInteger, nullable=True)
reject_delivery_type = Column(SmallInteger, nullable=True) # DeliveryType 코드

View File

@ -68,15 +68,6 @@ class QuotationService:
return int(int(price) / (1 + margin))
return int(price)
@staticmethod
def _naive_utc(dt):
"""DB 컬럼이 naive(TIMESTAMP WITHOUT TIME ZONE)라, tz-aware 입력(프론트 toISOString 등)은 UTC naive 로 변환."""
if dt is None:
return dt
if getattr(dt, "tzinfo", None) is not None:
return dt.astimezone(timezone.utc).replace(tzinfo=None)
return dt
@staticmethod
def _gen_number() -> str:
"""견적번호 자동 생성(미지정 시). EST-YYYYMM-XXXX."""
@ -156,8 +147,8 @@ class QuotationService:
type_=req.type,
status=req.status or QuotationStatus.CREATED.value,
round_=req.round or 1,
start_time=self._naive_utc(req.start_time or GTime.UTC()),
end_time=self._naive_utc(req.end_time),
start_time=req.start_time or GTime.UTC(),
end_time=req.end_time,
manager_name=req.manager_name,
manager_email=req.manager_email,
manager_contact_number=req.manager_contact_number,