Component ArchitectureΒΆ

@startuml Market Data Platform Architecture

skinparam componentStyle rectangle
skinparam backgroundColor white
skinparam shadowing false
skinparam ArrowColor #333333
skinparam ArrowThickness 2

title Kuhl Haus Market Data Platform - Component Architecture

cloud "Massive.com WebSocket API" as Massive #FFEEEE
cloud "Finlight News API" as Finlight #EEF4EE

package "Control Plane" #EEEEEE {
    component "Service Control Plane (SCP)" as SCP #7ED321
}

package "Data Plane" #E8F4F8 {

    package "Market Data Listener (MDL)" #DDDDDD {
        component "MassiveDataListener" as Listener
        component "MassiveDataQueues" as Queues
        component "QueueNameResolver" as Resolver
    }

    package "Finlight Data Listener (FDL)" #DDDDDD {
        component "FinlightDataListener" as FDListener
        component "FinlightDataQueues" as FDQueues
    }

    queue "Market Data Queues (MDQ)" as MDQ #D0021B

    package "Market Data Processor (MDP)" #DDDDDD {
        component "MassiveDataProcessor" as Processor
        component "MarketDataScanner" as Scanner
        component "MassiveDataAnalyzer" as Router
        component "LeaderboardAnalyzer" as Leaderboard
        component "TopTradesAnalyzer" as TopTrades
        component "TopStocksAnalyzer" as TopStocks
    }

    package "Finlight Data Processor (FDP)" #DDDDDD {
        component "FinlightDataProcessor" as FDProcessor
    }

    database "Market Data Cache (MDC)" as MDC #F5A623
    database "Widget Data Cache (WDC)" as WDC #E67E22

    package "Widget Data Service (WDS)" #DDDDDD {
        component "WidgetDataService" as Widget
    }
}

package "Observability" #FFF9E6 {
    component "OpenTelemetry" as OTel
    component "Structured Logging" as Logging
}

package "Shared Libraries" #F0F0F0 {
    component "ProcessManager" as PM
    component "WebSocketMessageSerde" as Serde
    component "Utils" as Utils
}

actor "Web Clients" as Clients

Massive -[#red,thickness=3]-> Listener : WebSocket stream
Listener --> Resolver : route by type
Resolver --> Queues : publish
Queues -[#orange,thickness=3]-> MDQ : RabbitMQ (TTL: 5s)

Finlight -[#green,thickness=3]-> FDListener : WebSocket stream
FDListener --> FDQueues : handle_message
FDQueues -[#orange,thickness=3]-> MDQ : RabbitMQ (news queue)

MDQ -[#orange,thickness=3]-> Processor : consume (prefetch: 100)
MDQ -[#orange,thickness=3]-> FDProcessor : consume (news queue)
Processor --> Router : analyze
Router --> Leaderboard : aggregate events
Router --> TopTrades : trade events
Router --> TopStocks : legacy path
Scanner --> Leaderboard : scan leaderboards
Scanner --> TopTrades : scan trades
Processor -[#orange,thickness=3]-> MDC : analyzer cache (internal)
Processor -[#blue,thickness=3]-> WDC : widget results + pub/sub
FDProcessor -[#orange,thickness=3]-> MDC : analyzer cache (internal)
FDProcessor -[#blue,thickness=3]-> WDC : widget results + pub/sub

WDC -[#blue,thickness=3]-> Widget : Redis pub/sub
Widget -[#green,thickness=3]-> Clients : WebSocket streaming

SCP .[#purple,dashed].> Widget : manage/monitor
SCP -[#green,thickness=3]-> Clients : SPA + auth token

Listener .down.> OTel : traces/metrics
FDListener .down.> OTel : traces/metrics
Processor .down.> OTel : traces/metrics
FDProcessor .down.> OTel : traces/metrics
Widget .down.> OTel : traces/metrics
Listener .down.> Logging : JSON logs
FDListener .down.> Logging : JSON logs
Processor .down.> Logging : JSON logs
FDProcessor .down.> Logging : JSON logs
Widget .down.> Logging : JSON logs

Listener --> Serde : serialize
Processor --> PM : orchestrate
Listener --> Utils : API keys

note right of MDQ
  RabbitMQ
  Non-persistent messages
  5-second TTL
  Per-subscription queues
  FIFO ordering
end note

note right of MDC
  Market Data Cache (MDC)
  Redis db 0
  Internal analyzer state
  Leaderboards, snapshots,
  float, avg volume, tickers
  TTL policies (5s-24h)
end note

note right of WDC
  Widget Data Cache (WDC)
  Redis db 1
  Client-facing results
  Scanner feeds, quote feed,
  news feeds, top trades
  Pub/Sub to WDS
end note

note bottom of Processor
  Concurrency Model
  Semaphore limit: 500
  Async processing
  Horizontal scaling
  Stateless design
end note

note bottom of Listener
  Reconnection Strategy
  Market-aware
  Auto-reconnect
  60s polling (closed)
  Health tracking
end note

note as DeploymentNote
  Deployment: Kubernetes + Docker
  Independent scaling per component
  Data plane: internal network only
  WDS: exposed to clients
  SCP: external access
end note

@enduml