diff --git a/README.md b/README.md index acc8b03..3927c02 100644 --- a/README.md +++ b/README.md @@ -134,6 +134,50 @@ curl -X POST -H "Authorization: Bearer $(cat ~/.coolify-token)" \ ``` +## Putting the live feed on production + +Production runs the default `LIVE_SOURCE=yahoo` and therefore shows "yahoo" with +a ~10 minute delay. `LIVE_SOURCE=schwab` and the credentials live in `.env`, +which is gitignored — so the switch has never crossed the deploy boundary. It +cannot: nothing in the repo carries it. + +Four things are needed, and all of them are set on the VPS rather than here. + +**1. Environment, in Coolify:** + +``` +LIVE_SOURCE=schwab +SCHWAB_API_KEY=... # same values as the local .env +SCHWAB_APP_SECRET=... +``` + +`SCHWAB_CALLBACK_URL` already defaults to `https://chart.amow.com/api/qt`, which +is what the Schwab app is registered with. Do not change it — a registered +callback edit can send the app back through approval. + +**2. The OAuth token, at `data/.schwab_token.json` on the persistent volume.** +No new login is required: the local token was minted against the production +callback, and Schwab tokens are bound to the app rather than the machine. Copy +the file's contents into that path on the volume. If the path is not persistent, +the next deploy erases it and production falls silently back to Yahoo. + +**3. Stop the dev stream first.** One refresh token means one Schwab streaming +connection. Dev and production both streaming will fight for it — see the risk +register on duplicate connections. Set `LIVE_SOURCE=yahoo` in the local `.env`, +or stop the local stack, before production goes live. + +**4. Plan for expiry.** The Schwab refresh token lasts about seven days. When it +lapses, production drops back to Yahoo and needs a fresh token by the same +route: run the flow locally, paste the callback URL from `/api/qt` into the +waiting prompt, then copy the new token onto the volume. + +Verify from anywhere: + +```bash +curl -s -H "X-Chart-Token: $TOKEN" https://chart.amow.com/api/status +# want: "source":"schwab","delay_minutes":0 +``` + ## Access token `CHART_AUTH_TOKEN` guards everything under `/api` plus the `/ws` stream. Leave