Skip to content

Architecture

Metering is a Layer 3 host on the Base Template layering (template layering and reuse). Layer suffixes are described in solution structure.

Service contracts

Contract gRPC adapter REST
IUsageMeterManagementService GrpcUsageMeterManagementService UsageMetersController @ api/usage-meters
IUsageMeterQueryService GrpcUsageMeterQueryService same controller

REST routes (POST, command/query style): queries/by-tenant-dimension, queries/by-id, commands/record-usage, commands/roll-counter, commands/ensure-provisioned, commands/apply-quota. Management operations: RecordUsageAsync, RollCounterAsync, EnsureProvisionedAsync, ApplyQuotaAsync.

Messaging (publish + consume)

Publishes four events (metering.usage.v1.*, metering.counters.v1.*, metering.quota.v1.*) and consumes three inbound topics via sagas (tenant activation, subscription created, entitlements changed). Sagas are registered in MassTransitExtensions.cs with in-memory repositories. One additional saga (UsageMeterQuotaEnforcementStateMachine) exists but its inbound topic is not wired (see features).

Persistence (single table)

NHibernate + Fluent mapping on UsageMeterEntityMap; schema ConnectSoft.Saas.Metering; single table UsageMeters with unique index UQ_UsageMeters_Tenant_Dimension on (TenantId, Dimension). Shipped dialect SQL Server; connection string ConnectSoft.Saas.Metering. MicroserviceMigration seeds one row via SampleMeteringSeed. Multitenancy via shared SaasTenantFilter (tenantId). Repository: IUsageMetersRepository / UsageMetersRepository (+ keyed variant).

Concurrency

UsageMeterGrain keyed {tenantId}:{dimension} serializes increments per meter.

See also