# `MishkaCmsCore.Install`
[🔗](https://github.com/mishka-group/mishka_cms_core/blob/v0.0.1/lib/mishka_cms_core/install.ex#L5)

First-run install state, kept in `:persistent_term` so the per-request install gate is a
lock-free RAM read — never a per-request database count.

The database is the source of truth; this is only the boot-loaded mirror. `BootHandler`
calls `refresh!/0` once at boot, the installer calls `mark_installed!/0` when the wizard
commits, and a fresh database (no master user and no site) re-opens `/install` on the next
boot. The key is absent until boot computes it (and in the test environment, where
`BootHandler` does not run) — `status/0` reports `:unknown` then, so the gate stays inert
rather than guessing.

See `MishkaCms.Plugs.InstallGate`.

# `status`

```elixir
@type status() :: :installed | :not_installed | :unknown
```

Install state as seen by the gate.

# `installed?`

```elixir
@spec installed?() :: boolean()
```

Whether first-run install has completed (a master user and at least one site exist).

# `mark_installed!`

```elixir
@spec mark_installed!() :: :ok
```

Marks the CMS installed — called once when the wizard commits. No reboot needed.

# `refresh!`

```elixir
@spec refresh!() :: boolean()
```

Recomputes install state from the database and caches it. Returns the boolean.

# `status`

```elixir
@spec status() :: status()
```

Returns `:installed`, `:not_installed`, or `:unknown`. `:unknown` means boot has not yet
computed the flag (or we are in a test environment) — callers should treat it as "do nothing".

---

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