Skip to content
CAI
Software that uses CAICheck a score

gvolpe/trading

53.7

Adequate · 21 September 2026

4.8k

lines of production code

Scala

primary language

4

measurements over time

CAI band scale
CAI trend line
CAI lens gauges

What this system is

This release delivers a comprehensive modernization of the trading platform, introducing new microservices for alerts, forecasts, and snapshots, alongside a complete rebuild of the frontend using Tyrian and Elm. The core architecture has been significantly refactored to leverage Scala 3 features, including strong typing for domain models, functional state machines, and centralized message handling via Pulsar. Additionally, the release establishes a robust observability and monitoring stack with Prometheus, Grafana, and Honeycomb, while upgrading the entire build infrastructure to Scala 3.5.2.

Features

Add HTTP health check endpoints and server configuration

The application now exposes a /health endpoint that returns a 200 OK status, allowing external monitoring systems to verify service availability. This is implemented via a new HealthRoutes module and an Ember server builder that integrates Prometheus metrics middleware. The server configuration is now explicit, supporting both standard HTTP and WebSocket routes, with the health check route automatically added to all service endpoints.

modules/core/src/main/scala/trading/core/http · high confidence

Add Redis-backed snapshot persistence for trading state

The trading system now persists and retrieves the latest trade state, including ask/bid prices and high/low values, via Redis. A new SnapshotReader reads the most recent snapshot (including status and message ID) to resume from the last known state, while the SnapshotWriter saves state updates into Redis with key expiration and retry logic for transactional writes.

modules/core/src/main/scala/trading/core/snapshots · high confidence

Add monitoring stack with Prometheus, Grafana, and Pulsar Manager

The monitoring area now includes a full observability stack. Prometheus is configured to scrape metrics from the application services (tracing, alerts, processor, snapshots, ws-server) and itself. Grafana is set up with a file-based provider to load dashboards, including a new JVM services dashboard that visualizes heap memory metrics. Additionally, the Pulsar Manager is configured with HerdDB for its backend, enabling a web UI for managing the Pulsar cluster.

monitoring · high confidence

Add new demo modules for Scala 3 features and distributed tracing

The x-demo module introduces several new examples demonstrating Scala 3 capabilities and distributed tracing patterns. These include DepTypes.scala for dependent types, DerivationDemo.scala for type class derivation, ErrorLifting.scala for union types in error handling, and a complete tracing application (TraceApp, Engine, Routes) using Natchez and Honeycomb. Additional demos cover effectful contexts, Kafka and in-memory consumers/producers, Redis-based distributed locks, Doobie transactions, and deduplication logic with tests.

modules/x-demo · high confidence

Added compiled JavaScript output for the ws-client module

The build process now generates a compiled JavaScript file (main.js) in the scala-3.2.1 target directory, making the ws-client's optimized output visible to the Nix build system.

modules/ws-client/target · high confidence

Added deduplication and trade state management for market data

Users benefit from improved reliability and state management in the trading domain. A new DedupState mechanism filters out duplicate command IDs within a 5-minute window to prevent redundant processing. Additionally, a new TradeState structure now tracks trading status and maintains a detailed record of bid and ask prices, including high and low price points, enabling more accurate market data handling.

modules/domain/shared/src/main/scala/trading/state · medium confidence

Initial release of the Elm-based web application

The web-app/src directory now contains the complete Elm application, including the main entry point, model, view, update logic, and WebSocket subscriptions. Users can connect to a WebSocket server, subscribe to and unsubscribe from trading symbols, and view real-time alerts including bid/ask prices, high/low values, and trade status. The UI displays connection details, online user count, and a table of alerts with icons for each alert type.

web-app/src · high confidence

Initial web client implementation using Tyrian and WebSocket support

The web client module (modules/ws-client) is introduced, providing a complete frontend for the trading application built with the Tyrian framework. This includes the core application entry point (WebApp), state management (Model, Update), and UI rendering (View, AlertsUI). The client establishes WebSocket connections to the server, handling connection states (Connecting, Connected, Disconnected) and processing incoming messages for trade alerts, subscription status, and online user counts. The implementation supports subscribing and unsubscribing to trading symbols, displaying real-time trade alerts in a table, and managing user input for symbol entry.

modules/ws-client/src · high confidence

Introduce Nix build system for the web-app

The web-app is now built using a Nix derivation (app.nix) that compiles the Elm application and minifies the output. The build process relies on Elm 0.19.1 and specific versions of core Elm packages (elm/core, elm/html, elm/browser, elm/json) as defined in elm.json and elm-srcs.nix. The resulting HTML page includes Bootstrap 4.5.2 and jQuery 3.5.1 for styling and interactivity.

