Merged
Conversation
…services and implementations
- Implemented WebSocketManager to manage connections and broadcast domain events. - Added WebSocket routes for handling client subscriptions and event notifications. - Introduced event classes for energy, miner, optimization, and policy events. - Integrated WebSocket dependencies into the application startup process. - Updated services to publish relevant events to the WebSocket manager. - Created unit tests for WebSocketManager and event classes to ensure functionality.
…decisional_context and test_rules
…d structures and various data types
…ish events for energy state and decisional context
- Refactored event classes to align with the new structure, moving events to their respective domain modules. - Enhanced tests to validate the new WebSocket broadcasting functionality and ensure proper event handling.
…turn payload dicts
…d return available topics
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds a WebSocket infrastructure for pushing domain events to connected clients in real-time. The system hooks into the existing event bus and follows the same DDD/hexagonal architecture patterns used by the FastAPI routes — each subdomain owns its serialization logic while a central manager handles connection lifecycle and message delivery.
What's included
Core Infrastructure (
adapters/infrastructure/websocket/)WebSocketManager— aggregator that collects subdomain handlers, subscribes to the event bus, and broadcasts serialized payloads to clients matching their subscription patternsWebSocketEventHandlerABC — pure serializer base class, each subdomain implements aregistrationsproperty returningWebSocketEventRegistrationentries (event_type + topic + serialize)WebSocketEventRegistrationfrozen dataclass — declarative binding of a domain event class to a topic string and a serialization functionWebSocketMessageNamedTuple — typed internal container pairing topic with payload/ws/eventswith topic-based pub/sub usingfnmatchglob patterns (energy.*,*, etc.){"get_topics": true}to receive the full list of subscribable topicsSubdomain Handlers
One handler per subdomain, each with its own Pydantic schema:
energy.stateEnergyWebSocketHandlerEnergyStateSnapshotUpdatedSchemaminer.stateMinerWebSocketHandlerMinerStateChangedSchemarule.engagedOptimizationUnitWebSocketHandlerRuleEngagedSchemapolicy.contextPolicyWebSocketHandlerDecisionalContextUpdatedSchemaconfig.updatedConfigurationWebSocketHandlerConfigurationUpdatedSchemaDocumentation
docs/architecture/websocket-design.md— technical architecture, component descriptions, file structure, and step-by-step guide for adding new eventsdocs/WEBSOCKET.md— client-facing guide with protocol reference, payload schemas, pattern matching, and JS/Python examplesHow it connects to the event bus
The
WebSocketManagerreceives anEventBusInterfaceat construction. It iterates all handler registrations and callsevent_bus.subscribe(event_type, callback, blocking=False)for each one. When a domain event is published anywhere in the system, the corresponding callback serializes it via the handler's function and broadcasts the result to matching WebSocket clients. The handlers themselves have no dependency on the event bus or the manager — they are pure serializers.How to extend
Adding a new event to an existing subdomain requires no changes to the manager. Add a
WebSocketEventRegistrationto the handler'sregistrationslist with a topic string, create the Pydantic schema, and write the serialize method. The manager discovers it automatically and the new topic appears inavailable_topics.Tests
WebSocket Manager (
test_websocket_manager.py)blocking=False;available_topicsreturns the complete listenergy.*), star-all (*)rule.engaged,miner.state,config.updatedmessages delivered with correct topic and payload{"get_topics": true}and receives sorted list of all available topicsEvent serialization (
tests/unit/application/events/)One test module per event type verifying
DomainEventinheritance, field initialization,event_id/occurred_atgeneration, andto_dict()serialization:test_energy_events.py—EnergyStateSnapshotUpdatedEventtest_miner_events.py—MinerStateChangedEventtest_optimization_events.py—RuleEngagedEventtest_policy_events.py—DecisionalContextUpdatedEventtest_configuration_events.py—ConfigurationUpdatedEvent