Skip to content
CAI
Software that uses CAICheck a score

mauroservienti/all-our-aggregates-are-wrong-demos

52.2

Adequate · 21 September 2026

2.2k

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 distributed e-commerce demo application built on .NET 10, featuring a WebApp frontend that orchestrates shopping cart operations across four distinct backend services: Sales, Marketing, Shipping, and Warehouse. It utilizes NServiceBus for asynchronous messaging and PostgreSQL for persistent storage, implementing patterns like the Outbox and ViewModel Composition to aggregate data from these services into a unified user interface. The architecture supports core retail functions including product browsing, inventory checking, pricing calculation, and shipping estimation, with automated lifecycle management for inactive shopping carts.

How it got here

2018 — Shopping cart feature implementation

36 changes.

This period focused on implementing the core shopping cart functionality across the Sales, Warehouse, and Shipping services, including API endpoints, data models, and NServiceBus handlers. The work established a unified PostgreSQL-backed data layer and integrated transactional messaging to support adding items, retrieving prices, and managing cart lifecycle events.

2020–2026 — Dev environment and test infrastructure

4 changes.

This period focused on establishing a robust local development environment through Dev Container support and a dedicated database initialization tool. It also introduced automatic ID population in view models and comprehensive integration tests to validate the WebApp's composition logic against simulated service responses.

Features

Add Dev Container support with .NET 10 and multi-service infrastructure

Developers can now launch the project in a standardized VS Code Dev Container environment. The setup provisions a .NET 10 runtime, connects to a RabbitMQ 3.13 management instance, and spins up six isolated PostgreSQL databases (marketing, sales, shipping, warehouse, and webapp) via dedicated environment files, providing a complete local development stack out of the box.

.devcontainer · high confidence

Add home, product details, and shopping cart controllers

New ASP.NET Core controllers have been introduced to handle core navigation and shopping flows. The HomeController exposes the root index and an error page, the ProductsController provides a route for viewing product details by ID, and the ShoppingCartController manages the cart view and supports adding items via a POST endpoint.

src/WebApp/Controllers · high confidence

Add shopping cart view pages

Users can now view their shopping cart contents and see a confirmation message after adding an item. The new Index.cshtml page displays a list of cart items including product details, quantity, price, shipping estimate, and availability, or shows a message if the cart is empty. The new Add.cshtml page provides a confirmation screen with a link to view the cart.

src/WebApp/Views/ShoppingCart · high confidence

Added SQL script to initialize core application databases

A new SQL script, Setup-Databases.sql, has been added to the scripts directory. This script automates the creation of four core databases required for the application: Sales, Warehouse, Shipping, and Marketing. Running this script against the master database will provision these empty databases, simplifying the initial environment setup for developers and deployment pipelines.

scripts · high confidence

Added database initialization tool for demo services

A new console application has been added to the solution to manually create the required database tables for the Sales, Marketing, Shipping, and Warehouse services. This tool addresses a specific issue in the demo environment where Entity Framework's \EnsureCreated\ might fail to initialize the database if NServiceBus persistence has already populated it, ensuring that the necessary schema exists before the services attempt to use it.

src/CreateRequiredDatabases · high confidence

Added default ASP.NET Core web application layout and static assets

The application now includes the standard Razor view structure and static web assets. This adds a shared layout (\_Layout.cshtml) featuring a responsive Bootstrap navigation bar with links to Home and My Cart, along with an Error view for handling request failures. Additionally, the wwwroot folder now contains the necessary CSS (site.css), JavaScript (site.js), and banner images (banner1-4.svg) required to render the default site theme and functionality.

src/WebApp/Views/Shared, src/WebApp/wwwroot · high confidence

Added handlers for shopping cart item addition and inactivity cleanup

