Skip to content
CAI
Software that uses CAICheck a score

richardchanjr90-cpu/ddd-by-example

57.2

Adequate · 21 September 2026

17.6k

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 loyalty program management platform built on Azure Functions, designed to handle the full lifecycle of venues, products, orders, and user interactions. It implements a CQRS architecture using MediatR to process commands for creating, updating, and archiving entities like loyalty programs, product groups, and orders. The system manages complex domain events to trigger notifications for order status changes, user interactions, and worker invites, while also handling purchase redemption and user profile management.

How it got here

2025 — Loyalty program domain implementation

46 changes.

This period focused on building the core domain and infrastructure for a new loyalty program feature, introducing entities, commands, and queries for managing venues, products, and purchases. The work established the application layer with MediatR handlers, AutoMapper mappings, and database access patterns, while also setting up the Azure Functions infrastructure and test coverage for the new services.

2026 — Loyalty domain implementation

42 changes.

This period focused on implementing the core loyalty domain, introducing comprehensive CRUD operations, queries, and commands for entities such as orders, products, venues, and user profiles. The work established the internal event-driven architecture by adding domain events, outbox-based persistence, and notification handlers to ensure reliable state management and integration.

Features

Add write API endpoints for venue, product, and order management

New HTTP functions have been added to the Write service to handle administrative and operational write operations. This includes venue approval and rejection, creating and managing loyalty programs and product groups, managing products and their images, handling order status updates and ratings, processing purchases, and managing worker invites. These endpoints expose the backend services for creating, updating, archiving, and deleting resources across the loyalty program system.

src/LoyaltyProgram/Http/Write · high confidence

Added Firebase query handlers for client info, current user, and email verification

Implemented three new query handlers in the Firebase infrastructure layer: GetClientInfoFirebaseQueryHandler, GetCurrentUserQueryHandler, and GetVerificationLinkQueryHandler. These handlers enable retrieving client information and current user details from Firebase, as well as generating email verification links for users.

src/Loyalty.Infrastructure.Firebase.Handlers/Queries · high confidence

Added Firebase token and email update handlers

New command handlers were added to manage Firebase authentication state. The SetupFirebaseTokenCommandHandler now processes user claims and roles to set custom Firebase user claims, while the UpdateUserEmailCommandHandler allows users to update their email address in Firebase, including handling verification status.

src/Loyalty.Infrastructure.Firebase.Handlers/Commands · high confidence

Added GetUserInfoByCodeQuery for retrieving user information by code

A new query class, GetUserInfoByCodeQuery, has been introduced in the Loyalty domain handlers. This class implements the MediatR IRequest interface to request user information associated with a specific code, establishing the structure for this new lookup capability.

src/Loyalty.Domain.Handlers.Queries/Queries/Code · high confidence

Added GetUserInfoByCodeQueryResult for code-based user lookups

A new query result class, GetUserInfoByCodeQueryResult, has been introduced in the Loyalty.Domain.Handlers.Queries.QueryResults.Code namespace. This class defines the structure for user information retrieved via a code, specifically exposing a UserId property for downstream processing.

src/Loyalty.Domain.Handlers.Queries/QueryResults/Code · high confidence

Added HTTP read endpoints for the Loyalty Program

Introduced a comprehensive set of new HTTP read functions across the Loyalty Program module, exposing RESTful endpoints for retrieving venues, products, product groups, loyalty programs, orders, purchases, and user profiles. These endpoints facilitate read-only access to core business entities, enabling clients to fetch detailed information about the loyalty ecosystem.

src/LoyaltyProgram/Http/Read · high confidence

Added SelfWarmer timer function to pre-warm database contexts

A new Azure Functions timer job named 'SelfWarmer' has been added to the LoyaltyProgram.Timer module. Executed every five minutes, this function initializes the LoyaltyDbContext and IntegrationEventsContext to warm up the database models, ensuring faster subsequent access.

src/LoyaltyProgram/Timer · high confidence

Added Service Bus function to process client events and order notifications

A new Azure Functions class, ClientEventsFunction, was added to the LoyaltyProgram.ServiceBus project. This function listens to Service Bus topics for code generation, new order, and order update notifications. It processes these events by updating user codes in the database and handling order creation and status updates, subsequently pushing new or declined order notifications to Azure Queues for downstream processing.

src/LoyaltyProgram/ServiceBus · high confidence

Added UserProfile query result model

A new C\# class, GetUserProfileByIdQueryResult, was added to the domain handlers. This model defines the structure for user profile data, including name, last name, phone, city, and photo URI, with corresponding JSON property names for serialization.

src/Loyalty.Domain.Handlers.Queries/QueryResults/UserProfile · high confidence

Added client notification types and Azure publish profiles for the Loyalty Program

The Loyalty.Client.Notifications library now includes a new IClientStatisticsNotification interface and an InteractionNotification class that carries user interaction data (userId, interactionType, timestamp, and venueId) for integration events. Additionally, new Azure Web App publish profiles (Web Deploy and Zip Deploy) have been added for the LoyaltyProgram service, configuring deployment to the 'loyaltyprogram-dev' Azure site.

common/Loyalty.Client.Notifications, src/LoyaltyProgram/Properties · high confidence

Added command definitions for creating and updating loyalty rules

