Skip to content
CAI
Software that uses CAICheck a score

itswuanran/enode

50.5

Weak · 22 September 2026

15.6k

lines of production code

Kotlin

with Java

7

measurements over time

CAI band scale
CAI trend line
CAI lens gauges

What this system is

Enode is an event-driven framework for building distributed systems using the Command and Event Sourcing patterns. It provides a unified infrastructure for asynchronous command processing, domain event handling, and message queue integration across multiple backends including Kafka, RabbitMQ, and Redis. The system supports various event stores such as MySQL, PostgreSQL, MongoDB, and in-memory implementations, all configured via Spring Boot auto-configuration. The core domain and messaging layers have been modernized in Kotlin to support non-blocking, coroutine-based execution.

How it got here

2019 — Framework modernization and sample migration

26 changes.

The project underwent a significant architectural shift, removing legacy Java command processing and MySQL-specific schemas in favor of a multi-backend, annotation-driven framework. This period focused on rewriting message queue integrations in Kotlin, introducing new core APIs and exception handling, and replacing old samples with a modernized bank-transfer example.

2020 — Kotlin migration and async support

18 changes.

The project underwent a comprehensive migration of its core subsystems—including commanding, domain, eventing, and messaging—to Kotlin, leveraging coroutines for asynchronous processing. This period also introduced extensive test coverage and configuration support for various event stores and message queues, alongside new in-memory and JDBC/PostgreSQL/MongoDB implementations.

2021–2023 — Kotlin migration and queue integration

15 changes.

This period focused on migrating the framework's core domain and queue modules to Kotlin, introducing new abstractions for aggregate management and message handling. It also expanded the system's capabilities by adding support for multiple message brokers (AMQP, Ons, Pulsar, TCP, Redis) and implementing comprehensive metrics monitoring for observability.

Features

Add JDBC-based event and version store implementations

The JDBC module now includes new Kotlin implementations for the event store and published version store: JDBCEventStore, JDBCPublishedVersionStore, and their associated handlers. These classes provide the underlying persistence logic for domain events and aggregate published versions using SQL client operations, enabling users to persist event-sourced data in a relational database.

jdbc · high confidence

Add Kafka, RocketMQ, and JDBC event consumer configurations

The event-consumer sample now includes explicit configuration classes for subscribing to and publishing events via Kafka, RocketMQ, and MySQL (via JDBC). EventAppConfig defines the JDBC pool and Vertx bean, while KafkaEventConfig and RocketMQEventConfig set up the respective message listeners and producers, enabling the application to consume and produce events through these specific message queue or database backends.

samples/bank-transfer/event-consumer/src/main/java/org/enodeframework/samples/eventhandlers · high confidence

Add Kotlin-based MongoDB event store implementation

The MongoDB event store is now implemented in Kotlin, introducing new files: MongoEventStore.kt, MongoHandlers.kt, and MongoPublishedVersionStore.kt. This change adds support for batch appending events, querying aggregate events, and managing published versions in MongoDB using the Vert.x MongoDB client. The implementation handles duplicate command and event detection, retry logic, and error mapping for MongoDB write and server exceptions.

mongo · high confidence

Add MySQL event store and published version store implementations

Introduced new Kotlin implementations for the MySQL event store (MySQLEventStore) and published version store (MySQLPublishedVersionStore), along with supporting handlers (MySQLHandlers). The event store provides batch appending of domain events, querying events by aggregate ID and version range, and finding events by version or command ID. The published version store manages processor-specific version tracking with insert/update logic. These components use the Vert.x MySQL client for database interactions.

mysql · high confidence

Add NoteController for note management

Added a new REST controller at /note that exposes endpoints for creating and updating notes via the CommandBus. The controller provides create and update operations that execute commands asynchronously, returning results as reactive Mono types. A test endpoint is also included to benchmark command execution performance using different return types and execution modes.

samples/bank-transfer/command-web/src/main/java/org/enodeframework/samples/controller/note · high confidence

Add Ons message broker integration for sending and replying to messages

New Kotlin classes (OnsMessageListeners, OnsProducerHolder, OnsSendMessageService, OnsSendReplyService) implement the message queue interfaces for Alibaba Cloud Ons. This adds support for sending messages asynchronously, handling incoming messages via listeners, and sending reply messages to a configured reply topic.

ons · high confidence

Add PostgreSQL event store implementation

The PostgreSQL event store implementation is added, providing a new backend for persisting and querying domain events. The change introduces PgEventStore, PgPublishedVersionStore, and associated handlers in the pg module, enabling the framework to store and retrieve event streams and published versions using PostgreSQL.

pg · high confidence

Add Pulsar message queue support with reply queue capability

