Skip to content
TilloTech Docs

Promotions require an existing standard rate

Date: 07-08-2026 Author(s): Jayden Vicarey Source: Team consensus; implemented in PR #1584 (EM-3902)

Status

accepted

Context

A promotion is a temporary promotional rate on top of a product's standard discount or cashback rate. Face-value catalogues have no purchase-scheme model, so there is nothing to promote. Discount/cashback products can also lack a discount/cashback row (and thus no standard rate) if setup is incomplete.

Allowing promotion create in those cases produced hard failures (getMaxAllowedRate() on a null scheme model) or meaningless rate math.

Decision Drivers

  • Promotions only make sense relative to a standard rate (standard_rate < promotional_rate < 100)
  • Face-value and incomplete purchase-scheme setup are not promotable states
  • Fail early with a clear validation/domain error, not a fatal on null

Considered Options

Allow promotion create without a standard rate

Infer or skip bounds; keep soft fallbacks (e.g. treat missing rate as 0).

Require a purchase-scheme model with a standard rate before promotion create

Reject face-value tenants and products without discount/cashback (and thus without a standard rate).

Decision Outcome

Chosen: Do not allow promotions without a standard rate.

Promotion create requires a discount or cashback purchase-scheme model that can supply the current standard rate and max allowed rate. Face-value products and products missing that model are rejected. PR #1584 enforces this on Hub promotion store and in Product::getMaxAllowedRate().

Consequences

Positive

  • Invariant always has a real baseline rate to compare against
  • Clear product rule for Hub authors and rate-guard callers

Negative

  • Incomplete product setup must set a standard rate before any promotion can be scheduled

Neutral

  • Rate-guard schedules (RateScheduleData) assume a non-null current standard rate; eligibility stays at the HTTP/caller boundary (not inside RateConflictService)
  • Related: ADR 0003 — standard rates are permanent until overridden