Notification Service (MILTON.NotificationService)

The Notification Service acts as the crucial real-time arterial network for the MILTON platform, deliberately designed as a standalone ASP.NET Core microservice to maintain high-throughput WebSocket connections without burdening the primary domain API. As MILTON fundamentally relies on long-running document generation tasks powered by AI workers, a robust, disconnected push-notification system is critical to provide the React frontend with seamless real-time updates regarding document processing status, structural updates, and generation errors.

By decoupling the SignalR infrastructure from the main API and background document processors, the architecture achieves precise separation of concerns. The API and Document Generator focus exclusively on their domain logic and heavy AI processing workloads, while the Notification Service specializes purely in connection management and event broadcasting.

Architectural Flow and Narrative

The flow of notifications operates on a unidirectional, fire-and-forget publish/subscribe model bridging robust message queuing with real-time WebSockets.

  1. Producer Emits Event: When a state change occurs (e.g., the API persists a new block, or the DocumentGenerator finishes processing a section), the producing service constructs an outbound notification message and publishes it to a RabbitMQ exchange via Wolverine.
  2. RabbitMQ to Wolverine: The Notification Service listens to the "notifications" queue. Wolverine consumes these messages, routing them based on their [MessageIdentity] to the appropriate strongly-typed handlers within the service.
  3. SignalR Broadcast: Upon receiving a message, the handler maps the Wolverine contract to a SignalR-friendly DTO. It then leverages the injected IHubContext<DocumentHub> to broadcast the event explicitly to targeted SignalR groups (either for a specific document, or across an entire project).
  4. React Client Ingestion: The React frontend, connected via the YARP reverse proxy, receives the SignalR event and updates its local client state to reflect the exact state of the backend processing.
sequenceDiagram
    participant API as MILTON API / DocGen
    participant RMQ as RabbitMQ
    participant NS as Notification Service
    participant YARP as Reverse Proxy
    participant React as React Client

    React->>YARP: Connect to /hubs/document
    YARP->>NS: Proxy WebSocket connection
    NS->>NS: Add client to groups (Doc/Project)
    
    API->>RMQ: Publish Wolverine Message (e.g., notify-progress)
    RMQ->>NS: Consume via NotificationHandler
    NS->>NS: Map to SignalR Event (e.g., DocumentProgressEvent)
    NS->>YARP: Push via SignalR Group Broadcast
    YARP->>React: Deliver Real-Time Update
    React->>React: Update UI state asynchronously

Submodules

  • Contracts: Details the structural parity between inbound RabbitMQ messages and outbound SignalR DTOs, emphasizing the message identity routing.
  • Handlers: Describes the Wolverine consumers that translate queuing events into immediate hub broadcasts.
  • Hubs: Explains the connection lifecycle, authorization headers passed via YARP, and group-based routing to ensure clients only receive necessary updates.

Business Logic Intent

The fundamental intent of the Notification Service is to create a reactive user experience out of heavily asynchronous, distributed backend processes. Document generation in MILTON spans numerous microservices, queues, and AI models, which could leave a user staring at a stale screen if they had to rely on HTTP polling. By leveraging Wolverine for resilient messaging and SignalR for efficient push, the Notification Service ensures that state changes are instantly reflected in the user interface, improving perceived performance and system transparency.