The service now includes handlers to process adding items to a shopping cart and to clean up inactive carts. The new AddItemToCartHandler processes commands to add products to a cart, ensuring idempotency via request IDs, creating the cart if it does not exist, and publishing a ProductAddedToCart event upon success. The ShoppingCartGotInactiveHandler listens for inactivity events and removes the corresponding shopping cart record from the database.

src/Sales.Service/Handlers, src/Shipping.Service/Handlers · high confidence

Added shipping options and shopping cart item models

The Shipping.Data.Models namespace now includes ProductShippingOptions and ShoppingCartItem classes. ProductShippingOptions defines the structure for product-specific shipping configurations, including individual options with estimated delivery timeframes. ShoppingCartItem represents an item within a shopping cart, tracking product ID, quantity, and delivery estimates.

src/Shipping.Data/Models · high confidence

Added shopping cart lifecycle event interfaces

New event interfaces have been introduced to the Sales.Messages.Events library to support the shopping cart lifecycle: ProductAddedToCart (carrying CartId and ProductId), ShoppingCartGotInactive, and ShoppingCartGotStale (both carrying CartId). These interfaces define the contract for events signaling product additions and cart inactivity/staleness.

src/Sales.Messages.Events · high confidence

Automatic ID population in view models from route data

A new preview handler has been added to the ViewModel Composition layer that automatically populates the Id property on composed view models when an 'id' parameter is present in the current route data. This ensures that view models generated during request processing inherit the identifier from the URL without requiring manual assignment in the view model logic.

src/ITOps.ViewModelComposition · high confidence

Display product details on the home page

The home page now lists available products, showing each product's name as a link to its details page, its description formatted as an H4 heading, and its price in dollars.

src/WebApp/Views/Home · high confidence

Initial Shipping API service setup with ASP.NET Core hosting

The Shipping.Api project is introduced with a standard ASP.NET Core web application structure. It configures the host using generic hosting principles and sets up the web server to use the Startup class for configuration. The service enables MVC controllers, adds routing, and configures CORS to allow requests from any origin. In development environments, it also enables the developer exception page for debugging.

src/Shipping.Api · high confidence

Initial Warehouse API service setup

The Warehouse.Api project has been introduced with a standard ASP.NET Core structure, including Program.cs for host creation and Startup.cs for configuration. The service is configured to use routing, enable CORS for all origins, and map controllers via the endpoint routing middleware. Development-specific error pages are enabled when running in the development environment.

src/Warehouse.Api · high confidence

Initial Warehouse data layer with PostgreSQL support

The Warehouse.Data project now provides the foundational data access layer, introducing a new WarehouseContext that connects to a PostgreSQL database via Npgsql. This context manages StockItem and ShoppingCartItem entities, includes seed data for initial stock levels, and configures identity generation for shopping cart items.

src/Warehouse.Data · high confidence

Initial setup of marketing event models and Razor view infrastructure

This change introduces the foundational structure for the marketing view composition layer. It adds the \AvailableProductsLoaded\ event class to the \Marketing.ViewModelComposition.Events\ namespace, which carries a dictionary of available product view models. Additionally, it establishes the Razor view engine configuration for the WebApp by creating \\_ViewImports.cshtml\ (enabling the WebApp namespace and MVC tag helpers) and \\_ViewStart.cshtml\ (setting the default layout to \\_Layout\), preparing the view layer for rendering marketing content.

src/Marketing.ViewModelComposition.Events, src/WebApp/Views · high confidence

Initial shipping data model and cart messaging support

The Shipping service now includes a foundational data layer using PostgreSQL via Entity Framework Core, defining entities for product shipping options and shipping methods with initial seed data. Additionally, a new message command for adding items to a shopping cart has been introduced to support cart-related interactions within the shipping domain.

src/Shipping.Data · high confidence

Introduction of ShoppingCartItem and StockItem data models

The Warehouse data layer now includes dedicated models for shopping cart and stock management. A new ShoppingCartItem class defines the structure for individual cart entries, including product and quantity details, while a new StockItem class models inventory records linked to products via a ProductId. These changes establish the foundational data structures for tracking cart contents and warehouse stock levels.

