Skip to content
CAI
Software that uses CAICheck a score

pmorelli92/Orleans.Tournament

46.5

Weak · 21 September 2026

1.7k

lines of production code

C#

primary language

4

measurements over time

CAI band scale
CAI trend line
CAI lens gauges

What this system is

This system is a tournament management platform built on the Orleans distributed actor framework, designed to handle team and tournament state management. It provides RESTful APIs for creating and tracking teams and tournaments, backed by a PostgreSQL database and in-memory event streams. The architecture leverages .NET 6 and modern C\# features to manage domain logic, projections, and real-time WebSocket updates for live tournament data.

Features

Added WebSocket subscribers for Team and Tournament streams

New Orleans grain subscribers (TeamSubscriber, TournamentSubscriber) have been added to listen to InMemoryStreams for Team and Tournament namespaces, forwarding events to the WebSocket namespace. The WebSocketMessage class was also updated to use a C\# record type.

src/WebSockets · medium confidence

Behavioural changes

Identity service refactored to .NET 6 minimal APIs with direct JWT handling

The Identity API has been migrated from a legacy ASP.NET Core 2.1 setup to .NET 6 using the new minimal API pattern. This replaces the old \Startup.cs\ and \UserStore\ with a streamlined \Program.cs\ that registers \UserAuthentication\ for both user creation and login. The controller layer now uses record structs for request/response models, and JWT token generation is handled directly via \Microsoft.IdentityModel\ rather than a third-party library. The Dockerfile has also been updated to use the official .NET 6.0 Alpine images.

src/API.Identity · high confidence

Migrate projections to C\# records and modernize serialization

The projection classes (PostgresOptions, TeamProjection, TournamentProjection) have been converted from verbose C\# classes with explicit constructors and extension methods into concise C\# primary constructor records. This change removes the dependency on Newtonsoft.Json in favor of the built-in System.Text.Json serializer, resulting in more compact and immutable data models for the projection layer.

src/Projections · high confidence

Migrated API to .NET 6 minimal hosting model

The API's startup configuration has been rewritten from the traditional ASP.NET Core 2.1 \Startup\ class to the .NET 6 minimal hosting model. This change updates the runtime environment from .NET Core 2.1 to .NET 6, which alters how the application initializes services, configures the Orleans cluster client, and registers middleware. Users will experience the application running on a newer, supported .NET 6 runtime.

src/API · high confidence

Migrated Silo to .NET 6 and modernized startup configuration

The Silo application has been upgraded from .NET 2.1/2.2 to .NET 6, updating the Dockerfile to use the official \mcr.microsoft.com/dotnet\ base images. The startup process has been refactored from the traditional ASP.NET Core \IWebHostBuilder\ and \Startup\ class pattern to the new minimal hosting model using \WebApplication.CreateBuilder\. This change simplifies the entry point, replaces the explicit \Startup.cs\ configuration with inline builder calls, and updates the entry point executable name from \Snaelro.Silo.dll\ to \Tournament.Silo.dll\.

src/Silo, src/Silo.Dashboard · medium confidence

Migrated domain abstractions to C\# records and modernized Orleans grain patterns

The domain abstractions have been refactored from C\# classes to C\# records, including the introduction of new record types like ErrorHasOccurred and StreamConfig, while removing older class-based implementations such as PrefixLogger and StreamOptions. Additionally, the Orleans grain implementations (EventSourcedGrain and SubscriberGrain) have been updated to use the new record types and modernize their stream handling, reflecting a shift from the legacy Snaelro namespace to the new Tournament.Domain.Abstractions namespace.

src/Domain.Abstractions · medium confidence

Moved WebSockets client utility to utils folder

The WebSockets client utility has been relocated from the tests directory to the utils folder, reflecting its role as a reusable utility rather than a test component. The client now defaults to connecting to localhost:7003, with an option to connect to localhost:30703 for the Kind environment, and outputs received messages as raw text instead of formatted JSON.

utils · low confidence

Refactor Teams and Tournaments API to use C\# records and simplified controllers

