huynxtb/progcoder-shop-microservices
28.9
Weak · 21 September 2026
27.2k
lines of production code
JavaScript
with C#
2
measurements over time
What this system is
This system is a .NET 8 microservices e-commerce platform named ProG Coder Shop, designed to manage product catalogs, shopping baskets, orders, inventory, and discounts. It implements a CQRS architecture with MediatR and utilizes an outbox pattern for reliable, event-driven communication between services via RabbitMQ. The platform supports user-facing store and admin interfaces, real-time notifications, and comprehensive observability through distributed tracing and logging.
How it got here
2025 — Microservices scaffolding and infrastructure
122 changes.
The project established the foundational structure for a .NET 8 microservices e-commerce platform, initializing core services such as Catalog, Basket, Order, Inventory, Discount, and Notification. Significant effort was dedicated to building shared building blocks, implementing distributed tracing and logging, and setting up containerized deployment with Docker and Keycloak authentication. Legacy code from the Agent and User services was removed to streamline the architecture.
2026 — CQRS adoption and service expansion
11 changes.
The project implemented the CQRS pattern with MediatR and outbox-based event publishing across multiple services, including Basket, Catalog, Inventory, Order, and Notification. This architectural shift standardized command and query handling while introducing new features for brand management, inventory tracking, order lifecycle, and dashboard reporting. The period also included infrastructure improvements such as generic repository interfaces and automated database migration scripts.
Features
Add basket checkout domain event with customer, address, and discount details
A new domain event, BasketCheckoutDomainEvent, has been introduced to capture the specific details required for order processing. This event carries the shopping cart content along with structured data for the customer (ID, name, email, phone), shipping address (including country and postal code), and applied discount (coupon code and amount). This change enables downstream services to react to checkout actions with comprehensive context rather than just a generic notification.
src/Services/Basket/Core/Basket.Domain/Events · high confidence
Add notification API endpoints for listing, counting, and marking notifications
The Notification API now exposes five new endpoints to manage user notifications. Users can retrieve all notifications, fetch a paginated list, get the count of unread items, view the top 10 unread notifications, and mark specific notifications as read. All endpoints are secured via authorization and integrate with the application's CQRS pattern to handle queries and commands.
src/Services/Notification/Api/Notification.Api/Endpoints · high confidence
Added API route constants for product search
The search service now defines explicit route constants for product endpoints, establishing the base path 'products' and the specific search route '/products' within the ApiRoutes class.
src/Services/Search/Api/Search.Api/Constants · high confidence
Added BsonCollectionAttribute for MongoDB collection mapping
A new BsonCollectionAttribute has been introduced in the Basket.Domain.Attributes namespace, allowing classes to explicitly specify their corresponding MongoDB collection name via a CollectionName property.
src/Services/Basket/Core/Basket.Domain/Attributes · high confidence
Added Nginx configuration for Admin and Store apps
New Nginx configuration files have been added for both the App.Admin and App.Store applications. These configurations set up an HTTP server on port 80 to serve static content from /usr/share/nginx/html, with routing configured to handle single-page application (SPA) style navigation by falling back to index.html for non-existent assets.
src/Apps/App.Admin/nginx, src/Apps/App.Store/nginx · high confidence
Added OrderStatus enum to define order lifecycle states
A new OrderStatus enumeration has been introduced in the Order.Domain layer to explicitly define the possible states of an order. This enum includes values for Pending, Confirmed, Processing, Shipped, Delivered, Canceled, and Refunded, providing a structured way to track order progression within the system.
src/Services/Order/Core/Order.Domain/Enums · high confidence
Added application models for basket and product queries
The Basket application layer now includes new data models to support product and basket operations. This introduces filter records for retrieving all categories, all products, specific products, and published products, enabling flexible querying. It also defines response models for external product data (including product details and lists) and coupon evaluation results (original, discount, and final amounts). Additionally, a result wrapper for retrieving the shopping cart basket has been added.
src/Services/Basket/Core/Basket.Application/Models · high confidence
Added background worker services for Catalog and Order consumers
New background services have been introduced for the Catalog and Order worker consumers. The Order consumer now includes an OrderBackgroundService that logs start and stop times while polling. The Catalog consumer has replaced its previous pagination extension utility with a CatalogBackgroundService that similarly logs lifecycle events and polls, effectively changing the Catalog worker's role from a utility provider to an active background process.
src/Services/Catalog/Worker/Catalog.Worker.Consumer/BackgroundServices, src/Services/Order/Worker/Order.Worker.Consumer/BackgroundServices · high confidence
Added domain entities for notifications, deliveries, payloads, and templates
The notification service's domain model now includes four new entities: NotificationEntity for storing user-facing notifications with read status and target URLs; DeliveryEntity for managing the lifecycle of outbound message deliveries (including retry logic, priority, and status tracking); MessagePayloadEntity to encapsulate message details like channel type, recipients, and content; and TemplateEntity for storing reusable message templates keyed by channel. These entities form the core data structures for the notification system's domain layer.
src/Services/Notification/Core/Notification.Domain/Entities · high confidence
Added domain enums for notification channels, priorities, statuses, and colors
The notification service now defines core domain constants via new enum types in the Notification.Domain layer. ChannelType specifies supported delivery methods (Email, InApp, Discord). DeliveryPriority allows messages to be marked as Low, Medium, or High. DeliveryStatus tracks the lifecycle of a notification (Queued, Sent, Failed, Sending, Illegal, GiveUp). DiscordColor provides specific integer color codes for Discord embeds. These enums provide the foundational data structures for the notification system's domain logic.
src/Services/Notification/Core/Notification.Domain/Enums · high confidence
Added domain models for Discord webhooks and Keycloak integration
New model classes have been introduced to support external integrations within the notification service. Specifically, \DiscordWebhookPayload\ and \DiscordEmbed\ define the structure for sending formatted messages via Discord webhooks, while \KeycloakAccessToken\ and \KeycloakUser\ model the data structures for authenticating with and retrieving user information from Keycloak.
src/Services/Notification/Core/Notification.Domain/Models · high confidence
Added domain value objects for orders, customers, products, discounts, and addresses
The order domain now includes new value objects to represent core business entities: Address (with fields for line, city, state, country, and postal code), Customer (with name, email, and phone), Discount (coupon code and amount), OrderNo (auto-generated unique order identifiers), and Product (id, name, price, and image URL). These classes provide structured, validated data containers for use within the order service.
src/Services/Order/Core/Order.Domain/ValueObjects · high confidence
Added event handlers for product creation and deletion in the search worker
The search worker consumer now includes new integration event handlers to keep the search index in sync with catalog changes. Specifically, the \UpsertedProductIntegrationEventHandler\ processes product creation or update events by mapping the incoming event data to a DTO and sending an \UpsertProductCommand\, while the \DeletedUnPublishedProductIntegrationEventHandler\ processes deletion events by sending a \DeleteProductCommand\. These handlers ensure that product additions, modifications, and removals in the catalog are reflected in the search service.
src/Services/Search/Worker/Search.Worker.Consumer/EventHandlers · high confidence
Added gRPC client services for Catalog and Discount integrations
The Basket service now includes infrastructure implementations for communicating with external Catalog and Discount services via gRPC. The new CatalogGrpcService enables fetching product details and lists by ID or search text, while the DiscountGrpcService allows evaluating coupons to calculate final amounts. These services provide the underlying connectivity for basket operations that depend on product data and pricing discounts.
src/Services/Basket/Core/Basket.Infrastructure/Services · high confidence
Added gRPC contract for catalog service
A new Protocol Buffers definition (catalog.proto) has been introduced to establish the gRPC interface for the catalog service. This contract defines the CatalogGrpc service with RPCs for retrieving products (GetProducts, GetProductById, GetAllAvailableProducts) and counting them (GetCountProduct), along with the associated request and response message structures.
src/Shared/Contracts/Catalog.Contract · high confidence
Added gRPC contract for discount operations
A new Protocol Buffers definition has been introduced to specify the gRPC service interface for discount functionality. This contract defines the \DiscountGrpc\ service, exposing two remote procedure calls: \ApplyCoupon\ and \EvaluateCoupon\. These methods allow clients to submit coupon codes and order amounts to receive calculated discount details (original, discount, and final amounts) or confirmation of application, establishing the communication contract for the discount feature.
src/Shared/Contracts/Discount.Contract · high confidence
Added gRPC service interfaces for catalog and discount operations
New interfaces ICatalogGrpcService and IDiscountGrpcService have been introduced to define the contract for external service communication. ICatalogGrpcService exposes methods to retrieve product details and lists by ID or search text, while IDiscountGrpcService defines operations for applying and evaluating coupons. These interfaces enable the order application to interact with catalog and discount services via gRPC.
src/Services/Basket/Core/Basket.Application/Services, src/Services/Order/Core/Order.Application/Services · high confidence
Added notification mapping profiles for DTOs
Introduced a new AutoMapper profile that defines mappings between domain entities and Data Transfer Objects (DTOs) for notifications and Keycloak users. This enables automatic conversion between NotificationEntity and NotificationDto, as well as between KeycloakUser and KeycloakUserDto, and KeycloakAccessToken and KeycloakAccessTokenDto, simplifying data transfer within the notification service.
src/Services/Notification/Core/Notification.Application/Mappings · high confidence
Added notification result models and channel result structure
Introduced new model classes to support notification retrieval and channel operations. Added \ChannelResult\ to represent the success or failure state of a notification channel operation, including provider message IDs and error messages. Added \NotificationContext\ to encapsulate notification details such as recipients (To, Cc, Bcc), subject, body, and HTML formatting. Added specific result models for retrieving notifications: \GetAllNotificationsResult\, \GetNotificationsResult\, \GetTop10NotificationsUnreadResult\, and \GetCountNotificationUnreadResult\, which wrap lists of \NotificationDto\ or count values to standardize API responses.
src/Services/Notification/Core/Notification.Application/Models · high confidence
Added outbox message processing background service
A new background service has been introduced to handle the processing of outbox messages. This service runs continuously, utilizing parallel execution to process messages from the outbox with configurable frequency and parallelism settings. It includes logging for iterations and total processed messages, and handles cancellation and errors gracefully.
src/Services/Basket/Worker/Basket.Worker.Outbox/BackgroundServices · high confidence
Added pagination extension methods for MongoDB and LINQ queries
A new static class, PagingExtensions, has been introduced in the BuildingBlocks.Pagination.Extensions namespace to simplify data retrieval. It provides WithPaging extension methods for both MongoDB's IFindFluent and standard LINQ IQueryable interfaces, allowing developers to apply skip and limit operations using a shared PaginationRequest model. Additionally, a GetTotalPages helper method is included to calculate the total number of pages based on the total item count and page size.
src/Shared/BuildingBlocks/Pagination/Extensions · high confidence
Added product search endpoint
A new API endpoint for searching products has been introduced at the route defined by ApiRoutes.Product.Search. This endpoint accepts pagination, search text, category filters, price range, status, and sorting parameters, and returns a paginated list of search results via the SearchProductQuery.
src/Services/Search/Api/Search.Api/Endpoints · high confidence
Added response models for external products, internal coupons, and Keycloak authentication
The Order application now includes specific data models to handle responses from external and internal services. This adds \GetAllProductsResponse\ and \ProductReponse\ for retrieving product details, \ApplyCouponResponse\ and \EvaluateCouponResponse\ for processing coupon logic, and \KeycloakAccessTokenResponse\ for managing authentication tokens from Keycloak.
src/Services/Order/Core/Order.Application/Models/Responses · high confidence
Adds common utility extension methods for enums, strings, numbers, and queries
This change introduces a new set of helper extension methods in the shared Common library to simplify common data manipulation tasks. Developers can now easily retrieve enum descriptions, convert integers or strings to enums, and format file sizes or short numbers. String handling is enhanced with methods to truncate text, generate URL-friendly slugs, and parse enums. Additionally, LINQ queries gain conditional filtering and pagination helpers (WhereIf, TakeIf, PageBy) to streamline data retrieval logic, while HashExtension provides convenient SHA-256 and SHA-512 hashing capabilities for strings and byte arrays.
src/Shared/Common/Extensions · high confidence
Adds gRPC client registration with API key interception for Catalog and Discount services
The Basket service now registers gRPC clients for the Catalog and Discount services via a new DI extension. These clients are configured to automatically attach an API key header to outgoing requests using a custom interceptor, with service URLs and keys sourced from configuration. The setup also includes a permissive server certificate validation callback for development environments.
src/Services/Basket/Core/Basket.Infrastructure/GrpcClients · high confidence
Admin interface now supports Keycloak authentication and internationalization
The Admin application now authenticates users via Keycloak, automatically handling token refresh and redirecting unauthenticated users to the login page. Additionally, the interface is fully internationalized with support for English and Vietnamese, translating all UI elements, menus, and error messages.
src/Apps/App.Admin/src · high confidence
App.Store and App.Admin receive Docker support, Keycloak configuration, and branding updates
The App.Store and App.Admin applications are now containerized with new Dockerfiles that build the Vite assets using Node 22 and serve them via Nginx, allowing for consistent deployment environments. Both apps now include .env.sample files to configure Keycloak authentication (URL, realm, client ID, and redirect URIs) and the API gateway endpoint, with App.Store redirecting to port 3001 and App.Admin to port 3002. The user-facing identity has been updated: the browser titles are now 'ProG Coder - Store' and 'ProG Coder - Admin', the favicons have been replaced with a custom SVG logo, and the App.Admin body class has been changed to 'progcoder-app' to reflect the new branding.
src/Apps/App.Store · high confidence
Basket API endpoints for CRUD and checkout operations
The Basket API now exposes four new HTTP endpoints to manage shopping carts: POST /basket to add items, GET /basket to retrieve the current user's cart, DELETE /basket to remove the entire cart, and POST /basket/checkout to process the purchase. All endpoints are secured via authentication, delegate processing to CQRS commands and queries through an ISender, and return standardized API responses (ApiCreatedResponse, ApiGetResponse, ApiDeletedResponse) with appropriate status codes for success, unauthorized access, forbidden access, and bad requests.
src/Services/Basket/Api/Basket.Api/Endpoints · high confidence
Basket API service initialization with multi-database support and containerization
The Basket API service is now available, providing endpoints for managing shopping baskets (get, store, delete, checkout) via Carter routes. The service supports multiple database backends (SQL Server, MySQL, PostgreSQL, MongoDB) through a dynamic health-check configuration and includes Redis caching, distributed tracing (OpenTelemetry/Prometheus), and Keycloak-based OAuth2 authentication. It is packaged with a .NET 8.0 Dockerfile for containerized deployment.
src/Services/Basket/Api/Basket.Api · high confidence
Basket infrastructure service registration and caching setup
The Basket infrastructure layer now registers its services via a new \DependencyInjection\ extension. This includes scanning for and registering services and repositories with scoped and singleton lifetimes, respectively. It configures MongoDB client and database connections using configuration settings, and sets up a Redis cache with specific connection options (endpoint, password, retry settings). Additionally, it decorates the \IBasketRepository\ with a \CachedBasketRepository\ to enable caching for basket operations. The setup also ensures MongoDB indexes are created on application startup.
src/Services/Basket/Core/Basket.Infrastructure · high confidence
Basket service now supports caching and reliable message processing
The basket repository layer has been expanded to include a distributed cache wrapper (CachedBasketRepository) that stores shopping cart data in Redis with a 1-day absolute and 1-hour sliding expiration, reducing database load. Additionally, an OutboxRepository has been introduced to manage event outbox messages in MongoDB, featuring atomic claim-and-update logic to ensure reliable, duplicate-free processing of background tasks and retries.
src/Services/Basket/Core/Basket.Infrastructure/Repositories · high confidence
Catalog API endpoints now support product image uploads and public product browsing
The Catalog API endpoints have been updated to allow creating and updating products with image files (handled via multipart forms) and to expose public endpoints for browsing published products without authentication. Additionally, a new endpoint allows initializing catalog data.
src/Services/Catalog/Api/Catalog.Api/Endpoints · high confidence
Catalog Application layer scaffolding with DTOs, mappings, and DI configuration
The Catalog.Application project has been initialized with the core application-layer infrastructure required for the catalog service. This includes a DependencyInjection setup that registers MediatR (with validation and logging behaviors), FluentValidation, AutoMapper, and Feature Management. A comprehensive set of Data Transfer Objects (DTOs) has been added for Products, Categories, and Brands, featuring audit trails (creation/modification timestamps and users) and support for image uploads. Mapping profiles are configured to translate between domain entities and these DTOs, and result/filter models are defined to structure API responses (including pagination and tree structures for categories). Additionally, interfaces for external services (MinIO storage, seed data) and an outbox repository for event sourcing are introduced to support the service's operational requirements.
src/Services/Catalog/Core/Catalog.Application · high confidence
Discord notifications for product updates
The notification worker now listens for product upsert events and sends Discord notifications to the configured channel. This change introduces a new event handler that processes product creation and update events, triggering Discord messages to keep users informed about product changes.
src/Services/Notification/Worker/Notification.Worker.Consumer/EventHandlers · high confidence
Discount service infrastructure: MongoDB persistence, Unit of Work, and seed data
The Discount service now includes its infrastructure layer, introducing a MongoDB-based persistence strategy for coupons. This adds a Unit of Work pattern with transaction support (Begin/Commit/Rollback) to ensure data consistency across repository operations. The service automatically creates necessary database indexes (e.g., unique code, status, validity dates) and seeds initial test data (random fixed and percentage coupons) upon startup. Dependency injection is configured to register repositories and the Unit of Work as scoped services, while a custom exception type handles infrastructure-level errors.
src/Services/Discount/Core/Discount.Infrastructure · high confidence
Elasticsearch-based product search infrastructure added
The Search service now uses Elasticsearch as its data store instead of a relational database. This change introduces an \ElasticSearchInitializer\ that creates and configures the product index on startup with custom analyzers, and a \ProductRepository\ that handles CRUD operations and search queries (including text matching, category filtering, price ranges, and sorting) against this index. Dependency injection is configured to register the Elasticsearch client and repository, enabling the search functionality to rely on this new backend.
src/Services/Search/Core/Search.Infrastructure · high confidence
Initial Discount service scaffolding with coupon domain and application layer
The Discount service is introduced with a foundational application and domain structure. The application layer registers core infrastructure services including MediatR with validation and logging behaviors, FluentValidation, AutoMapper, and Feature Management via a new DependencyInjection entry point. It defines a comprehensive set of DTOs for coupon operations (create, update, evaluate, apply, and retrieval) and result models, alongside an AutoMapper profile mapping the domain entity to the coupon DTO. The domain layer establishes the core CouponEntity with business logic for validation, status transitions (pending, approved, rejected, out of stock), and discount calculation, supported by abstractions for entities, aggregates, and audit trails. A Unit of Work pattern and repository interface (ICouponRepository) are added to manage data access and transactions, providing the necessary plumbing for future command handlers.
src/Services/Discount/Core/Discount.Application · high confidence
Initial Report Application layer scaffolding
The Report.Application project has been initialized with the core infrastructure required for the report service. This includes dependency injection setup for MediatR (with validation and logging behaviors), FluentValidation, AutoMapper, and Feature Management. The layer defines repository interfaces for dashboard totals, order growth line charts, and top product pie charts, along with corresponding DTOs, mapping profiles, and result models to support these reporting features.
src/Services/Report/Core/Report.Application · high confidence
Initial Search Domain model and abstractions
Introduces the foundational domain layer for the new Search service, including base abstractions for entities and aggregates with domain event tracking and audit fields. Adds the core ProductEntity with properties for pricing, categorization, and status, along with enums for product status, sorting options, and ElasticSearch index mapping.
src/Services/Search/Core/Search.Domain · high confidence
Initial catalog data seeding for brands, categories, and products
The Catalog service now includes seed data infrastructure to automatically populate the database with initial content upon startup. This change adds seed definitions for brands (such as Apple, Samsung, Zara, and Gucci), a hierarchical category structure (including Electronics, Fashion, and Home), and 15 sample products (like the iPhone 15 Pro and MacBook Pro). The \InitialData\ class implements the \IInitialData\ interface using Marten, orchestrating the population process with retry and circuit-breaker policies to ensure data integrity during application initialization.
src/Services/Catalog/Core/Catalog.Infrastructure/Data · high confidence
Initial domain model and event sourcing infrastructure for the Order service
This change introduces the core domain entities and eventing structures for the Order service. It adds the OrderEntity, OrderItemEntity, and associated value objects to model order creation, item management, discounts, and status transitions (including cancellation and delivery). It also establishes the OutboxMessageEntity and InboxMessageEntity, which implement an outbox pattern with retry logic and exponential backoff to ensure reliable event publishing and consumption. Finally, it defines the specific domain events (OrderCreated, OrderCancelled, OrderDelivered) that are raised by the order aggregate to signal state changes.
src/Services/Order/Core/Order.Domain/Entities · high confidence
Initial domain model and infrastructure abstractions for the Report service
This change introduces the foundational domain layer for the new Report service. It establishes core DDD abstractions including \Entity\ and \Aggregate\ roots with built-in domain event tracking and audit fields (created/modified by/on). The domain defines specific entities for reporting features: \DashboardTotalEntity\ for summary metrics, and chart entities (\OrderGrowthLineChartEntity\, \TopProductPieChartEntity\) for visualizations. It also includes an enum for dashboard titles, a custom \DomainException\, and models for external Keycloak integration (\KeycloakAccessToken\, \KeycloakUserResponse\).
src/Services/Report/Core/Report.Domain · high confidence
Initial infrastructure setup for Catalog service
This change introduces the foundational infrastructure layer for the Catalog service. It adds dependency injection configuration to register Marten (document database), MinIO (object storage), and auto-scan for Services and Repositories. It also implements the MinIO cloud service for file uploads and share links, a seed data service to initialize categories, brands, and products, and global using statements to streamline namespaces. Additionally, the InfrastructureException class has been moved from the Agent service and updated to use the Catalog namespace.
src/Services/Catalog/Core/Catalog.Infrastructure · high confidence
Initial inventory service background worker and gRPC contract
The inventory service now includes a background worker service that runs a simple loop with logging, and a gRPC contract defining an \InventoryGrpc\ service with an \ExpireReservation\ RPC method. This establishes the foundational infrastructure for the inventory service's background processing and inter-service communication.
src/Services/Inventory/Worker/Inventory.Worker.Consumer/BackgroundServices, src/Shared/Contracts/Inventory.Contract · high confidence
Initial launch of the Discount API service
The Discount API is now available as a standalone .NET 8.0 service, enabling users to manage discounts via a Carter-based HTTP interface. The service supports multiple database backends (SQL Server, MySQL, PostgreSQL, and MongoDB) with MongoDB configured as the default, and includes built-in health checks, Serilog logging, and distributed tracing via OpenTelemetry. Authentication and authorization are handled through Keycloak (OAuth2), and the API exposes Swagger documentation for easy integration. The service is containerized with a multi-stage Dockerfile for efficient builds and deployment.
src/Services/Discount/Api/Discount.Api · high confidence
Initial notification application data models and repository contracts
This change introduces the foundational data transfer objects (DTOs) and repository interfaces for the new Notification service. It defines core abstractions for audit trails (creation and modification timestamps/users) and entity identification. Specific DTOs are added for managing notifications (including read status and target URLs), delivering messages via various channels with priority and retry logic, and integrating with Keycloak for user and token data. Additionally, repository interfaces are established to handle command operations (inserting/upserting notifications and deliveries) and query operations (retrieving notifications by user, checking unread counts, and fetching delivery details).
src/Services/Notification/Core/Notification.Application/Dtos · high confidence
Initial release of the App.Store frontend with internationalization and authentication
This change introduces the initial codebase for the App.Store application, establishing the core user-facing features and infrastructure. It adds a Keycloak-based authentication system (including a ProtectedRoute component and context) to secure user sessions, and implements full internationalization (i18n) with support for English and Vietnamese via a language switcher. The store UI includes product browsing capabilities with brand filtering, a notification system with unread counts and a dedicated list view, and a complete order management section allowing users to view their order history, see order details in a modal, and view a success confirmation after checkout.
src/Apps/App.Store/src · high confidence
Initial release of the Order API service
The Order API service is now available, providing the entry point for order-related operations. It is built on .NET 8 and includes dependency injection for distributed tracing, Serilog logging, Carter routing, and health checks supporting SQL Server, MySQL, and PostgreSQL. The service exposes Swagger documentation, OAuth2 authentication via Keycloak, and Prometheus metrics. It is configured to connect to local development services (SQL Server, RabbitMQ, MinIO, Keycloak) in the development environment and containerized services in production, with a Dockerfile provided for containerized deployment.
(repo-wide) · high confidence
Initial repository structure and documentation for ProG Coder Shop Microservices
The repository is initialized with the foundational structure for a .NET 8 microservices e-commerce platform. This includes the solution file defining projects for services like Catalog, Basket, Order, Inventory, and Discount, alongside shared libraries and workers. Configuration files for Docker Compose (infrastructure and full stack) are added to manage databases (PostgreSQL, MySQL, SQL Server, MongoDB, Redis), message brokers (RabbitMQ), and identity (Keycloak). Documentation files (README, CONTRIBUTING, LICENSE, DONATE) and a Makefile for build/run/migration commands are also introduced to support local development and contribution.
(repo-wide) · high confidence
Initial scaffolding of the notification service infrastructure
This change introduces the foundational structure for the new notification service. It adds an interface for interacting with Keycloak user data within the application layer, creates a placeholder directory for domain value objects, and establishes a basic background worker service that logs its start and stop times.
src/Services/Notification/Core/Notification.Application/Services, src/Services/Notification/Core/Notification.Domain/valueobjects, src/Services/Notification/Worker/Notification.Worker.Consumer/BackgroundServices · high confidence
Initial setup of the Catalog API service with Docker, Carter, and Keycloak authentication
The Catalog.Api project is introduced, providing the entry point for the catalog service. It includes a Dockerfile for containerization (exposing port 8080) and configuration files (appsettings) for PostgreSQL, MinIO, and Keycloak OAuth2 authentication. The API layer utilizes Carter for routing, MediatR for request handling, and AutoMapper for mapping product requests (CreateProductRequest, UpdateProductRequest) to application DTOs. Dependency injection is configured to register health checks, distributed tracing, and Swagger, while Program.cs wires up the application services, infrastructure, and API middleware.
src/Services/Catalog/Api/Catalog.Api · high confidence
Initial setup of the Search Application layer
This change introduces the core structure for the Search service's application layer, establishing the foundation for product search capabilities. It includes dependency injection configuration for MediatR, FluentValidation, AutoMapper, and Feature Management, alongside global using statements. The update defines data transfer objects (ProductDto, UpsertProductDto) and base abstractions for auditing and identification, implements an AutoMapper profile for mapping between domain entities and DTOs, and specifies the IProductRepository interface with methods for searching, upserting, and deleting products.
src/Services/Basket/Core/Basket.Application, src/Services/Search/Core/Search.Application · high confidence
Initial structure for the Basket service domain and application layers
This change introduces the foundational building blocks for the new Basket service, including domain enums like ProductStatus, application DTOs with audit capabilities (creation and modification timestamps/users), and exception classes. These components establish the data contracts and error handling patterns specific to the Basket service, separating it from previous shared or agent-specific code structures.
(repo-wide) · high confidence
Interactive and batch database migration scripts for Inventory and Order services
Added two new shell scripts to streamline database migrations for the Inventory and Order services. The \scripts/add-migration.sh\ script provides an interactive menu to create new Entity Framework migrations for a specific service, automatically installing the required \dotnet-ef\ tool (v8.0.6) and generating the migration files. The \scripts/run-migration.sh\ script allows users to apply pending migrations across all configured services in a single batch execution, providing a summary of successes and failures.
scripts · high confidence
Introduce Basket Worker Outbox service for reliable event processing
A new dedicated worker service has been added to handle the outbox pattern for the Basket service, ensuring reliable event delivery. This service registers an OutboxProcessor and an OutboxBackgroundService, leveraging Serilog for logging and MassTransit for message broker integration. It is configured to connect to MongoDB for persistence and RabbitMQ for messaging, with specific settings for batch processing (batch size 1000, processor frequency 5, max parallelism 5). The service also includes gRPC client configurations for interacting with the Catalog and Discount services, and is packaged with a Dockerfile for containerized deployment.
src/Services/Basket/Worker/Basket.Worker.Outbox · high confidence
Introduce CQRS command and query handlers for brand management, system seeding, and Keycloak user retrieval
This change adds the application-layer implementation for several new capabilities using the CQRS pattern. In the Catalog service, it introduces commands to create, update, and delete brands (including validation and persistence via Marten), a query to retrieve all brands, and a command to trigger initial data seeding. In the Notification service, it adds queries to retrieve all Keycloak users and to filter Keycloak users by role, delegating to the Keycloak service.
src/Services/Catalog/Core/Catalog.Application/Features/Brand, src/Services/Catalog/Core/Catalog.Application/Features/System, src/Services/Notification/Core/Notification.Application/Features/Keycloak · high confidence
Introduce Catalog Worker Outbox service with Docker support
A new background worker service for the Catalog domain has been added to handle outbox message processing. This service registers an OutboxProcessor and an OutboxBackgroundService, integrating with Serilog for logging, MassTransit for the message broker, and gRPC clients for Catalog and Discount services. Configuration is provided for both development and production environments, including connection strings for PostgreSQL, RabbitMQ, MinIO, and Keycloak authentication. A Dockerfile is included to containerize the .NET 8 application, enabling deployment via Docker.
src/Services/Catalog/Worker/Catalog.Woker.Outbox, src/Services/Catalog/Worker/Catalog.Worker.Consumer, src/Services/Inventory/Worker/Inventory.Worker.Consumer · high confidence
Introduce Communication.Api service with real-time SignalR notifications
A new Communication.Api service has been added to the platform, enabling real-time push notifications via ASP.NET Core SignalR. The service exposes a NotificationHub at /hubs/notifications, allowing clients to join user-specific groups for targeted messaging or receive broadcasts. It integrates with the existing event bus to listen for integration events (such as OrderCreated) and automatically pushes corresponding alerts to connected clients. The service is configured with standard infrastructure features including Serilog logging, distributed tracing, and health checks, and is containerized with a Dockerfile for deployment.
src/Services/Communication · high confidence
Introduce Order gRPC service with API key authentication and containerization
This change adds the Order gRPC API service, enabling order operations via a gRPC endpoint secured by an API key validation interceptor that checks requests against a configured key. The service includes dependency injection setup for gRPC, Serilog logging, and distributed tracing, along with a Dockerfile for containerized deployment and configuration files for development and production environments.
src/Services/Order/Api/Order.Grpc · high confidence
Introduce Search Worker Consumer service with background processing and infrastructure wiring
A new Search Worker Consumer service has been added to handle background search tasks. It includes a \SearchBackgroudService\ that runs as a hosted service, along with dependency injection setup for Serilog logging and a MassTransit message broker. The service is configured with development and production settings for ElasticSearch, RabbitMQ, MinIO, and Keycloak authentication, and includes a Dockerfile for containerized deployment.
src/Services/Search/Worker/Search.Worker.Consumer · high confidence
Introduce basket domain entities and value objects
This change introduces the core domain model for the basket service, adding the ShoppingCartEntity and ShoppingCartItemEntity to manage user cart items, quantities, and pricing, along with the OutboxMessageEntity to support reliable event publishing via the outbox pattern. It also adds the Money value object to enforce validation rules for currency amounts. These entities form the foundational data structures for basket operations within the domain layer.
src/Services/Basket/Core/Basket.Domain/Entities · high confidence
Introduce dedicated Outbox Worker for reliable event publishing
A new background worker service has been added to the Order service to implement the Outbox pattern, ensuring reliable event delivery to the message broker. This worker periodically polls the database for unprocessed messages and publishes them via MassTransit, supporting MySQL, PostgreSQL, and SQL Server through a pluggable provider architecture. It includes built-in retry logic with exponential backoff for failed publishes, configurable batch sizes and parallelism, and is packaged with a Dockerfile for containerized deployment.
src/Services/Order/Worker/Order.Woker.Outbox · high confidence
Introduction of Basket and Outbox persistence interfaces
The application layer now exposes dedicated repository interfaces for managing shopping cart data and implementing the outbox pattern. IBasketRepository provides methods to retrieve, store, and delete shopping carts for specific users, while IOutboxRepository introduces capabilities to add, update, claim, and release outbox messages, enabling reliable event publishing with retry and expiration handling.
src/Services/Basket/Core/Basket.Application/Repositories · high confidence
Introduction of Order-related Data Transfer Objects
New DTOs have been added to the Order application layer to support order creation and data representation. This includes \CreateOrUpdateOrderDto\ for submitting order details (basket, customer, shipping address, items, coupon, and notes), \CreateOrderItemDto\ for individual line items, \OrderDto\ for representing the full order state (including status, pricing, discounts, and reasons), and \OrderItemDto\ for item-level product and quantity data.
src/Services/Order/Core/Order.Application/Dtos/Orders · high confidence
Introduction of centralized configuration constants and Actor value object
This change introduces a new set of strongly-typed configuration classes in the shared common layer to standardize how application settings are defined. New files define constants for API clients (Catalog, Keycloak), gRPC clients (Catalog, Discount, Inventory, Order, Report), authentication (Keycloak/OAuth2), distributed tracing (Zipkin, OTLP, Prometheus), logging (Serilog), caching (Redis), messaging (Message Broker), storage (MinIO), search (ElasticSearch), notifications (Email, WhatsApp, Discord), and worker/outbox settings. Additionally, a new \Actor\ value object is added to the \Common.ValueObjects\ namespace, providing a structured way to represent different system actors (User, System, Job, Worker, Consumer) with specific formatting logic.
src/Shared/Common/Configurations · high confidence
Introduction of domain abstraction base classes and interfaces
The Notification service's domain layer now includes foundational abstractions to support domain-driven design patterns. This change introduces base classes for \Entity\ and \Aggregate\, providing standard identity management, audit tracking (creation and modification timestamps/users), and domain event handling capabilities. Corresponding interfaces (\IAggregate\, \IAuditable\, \IDomainEvent\, etc.) are added to define contracts for these behaviors, enabling consistent implementation across domain models.
src/Services/Notification/Core/Notification.Domain/Abstractions · high confidence
Introduction of generic repository interfaces for order domain entities
The order domain now exposes a set of new repository interfaces (IRepository, IOrderRepository, IInboxMessageRepository, IOutboxMessageRepository, and IOrderItemRepository) that define the data access contract for order-related entities. These interfaces provide standard CRUD operations via the generic IRepository base, along with specific query methods for orders (such as retrieving by ID with relationships, searching with pagination, and finding by order number) and inbox messages (retrieving by message ID). This change establishes the foundational abstraction layer for data persistence within the Order service.
src/Services/Order/Core/Order.Domain/Repositories · high confidence
Introduction of outbox message processing background service
A new background service has been added to handle the processing of outbox messages. This service runs in parallel with a configurable degree of parallelism and frequency, polling for and executing messages via the OutboxProcessor. It includes logging for iteration counts and total processed messages, and handles cancellation and errors gracefully.
src/Services/Catalog/Worker/Catalog.Woker.Outbox/BackgroundServices · high confidence
Introduction of shared API response and context models
This change introduces a new set of shared models in the \src/Shared/Common/Models\ directory to standardize API communication and user context handling. It adds a \UserContext\ class to encapsulate user identity and role information, a \PaginationRequest\ record for handling list queries, and an \ErrorResult\ class for structured error reporting. Furthermore, it defines a suite of generic API response wrappers (\ApiCreatedResponse\, \ApiDeletedResponse\, \ApiGetResponse\, \ApiPerformedResponse\, \ApiUpdatedResponse\) and a comprehensive \ResultSharedResponse\ class that unifies success/failure states with status codes and error lists. File upload capabilities are also supported via \UploadFileBytes\ and \UploadFileResult\ models.
src/Shared/Common/Models · high confidence
Inventory API and gRPC service scaffolding with reservation and stock management endpoints
The Inventory.Api project now exposes REST endpoints for managing inventory items, locations, and inventory history, including new capabilities to create, update, and delete inventory items and locations, adjust stock levels (increase/decrease), and view all inventory reservations. The Inventory.Grpc project provides a gRPC service that exposes an ExpireReservation operation, protected by an ApiKeyValidationInterceptor that enforces constant-time key comparison. Both services are configured for Docker deployment, use .NET 8.0, and integrate distributed tracing, Serilog logging, and health checks.
src/Services/Inventory/Api · high confidence
Inventory application layer scaffolding and reservation support
The Inventory.Application project has been initialized with a comprehensive set of application-layer components, including dependency injection configuration (MediatR, FluentValidation, AutoMapper, Feature Management), global usings, and a standard exception handler. This change introduces Data Transfer Objects (DTOs) and result models for managing inventory items, locations, and inventory history, alongside new DTOs and results specifically for inventory reservations (CreateReservationDto, ReservationDto). It also defines interfaces for external catalog communication (ICatalogApiService, ICatalogGrpcService) and establishes base abstractions for auditable and ID-based DTOs to standardize data contracts across the service.
src/Services/Inventory/Core/Inventory.Application · high confidence
Inventory domain model and infrastructure abstractions introduced
The Inventory service now includes a complete domain layer defining core entities (InventoryItem, InventoryReservation, Location, Inbox/Outbox messages) and value objects (Product). This change introduces domain-driven design patterns, including an Aggregate base class with domain event tracking, a Unit of Work abstraction with specific repository interfaces, and an Outbox pattern for reliable message publishing. Users benefit from structured inventory management capabilities such as stock tracking, reservation lifecycles (pending, committed, released, expired), and location-based inventory handling, all supported by auditable entity states and event-driven architecture.
src/Services/Catalog/Core/Catalog.Domain, src/Services/Inventory/Core/Inventory.Domain · high confidence
Inventory item management commands and queries
The Inventory service now exposes full CRUD capabilities for inventory items through new CQRS command and query handlers. Users can create, update, delete, and adjust stock levels of inventory items, with validation ensuring required fields like product ID, quantity, and location are present. The update logic handles location changes by merging stock if an item already exists at the new location. Additionally, domain events for stock changes, location moves, and deletions are now captured in the inventory history and pushed to the outbox for downstream integration.
src/Services/Inventory/Core/Inventory.Application/Features/InventoryItem · high confidence
Inventory service infrastructure scaffolding and initial database schema
This change introduces the foundational infrastructure for the Inventory service, including the initial Entity Framework Core migration that creates the database schema for inventory items, reservations, history, locations, and outbox/inbox message tables. It also adds the database context extension to seed initial location data (Hanoi, Da Nang, Ho Chi Minh City) and registers Refit HTTP clients for external integrations with Keycloak (authentication) and the Catalog service (product lookups).
src/Services/Inventory/Core/Inventory.Infrastructure · high confidence
New CQRS handlers for dashboard totals and chart data
The application now exposes new command and query handlers for managing dashboard totals, order growth line charts, and top product pie charts. Users can now update dashboard totals, order growth data (grouped by month and day), and top product metrics via dedicated commands, while retrieving current data through corresponding queries. These handlers implement validation for input data (e.g., non-negative values, required fields) and interact with repositories to persist changes or fetch mapped DTOs.
src/Services/Report/Core/Report.Application/Features/DashboardTotal, src/Services/Report/Core/Report.Application/Features/OrderGrowthLineChart, src/Services/Report/Core/Report.Application/Features/TopProductPieChart · high confidence
New Order API endpoints for creating, retrieving, and updating orders
The Order API now exposes a comprehensive set of endpoints for managing orders, including creating new orders, retrieving individual orders by ID or order number, listing orders with filtering and pagination, and updating order details or status. All endpoints are secured with authorization requirements and follow a consistent response pattern using specific API response wrappers.
src/Services/Order/Api/Order.Api/Endpoints · high confidence
New Outbox Worker Service for Reliable Event Publishing
A new background worker service has been introduced to implement the outbox pattern, ensuring reliable delivery of domain events. This service runs as a hosted background task that periodically polls the database for unprocessed messages, publishes them via MassTransit, and updates their status. It supports MySQL, PostgreSQL, and SQL Server through a pluggable provider architecture, handles message retries with exponential backoff, and is configured via standard appsettings files for both development and production environments.
src/Services/Inventory/Worker/Inventory.Worker.Outbox · high confidence
New Report gRPC service contract for dashboard and order metrics
A new gRPC service contract has been introduced for the Report module, defining a \ReportGrpc\ service with three RPC methods: \PutDashboardTotal\ for updating dashboard summary data, \PutOrderGrowthLineChart\ for submitting order growth line chart data, and \PutTopProductPieChart\ for submitting top product pie chart data. This change establishes the interface for these specific reporting endpoints.
src/Shared/Contracts/Report.Contract · high confidence
New Report gRPC service with API key authentication
A new gRPC API service for the Report domain has been introduced, exposing the \ReportGrpcService\. This service enforces API key validation via a custom interceptor that checks the \GrpcKey\ header against a configured value, using constant-time comparison to mitigate timing attacks. The service is configured for HTTP/2 transport, includes Serilog logging and Prometheus metrics, and supports distributed tracing via OTLP. A Dockerfile is provided to containerize the service, which connects to a MongoDB database.
src/Services/Report/Api/Report.Grpc · high confidence
New background job service for dashboard reports and inventory management
A new App.Job service has been introduced to handle scheduled background tasks using the Quartz scheduler. This service automatically synchronizes dashboard statistics every minute by aggregating data from the Order, Catalog, and Keycloak services (for user counts) and pushing the results to the Report service via gRPC. It also includes a job that runs every five minutes to expire pending inventory reservations. The implementation features a custom attribute-based job discovery mechanism, gRPC client interceptors for API key authentication, and a Refit client for Keycloak token management.
src/JobOrchestrator · high confidence
New coupon management API endpoints
The Discount API now exposes a comprehensive set of endpoints for managing coupons, including creating, updating, deleting, approving, and rejecting coupons, as well as retrieving them by ID, code, status, or type. These endpoints are defined in the new ApiRoutes constants and implemented via Carter modules, enabling administrators to perform full lifecycle operations on discount coupons.
src/Services/Discount/Api/Discount.Api/Endpoints · high confidence
New dashboard and order analytics endpoints
The Report API now exposes three new read-only endpoints for dashboard statistics: total dashboard metrics, order growth line chart data (accepting optional year and month filters), and a top products pie chart (with a configurable limit). All endpoints are secured via authorization and return structured API responses.
src/Services/Report/Api/Report.Api/Endpoints · high confidence
New data transfer objects for basket checkout and shopping cart operations
Added a set of new DTOs in the Basket.Application layer to support basket checkout and shopping cart workflows. This includes \BasketCheckoutDto\ (aggregating customer details, shipping address, and coupon code), \BasketCheckoutAddressDto\, \BasketCheckoutCustomerDto\, and \BasketCheckoutItemDto\ for structured checkout data. Additionally, \ShoppingCartDto\ and \ShoppingCartItemDto\ define the user-facing cart structure with item details like price and product slug, while \StoreShoppingCartDto\ and \StoreShoppingCartItemDto\ provide a simplified view for store-level operations.
src/Services/Basket/Core/Basket.Application/Dtos/Baskets · high confidence
New filter models for order and inventory queries
The application now includes dedicated filter models for querying orders and inventory items. Users can filter orders by search text, specific IDs, customer ID, status, and date ranges using the new GetAllOrdersFilter and GetOrdersFilter classes. A separate GetMyOrdersFilter allows users to filter their own orders by search text and date range. Additionally, a GetInventoryItemsFilter enables searching inventory items by text.
src/Services/Order/Core/Order.Application/Models/Filters · high confidence
New gRPC contract for order retrieval operations
A new Protocol Buffers definition has been added to define the Order gRPC service interface. This contract introduces the OrderGrpc service with two remote procedure calls: GetOrdersByMonth, which retrieves orders filtered by a specific year and month, and GetAllOrders, which retrieves the complete list of orders. The data model includes Order, OrderItem, and Product messages to structure the response payloads.
src/Shared/Contracts/Order.Contract · high confidence
New gRPC service for coupon application and evaluation
A new gRPC service implementation has been added to handle coupon-related operations. Users can now apply coupons to retrieve the coupon code and evaluate coupons to receive detailed discount calculations, including the discount amount, final amount, and original amount, via the standard gRPC interface.
src/Services/Discount/Api/Discount.Grpc/Services · high confidence
New gRPC service for report data updates
A new ReportGrpcService has been added to expose gRPC endpoints for updating dashboard totals, order growth line charts, and top product pie charts. This service acts as the RPC interface, receiving requests and dispatching corresponding MediatR commands to the application layer.
src/Services/Report/Api/Report.Grpc/Services · high confidence
New gRPC service for retrieving order data
A new OrderGrpcService has been added to the Order gRPC API, exposing two RPC methods: GetOrdersByMonth and GetAllOrders. These endpoints allow clients to retrieve order details, including items and product information, by delegating to existing MediatR queries within the application layer.
src/Services/Order/Api/Order.Grpc/Services · high confidence
New gRPC service implementation for catalog product queries
The Catalog.Grpc.Services layer now includes a concrete implementation of the Catalog gRPC service (CatalogGrpcService). This service exposes RPC methods to retrieve individual products by ID, list products with filtering, count total products, and retrieve all available products. It acts as the gRPC interface that delegates these requests to the underlying CQRS application layer via MediatR, mapping the query results to the appropriate gRPC response messages.
src/Services/Catalog/Api/Catalog.Grpc/Services · high confidence
New order application DTOs for address, customer, discount, and product data
The order service now exposes dedicated Data Transfer Objects in the application layer to represent core order entities. New value objects have been added for Address (including line, city, state, country, and postal code), Customer (with ID, phone, name, and email), and Discount (coupon code and amount). Additionally, the previous Subscription entity from the Agent service has been renamed and refactored into a ProductDto, shifting its identity from a long-based Entity to a Guid-based DtoId and updating its properties to include name, image URL, and price.
src/Services/Order/Core/Order.Application/Dtos/ValueObjects · high confidence
New order management API endpoints and status update model
The Order API now exposes a comprehensive set of endpoints for managing orders, including creation, updates, and retrieval for both administrators and current users. Specific routes are defined for admin operations (create, update, get all, get by ID, update status) and user-specific operations (get orders by order number, get current user's orders, get all current user's orders, get current user's order by ID). Additionally, a new \UpdateOrderStatusRequest\ model has been introduced to support the order status update functionality, accepting a status enum and an optional reason.
src/Services/Order/Api/Order.Api/Constants · high confidence
Notification application logic implemented via CQRS commands and queries
The notification service now exposes application-layer capabilities through a CQRS structure, introducing specific handlers for managing deliveries and user notifications. For deliveries, the system can now create new delivery records (handling template rendering and duplicate checks), process them (resolving senders, updating status, and handling failures), and retrieve due deliveries for batch processing. For user notifications, the service supports marking notifications as read, retrieving paginated or full lists of notifications, and fetching unread counts or the top 10 unread items, with data mapping handled via AutoMapper.
src/Services/Notification/Core/Notification.Application/Features/Notification · high confidence
Notification service infrastructure initializes MongoDB and integrates Discord, Email, and Keycloak channels
The Notification service now includes its infrastructure layer, which sets up a MongoDB database with pre-seeded notification templates and required indexes on startup. It registers dependency injection for repositories and external API clients, enabling notifications to be delivered via Discord webhooks, SMTP email, and in-app storage. Additionally, a Keycloak service integration allows the system to fetch user lists and role-based user groups for targeted notifications.
src/Services/Notification/Core/Notification.Infrastructure · high confidence
Order and Product management commands and queries implemented
The Order service now supports full order lifecycle management through new CQRS commands and queries: customers can create and update orders (including validation for customer details, shipping addresses, and items, plus coupon application), update order statuses (cancel, refund, deliver), and retrieve orders via various filters (by ID, order number, date range, or monthly reports). Domain events for order creation, cancellation, and delivery are now handled by outbox event handlers to ensure reliable integration messaging. In the Search service, product indexing is managed via commands to upsert and delete products in Elasticsearch, alongside a query to search products with pagination and filtering.
src/Services/Order/Core/Order.Application/Features/Order, src/Services/Search/Core/Search.Application/Features/Product · high confidence
Order service database schema and persistence configuration
The Order Infrastructure layer now defines the database schema for the new Order service, including tables for orders, order items, inbox messages, and outbox messages. The schema supports complex properties for customer details, shipping addresses, and discounts, and includes migration scripts to initialize the database and update address fields. The outbox and inbox message tables are configured with retry logic (max attempts, next attempt timestamp) to support reliable event-driven communication.
src/Services/Order/Core/Order.Infrastructure · high confidence
Order worker now handles basket checkout and inventory reservation expiration events
The order worker consumer now processes two new integration events to improve order lifecycle management. When a customer completes checkout, the new BasketCheckoutIntegrationEventHandler consumes the event, validates idempotency via an inbox mechanism, and triggers the creation or update of an order. Additionally, the new ReservationExpiredIntegrationEventHandler listens for inventory reservation expirations; upon receiving such an event, it automatically cancels the associated order to prevent inventory discrepancies. Both handlers ensure reliable processing by tracking message state and handling failures gracefully.
src/Services/Order/Worker/Order.Worker.Consumer/EventHandlers · high confidence
Outbox message persistence and claim management implemented
The Catalog Infrastructure layer now includes an OutboxRepository that handles storing, claiming, and releasing outbox messages using Marten. This enables reliable event sourcing by allowing the system to batch-process unprocessed messages, manage claim timeouts to prevent duplicate processing, and handle retry logic for failed messages, ensuring eventual consistency in the catalog service.
src/Services/Catalog/Core/Catalog.Infrastructure/Repositories · high confidence
Outbox processor implementation for reliable message publishing
The basket worker now includes an outbox processor that reliably publishes domain events by fetching and claiming messages from the outbox storage. It processes messages in configurable batches, deserializes content based on event types, and publishes them via MassTransit. The processor handles success, retry, and permanent failure scenarios, updating message status and tracking attempt counts to ensure eventual delivery or proper error logging.
src/Services/Basket/Worker/Basket.Worker.Outbox/Processors · high confidence
Outbox processor with retry and bulk update logic
The catalog worker now includes an OutboxProcessor that retrieves and claims messages from the outbox, publishes them via MassTransit, and handles failures by either marking messages as permanently failed or scheduling them for retry. Processed messages are updated in bulk using a new OutboxUpdate struct, ensuring efficient state management and reliable message delivery.
src/Services/Catalog/Worker/Catalog.Woker.Outbox/Processors, src/Services/Catalog/Worker/Catalog.Woker.Outbox/Structs · high confidence
Report service infrastructure: MongoDB persistence, Keycloak integration, and gRPC client wiring
The Report service now includes its infrastructure layer, enabling it to store and retrieve report data in MongoDB and integrate with external identity and catalog services. MongoDB support is provided via repositories for DashboardTotal, OrderGrowthLineChart, and TopProductPieChart entities, along with DI registration, index creation, and initial seeding of dashboard totals. Keycloak integration is introduced through an IKeycloakApi client (using Refit) for obtaining access tokens and querying users/roles. A gRPC client for the Catalog service is registered with an API-key interceptor, and the infrastructure module exposes DI and database-initialization extension methods for the application to consume.
src/Services/Report/Core/Report.Infrastructure · high confidence
Removals
Removal of Agent Service initial codebase and configuration
The initial implementation of the Agent service has been removed, deleting the entire codebase including API endpoints (AccountProfile, Agent, Keycloak), CQRS handlers, domain entities (Agent, KeycloakUser, AccountProfile, ChatThread, etc.), database configurations, and the initial PostgreSQL migration. This also removes the associated development and production configuration files (appsettings.json), effectively stripping the service of its current functionality and data access layer.
src/Services/Agent · high confidence
Removal of Keycloak API client and infrastructure dependency injection
The User Infrastructure layer has removed the \IKeycloakApi\ interface and its associated Refit HTTP client configuration, along with the \DependencyInjection.cs\ file that registered these services. This eliminates the direct dependency on Keycloak for user management operations (such as token retrieval, user CRUD, and role/group assignments) within this service, effectively decoupling the user service from the Keycloak identity provider at the infrastructure level.
src/Services/User/Infrastructure · high confidence
Removal of Keycloak and MinIO cloud storage service implementations
The KeycloakService and MinIOCloudService classes have been removed from the user infrastructure layer. This eliminates the existing (though partially unimplemented) integration with Keycloak for user management and the MinIO-based cloud storage capabilities for uploading, downloading, and generating share links for files.
src/Services/User/Infrastructure/Services · high confidence
Removal of User Service Application and Domain layers
The application and domain logic for the User service has been removed, deleting all CQRS handlers, domain entities, and related infrastructure. This includes the removal of account profile queries, agent creation and listing commands, and Keycloak user registration commands. The underlying domain model (AccountProfile, Agent, KeycloakUser, ChatThread, ChatHistory, Coupon, etc.) and their associated domain events have been deleted, along with the database context interfaces (IReadDbContext, IWriteDbContext) and DTOs. This effectively strips the service of its ability to manage user profiles, agents, subscriptions, and chat interactions.
src/Services/User/Application · high confidence
Removal of User Service database configuration and migrations
The Entity Framework Core configuration files, database migrations, and initialization extensions for the User service have been deleted. This removes the infrastructure code responsible for mapping entities such as AccountProfile, Agent, ChatThread, and Subscription to the PostgreSQL database, effectively stripping the data persistence layer for this service.
src/Services/User/Infrastructure/Data · high confidence
Removal of legacy User API endpoints and configuration
The User API service has removed several endpoint implementations, including those for account profiles, agents, user retrieval, and Keycloak event handling, along with the development configuration file. This change eliminates the HTTP routes previously exposed by these components, effectively removing this functionality from the service's public interface.
src/Services/User/API · high confidence
Removal of shared building blocks and common utilities
This change removes a large set of shared infrastructure and utility components from the \src/SharedProjects\ directory. Specifically, it deletes the \LogServer\ logging extension, the \Pagination\ request record, and the entire \SourceCommon\ library, which included configuration options (e.g., \AppConfigOptions\, \AuthorizationOptions\, \LogServerOptions\), extension methods (e.g., \StringExtension\, \HashExtension\, \QueryableExtension\), helper classes (e.g., \ExportExcelHelper\), and model classes (e.g., \ResultSharedResponse\, \UserIdentity\). This effectively strips out the shared logging, configuration, data transformation, and response wrapping capabilities previously provided by this location.
src/SharedProjects · high confidence
Behavioural changes
2 commits (0 fixes) modifying src/Apps
A change to existing behaviour in src/Apps — 2 commits, 1 file.
src/Apps · medium confidence · unverified
API Gateway expands service routing, adds health checks, and enables containerization
The YARP API Gateway now supports a broader set of backend services, replacing the previous agent and payment routes with dedicated routes and clusters for basket, catalog, discount, inventory, notification, order, report, search, and communication services. To support real-time features, CORS configuration has been updated to allow credentials, enabling SignalR to send cookies and tokens. Operational visibility is improved with the addition of a /health endpoint that integrates with the HealthChecks UI, and a root endpoint providing service status and environment details. Additionally, a Dockerfile has been added to containerize the gateway, exposing port 8080.
src/ApiGateway/YarpApiGateway · high confidence
Add global using directives to domain services
The Basket, Notification, and Order domain services now include GlobalUsing.cs files to register common namespaces. Specifically, the Basket and Order domains automatically import Common.Constants, while the Order domain additionally imports Common.Models, reducing the need for explicit using statements in individual source files.
src/Services/Basket/Core/Basket.Domain, src/Services/Notification/Core/Notification.Domain, src/Services/Order/Core/Order.Domain · high confidence
Basket and Catalog services adopt CQRS with MediatR and outbox-based event publishing
The Basket and Catalog application layers have been restructured to use the Command Query Responsibility Segregation (CQRS) pattern, with all business logic now implemented as MediatR commands and queries under the \Features\ namespace. Basket operations (checkout, store, delete, get) and Catalog operations (CRUD for categories and products, status changes, tree retrieval) are now handled by dedicated command/query handlers that validate input and interact with repositories or the Marten document session. A key behavioral change is the introduction of an outbox pattern for domain events: when a product is created, updated, unpublished, or a basket is checked out, the system publishes a domain event that is immediately persisted to an outbox table via \OutboxMessageEntity\, ensuring reliable delivery of integration events (such as \BasketCheckoutIntegrationEvent\ or \UpsertedProductIntegrationEvent\) to downstream services.
(repo-wide) · high confidence
Basket domain introduces base abstractions for entities and aggregates
The Basket service now includes a set of domain abstractions in the \Basket.Domain.Abstractions\ namespace to standardize entity structure and auditing. New files define \Entity\<T\>\ and \EntityId\<T\>\ as base classes with MongoDB serialization attributes, while interfaces \IAuditable\, \ICreationAuditable\, and \IModificationAuditable\ enforce creation and modification tracking properties. The \Aggregate\<TId\>\ class and \IAggregate\ interface have been moved from the Agent service and adapted to the Basket namespace, adding domain event management capabilities. Additionally, \IDomainEvent\ is updated to use \DateTimeOffset\ for the \OccurredOn\ property, and \IEntityId\<T\>\ is introduced to standardize identity definitions.
src/Services/Basket/Core/Basket.Domain/Abstractions · high confidence
Centralized application constants and configuration values
The constants previously scattered across the legacy \SourceCommon\ project have been consolidated into the new \src/Shared/Common/Constants\ directory. This change introduces dedicated files for service names (such as basket, catalog, and order), supported database types (including SQL Server, PostgreSQL, and MongoDB), and standardized message codes for validation and error handling. Additionally, authorization roles and required gRPC header names have been updated and moved to this shared location to ensure consistent configuration across the microservices.
src/Shared/Common/Constants · high confidence
Defined API route constants for report statistics endpoints
The application now centralizes the URL paths for report statistics endpoints within a dedicated constants class. This change introduces specific route definitions for retrieving dashboard statistics, order growth statistics, and top product statistics under the /admin prefix, ensuring consistent path usage across the report service API.
src/Services/Report/Api/Report.Api/Constants · high confidence
Expanded observability stack with distributed tracing and log aggregation
The configuration now supports a full distributed tracing and logging pipeline. The OpenTelemetry Collector has been reconfigured to export traces to Tempo and logs to Loki, replacing previous debug and Zipkin exporters. Tempo and Loki services have been added with their respective configurations, and Grafana has been provisioned with a Tempo datasource to enable trace-to-log correlation. Additionally, Prometheus has been updated to scrape metrics from the new Tempo and Loki endpoints, and Elasticsearch disk watermark settings are now automatically configured on startup.
config · high confidence
Introduce dedicated notification worker services for message consumption and delivery processing
The notification service is now split into two distinct background workers: the Consumer and the Processor. The Consumer (Notification.Worker.Consumer) handles incoming message broker events and exposes a hosted service (NotificationBackgroundService), while the Processor (Notification.Worker.Processor) periodically queries for due deliveries and executes them via the application's command/query handlers. Both workers are configured with their own dependency injection, Serilog logging, and environment-specific settings (appsettings.json / appsettings.Development.json) for MongoDB, RabbitMQ, and authentication, and are containerized via dedicated Dockerfiles targeting .NET 8.0.
src/Services/Notification/Worker/Notification.Worker.Processor · high confidence
Introduces dedicated result models for order queries
The Order application layer now uses specific result classes (e.g., GetAllMyOrdersResult, GetMyOrdersResult) to structure query responses. These models wrap OrderDto collections and, for paginated endpoints, include PagingResult metadata, replacing previous ad-hoc return types with a consistent, strongly-typed contract for order retrieval operations.
src/Services/Order/Core/Order.Application/Models/Results · high confidence
Introduction of API key validation and foundational application abstractions
The Catalog gRPC service now enforces API key authentication via a new interceptor that validates incoming requests against a configured key using constant-time comparison to prevent timing attacks. Additionally, the Order and Notification services introduce foundational application-layer abstractions, including auditable DTOs with creation and modification tracking, generic ID wrappers, and standard exception classes. The Notification service also replaces the previous Keycloak user management interface with a template rendering provider, shifting its focus to content generation.
(repo-wide) · high confidence
Introduction of domain abstractions and unit of work pattern
The Order.Domain.Abstractions layer now provides foundational domain building blocks, including base classes for Entity and Aggregate root that handle unique identifiers, creation/modification auditing, and domain event management. Additionally, a Unit of Work interface (IUnitOfWork) has been introduced to centralize repository access (Orders, OrderItems, Inbox/Outbox messages) and manage database transactions and persistence across multiple repositories.
src/Services/Order/Core/Order.Domain/Abstractions · high confidence
Introduction of strategy pattern for notification sending
The notification application now uses a strategy pattern to handle different notification channels. A new \INotificationSender\ interface defines the contract for sending notifications via specific channels, while \INotificationSenderResolver\ (renamed from \CustomValidators\) provides a mechanism to resolve the appropriate sender implementation based on the channel type. This replaces the previous validation-focused code in this location with a dedicated infrastructure for dispatching notifications.
src/Services/Notification/Core/Notification.Application/Strategy · high confidence
Inventory application features now use Unit of Work for data persistence
The application layer for Inventory Item History, Inventory Reservations, and Locations has been refactored to use the Unit of Work pattern. All command and query handlers in these features now rely on the IUnitOfWork abstraction to manage database transactions, ensuring that operations like committing or expiring reservations, creating locations, and retrieving history are persisted atomically. This change standardizes how data access is handled across these features, replacing previous direct persistence mechanisms with a unified transactional boundary.
src/Services/Inventory/Core/Inventory.Application/Features/InventoryItemHistory, src/Services/Inventory/Core/Inventory.Application/Features/InventoryReservation, src/Services/Inventory/Core/Inventory.Application/Features/Location · high confidence
Inventory worker now handles order lifecycle events with idempotency and unit of work
The inventory consumer now processes OrderCreated, OrderCancelled, and OrderDelivered integration events to manage inventory reservations throughout the order lifecycle. On order creation, it reserves stock by fetching product details from the catalog service and sending reservation commands, ensuring idempotency via an inbox pattern and using a unit of work for transactional consistency. On order cancellation, it releases previously reserved inventory, and on delivery, it commits the reservations. All handlers track message processing status to prevent duplicate execution.
src/Services/Inventory/Worker/Inventory.Worker.Consumer/EventHandlers · high confidence
MongoDB index configuration for basket and outbox collections
The Basket service now automatically creates specific MongoDB indexes on startup to optimize data retrieval and outbox message processing. For the shopping cart collection, a unique index is created on the user ID to ensure data integrity. For the outbox message collection, multiple indexes are established to support efficient querying by occurrence time, event type, and processing status, as well as compound indexes to optimize the selection of unprocessed/unclaimed messages and retry eligibility based on attempt counts and timestamps.
src/Services/Basket/Core/Basket.Infrastructure/Data · high confidence
New integration events and refactored event base with updated message broker configuration
The EventSourcing module now includes a comprehensive set of new integration events for Basket, Catalog, Inventory, and Order domains, enabling detailed tracking of product upserts, stock changes, reservation expirations, and the full order lifecycle (creation, delivery, cancellation). The base IntegrationEvent record has been simplified, removing audit fields (Created/Modified by/on) and switching the timestamp to DateTimeOffset. Additionally, the MassTransit message broker extension has been refactored to read configuration directly via keys rather than a dedicated options object, and the assembly reference has been moved to the new EventSourcing namespace.
src/Shared/EventSourcing · high confidence
Refactor shared common library structure and add new utility types
The shared common library has been reorganized: the ExportExcelAttribute and EnumHelper classes have been moved from the SourceCommon namespace to the Common namespace, and the ExportExcelAttribute file was renamed to reflect this structural change. Additionally, two new files were introduced: ApplicationStatus, an enum defining lifecycle states for applications (Draft, Awaiting Approval, Approved, Rejected, Expired, Active, Inactive), and NumericHelper, a static utility class providing a method to calculate discount percentages based on original and sale prices.
src/Shared/Common/Attributes, src/Shared/Common/Enums, src/Shared/Common/Helpers · high confidence
Refactored Swagger configuration to use direct configuration keys and added multipart form support
The Swagger building block now reads OpenID Connect and application settings directly from the configuration provider using specific key paths (e.g., \AuthorizationCfg:Authority\) instead of strongly-typed options classes, and includes contact details in the API documentation. Additionally, a new \WithMultipartForm\ extension method allows endpoints to automatically generate correct OpenAPI schemas for \multipart/form-data\ requests, including support for file uploads and complex nested types.
src/Shared/BuildingBlocks/Swagger · high confidence
Refactored authentication extension methods and user context model
The authentication building block has been refactored to simplify configuration and improve user context handling. The \AddAuthorizationServerAuthentication\ extension method has been renamed to \AddAuthenticationAndAuthorization\ and now reads configuration values directly from the \IConfiguration\ interface using the \AuthorizationCfg\ keys, replacing the previous strongly-typed \AuthorizationOptions\ model binding. Additionally, the user identity extraction logic has been moved from \UserIdentityExtension\ to \UserContextExtension\, and the returned model has changed from \UserIdentity\ to \UserContext\, with the roles extraction logic reordered for clarity.
src/Shared/BuildingBlocks/Authentication · high confidence
Refactored distributed tracing and logging configuration
The distributed tracing and logging infrastructure has been restructured to improve configurability and reduce noise. The \DistributedTracingExtension\ now reads settings directly from configuration rather than relying on a strongly-typed options class, and it removes the deprecated Zipkin exporter in favor of an OpenTelemetry (OTLP) exporter with configurable timeouts. Tracing behavior has changed to filter out health, metrics, and favicon requests, and metrics now use explicit bucket histograms for HTTP duration. Additionally, a new \ActivityTraceEnricher\ ensures that \trace\_id\ and \span\_id\ are automatically attached to Serilog log events, and request logging is configured to exclude debug-level entries for health and metrics endpoints.
src/Shared/BuildingBlocks/Logging · high confidence
Refactored exception handling and building blocks structure
The exception handling system in the shared building blocks has been significantly refactored to support richer error details and more granular control. New exception types, ClientValidationException and UnauthorizedException, have been added alongside a renamed NoPermissionException, all now carrying an optional 'Details' object instead of a string. The CustomExceptionHandler has been updated to use configuration settings for including inner exceptions and stack traces, and it now maps these specific exception types to appropriate HTTP status codes and error messages. Additionally, several core classes (LoggingBehavior, ValidationBehavior, InternalServerException, NotFoundException) have been made sealed, and the entire set of files has been moved from the 'SharedProjects' directory to 'Shared'.
src/Shared/BuildingBlocks/Exceptions · high confidence
Refined pagination result models and added phone number validation
The pagination infrastructure has been updated to provide more flexible and robust result handling. The \PaginatedResult\<T\>\ class now exposes items as an \IEnumerable\<T\>\ instead of a \List\<T\>\, allowing consumers to handle various collection types without forcing a specific list implementation. A new \PagingResult\ class has been introduced to offer detailed pagination metadata, including total page counts and next/previous page availability flags, which aids in building complete pagination UIs. Additionally, a new \CustomValidators\ utility has been added to the shared building blocks, providing a fluent validation extension for phone numbers that supports international formats and standardizes input cleaning.
src/Shared/BuildingBlocks/Pagination · high confidence
Stock change events now update product availability status
The worker consumer now includes a handler for StockChangedIntegrationEvent that automatically updates product status in the catalog. When stock amount is greater than zero, the product is marked as InStock; when the amount is zero or less, it is marked as OutOfStock. This ensures the catalog reflects real-time inventory changes received via integration events.
src/Services/Catalog/Worker/Catalog.Worker.Consumer/EventHandlers · high confidence
Switch mapping library to AutoMapper and update dependency injection
The Order application now uses AutoMapper for object mapping instead of the previous library, introducing a new OrderMappingProfile that defines mappings between domain entities (Order, OrderItem, Customer, Address, Discount, Product) and their corresponding DTOs. The dependency injection setup has been updated to register AutoMapper and remove the message broker integration, while also adding global using directives to simplify imports across the application layer.
src/Services/Order/Core/Order.Application · high confidence
Dependencies
Centralized dependency management and initial service scaffolding
The project introduces centralized package version management via a new Directory.Packages.props file, establishing baseline versions for core libraries including .NET 8, Entity Framework Core 8, AutoMapper 12, MediatR 12, and gRPC components. This change accompanies the initial creation of .csproj files for multiple microservices (Basket, Catalog, Discount, Inventory, Notification, Order) and the Job Orchestrator, defining their specific dependencies on shared building blocks, health checks, and database drivers.
(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
Baseline
- First survey — no prior run to compare against. CAI 29.
Lenses
- Code Health 44
- Architecture 89
- Maturity 69
- Readiness 16
- Security 26
- Domain Modelling 63
- Event-Driven 77
- Accessibility 44
- Performance 60
Changes since last survey
- 156 commits — 147 feature/other, 9 fixes
By area
- src/Services — 83 commits
- (root) — 29 commits
- src/Apps — 26 commits
- assets/imgs — 6 commits
- .github/workflows — 5 commits
- .github/CODE_OF_CONDUCT.md — 1 commit
- .github/FUNDING.yml — 1 commit
- .github/ISSUE_TEMPLATE — 1 commit
- assets/postman collections — 1 commit
- src/ApiGateway — 1 commit
- src/JobOrchestrator — 1 commit
- src/Shared — 1 commit
Notable commits
- fix: chore(App.Admin): fix build
- fix: chore(App.Store): fix build
- fix: chore: fix build
- fix: chore: fix github actions
- fix: chore: fix github docs
- fix: chore: fix grpc key
- fix: chore: fix project link and improve image description
- fix: chore: fix sso
- fix: fix: swagger issues
- change: Refactor Docker workflow for building and pushing images
- change: chore(App.Admin): update package-log
- change: chore(Notificaiton): add comments
- change: chore: add & update md files
- change: chore: add Makefile, move migration scripts into scripts/, clean up stale docs
- change: chore: add app job and update admin ui
- change: chore: add basket apis
- change: chore: add i18n to admin fe
- change: chore: add init catalog data
- change: chore: add keycloak authen for fe
- change: chore: add postman collection
- …and 136 more
API surface
- 1 HTTP endpoints (baseline)
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
Survey your own repository
huynxtb/progcoder-shop-microservices 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 ec2480af255f0e39a4577dddd508fced93ab5923 — 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-fa71c66cabd8.