The Pulsar integration now supports sending messages and handling replies via new Kotlin-based services. Users can send messages asynchronously through PulsarProducerHolder and PulsarSendMessageService, while the new PulsarSendReplyService enables reply queue support, allowing the framework to process and send reply messages back through Pulsar.

pulsar · high confidence

Add TCP-based reply queue support for message delivery

The TCP transport layer now supports a reply queue mechanism, enabling asynchronous message delivery via a new \PointToPointEventBus\ implementation. This change introduces three new components: \TcpReplyMessageListener\ to handle incoming reply messages and route them to the command result processor, \TcpSendReplyService\ to send reply messages over TCP, and the underlying \PointToPointEventBus\ to manage TCP connections and message queuing. This allows the system to send and receive reply messages through the TCP bridge, improving reliability for distributed event bus communication.

tcp · high confidence

Add configuration for event consumer service

The event consumer sample now includes an application.properties file that configures the service on port 8004, sets up a JDBC-MySQL event store, and connects to a Kafka message queue. A logback-spring.xml file is also added to define logging behavior for the Enode framework and the application.

samples/bank-transfer/command-web/src/main/resources, samples/bank-transfer/event-consumer/src/main/resources · high confidence

Add message queue and database configuration for the bank-transfer sample

The bank-transfer sample now includes configuration classes for connecting to Kafka, RocketMQ, and a MySQL-backed JDBC event store. Users can enable these backends by setting the 'spring.enode.mq' and 'spring.enode.datasource.eventstore' properties, which wire up the necessary Spring beans for message listening and database pooling.

samples/bank-transfer/command-consumer/src/main/java/org/enodeframework/samples/commandhandles · high confidence

Add message queue configuration for Kafka and RocketMQ

The sample application now includes dedicated configuration classes for integrating with Kafka and RocketMQ message brokers. New files, KafkaConfig.java and RocketMQConfig.java, define the necessary beans for producing and consuming messages, enabling the application to route commands and replies through these specific message queue systems.

samples/bank-transfer/command-web/src/main/java/org/enodeframework/samples/controller · high confidence

Add queue and service configuration properties

A new Java class, QueueProperties, has been added to the samples domain to centralize configuration values for message queues and services. This includes connection details for a nameserver and Kafka server, as well as default producer and consumer group identifiers for multiple instances, alongside a JDBC URL for database connectivity.

samples/bank-transfer/samples-domain/src/main/java/org/enodeframework/samples · high confidence

Add reply queue support with new message handler and model

A new reply queue mechanism has been introduced, featuring a GenericReplyMessage model and a DefaultReplyMessageHandler. The handler processes incoming reply messages by deserializing them into the GenericReplyMessage model and forwarding the result to the command result processor, enabling the system to handle command execution replies from the queue.

enode/src/main/java/org/enodeframework/queue/reply · high confidence

Added NoteEventHandler for processing note domain events

A new event handler class, NoteEventHandler, has been introduced in the event-consumer module. It subscribes to note-related domain events (NoteCreated, NoteTitleChanged, and NoteTitleChanged2) and logs the denormalized data, including title, version, and timestamp. This adds a concrete implementation for handling these specific events within the sample application.

samples/bank-transfer/event-consumer/src/main/java/org/enodeframework/samples/eventhandlers/note · high confidence

Added asynchronous task and I/O helper utilities

The framework introduces new utility classes for managing asynchronous operations and I/O tasks. The new IOHelper object provides a robust mechanism for executing asynchronous actions with built-in recursive retry logic, allowing developers to specify success, failure, and context information for async tasks. Additionally, the new Task object offers static methods to await CompletableFuture results, wait on CountDownLatch, and sleep, simplifying the handling of common concurrency primitives within the framework.

enode/src/main/java/org/enodeframework/common/io · high confidence

Added bank account event handling for transfer transactions

A new event handler for bank accounts has been introduced to process various transfer-related events, including account creation, validation results, transaction preparations, and transfer lifecycle states (started, completed, canceled). This enables the system to react to and log key banking events such as insufficient balance exceptions and transaction confirmations.

samples/bank-transfer/event-consumer/src/main/java/org/enodeframework/samples/eventhandlers/bank · high confidence

Added bank transfer sample controller

A new REST controller at /bank exposes endpoints for executing bank transfer commands. The 'transfer' endpoint demonstrates creating accounts, depositing funds, and processing transfers (including invalid and insufficient-funds scenarios) using the CommandBus. The 'perf' endpoint provides a performance test that creates multiple accounts, deposits funds, and executes a high volume of transfer transactions to measure throughput.

samples/bank-transfer/command-web/src/main/java/org/enodeframework/samples/controller/bank · high confidence

