Triage review: Resolved: frontend/package-lock.json exists (4728 lines). Closing as already complete.
Triage review: Resolved: Batch.tsx and Analytics.tsx already have loading and error states. Closing as already complete.
Triage review: Resolved: docs/DEPLOYMENT.md has detailed patent PDF volume mount documentation. analyze_single_patent auto-downloads PDFs from cached metadata. Closing as already complete.
Triage review: Resolved: types.py has patent_id: str (line 7). Already typed correctly. Closing as already complete.
Triage review: Resolved: config.py reads SERP_CACHE_TTL_HOURS from env var (default 24). Used in analyzer.py. Closing as already complete.
Triage review: Resolved: config.py reads MODEL from env var with fallback to anthropic/claude-3.5-sonnet. Closing as already complete.
Triage review: Resolved: analyzer.py, serp_api.py, and llm.py all use the logging module. No print() calls remain. Closing as already complete.
Resolved (triage review): api.py uses slowapi Limiter with 5/min on register and 10/min on login. Returns HTTP 429 with Retry-After header. tests/test_rate_limit.py exists. Closing as already…
Resolved (triage review): auth.py uses a module-level _db_client singleton with init_db_client()/close_db_client()/get_db_client(). No new DatabaseClient is created per request. Closing as…
Resolved (triage review): auth.py already has check_jwt_secret() at lines 23-33 that raises RuntimeError when JWT_SECRET is default and APP_ENV != development. Closing as already complete.