From abeb9d7298d3e207ea0167026a8fba2e54b47314 Mon Sep 17 00:00:00 2001 From: Chris Hondl Date: Fri, 17 Jul 2026 09:40:20 -0700 Subject: [PATCH 1/2] fix: make BACKEND_URL env-configurable so the mirror self-triggers its own ETL MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The freshness ping probe and the cron's update_curr_year_background HTTP-call BACKEND_URL to reach the data router. It was hardcoded to upstream api.statbotics.io under PROD, so on the single-container mirror the self-trigger hit the (down) upstream instead of the mirror's own backend and ingestion never ran — live offseason match updates never landed. Read BACKEND_URL from env (fallback to the old default) and set it to the mirror's run.app URL at deploy. --- backend/src/constants.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/backend/src/constants.py b/backend/src/constants.py index 4aec2ff2..41b24c96 100644 --- a/backend/src/constants.py +++ b/backend/src/constants.py @@ -6,7 +6,15 @@ PROD = os.getenv("PROD", "False") == "True" # 8001 emulates the data server -BACKEND_URL = "https://api.statbotics.io" if PROD else "http://localhost:8001" +# The ETL self-trigger (update_curr_year_background, the freshness ping probe) +# HTTP-calls BACKEND_URL to reach the data router. In the original multi-service +# layout the data router was a separate service; on the single-container mirror +# it is the SAME service, so BACKEND_URL must point at the mirror's own backend +# (set the env var to the run.app URL), not upstream api.statbotics.io — else the +# self-trigger hits the wrong host and ingestion never runs. +BACKEND_URL = os.getenv("BACKEND_URL") or ( + "https://api.statbotics.io" if PROD else "http://localhost:8001" +) # DB From cd671121fda45cc0b67310a355b5f6ae12e0c710 Mon Sep 17 00:00:00 2001 From: Chris Hondl Date: Mon, 20 Jul 2026 22:02:09 -0700 Subject: [PATCH 2/2] rig: smoke.py sends a browser UA (Cloudflare 403s urllib); Makefile deploys cph-staging - smoke.py: install a global opener with a browser User-Agent so live-mirror checks aren't 403'd by Cloudflare's bot filter (was reporting false failures). - Makefile: DEPLOY_DIR -> .worktrees/cph-staging so deploys build the cph-staging branch (the deployed fork line), not the retiring 'staging' branch. --- docs/superpowers/rig/deploy/Makefile | 13 ++++++------- docs/superpowers/rig/smoke/smoke.py | 8 ++++++++ 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/docs/superpowers/rig/deploy/Makefile b/docs/superpowers/rig/deploy/Makefile index fd79e8ea..5562360e 100644 --- a/docs/superpowers/rig/deploy/Makefile +++ b/docs/superpowers/rig/deploy/Makefile @@ -40,14 +40,13 @@ API_CPU ?= 2 UPDATE_SCHED ?= statbotics-update GC_SCHED ?= statbotics-gc -# Build/deploy the DEPLOY BRANCH checkout, not the main worktree. docs/ (where -# this Makefile lives) is git-excluded and only exists in the main checkout on -# `master`, but the code + Dockerfiles that get deployed live on the `staging` -# branch — its worktree at
/.worktrees/staging. MAIN_DIR is 4 up from -# here; DEPLOY_DIR is the staging worktree. Override DEPLOY_DIR to deploy a -# different checkout. +# Build/deploy the DEPLOY BRANCH checkout, not the main worktree. The code + +# Dockerfiles that get deployed live on the `cph-staging` branch (the deployed +# fork line) — its worktree at
/.worktrees/cph-staging. MAIN_DIR is 4 up +# from here; DEPLOY_DIR is the cph-staging worktree. Override DEPLOY_DIR to +# deploy a different checkout. MAIN_DIR ?= $(abspath $(dir $(lastword $(MAKEFILE_LIST)))/../../../..) -DEPLOY_DIR ?= $(MAIN_DIR)/.worktrees/staging +DEPLOY_DIR ?= $(MAIN_DIR)/.worktrees/cph-staging BACKEND_DIR ?= $(DEPLOY_DIR)/backend FRONTEND_DIR ?= $(DEPLOY_DIR)/frontend SMOKE ?= $(MAIN_DIR)/docs/superpowers/rig/smoke/smoke.py diff --git a/docs/superpowers/rig/smoke/smoke.py b/docs/superpowers/rig/smoke/smoke.py index 2e7872c5..9d585cd2 100644 --- a/docs/superpowers/rig/smoke/smoke.py +++ b/docs/superpowers/rig/smoke/smoke.py @@ -41,6 +41,14 @@ import urllib.request import zlib +# Send a browser-like User-Agent on every request. Cloudflare (which fronts the +# staging mirror) returns 403 to the default Python-urllib UA as suspected-bot +# traffic, which otherwise fails every https check against the live mirror. +_UA = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) statbotics-smoke/1.0" +_opener = urllib.request.build_opener() +_opener.addheaders = [("User-Agent", _UA)] +urllib.request.install_opener(_opener) + TOL = 0.5 # EPA point tolerance for blob-vs-API equality _results = []