Skip to content
This repository was archived by the owner on Aug 11, 2026. It is now read-only.
This repository was archived by the owner on Aug 11, 2026. It is now read-only.

feat(usage-metering): add idempotent usage events, aggregation, quotas, corrections, and reconciliation #875

Description

@ahliweb

Parent epic: #868
Depends on: #869, #871, #874

Context

SaaS quotas and usage-based billing require a trustworthy metering foundation. Directly incrementing counters inside feature transactions would create coupling, contention, duplicate-count risks, and weak auditability. Usage must be tenant-aware, versioned, idempotent, privacy-minimized, and reconcilable.

Objective

Implement a provider-neutral usage_metering capability for accepting reviewed meter events, deduplicating them, aggregating usage windows, enforcing quota decisions, applying corrections, and reconciling source versus aggregate results.

Scope

  • Add admitted module/extension descriptor, permissions, jobs, events, lifecycle descriptors, and admin navigation.
  • Add schemas for:
    • immutable usage events;
    • producer/idempotency identity;
    • event timestamp and received timestamp;
    • quantity/value with safe exact representation;
    • dimensions allowed by the meter descriptor;
    • aggregation windows and checkpoints;
    • corrections/reversals linked to original events;
    • reconciliation runs/results.
  • Provide a transaction-safe append port so owning modules can emit usage records in the same commit through the domain-event/outbox pattern.
  • Add asynchronous aggregation workers with lease, checkpoint, bounded batch, retry, replay, and idempotent rebuild.
  • Support meter semantics from feat(saas-contracts): add static feature, quota, meter, and commercial-event registries with conformance gates #874: sum, max, last-value, distinct-count only where safe and explicitly admitted.
  • Expose effective usage and quota decision APIs to feat(tenant-entitlement): compute and enforce effective features, modules, quotas, and overrides #871.
  • Support late/out-of-order events and documented window-closing rules.
  • Add correction/reversal commands; never mutate immutable source events.
  • Add data-lifecycle policy, partitioning guidance, archive/purge, legal hold, and metrics.
  • Add operator UI for usage timeline, aggregate freshness, correction, and reconciliation.

Out of scope

Security and integrity requirements

  • Meter key and dimensions resolve against feat(saas-contracts): add static feature, quota, meter, and commercial-event registries with conformance gates #874; unknown values fail closed.
  • Producers cannot submit usage for another tenant or spoof server-derived actor/resource context.
  • Idempotency identity binds tenant, producer, meter, source event, and version.
  • Quantity bounds, sign rules, timestamp skew, and correction semantics are enforced.
  • Billable events and correction actions are audited without duplicating sensitive payloads.
  • Aggregation is deterministic and reproducible from immutable events.
  • Quota enforcement cannot rely solely on a stale cache; authoritative state remains durable.

Acceptance criteria

  • Duplicate producer events are counted once.
  • Late and out-of-order events produce documented deterministic aggregates.
  • Corrections preserve original evidence and update aggregates idempotently.
  • Rebuild from source events reproduces stored aggregates.
  • Effective usage can be queried by tenant, meter, and window with freshness metadata.
  • Quota decisions integrate with feat(tenant-entitlement): compute and enforce effective features, modules, quotas, and overrides #871 and fail safely when usage is stale/unavailable according to descriptor policy.
  • Tenant A cannot submit/read/correct tenant B usage.
  • High-volume lifecycle, partitioning, archive, purge, and legal hold are registered.
  • Derived modules can emit a reviewed meter event without direct table access.

Testing

  • Unit tests for event validation, aggregation semantics, late events, corrections, and quota decisions.
  • PostgreSQL integration tests for RLS, idempotency races, immutable events, checkpoint/rebuild, and least-privilege roles.
  • Concurrency and worker-restart tests.
  • Large-data/query-plan tests and representative load/soak scenario.
  • Reconciliation mutation tests: duplicate counting or lost late event must turn tests red.
  • E2E operator usage/reconciliation flow.

Documentation

  • ERD/data dictionary, meter producer guide, OpenAPI/AsyncAPI, correction/reconciliation SOP, retention/partition runbook, privacy classification, module README, and changeset.

Dependencies

Provides usage data to #876 subscription billing and #880 reporting/operations.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:apiKontrak OpenAPI/RESTarea:databaseSchema, migration, pooling, RLSarea:reportingManagement reporting viewspriority:p1Prioritas tinggi - core domaintype:taskAtomic implementation task

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions