Skip to content

Features

Product aggregate

IProduct / ProductEntity owns (NHibernate cascade from ProductEntityMap):

  • IEdition / EditionEntity - product tier (EditionStatusEnumeration: Draft/Published/Deprecated/Retired)
  • IEditionFeature / EditionFeatureEntity - composite key EditionFeatureKey (editionId + featureId)
  • IEditionSla / EditionSlaEntity, IEditionPricing / EditionPricingEntity, IEditionBusinessModel / EditionBusinessModelEntity
  • IServiceLevelAgreement / ServiceLevelAgreementEntity

ProductStatusEnumeration: Draft/Active/Deprecated/Retired.

Peer catalog entities (separate aggregates/repos)

  • IFeature / FeatureEntity
  • IPricingModel / PricingModelEntity (PricingModelKindEnumeration)
  • IBusinessModel / BusinessModelEntity (BusinessModelKindEnumeration)

Value objects

UsageLimit (+ UsageWindowEnumeration: PerRequest/PerMinute/PerHour/PerDay/PerMonth/PerBillingCycle), BillingRule, AccessRule (+ AccessModeEnumeration, ProrationKindEnumeration).

Published events (publish-only, ADR-0003)

Event Topic
ProductCreatedEvent catalog.domain.v1.product-created
ProductUpdatedEvent catalog.domain.v1.product-updated
ProductRetiredEvent catalog.domain.v1.product-retired
EditionAddedEvent catalog.domain.v1.edition-added
EditionUpdatedEvent catalog.domain.v1.edition-updated
FeatureActivatedEvent catalog.domain.v1.feature-activated
FeatureDeactivatedEvent catalog.domain.v1.feature-deactivated
EntitlementsChangedEvent catalog.entitlements.v1.entitlements-changed

No IConsumer implementations and no sagas - this context is a pure source of catalog truth. EntitlementsChangedEvent is a downstream hook for Entitlements/Metering.

Orleans

ProductEditorGrain (IProductEditorGrain : IProductEditorActor) keyed {tenantId}/{productId} (KeySeparator = "/") serializes writes to one product; stateless - delegates to IProductsProcessor.

See also