web-app · high confidence

Introduce WebSocket server for real-time trading alerts

Added a new WebSocket server module that exposes a /v1/ws endpoint to deliver real-time trading alerts to connected clients. The implementation manages individual socket connections, allowing users to subscribe and unsubscribe from specific symbol alerts, with the server tracking active connections and broadcasting relevant trade alerts via JSON-encoded WebSocket frames.

modules/ws-server/src/main · high confidence

Introduce configurable feed service with HTTP and Pulsar integration

The feed module now includes a new configuration system that loads the HTTP port and Pulsar connection details from environment variables, allowing the feed service to be configured at runtime. The main entry point wires up Pulsar producers and consumers for trading, switch, and forecast commands, while also exposing an HTTP health check route. This change enables the feed service to be started with flexible network and messaging settings rather than hardcoded values.

modules/feed · high confidence

Introduce distributed tracing for trading and forecasting commands and events

Added new tracing implementations for the trading and forecasting domains, enabling end-to-end visibility into command and event processing. The \TradingTracer\ and \ForecastingTracer\ modules create Natchez spans for commands, events, and alerts, attaching correlation IDs, timestamps, and JSON payloads to each trace. A Honeycomb entry point is provided to configure the tracing backend, allowing users to integrate their distributed tracing infrastructure with the trading system.

modules/tracing/src/main/scala/trading/trace/tracer · medium confidence

Introduce new tracing module for monitoring trading and forecasting events

A new \tracing\ module has been added to provide observability for the trading and forecasting systems. This includes configuration for HTTP ports, Pulsar message queues, and Honeycomb API keys, alongside the main application entry point that subscribes to various event streams (alerts, trading, author, and forecast events) and processes them through finite state machines. The module also defines specific kernel types for commands and events to support tracing.

modules/tracing/src/main/scala/trading/trace · high confidence

Introduce snapshots service to persist and restore trading state

A new snapshots service has been added to the system, responsible for persisting the current state of trades and switch events to Redis. The service loads the latest persisted state on startup to ensure continuity, uses a distributed lock to manage exclusive subscriptions to Pulsar topics for both trade and switch events, and periodically saves state updates. This allows the system to recover from failures by replaying from the last known good snapshot.

modules/snapshots/src/main · high confidence

Introduce the Forecasts service with SQL persistence and CDC outbox pattern

The Forecasts service is introduced, providing a new capability to manage authors, forecasts, and votes. The service persists data to a SQL database using Flyway migrations (creating tables for authors, forecasts, votes, and an outbox) and utilizes a CDC outbox pattern to publish events to Pulsar. The implementation includes an Engine to process commands, a VotesHandler to process events, and a H2-specific trigger to simulate CDC for local development.

modules/forecasts/src/main · high confidence

Introduce the Tyrian-based web client for the trading application

The web client has been rebuilt using the Tyrian framework, providing a modern, component-based UI for the trading platform. This change introduces a new frontend architecture that leverages Scala.js and the Tyrian library to render the trading interface, replacing the previous implementation. The update includes a new Nix build configuration for the web application, ensuring consistent and reproducible builds for the client-side assets and dependencies.

modules/ws-client · high confidence

Introduce the alerts service as a stateful engine processing trading and switch events

The alerts module now contains the core logic for the alerts service, including configuration loading, an FSM-based engine that processes TradeEvent, SwitchEvent, and PriceUpdate messages, and a main entry point that wires up Pulsar consumers and producers. The engine maintains state via snapshots and emits alerts based on price update thresholds, with transactional acknowledgments and deduplication support.

modules/alerts · high confidence

Introduced new domain types for alerts, forecasts, and trading status

Added new domain models including Alert, AlertType, Forecast, ForecastTag, PriceUpdate, TradeAction, TradingStatus, and VoteResult, along with supporting types like AppId, Author, and OrphanInstances. These changes establish the data structures for handling trading alerts, price updates, and forecast data within the shared domain layer.

modules/domain/shared/src/main/scala/trading/domain · high confidence

New command types for trading, forecasting, and switching

Added new domain command types for the trading system: TradeCommand (Create, Update, Delete), ForecastCommand (Register, Publish, Vote), and SwitchCommand (Start, Stop). Each command includes standard metadata fields (id, correlationId, createdAt) and uses Scala 3 enums with automatic derivation for serialization and equality.

modules/domain/shared/src/main/scala/trading/commands · high confidence

