Guard /api/ideas/from-url and /from-text against uncapped LLM invocations
The two LLM-backed ingest endpoints — ingest_url (line 844) and ingest_text (line 861) in src/project_forge/web/routes.py — accept POST requests from any client with no rate limiting. The _check_rate_limit helper already exists and is applied to /approve, /promote, and /report, but was never wired to the ingest paths, which are far more expensive: each call triggers a full Claude CLI or Anthropic API round-trip. The fix adds request: Request to both route signatures and calls _check_rate_limit(f"ingest:{client_ip}") at the top of each handler, mirroring the existing pattern exactly. The scaffold endpoint (line 350) has the same gap and should be patched at the same time. No new infrastructure is required; a new test file covers the 429 response and verifies the non-LLM endpoints are unaffected.
Feasibility: 0.93
MVP Scope: Modify src/project_forge/web/routes.py: add request: Request param + _check_rate_limit(f"ingest:{client_ip}") to ingest_url (line 844), ingest_text (line 861), and scaffold_idea (line 350). Create tests/test_routes_rate_limit.py with parametrized tests asserting HTTP 429 after 5 rapid POSTs to each protected endpoint and HTTP 200 on the 1st call.
Guard /api/ideas/from-url and /from-text against uncapped LLM invocations
The two LLM-backed ingest endpoints —
ingest_url(line 844) andingest_text(line 861) insrc/project_forge/web/routes.py— accept POST requests from any client with no rate limiting. The_check_rate_limithelper already exists and is applied to/approve,/promote, and/report, but was never wired to the ingest paths, which are far more expensive: each call triggers a full Claude CLI or Anthropic API round-trip. The fix addsrequest: Requestto both route signatures and calls_check_rate_limit(f"ingest:{client_ip}")at the top of each handler, mirroring the existing pattern exactly. The scaffold endpoint (line 350) has the same gap and should be patched at the same time. No new infrastructure is required; a new test file covers the 429 response and verifies the non-LLM endpoints are unaffected.Feasibility: 0.93
MVP Scope: Modify
src/project_forge/web/routes.py: addrequest: Requestparam +_check_rate_limit(f"ingest:{client_ip}")toingest_url(line 844),ingest_text(line 861), andscaffold_idea(line 350). Createtests/test_routes_rate_limit.pywith parametrized tests asserting HTTP 429 after 5 rapid POSTs to each protected endpoint and HTTP 200 on the 1st call.