Skip to content

Farm configuration and identity become Owner-only, matching spec §5.1 #729

Description

@mforce

What

Move the farm settings screen, the farm logo and the farm banner from the
AdminOnly tier (Owner or Manager) to OwnerOnly.

Why

The spec already says this. specs/product/specs.md §5.1 defines the roles as:

| Owner | Full access |
| Manager | Farm operations, inventory, health, reports |

Configuration is not in Manager's list. The broader reading lives only in a code
comment in AuthPolicies.cs written for #103 — "Manager → corrective actions,
config, money"
— which is an interpretation, not the spec. Today
GET/PUT /account/settings are AuthPolicies.AdminOnly
(AccountEndpoints.cs:26,31) and nav.tsx:79 mirrors that gate deliberately, so
a Manager can change the farm's currency, timezone, locale, unit system and
worker sale allocation policy.

This came up while scoping #727 (a per-farm discount ceiling). That issue no
longer depends on this one — see the decision there — but the question it exposed
is worth settling on its own terms.

Scope

  • AccountEndpoints.cs — GET /settings and PUT /settings to AuthPolicies.OwnerOnly.
  • FarmLogoEndpoints.cs and FarmBannerEndpoints.cs — the same move. Include
    them.
    They are farm identity in the same Accounts group; moving settings and
    leaving these splits one concept across two tiers for no reason.
  • nav.tsx:79 — gate the Farm settings entry on role === "Admin" rather than
    isAdmin. The pattern already exists at nav.tsx:88 for /users, so no new
    isOwner helper is needed.
  • specs/product/specs.md §5.1 — say explicitly that farm configuration is
    Owner-only, so the table and the code agree.
  • A decision record. F27: Roles + scoped permissions — role model, flock-scoped workers, RBAC UI (builds on #73) #103 set the current gate deliberately; without a record a
    future reader will assume this drifted.

Out of scope

The other 33 AuthPolicies.AdminOnly call sites. Flocks, inventory, products,
egg grades, reports, daily entries, stock and sales corrections are all genuinely
"farm operations, inventory, health, reports" and stay where they are. This issue
is about configuration and identity, not the whole tier.

What a Manager loses

Farm name, timezone, locale, currency, unit system, date format, time format,
custom date/time formats, first day of week, default stepper unit, worker sale
allocation policy, logo and banner. Worth stating plainly before this ships:
a Manager will no longer be able to correct a wrong timezone without an Owner.

Acceptance

  • A Manager gets 403 from GET and PUT /account/settings, and from the logo
    and banner endpoints.
  • The Farm settings entry does not render in a Manager's nav.
  • An Owner is unaffected on every path.
  • The farm brand/palette that every role's shell needs still loads for a Manager
    — that comes from a separate endpoint (AccountEndpoints.cs:176), and a test
    should pin that it did not regress.
  • §5.1 and AuthPolicies.cs agree in wording.

Notes

grep -rln "AdminOnly\|isAdmin" tests/ web/src returns 44 files. Most are
unrelated to settings, but the role-matrix and admin-gating suites will need the
new expectation, and FarmSettingsTests.cs (939 lines) and
SettingsPage.test.tsx (1307 lines) carry the bulk of the coverage.

Activity

  1. added this to the Phase 1.5 — Hardening milestone on Sep 8, 2026
  2. added
    sliceThin vertical work item
    area:apiAPI/endpoint layer
    size:MA day or two; migration or a multi-state UI
    priority:tier3Real product weight, real cost
    on Sep 8, 2026
  3. mforce commented on Sep 13, 2026

    @mforce
    OwnerAuthor

    Triaged in the 2026-09-13 issue cleanup. Kept open, labelled priority:tier3 ("real product weight, real cost").

    Why it stays open: it closes a genuine code-vs-spec divergence, and the spec is the authority. §5.1 gives Manager "Farm operations, inventory, health, reports"; configuration is not in that list. The broader reading exists only as a code comment in AuthPolicies.cs written for #103 — an interpretation, never a decision anyone recorded. Today a Manager can change the farm's currency, timezone, locale, unit system, date and time formats, first day of week, default stepper unit and the worker sale allocation policy.

    Why tier3 and not higher: the farm running this deployment has a trusted Manager, so nothing is being exploited. It is a divergence to resolve, not an incident to contain.

    Two things for whoever picks it up:

    1. Either direction closes the divergence, and the issue argues only one of them. Amending §5.1 to say Manager may configure is also a valid resolution, and it is a one-file docs change. Tier3 was chosen on the assumption that the spec is right and the code drifted — if that assumption is wrong, say so on this issue rather than implementing against it.
    2. The body is honest about the cost and it is worth re-reading before starting: a Manager would no longer be able to correct a wrong timezone without an Owner. On a farm whose Owner is not at a desk, that is a real operational change, not a paperwork one.

    Scope is unchanged and fully enumerated in the body: AccountEndpoints.cs GET/PUT /settings, FarmLogoEndpoints.cs, FarmBannerEndpoints.cs, nav.tsx:79 (the role === "Admin" pattern already exists at nav.tsx:88), the §5.1 amendment, and a decision record — #103 set the current gate deliberately, so without a record a future reader will assume this drifted.

    The out-of-scope note also stands: the other 33 AuthPolicies.AdminOnly call sites stay where they are. This is about configuration and identity, not the whole tier.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:apiAPI/endpoint layerarea:frontendReact/Vite web clientpriority:tier3Real product weight, real costsize:MA day or two; migration or a multi-state UIsliceThin vertical work item

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions