- Shipped
- September 7, 2026 at 5:22 AM UTC
- Author
- Kamo
- Commit
- a1e62a3
The `accounts` option was gated on `organization.isHrs && VIEW_EMPLOYEES`. Neither half is what /account is: its own backend enforces VIEW_ACCOUNTS (CRM) on the customer directory and MANAGE_MEMBERS on the member and team-member tabs, AppAvailabilityInterceptor maps none of its paths to an app because member administration is platform core, and unlike /hr the route carries no layout guard at all — type the URL on a Free plan today and the page loads and works. It was hidden from the rail, the top bar, the command palette, the App Shelf and the Navigation Layout page, and nowhere else. The flag was written before the HR module existed, when HRS was simply the app that meant "people" and every org had it auto-provisioned on. Then /hr arrived and took the flag for the real HR module, and four days later kamo-shared-library ebe504f2 taught computeEffectiveFeatures to project an app OFF when the plan does not include it. Between them `isHrs` changed meaning from "this org switched HR on" to "this org pays for HR", in a different repository, with nothing here to change and nothing to fail. The FREE plan has HR_SYSTEM is_included = false, so the app vanished for every free organization — the tier that most needs the screen where members are added, and which is not seat-capped anyway: MemberCreateController has no seat check, and members added are already held to the plan's own limits. Verified against production: org 1188756624575266822 (FREE) has org_features feature_type=6 is_active = t, while GET **************** returns HRS false. Every team member of every live free org holds both MANAGE_MEMBERS and VIEW_ACCOUNTS, so all of them get the app back. VIEW_EMPLOYEES stays in the OR purely so no org that can see the option today loses it; it is left declared under ServiceType.HRS, where its whole child subtree (CREATE/EDIT/DELETE_EMPLOYEES, VIEW_PAYROLL, VIEW_TIME_OFF) belongs.