# Changelog — Salud eCW Charge Entry Bot What changed, when, where, and **why**. The why matters more than the what: most of the decisions below look strange until you know which eCW behaviour forced them, and without that a future change quietly undoes them. Dates are the working dates on this machine (IST). --- ## Day 1 — 2026-09-02 ### Status at end of day | Phase | State | |---|---| | Login (proxy + 2FA) | **working, proven end to end** | | Navigate to Billing → Claims | **working, proven** | | Claim Lookup filters | **working, proven** | | Lookup results | click proven; `Total Counts` never captured | | Charge entry | not started | Last verified run: `Logs/run_20260902_181115.log`. ### What was built **`src/config.py`** — every setting, selector and timeout in one place, loaded from `.env`. Written without `python-dotenv` on purpose: these machines are locked down and each new dependency is one more thing to get approved. **`src/auth.py`** — the login. Navigation retries, the security-image page, CAPTCHA escalation, two-factor, and the landing page. **`src/otp.py`** — reads the second factor out of the mailbox over IMAP and reports *what kind* of challenge it is, so `auth.py` can drive the browser accordingly. **`src/nav.py`** — post-login navigation to the Claim Lookup screen. **`src/claims.py`** — the Claim Lookup form: status, date type, date range, balance, Lookup. **`src/guard.py`** — refuses to run when attempts come too close together. **`src/ui.py`** — operator message boxes that always time out. **`src/runlog.py`** — tees the run to `Logs/run_.log`, flushed per line so a killed run still leaves a readable log. **`src/check_net.py`, `src/check_imap.py`** — preflight probes. Run these before blaming the bot. ### Decisions that are load-bearing **The proxy is per-browser, not system-wide.** `chromium.launch(proxy=…)` in `auth.py`. This is the single thing that makes the project possible. Measured: | | no proxy | via proxy | |---|---|---| | eCW portal | HTTP 400 | **200** | | approval link | HTTP 400 → "restricted" | **200** | | webmail site (:2096) | **200** | 403, blocked by proxy | | mailbox IMAP :993 | **connects** | not proxied at all | A human is deadlocked by that table — proxy on for eCW, off for the mail, on again to confirm, and no ordering works. The bot escapes it by never opening the webmail *website*: the browser is proxied, and mail is read by `imaplib` over a raw socket that ignores the proxy entirely. The Windows system proxy stays off. **"Access to the application has been restricted" is an IP check, not a lockout.** Same link: 400 unproxied, 200 proxied, seconds apart. So it almost always means the browser lost the proxy — not that the account is locked. This was initially misdiagnosed as rate limiting; the comments and the 30-minute lockout that came from that were corrected. **The second factor is a push-approval link, not a 6-digit code.** The mail contains no digits at all. An earlier build assumed a code and "found" `000000`, scraped out of `color: #000000` in the mail's stylesheet. Fixed by stripping `