# `zfin doctor`

Health-check your zfin setup -- files and environment -- without
changing anything.

```
Usage: zfin doctor
```

`doctor` answers "is my setup sane?" It is **read-only**: no provider
fetches, no cache writes, no portfolio changes. The only network call
is an optional `GET {ZFIN_SERVER}/help` to confirm the server is
reachable, so it's safe to run in CI or cron.

## What it checks

Four sections, each line tagged `OK` / `INFO` / `WARN` / `FAIL`:

- **Files** -- every config file: is it present, where was it resolved
  from, and does it parse?
- **Cross-checks** -- do `accounts.srf` / `metadata.srf` /
  `transaction_log.srf` reference entries that actually exist (e.g.
  every account used by a lot has an `accounts.srf` entry)?
- **Environment** -- cache size, staleness of the hand-maintained data
  tables, and `ZFIN_SERVER` reachability and version.
- **Capabilities** -- which API keys are set and what each enables (or
  what you give up without it).

## Exit code

`0` unless a file that **exists** fails to parse (a `FAIL`), in which
case it exits `1`. Missing optional files, cross-reference gaps, stale
data, an unreachable server, and absent API keys are all non-fatal
(`INFO` / `WARN`) -- so a clean install with only `portfolio.srf` still
exits `0`.

## Example

```bash
ZFIN_HOME=examples/pre-retirement-both zfin doctor
```

```
zfin doctor

Files
  [OK  ] examples/pre-retirement-both/portfolio.srf: 20 lots
  [OK  ] accounts.srf: examples/pre-retirement-both/accounts.srf
  [OK  ] metadata.srf: examples/pre-retirement-both/metadata.srf
  [INFO] transaction_log.srf: not present
  [OK  ] projections.srf: examples/pre-retirement-both/projections.srf
  [INFO] history/imported_values.srf: not present
  [INFO] history/ snapshots: no history/ directory
  [INFO] keys.srf: not present; using built-in defaults
  [INFO] theme.srf: not present; using built-in defaults

Cross-checks
  [OK  ] accounts.srf coverage: all referenced entries present
  [OK  ] metadata.srf coverage: all referenced entries present
  [INFO] transaction_log.srf references: skipped (transaction_log.srf not loaded)

Environment
  [OK  ] Cache: 42 symbols, 168 files, 23.4 MB (~/.cache/zfin)
  [OK  ] T-bill risk-free rate table: current
  [OK  ] Shiller annual returns (ie_data.csv): current
  [OK  ] Review tab MaxDD color thresholds: current
  [OK  ] Observation engine thresholds: current
  [OK  ] ZFIN_SERVER: reachable: zfin-server abc1234 (https://zfin.example.com)

Capabilities
  [OK  ] TIINGO_API_KEY: daily candles
  [OK  ] POLYGON_API_KEY: dividend/split history + dividend-reinvested total return
  [OK  ] FMP_API_KEY: earnings history and estimates
  [OK  ] TWELVEDATA_API_KEY: quote fallback after Yahoo
  [OK  ] ZFIN_USER_EMAIL: ETF profiles and `enrich`
  [OK  ] OPENFIGI_API_KEY: faster CUSIP lookups (higher rate limit)
  [OK  ] Quotes (Yahoo): always available, no key required
  [OK  ] Options (CBOE): always available, no key required

Summary: 20 OK, 0 warning(s), 0 failure(s)
```

A key you haven't set is not an error -- it shows as `INFO` with what
you give up, for example:

```
  [INFO] POLYGON_API_KEY: price-only returns; no dividend/split history
  [INFO] FMP_API_KEY: no earnings data
```

With `ZFIN_SERVER` unset, the Environment section shows
`[INFO] ZFIN_SERVER: not set (provider fetch only; no server sync)`.

## See also

- [Environment variables](../config/environment.md) -- the keys and paths doctor inspects.
- [Data providers and API keys](../providers.md) -- where to get each key.
- [Caching and data freshness](../../explanation/caching.md) -- the cache and the `ZFIN_SERVER` tier doctor reports on.

---

[CLI command reference](index.md)