New domain event types for trading, forecasts, and switches

Introduced new domain event types for the trading system, including TradeEvent (CommandExecuted/CommandRejected), ForecastEvent (Published/Voted), SwitchEvent (Started/Stopped/Ignored), and AuthorEvent (Registered). These events are defined as Scala enums with Circe codecs, enabling structured serialization and deserialization of domain events across the system.

modules/domain/shared/src/main/scala/trading/events · high confidence

New lib module provides core abstractions for message processing and state management

The modules/lib directory now contains a suite of new abstractions for the trading system. This includes the Acker trait for managing message acknowledgments, and the Consumer and Producer traits that define interfaces for interacting with message brokers (Pulsar and Kafka). The FSM trait introduces a functional state machine model for processing events. Additionally, the library adds support for distributed locking via Redis (DistLock), a generic UUID generator (GenUUID), a structured logging facade (Logger), and typeclasses for message key extraction (Compaction and Shard) to support topic compaction and key-shared subscriptions. These components collectively provide the foundational building blocks for the application's messaging and state management.

modules/lib · high confidence

Behavioural changes

Add JS-specific Symbol domain type

A new Scala file, Symbol.scala, has been added to the JS module, defining a newtype wrapper for currency pair symbols (e.g., EURUSD, GBPUSD). This implementation provides a Monoid instance for combining symbols, defaulting to an XEMPTY placeholder. This change reflects a platform-specific implementation for JavaScript, as the codebase notes that refinement types (like those used in the JVM version) are not yet supported by the iron library on Scala.JS.

modules/domain/js · high confidence

Centralized WebSocket management in new WsPorts module

The JavaScript code for managing WebSocket connections has been extracted into a new, dedicated file, WsPorts.js. This module now encapsulates the logic for connecting, sending, and receiving messages over a WebSocket, including a heartbeat mechanism to keep the connection alive and handling of connection errors and closures.

web-app/js · high confidence

Enable message deduplication and add Debezium PostgreSQL demo configuration

The Pulsar broker now enforces message deduplication by default, preventing duplicate messages from being stored in topics. This is configured in the standalone broker configuration file. Additionally, a new configuration file has been added to support a Debezium PostgreSQL connector demo, allowing users to test PostgreSQL data replication into Pulsar.

pulsarconf · high confidence

Introduce Pulsar-based message processing with transactional guarantees and deduplication

The processor module now implements a functional state machine (FSM) that consumes trade and switch commands from Pulsar topics, processes them against the current state, and publishes resulting events back to Pulsar. This change introduces transactional support for message acknowledgment (ensuring at-least-once delivery with deduplication enabled on producers) and configures exclusive subscriptions for switch commands to support topic compaction. The application entry point wires up HTTP health checks, Pulsar consumers/producers, and the processing engine, making the processor fully reliant on Pulsar for both input and output messaging.

modules/processor/src/main · high confidence

Introduce centralized topic definitions and refactored trade engine logic

The core module now defines all message topics in a single \AppTopic\ enum, replacing the previous scattered or implicit topic naming. The \TradeEngine\ has been refactored to use a state-machine (FSM) approach, explicitly handling trading start/stop commands and rejecting trade commands when the system is off. Additionally, the generic \Consumer\, \Producer\, and \Time\ traits have been removed, indicating a shift away from the previous abstraction layer for these concerns.

modules/core/src/main/scala/trading/core · medium confidence

Introduce strong typing for domain identifiers and values

The trading domain now uses opaque newtypes for identifiers (CommandId, AlertId, EventId, CorrelationId, SocketId, AuthorId, ForecastId) and value objects (PulsarURI, RedisURI, Timestamp, Quantity, Price, etc.), replacing raw types like String, Int, and Instant with distinct, type-safe wrappers. This change enforces compile-time guarantees that these values are used correctly across the application, reducing the risk of mixing up different kinds of IDs or timestamps.

modules/domain/shared/src/main/scala/trading · high confidence

Introduces typed state machines for tracing forecast and trade flows

The tracing module now uses distinct, strongly-typed finite state machines (FSM) for handling forecast and trade events. For forecasts, the system tracks authoring, forecasting, and command events in separate lists, matching them by correlation ID. For trades, the FSM tracks trade events, alerts, and a time-expiring map of matching command/event kernels, ensuring that commands and events are correctly correlated and that stale entries are cleaned up after one minute. This structural change replaces previous, less explicit state handling with explicit types for states (ForecastState, TradeState) and inputs (ForecastIn, TradeIn), improving type safety and clarity in the tracing logic.

