Skip to content

Nightly Refresh Runbook

What It Does

Runs every day at 6am via launchd (com.stickymetrics.daily). Orchestrates the full data pipeline in 10 steps:

  1. Pull orders (last 7 days)
  2. Pull FBA restock report 2b. Pull inventory ledger (last 60 days)
  3. Pull AWD inventory 3b. Pull SoStocked POs 3c. Pull warehouse inventory (HIEX)
  4. Forecast (Chronos-Bolt-mini, 365-day horizon, lifecycle-aware) 4b. Compute PO recommendations (per-ASIN, MOQ-gated) 4c. Build styled XLSX dashboard
  5. Push Claude MRP to source sheet
  6. Push forecast to purchasing sheet
  7. Push restock raw data 7b. Push forecast feed
  8. Push AWD raw data
  9. Score predictions vs actuals
  10. Self-healing calibration (1st of month only) 10b. Validate dashboard consistency (smoke test, non-blocking)

Logs

~/.stickymetrics/logs/nightly_YYYY-MM-DD.log

How to Debug

  1. Check today's log: cat ~/.stickymetrics/logs/nightly_$(date +%Y-%m-%d).log
  2. If a step failed, run it manually: cd ~/stickymetrics && python3 scripts/<script>.py --seller ecomhd_us
  3. Common failures:
  4. SP-API token expired: lib_sticky.py auto-refreshes LWA tokens, but if the refresh_token itself is revoked, re-auth in Seller Central
  5. Ads API 425: Duplicate report request - the existing reportId is returned, use it
  6. Sheet push fails: Usually a quota issue (Google Sheets API limit: 300 req/min). Wait and retry.
  7. Forecast OOM: Chronos-Bolt-mini needs ~4GB RAM. Check if other processes are hogging memory.

How to Run Manually

cd ~/stickymetrics
bash scripts/nightly_refresh.sh
# Or individual steps:
python3 scripts/pull_orders.py --seller ecomhd_us --days 7
python3 forecasts/forecast_all_lifecycle.py --seller ecomhd_us --horizon-days 365 --use-pretrained mini

Key Google Sheets

Sheet ID Purpose
Purchasing Dashboard 1TmQk3sKrLxS1ooUb1UfliA3-XkQ7gqBVZQQbswZDnb8 Main ops dashboard
Source/MRP 1kV6N_vMUqJzT8w2Sbq7DfmJI5Ttadxol8AIu_UaaHow Forecast source
Restock 13u0g4ruHyayZ2AA8GvOcccgy1wZ2R175rtQk1zi2avU FBA restock data
AWD 1Zj6viurclBiZJwGL6iH4AozuAv1NeBplJmNYt0KMRuQ AWD inventory

Month-End Behavior

  • Last day of month: tags the forecast run as month_end_baseline_for next month
  • 1st of month: runs calibrate.py (compares last month's forecast vs actuals, adjusts weights)