Skip to content
CAI
Software that uses CAICheck a score

j5ik2o/cqrs-es-example-js

58.6

Adequate · 21 September 2026

4.7k

lines of production code

TypeScript

primary language

4

measurements over time

CAI band scale
CAI trend line
CAI lens gauges

What this system is

This system is a group chat application built on a CQRS (Command/Query Responsibility Segregation) architecture, separating command-side persistence from query-side read models. It manages group chat entities and messages through a functional domain model, exposing operations via GraphQL APIs for both commands and queries. The system supports pluggable persistence backends, allowing the command side to store events in either DynamoDB or Cloud Spanner, while the read model updater processes these events to maintain denormalized views in a MySQL database.

Features

Add GraphQL API for querying group chats, members, and messages

The GraphQL interface layer now exposes queries to retrieve group chats, their members, and messages. Users can fetch a single group chat or a list of all group chats a user belongs to, view specific member details, and retrieve individual or paginated message lists, all filtered by user account and group chat ID.

packages/query/interface-adaptor/src/graphql · high confidence

Add GroupChat repository implementation with conditional snapshotting

Introduced the GroupChat repository implementation, providing persistence for GroupChat entities via DynamoDB and Spanner backends. The repository now supports conditional snapshotting: it saves snapshots based on a configurable retention criteria (defaulting to every Nth event), and explicitly handles optimistic lock conflicts as error results. This includes new test coverage for both DynamoDB and Spanner storage backends.

packages/command/interface-adaptor-impl/src/repository · high confidence

Add Okite AI reference implementation

A new submodule reference for the Okite AI project has been added to the repository, pointing to commit 69fa7cb4761b8767d29310a1115a1e511daf5fcf. This provides a concrete example or integration point for the Okite AI system within the broader codebase.

references · low confidence

Add Prisma schema for group chat and read model tracking

A new Prisma schema is introduced for the RMU package, defining database models for tracking read model processing positions and for a new group chat feature. The schema includes a \ReadModelPositions\ model to track sequence numbers, alongside \GroupChats\, \Members\, and \Messages\ models that establish the data structure for group chat functionality.

packages/rmu/prisma · high confidence

Add e2e-test tooling for group chat verification

Added a new e2e-test tooling package in the tools/e2e-test directory. This includes a Dockerfile for the test environment, a Makefile with build/run/release targets, a shell script (verify-group-chat.sh) that performs GraphQL mutations and queries to verify group chat functionality, and a version file. The script handles waiting for API readiness, creating group chats, adding members, posting messages, and verifying read models.

tools/e2e-test · high confidence

Add group chat domain model and serialization

The \packages/command/domain\ package now includes a complete domain model for group chats, introducing types for group chat IDs, names, members, and messages, along with event definitions for state changes like creation, renaming, member management, and message posting. The diff adds serialization logic (toJSON/fromJSON) for all domain entities and events, ensuring consistent data representation. Additionally, the directory is configured with ESLint, Prettier, and Biome for code quality, and Jest is set up for testing the domain logic.

packages/command/domain · high confidence

Add local development tooling and Spanner change-stream bridge

The bootstrap package now includes configuration files for the Biome linter and Jest test runner, alongside a new integration test for the Spanner change-stream reader. Additionally, a new \spanner-change-stream-bridge-main.ts\ module has been added to read from a Spanner change stream and publish domain events to a Pub/Sub topic, supporting local development of the Spanner read-model pipeline.

packages/bootstrap · high confidence

Add local development tooling for DynamoDB, database migrations, and Lambda functions

Developers can now use Docker-based tooling to manage local infrastructure and build artifacts. This includes a new \tools/dynamodb-setup\ directory with a Dockerfile and scripts to create DynamoDB tables locally, a \tools/migrate\ directory containing SQL migration files and a Dockerfile for running database schema updates, and \tools/scripts\ containing shell scripts to build the DynamoDB read-model-updater Lambda function and deploy it to LocalStack. Additionally, new curl scripts are provided to test group chat and message APIs, and a script is added to clean all node\_modules directories.

tools/scripts · high confidence

Added GraphQL API for group chat commands

The GraphQL interface for the command side of the application has been implemented. This includes input types for creating, deleting, and renaming group chats, as well as adding or removing members. It also supports posting and deleting messages within a group chat. The schema is built using type-graphql, exposing mutations for all these operations and a health check query.

packages/command/interface-adaptor-impl/src/graphql · high confidence

Added Prisma schema for group chat and message data models

Introduced a new Prisma schema file defining the database structure for the query interface adaptor. The schema configures a MySQL datasource and defines models for tracking read model processing positions, as well as entities for group chats, their members, and associated messages, establishing the data layer for these features.

packages/query/interface-adaptor/prisma · high confidence

Introduce group chat read-model projection with DynamoDB and Spanner adapters

Added a new read-model update mechanism for group chats, supporting both DynamoDB Streams and Spanner Pub/Sub backends. The change introduces a provider-neutral \ReadModelUpdater\ that decodes events from either source, applies idempotent projections to a \GroupChatDao\ (backed by Prisma/MySQL), and ensures correct timestamp handling and sequence ordering. Tests verify that both adapters produce equivalent results and that the system handles various payload encodings and edge cases.

packages/rmu/src · high confidence

Introduce group-chat command processor with new tooling and test infrastructure

Added a new group-chat command processor implementation in packages/command/processor, providing operations for creating, deleting, renaming, and managing members and messages in group chats. The change also introduces Biome configuration for code formatting and linting, a Jest configuration for running tests, and a placeholder test file for the group-chat module.

packages/command/processor · high confidence

Introduce group-chat repository interface and project configuration