New command classes have been introduced in the domain handlers to support creating and updating loyalty rules. Specifically, the system now includes CreateRuleCommand and CreateSingleRuleCommand to handle the creation of single or multiple rules, and UpdateRuleCommand and UpdateSingleRuleCommand to handle updates. These commands define the structure for rule data, including rule type, version, and the rule object itself, enabling the backend to process these specific operations.

src/Loyalty.Domain.Handlers.Queries/Commands/Rules · high confidence

Added command definitions for loyalty program lifecycle

Introduced new MediatR command classes to support creating, updating, and archiving loyalty programs. The diff adds \CreateLoyaltyProgramCommand\ (accepting name, description, dates, venue, and external URI), \UpdateLoyaltyProgramCommand\ (for modifying existing programs with similar fields plus a publish status), and \ArchiveLoyaltyProgramCommand\ (identifying the program by ID and user). These commands enable the backend to process loyalty program creation, modification, and archival requests.

src/Loyalty.Domain.Handlers.Queries/Commands/LoyaltyPrograms · high confidence

Added command definitions for managing loyalty product groups

New command classes (ArchiveLoyaltyProductGroupCommand, CreateLoyaltyProductGroupCommand, UpdateLoyaltyProductGroupCommand) were added to the LoyaltyProductGroup namespace. These commands define the input structures for archiving, creating, and updating loyalty product groups, each inheriting from MediatR's IRequest interface and containing relevant properties such as user ID, loyalty program ID, name, description, and rule configurations.

src/Loyalty.Domain.Handlers.Queries/Commands/LoyaltyProductGroup · high confidence

Added command handlers for managing loyalty programs, product groups, products, orders, purchases, user profiles, and venues

Implemented command handlers for creating, updating, archiving, and patching loyalty programs, product groups, products, orders, purchases, user profiles, and venues. These handlers process commands to create new entities (e.g., CreateLoyaltyProgramCommandHandler, CreateProductGroupCommandHandler), update existing ones (e.g., UpdateLoyaltyProgramCommandHandler, PatchProductCommandHandler), archive or reject them (e.g., ArchiveLoyaltyProgramCommandHandler, RejectVenueCommandHandler), and perform specific actions like burning or creating purchases (e.g., BurnPurchaseCommandHandler, CreateAndBurnPurchaseCommandHandler). The changes also include handlers for managing venue details, images, and order acceptance status.

src/Loyalty.Infrastructure.Handlers.Commands/Commands · high confidence

Added command models for creating and updating venue invites

Introduced new command classes, CreateInviteCommand and UpdateInviteCommand, within the Invites directory. These define the data structures for creating and updating venue invites, including fields for venue ID, user role, phone number, name, and position name.

src/Loyalty.Domain.Handlers.Queries/Commands/Workers/Invites · high confidence

Added core domain model base classes and interfaces

The codebase now includes foundational domain-driven design primitives in the \Loyalty.Core.Entities.SeedWork\ namespace. This includes an \Entity\ base class managing domain events and identity-based equality, an \Enumeration\ abstract class for strongly-typed enums with lookup capabilities, a \ValueObject\ base class for value-type equality semantics, and interfaces for \IAggregateRoot\, \IRepository\, and \IUnitOfWork\ to support repository and unit-of-work patterns.

src/Loyalty.Core.Entities/SeedWork · high confidence

Added data access infrastructure components

The Loyalty.Infrastructure.DataAccess module now includes three new classes: a factory for creating the EF Core DbContext for design-time operations, an extension method to dispatch domain events via MediatR, and a provider to extract tenant identifiers from the current HTTP context.

src/Loyalty.Infrastructure.DataAccess · high confidence

Added database context and migrations for integration event logging

Introduced the \IntegrationEventsContext\ and its corresponding interface \IIntegrationEventsContext\ to manage the persistence of integration events. This includes the entity configuration for \IntegrationEventLogEntry\, a database migration script to create the \IntegrationEvents\ table in the \events\ schema, and a design-time context factory to support database migrations.

src/Loyalty.Infrastructure.Events.DataAccess · high confidence

Added domain event handlers for loyalty programs, orders, and purchases

New domain event handlers have been introduced to process events for loyalty programs (creation, update, and archival), orders (status changes and user ratings), and purchases (creation and redemption). Each handler listens for specific domain events and persists corresponding notifications to the event bus, ensuring that downstream systems are notified of these key business actions.

src/Loyalty.Application.DomainEvents.Handlers/LoyaltyPrograms, src/Loyalty.Application.DomainEvents.Handlers/Orders, src/Loyalty.Application.DomainEvents.Handlers/Purchases · high confidence

Added domain event handlers for worker lifecycle and profile updates

New domain event handlers were added to the application layer to process worker-related events, including creation, archiving, patching, and updates. These handlers persist notifications such as UpdatedWorkerNotification, SetupFirebaseTokenNotification, ArchiveWorkerNotification, PatchWorkerNotification, and UpdateWorkerProfileNotification to the event bus. In the infrastructure layer, corresponding notification handlers were introduced to update Firebase user claims with worker details (name, surname, city, roles) and manage token setup, ensuring that Firebase authentication claims are synchronized with the worker's profile and venue roles.

src/Loyalty.Application.DomainEvents.Handlers/Workers, src/Loyalty.Infrastructure.Firebase.Handlers/Notifications · high confidence

Added domain events for all core entities