The Teams and Tournaments API endpoints have been refactored to use C\# records for input and output models, replacing the previous class-based approach. Specifically, \Input.cs\ and \Output.cs\ files now define \record\ types (e.g., \CreateTeamModel\, \TeamResponse\) instead of separate class files. Additionally, the \TeamController\ and \TournamentController\ classes have been renamed to \Controller\ and moved to the root of their respective directories, with the \Controllers\ subdirectory removed. The controllers also now handle null/missing projections by returning \NotFound()\ directly rather than checking for null explicitly in the success path, simplifying the response logic.

src/API/Tournaments · medium confidence

Refactored domain model to use C\# records and simplified error handling

The domain layer has been refactored to replace class-based command and event definitions with C\# records, and error handling has been simplified by replacing the \BusinessErrors\ enum with a \Results\ enum and a \ResultsUtil\ helper for validation. Additionally, the \Constants\ class was updated to include new stream and namespace definitions, and obsolete files (such as \StartNextPhase\ and \NextPhaseStarted\) were removed.

src/Domain · high confidence

Removed WebSocket event subscribers for Teams and Tournaments

The \TeamSubscriber\ and \TournamentSubscriber\ classes, which previously handled WebSocket message publishing for team and tournament events, have been removed from the \src/WebSockets/Teams\ directory. This eliminates the automatic forwarding of \ITraceable\ domain events to WebSocket clients for these specific resources.

src/WebSockets/Teams · high confidence

Removed unused MVC utilities and middlewares

The following components have been removed from the \src/Utils.Mvc\ library: the \FromEnvironment\ configuration class, \ConfigurationExtensions\ for environment variable handling, \ApplicationBuilderExtensions\ for routing, \LeaveMiddleware\ and \VersionMiddleware\ for request handling, and the \ResourceResponse\ and \TraceResponse\ base classes. This eliminates unused code and simplifies the library's public API.

src/Utils.Mvc · high confidence

Updated PostgreSQL schema for Orleans 3.x and upgraded base image

The PostgreSQL initialization scripts have been updated to align with the Orleans 3.x AdoNet provider, introducing a new main query table and renaming the clustering table. The persistence script now uses 'OrleansStorage' instead of 'Storage', changes the 'payloadjson' column from 'jsonb' to 'text' type, and updates timestamp columns to 'timestamptz'. Additionally, the Dockerfile has been upgraded from PostgreSQL 11 to 14.0-alpine, and the default database name has been changed to 'orleans-tournament'.

postgres · high confidence

Updated build and deployment tooling with new Makefile and Kubernetes configuration

The project now provides a \Makefile\ to streamline local development and deployment workflows. This includes targets for building Docker images for all services (API, Silo, Dashboard, Postgres), initializing a local Kind Kubernetes cluster with the metrics server, loading images, and applying Kubernetes manifests. The \kind-cluster.yaml\ configures port mappings for the application services. Additionally, the solution file has been renamed to \Orleans.Tournament.sln\ and updated to reflect the new project structure, while \.dockerignore\ and \.gitignore\ files have been updated to better manage build artifacts and IDE files.

(repo-wide) · high confidence

Test coverage

Added unit tests for tournament fixture logic

Added a new test file, FixtureTest.cs, in the Domain.Tests project. This test verifies that the SetMatchResult method preserves the index position of matches within the tournament fixture structure.

tests · high confidence

Dependencies

Upgrade to .NET 6 and Orleans 3.6

The project has been upgraded from .NET Core 2.1/2.2 to .NET 6.0 across all components, including the API, Silo, Domain, and Projections. Additionally, the codebase has been renamed from 'Snaelro' to 'Tournament'. The Orleas framework has been upgraded from version 2.1 to 3.6, and various dependencies like Npgsql and Dapper have been updated to newer versions.

