From db1aed81d9d8b371d31d027884b3559156a34863 Mon Sep 17 00:00:00 2001 From: OG T Date: Thu, 2 Apr 2026 09:13:36 +0800 Subject: [PATCH] =?UTF-8?q?fix(db):=20C1=20=E6=99=82=E5=8D=80=E7=B5=B1?= =?UTF-8?q?=E4=B8=80=E9=81=B7=E7=A7=BB=20=E2=80=94=20utc=5Fnow=20=E2=86=92?= =?UTF-8?q?=20taipei=5Fnow=20(=E5=85=A8=205=20table)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🔴 首席架構師審查 C1: 全系統禁止 UTC,必須台北時區 +8 - utc_now() → taipei_now() (調用 src.utils.timezone.now_taipei) - 影響: ApprovalRecord, TimelineEvent, AuditLog, IncidentRecord, KnowledgeEntryRecord - 13 處 default/onupdate 全部替換 - 移除 datetime.UTC import Co-Authored-By: Claude Opus 4.6 (1M context) --- apps/api/src/db/models.py | 37 +++++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/apps/api/src/db/models.py b/apps/api/src/db/models.py index cee42a04b..b2dd1987f 100644 --- a/apps/api/src/db/models.py +++ b/apps/api/src/db/models.py @@ -10,7 +10,7 @@ Schema 設計原則: - 索引優化查詢 """ -from datetime import UTC, datetime +from datetime import datetime from typing import Any from uuid import uuid4 @@ -36,9 +36,14 @@ from src.models.knowledge import EntrySource, EntryStatus, EntryType # Helper Functions # ============================================================================= -def utc_now() -> datetime: - """Get current UTC datetime""" - return datetime.now(UTC) +def taipei_now() -> datetime: + """取得台北時區當前時間 (UTC+8) + + 🔴 HARD RULE: 全系統使用台北時區,禁止 UTC + 2026-04-02 Claude Code: C1 時區統一遷移 (首席架構師審查) + """ + from src.utils.timezone import now_taipei + return now_taipei() def generate_uuid() -> str: @@ -114,7 +119,7 @@ class ApprovalRecord(Base): # 最後觸發時間 - 同指紋告警最近一次出現的時間 last_seen_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), - default=utc_now, + default=taipei_now, nullable=False, comment="Last time this alert pattern was seen", ) @@ -122,12 +127,12 @@ class ApprovalRecord(Base): # Timestamps created_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), - default=utc_now, + default=taipei_now, ) updated_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), - default=utc_now, - onupdate=utc_now, + default=taipei_now, + onupdate=taipei_now, ) expires_at: Mapped[datetime | None] = mapped_column( DateTime(timezone=True), @@ -200,7 +205,7 @@ class TimelineEvent(Base): # Timestamp created_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), - default=utc_now, + default=taipei_now, ) # Indexes @@ -324,7 +329,7 @@ class AuditLog(Base): # Timestamps created_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), - default=utc_now, + default=taipei_now, ) # Indexes @@ -417,13 +422,13 @@ class IncidentRecord(Base): # === 時間軸 === created_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), - default=utc_now, + default=taipei_now, nullable=False, ) updated_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), - default=utc_now, - onupdate=utc_now, + default=taipei_now, + onupdate=taipei_now, nullable=False, ) resolved_at: Mapped[datetime | None] = mapped_column( @@ -537,12 +542,12 @@ class KnowledgeEntryRecord(Base): created_by: Mapped[str | None] = mapped_column(String(100), nullable=True) created_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), - default=utc_now, + default=taipei_now, ) updated_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), - default=utc_now, - onupdate=utc_now, + default=taipei_now, + onupdate=taipei_now, ) # Indexes