Added command classes for note operations

New command classes, CreateNoteCommand and ChangeNoteTitleCommand, have been added to the samples domain. These classes extend AbstractCommandMessage and allow users to create notes and update note titles within the bank-transfer sample application.

samples/bank-transfer/samples-domain/src/main/java/org/enodeframework/samples/commands/note · medium confidence

Added command handlers for bank account, deposit, and transfer transactions

The sample application now includes command handlers for managing bank accounts, deposit transactions, and transfer transactions. Specifically, \BankAccountCommandHandler\ processes account creation, validation, and transaction preparation/commit commands. \DepositTransactionCommandHandle\ manages the lifecycle of deposit transactions, including starting, confirming preparation, and finalizing deposits. \TransferTransactionCommandHandlers\ handles the full flow of transfer transactions, including starting, confirming account validation, and processing out/in transfers and cancellations. These handlers implement the asynchronous command processing logic for the bank transfer sample.

samples/bank-transfer/command-consumer/src/main/java/org/enodeframework/samples/commandhandles/bank · high confidence

Added common extensions for messaging, ID generation, and classpath scanning

Added new components in the \org.enodeframework.common.extensions\ package: a \MessageMonitor\ interface and \NoOpMessageMonitor\ for tracking message processing results; a \SnowFlake\ class for generating unique IDs based on timestamp, datacenter, and machine identifiers; an \ObjectContainer\ interface for dependency injection resolution; a \SystemClock\ class that provides a high-performance, thread-safe current time retrieval; and a \ClassPathScanHandler\ for scanning classes in the classpath, which was also renamed from the \com.enode\ package to \org.enodeframework\. Additionally, a \SysProperties\ class was added to define system-level constants for message and command handling.

enode/src/main/java/org/enodeframework/common/extensions · high confidence

Added database schema scripts for EventStore implementations

New SQL scripts for MySQL and PostgreSQL define the 'event\_stream' and 'published\_version' tables, establishing the required unique indexes for idempotent event processing. A MongoDB script (mongo.js) also adds corresponding unique indexes. Additionally, a broker configuration file and a README explaining the EventStore setup have been added to the scripts directory.

scripts · medium confidence

Added default JSON serialization service

A new default serialization implementation has been introduced in the \org.enodeframework.common.serializing\ package. The \SerializeService\ interface defines methods for serializing objects to and from JSON strings and byte arrays, and the \DefaultSerializeService\ provides a concrete implementation using Jackson's \JsonMapper\. This change enables standard JSON serialization and deserialization for the framework's components.

enode/src/main/java/org/enodeframework/common/serializing · medium confidence

Added default handlers and publishers for application and exception messages

The framework now includes default implementations for publishing and handling application messages and domain exception messages. Specifically, it adds DefaultApplicationMessageHandler and DefaultApplicationMessagePublisher to process and send standard application messages, as well as DefaultPublishableExceptionMessageHandler and DefaultPublishableExceptionMessagePublisher to handle and send domain exception messages. These components enable the queuing system to serialize, route, and dispatch these specific message types asynchronously.

enode/src/main/java/org/enodeframework/queue/applicationmessage, enode/src/main/java/org/enodeframework/queue/publishableexceptions · high confidence

Added functional programming interfaces and delayed task support

The enode framework introduces a new set of functional interfaces in the \org.enodeframework.common.function\ package, including \Action\, \Action1\ through \Action4\, \Func\, \Func1\ through \Func3\, and a \DelayedTask\ utility for scheduling tasks with delays. These additions provide a consistent way to pass and execute code blocks and functions within the framework.

enode/src/main/java/org/enodeframework/common/function · high confidence

Added metrics monitoring for message processing and system capacity

New classes have been added to the metrics module to provide observability into message processing performance and system capacity. The \GlobalMetricRegistry\ now registers monitors for event processors, command buses, and message publishers, tracking metrics such as message latency, processing duration, and capacity utilization. Specific monitors include \EventProcessorLatencyMonitor\ for measuring processing delays, \CapacityMonitor\ for tracking resource utilization, \MessageTimerMonitor\ for timing message flows, and \MessageCountingMonitor\ for counting message states.

metrics · high confidence

Added process managers for bank transfer and deposit transactions

New process managers have been introduced to coordinate the flow of bank transactions. The \DepositTransactionProcessManager\ handles the lifecycle of deposit transactions, reacting to start, preparation, and completion events to trigger subsequent commands. Similarly, the \TransferTransactionProcessManager\ orchestrates transfer transactions, managing account validation, debit/credit preparation, and final confirmation steps. These components implement the event-driven logic for these specific banking operations within the event consumer.