modules/tracing/src/main/scala/trading/trace/fsm · medium confidence

Migrate development environment from legacy shell.nix to Nix flakes

The project has replaced the legacy shell.nix with a new flake.nix and flake.lock, introducing a unified Nix-based build and development environment. This change introduces dedicated Nix shells for Scala, Elm, and Tyrian web clients, and provides pre-built Docker images for JDK 17. The migration also updates the .scalafmt configuration to support Scala 3 syntax and updates the .gitignore to exclude new build artifacts and cache directories.

(repo-wide) · high confidence

Refactor WebSocket message types into dedicated enums

The WebSocket domain model has been refactored to use dedicated Scala 3 enums for incoming and outgoing messages. Incoming messages (WsIn) now explicitly define Close, Heartbeat, Subscribe, and Unsubscribe actions. Outgoing messages (WsOut) define Attached, Notification, and OnlineUsers, with custom equality logic for the WsOut enum. This change replaces previous representations with stronger, more explicit types for the trading WebSocket interface.

modules/domain/shared/src/main/scala/trading/ws · medium confidence

Removal of TradeCommand domain model

The TradeCommand domain model, which previously defined Create, Update, and Delete commands for trading operations, has been removed from the codebase. This change eliminates the specific command structures used to represent trade actions, prices, and quantities within the trading module.

modules/domain/src/main/scala/trading/commands · high confidence

Removal of TradeEvent domain model

The TradeEvent sealed trait and its CommandExecuted case class have been removed from the trading domain. This eliminates the previous event structure that included a command reference and timestamp, indicating a shift in how trading events are modeled or handled within the system.

modules/domain/src/main/scala/trading/events · high confidence

Removal of the legacy trading engine and main entry point

The \Engine\ trait and its \Main\ application entry point in the \modules/trading\ module have been deleted. This removes the previous implementation that processed \TradeCommand\ streams and produced \TradeEvent\ outputs via a queue-based producer/consumer model. Users will no longer interact with this specific engine implementation.

modules/trading · high confidence

Removed domain type aliases from package object

The package object in the trading domain module, which previously defined type aliases for financial concepts such as Symbol, Price, Quantity, and Timestamp, has been removed. This change eliminates the global availability of these type aliases within the trading domain package, requiring explicit imports or local definitions for these types.

modules/domain/src/main/scala/trading · high confidence

Removed obsolete TradeState and Prices domain models

The TradeState and Prices case classes, which previously tracked ask, bid, high, and low prices in a Map structure, have been removed from the trading state module. This change eliminates the legacy data structures in favor of the new state representation.

modules/domain/src/main/scala/trading/state · medium confidence

Removed obsolete domain models for alerts and trade actions

The Alert and TradeAction domain models have been removed from the trading domain. Specifically, the sealed traits for alert types (StrongBuy, StrongSell, Neutral, Buy, Sell) and trade actions (Ask, Bid) are no longer present in the codebase, indicating a simplification or migration away from these specific domain concepts.

modules/domain/src/main/scala/trading/domain · high confidence

Symbol type now enforces 6-character alphanumeric format via refinement types

The Symbol domain type has been refactored to use refinement types (via the 'iron' library), ensuring that Symbol values strictly match the pattern of six alphanumeric characters. This change introduces a compile-time or runtime constraint that prevents invalid symbol formats from being constructed, improving data integrity for trading operations.

modules/domain/jvm/src/main · high confidence

Test coverage

Add smoke tests for the trading system; Add unit tests for the trading processor engine; Added integration tests for Redis and SQL stores; Added property-based and round-trip tests for trading domain and WebSocket codecs; Added property-based tests for TradeState optics; Added test suite for the WebSocket handler; Added tests for the trading FSM; Added tests for the trading snapshot FSM engine; Added unit tests for the TradeEngine state machine; Added unit tests for the forecast engine and vote handling.

Dependencies

Upgrade build tooling and core Scala libraries

The project has upgraded its build infrastructure and dependencies. SBT has been updated to version 1.9.4, and the SBT plugin ecosystem has been modernized, including updates to sbt-tpolecat, sbt-revolver, sbt-native-packager, sbt-scalafmt, and sbt-scalafix. Additionally, the codebase has been migrated to Scala 3, and core libraries such as cats-effect, http4s, and fs2 have been updated to their latest versions.

project · high confidence

Upgrade to Scala 3.5.2 and modernize build configuration

