# `MishkaCmsCore.Runtime.Resources.Preparations.SiteWithGlobals`
[🔗](https://github.com/mishka-group/mishka_cms_core/blob/v0.0.1/lib/mishka_cms_core/runtime/resources/__preparations/site_with_globals.ex#L5)

Scopes a read to one site plus the shared rows, deciding whose site from WHO IS ASKING.

For the `multitenancy :bypass` reads that answer "this site's rows and the global ones" —
`:for_tenant_with_globals` and its single-row twin, the builder's `:for_editor` reads, a
stylesheet's `:for_compiler`. A missing tenant is never a master:

  * a master (`MishkaCmsCore.Accounts.Helper.master_user?/1`, `site_id` nil) reads the tenant's
    site when one is passed, else the site named in the `:site_id` argument, else every site;
  * a site user, whatever it holds, reads its own site. Passing another site's tenant or naming
    another site in `:site_id` reads nothing;
  * a call made as the system — no actor, `authorize?: false` — reads as a master does;
  * a call with no actor made as a user reads the tenant's site when one is passed, else nothing.
    A query built without `authorize?` is such a call: Ash hands the preparation the domain's
    default, `true`;
  * any other actor reads nothing.

The actor is the one the query was built with. What holds the actor that runs the read is the
policy on the same actions — see `MishkaCmsCore.Runtime.Layout` — and a test holds every action
that uses this preparation to that policy.

## Options

  * `:shape` — `:with_globals` (the default) adds the shared rows to the site's own; `:exact`
    reads the site's rows alone, and the shared rows alone when the reach is every site.
  * `:fallback` — what a master or the system reads with neither a tenant nor a `:site_id`:
    `:everything` (the default) or `:globals`.

## Usage

    read :for_tenant_with_globals do
      multitenancy :bypass
      argument :site_id, :uuid, allow_nil?: true

      prepare MishkaCmsCore.Runtime.Resources.Preparations.SiteWithGlobals
    end

# `acting_site`

```elixir
@spec acting_site(map()) :: String.t() | nil
```

The site a call acts on: its tenant, when whoever makes the call may act for that site — a master,
the system (no actor, `authorize?: false`), or a site user whose own site it is. Anyone else, a
site user naming another site and a missing actor included, acts on none: `nil`.

For the actions that read or write as the system once they know whose record it is — the version
wrappers — so that knowing comes from the actor and not from the tenant alone.

# `acts_on?`

```elixir
@spec acts_on?(map(), String.t() | nil) :: boolean()
```

Whether a call made with `context` may write a record of `site_id` — a record of no site when
`site_id` is nil. With no tenant, only a master or the system does; with one, whoever acts on the
tenant (`acting_site/1`), and only on that site's record.

# `reach`

```elixir
@spec reach(map() | nil, String.t() | nil, String.t() | nil, boolean()) ::
  {:site, String.t()} | :everything | :nothing
```

Which site `actor` reaches for a read made with `tenant` and naming `site_argument`: `{:site, id}`,
`:everything` or `:nothing`. `authorize?` is whether the call is made as a user.

# `reading_site`

```elixir
@spec reading_site(map()) :: String.t() | nil
```

The site a read made with `context` reads: its tenant, for a master, the system, a call with no
actor, and a site user whose own site it is — the reach `reach/4` gives a read. A site user naming
another site, and anything that is not a user, reads none: `nil`. What the read then shows the
actor that runs it is the resource's read policy.

# `supports`

# `temporal_safe?`

---

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