samples/bank-transfer/event-consumer/src/main/java/org/enodeframework/samples/eventhandlers/bank/processmanagers · high confidence

Added utility classes for assertions and ID generation

The framework introduces new utility classes in the common package: an Assert class providing methods for validating non-null, non-empty, and boolean states, and an IdGenerator class that generates unique identifiers using a SnowFlake algorithm.

enode/src/main/java/org/enodeframework/common/utils · high confidence

Adds bank domain commands for transaction lifecycle management

The sample application now includes a comprehensive set of command classes for managing the bank transfer domain, including creating accounts, validating accounts, and initiating or confirming deposits and transfers. New commands such as AddTransactionPreparationCommand, CommitTransactionPreparationCommand, and various Confirm\* commands allow users to execute specific stages of the transaction workflow, supporting both deposit and transfer operations within the Enode framework.

samples/bank-transfer/samples-domain/src/main/java/org/enodeframework/samples/commands/bank · high confidence

Adds domain models for bank transfer and note features

Introduces new domain entities and events for the bank-transfer sample, including the BankAccount aggregate with transaction preparation and balance management, DepositTransaction and TransferTransaction aggregates with their respective state machines and events, and a simple Note aggregate. These files define the core domain logic for account validation, fund transfers, and note management within the application.

samples/bank-transfer/samples-domain/src/main/java/org/enodeframework/samples/domain · high confidence

Commanding subsystem migrated to Kotlin with new abstractions

The commanding module has been rewritten in Kotlin, introducing new abstractions for command execution and processing. This includes the \CommandBus\ interface for sending and executing commands asynchronously or synchronously, a \CommandContext\ for managing aggregate roots during command processing, and a \CommandProcessor\ to manage the lifecycle of command processing. Additionally, a \ProcessingCommandMailbox\ has been added to handle message ordering and concurrency for aggregate roots, ensuring that commands for the same aggregate are processed sequentially. The package structure has also been updated from \com.enode.commanding\ to \org.enodeframework.commanding\.

enode/src/main/java/org/enodeframework/commanding · high confidence

Introduce Kotlin-based eventing infrastructure with coroutine-backed mailboxes

The eventing subsystem has been rewritten in Kotlin, introducing a new set of core classes and interfaces for domain event handling. This includes the \DomainEventStream\ and \AbstractDomainEventMessage\ for representing and managing domain events, alongside result types like \EventAppendResult\ and \BatchAggregateEventAppendResult\ to track event append statuses. A significant behavioral change is the introduction of \EventCommittingContextMailBox\ and \ProcessingEventMailBox\, which utilize Kotlin coroutines to manage asynchronous event processing and message queues, replacing previous synchronous or non-coroutine-based implementations. The \EventCommittingService\ and \EventStore\ interfaces define the new contract for committing and storing events, supporting batch operations and async retrieval.

enode/src/main/java/org/enodeframework/eventing · high confidence

Introduce in-memory eventing implementations for the Enode framework

Added new in-memory implementations for event sourcing and processing within the Enode framework, including DefaultEventCommittingService, DefaultProcessingEventProcessor, and DefaultEventSerializer, alongside InMemoryEventStore and InMemoryPublishedVersionStore. These components enable lightweight, non-persistent event handling and version tracking, supporting features like domain event publishing, batch message processing, and coroutine-based mailbox handling for testing or scenarios where durable storage is not required.

enode/src/main/java/org/enodeframework/eventing/impl · high confidence

Introduces new queue message handling and sending interfaces in Kotlin

The queue module now includes new Kotlin-based interfaces and classes for message handling and sending. A new MessageContext interface allows for post-processing of messages, while the MessageHandler interface and its holder (MessageHandlerHolder) provide a mechanism to route and execute handlers for different message types. The QueueMessage class defines the structure for messages including body, topic, tag, routeKey, and type. Additionally, SendMessageService and SendReplyService interfaces are introduced to support asynchronous message sending and reply handling, with the latter specifically supporting ReplyMessage types.

enode/src/main/java/org/enodeframework/queue · medium confidence

Introduces queue-based command bus and result processing

The enode framework now supports asynchronous command execution via a message queue. A new 'queue/command' package provides a DefaultCommandBus that sends commands to a queue and waits for results using a DefaultCommandResultProcessor. This processor manages task completion sources, handles reply messages, and enforces a timeout to prevent memory leaks from uncompleted commands.

enode/src/main/java/org/enodeframework/queue/command · high confidence

Migrated RocketMQ integration to Kotlin with new message handling classes

