Skip to content
CAI
Software that uses CAICheck a score

hnaderi/edomata

66.9

Adequate · 21 September 2026

6.7k

lines of production code

Scala

primary language

4

measurements over time

CAI band scale
CAI trend line
CAI lens gauges

What this system is

Edomata is a functional domain modeling library for Scala that supports both Event Sourcing and CQRS architectural patterns. It provides a core DSL for defining state machines and commands, backed by pluggable persistence drivers for PostgreSQL via Doobie and Skunk. The system includes built-in mechanisms for command caching, retry logic, and outbox-based event publishing, with comprehensive cross-platform testing across JVM, Scala.js, and Scala Native.

Features

Add Jsoniter integration for Doobie and Skunk modules

Users can now serialize and deserialize JSON and MessagePack data using the Jsoniter library in both the Doobie and Skunk database modules. New \JsoniterCodec\ objects provide \json\, \jsonb\, and \msgpack\ codecs that leverage \com.github.plokhotnyuk.jsoniter\_scala\ for efficient encoding and decoding, allowing applications to switch from default JSON handling to the high-performance Jsoniter implementation.

modules/doobie-jsoniter, modules/skunk-jsoniter · high confidence

Add PlantUML diagram support in mdoc

Users can now include PlantUML diagrams in their documentation by using the \plantuml\ directive. The new \PlantumlModifier\ registers this capability, allowing code blocks to be rendered as SVG images via the PlantUML server. The implementation defaults to the 'toy' theme for visual styling.

mdoc-plantuml · high confidence

Added Circe and Upickle codecs for the Doobie backend

The Doobie backend now includes built-in serialization codecs for JSON and binary formats. Users can leverage \CirceCodec\ to encode/decode data using Circe (supporting JSON and JSONB) and \UpickleCodec\ for Upickle (supporting JSON, JSONB, and MessagePack), simplifying the integration of these libraries with the Doobie persistence layer.

modules/doobie-circe, modules/skunk-circe · high confidence

Added compile-time validation for PostgreSQL namespace names

The \modules/postgres\ module now includes a \PGNamespace\ opaque type that enforces PostgreSQL naming rules at compile time. Users can create namespace identifiers using a macro constructor (\`PGNamespace(

modules/postgres · high confidence

Introduce CQRS backend with command caching and retry logic

The CQRS backend module now provides a configurable \BackendBuilder\ that assembles a \Backend\ from a \StorageDriver\, an optional in-memory command cache, and a state cache. The command cache prevents redundant command processing by tracking executed command IDs, while the state cache (LRU) reduces database load by storing recent aggregate states. The \CommandHandler\ now includes built-in retry logic with jitter for handling version conflicts, configurable via \withRetryConfig\. Additionally, a \Notifications\ system using circular buffers allows consumers to subscribe to outbox and state update streams.

modules/backend/src/main/scala/cqrs · high confidence

New Doobie-based PostgreSQL persistence backend

Added a new persistence backend for PostgreSQL using the Doobie library, enabling users to store event-sourced state and command data in a relational database. This change introduces the \edomata.doobie\ package, which includes \DoobieDriver\ for event sourcing (with journal, snapshot, and outbox support) and \DoobieCQRSDriver\ for CQRS-style storage. The implementation provides \BackendCodec\ for serializing state and events as JSON, JSONB, or binary, and defines the necessary database schema (tables for journal, outbox, snapshots, and commands) along with readers and repositories to handle persistence operations.

modules/doobie/src/main · high confidence

New eventsourcing backend with command caching and retry logic

The \modules/backend/src/main/scala/eventsourcing\ directory now contains the implementation of the eventsourcing backend. This includes a \BackendBuilder\ that allows configuring command caching (with an in-memory default) and retry policies (with jitter) for command handling. The implementation introduces a \CachedRepository\ to optimize command processing by checking a command store and snapshots before hitting the underlying storage, and a \SnapshotStore\ with support for both in-memory and persisted snapshots, including deduplication of snapshot items on persistence.

modules/backend/src/main/scala/eventsourcing · high confidence

New examples demonstrating Skunk backend and CQRS integration

Added two new example files, Example1.scala and StomatonExample.scala, to illustrate the usage of the new Skunk backend and CQRS capabilities. Example1.scala shows a full application setup using the SkunkDriver with Circe codecs for JSONB storage, including session pooling and retry configuration. StomatonExample.scala demonstrates the CQRS model pattern, including the use of SkunkCQRSDriver and event handlers, providing a reference for implementing command/query separation with the new backend modules.

examples · high confidence

Project initialization and repository scaffolding

The repository has been initialized with the Edomata project, including the Apache 2.0 license, code of conduct, and a README detailing usage for Scala, Scala.js, and Scala Native. Development and CI workflows are established using Nix (flake.nix) and GitHub Actions (ci.sbt), with Docker Compose configured for PostgreSQL test databases. The build is configured with sbt-typelevel, pinned to Scala 3.3 LTS, and uses scalafmt 3.11.5 for code formatting.

(repo-wide) · high confidence

Removals

Removed HTTP endpoint routing and backend test infrastructure

The HTTP route definitions for FSM commands (FSMRoute) and their associated integration tests have been removed from the endpoint module. Additionally, the backend test kit infrastructure—including the DomainSuite trait, FakeCommandHandler, ScenarioCommandHandler, and Timeline utilities used for testing domain logic—has been deleted from the testkits/backend module.

modules/endpoint, testkits/backend · high confidence

Removed initial event-sourcing implementation draft

The \modules/eventsourcing\ module has been cleared of its initial draft code, removing all core abstractions and implementations. This includes the deletion of the \Journal\ and \SnapshotStore\ traits, their in-memory implementations (\InMemJournal\, \InMemSnapshotStore\), the \ESRepository\ interface and its \MyESRepository\ implementation, along with supporting types like \ConsumerController\, \JournalConsumer\, \SnapshotCache\, and the \Transition\ type. Corresponding unit tests for these components have also been removed.

modules/eventsourcing · high confidence

Behavioural changes

Backend refactored to support CQRS and Event Sourcing with outbox and retry mechanisms

The backend module has been restructured to support both Event Sourcing and CQRS patterns, replacing the previous single-pattern implementation. Users can now build backends for either domain type via the new \Backend.builder\ entry points. The change introduces an outbox pattern with \OutboxReader\ and \OutboxConsumer\ to handle event publishing, and adds a retry mechanism with jitter in \Helpers\ to handle \VersionConflict\ errors during command processing. Additionally, the internal \LRUCache\ has been refactored to implement a new \Cache\ trait with conditional replace capabilities, and the package has been renamed from \edfsm\ to \edomata\.

modules/backend/src/main/scala · high confidence

Core domain modeling API restructured with new DSLs and types

The core module has been refactored to introduce a new domain modeling architecture. The previous \edfsm.core\ package has been replaced by \edomata.core\, featuring new \Edomaton\ and \Stomaton\ types for event-driven state machines, alongside a comprehensive DSL (\DomainDSL\, \CQRSDomainDSL\) for constructing domain logic. The response model has been updated from \Response\ to \ResponseD\ (built on \ResponseT\), and the \Action\ monad now wraps \ResponseD\ directly. Additionally, \RequestContext\ and \CommandMessage\ types have been introduced to standardize input handling, while legacy files like \EDFSM\ and \Request\ have been removed.

modules/core/src/main · high confidence

Migrated documentation site to Typelevel Helium and updated build infrastructure

The project documentation site has been rebuilt using the Typelevel Helium theme, replacing the previous microsites setup. This change introduces a new landing page with updated metadata, navigation links to related Typelevel projects (cats, cats-effect, fs2), and specific teasers highlighting Edomata's features such as cross-platform support and functional design. The build infrastructure has been significantly modernized: sbt has been upgraded to version 1.13.0, and the plugin suite has shifted to the Typelevel ecosystem (sbt-typelevel, sbt-typelevel-site) while adding support for Scala Native and Scala.js. Additionally, core library dependencies have been updated to their latest versions, including Cats 2.13.0, Cats Effect 3.7.1, FS2 3.14.0, and Doobie 1.0.0-RC12.

project · high confidence

Skunk backend persistence layer refactored and modernized

The \modules/skunk/src/main\ persistence implementation has been completely rewritten to use the \edomata\ package structure and the \BackendCodec\ abstraction for type-safe serialization, replacing the legacy \edfsm\ codebase. Old files such as \DAOError\, \DataAccessLayer\, \Database\, \PGJournal\, and \PGServiceBuilder\ have been removed and replaced with new, modular components including \SkunkDriver\, \SkunkCQRSDriver\, \SkunkRepository\, \SkunkCQRSRepository\, \SkunkJournalReader\, \SkunkOutboxReader\, and \SkunkSnapshotPersistence\. This change introduces a cleaner separation between Event Sourcing and CQRS storage drivers, utilizes \Resource\-based session pooling for safer database access, and standardizes schema management and query definitions within the \Queries\ object.

modules/skunk/src/main · high confidence

Test coverage

Added Doobie integration tests for event sourcing and CQRS backends; Added comprehensive test suites for core Decision, Stomaton, and ResponseT components; Added end-to-end tests for the accounts module with Doobie and Skunk backends; Added integration test suites for backend storage and CQRS implementations; Added munit integration module; Added test coverage for CQRS backend components; Added test suite and test doubles for backend components; Added tests for the eventsourcing backend components; Migrated skunk backend tests to edomata compatibility suites.

Dependencies

Upgrade to Scala 3.3.6 and update core dependencies

The project has upgraded its base Scala version from 3.1.0 to 3.3.6. This change is accompanied by updates to key libraries, including scala-java-time to 2.7.0 for JavaScript platforms and PlantUML to 1.2026.8 for documentation generation. The build structure has also been refactored to use the Typelevel sbt plugin conventions, updating the base version to 0.13 and reorganizing module definitions.

(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 → 67 (+14.0)
  • Rubric changed (rubric-2026.08.19 → rubric-2026.09.15) — scores are not directly comparable.

Lenses

  • Code Health 100 → 98 (-1.5)
  • Architecture 100 → 99 (-0.6)
  • Maturity 42 → 66 (+24.0)
  • Readiness 61 → 56 (-5.1)
  • Security 42 → 74 (+31.4)
  • Domain Modelling 100 → 100 (+0.0)

Resolved (30)

  • Coverage not included — suite not readable by the collector
  • Dependency hygiene not measured — dependency manifest found but not parsed for hygiene
  • 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)
  • 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 10 more

New (33)

  • Documentation: no contributor guidance (README.md)
  • Documentation: no installation or build instructions (README.md)
  • Documentation: no usage examples (README.md)
  • DoobieCQRSRepository.save (cognitive 19) (modules/doobie/src/main/scala/DoobieCQRSRepository.scala)
  • DoobieRepository.append (cognitive 30) (modules/doobie/src/main/scala/DoobieRepository.scala)
  • Duplicated block (11 lines × 2) (modules/doobie-upickle/src/main/scala/UpickleCodec.scala)
  • Duplicated block (16 lines × 2) (modules/doobie-jsoniter/src/main/scala/JsoniterCodec.scala)
  • 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)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • …and 13 more

Changes since last survey

  • 17 commits — 17 feature/other, 0 fixes

By area

  • project/Dependencies.scala — 6 commits
  • project/plugins.sbt — 5 commits
  • (root) — 4 commits
  • project/build.properties — 2 commits

Notable commits

  • change: Removed dead external link
  • change: Update cats-effect, cats-effect-testkit to 3.7.1 (#666)
  • change: Update fs2-core to 3.14.0 (#675)
  • change: Update jsoniter-scala-core to 2.40.1 (#655)
  • change: Update jsoniter-scala-core to 2.41.0 (#681)
  • change: Update mdoc, sbt-mdoc to 2.9.2 (#671)
  • change: Update munit-cats-effect to 2.2.1 (#682)
  • change: Update munit-scalacheck to 1.3.1 (#673)
  • change: Update plantuml to 1.2026.7 (#667)
  • change: Update plantuml to 1.2026.8 (#676)
  • change: Update sbt, scripted-plugin to 1.12.15 (#657)
  • change: Update sbt, scripted-plugin to 1.13.0 (#663)
  • change: Update sbt-buildinfo to 0.13.2 (#679)
  • change: Update sbt-scala-native-crossproject to 1.4.0 (#662)
  • change: Update sbt-scalafix to 0.14.8 (#677)
  • change: Update sbt-scalafix to 0.14.9 (#678)
  • change: flake.lock: Update (#670)

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

Survey your own repository

hnaderi/edomata 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 a1e2ac264a864f57138597b3acf42d09924901cd — 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-fa71c66cabd8.