A comprehensive set of domain events has been added to the \Loyalty.Core.Entities\ module, covering lifecycle and state changes for Loyalty Programs, Product Groups, Products, Orders, Purchases, Venues, and Workers. Each entity now exposes specific events (such as \LoyaltyProgramCreatedDomainEvent\, \ProductArchivedDomainEvent\, and \VenueApprovedDomainEvent\) to support internal event-driven workflows.

src/Loyalty.Core.Entities/Events · high confidence

A new Azure Function, SendEmailConfirmationLinkFunction, has been introduced to process email invitations. This function listens to a queue for invitation data and uses SendGrid to send confirmation emails with verification links, supporting dynamic template data for the link.

src/LoyaltyProgram/SendGrid · high confidence

Added exception handling and transactional notification decorators

Introduced a new HandlerWrapper class in the IoC infrastructure layer that standardizes HTTP error responses by catching AuthenticationException to return 401 Unauthorized, and other exceptions to return 400 Bad Request with error details. Additionally, added a TransactionalNotificationDecorator for MediatR notifications, which wraps notification handling to ensure transactional behavior (though the current implementation appears to be a placeholder or minimal wrapper).

src/Loyalty.Infrastructure.IoC · high confidence

Added integration event notifications for domain entities

Added a comprehensive set of MediatR notification classes to the \Loyalty.Domain.Handlers.Notifications\ module, establishing the messaging contracts for domain events. This includes base interfaces (\IIntegrationEventsNotification\, \IUserEventsNotification\, \IVenueIntegrationEventsNotification\) and specific event payloads for Loyalty Programs, Product Groups, Products, Orders, Purchases, Ratings, Venues, Visits, and Workers. These notifications carry the necessary data (such as IDs, status changes, and metadata) to trigger downstream processing or user notifications.

common/Loyalty.Domain.Handlers.Notifications · high confidence

Added new DTOs for order lifecycle events

Three new data transfer objects have been introduced to represent order state changes: NewOrderDto for creating orders, OrderChangedDto for tracking status updates, and OrderDeclinedDto for declined orders. These DTOs expose specific fields such as venue ID, user ID, order status, and reason for decline, enabling the application to handle these distinct order events.

src/Loyalty.Application.Storage.Dto/Orders · high confidence

Added new Firebase command models for user management

Three new command models have been introduced to support user-related Firebase operations: AddUserToVenueFirebaseCommand for associating users with venues, SetupFirebaseTokenCommand for configuring user tokens and profile details, and UpdateUserEmailCommand for modifying user email addresses.

src/Loyalty.Domain.Handlers.Firebase.Queries/Commands · medium confidence

Added new query classes for retrieving orders by venue, user, and ID

Three new MediatR query classes have been introduced in the Orders module: GetAllOrdersByVenueIdQuery, GetOrderByIdQuery, and GetOrdersByUserIdQuery. These additions provide the application with the ability to fetch order data filtered by venue ID, specific order ID, and user ID respectively, expanding the available data retrieval capabilities for the loyalty domain.

src/Loyalty.Domain.Handlers.Queries/Queries/Orders · high confidence

Added new query result models for active purchases

New result classes have been introduced to support querying active purchases. The changes add GetActivePurchaseResult, which includes loyalty program details and a list of group purchases; GetActivePurchasesResult, which wraps a list of these results; GroupPurchaseResult, which captures group-level purchase data including rules and associated products; and ProductPurchaseResult, which details individual product information such as name, icon, image URL, and price. These models enable the system to return structured data about active purchases and their associated products and groups.

src/Loyalty.Domain.Handlers.Queries/QueryResults/Purchase · high confidence

Added notification functions for order lifecycle and invite SMS

Added new Azure Functions to handle push notifications for order status changes (new, changed, declined) and purchase confirmations, as well as an SMS notification for worker invites. These functions listen to specific message queues and send targeted notifications to Android and Apple devices or via SMS, improving user awareness of order updates and invite status.

src/LoyaltyProgram/Storage · high confidence

Added order patching commands for status and rating updates

New command classes, PatchOrderCommand and PatchRateOrderCommand, have been introduced in the Orders directory. PatchOrderCommand enables updating an order's status and adding a venue comment, while PatchRateOrderCommand allows updating an order's venue rating and associated comment. These commands facilitate the modification of existing orders through the MediatR pipeline.

src/Loyalty.Domain.Handlers.Queries/Commands/Orders · high confidence

Added order query result models for user and venue lookups

Introduced new C\# classes to represent order data for queries by user ID and venue ID. The changes add GetOrderByUserIdQueryResult, GetOrderByVenueIdQueryResult, and GetOrderItemByVenueIdQueryResult, which define the structure for order details including items, status, dates, and comments. These models support retrieving order lists via GetOrdersByUserIdQueryResult and GetOrdersByVenueIdQueryResult, enabling the system to return structured order information for both individual users and specific venues.

src/Loyalty.Domain.Handlers.Queries/QueryResults/Orders · high confidence

Added outbox-based event persistence and publishing service

Introduced a new outbox implementation in the Loyalty.Infrastructure.Outbox module, featuring an EventBusPublishingService that retrieves unprocessed integration events from a persistent store, publishes them via MediatR, and updates their status (published or failed) in the database. The change also includes the underlying PersistentIntegrationEventService for database operations and a LoggingIntegrationEventService that adds logging around event saving and retrieval.

src/Loyalty.Infrastructure.Outbox · high confidence

Added product domain event handlers to propagate product lifecycle changes