The RocketMQ integration has been rewritten in Kotlin, replacing the previous Java implementation. This change introduces new classes for message listening (RocketMQMessageListener, RocketMQMessageOrderlyListener), production (RocketMQProducerHolder), and sending (RocketMQSendMessageService, RocketMQSendReplyService). The old Java classes (including RocketMQTool, SendRocketMQService, and various listener/publisher classes) have been removed.

rocketmq · high confidence

New annotations for command, event, priority, and subscribe markers

The enode framework now provides a set of new Java annotations in the org.enodeframework.annotation package: @Command, @Event, @Priority, and @Subscribe. These annotations allow developers to mark classes and methods for framework processing, such as identifying command handlers, event sources, execution priorities, and subscription points. This change introduces new API surface for building event-driven applications within the framework.

enode/src/main/java/org/enodeframework/annotation · high confidence

New command handlers for note creation and title updates

The sample application now includes dedicated command handlers for managing notes. Specifically, a new Java handler allows creating a new note, while a new Kotlin handler enables updating a note's title. These additions demonstrate how to implement command handling for these specific business operations within the Enode framework.

samples/bank-transfer/command-consumer/src/main/java/org/enodeframework/samples/commandhandles/note · high confidence

New exception classes for Enode framework

The Enode framework now provides a comprehensive set of new exception classes in the \org.enodeframework.common.exception\ package, including \AggregateRootAlreadyExistException\, \AggregateRootCreateException\, \AggregateRootInvalidException\, \AggregateRootNotFoundException\, \AggregateRootReferenceChangedException\, \AggregateRootTypeNotMatchException\, \AggregateRootTypeRepositoryNotFoundException\, \DomainEventInvalidException\, \DuplicateCommandRegisterException\, \DuplicateEventStreamException\, \EnodeClassNotFoundException\, \EnodeException\, \EnodeInterruptException\, \EventStoreException\, \HandlerNotFoundException\, \HandlerRegisterException\, \IdGenerateException\, \MailBoxInvalidException\, \MailBoxProcessException\, \MessageInstanceCreateException\, \MethodInvokeException\, \ProducerNotFoundException\, \PublishedVersionStoreException\, and \ReplyAddressInvalidException\. Additionally, the existing \IORuntimeException\ has been migrated from the \com.enode.common.io\ package to this new exception package and now extends the new \EnodeException\ base class.

enode/src/main/java/org/enodeframework/common/exception · high confidence

New messaging abstractions and handler proxies for asynchronous processing

The enode framework introduces a new messaging layer in the \org.enodeframework.messaging\ package, providing core abstractions for message handling. This includes base classes for application and reply messages, along with interfaces for message dispatching, publishing, and handler registration. Specifically, it adds \Message\ and \ReplyMessage\ interfaces, abstract message classes, and proxy interfaces (\MessageHandlerProxy1\, \2\, \3\) that support asynchronous handling of one, two, or three messages respectively. These components enable the framework to route and process messages asynchronously via \MessageDispatcher\ and \MessagePublisher\ interfaces, supporting a more flexible and scalable messaging architecture.

enode/src/main/java/org/enodeframework/messaging · high confidence

Spring Boot auto-configuration for Enode framework

The Spring module now provides comprehensive auto-configuration for the Enode framework, enabling zero-configuration setup for various event stores (In-Memory, MySQL, PostgreSQL, MongoDB) and message queues (Kafka, AMQP, Pulsar, Ons). The \@EnableEnode\ annotation triggers the import of \EnodeConfigurationSelector\, which wires up core components like \DefaultCommandOptions\, \DefaultEventStoreOptions\, and specific store implementations (e.g., \JDBCEventStore\, \MongoEventStore\). This allows users to enable Enode functionality in a Spring Boot application simply by adding the dependency and using the \@EnableEnode\ annotation, with behavior determined by properties like \spring.enode.mq\ and \spring.enode.eventstore\.

spring · high confidence

Removals

Removal of command and event sample implementations

The command and event sample implementations for the bank and note domains have been removed. This includes all command handlers (e.g., CreateAccountCommandHandler, StartDepositTransactionCommandHandler), event handlers (e.g., AccountCreatedEventHandler, TransferTransactionCompletedEventHandler), and process managers (e.g., AbstractDepositTransactionProcessManager) from the command-consumer and event-consumer samples. Configuration files (application.yml, log4j2.xml) and application entry points (Application.java) for these samples have also been deleted.

samples/command-consumer, samples/event-consumer · high confidence

Removal of core command processing and infrastructure components

The enode module has removed a large set of core command processing classes, including the \ENodeAutoConfiguration\, \ENodeBootstrap\, and \InMemoryConfiguration\ setup classes, as well as the entire \commanding\ package containing command interfaces, handlers, and implementations. This change eliminates the built-in command execution, message routing, and in-memory event storage capabilities from the framework.

