# lunchflow

Rust client library and optional CLI for the LunchFlow API.

## Build commands

```bash
cargo build                      # library only
cargo build --features cli       # library + CLI binary
cargo test --all-features        # run tests
cargo clippy --all-features -- -D warnings
cargo fmt --check
```

## Project structure

```
src/
  lib.rs              # Public exports: LunchFlowClient, TransactionParams, Error, Result, models
  client.rs           # LunchFlowClient + TransactionParams — all API methods live here
  error.rs            # Error enum (thiserror) + Result<T> alias
  models/
    mod.rs            # Re-exports all model types
    account.rs        # Account, AccountList, AccountStatus, Provider
    balance.rs        # Balance, BalanceResponse
    transaction.rs    # Transaction, TransactionList
    holdings.rs       # Holdings, Holding, Security
  main.rs             # CLI (clap, gated behind --features cli)
.github/workflows/
  ci.yml              # Test + clippy + fmt on every push/PR
  release.yml         # cargo publish on v* tags
```

## Architecture notes

**Auth:** API key passed via `x-api-key` header on every request. Key is stored in `LunchFlowClient` and injected by the private `send()` method — callers never touch headers directly.

**HTTP:** `reqwest` with `https_only(true)`. All requests flow through `send()`, which maps HTTP status codes to typed `Error` variants (401 → `Unauthorized`, 403 → `Forbidden`, 404 → `NotFound`, 501 → `HoldingsNotSupported`). The `decode<T>()` helper reads the raw response text before deserializing so decode errors include the actual body.

**Models:** Serde structs with `#[serde(rename = "...")]` where the API uses camelCase (`accountId`, `isPending`, `totalValue`, etc.). `currency` on `Account` is `Option<String>` — the API docs say it's always present but it isn't.

**Error type:** `Error` enum in `error.rs`. `Decode(String)` includes the raw body for diagnosing API response shape mismatches. Add new variants here when the API returns a new error condition.

**CLI:** Behind the `cli` feature flag to keep `clap` out of library consumers' dependency trees. API key from `--api-key` flag or `LUNCHFLOW_API_KEY` env var.

## Known API doc discrepancies

- `Account.currency` — documented as required, actually absent in responses; modeled as `Option<String>`

## Adding a new endpoint

1. Add response struct(s) to the appropriate file under `src/models/` (or create a new one)
2. Re-export from `src/models/mod.rs`
3. Add a method to `LunchFlowClient` in `src/client.rs` following the existing pattern
4. Add a subcommand to the CLI in `src/main.rs` if it should be user-accessible