(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 45 → 46 (+1.1)
  • Rubric changed (rubric-2026.08.18 → rubric-2026.09.15) — scores are not directly comparable.

Lenses

  • Code Health 82 → 82 (-0.0)
  • Architecture 90 → 90 (+0.0)
  • Maturity 51 → 51 (+0.0)
  • Readiness 37 → 37 (+0.0)
  • Security 39 → 39 (-0.2)
  • Domain Modelling 96 (new)

Resolved (26)

  • Bounded contexts not declared
  • High IaC: KSV-0014 (kubernetes/api-deployment.yaml)
  • High IaC: KSV-0014 (kubernetes/silo-deployment.yaml)
  • Low IaC: KSV-0011 (kubernetes/api-deployment.yaml)
  • Low IaC: KSV-0011 (kubernetes/silo-deployment.yaml)
  • Low IaC: KSV-0015 (kubernetes/api-deployment.yaml)
  • Low IaC: KSV-0015 (kubernetes/silo-deployment.yaml)
  • Low IaC: KSV-0016 (kubernetes/api-deployment.yaml)
  • Low IaC: KSV-0016 (kubernetes/silo-deployment.yaml)
  • Low IaC: KSV-0018 (kubernetes/api-deployment.yaml)
  • Low IaC: KSV-0110 (kubernetes/api-deployment.yaml)
  • Medium IaC: KSV-0001 (kubernetes/api-deployment.yaml)
  • Medium IaC: KSV-0001 (kubernetes/silo-deployment.yaml)
  • Medium IaC: KSV-0117 (kubernetes/api-deployment.yaml)
  • Medium IaC: KSV-0117 (kubernetes/silo-deployment.yaml)
  • Medium: security finding (details withheld)
  • Medium: security finding (details withheld)
  • Medium: security finding (details withheld)
  • Medium: security finding (details withheld)
  • Medium: security finding (details withheld)
  • …and 6 more

New (175)

  • Documentation: no installation or build instructions (README.md)
  • Documentation: no usage examples (README.md)
  • Duplicated block (12 lines × 2) (src/WebSockets/TeamSubscriber.cs)
  • End-of-life runtime: .NET net6.0
  • High IaC: KSV-0014 (kubernetes/api-deployment.yaml)
  • High IaC: KSV-0014 (kubernetes/api-deployment.yaml)
  • High IaC: KSV-0014 (kubernetes/silo-deployment.yaml)
  • High IaC: KSV-0014 (kubernetes/silo-deployment.yaml)
  • Inconsistent grammatical structure for negative existence checks. Some methods use the present participle 'IsNot' (e.g., MatchExistsAndIsNotPlayed, TeamIsNotAdded), while others use the past participle 'DoesNot' (e.g., TournamentDoesNotExists, TeamDoesNotExists). Additionally, 'DoesNotExists' is grammatically incorrect (should be 'DoesNotExist'), whereas 'IsNot' is standard.
  • Inconsistent naming for tournament lifecycle state checks. 'TournamentExists' and 'TournamentStarted' use the present tense verb form. 'TournamentDidNotStart' uses the past tense negative, while 'TournamentDoesNotExists' uses the grammatically incorrect present tense negative. This mixes tenses and grammatical structures for similar boolean state queries.
  • Inconsistent phrasing for match state checks. 'MatchIsNotDraw' is a concise boolean check. 'MatchExistsAndIsNotPlayed' is a compound condition. While semantically different, the naming style differs significantly. More critically, 'MatchIsNotDraw' implies a specific state check, whereas 'MatchExistsAndIsNotPlayed' checks existence AND state. If 'MatchExistsAndIsNotPlayed' is intended to be a simple state check (assuming existence is guaranteed by context), the name is overly verbose compared to 'MatchIsNotDraw'.
  • Low IaC: DS-0026 (postgres/Dockerfile)
  • Low IaC: KSV-0011 (kubernetes/api-deployment.yaml)
  • Low IaC: KSV-0011 (kubernetes/api-deployment.yaml)
  • Low IaC: KSV-0011 (kubernetes/silo-deployment.yaml)
  • Low IaC: KSV-0011 (kubernetes/silo-deployment.yaml)
  • Low IaC: KSV-0015 (kubernetes/api-deployment.yaml)
  • Low IaC: KSV-0015 (kubernetes/api-deployment.yaml)
  • Low IaC: KSV-0015 (kubernetes/silo-deployment.yaml)
  • Low IaC: KSV-0015 (kubernetes/silo-deployment.yaml)
  • …and 155 more

API surface

  • Unchanged — 14 HTTP endpoints

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

Survey your own repository

pmorelli92/Orleans.Tournament 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 49257cc9207f8122bddfb9618e1ae6a35d313ec7 — 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.