markitect-main/markitect/spaces/events/models.py

240 lines
6.5 KiB
Python
Raw Normal View History

"""
Event models for Information Spaces.
This module defines the event types and data structures used
by the event system for space operations.
"""
from dataclasses import dataclass, field
from datetime import datetime
from enum import Enum
from typing import Any, Dict, Optional
import uuid
class SpaceEventType(Enum):
"""
Types of events that can occur in the space system.
Events are organized by category:
- Space lifecycle: creation, updates, deletion, status changes
- Document operations: add, update, remove, move
- Variable operations: set, delete
- Rendering: start, complete, fail
- Sync: start, complete, conflict
"""
# Space lifecycle events
SPACE_CREATED = "space.created"
SPACE_UPDATED = "space.updated"
SPACE_DELETED = "space.deleted"
SPACE_ACTIVATED = "space.activated"
SPACE_ARCHIVED = "space.archived"
# Document events
DOCUMENT_ADDED = "document.added"
DOCUMENT_UPDATED = "document.updated"
DOCUMENT_REMOVED = "document.removed"
DOCUMENT_MOVED = "document.moved"
DOCUMENT_CONTENT_CHANGED = "document.content_changed"
# Variable events
VARIABLE_SET = "variable.set"
VARIABLE_DELETED = "variable.deleted"
# Reference events
REFERENCE_ADDED = "reference.added"
REFERENCE_CLEARED = "reference.cleared"
# Rendering events
RENDER_STARTED = "render.started"
RENDER_COMPLETED = "render.completed"
RENDER_FAILED = "render.failed"
# Sync events
SYNC_STARTED = "sync.started"
SYNC_COMPLETED = "sync.completed"
SYNC_CONFLICT = "sync.conflict"
# Cache events
CACHE_INVALIDATED = "cache.invalidated"
@dataclass
class SpaceEvent:
"""
Represents an event in the space system.
Events are immutable records of operations that have occurred.
They carry enough information for handlers to react appropriately.
Attributes:
event_type: The type of event
space_id: The ID of the affected space
payload: Event-specific data
event_id: Unique identifier for this event
timestamp: When the event occurred
source: Optional identifier of the event source
correlation_id: Optional ID to correlate related events
"""
event_type: SpaceEventType
space_id: str
payload: Dict[str, Any] = field(default_factory=dict)
event_id: str = field(default_factory=lambda: str(uuid.uuid4()))
timestamp: datetime = field(default_factory=datetime.now)
source: Optional[str] = None
correlation_id: Optional[str] = None
def to_dict(self) -> Dict[str, Any]:
"""Convert the event to a dictionary for serialization."""
return {
"event_id": self.event_id,
"event_type": self.event_type.value,
"space_id": self.space_id,
"payload": self.payload,
"timestamp": self.timestamp.isoformat(),
"source": self.source,
"correlation_id": self.correlation_id,
}
@classmethod
def from_dict(cls, data: Dict[str, Any]) -> "SpaceEvent":
"""Create an event from a dictionary."""
return cls(
event_id=data.get("event_id", str(uuid.uuid4())),
event_type=SpaceEventType(data["event_type"]),
space_id=data["space_id"],
payload=data.get("payload", {}),
timestamp=datetime.fromisoformat(data["timestamp"])
if data.get("timestamp")
else datetime.now(),
source=data.get("source"),
correlation_id=data.get("correlation_id"),
)
# Convenience factory functions for common events
def space_created_event(
space_id: str,
name: str,
source: Optional[str] = None,
) -> SpaceEvent:
"""Create a SPACE_CREATED event."""
return SpaceEvent(
event_type=SpaceEventType.SPACE_CREATED,
space_id=space_id,
payload={"name": name},
source=source,
)
def space_updated_event(
space_id: str,
changes: Dict[str, Any],
source: Optional[str] = None,
) -> SpaceEvent:
"""Create a SPACE_UPDATED event."""
return SpaceEvent(
event_type=SpaceEventType.SPACE_UPDATED,
space_id=space_id,
payload={"changes": changes},
source=source,
)
def space_deleted_event(
space_id: str,
name: str,
source: Optional[str] = None,
) -> SpaceEvent:
"""Create a SPACE_DELETED event."""
return SpaceEvent(
event_type=SpaceEventType.SPACE_DELETED,
space_id=space_id,
payload={"name": name},
source=source,
)
def document_added_event(
space_id: str,
document_id: str,
space_path: str,
source: Optional[str] = None,
) -> SpaceEvent:
"""Create a DOCUMENT_ADDED event."""
return SpaceEvent(
event_type=SpaceEventType.DOCUMENT_ADDED,
space_id=space_id,
payload={"document_id": document_id, "space_path": space_path},
source=source,
)
def document_updated_event(
space_id: str,
document_id: str,
changes: Dict[str, Any],
source: Optional[str] = None,
) -> SpaceEvent:
"""Create a DOCUMENT_UPDATED event."""
return SpaceEvent(
event_type=SpaceEventType.DOCUMENT_UPDATED,
space_id=space_id,
payload={"document_id": document_id, "changes": changes},
source=source,
)
def document_removed_event(
space_id: str,
document_id: str,
space_path: str,
source: Optional[str] = None,
) -> SpaceEvent:
"""Create a DOCUMENT_REMOVED event."""
return SpaceEvent(
event_type=SpaceEventType.DOCUMENT_REMOVED,
space_id=space_id,
payload={"document_id": document_id, "space_path": space_path},
source=source,
)
def document_content_changed_event(
space_id: str,
document_id: str,
old_hash: Optional[str],
new_hash: str,
source: Optional[str] = None,
) -> SpaceEvent:
"""Create a DOCUMENT_CONTENT_CHANGED event."""
return SpaceEvent(
event_type=SpaceEventType.DOCUMENT_CONTENT_CHANGED,
space_id=space_id,
payload={
"document_id": document_id,
"old_hash": old_hash,
"new_hash": new_hash,
},
source=source,
)
def cache_invalidated_event(
space_id: str,
document_ids: list,
reason: str,
source: Optional[str] = None,
) -> SpaceEvent:
"""Create a CACHE_INVALIDATED event."""
return SpaceEvent(
event_type=SpaceEventType.CACHE_INVALIDATED,
space_id=space_id,
payload={"document_ids": document_ids, "reason": reason},
source=source,
)