The project has been upgraded to Scala 3.5.2, bringing the latest language features and performance improvements. The build configuration has been modernized with improved task management, enabled semanticdb for better IDE support, and updated plugin dependencies. Additionally, the ws-client module now includes a package.json and yarn.lock file, introducing Parcel as the JavaScript bundler for the web client.

(dependencies) · high confidence

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

How this codebase got here

This is the PUBLIC form of this artifact. Findings are listed in full, but the details of SECURITY findings — which rule fired, in which file, on which line, and how to fix it — are deliberately withheld, and any secret-scanner results are excluded entirely. Where detail is absent here it was REMOVED FOR PUBLICATION; it is not missing from the analysis. The complete artifact is available from the repository owner.

Score

  • CAI 53 → 54 (+0.6)
  • Rubric changed (rubric-2026.08.18 → rubric-2026.09.15) — scores are not directly comparable.

Lenses

  • Code Health 100 → 95 (-4.7)
  • Architecture 95 → 100 (+5.0)
  • Maturity 44 → 48 (+3.3)
  • Readiness 59 → 56 (-2.3)
  • Security 55 → 53 (-2.3)
  • Domain Modelling 100 → 88 (-12.1)
  • Accessibility 53 → 53 (+0.0)

Resolved (27)

  • Boundary-crossing change coupling: Model.scala ↔ Dependencies.scala (modules/ws-client/src/main/scala/trading/client/Model.scala)
  • Boundary-crossing change coupling: Update.scala ↔ Dependencies.scala (modules/ws-client/src/main/scala/trading/client/Update.scala)
  • Change coupling: AuthorStore.scala ↔ ForecastStore.scala (modules/forecasts/src/main/scala/trading/forecasts/store/AuthorStore.scala)
  • Coverage not included — suite not readable by the collector
  • Dependency hygiene not measured — dependency manifest found but not parsed for hygiene
  • High CVE: [GHSA redacted] (modules/ws-client/yarn.lock)
  • High CVE: [GHSA redacted] (modules/ws-client/yarn.lock)
  • High CVE: [GHSA redacted] (modules/ws-client/yarn.lock)
  • High CVE: [GHSA redacted] (modules/ws-client/yarn.lock)
  • High IaC: DS-0002 (modules/Dockerfile)
  • High vulnerability: [GHSA redacted] (modules/ws-client/yarn.lock)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • …and 7 more

New (245)

  • CI runs a third-party container image from a mutable tag (.github/workflows/ci-smokey.yml)
  • CI runs a third-party container image from a mutable tag (.github/workflows/ci-smokey.yml)
  • CI runs a third-party container image from a mutable tag (.github/workflows/ci-smokey.yml)
  • Dependency hygiene PARTLY measured — npm pinning read, dependency currency not (the committed lockfile resolved no direct production dependency)
  • Documentation: no installation or build instructions (README.md)
  • Documentation: no usage examples (README.md)
  • Duplicated block (10 lines × 3) (modules/forecasts/src/main/scala/trading/forecasts/Config.scala)
  • Duplicated block (6–7 lines × 2) (modules/tracing/src/main/scala/trading/trace/tracer/ForecastingTracer.scala)
  • Engine.fsm (cognitive 16) (modules/alerts/src/main/scala/trading/alerts/Engine.scala)
  • High CVE: [GHSA redacted] (modules/ws-client/yarn.lock)
  • High CVE: [GHSA redacted] (modules/ws-client/yarn.lock)
  • High CVE: [GHSA redacted] (modules/ws-client/yarn.lock)
  • High CVE: [GHSA redacted] (modules/ws-client/yarn.lock)
  • High CVE: [GHSA redacted] (modules/ws-client/yarn.lock)
  • High CVE: [GHSA redacted] (modules/ws-client/yarn.lock)
  • High IaC: WD-COMPOSE-0002 (docker-compose.yml)
  • High IaC: WD-COMPOSE-0002 (docker-compose.yml)
  • High IaC: WD-COMPOSE-0002 (docker-compose.yml)
  • High IaC: WD-COMPOSE-0002 (docker-compose.yml)
  • High IaC: WD-COMPOSE-0002 (docker-compose.yml)
  • …and 225 more

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

Survey your own repository

gvolpe/trading was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.

About this page

  • The score is its most recent published measurement, taken on 21 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
  • Measured at commit e38afe019eda8c97185371de228002047a5ae890 — the exact code this score is about.
  • Scored under rubric-2026.09.15 — the same rubric and the same method as every other entry in this index.
  • Measured by watchdog.canine.dev using codehealth-analyzer preprod-28e75b8e3254.