src/Warehouse.Data/Models · high confidence

Marketing service now reacts to inactive and stale shopping carts

The Marketing.Service has been introduced to monitor shopping cart activity via NServiceBus. It now includes handlers that trigger specific console notifications when a cart becomes inactive (logged in red) or stale (logged in yellow), allowing the marketing team to identify potential lost customers or opportunities for re-engagement.

src/Marketing.Service · high confidence

New API endpoints for listing and retrieving product details

Added two new API controllers to expose product data. The AvailableProductsController provides a GET endpoint at /api/available/products to return a list of all product IDs. The ProductsDetailsController adds GET endpoints at /api/product-details/product/{id} to retrieve a single product by ID and at /api/product-details/products/{ids} to retrieve multiple products by a comma-separated list of IDs.

src/Marketing.Api/Controllers · high confidence

New API endpoints for product pricing and shopping cart retrieval

The API now exposes two new controllers to support product pricing queries and shopping cart management. The PricesController provides endpoints to fetch individual product prices by ID and bulk prices for multiple products via comma-separated IDs. The ShoppingCartController allows clients to retrieve the contents of a specific shopping cart, including aggregated item details such as product ID, total quantity, and current/last known prices.

src/Sales.Api/Controllers · high confidence

New AddItemToCart command message

A new message type, AddItemToCart, has been introduced in the Sales.Messages library to support adding items to a shopping cart. This command carries the necessary context for the operation, including the ProductId, Quantity, CartId, and a unique RequestId, enabling the system to process cart addition requests via messaging.

src/Sales.Messages · high confidence

New ViewModel Composition handlers for product details, pricing, and cart operations

This change introduces a set of new composition handlers in the Sales and Marketing areas to enrich view models with product details, prices, and cart data. The Marketing area now fetches available products and enriches them with names and descriptions via a subscriber. The Sales area adds handlers to retrieve product prices, load shopping cart items (including price change indicators), and process 'Add to Cart' requests using NServiceBus.TransactionalSession to send commands directly from the composition layer.

src/Sales.ViewModelComposition · high confidence

New inventory and shopping cart API endpoints

Added InventoryController and ShoppingCartController to expose warehouse data. The InventoryController provides endpoints to retrieve stock items by a single product ID or a comma-separated list of IDs. The ShoppingCartController adds an endpoint to fetch cart items for specified product IDs, grouping them by product and returning the associated inventory details.

src/Warehouse.Api/Controllers · high confidence

New product details page with cart and shipping info

A new product details view has been added that displays the product name, description, price, and inventory status. Users can now select a quantity and add the item directly to their shopping cart from this page. The view also explicitly shows available shipping options for the product.

src/WebApp/Views/Products · high confidence

New shipping options and shopping cart API endpoints

Added two new API controllers to expose shipping and cart data. The ProductShippingOptionsController provides endpoints to retrieve shipping options for a single product or a batch of products via the /api/shipping-options route. The ShoppingCartController adds a new endpoint at /api/shopping-cart/products/{ids} to fetch delivery estimates for specific products currently in the shopping cart.

src/Shipping.Api/Controllers · high confidence

Warehouse ViewModel Composition: Product details and cart integration

The Warehouse.ViewModelComposition module now handles product inventory lookups and shopping cart item enrichment. Product details are fetched via a new handler that calls the inventory service to populate stock status. Additionally, cart operations are integrated: adding an item to the cart sends a command to the Warehouse Service using NServiceBus TransactionalSession, and loading cart items enriches the view model with real-time inventory counts from the inventory service.

src/Warehouse.ViewModelComposition · high confidence

Warehouse service now supports shopping cart operations

The Warehouse service has added handlers to process shopping cart commands and events. It can now add items to a cart via the AddItemToCartHandler, which checks for duplicate requests and persists item details, and remove items via the ShoppingCartGotInactiveHandler, which wipes cart contents upon receiving an inactivity event.

