feat(apify): any authenticated key can poll GET /api/apify/runs/{runId} (chat#1840)

Merged
SW
4mo ago
+17-19

Item 1 of recoupable/chat#1840. No docs or database dependency — docs#262 and database#39 both closed unmerged per the design decision below (the existing docs page already matches the new behavior).

Why

An account-scoped key can start a scrape via POST /api/socials/{id}/scrape but got Forbidden polling its own run — validateGetScraperResultsRequest was admin-only (7/7 Forbidden polls in the issue's production evidence, while docs/skills/task prompts all direct agents to poll).

Decision (2026-07-03, supersedes the owner-or-admin draft)

Any valid API key or Bearer token can poll any run id. Scrape datasets are public social content and Apify run ids are long random strings; possession + a valid credential is sufficient. Authentication still gates the endpoint so anonymous callers can't use it as a free Apify proxy. Admin behavior is unchanged (admins hold valid credentials); backend pollers unaffected.

What

One swap in validateGetScraperResultsRequest: validateAdminAuth → validateAuthContext. 401 (no/both credentials), 400 (bad runId), 200/500 all unchanged in shape. Final diff: 2 files, +17/−19.

Tests (TDD, RED→GREEN)

Validator suite rewritten for the new contract: auth-error propagation, 400 empty runId, any-authenticated-caller passthrough. Full lib/apify + lib/socials suites: 117 passed; tsc --noEmit no new errors vs main; eslint clean.

Done-when — preview verification to follow as a comment

  • an account key polls a real runId to completion (no admin token involved) — verified on preview 2026-07-03, results table in comments; scrape-start with an account key was already working in prod (this PR only changes the poll validator)

🤖 Generated with Claude Code