v0.3.2 — Recent-calculations debug log + cache fix
What's new
Recent-calculations debug log — a 50-entry ring buffer that captures every cart tax calculation so merchants can answer "why is this tax $8.25 when it should be $9.03?" without grepping the server's PHP error log.
Each entry records:
- Timestamp (UTC, ISO-8601)
- Source: `cache-hit` / `engine-call` / `error`
- Destination ZIP, OST category, pre-tax amount
- Computed tax total
- Round-trip duration (ms) for engine calls
- Error message + class name for failures
Disabled by default — adds one option-write per calculation, so leave it OFF in production unless investigating an issue.
How to use
Toggle: WC > Settings > Tax > OpenSalesTax → "Calculation log" → Enabled.
Or via WP-CLI:
```bash
wp option update opensalestax_calc_log_enabled 1
```
View:
- Settings page: scroll below the form for the "Recent calculations" panel.
- WP-CLI: `wp opensalestax recent-calcs` (with `--limit` flag).
- Programmatic: `OpenSalesTax\WooCommerce\CalculationLog::getRecent()`.
Clear:
```bash
wp opensalestax clear-log
```
🐞 Pre-existing cache bug fixed
While instrumenting the log paths, I found that Cache::get() was silently degrading to "no caching" since v0.1.1. PHP auto-converts numeric-string array keys to `int` when an array is constructed with `[$key => $val]`, but `Cache::get()`'s validator rejected entries where any key wasn't `is_string()`. So when the placeholder rate ID (a stringified int) round-tripped through the transient layer, it came back as int and the cache layer rejected it.
Result: every cart calculation hit the engine, every time. Performance hit but no correctness issue.
Now fixed. Verified end-to-end on VM 907 against engine v0.39: call 1 → `engine-call` (241ms), call 2 → `cache-hit` (no engine round-trip). Caching now actually caches.
Quality gate
- 85/85 unit tests pass (10 new in `CalculationLogTest`)
- PHPStan level=max clean
- PHP-CS-Fixer (PSR-12 + risky) clean
- Security review re-run for v0.3.2: deserialization safety verified (loadRaw rejects non-array roots and entries); output escaping on the settings-page log viewer passes every value through `esc_html()` via a `stringify` helper
Upgrade
Drop-in upgrade from v0.3.1 — no configuration required. The cache bug fix means the engine will see significantly fewer requests once cached entries start landing.
```bash
cd wp-content/plugins/opensalestax-woocommerce
git pull
composer install --no-dev
```
Full changelog
See CHANGELOG.md.