src/Warehouse.Service/Handlers · high confidence

Behavioural changes

Automated expiration of inactive shopping carts

The system now automatically manages the lifecycle of shopping carts using a new saga. When a product is added to a cart, the system tracks the last activity time. If the cart remains inactive for 30 seconds, a 'ShoppingCartGotStale' event is published. If inactivity persists for 60 seconds, a 'ShoppingCartGotInactive' event is published and the cart is marked as complete, ensuring stale data is cleaned up automatically.

src/Sales.Service/Policies · high confidence

Centralized NServiceBus configuration with PostgreSQL persistence and transactional sessions

A new shared configuration class, CommonEndpointSettings, standardizes endpoint setup by applying common behaviors such as message auditing, error handling, Newtonsoft JSON serialization, and heartbeat/metrics reporting to ServiceControl. It configures the transport for receive-only transactions to support the outbox pattern and introduces PostgreSQL as the persistence layer using Npgsql, including specific JSONB parameter handling. Additionally, it enables NServiceBus Transactional Sessions and the Outbox for reliable message sending.

src/NServiceBus.Shared · high confidence

Introduce PostgreSQL-backed data layer with seed data

The Marketing.Data module now uses Entity Framework Core with the Npgsql provider to connect to a PostgreSQL database (localhost:6432) instead of the previous database engine. The new MarketingContext class configures this connection and seeds the ProductsDetails table with two initial records (Banana Holder and Nokia Lumia 635) via OnModelCreating. A new ProductDetails model class defines the entity structure with Id, Name, and Description properties.

src/Marketing.Data · high confidence

Introduce PostgreSQL-backed data models for product pricing and shopping carts

The application now uses PostgreSQL as its database backend, configured via a hardcoded connection string in the SalesContext. New entity models have been added to support product pricing (ProductPrice) and shopping cart functionality (ShoppingCart and ShoppingCartItem), including a one-to-many relationship between carts and their items with cascade deletion. Initial seed data for product prices is also included in the context configuration.

src/Sales.Data · high confidence

Migrate Sales.Api to generic host and modern ASP.NET Core startup

The Sales.Api project has been updated to use the generic host model (IHostBuilder) instead of the legacy WebHost builder, aligning its startup behavior with other services in the solution. This change involves replacing the previous Program.cs and Startup.cs implementations with standard ASP.NET Core templates that configure logging, routing, CORS (allowing all origins), and controller endpoints, ensuring consistent hosting infrastructure across the application.

src/Sales.Api · high confidence

Sales Service initializes with PostgreSQL persistence and saga state auditing

The Sales Service now starts as an NServiceBus endpoint configured to use PostgreSQL (host localhost, port 7432) for persistence and automatically audits saga state changes to the Particular.ServiceControl queue. The service console title is set to the service name for easier identification.

src/Sales.Service · high confidence

Shipping service integrates with cart via ViewModel Composition

The Shipping service now participates in the e-commerce flow by using ServiceComposer.AspNetCore to react to cart events and serve product details. When items are added to the cart, a subscriber uses NServiceBus.TransactionalSession to send an AddItemToCart command to the Shipping Service in a transactional manner. When cart items are loaded, another subscriber fetches shipping estimates from the internal API and updates the cart view model with delivery estimates. Additionally, a new handler exposes a product details endpoint that retrieves and composes shipping options for a specific product.

src/Shipping.ViewModelComposition · high confidence

Shipping service now uses PostgreSQL persistence with custom health checks and recoverability settings

The Shipping service has been updated to use PostgreSQL as its persistence backend, replacing the previous SQL client configuration. This change includes the addition of a custom health check (MyCustomCheck) that verifies the existence of a specific integration directory, and the configuration of recoverability settings with immediate and delayed retry policies. The service now reports custom checks to ServiceControl and uses a connection string for PostgreSQL.

src/Shipping.Service · high confidence

Transactional HTTP sessions and automatic cart identification

The WebApp now ensures that every POST request is wrapped in a database transaction via a new TransactionalSessionMiddleware, automatically committing or rolling back changes based on request success. Additionally, a ShoppingCartMiddleware guarantees that every user session has a persistent cart identifier by setting a 'cart-id' cookie if one is missing. These changes are supported by new JSON utilities for handling camelCase-to-PascalCase conversion and a shift to libman for client-side library management.

src/WebApp · high confidence

Warehouse Service initializes with PostgreSQL-backed NServiceBus

The Warehouse Service now starts as an NServiceBus endpoint configured to use PostgreSQL for persistence, connecting to a local instance on port 9432 with the specified database credentials. This establishes the foundational messaging infrastructure for the service.

src/Warehouse.Service · high confidence

Test coverage

Added integration tests for WebApp composition endpoints; Solution renamed and end-to-end integration tests added.

Dependencies

Upgrade to .NET 10 and update core dependencies

The application projects have been migrated to target .NET 10.0. This update includes upgrading NServiceBus to version 10.2.9, ServiceComposer.AspNetCore to 5.2.2, and Npgsql.EntityFrameworkCore.PostgreSQL to 10.0.3. Additionally, the test infrastructure has been updated to use xunit 2.9.3, xunit.runner.visualstudio 4.0.0, and coverlet.collector 10.0.1.

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

Lenses

  • Code Health 61 → 61 (-0.1)
  • Architecture 86 → 86 (+0.0)
  • Maturity 52 → 52 (+0.0)
  • Readiness 46 → 47 (+1.1)
  • Security 44 → 57 (+13.3)
  • Accessibility 59 → 59 (+0.0)

Resolved (19)

  • Ambiguous pluralization: 'ShoppingCart' is used for the aggregate root, while 'ShoppingCartItem' is used for the line item. However, in other parts of the codebase (e.g., Sales.Data.SalesContext.ShoppingCarts), the plural form 'ShoppingCarts' is used for a collection of carts, while Sales.Data.Models.ShoppingCartItem is a single item. The inconsistency lies in the naming of the line item: ShoppingCartItem vs potentially CartLine or CartItem elsewhere. More critically, Sales.Data.Models.ShoppingCart is the entity, but Sales.Data.SalesContext.ShoppingCarts suggests a DbSet. The main inconsistency is between ShoppingCart (the container) and ShoppingCartItem (the content). While distinct, the term 'ShoppingCart' is used for both the aggregate and the collection property ShoppingCarts, which can be confusing. A more significant inconsistency is the use of ShoppingCartItem in Sales.Data.Models but Shipping.Data.Models.ShoppingCartItem in other namespaces, implying a potential duplication or mismatch in model definitions across bounded contexts.
  • Bounded contexts not declared
  • Build did not complete in the analyzer
  • Command duplication: 'AddItemToCart' is defined in multiple namespaces (Sales, Shipping, Warehouse, Marketing). While each may have different payloads, the command name is identical. This can cause confusion when debugging or tracing messages across services.
  • Coverage not measured — analyzer environment
  • Duplicated block (10 lines × 2) (src/Warehouse.Api/Controllers/ShoppingCartController.cs)
  • Duplicated block (11 lines × 2) (src/Warehouse.Service/Handlers/ShoppingCartGotInactiveHandler.cs)
  • Duplicated block (12 lines × 2) (src/Warehouse.ViewModelComposition/ShoppingCartItemsLoadedSubscriber.cs)
  • 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)
  • Inconsistent event naming for state changes: 'ShoppingCartGotInactive' and 'ShoppingCartGotStale' use different verbs ('Inactive' vs 'Stale') to describe potentially similar or related lifecycle states. This makes it unclear if these are distinct states or if one should be renamed to match the other's pattern (e.g., 'ShoppingCartExpired' or 'ShoppingCartTimedOut').
  • Inconsistent naming for policy/timeout concepts: 'ShoppingCartLifecyclePolicy' is a saga/policy, while 'CartGettingStaleTimeout' is a timeout state or configuration. The naming convention differs: one uses 'Policy' and the other uses 'Timeout' or 'State'.
  • No exposed public API
  • XML-doc coverage: CreateRequiredDatabases (src/CreateRequiredDatabases/CreateRequiredDatabases.csproj)
  • dormant codebase — no living knowledge left to concentrate

