wacrm/src/components/auth
Arnas Donauskas 7593253c85
feat(auth): extend useAuth with account context + RequireRole + useCan
PR 5 of the multi-user accounts series. Surfaces the account
+ role state from the profile row through useAuth so every UI
gate downstream can read it without its own fetch, and lands
two reusable patterns the upcoming Members tab / Join page /
sidebar gating PRs will all consume.

What's new in useAuth
- Profile SELECT now includes `account_id`, `account_role`, and
  the joined `accounts(id, name)` via the existing `account_id`
  FK. `!inner` mirrors the server-side `getCurrentAccount`
  helper from PR #169.
- Context value adds `accountId`, `accountRole`, `account`
  (`{id, name}` summary), and six derived booleans: `isOwner`,
  `isAdmin`, `isAgent`, `isViewer`, plus the capability-level
  `canManageMembers`, `canEditSettings`, `canSendMessages`.
- All derived booleans memoise off `profile.account_role`, so
  consumers can use them as React dep-array entries without
  re-renders cascading on unrelated profile fields.
- The no-provider fallback returns every new field at its
  least-privileged value (null / false) — UI gates fail closed
  if a component is somehow rendered outside the AuthProvider.

`<RequireRole min="admin" fallback={…}>{children}</RequireRole>`
- Renders `children` iff `accountRole >= min`, else `fallback`.
- Treats `profileLoading` as "below threshold" so under-
  privileged users never see a flash of gated content during
  the initial profile fetch.

`useCan(action)` hook
- Typed action union: `manage-members` | `edit-settings` |
  `send-messages` | `view-only` | `delete-account` |
  `transfer-ownership`. Closed set lets the compiler catch
  typos at every call site.
- Returns `false` while loading. The boolean alternative to
  `<RequireRole>` — useful for `disabled={!useCan('edit-settings')}`
  on buttons / inputs / tooltip copy without restructuring JSX.

Why no React-renderer tests
- The wacrm test convention is pure unit tests (`vitest` without
  any React testing library). The role predicates that back
  every new piece here are already covered by the test suite
  added in PR #169 — the new code is thin glue, and adding a
  React testing harness for it would be a much larger change
  than this PR warrants.

Verification
- `npm run lint`      → 0 errors. Warnings drop from 20 → 19
                        because the rewritten useEffect now
                        lists `fetchProfile` in its deps.
- `npm run typecheck` → clean
- `npm test`          → 366/366 pass
- `npm run build`     → succeeds

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-31 17:58:53 +03:00
..
require-role.tsx feat(auth): extend useAuth with account context + RequireRole + useCan 2026-05-31 17:58:53 +03:00