enode/src/main/java/com · high confidence

Removed bank and note sample implementations

The \samples/command-sender\ and \samples/domain\ directories have been deleted, removing the entire bank and note sample implementations. This includes all related command classes (e.g., \CreateAccountCommand\, \StartTransferTransactionCommand\), domain models (e.g., \BankAccount\, \DepositTransaction\), event classes, and configuration files (e.g., \application.yml\, \log4j2.xml\).

samples/command-sender, samples/domain · high confidence

Behavioural changes

AMQP message handling migrated to Kotlin with async support

The AMQP module has been rewritten in Kotlin, introducing new services for sending messages and replies asynchronously. AmqpMessageListeners now handle incoming messages and batches, supporting both standard and channel-aware processing. AmqpProducer and AmqpSendMessageService provide async sending capabilities, while AmqpSendReplyService enables reply message support. The implementation leverages Spring AMQP's reactive template for non-blocking operations.

amqp · high confidence

Configure Enode framework with JDBC, Kafka, and logging for the bank-transfer consumer

The bank-transfer command-consumer sample now includes explicit configuration for the Enode framework, specifying a MySQL JDBC event store and Kafka message queue with dedicated topics for commands, events, and replies. Additionally, a Logback logging configuration is added to capture Enode framework logs at the DEBUG level, with file and console appenders configured for application and console output.

samples/bank-transfer/command-consumer/src/main/resources · high confidence

Domain layer refactored to Kotlin with new interfaces and base classes

The domain layer has been refactored, moving from Java to Kotlin and introducing new abstractions for aggregate management. This includes the new AbstractAggregateRoot base class and the AggregateRoot interface, alongside updated interfaces for repositories (AggregateRepository, Repository), storage (AggregateStorage, AggregateSnapshotter), and caching (MemoryCache). The change also migrates the package structure from com.enode to org.enodeframework.domain and renames several components, such as IAggregateRepositoryProvider becoming AggregateRepositoryProvider, to align with the new architecture.

enode/src/main/java/org/enodeframework/domain · high confidence

Introduces Kotlin-based domain implementation classes

The domain layer's implementation classes in \enode/src/main/java/org/enodeframework/domain/impl\ have been rewritten in Kotlin. This includes new implementations for aggregate repository management (\DefaultAggregateRepositoryProvider\, \DefaultAggregateRepositoryProxy\), aggregate root creation (\DefaultAggregateRootFactory\), internal event handling (\DefaultAggregateRootInternalHandlerProvider\), snapshotting (\DefaultAggregateSnapshotter\), memory caching (\DefaultMemoryCache\), repository access (\DefaultRepository\), and event sourcing storage (\EventSourcingAggregateStorage\, \SnapshotOnlyAggregateStorage\).

enode/src/main/java/org/enodeframework/domain/impl · high confidence

Kafka integration rewritten in Kotlin with new message handling architecture

The Kafka integration has been completely rewritten in Kotlin, replacing the previous Java implementation. This change introduces new classes for message listeners (KafkaMessageListeners), a producer holder (KafkaProducerHolder), and dedicated services for sending messages (KafkaSendMessageService) and replies (KafkaSendReplyService). The old Java-based consumers, publishers, and utility classes have been removed.

kafka · high confidence

Message dispatching rewritten in Kotlin with coroutine support

The message dispatching implementation in the enode framework has been rewritten in Kotlin, introducing native support for Kotlin suspend functions and reactive types (Mono/Flux/CompletionStage). The new DefaultMessageDispatcher and its supporting classes (DefaultMessageHandlerProxy1/2/3, etc.) handle message routing and handler invocation using Kotlin coroutines, allowing handlers to be defined as suspend functions or return reactive streams, improving integration with modern asynchronous programming models.

enode/src/main/java/org/enodeframework/messaging/impl · high confidence

Migrate commanding implementation to Kotlin with coroutine support

The command processing and execution components in the \enodeframework.commanding.impl\ package have been rewritten in Kotlin. This change introduces support for Kotlin coroutines, allowing command handlers to be defined as suspend functions. The \DefaultCommandHandlerProxy\ now detects and invokes suspend methods, while \DefaultCommandProcessor\ and \DefaultProcessingCommandHandler\ utilize coroutine dispatchers and async/await patterns for asynchronous command execution and mailbox management.

enode/src/main/java/org/enodeframework/commanding/impl · high confidence

Migrate domain event queue handling to Kotlin