The package now includes a new \GroupChatRepository\ interface that defines persistence operations for group chat aggregates, including methods for storing events and snapshots, and a \SnapshotDecider\ type for conditional snapshotting. The package also adds configuration files for TypeScript (\tsconfig.json\), Jest (\jest.config.ts\), ESLint (\.eslintrc.cjs\), Prettier (\.prettierrc.yml\, \.prettierignore\), and Biome (\biome.json\), establishing the project's build, linting, and testing infrastructure.

packages/command/interface-adaptor-if · high confidence

Behavioural changes

Exposes command interface adaptor implementations

The package now exports its internal repository and GraphQL adaptors, making the command interface adaptor implementations available for use.

packages/command/interface-adaptor-impl/src · medium confidence

Introduce monotonic ULID generation and testing infrastructure

The infrastructure package now provides a new function, generateULID, which produces monotonic unique identifiers using the ulidx library. This change ensures that generated IDs maintain a strictly increasing order, which can improve database index performance and sorting. Additionally, the package is now equipped with a Jest test configuration and a basic test suite for GroupChat, enabling developers to run automated tests against the new ID generation logic.

packages/infrastructure · high confidence

Migrate to functional domain style and pluggable persistence backends

The domain and application layers now use a functional, non-class style (plain frozen objects with namespace companions) as seen in event-store-adapter-js v3.1.0. The write API can now persist to either DynamoDB or Cloud Spanner, controlled by the PERSISTENCE\_BACKEND environment variable. Additionally, the project includes a Read Model Updater on AWS Lambda (with LocalStack support) and a Spanner read-model pipeline.

(repo-wide) · high confidence

Test coverage

Added initial test and entry point for the query interface adaptor; Added test utilities and verification tests for DynamoDB and Spanner backends.

Dependencies

Initial project setup with pnpm workspaces and TypeScript tooling

The repository is initialized as a pnpm monorepo using a workspace structure, establishing the foundational build and development environment. This includes configuring the root \package.json\ with pnpm v9.15.9 and Turbo v2.1.1, and creating individual \package.json\ files for each workspace package (bootstrap, command, query, infrastructure, rmu). The setup integrates TypeScript 5.2.2, Jest for testing, Biome for linting/formatting, and establishes dependencies on \event-store-adapter-js\ v3.1.0, \@aws-sdk/client-dynamodb\, and \@prisma/client\ v6.0.0 across the relevant packages.

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

Lenses

  • Code Health 86 → 88 (+2.9)
  • Architecture 88 → 57 (-30.8)
  • Maturity 66 → 75 (+9.2)
  • Readiness 57 → 58 (+1.0)
  • Security 59 → 54 (-4.6)

Resolved (50)

  • Coverage not included — suite not readable by the collector
  • Critical CVE: [GHSA redacted] (pnpm-lock.yaml)
  • Dependency hygiene not measured — dependency manifest found but not parsed for hygiene
  • High CVE: [GHSA redacted] (pnpm-lock.yaml)
  • High CVE: [GHSA redacted] (pnpm-lock.yaml)
  • High CVE: [GHSA redacted] (pnpm-lock.yaml)
  • High CVE: [GHSA redacted] (pnpm-lock.yaml)
  • High CVE: [GHSA redacted] (pnpm-lock.yaml)
  • High CVE: [GHSA redacted] (pnpm-lock.yaml)
  • High CVE: [GHSA redacted] (pnpm-lock.yaml)
  • High CVE: [GHSA redacted] (pnpm-lock.yaml)
  • High CVE: [GHSA redacted] (pnpm-lock.yaml)
  • High CVE: [GHSA redacted] (pnpm-lock.yaml)
  • High CVE: [GHSA redacted] (pnpm-lock.yaml)
  • High CVE: [GHSA redacted] (pnpm-lock.yaml)
  • High CVE: [GHSA redacted] (pnpm-lock.yaml)
  • High CVE: [GHSA redacted] (pnpm-lock.yaml)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • …and 30 more

New (98)

  • Critical CVE: [GHSA redacted] (pnpm-lock.yaml)
  • FileTooLong: group-chat/group-chat-events.ts (packages/command/domain/src/group-chat/group-chat-events.ts)
  • FunctionTooLong: group-chat.make (packages/command/domain/src/group-chat/group-chat.ts)
  • High CVE: [GHSA redacted] (pnpm-lock.yaml)
  • High CVE: [GHSA redacted] (pnpm-lock.yaml)
  • High CVE: [GHSA redacted] (pnpm-lock.yaml)
  • High CVE: [GHSA redacted] (pnpm-lock.yaml)
  • High CVE: [GHSA redacted] (pnpm-lock.yaml)
  • High CVE: [GHSA redacted] (pnpm-lock.yaml)
  • High CVE: [GHSA redacted] (pnpm-lock.yaml)
  • High CVE: [GHSA redacted] (pnpm-lock.yaml)
  • High CVE: [GHSA redacted] (pnpm-lock.yaml)
  • High CVE: [GHSA redacted] (pnpm-lock.yaml)
  • High CVE: [GHSA redacted] (pnpm-lock.yaml)
  • High CVE: [GHSA redacted] (pnpm-lock.yaml)
  • High CVE: [GHSA redacted] (pnpm-lock.yaml)
  • High CVE: [GHSA redacted] (pnpm-lock.yaml)
  • High CVE: [GHSA redacted] (pnpm-lock.yaml)
  • High CVE: [GHSA redacted] (pnpm-lock.yaml)
  • High CVE: [GHSA redacted] (pnpm-lock.yaml)
  • …and 78 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

j5ik2o/cqrs-es-example-js 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 d32c387b5585532e7f36aabce837aec5084dbc6b — 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-b84573e22831.