jortt 0.1.0

Async Rust SDK for the Jortt API with typed modules, hybrid OAuth helpers, and raw operation escape hatch
Documentation
# Live Testing Guide

This guide covers end-to-end usage of the `examples/` programs against real Jortt accounts.

## Security and Credential Model

The repository never stores real credentials.

Use environment variables only:

- `JORTT_CLIENT_ID`
- `JORTT_CLIENT_SECRET`
- optional `JORTT_ACCESS_TOKEN`

When `JORTT_ACCESS_TOKEN` is set and non-empty, examples use it directly.
When it is absent, examples call OAuth client-credentials flow to obtain a token.

## Example Matrix

| Example | Purpose | Default Write Behavior |
| --- | --- | --- |
| `oauth_client_credentials` | Fetch and print token metadata from OAuth | No writes |
| `typed_live_workflow` | Typed customer/invoice flow validation | Read-only unless `JORTT_ALLOW_WRITES=true` |
| `full_openapi_smoke` | Full operation smoke by iterating generated catalog (`126`) | Read-only unless `JORTT_RUN_MUTATIONS=true` |

## Shared Environment Variables

| Variable | Required | Description |
| --- | --- | --- |
| `JORTT_CLIENT_ID` | Yes (unless only using `JORTT_ACCESS_TOKEN`) | OAuth client id |
| `JORTT_CLIENT_SECRET` | Yes (unless only using `JORTT_ACCESS_TOKEN`) | OAuth client secret |
| `JORTT_ACCESS_TOKEN` | Optional | Direct bearer token override |
| `JORTT_BASE_URL` | Optional | API base URL override, defaults to `https://api.jortt.nl/` |

Starter templates:

- PowerShell: [`examples/env.template.ps1`]../examples/env.template.ps1
- POSIX shell: [`examples/env.template.sh`]../examples/env.template.sh

## Typed Workflow Variables

| Variable | Required | Description |
| --- | --- | --- |
| `JORTT_PARAM_CUSTOMER_ID` | Optional | Enables `get_customer` check |
| `JORTT_PARAM_INVOICE_ID` | Optional | Enables `get_invoice` and PDF URL checks |
| `JORTT_ALLOW_WRITES` | Optional | `true`/`1` enables create customer + create invoice |

## Full OpenAPI Smoke Variables

| Variable | Required | Description |
| --- | --- | --- |
| `JORTT_RUN_MUTATIONS` | Optional | `true`/`1` enables POST/PUT/PATCH/DELETE execution |
| `JORTT_PARAM_<NAME>` | Conditional | Supplies path parameter values for operations with `{name}` |
| `JORTT_QUERY_<METHOD>_<PATH_KEY>` | Optional | Query pairs as `k=v&k2=v2` |
| `JORTT_BODY_<METHOD>_<PATH_KEY>` | Optional | Raw JSON payload string |
| `JORTT_ACCEPT_<METHOD>_<PATH_KEY>` | Optional | Explicit `Accept` header override |

### Path Key Derivation

`<PATH_KEY>` is generated by:

1. taking the literal path template from the OpenAPI catalog
2. replacing non-alphanumeric characters with `_`
3. collapsing repeated `_`
4. uppercasing the result

Examples:

- `POST /v2/invoices` => `POST_V2_INVOICES`
- `GET /customers/{customer_id}` => `GET_CUSTOMERS_CUSTOMER_ID`
- `PUT /projects/{id}/line_items/{line_item_id}` => `PUT_PROJECTS_ID_LINE_ITEMS_LINE_ITEM_ID`

## Execution Steps

### 1) OAuth only

```bash
cargo run --example oauth_client_credentials
```

### 2) Typed workflow

```bash
cargo run --example typed_live_workflow
```

Enable writes explicitly:

```bash
set JORTT_ALLOW_WRITES=true
cargo run --example typed_live_workflow
```

### 3) Full operation smoke

```bash
cargo run --example full_openapi_smoke
```

Enable mutations:

```bash
set JORTT_RUN_MUTATIONS=true
cargo run --example full_openapi_smoke
```

## PowerShell Setup Example

```powershell
$env:JORTT_CLIENT_ID = "your-client-id"
$env:JORTT_CLIENT_SECRET = "your-client-secret"
$env:JORTT_PARAM_CUSTOMER_ID = "408d4652-b07a-4195-817e-0390bb0c9428"
$env:JORTT_PARAM_INVOICE_ID = "b3b0b7c4-9dab-4ca7-b1c0-16b0ebbb75f7"
cargo run --example typed_live_workflow
```

## Mutation Safety Notes

- Mutation examples are opt-in by environment flag.
- Use a sandbox/test organization whenever possible.
- For broad smoke runs, start read-only first, then enable mutations incrementally with scoped params/bodies.
- Failing operation lines are printed as `FAIL <METHOD> <PATH> -> <error>` and execution continues, so you can see complete coverage state in one run.

## Troubleshooting

### `access_token.invalid` or `invalid_client`

- Confirm `JORTT_CLIENT_ID` and `JORTT_CLIENT_SECRET` are valid for the target org.
- If supplying `JORTT_ACCESS_TOKEN`, ensure it is not expired and belongs to expected scopes.

### Frequent `SKIP ... missing path param env`

- Add required `JORTT_PARAM_<NAME>` variables matching each path placeholder.
- For common placeholders like `{id}`, set `JORTT_PARAM_ID`.

### `params.invalid`

- Supply required query/body fixtures for that operation:
  - `JORTT_QUERY_<METHOD>_<PATH_KEY>`
  - `JORTT_BODY_<METHOD>_<PATH_KEY>`

### PDF download endpoint failures

- Invoice PDF URLs can require already-sent invoices.
- Test against invoice records in a send-complete state.