- Shipped
- April 19, 2026 at 9:34 PM UTC
- Author
- Kamo
- Commit
- b111835
Adds the read-time gate that makes the applied security model the final source of truth for feature availability, so stale DB state can't leak a disabled feature through and a force-enabled feature is always visible even when the DB hasn't caught up. New methods on AppliedModelEnforcementService: - computeAvailabilitiesMap(org) — one-pass resolution of every ServiceType's availability for an org in a single lookup. Serves as the batch primitive the other new methods build on. - isAppEffectivelyEnabled(org, serviceType, features) — the canonical "is this app on" check. Core services always on, deprecated always off, FORCE_ENABLED always on, NOT_AVAILABLE always off; OPTIONAL_* defers to the OrgFeature row's isActive state. - **************** features) — the Set<ServiceType> companion for callers that need "all effectively-on apps" as a set. - computeEffectiveFeatures(org, features) — returns a fresh ArrayList of OrgFeature rows projected through the gate: NOT_AVAILABLE dropped, FORCE_ENABLED forced to active (even on disabled DB rows), and FORCE_ENABLED apps with no DB row yet represented by transient rows (organization-scoped, never persisted). Callers serializing an org's features to clients now route through computeEffectiveFeatures rather than reading the raw collection, so the frontend sees the applied-model-gated view by default.