New domain event handlers have been added for product lifecycle events, including creation, updates, image changes, availability changes, and archiving. Each handler listens for its respective domain event and persists corresponding notifications (e.g., CreateProductNotification, UpdateProductNotification, PatchProductNotification, ArchiveProductNotification) to the event bus, ensuring downstream systems are notified of product state changes.

src/Loyalty.Application.DomainEvents.Handlers/Product · high confidence

Added product group command models

New command classes for managing product groups have been introduced, enabling users to create, update, patch, and archive product groups. Specifically, the system now supports creating a product group with a name, icon, and associated products; updating an existing group's details and products; patching availability status; and archiving a group.

src/Loyalty.Domain.Handlers.Queries/Commands/ProductGroups · high confidence

Added product group query result models and validation exception

Introduced a new exception type, LoyaltyValidationException, which carries a list of error codes alongside the standard exception message. Additionally, added query result models for product groups: GetProductGroupByIdQueryResult, which includes fields for id, venueId, name, icon, availability status, and a list of products; and corresponding wrapper results for retrieving product groups by user or generally.

src/Loyalty.Common.Shared/Exceptions, src/Loyalty.Domain.Handlers.Queries/QueryResults/ProductGroup · high confidence

Added purchase command models for the loyalty domain

Three new command classes were added to the purchase handling layer: BurnPurchaseCommand, CreateAndBurnCommand, and CreatePurchaseCommand. These define the data structures used to process purchase-related actions, including fields for loyalty product groups, user and worker identifiers, venue, and monetary values.

src/Loyalty.Domain.Handlers.Queries/Commands/Purchase · medium confidence

New MediatR query classes and their corresponding result models have been introduced in the Firebase domain handlers. Specifically, the system now supports fetching detailed client information (including name, city, phone, and photo), retrieving the current user's profile and email verification status, and generating an email verification link. These additions enable the application to query and display user profile data and email verification states directly from Firebase.

src/Loyalty.Domain.Handlers.Firebase.Queries/Queries · high confidence

Added query and command definitions for location, product, and purchase domains

This change introduces a new set of MediatR command and query classes to support location, product, and purchase domain operations. Specifically, it adds \CreateLocationCommand\ and \UpdateLocationCommand\ for managing location data, alongside several new queries for retrieving loyalty programs, product groups, and active purchases. These additions establish the request structures needed for the application's internal handlers to process these specific domain events and data retrieval requests.

(repo-wide) · high confidence

Added query for retrieving user profile by ID

A new query class, GetUserProfileByIdQuery, has been introduced to the UserProfile query namespace. This change adds the capability to fetch a user's profile data using a specific user identifier, supporting the existing MediatR-based request/response pattern.

src/Loyalty.Domain.Handlers.Queries/Queries/UserProfile · high confidence

Added query handlers for loyalty system data access

The system now includes a suite of new query handlers in the infrastructure layer that retrieve data from the database using Dapper. These include handlers for fetching user codes, loyalty programs, product groups, products, orders, and venue details, as well as a base handler for database access. Additionally, new entity classes and an event bus service interface were added to support the outbox pattern for integration events.

src/Loyalty.Infrastructure.Handlers · high confidence

Added query result models and build configuration files

The codebase now includes new query result models for retrieving loyalty product groups and rules, specifically GetLoyaltyProductGroupByIdQueryResult, GetLoyaltyProductGroupsQueryResult, GetRuleByIdQueryResult, and GetSingleRuleByIdQueryResult. Additionally, the project has been equipped with a new solution file (LoyaltyProgram.sln) and configuration files for NuGet package management (nuget.config) and code style enforcement (StyleCop.ruleset, stylecop.json).

src · high confidence

Added query result models for loyalty program data

Three new C\# classes have been introduced to structure loyalty program data for queries: GetLoyaltyProgramByIdQueryResult, which exposes program details like name, description, and publication status; and the collection wrappers GetLoyaltyProgramsQueryResult and GetLoyaltyProgramsByUserIdQueryResult, which return lists of these program objects. These models enable the application to retrieve and display loyalty program information to users.

src/Loyalty.Domain.Handlers.Queries/QueryResults/LoyaltyProgram · high confidence

Added repository implementations for core domain entities

The Loyalty.Infrastructure.Commands.Repository project now includes new repository classes for managing Loyalty Programs, Orders, Product Groups, Products, Purchases, Venues, and Workers. Each repository implements its corresponding interface and provides data access methods (such as GetAsync, AddAsync, and Update) backed by Entity Framework Core, enabling the application to persist and retrieve these domain aggregates.

src/Loyalty.Infrastructure.Commands.Repository · high confidence

Added shared contract enums for orders, venues, and user claims

The common contracts library now includes a new set of enumerations that define the structure for order processing, venue management, and user identity. Specifically, the change introduces \CustomClaimsConstants\ for user profile data, and a suite of enums including \LoyaltyRuleType\, \OrderPaymentType\, \OrderPickupType\, \OrderStatus\, \OrderVenueRate\, \ProductGroupIconType\, \ProductIconType\, \UserInteractionType\, \VenueApprovalStatus\, \VenueCategoryType\, \VenueType\, and \VenueUserRole\. These definitions provide the shared data types required for order and venue operations across the system.

common/Loyalty.Shared.Contracts · medium confidence

Added venue and order status domain models

Introduced new entity classes for the loyalty system: \LoyaltyGroupRule\ for managing loyalty program rules, a set of \OrderStatus\ classes (e.g., \PlacedOrder\, \ReadyOrder\, \FinishedOrder\) to define order lifecycle states, and several value objects for venues including \ContactInfo\, \Location\, \SocialNetworks\, and \VenueDetails\.

src/Loyalty.Core.Entities/Aggregates · high confidence

Added venue domain event handlers for lifecycle and update notifications

New domain event handlers have been introduced for the Venue aggregate, ensuring that key venue lifecycle events—creation, approval, acceptance changes, archiving, and updates to images, logos, and general details—are properly processed. Each handler listens for its respective domain event and publishes corresponding outbox notifications (e.g., WorkerAddedToVenueNotification, CreateVenueNotification, UpdateVenueNotification, PatchVenueApproveNotification, etc.) to the event bus, enabling downstream systems to react to venue state changes.

src/Loyalty.Application.DomainEvents.Handlers/Venues · high confidence

Added venue management commands

Introduced a new set of commands for managing venue data, including creating, updating, and patching venue details such as name, description, location, working hours, and social network links. The update also includes commands for approving, rejecting, archiving, and modifying venue images and logos, as well as handling order acceptance status for venues.

src/Loyalty.Domain.Handlers.Queries/Commands/Venue · high confidence

Added venue query models for admin and user retrieval

Three new query models were added to the venue domain: GetVenueByIdQuery for retrieving a single venue by ID, GetVenuesForAdminQuery for admin-level venue access, and GetVenuesQuery for retrieving venues associated with a specific user ID. These changes introduce the request side of the CQRS pattern for venue data access.

src/Loyalty.Domain.Handlers.Queries/Queries/Venue · high confidence

Added venue query result models

Introduced new C\# classes that define the structure of venue-related query results, including GetVenueByIdQueryResult, GetVenuesQueryResult, GetVenuesByUserIdQueryResult, GetSocialNetworksResult, GetVenueWorkingHoursQueryResult, and GetLocationQueryResult. These models represent the data returned by venue queries, containing fields such as name, description, location, social network links, and working hours.

src/Loyalty.Domain.Handlers.Queries/QueryResults/Product, src/Loyalty.Domain.Handlers.Queries/QueryResults/Venue · high confidence

Added view models and validators for the loyalty application

Introduced a comprehensive set of data transfer objects and validation rules for the loyalty system. New view models were added to represent core entities including clients, locations, products, purchases, and venues, alongside their corresponding FluentValidation validators to enforce data integrity.

src/Loyalty.Application.ViewModels · high confidence

Added worker management commands

New MediatR command classes have been introduced to support worker lifecycle operations, including creating workers (with and without venue association), updating worker details, archiving workers by UID or ID, and updating worker photos. These commands provide the necessary data structures for handling worker-related requests within the loyalty domain.

src/Loyalty.Domain.Handlers.Queries/Commands/Workers · high confidence

Added worker query handlers for retrieving worker data

Introduced new MediatR query classes for fetching worker information, including lookups by email, ID, phone, and user ID, as well as a general query to list workers by venue. These additions provide the underlying data access methods for worker-related operations.

src/Loyalty.Domain.Handlers.Queries/Queries/Worker · high confidence

Added worker query result models for loyalty system

New C\# classes have been introduced to represent worker data in the loyalty domain, including GetWorkerByIdQueryResult, GetWorkersQueryResult, GetWorkersByUserIdQueryResult, GetInviteByEmailQueryResult, GetInviteByPhoneQueryResult, and GetVenueWorkerResult. These models define the structure for retrieving worker information, including fields like ID, name, phone, email, photo URI, and associated venue roles, enabling the system to query and return worker details.

src/Loyalty.Domain.Handlers.Queries/QueryResults/Worker · high confidence

Adds shared extension methods for claims, HTTP requests, and environment detection

New extension methods are introduced in the shared library to simplify common operations. ClaimsPrincipal is extended with helpers to extract user identity, phone number, email, name, surname, city, avatar, and venue roles/IDs from security claims. HttpRequest gains a method to validate an admin secret header and a generic deserializer for request bodies. Environment detection is added to identify local, stage, or production deployments. Additional utilities include string splitting with quote unwrapping, enumerable-to-JSON serialization for service bus messages, and a helper to join strings with commas.

src/Loyalty.Common.Shared/Extensions · high confidence

Initial AutoMapper configuration for domain entities

The application introduces a new AutoMapper profile that establishes mapping rules for a wide range of domain entities, including venues, workers, products, loyalty programs, and purchases. This configuration bridges the gap between internal query results and external view models, enabling seamless data transformation for the loyalty system.

src/Loyalty.Application.AutoMapper · high confidence

Initial setup of the Loyalty Program Azure Function

The Loyalty Program service is introduced as a new Azure Function application. This includes the core startup configuration for dependency injection and Swagger documentation, along with WebJobs startup logic for Azure token validation and Application Insights telemetry processing. The service is configured with an 'api' route prefix, structured logging, and sampling for Application Insights. A .gitignore file is added to exclude build artifacts and sensitive local settings, while a local.settings.example.json template provides the necessary configuration keys for local development.

src/LoyaltyProgram · high confidence

Introduce command result abstractions and handler interfaces for loyalty products and programs

Added new domain contract classes (CommandResult, CommandNotificationResult) and their corresponding interfaces to standardize command execution outcomes and notification handling. Additionally, introduced interface definitions for command handlers managing the creation, update, and archiving of loyalty product groups and loyalty programs, establishing the contract layer for these specific operations.

