Add GET /admin/rate-limits endpoint (admin-only) that returns current
rate limit configuration and request statistics for all rate-limited
endpoints (/auth/register and /auth/login). Tracks total requests and
rejection counts via in-memory counters.
Includes tests for admin access, non-admin rejection, empty state,
request tracking, and configuration display.
Closesleeworks-agents/SPARC#1675
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The scheduler was refactored (PR #1665) to use the pooled
get_db_client() from SPARC.auth instead of creating its own
DatabaseClient. Update test mocks accordingly and remove the
db.close() assertion since the pooled client is no longer closed
by the scheduler.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
7 test cases covering:
- PDF on disk analyzed directly (no download)
- Auto-download from cached metadata link when PDF missing
- FileNotFoundError when no cached link available
- Cached patent without pdf_link raises FileNotFoundError
- Analysis pipeline failure returns error string gracefully
- Model override parameter forwarded to LLM
- FileNotFoundError during parsing re-raised (not swallowed)
Closesleeworks-agents/SPARC#1661
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Move all completed items (security hardening, structured logging, dark mode,
export, webhooks, scheduled analysis, multi-model, trend charts, CI, etc.)
into a new Completed section. Reorganize remaining P1/P2/P3 items to reflect
current priorities. Add new next-horizon items: historical diffing, patent
classification tagging, user API keys, batch export, and multi-tenant support.
Closesleeworks-agents/SPARC#1659
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace the per-invocation DatabaseClient creation in
run_scheduled_analysis() with the shared pooled client from
SPARC.auth.get_db_client(). This avoids creating a new database
connection on every scheduler tick, which could exhaust the connection
pool under load.
Key changes:
- Import get_db_client from SPARC.auth instead of DatabaseClient
- Remove manual connect/initialize_schema/close calls
- Remove unused SPARC.config import
Closesleeworks-agents/SPARC#1658
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
20 test cases covering:
- GET/POST/DELETE /admin/tracked endpoints with admin auth enforcement
- GET /admin/alerts with limit parameter and auth
- scheduler.run_scheduled_analysis() for multi-company analysis, alert
triggering on significant patent count changes, graceful failure handling
Closesleeworks-agents/SPARC#1656
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Covers GET /export/{company_name} and /export/{company_name}/pdf with
13 test cases: successful export, 404 on missing data, auth enforcement,
filename sanitization, XML-special character handling in PDF, and
multi-row output validation.
Closesleeworks-agents/SPARC#1655
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The prose-invert class was applied unconditionally, causing inverted
(light) text in light mode within the AI analysis results section.
Changed to dark:prose-invert so it only activates when dark mode is
enabled.
Note: The broader dark mode feature (issue #1605) is already fully
implemented -- ThemeContext, toggle button, CSS variables, dark:
variants across all pages. This fix addresses the only remaining
unstyled element.
Closesleeworks-agents/SPARC#1605
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Uncomment the ruff check and pytest steps in the Gitea Actions build
workflow so that linting violations and test failures block image builds.
Fix all pre-existing ruff violations (E402 import ordering in analyzer.py,
F821 undefined name in api.py, I001 unsorted imports in test files, F401
unused import in test_rate_limit.py).
Closesleeworks-agents/SPARC#1559Closesleeworks-agents/SPARC#1560
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace Alpine-style commands (apk, py3-pip, musl-dev) and incorrect
apt usage with proper apt-get invocations and Debian package names for
the ubuntu-latest runner.
Add gitea.leeworks.dev image references alongside build directives so
`docker compose up` pulls pre-built images while `--build` still builds
from local sources.
API_URL already includes a trailing slash, so the extra slash in
proxy_pass produced //auth/login paths, causing 404s. Also clear
ROOT_PATH since nginx strips /api/ before proxying.
Switch docker-compose.yml from bind mount to a named volume (patent_data)
so downloaded PDFs survive container recreation. Add a "Patent PDF Storage"
section to DEPLOYMENT.md covering Docker Compose, Kubernetes PVC, and S3
alternatives.
Closesleeworks-agents/SPARC#1360
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace hardcoded dark-theme hex colors in recharts components
(tooltips, axes) with a useChartTheme hook that reads the current
theme from ThemeContext. Charts now render correctly in both light
and dark mode.
Closesleeworks-agents/SPARC#1324
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Reject unsupported LLM model identifiers with HTTP 400 on all analysis
endpoints (single, batch, async batch). The SUPPORTED_MODELS list was
already defined for the /models endpoint but not enforced on incoming
requests. This completes the multi-model support feature by adding the
missing server-side validation.
Closesleeworks-agents/SPARC#1013
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Closesleeworks-agents/SPARC#426
- Generate schema.d.ts from committed openapi.json using openapi-typescript
- Rewrite types/index.ts to derive all application types from the generated schema
- Add CI step in both build.yaml and test.yaml to verify schema.d.ts stays in sync
- TypeScript compilation passes with zero errors
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Combine both useQuery hooks (modelsQuery for model selector, jobsQuery for
job history) and pass selectedModel to analyzeBatch while also triggering
jobsQuery.refetch() on successful submission.
Thread the optional model parameter through the entire analysis pipeline:
- analyzer.py: analyze_company, _analyze_company_safe, analyze_companies,
and analyze_single_patent now accept and forward model override
- api.py: single company endpoint accepts model query param; batch and
async batch endpoints pass request.model through to the analyzer
- client.ts: analyzeCompany, analyzeBatch, analyzeBatchAsync accept model;
add listModels() to fetch available models from GET /models
- Analysis.tsx: add model selector dropdown that loads from /models API
- Batch.tsx: add model selector alongside the workers slider
Users can now pick a specific LLM (GPT-4o, Claude 3.5, Gemini, etc.)
per analysis request, or leave it on the server default.
Closesleeworks-agents/SPARC#351
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add a Job History section that loads past jobs via useQuery with:
- Animated skeleton placeholders while the job list is loading
- Error banner with retry button when the API call fails
- Empty state with helpful message when no jobs exist
- Job list cards with status badges and progress bars
Also improve the batch submission error state with a retry button
alongside the existing dismiss button.
Closesleeworks-agents/SPARC#343
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>