Architecture¶
Entitlements is a Layer 3 host on the Base Template layering (template layering and reuse). Layer suffixes are described in solution structure.
Service contracts¶
Code-first contracts in ConnectSoft.Saas.Entitlements.ServiceModel (namespace ConnectSoft.Saas.Entitlements.servicemodel/2025/entitlements/):
| Contract | gRPC adapter |
|---|---|
IEntitlementManagementService |
GrpcEntitlementManagementService |
IEntitlementQueryService |
GrpcEntitlementQueryService |
REST surface (EntitlementsController, api/entitlements)¶
| HTTP | Route | Operation |
|---|---|---|
| POST | /draft |
CreateDraftAsync |
| PUT | /activate |
ActivateAsync |
| POST | /assign-edition |
AssignEditionAsync |
| PUT | /feature-override |
OverrideFeatureAsync |
| POST | /queries/by-tenant |
GetEntitlementForTenantAsync |
| POST | /queries/by-id |
GetEntitlementByIdAsync |
DTOs: EntitlementDto (nested EntitlementAssignmentDto, TenantFeatureOverrideDto), EntitlementResponse, request types.
Messaging¶
Publishes three entitlements.v1.* events and consumes Products Catalog events from the NuGet ConnectSoft.Saas.ProductsCatalog.MessagingModel. ProductRetiredEvent is handled by ProductCatalogReactionStateMachine; ProductCreated/Updated are topology-mapped only. Inbound topics via EntitlementsConstants.CatalogInboundEventTopics.
Persistence (3-table schema)¶
NHibernate + Fluent mappings (EntitlementEntityMap, EntitlementAssignmentEntityMap, TenantFeatureOverrideEntityMap); schema ConnectSoft.Saas.Entitlements. Tables:
| Table | Notes |
|---|---|
Entitlements |
TenantId UNIQUE - one entitlement per tenant |
EntitlementAssignments |
FK -> Entitlements (cascade); indexes on TenantId, EntitlementId, ProductId |
TenantFeatureOverrides |
FK -> Entitlements; UNIQUE (EntitlementId, FeatureKey) |
All maps apply SaasTenantFilter on TenantId. SampleEntitlementSeed seeds an entitlement + assignment + feature override referencing sample catalog GUIDs.
Concurrency¶
EntitlementEditorGrain (keyed by tenant id) serializes writes per tenant.