src/Loyalty.Domain.Contracts, src/Loyalty.Domain.Handlers.Contracts · high confidence

Introduce new application services and DTOs for venue management and user interactions

Added a suite of new application services in the Venue module to handle core business logic for venues, products, orders, purchases, and users. This includes \LoyaltyVenueAppService\ for venue CRUD and image patching, \ProductAppService\ and \ProductGroupAppService\ for product management, \OrderAppService\ for order status updates, and \PurchaseAppService\ for handling purchase and burn operations. Additionally, \ClientInfoAppService\ and \CodeAppService\ provide user and purchase retrieval by code, while \LoyaltyProgramAppService\ manages loyalty programs. Supporting DTOs like \EmailInvitationDto\ and \PurchaseNotificationDto\ were added to the storage layer, and new interfaces \IDbContext\ and \ITenantProvider\ were introduced to support database and tenant context access.

src/Loyalty.Application.Venue · high confidence

Introduce new loyalty rule entity models

Added new entity classes for loyalty rules, including a base rule class and specific implementations for percentage-based calculations (fixed and range-based) and stamp-based rewards. These new models define the structure for different types of loyalty rules, each specifying compatible rule types and specific configuration properties.

src/Loyalty.Core.Entities/Rules · high confidence

Introduce notification handlers for product and worker events

Added new notification handlers to process specific domain events: a handler for product acceptance changes that updates venue order availability, and a handler for worker venue assignments that updates worker-venue relationships. These handlers utilize a new base notification handler and service bus topic interfaces to send messages via Azure Service Bus.

src/Loyalty.Infrastructure.Handlers.Notifications · high confidence

Introduced centralized dependency injection setup for database, service bus, and application services

The application now registers all core infrastructure services through a new set of extension methods in the DI layer. This includes configuring SQL connection strings and repository mappings for the database context, setting up Azure Service Bus clients for integration and user topics, binding configuration sections for settings like SMS and email, and registering application-level services such as venue, product, and order handlers. Additionally, third-party integrations including MediatR, AutoMapper, and logging are wired up, with a transactional behavior pipeline added for commands.

src/Loyalty.Infrastructure.IoC/DI · high confidence

Introduces core domain entities for the loyalty system

Adds new entity classes for managing loyalty programs, product groups, orders, purchases, venues, and workers. These include LoyaltyProgram, LoyaltyProductGroup, Order, OrderItem, Product, Purchase, Venue, and Worker aggregates, each with their respective domain events and validation logic.

Loyalty.Core.Entities · high confidence

Introduces scoped DbContext lifecycle and transactional context management

The data access layer now implements a custom scoped lifecycle for database contexts, ensuring that each HTTP request or function invocation receives a dedicated, reusable DbContext instance via a new \DbContextScoped\ wrapper and \ObjectStore\ cache. This change introduces \TransactionalContext\ to manage explicit database transactions and adds an \EmptyMediator\ stub, while defining the \ILoyaltyDbContext\ and \ILoyaltyTenantDbContext\ interfaces that map to specific entity sets for the loyalty system.

src/Loyalty.Infrastructure.DataAccess/Context · high confidence

New base interfaces for entity lifecycle and auditing

The codebase introduces four new base interfaces in the entity model: IArchivableEntity (with an IsArchived flag), IAuditableEntity (tracking Created/Modified timestamps and user IDs), IOrderable (an IsAvailableForOrder flag), and ITenantEntity (a TenantId). These interfaces provide a standardized contract for archiving, auditing, ordering, and multi-tenancy across entities.

src/Loyalty.Core.Entities/Base · high confidence

New commands for updating user profile and email

Added new MediatR command classes for updating a user's profile information and email address. The \UpdateUserProfileCommand\ allows updating a user's name and last name, while the \UpdateEmailCommand\ enables updating the email address and its verification status.

src/Loyalty.Domain.Handlers.Queries/Commands/UserProfile · high confidence

New configuration settings for image, email, and messaging services

Added new settings classes to the application's configuration layer, introducing structured options for database connections, email templates and domains, Google authentication, image storage and dimensions, Service Bus queues, SMS host and tokens, Swagger endpoints, and venue limits. These changes allow the system to externalize and manage configuration for these specific services.

src/Loyalty.Common.Shared/Settings · high confidence

New notification types for orders, interactions, and codes

The system now supports new notification events for order lifecycle changes (creation and updates), user interactions, and generated codes. Users will receive notifications when an order is created or modified, when a user interaction occurs, and when a code is generated, enabling real-time updates for these specific events.

common/LoyaltyClient.Domain.Handlers.Notifications · medium confidence

New repository interfaces for domain aggregates

Added repository interfaces for LoyaltyProgram, Order, ProductGroup, Product, Purchase, VenueAdmin, Venue, and Worker aggregates. These interfaces define the data access contracts for each entity, enabling the implementation of persistence logic for these core business objects.

src/Loyalty.Core.Entities/Interfaces · high confidence

Architecture

Added solution file for common project

A new solution file, Loyalty.Venue.Common.sln, has been added to the common directory. This file defines the build configuration for three specific projects: Loyalty.Shared.Contracts, Loyalty.Domain.Handlers.Notifications, and LoyaltyClient.Domain.Handlers.Notifications.

common · high confidence

Behavioural changes

