-
Notifications
You must be signed in to change notification settings - Fork 400
Expand file tree
/
Copy pathmongo_session_repository.py
More file actions
179 lines (155 loc) · 7.41 KB
/
Copy pathmongo_session_repository.py
File metadata and controls
179 lines (155 loc) · 7.41 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
from typing import Optional, List
from datetime import datetime, UTC
from app.domain.models.session import Session, SessionStatus
from app.domain.models.file import FileInfo
from app.domain.repositories.session_repository import SessionRepository
from app.domain.models.event import BaseEvent
from app.infrastructure.models.documents import SessionDocument
import logging
logger = logging.getLogger(__name__)
class MongoSessionRepository(SessionRepository):
"""MongoDB implementation of SessionRepository"""
async def save(self, session: Session) -> None:
"""Save or update a session"""
mongo_session = await SessionDocument.find_one(
SessionDocument.session_id == session.id
)
if not mongo_session:
mongo_session = SessionDocument.from_domain(session)
await mongo_session.save()
return
# Update fields from session domain model
mongo_session.update_from_domain(session)
await mongo_session.save()
async def find_by_id(self, session_id: str) -> Optional[Session]:
"""Find a session by its ID"""
mongo_session = await SessionDocument.find_one(
SessionDocument.session_id == session_id
)
return mongo_session.to_domain() if mongo_session else None
async def find_by_user_id(self, user_id: str) -> List[Session]:
"""Find all sessions for a specific user"""
mongo_sessions = await SessionDocument.find(
SessionDocument.user_id == user_id
).sort("-latest_message_at").to_list()
return [mongo_session.to_domain() for mongo_session in mongo_sessions]
async def find_by_id_and_user_id(self, session_id: str, user_id: str) -> Optional[Session]:
"""Find a session by ID and user ID (for authorization)"""
mongo_session = await SessionDocument.find_one(
SessionDocument.session_id == session_id,
SessionDocument.user_id == user_id
)
return mongo_session.to_domain() if mongo_session else None
async def update_title(self, session_id: str, title: str) -> None:
"""Update the title of a session"""
result = await SessionDocument.find_one(
SessionDocument.session_id == session_id
).update(
{"$set": {"title": title, "updated_at": datetime.now(UTC)}}
)
if not result:
raise ValueError(f"Session {session_id} not found")
async def update_latest_message(self, session_id: str, message: str, timestamp: datetime) -> None:
"""Update the latest message of a session"""
result = await SessionDocument.find_one(
SessionDocument.session_id == session_id
).update(
{"$set": {"latest_message": message, "latest_message_at": timestamp, "updated_at": datetime.now(UTC)}}
)
if not result:
raise ValueError(f"Session {session_id} not found")
async def add_event(self, session_id: str, event: BaseEvent) -> None:
"""Add an event to a session"""
result = await SessionDocument.find_one(
SessionDocument.session_id == session_id
).update(
{"$push": {"events": event.model_dump()}, "$set": {"updated_at": datetime.now(UTC)}}
)
if not result:
raise ValueError(f"Session {session_id} not found")
async def add_file(self, session_id: str, file_info: FileInfo) -> None:
"""Add a file to a session"""
result = await SessionDocument.find_one(
SessionDocument.session_id == session_id
).update(
{"$push": {"files": file_info.model_dump()}, "$set": {"updated_at": datetime.now(UTC)}}
)
if not result:
raise ValueError(f"Session {session_id} not found")
async def remove_file(self, session_id: str, file_id: str) -> None:
"""Remove a file from a session"""
result = await SessionDocument.find_one(
SessionDocument.session_id == session_id
).update(
{"$pull": {"files": {"file_id": file_id}}, "$set": {"updated_at": datetime.now(UTC)}}
)
if not result:
raise ValueError(f"Session {session_id} not found")
async def get_file_by_path(self, session_id: str, file_path: str) -> Optional[FileInfo]:
"""Get file by path from a session"""
mongo_session = await SessionDocument.find_one(
SessionDocument.session_id == session_id
)
if not mongo_session:
raise ValueError(f"Session {session_id} not found")
# Search for file with matching path
for file_info in mongo_session.files:
if file_info.file_path == file_path:
return file_info
return None
async def delete(self, session_id: str) -> None:
"""Delete a session"""
mongo_session = await SessionDocument.find_one(
SessionDocument.session_id == session_id
)
if mongo_session:
await mongo_session.delete()
async def get_all(self) -> List[Session]:
"""Get all sessions"""
mongo_sessions = await SessionDocument.find().sort("-latest_message_at").to_list()
return [mongo_session.to_domain() for mongo_session in mongo_sessions]
async def update_status(self, session_id: str, status: SessionStatus) -> None:
"""Update the status of a session"""
result = await SessionDocument.find_one(
SessionDocument.session_id == session_id
).update(
{"$set": {"status": status, "updated_at": datetime.now(UTC)}}
)
if not result:
raise ValueError(f"Session {session_id} not found")
async def update_unread_message_count(self, session_id: str, count: int) -> None:
"""Update the unread message count of a session"""
result = await SessionDocument.find_one(
SessionDocument.session_id == session_id
).update(
{"$set": {"unread_message_count": count, "updated_at": datetime.now(UTC)}}
)
if not result:
raise ValueError(f"Session {session_id} not found")
async def increment_unread_message_count(self, session_id: str) -> None:
"""Atomically increment the unread message count of a session"""
result = await SessionDocument.find_one(
SessionDocument.session_id == session_id
).update(
{"$inc": {"unread_message_count": 1}, "$set": {"updated_at": datetime.now(UTC)}}
)
if not result:
raise ValueError(f"Session {session_id} not found")
async def decrement_unread_message_count(self, session_id: str) -> None:
"""Atomically decrement the unread message count of a session"""
result = await SessionDocument.find_one(
SessionDocument.session_id == session_id
).update(
{"$inc": {"unread_message_count": -1}, "$set": {"updated_at": datetime.now(UTC)}}
)
if not result:
raise ValueError(f"Session {session_id} not found")
async def update_shared_status(self, session_id: str, is_shared: bool) -> None:
"""Update the shared status of a session"""
result = await SessionDocument.find_one(
SessionDocument.session_id == session_id
).update(
{"$set": {"is_shared": is_shared, "updated_at": datetime.now(UTC)}}
)
if not result:
raise ValueError(f"Session {session_id} not found")