Architecture¶
Products Catalog is a Layer 3 host on the Base Template layering (template layering and reuse). Layer suffixes are described in solution structure.
Service contracts (five surfaces)¶
Code-first ServiceModel.Grpc contracts (no .proto):
| Contract | gRPC adapter | REST controller | Route prefix |
|---|---|---|---|
IProductManagementService |
GrpcProductManagementService |
ProductsController |
api/products-catalog |
IProductQueryService |
GrpcProductQueryService |
ProductsController |
same |
IFeatureCatalogService |
GrpcFeatureCatalogService |
FeaturesController |
api/products-catalog/features |
IPricingModelCatalogService |
GrpcPricingModelCatalogService |
PricingModelsController |
api/products-catalog/pricing-models |
IBusinessModelCatalogService |
GrpcBusinessModelCatalogService |
BusinessModelsController |
api/products-catalog/business-models |
REST endpoints on ProductsController: POST products, PUT products/{productId}, POST products/{productId}/retire, POST products/{productId}/editions, PUT editions/{editionId}, POST editions/{editionId}/features/{featureId}/activate|deactivate, GET products/{productId}, GET products, GET editions/{editionId}.
Messaging¶
Publish-only (ADR-0003): eight events published from DefaultProductsProcessor via IEventBus.PublishEvent; topology CatalogMassTransitTopology.ConfigureIntegrationEventPublishTopology. No consumers or sagas.
Persistence (10-table schema)¶
NHibernate + Fluent mappings; schema ConnectSoft.Saas.ProductsCatalog; FluentMigrator MicroserviceMigration. Tables: Products, Editions, Features, EditionFeatures, PricingModels, BusinessModels, ServiceLevelAgreements, EditionSlas, EditionPricings, EditionBusinessModels.
Key constraints: UQ_Products_TenantId_Slug (slug unique per tenant), UQ_Editions_ProductId_Code (edition code unique per product), tenant indexes. Multitenancy via shared SaasTenantFilter (tenantId) on entity maps. Repositories: IProductsRepository, IFeaturesRepository, IPricingModelsRepository, IBusinessModelsRepository (+ keyed variants).
Shipped dialect is SQL Server; docs/Testing.md references PostgreSQL for some persistence-spec tests (dialect is config-driven).
Concurrency¶
ProductEditorGrain keyed {tenantId}/{productId} serializes writes per product.