11from datetime import datetime , timedelta , timezone
2- from typing import Any , Dict
2+ from typing import Any
33from uuid import uuid4
44
55import pymongo
@@ -28,10 +28,10 @@ class EventMetadata(BaseModel):
2828
2929
3030class EventDocument (Document ):
31- """Event document as stored in database .
31+ """Event document for event browsing/admin system .
3232
33- Copied from EventInDB schema. Uses extra="allow" to store
34- additional fields from polymorphic BaseEvent subclasses .
33+ Uses payload dict for flexible event data storage.
34+ This is separate from EventStoreDocument which uses flat structure for Kafka events .
3535 """
3636
3737 event_id : Indexed (str , unique = True ) = Field (default_factory = lambda : str (uuid4 ())) # type: ignore[valid-type]
@@ -40,7 +40,7 @@ class EventDocument(Document):
4040 timestamp : Indexed (datetime ) = Field (default_factory = lambda : datetime .now (timezone .utc )) # type: ignore[valid-type]
4141 aggregate_id : Indexed (str ) | None = None # type: ignore[valid-type]
4242 metadata : EventMetadata
43- payload : Dict [str , Any ] = Field (default_factory = dict )
43+ payload : dict [str , Any ] = Field (default_factory = dict )
4444 stored_at : datetime = Field (default_factory = lambda : datetime .now (timezone .utc ))
4545 ttl_expires_at : datetime = Field (default_factory = lambda : datetime .now (timezone .utc ) + timedelta (days = 30 ))
4646
@@ -86,68 +86,10 @@ class Settings:
8686 ]
8787
8888
89- class EventStoreDocument (Document ):
90- """Event store document for permanent event storage.
91-
92- Same structure as EventDocument but in event_store collection.
93- Uses extra="allow" to store additional fields from polymorphic events.
94- No TTL index since this is permanent storage.
95- """
96-
97- event_id : Indexed (str , unique = True ) = Field (default_factory = lambda : str (uuid4 ())) # type: ignore[valid-type]
98- event_type : EventType # Indexed via Settings.indexes
99- event_version : str = "1.0"
100- timestamp : Indexed (datetime ) = Field (default_factory = lambda : datetime .now (timezone .utc )) # type: ignore[valid-type]
101- aggregate_id : Indexed (str ) | None = None # type: ignore[valid-type]
102- metadata : EventMetadata
103- payload : Dict [str , Any ] = Field (default_factory = dict )
104- stored_at : datetime = Field (default_factory = lambda : datetime .now (timezone .utc ))
105- ttl_expires_at : datetime | None = None
106-
107- model_config = ConfigDict (from_attributes = True , extra = "allow" )
108-
109- class Settings :
110- name = "event_store"
111- use_state_management = True
112- indexes = [
113- # Compound indexes for common query patterns
114- IndexModel ([("event_type" , ASCENDING ), ("timestamp" , DESCENDING )], name = "idx_event_type_ts" ),
115- IndexModel ([("aggregate_id" , ASCENDING ), ("timestamp" , DESCENDING )], name = "idx_aggregate_ts" ),
116- IndexModel ([("metadata.correlation_id" , ASCENDING )], name = "idx_meta_correlation" ),
117- IndexModel ([("metadata.user_id" , ASCENDING ), ("timestamp" , DESCENDING )], name = "idx_meta_user_ts" ),
118- IndexModel ([("metadata.service_name" , ASCENDING ), ("timestamp" , DESCENDING )], name = "idx_meta_service_ts" ),
119- # Payload sparse indexes
120- IndexModel ([("payload.execution_id" , ASCENDING )], name = "idx_payload_execution" , sparse = True ),
121- IndexModel ([("payload.pod_name" , ASCENDING )], name = "idx_payload_pod" , sparse = True ),
122- # Additional compound indexes for query optimization
123- IndexModel ([("event_type" , ASCENDING ), ("aggregate_id" , ASCENDING )], name = "idx_events_type_agg" ),
124- IndexModel ([("aggregate_id" , ASCENDING ), ("timestamp" , ASCENDING )], name = "idx_events_agg_ts" ),
125- IndexModel ([("event_type" , ASCENDING ), ("timestamp" , ASCENDING )], name = "idx_events_type_ts_asc" ),
126- IndexModel ([("metadata.user_id" , ASCENDING ), ("timestamp" , ASCENDING )], name = "idx_events_user_ts" ),
127- IndexModel ([("metadata.user_id" , ASCENDING ), ("event_type" , ASCENDING )], name = "idx_events_user_type" ),
128- IndexModel (
129- [("event_type" , ASCENDING ), ("metadata.user_id" , ASCENDING ), ("timestamp" , DESCENDING )],
130- name = "idx_events_type_user_ts" ,
131- ),
132- # Text search index
133- IndexModel (
134- [
135- ("event_type" , pymongo .TEXT ),
136- ("metadata.service_name" , pymongo .TEXT ),
137- ("metadata.user_id" , pymongo .TEXT ),
138- ("payload" , pymongo .TEXT ),
139- ],
140- name = "idx_text_search" ,
141- language_override = "none" ,
142- default_language = "english" ,
143- ),
144- ]
145-
146-
14789class EventArchiveDocument (Document ):
14890 """Archived event with deletion metadata.
14991
150- Uses extra="allow" to preserve all fields from polymorphic events .
92+ Mirrors EventDocument structure with additional archive metadata .
15193 """
15294
15395 event_id : Indexed (str , unique = True ) # type: ignore[valid-type]
@@ -156,13 +98,14 @@ class EventArchiveDocument(Document):
15698 timestamp : Indexed (datetime ) # type: ignore[valid-type]
15799 aggregate_id : str | None = None
158100 metadata : EventMetadata
159- payload : Dict [str , Any ] = Field (default_factory = dict )
101+ payload : dict [str , Any ] = Field (default_factory = dict )
160102 stored_at : datetime | None = None
161103 ttl_expires_at : datetime | None = None
162104
163105 # Archive metadata
164106 deleted_at : Indexed (datetime ) = Field (default_factory = lambda : datetime .now (timezone .utc )) # type: ignore[valid-type]
165107 deleted_by : str | None = None
108+ deletion_reason : str | None = None
166109
167110 model_config = ConfigDict (from_attributes = True , extra = "allow" )
168111
0 commit comments