The domain event queue implementation has been rewritten in Kotlin, introducing new classes for handling and publishing domain events. DefaultDomainEventMessageHandler now processes incoming queue messages, deserializes them into a DomainEventStream, and processes them via the event processor. DefaultDomainEventPublisher converts outgoing DomainEventStream objects into queue messages for publishing. Additionally, new message types DomainEventHandledMessage and GenericDomainEventMessage are introduced to support event handling and serialization in the queue system.

enode/src/main/java/org/enodeframework/queue/domainevent · medium confidence

Redis message handling migrated to Kotlin

The Redis integration for message handling has been rewritten in Kotlin. This introduces \RedisReplyMessageListener\ to process incoming Redis messages and route them to the appropriate message handler, and \RedisSendReplyService\ to asynchronously send reply messages via Redis. These changes replace the previous implementation, affecting how the application communicates with Redis for queue and reply messaging.

redis · high confidence

Refactor infrastructure layer to Kotlin and introduce new core interfaces

The infrastructure package has been migrated to Kotlin, introducing new core interfaces such as AssemblyInitializer, MethodInvocation, ObjectProxy, and TypeNameProvider. A new AbstractHandlerProvider base class manages handler registration and priority, while supporting Kotlin suspend methods. Additionally, utility classes like TypeUtils and ManyType are added to support type resolution and generic type handling.

enode/src/main/java/org/enodeframework/infrastructure · medium confidence

Refactored scheduling and worker components with modern Java practices

The scheduling subsystem was refactored to modernize the codebase: the \ScheduleService\ interface and \DefaultScheduleService\ implementation were moved to the \org.enodeframework\ package, replacing the legacy \com.enode\ package. The \ScheduleService\ class was renamed to \DefaultScheduleService\ and updated to use \java.util.concurrent\ types (e.g., \ScheduledFuture\<?\>\) and \slf4j\ logging. The \Worker\ class was similarly moved to the new package, updated to use \slf4j\ logging, and had its \actionName\ field and related accessor methods removed. These changes improve code consistency and logging standards within the scheduling module.

enode/src/main/java/org/enodeframework/common/scheduling · high confidence

Removed MySQL-specific database schema scripts

The MySQL-specific table generation SQL scripts have been removed from the repository. This change eliminates the hardcoded MySQL database schema definitions, aligning with the project's shift to support multiple event store backends (such as MongoDB, TiDB, and PostgreSQL) rather than being tied to a single database implementation.

enode/scripts · high confidence

Test coverage

Added comprehensive test suite for Enode framework core and message publishing; Added test configuration for event store and message queue backends.

Dependencies

Maven build system restructured with new module layout and dependency management

The project's Maven build structure has been significantly reorganized. The root artifact and parent POM have been migrated from \com.enode:enode-java:1.0.0\ to \org.enodeframework:enode-parent\ using a \${revision}\ property. A new Bill of Materials (BOM) module (\enode-dependencies-bom\) has been introduced to centralize dependency management for all sub-modules. Several existing sample modules (\command-consumer\, \event-consumer\, \command-sender\, \domain\) were removed and replaced with a new \bank-transfer\ sample. Additionally, new modules for JDBC, MySQL, PostgreSQL, MongoDB, AMQP, TCP, and Metrics have been added to the build, each with their own \pom.xml\ files defining their specific dependencies.

