# Afton Electric QBO Onboarding — Runbook

**From:** Riv (Integrations)
**To:** Jimmie
**Date:** 2026-05-18
**Time needed:** ~10 minutes

This wires Afton Electric into the Intuit Developer app so Ledger can read and (through the Sheet queue) write to Afton's QBO file.

The Intuit app, OAuth flow, and credential storage are already built. You're running the OAuth handshake for Afton, and that's it.

---

## What's been built (no action needed from you)

- `Atlas\app\qbo_client.py` — shared module for OAuth + reads, used by every QBO script
- `Atlas\app\qbo_migrate_env.py` — one-shot migration from legacy `.env` into a multi-client `qbo_clients.json`
- `Atlas\app\qbo_oauth_add_client.py` — interactive OAuth handshake for a new client
- `Atlas\app\set_print_later.py` — existing VIP Play check workflow, refactored to use the shared module (no functional change)

---

## Step 1 — Confirm the redirect URI on the Intuit Developer app (~2 min, one-time)

The OAuth callback needs to be registered on the app before it'll work.

1. Open https://developer.intuit.com/app/developer/myapps
2. Click your QBO app (the one we used for VIP Play)
3. Left nav: **Keys & OAuth** (under "Production Settings" — make sure you're on the production tab, not sandbox)
4. Under **Redirect URIs**, add:

   ```
   http://localhost:8765/callback
   ```

5. Save.

If `http://localhost:8765/callback` is already there, skip this step.

If you'd rather use a different port, change it on the Intuit side AND in `qbo_clients.json` under `app.redirect_uri` after Step 2 runs.

---

## Step 2 — Migrate the legacy `.env` into the new credential store (~30 sec, one-time)

```powershell
cd C:\PKA\Atlas\app
python qbo_migrate_env.py
```

Expected output:
```
Wrote C:\PKA\Atlas\app\qbo_clients.json
  app.environment = production
  app.redirect_uri = http://localhost:8765/callback
  clients.vipplay = VIP Play TN (chairman_group=True)
...
Next: add Afton Electric: ...
```

If you see "qbo_clients.json already exists" — that's fine, someone already ran it. Move on.

After this runs, `.env` is no longer read by anything. You can leave it as a backup or rename to `.env.legacy`.

---

## Step 3 — Onboard Afton Electric (~3 min)

```powershell
cd C:\PKA\Atlas\app
python qbo_oauth_add_client.py --slug afton --name "Afton Electric"
```

What happens:

1. Terminal prints `Listening on localhost:8765 for the OAuth callback...`
2. Browser opens to Intuit's authorize page
3. **You sign in with the Intuit/QBO account that has access to Afton Electric's books** (must be Company Admin role on that file)
4. Select **Afton Electric** from the company dropdown if prompted
5. Click **Connect**
6. Browser redirects to `localhost:8765/callback` and shows "QBO authorization received"
7. Terminal prints the captured realmId and saves the refresh token

Expected terminal output at the end:
```
Saved clients.afton to qbo_clients.json
  display_name = Afton Electric
  realm_id = 9341234567890
  chairman_group = False
```

---

## Step 4 — Sanity check (~30 sec)

The onboarding script prints this command at the end. Paste it into PowerShell:

```powershell
python -c "from qbo_client import refresh_access_token, query; t = refresh_access_token('afton'); print(query('afton', t, 'SELECT COUNT(*) FROM Account'))"
```

Expected: a JSON blob with the COUNT (something like `{'totalCount': 87}`).

If that prints a sensible number, OAuth is good and we can read Afton's QBO.

---

## What's next (after you finish this runbook)

Reply to Larry that Afton is wired up. Then I'll:

1. Stand up the `QBO Write Queue` Google Sheet (the visible-queue UX from your last message)
2. Build the Apps Script worker that polls approved rows and executes writes
3. Wire Ledger's tool wrappers (tier-aware: reads automatic, Tier 2/3 land in the queue)
4. Hand Ledger the May 13 A/R worklist and let him start posting reclassifies into the queue for your batch review

ETA from your green-light to "Ledger working through the A/R worklist in the queue": about a day of build + your test runs.

---

## If anything breaks

- **Browser doesn't open** — the terminal prints the URL. Copy it into a browser manually.
- **"Redirect URI mismatch" on Intuit's page** — Step 1 wasn't done or the URI doesn't exactly match `http://localhost:8765/callback`. Trailing slash matters.
- **"Address already in use" on port 8765** — something else is using that port. Either close it, or edit `qbo_clients.json` -> `app.redirect_uri` to a different port (e.g. `http://localhost:8770/callback`) and re-add that URI on developer.intuit.com.
- **Script hangs after browser opens** — you didn't complete the authorize flow within 5 minutes. Just re-run the script.
- **You sign in with the wrong Intuit account** — kill the script (Ctrl+C), sign out at qbo.intuit.com, re-run.

Ping Larry if anything else gets weird.
