Skip to content

Commit 2654a93

Browse files
committed
feat(SCRUM-219): 채팅 세션 및 메시지 생성 시 시간 동기화 개선
- `created_at` 및 `updated_at` 필드를 UTC 시간으로 동기화하여 일관성 유지 - 채팅 세션 생성 시 동일한 시간으로 설정되도록 수정 - 메시지 저장 시 해당 세션의 `updated_at` 필드도 함께 업데이트하도록 로직 추가 - 관련 문서에 시간 동기화 내용 추가
1 parent 92f796b commit 2654a93

3 files changed

Lines changed: 38 additions & 14 deletions

File tree

app/models/chat.py

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
- 사용자 피드백 모델
1010
- 벡터 저장소 모델 (PostgreSQL pgvector)
1111
"""
12-
from datetime import datetime
12+
from datetime import datetime, timezone
1313
from typing import Any, Dict, List, Optional
1414
from uuid import UUID, uuid4
1515
from sqlmodel import Field as SQLField, Relationship, SQLModel
@@ -45,7 +45,7 @@ class ChatSessionBase(SQLModel):
4545
# 통계 필드
4646
total_messages: int = SQLField(default=0)
4747
avg_response_time_ms: Optional[int] = SQLField(default=None)
48-
last_activity_at: datetime = SQLField(default_factory=datetime.utcnow)
48+
last_activity_at: datetime = SQLField(default_factory=lambda: datetime.now(timezone.utc))
4949

5050
class ChatSession(ChatSessionBase, table=True):
5151
"""채팅 세션 테이블"""
@@ -57,14 +57,14 @@ class ChatSession(ChatSessionBase, table=True):
5757
sa_column=Column(PG_UUID(as_uuid=True), primary_key=True)
5858
)
5959
created_at: datetime = SQLField(
60-
default_factory=datetime.utcnow,
60+
default_factory=lambda: datetime.now(timezone.utc),
6161
# pylint: disable=not-callable
6262
sa_column=Column(DateTime(timezone=True), server_default=func.now())
6363
)
64-
updated_at: Optional[datetime] = SQLField(
65-
default=None,
64+
updated_at: datetime = SQLField(
65+
default_factory=lambda: datetime.now(timezone.utc),
6666
# pylint: disable=not-callable
67-
sa_column=Column(DateTime(timezone=True), onupdate=func.now())
67+
sa_column=Column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now())
6868
)
6969

7070
# 관계 정의
@@ -83,7 +83,7 @@ class ChatSessionRead(ChatSessionBase):
8383
"""채팅 세션 조회 스키마"""
8484
id: UUID
8585
created_at: datetime
86-
updated_at: Optional[datetime]
86+
updated_at: datetime
8787

8888
class ChatSessionUpdate(SQLModel):
8989
"""채팅 세션 업데이트 스키마"""
@@ -119,7 +119,7 @@ class ChatMessage(ChatMessageBase, table=True):
119119
sa_column=Column(PG_UUID(as_uuid=True), primary_key=True)
120120
)
121121
created_at: datetime = SQLField(
122-
default_factory=datetime.utcnow,
122+
default_factory=lambda: datetime.now(timezone.utc),
123123
# pylint: disable=not-callable
124124
sa_column=Column(DateTime(timezone=True), server_default=func.now())
125125
)
@@ -169,7 +169,7 @@ class UserFeedback(UserFeedbackBase, table=True):
169169
sa_column=Column(PG_UUID(as_uuid=True), primary_key=True)
170170
)
171171
created_at: datetime = SQLField(
172-
default_factory=datetime.utcnow,
172+
default_factory=lambda: datetime.now(timezone.utc),
173173
# pylint: disable=not-callable
174174
sa_column=Column(DateTime(timezone=True), server_default=func.now())
175175
)
@@ -220,7 +220,7 @@ class RAGReference(RAGReferenceBase, table=True):
220220
sa_column=Column(PG_UUID(as_uuid=True), primary_key=True)
221221
)
222222
created_at: datetime = SQLField(
223-
default_factory=datetime.utcnow,
223+
default_factory=lambda: datetime.now(timezone.utc),
224224
# pylint: disable=not-callable
225225
sa_column=Column(DateTime(timezone=True), server_default=func.now())
226226
)
@@ -261,7 +261,7 @@ class UserProfile(UserProfileBase, table=True):
261261

262262
# 기본 필드들 (직접 정의)
263263
created_at: datetime = SQLField(
264-
default_factory=datetime.utcnow,
264+
default_factory=lambda: datetime.now(timezone.utc),
265265
# pylint: disable=not-callable
266266
sa_column=Column(DateTime(timezone=True), server_default=func.now())
267267
)
@@ -333,7 +333,7 @@ class DocumentVector(DocumentVectorBase, table=True):
333333
sa_column=Column(PG_UUID(as_uuid=True), primary_key=True)
334334
)
335335
created_at: datetime = SQLField(
336-
default_factory=datetime.utcnow,
336+
default_factory=lambda: datetime.now(timezone.utc),
337337
# pylint: disable=not-callable
338338
sa_column=Column(DateTime(timezone=True), server_default=func.now())
339339
)

app/repositories/chat_repository.py

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,16 @@ async def create_session(
3636

3737
async with AsyncSessionLocal() as new_session:
3838
try:
39+
# 동일한 시간을 created_at과 updated_at에 사용
40+
current_time = datetime.now(timezone.utc)
41+
3942
chat_session = ChatSession(
4043
user_id=user_id,
4144
title=title or "새로운 대화",
4245
session_type=session_type,
43-
is_active=True
46+
is_active=True,
47+
created_at=current_time,
48+
updated_at=current_time
4449
)
4550
new_session.add(chat_session)
4651
await new_session.commit()
@@ -239,10 +244,28 @@ async def save_message(
239244
rag_metadata=metadata or {}
240245
)
241246
new_session.add(message)
247+
248+
# 메시지 저장 시 해당 세션의 updated_at도 함께 업데이트
249+
try:
250+
session_stmt = select(ChatSession).where(
251+
and_(
252+
ChatSession.id == session_id,
253+
ChatSession.user_id == user_id
254+
)
255+
)
256+
session_result = await new_session.execute(session_stmt)
257+
chat_session = session_result.scalar_one_or_none()
258+
259+
if chat_session:
260+
chat_session.updated_at = datetime.now(timezone.utc)
261+
new_session.add(chat_session)
262+
except Exception as session_update_error:
263+
logger.warning(f"⚠️ 세션 updated_at 업데이트 실패 (메시지 저장은 계속): {session_update_error}")
264+
242265
await new_session.commit()
243266
await new_session.refresh(message)
244267

245-
logger.debug(f"💾 메시지 저장 - session_id: {session_id}, role: {role}")
268+
logger.debug(f"💾 메시지 저장 및 세션 업데이트 완료 - session_id: {session_id}, role: {role}")
246269
return message
247270

248271
except Exception as e: # pylint: disable=broad-exception-caught

app/routers/chat_stream.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,7 @@ async def chat_stream_direct(
234234
- AI가 사용자의 첫 번째 메시지를 분석하여 의미있는 세션 제목 자동 생성
235235
- 제목 생성 실패 시 기본 제목("대화 YYYY-MM-DD HH:MM") 사용
236236
3. **잘못된 세션 ID시**: 새로운 세션을 생성하여 대화 시작 (제목 자동 생성)
237+
4. **시간 동기화**: 새로운 세션 생성 시 `created_at`과 `updated_at`이 동일한 시간으로 설정
237238
238239
## 요청 예시
239240
### 새로운 대화 시작 (세션 ID 없음)

0 commit comments

Comments
 (0)