Feature Overrides per Gym

Feature Overrides

A gym's features normally come from its plan. An override in gym_feature_overrides pins one feature on or off for that gym regardless of the plan.

Feature Access Hierarchy

useGymFeatureAccess resolves access in this strict order, first match wins:

  1. Gym override — a row for this gym and feature. enabled = true grants, enabled = false denies, even if the plan includes the feature.
  2. Plan features — the feature is linked to the gym's plan.
  3. Global default — the feature is flagged as a default for everyone.

The result is cached for five minutes, so a change is not visible to the gym until the cache expires or they reload.

What can be toggled in the UI today

Only Comp OS. Its switch lives on Gyms → [Gym] → Billing & Subscription → Comp OS Add-On, and it writes a comp_os override as part of the add-on flow (contract, Stripe line item, activation).

There is no generic per-feature override screen. Every other override — an Engage feature trialled on Core, a paid bolt-on such as athlete_development or maintenance_tracker, a feature disabled during an incident — has to be applied to gym_feature_overrides directly. Raise it with engineering rather than promising a gym a self-serve toggle, and record what was set, why, and when it should be removed.

Common Use Cases

ScenarioAction
Paid add-on on a lower tierOverride enabled for that feature, with the commercial arrangement recorded
Trial of a higher-tier featureOverride enabled, plus a dated note for removal
Beta feature for selected gymsMark the feature hidden from the public website, then override it on for the beta gyms
Disable during an incidentOverride disabled — remember this beats the plan and will survive an upgrade

First thing to check on "we upgraded but still cannot see it"

A stale enabled = false override. Because an override beats the plan, an old disable silently defeats an upgrade. Check overrides before plans, flags or roles.