ワンクリックで
api-infrastructure
API feeds, pollers, feed thresholds, data paths, StakTrakrApi structure, Fly.io and health badge issues.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
API feeds, pollers, feed thresholds, data paths, StakTrakrApi structure, Fly.io and health badge issues.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
Use when starting a new patch session and needing to pick a Plane issue to work on before claiming a version lock and creating a worktree.
Use when starting a new patch session and needing to pick a Plane issue to work on before claiming a version lock and creating a worktree.
Post-deploy verification for both Portainer (home) and Fly.io (cloud) environments. Runs environment-appropriate health checks, log inspection, env var verification, cron validation, and endpoint smoke tests. Covers the gap between "deploy succeeded" and "deploy actually works." Triggers on: "deploy verify", "post-deploy", "verify deploy", "smoke test deploy", "did the deploy work", "check the deploy", "/deploy-verify"
StakTrakr-specific Phase 1 version bump — edits 6 files, trims What's New, delegates sw.js to pre-commit hook.
Ship dev→main — PR, resolve threads, GitHub Release. Only on explicit user "ready to ship".
Use when adding, editing, or removing StakTrakr in-app FAQ entries in the Settings FAQ tab, including known or honest limitation copy.
| name | api-infrastructure |
| description | API feeds, pollers, feed thresholds, data paths, StakTrakrApi structure, Fly.io and health badge issues. |
All feeds served from lbruton/StakTrakrApi api branch via GitHub Pages at api.staktrakr.com.
| Feed | File | Poller | Threshold |
|---|---|---|---|
| Market prices | data/api/manifest.json | Fly.io run-local.sh + run-publish.sh | 30 min |
| Spot prices | data/hourly/YYYY/MM/DD/HH.json | Fly.io run-spot.sh cron (5,20,35,50 * * * *) | 75 min |
| Goldback | data/api/goldback-spot.json | Home poller scrapes → sqld → Fly.io api-export.js publishes (STAK-491) | 25h (info only) |
| sqld | price_snapshots table | Dual-poller write-through (Fly.io POLLER_ID=api + Portainer VM POLLER_ID=home). Manage via Portainer API — see home-infrastructure skill | internal |
Critical: spot-history-YYYY.json is a seed file (noon UTC daily) — never use it for freshness checks. Live spot data is always in data/hourly/.
5 * * * * in devops/pollers/home-poller/docker-entrypoint.sh) — changed from daily by STRK-58 (CurrencyLayer-backed rate shifts intraday). goldback-scraper.js has no in-script skip-guard — the hourly cron is the dedup. Note: goldback.com's published rate (the data.t/t field in the v2 envelope) can lag the scrape time by hours, so g1_usd may be unchanged across several consecutive hourly publishes.api-health.js reads generated_at, not scraped_at — generated_at is rewritten each publish cycle by api-export.js. The goldback scraped_at is now refreshed hourly, but the 25h "info only" threshold is intentionally loose so a multi-hour scrape outage keeps the badge green.devops/pollers/home-poller/docker-entrypoint.sh before citing any cron schedule.data/v2/ — set in js/constants.js.curl the exact URL the frontend constructs BEFORE analyzing parse/schema logic. A 404 beats any schema analysis, and stale localStorage on a dev browser can mask fresh-browser regressions for months.staktrakr) — Thin Publisher (STAK-478)staktrakr — region dfw, 512MB RAM, 1 shared CPU, 3GB volume (/data)/data/staktrakr-api-export caps pack memory (pack.threads=1, pack.windowMemory=32m, gc.auto=0); re-apply after any re-clone. Self-cleaning publisher work tracked in STRK-187.StakTrakr/devops/pollers/remote-poller/fly.toml + Dockerfile0,30), publish cron (8,23,38,53), provider export (*/5), serve.js. Retail/goldback disabled — handled by home poller.cd devops/pollers && fly deploy --config remote-poller/fly.toml --dockerfile remote-poller/Dockerfilefly logs --app staktrakrfly ssh console --app staktrakr| Workflow | Repo | Schedule | Purpose |
|---|---|---|---|
spot-poller.yml | StakTrakr | RETIRED 2026-02-23 — workflow_dispatch only | Was Python→MetalPriceAPI; now Fly.io run-spot.sh |
Merge Poller Branches | StakTrakrApi | RETIRED — repo has no workflows | GH Pages serves the api branch directly |
StakTrakrApi branch model: api is the default and only branch — there is no main. GH Pages (legacy build) serves api at api.staktrakr.com; each force-push triggers pages-build-deployment directly. The No Delete ruleset on refs/heads/api blocks deletion and non-fast-forward pushes (routine publishes are effective fast-forwards; a history rewrite requires temporarily disabling the ruleset via API).
sqld is a self-hosted libSQL server on the home VM (192.168.1.81:8080). Both pollers write to it. Turso Cloud is retained as a nightly DR backup only.
http://staktrakr-sqld:8080 (Docker) / http://192.168.1.81:8080 (Tailscale)staktrakrapi-lbruton.aws-us-east-2.turso.io (Turso Cloud free tier, nightly sync)TURSO_DATABASE_URL + TURSO_AUTH_TOKEN (Infisical)price_snapshots — one row per scrape attempt, per vendor, per 15-min windowprice-extract.js, extract-vision.js, api-export.js (retail-poller only)turso-schema.md (sqld schema page — filename retained from pre-migration)| Location | What to update |
|---|---|
js/api-health.js | Stale thresholds, feed URLs, _normalizeTs logic |
DocVault (/Volumes/DATA/GitHub/DocVault/Projects/StakTrakr/): | |
— Health Checks.md | Health checks, stale thresholds, diagnosis commands |
— Remote Poller.md | Fly config, crons, VM spec, GHA workflow table |
— API Reference.md | Endpoint map, schemas, confidence tiers |
— Turso Schema.md | Database tables, indexes, key queries |
— Home Poller.md | Home poller crons, dashboard, Firecrawl |
— Poller Parity.md | Scrape pipeline comparison between pollers |
lbruton/StakTrakrApi README.md | If endpoints, branches, or directory structure changes |
Lookup:
Read /Volumes/DATA/GitHub/DocVault/Projects/StakTrakr/<page>.mdorGrepon the vault. Deprecated: In-repowiki/anddocs/devops/api-infrastructure-runbook.md— do not update.
python3 << 'EOF'
import urllib.request, json, re
from datetime import datetime, timezone, timedelta
def age_min(ts):
ts = ts.strip()
if not re.search(r'[zZ]$|[+-]\d{2}:?\d{2}$', ts):
ts = ts.replace(' ', 'T') + 'Z'
return (datetime.now(timezone.utc) - datetime.fromisoformat(ts.replace('Z','+00:00'))).total_seconds()/60
def fetch(url):
with urllib.request.urlopen(url, timeout=10) as r: return json.load(r)
print(f"API Health — {datetime.now(timezone.utc).strftime('%Y-%m-%d %H:%M UTC')}\n")
try:
d = fetch('https://api.staktrakr.com/data/api/manifest.json')
age = age_min(d['generated_at'])
print(f"Market {'✅' if age<=30 else '⚠️'} {age:.0f}m ago ({len(d.get('coins',[]))} coins)")
except Exception as e: print(f"Market ❌ {e}")
try:
now = datetime.now(timezone.utc)
def url(dt): return f"https://api.staktrakr.com/data/hourly/{dt.year}/{dt.month:02d}/{dt.day:02d}/{dt.hour:02d}.json"
try: d = fetch(url(now))
except: d = fetch(url(now - timedelta(hours=1)))
age = age_min(d[-1]['timestamp'])
print(f"Spot {'✅' if age<=75 else '⚠️'} {age:.0f}m ago")
except Exception as e: print(f"Spot ❌ {e}")
try:
d = fetch('https://api.staktrakr.com/data/api/goldback-spot.json')
age = age_min(d['scraped_at'])
print(f"Goldback {'✅' if age<=1500 else '⚠️'} {age:.0f}m ago (${d.get('g1_usd')} G1)")
except Exception as e: print(f"Goldback ❌ {e}")
EOF
| Source | Status |
|---|---|
| Notion infrastructure pages | Deprecated 2026-02-25 — do not update |
docs/devops/api-infrastructure-runbook.md | Deprecated — will be deleted after next wiki audit |
DocVault is the single source of truth. All documentation changes go there via /vault-update.