Fixed
-
allFeatures()now includes direct feature grants.FeatureInfoBuilder::buildAll()
only iterated the subscription plan's features, so a feature granted with
grantFeature()but absent from the plan never appeared in the list — even though
featureInfo()on that same slug returned correct data. A subscribable with no
subscription at all returned an empty collection rather than its grants.Plan and grant slugs are now unioned, keeping plan ordering and deduplicating
overlaps (an overlapping grant is listed once, with the additive limit).
Behavior change
subscriptionInfo() delegates to allFeatures(), so its features collection now
includes direct-only grants. If you serialize that DTO, expect additional entries.
subscriptionInfo() still returns an empty DTO for a subscribable with no subscription —
its payload is plan- and billing-shaped. Use allFeatures() for grant-only subscribables.
Documentation
- Reframed Direct Feature Grants as a standalone mechanism rather than a plan add-on:
grants resolve with no subscription present. - Documented plan/grant overlap resolution — quota is additive, but unit price and reset
cycle are overrides, not additive. - Added an "Entitlements without a subscription" recipe for mirroring a parent's plan onto
child records, and a table of which APIs work on grants alone vs. require a subscription.
Dependencies
Full Changelog: 1.0.1...1.0.2