New (24)

  • Documentation: no installation or build instructions (README.md)
  • Documentation: no licence statement (README.md)
  • Documentation: no usage examples (README.md)
  • Duplicated block (11 lines × 4) (src/Marketing.Api/Program.cs)
  • Duplicated block (12 lines × 2) (src/Shipping.Api/Controllers/ShoppingCartController.cs)
  • Duplicated block (12 lines × 2) (src/Shipping.Service/Handlers/ShoppingCartGotInactiveHandler.cs)
  • Duplicated block (12 lines × 2) (src/Shipping.ViewModelComposition/ShoppingCartItemsLoadedSubscriber.cs)
  • Duplicated block (17 lines × 4) (src/Marketing.Api/Startup.cs)
  • 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)
  • Low IaC: WD-COMPOSE-0002 (.devcontainer/docker-compose.yml)
  • Low IaC: WD-COMPOSE-0002 (.devcontainer/docker-compose.yml)
  • Low IaC: WD-COMPOSE-0002 (.devcontainer/docker-compose.yml)
  • Low IaC: WD-COMPOSE-0002 (.devcontainer/docker-compose.yml)
  • Low IaC: WD-COMPOSE-0002 (.devcontainer/docker-compose.yml)
  • …and 4 more

Changes since last survey

  • 19 commits — 19 feature/other, 0 fixes

By area

  • src/EndToEndTests — 8 commits
  • .github/workflows — 6 commits
  • src/ITOps.Middlewares — 3 commits
  • src/ITOps.ViewModelComposition — 1 commit
  • src/NServiceBus.Shared — 1 commit

Notable commits

  • change: Update dependency Microsoft.NET.Test.Sdk to 18.10.0 (#669)
  • change: Update dependency Microsoft.NET.Test.Sdk to 18.10.1 (#672)
  • change: Update dependency Microsoft.NET.Test.Sdk to 18.9.0 (#657)
  • change: Update dependency NServiceBus to 10.2.8 (#654)
  • change: Update dependency NServiceBus to 10.2.9 (#664)
  • change: Update dependency NServiceBus.Persistence.Sql to 9.0.4 (#660)
  • change: Update dependency NServiceBus.Persistence.Sql.TransactionalSession to 9.0.4 (#661)
  • change: Update dependency ServiceComposer.AspNetCore to 5.2.2 (#665)
  • change: Update dependency Testcontainers.PostgreSql to 4.14.0 (#658)
  • change: Update dependency Testcontainers.PostgreSql to 4.15.0 (#667)
  • change: Update dependency xunit.runner.visualstudio to v4 (#659)
  • change: Update dotnet monorepo (#656)
  • change: Update dotnet monorepo (#668)
  • change: Update renovatebot/github-action action to v46.2.2 (#655)
  • change: Update renovatebot/github-action action to v46.2.4 (#662)
  • change: Update renovatebot/github-action action to v46.2.5 (#663)
  • change: Update renovatebot/github-action action to v46.2.6 (#666)
  • change: Update renovatebot/github-action action to v46.3.0 (#670)
  • change: Update renovatebot/github-action action to v46.3.1 (#671)

API surface

  • Unchanged — 11 HTTP endpoints

Architecture

  • Unchanged — 12 containers · 0 contexts · 0 edges

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

Survey your own repository

mauroservienti/all-our-aggregates-are-wrong-demos 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 9d951a0417abbca5632951c21aa16adcb73947ee — 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.