Added database entity configurations for loyalty domain aggregates

The data access layer now includes Entity Framework Core configuration classes for a new set of loyalty domain entities. New mappings have been added for LoyaltyGroupRule, LoyaltyProductGroup, LoyaltyProgram, Order, OrderItem, Product, ProductGroup, Purchase, Venue, VenueWorker, and Worker. These configurations define table names within the 'Loyalty' schema, primary keys, unique indexes, and relationships such as the one-to-many between Venue and its ProductGroups and LoyaltyPrograms.

src/Loyalty.Infrastructure.DataAccess/EntityConfigurations · high confidence

Added domain event handlers for loyalty product group lifecycle events

Implemented new domain event handlers for the LoyaltyProductGroups module, enabling the system to react to the creation, update, and archival of loyalty product groups. These handlers listen for corresponding domain events and persist notifications to the event bus, ensuring that external systems are notified of these state changes.

src/Loyalty.Application.DomainEvents.Handlers/LoyaltyProductGroups · high confidence

Added error code and claim constants for validation and state management

The application now defines a centralized set of error codes and claim identifiers to standardize error handling and state management across the loyalty system. New constants include specific error codes for scenarios such as limit reached, duplicated entities, incorrect product or loyalty group references, and venue-related states (e.g., approval, publishing, and order states). Additionally, new claim constants for 'venues' and 'new\_venue' are introduced to support identity or permission checks. These changes ensure consistent error messaging and state validation throughout the shared components.

src/Loyalty.Common.Shared/Constants · high confidence

Added image validation logic for various entity types

The system now enforces image validation rules for product photos, venue images, venue logos, and worker photos. This includes checks for file size (up to 1 MB), format (PNG or JPG), and specific width/height constraints for each entity type, ensuring uploaded images meet the required specifications.

src/Loyalty.Application.Storage.Dto/Validators · high confidence

Added product command DTOs for the MediatR pipeline

New command classes have been introduced in the product domain to handle product lifecycle operations via the MediatR framework. Specifically, ArchiveProductCommand, CreateProductCommand, PatchProductCommand, PatchProductImageCommand, and UpdateProductCommand have been added. These DTOs define the input contracts for creating, updating, patching, archiving, and updating product images, enabling the application to process these product management requests through the existing command handler pipeline.

src/Loyalty.Domain.Handlers.Queries/Commands/Products · high confidence

Added product group domain event handlers

New domain event handlers have been added for product group lifecycle events: archiving a product group now archives all associated products; changing a product group's visibility state now updates the visibility of all associated products; and updating a product group now publishes notifications to update each associated product's icon and name.

src/Loyalty.Application.DomainEvents.Handlers/ProductGroup · high confidence

Added script to clear all application data

A new SQL script, delete\_all\_data.sql, has been added to the scripts directory. This script executes DELETE statements against multiple tables across the client and loyalty schemas, including Card, ProductGroup, Venue, Worker, UserProfile, and UserCode, effectively clearing all stored data.

scripts · high confidence

Added transactional command handling with automatic commit/rollback

A new base handler and a MediatR pipeline behavior were added to the command handling layer. The \BaseHandler\ provides a shared interface for command handlers, injecting the database context and HTTP principal. The \TransactionBehaviour\ pipeline behavior wraps each command in a database transaction, automatically committing on success or rolling back on failure, and publishes outbox events after a successful transaction. This ensures that command execution is atomic and consistent with the application's event-driven architecture.

src/Loyalty.Infrastructure.Handlers.Commands/Pipelines · medium confidence

Custom App Insights telemetry processing and user context enrichment

The application now filters out low-latency dependency telemetry and enriches request telemetry with user identity and profile data. A new MyTelemetryProcessor is introduced to discard DependencyTelemetry items with a duration under 200ms, reducing noise in Application Insights. Additionally, a TelemetryInitializer adds user-specific properties (City, Phone, Role) to request telemetry when available from the HTTP context, enabling better tracking of user attributes in logs.

src/Loyalty.Infrastructure.Logging.AppInsights · medium confidence

Initial database schema for the loyalty platform

The database schema is initialized with tables for venues, workers, orders, and loyalty programs, establishing the core data model for the loyalty system.

src/Loyalty.Infrastructure.DataAccess/Migrations · high confidence

Test coverage

Added AuthUser test helper for Firebase authentication; Added availability tests for the loyalty program API; Added functional tests for venue and worker management; Added test data factories for loyalty program entities; Added test data factories for the loyalty program; Added test fixtures and integration tests for the Loyalty Program; Added test infrastructure and configuration; Added tests for Loyalty, Product, and ProductGroup management.

Dependencies

Updated .NET and NuGet dependencies across the solution

The project files have been updated to use .NET Standard 2.1 and .NET Core 3.1 as the target frameworks. Key package references have been upgraded, including MediatR to 8.0.1, AutoMapper to 10.0.0, and Microsoft.EntityFrameworkCore to 3.1.8. Additional dependencies such as FirebaseAdmin, Serilog, and various Azure SDKs have also been updated to their latest compatible 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

Score

  • CAI 60 → 57 (-2.9)
  • Rubric changed (rubric-2026.08.18 → rubric-2026.09.15) — scores are not directly comparable.

Lenses

  • Code Health 59 → 53 (-5.8)
  • Architecture 84 → 84 (-0.0)
  • Maturity 77 → 77 (+0.0)
  • Readiness 75 → 75 (-0.1)
  • Security 86 → 79 (-6.3)
  • Domain Modelling 50 → 46 (-3.8)
  • Event-Driven 100 (new)

