# `PhoenixKit.Users.ActingLink`
[🔗](https://github.com/BeamLabEU/phoenix_kit/blob/v3.5.0/lib/phoenix_kit/users/acting_link.ex#L1)

What a person's link to an organization gives them while they act for it.

An acting session belongs to the organization, so its roles are the organization's.
The link narrows them: `narrow/2` keeps the roles the organization holds that are
also on the link, and a link can never give what the organization does not have.

`PhoenixKit.Users.Auth.Scope.for_user/2`, `PhoenixKit.Users.ActiveRole` and the
session lists all go through here, so they cannot disagree.

The link reaches a scope through `%User{organization_manager_uuid: _}`, a virtual
field only the session token loader fills. A link named there that is gone gives `nil`,
and `narrow/2` answers no roles.

## Outside a session

A scope built from a bare organization (a background job, a module checking an
account by uuid) has no link to go by. `outside_session/1` limits it to the roles
**every** link allows, so it is never wider than any person's session could be. While
nobody is narrowed that is all the organization's roles, as it always was: a site that
never narrows sees no change.

# `t`

```elixir
@type t() :: %{
  uuid: String.t(),
  organization_uuid: String.t(),
  type_key: String.t(),
  can_manage?: boolean(),
  all_roles?: boolean(),
  role_uuids: [String.t()]
}
```

# `for_user`

```elixir
@spec for_user(PhoenixKit.Users.Auth.User.t()) :: t() | nil
```

The link of the session `user` was loaded from, or `nil`.

# `load_many`

```elixir
@spec load_many([String.t() | nil]) :: %{optional(String.t()) =&gt; t()}
```

The links with these uuids, keyed by uuid. `nil`s are ignored.

# `narrow`

```elixir
@spec narrow([role], %{all_roles?: boolean(), role_uuids: [String.t()]} | nil) :: [
  role
]
when role: %{uuid: String.t(), name: String.t()}
```

The roles of `roles` that `link` allows: all of them for an `all_roles` link, else
the listed ones. The `User` system role stays, as it does through the role switcher:
it is a baseline, not something to tick. No link means no roles.

# `outside_session`

```elixir
@spec outside_session(PhoenixKit.Users.Auth.User.t()) ::
  %{all_roles?: boolean(), role_uuids: [String.t()]} | nil
```

What limits a managed organization's roles when `user` did not come from a session, to
give `narrow/2`: every narrowed link's list in common. See the module documentation.

A user that names a link did come from a session, so `for_user/1` answers for it; if
that found nothing, the link is gone and this is `nil` as well.

# `staff?`

```elixir
@spec staff?(PhoenixKit.Users.Auth.User.t()) :: boolean()
```

Whether `user` is a session acting for an organization through a link that does not
manage it (staff). Staff keep their own preferences but do not change the company's
profile. Read from the link each time, so a link changed during the session counts at
once.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
