# `mix phoenix_kit.doctor`
[🔗](https://github.com/BeamLabEU/phoenix_kit/blob/v2.2.0/lib/mix/tasks/phoenix_kit.doctor.ex#L1)

Diagnoses PhoenixKit installation, migration, and runtime issues.

Runs a comprehensive suite of checks covering database connectivity, pool
configuration, PgBouncer detection, migration state, lock conflicts, and
application configuration. Prints a clear pass/fail report with actionable
remediation steps.

## Usage

    $ mix phoenix_kit.doctor
    $ mix phoenix_kit.doctor --prefix=auth
    $ mix phoenix_kit.doctor --exit-code

## Options

  * `--prefix` - Database schema prefix. When omitted, resolves from
    `config :phoenix_kit, :prefix`, then `"public"` — the same resolution
    `mix phoenix_kit.update` / `--status` use, so a prefixed install is
    diagnosed against the schema it actually lives in.
  * `--exit-code` - Exit non-zero when any check FAILED. Without it this task
    prints "N failures" and still exits 0, so a deploy script that runs it
    cannot act on the result — the same silent success `mix phoenix_kit.status
    --exit-code` exists to remove. Warnings never fail the run; they are
    advisory by construction and several fire on healthy installs. Off by
    default so deploys that run this purely for its report keep passing.

## Checks Performed

  1. **Repo Detection** — Can we find and start the Ecto repo?
  2. **DB Connectivity** — Can we execute a simple query?
  3. **Pool Configuration** — Pool size, checkout timeout, queue settings
  4. **PgBouncer Detection** — Is PgBouncer between app and PostgreSQL?
  5. **Migration State** — PhoenixKit version (COMMENT), schema_migrations alignment
  6. **Module Schema Versions** — Modules owning their own chain, vs what their code expects
  7. **Schema Drift** — Columns a migration should have added but the DB lacks
  8. **Pending Migrations** — Migration files not yet recorded in schema_migrations
  9. **UUID Column Types** — Detects varchar uuid columns that crash Ecto on startup
 10. **UUID Primary Keys** — Detects primary keys that are not the expected uuid type
 11. **NULL UUIDs in FK Sources** — Detects NULL uuids that cause infinite backfill loops
 12. **Orphaned FK References** — Detects orphaned rows that block FK constraint creation
 13. **Lock Conflicts** — Any blocked or long-running queries?
 14. **Orphaned Connections** — Idle-in-transaction or stuck connections
 15. **Oban Configuration** — Queues and plugins that consume pool connections
 16. **PhoenixKit Supervisor** — What's running (update_mode vs full)?
 17. **Child Start Order** — Does the Repo start before PhoenixKit/Oban in application.ex?
 18. **Update Mode** — Is update_mode active?
 19. **daisyUI Version** — Is the host's vendored daisyUI recent enough?
 20. **User Dashboard (deprecated)** — Is the host still on the retired dashboard?
 21. **Sitemap Discoverability** — Is the sitemap actually reachable?
 22. **Demo Auth Pages** — Are the demo auth routes still exposed?
 23. **Manifest Repair (dry-run)** — `PhoenixKit.Migrations.Repair.verify/1`
     runs read-only against the generated
     `PhoenixKit.Migrations.ExpectedSchema` manifest as an additional,
     non-fatal check (never `:fail`). Passes and says so if the manifest
     has been removed or overridden away in this checkout.

# `exit_code`

```elixir
@spec exit_code([{String.t(), {:pass | :warn | :fail, String.t()}}]) :: 0 | 1
```

The process exit status `--exit-code` should produce: `1` when any check
failed, `0` otherwise.

Public because `run/1` is not a unit-test seam (it starts the app and needs a
real database) — this is the pure decision behind the flag, in the same shape
as `Mix.Tasks.PhoenixKit.Status.exit_code/2` and
`Mix.Tasks.PhoenixKit.Repair.exit_code/1`.

Only `:fail` gates. A `:warn` is advisory by construction — several fire on
perfectly healthy installs (a capped pool under `update_mode`, an unreadable
`application.ex`) — and gating on them would make the flag unusable, which is
how a task ends up back at "reports a problem and exits 0".

---

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