Resolved (16)

  • Bounded contexts not declared
  • Build status unknown
  • Duplicated block (11 lines × 2) (src/Loyalty.Application.ViewModels/Validators/Venue/CreateVenueValidator.cs)
  • Duplicated block (11 lines × 2) (src/LoyaltyProgram/Http/Write/Admin/VenueApprovePatchFunction.cs)
  • Duplicated block (13 lines × 3) (src/Loyalty.Application.Storage.Dto/Validators/VenueImageValidator.cs)
  • Duplicated block (19 lines × 2) (src/Loyalty.Application.Storage.Dto/Validators/VenueLogoValidator.cs)
  • Duplicated block (8 lines × 2) (src/Loyalty.Application.ViewModels/Validators/Venue/CreateVenueValidator.cs)
  • Duplicated block (9 lines × 2) (src/LoyaltyProgram/Http/Write/VenueImages/VenueCreateImageFunction.cs)
  • Inconsistent Naming and Structure: ICommandNotificationResult is an interface that duplicates the structure of CommandResult but with different naming conventions (e.g., OnSuccessNotifications, OnFailNotifications). This suggests a lack of clear distinction between the result of a command and the notification of its outcome.
  • LLM evaluation failed
  • Low cohesion: LoyaltyVenueImageAppService (LCOM4 5) (src/Loyalty.Application.Venue/LoyaltyVenueImageAppService.cs)
  • Monorepo: only 1 of 2 solutions was scored
  • Redundant/Overlapping Types: CommandNotificationResult appears to be a wrapper around CommandResult (it has a CommandResult property) but also duplicates the Success, Message, and Result properties directly. This creates confusion about whether consumers should use CommandResult or CommandNotificationResult, and why both exist.
  • Tests co-located / outside the solution
  • redundant comment (src/Loyalty.Infrastructure.DataAccess/Context/Scoped/ObjectStore.cs)
  • single-maintainer — knowledge-concentration (bus factor) risk

New (77)

  • Boundary-crossing change coupling: AutoMapperProfile.cs ↔ UpdateVenueCommandHandler.cs (src/Loyalty.Application.AutoMapper/AutoMapperProfile.cs)
  • Boundary-crossing change coupling: CreateVenueViewModel.cs ↔ UpdateVenueCommandHandler.cs (src/Loyalty.Application.ViewModels/Venue/CreateVenueViewModel.cs)
  • Change coupling: CreateLoyaltyProgramCommandHandler.cs ↔ UpdateLoyaltyProgramCommandHandler.cs (src/Loyalty.Infrastructure.Handlers.Commands/Commands/LoyaltyPrograms/CreateLoyaltyProgramCommandHandler.cs)
  • Change-coupling hub: VenueGetAllFunction.cs → VenueGetFunction.cs, VenueDeleteFunction.cs, VenuePostFunction.cs, VenuePutFunction.cs (src/LoyaltyProgram/Http/Read/Venue/VenueGetAllFunction.cs)
  • Change-coupling hub: VenueGetFunction.cs → VenueDeleteFunction.cs, VenuePostFunction.cs, VenuePutFunction.cs (src/LoyaltyProgram/Http/Read/Venue/VenueGetFunction.cs)
  • CommentedOutCode (src/Loyalty.Core.Entities/Aggregates/ProductGroups/ProductGroup.cs)
  • CommentedOutCode (src/LoyaltyProgram/Startup.cs)
  • Documentation: no installation or build instructions (README.md)
  • Documentation: no licence statement (README.md)
  • Documentation: no usage examples (README.md)
  • Duplicated block (10 lines × 2) (src/LoyaltyProgram/Http/Write/VenueImages/VenueCreateImageFunction.cs)
  • Duplicated block (11 lines × 2) (src/LoyaltyProgram/Http/Write/Admin/VenueApprovePatchFunction.cs)
  • Duplicated block (11 lines × 3) (src/Loyalty.Application.Storage.Dto/Validators/VenueImageValidator.cs)
  • Duplicated block (13 lines × 2) (src/Loyalty.Domain.Handlers.Queries/QueryResults/Orders/GetOrderByUserIdQueryResult.cs)
  • Duplicated block (13 lines × 3) (src/Loyalty.Application.Storage.Dto/Validators/VenueImageValidator.cs)
  • Duplicated block (14 lines × 3) (src/Loyalty.Application.ViewModels/Venue/CreateVenueViewModel.cs)
  • Duplicated block (16 lines × 2) (src/Loyalty.Application.ViewModels/Product/CreateProductViewModel.cs)
  • Duplicated block (17 lines × 2) (src/Loyalty.Application.ViewModels/LoyaltyProductGroup/LoyaltyProductGroupGetViewModel.cs)
  • Duplicated block (18 lines × 2) (src/Loyalty.Application.ViewModels/Venue/CreateVenueViewModel.cs)
  • Duplicated block (18–21 lines × 2) (src/Loyalty.Infrastructure.Firebase.Handlers/Notifications/SetupFirebaseTokenNotificationHandler.cs)
  • …and 57 more

Architecture

  • Unchanged — 1 containers · 1 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

richardchanjr90-cpu/ddd-by-example 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 495458f3b45146be55076fadaf329257a1ea0bab — 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.