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
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.