(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

Score

  • CAI 50 → 50 (+0.6)
  • Rubric changed (rubric-2026.08.19 → rubric-2026.09.15) — scores are not directly comparable.

Lenses

  • Code Health 97 → 98 (+0.3)
  • Architecture 100 → 97 (-3.1)
  • Maturity 57 → 57 (+0.0)
  • Readiness 22 → 26 (+4.0)
  • Security 87 → 79 (-7.6)

Resolved (32)

  • Change coupling: EnodeOnsAutoConfig.java ↔ EnodeRocketMQAutoConfig.java (spring/src/main/java/org/enodeframework/spring/EnodeOnsAutoConfig.java)
  • Change coupling: JDBCEventStore.kt ↔ JDBCPublishedVersionStore.kt (jdbc/src/main/java/org/enodeframework/jdbc/JDBCEventStore.kt)
  • Coverage not included — suite not readable by the collector
  • Dependency hygiene not measured — dependency manifest found but not parsed for hygiene
  • Duplicated block (10 lines × 2) (enode/src/main/java/org/enodeframework/commanding/impl/DefaultCommandHandlerProvider.kt)
  • Duplicated block (10 lines × 2) (enode/src/main/java/org/enodeframework/messaging/impl/DefaultThreeMessageHandlerProvider.kt)
  • Duplicated block (10 lines × 2) (jdbc/src/main/java/org/enodeframework/jdbc/JDBCHandlers.kt)
  • Duplicated block (10 lines × 3) (jdbc/src/main/java/org/enodeframework/jdbc/JDBCHandlers.kt)
  • Duplicated block (10 lines × 4) (enode/src/main/java/org/enodeframework/messaging/impl/DefaultThreeMessageHandlerProvider.kt)
  • Duplicated block (11 lines × 2) (jdbc/src/main/java/org/enodeframework/jdbc/JDBCHandlers.kt)
  • Duplicated block (12 lines × 2) (jdbc/src/main/java/org/enodeframework/jdbc/JDBCEventStore.kt)
  • Duplicated block (13 lines × 2) (enode/src/main/java/org/enodeframework/eventing/impl/DefaultEventCommittingService.kt)
  • Duplicated block (7 lines × 2) (enode/src/main/java/org/enodeframework/commanding/impl/DefaultProcessingCommandHandler.kt)
  • Duplicated block (7 lines × 2) (mongo/src/main/java/org/enodeframework/mongo/MongoEventStore.kt)
  • Duplicated block (8 lines × 2) (amqp/src/main/java/org/enodeframework/amqp/message/AmqpMessageListeners.kt)
  • Duplicated block (8 lines × 2) (enode/src/main/java/org/enodeframework/eventing/ProcessingEventMailBox.kt)
  • Duplicated block (8 lines × 2) (jdbc/src/main/java/org/enodeframework/jdbc/JDBCPublishedVersionStore.kt)
  • Duplicated block (8 lines × 2) (mongo/src/main/java/org/enodeframework/mongo/MongoEventStore.kt)
  • Duplicated block (8 lines × 2) (mongo/src/main/java/org/enodeframework/mongo/MongoHandlers.kt)
  • Duplicated block (8 lines × 2) (rocketmq/src/main/java/org/enodeframework/rocketmq/message/RocketMQMessageListener.kt)
  • …and 12 more

New (51)

  • ClassPathScanHandler.doScanPackageClassesByJar (cognitive 20) (enode/src/main/java/org/enodeframework/common/extensions/ClassPathScanHandler.java)
  • Dependency hygiene PARTLY measured — Maven/Gradle declarations read, no dependency graph resolved
  • Documentation: no installation or build instructions (README.md)
  • Documentation: written for insiders (docs/intro.md)
  • Duplicated block (10 lines × 2) (enode/src/main/java/org/enodeframework/commanding/ProcessingCommandMailbox.kt)
  • Duplicated block (10 lines × 2) (jdbc/src/main/java/org/enodeframework/jdbc/JDBCHandlers.kt)
  • Duplicated block (10–14 lines × 2) (jdbc/src/main/java/org/enodeframework/jdbc/JDBCHandlers.kt)
  • Duplicated block (12 lines × 2) (enode/src/main/java/org/enodeframework/commanding/impl/DefaultCommandHandlerProvider.kt)
  • Duplicated block (12 lines × 2) (enode/src/main/java/org/enodeframework/eventing/impl/DefaultEventCommittingService.kt)
  • Duplicated block (13 lines × 2) (mongo/src/main/java/org/enodeframework/mongo/MongoEventStore.kt)
  • Duplicated block (13 lines × 3) (jdbc/src/main/java/org/enodeframework/jdbc/JDBCHandlers.kt)
  • Duplicated block (15 lines × 2) (jdbc/src/main/java/org/enodeframework/jdbc/JDBCEventStore.kt)
  • Duplicated block (15–18 lines × 4) (enode/src/main/java/org/enodeframework/messaging/impl/DefaultThreeMessageHandlerProvider.kt)
  • Duplicated block (17 lines × 3) (jdbc/src/main/java/org/enodeframework/jdbc/JDBCEventStore.kt)
  • Duplicated block (17–18 lines × 3) (jdbc/src/main/java/org/enodeframework/jdbc/JDBCHandlers.kt)
  • Duplicated block (21 lines × 2) (enode/src/main/java/org/enodeframework/messaging/impl/DefaultThreeMessageHandlerProvider.kt)
  • Duplicated block (6 lines × 2) (enode/src/main/java/org/enodeframework/commanding/impl/DefaultProcessingCommandHandler.kt)
  • Duplicated block (6 lines × 2) (mongo/src/main/java/org/enodeframework/mongo/MongoEventStore.kt)
  • Duplicated block (7 lines × 2) (amqp/src/main/java/org/enodeframework/amqp/message/AmqpMessageListeners.kt)
  • Duplicated block (7 lines × 2) (enode/src/main/java/org/enodeframework/eventing/ProcessingEventMailBox.kt)
  • …and 31 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

itswuanran/enode 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 22 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 06bee95b1ba2335fdad0174f871b667749281d00 — 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-821afab8930d.