- Fix route ordering bug: GET /analyze/batch was shadowed by
GET /analyze/{company_name} causing all GET requests to /analyze/batch
to be erroneously handled as single-company analysis (503). Move
/analyze/batch GET registration to before the {company_name} route.
- Update TypeScript schema.d.ts: add AnalysisRecord, PaginatedAnalysisResponse,
PaginatedJobsResponse schemas; add GET /analyze/batch operation with
cursor+limit+company_name params; update list_jobs_jobs_get to include
cursor param and return PaginatedJobsResponse.
- Update frontend/src/api/client.ts: add listBatchAnalyses() method with
cursor/limit support; update listJobs() to accept cursor and return
PaginatedJobsResponse; default limit changed from 10 to 50.
- Update frontend/src/types/index.ts: export AnalysisRecord,
PaginatedAnalysisResponse, PaginatedJobsResponse.
- Expand tests/test_pagination.py: add auth fixture so tests pass JWT
validation; add 11 new /jobs tests covering first page, last page,
subsequent pages, empty results, status filter, limit boundaries, cursor
forwarding, and paginated response shape.
Closesleeworks-agents/SPARC#1684
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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>
Add a new GET /analyze/batch endpoint that returns stored analysis results
with cursor-based pagination (default limit 50, max 200). Also update the
existing /jobs endpoint defaults from limit=10/max=100 to limit=50/max=200
for consistency.
The database layer gains a list_analyses() method with cursor support using
(timestamp, id) ordering, matching the existing list_jobs() pattern.
Includes tests for pagination behavior, boundary limits, cursor forwarding,
company name filtering, and empty result sets.
Closesleeworks-agents/SPARC#1669
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add a CompanyName validated type enforcing 2-100 character length and
allowing only alphanumeric characters, spaces, hyphens, ampersands, and
periods. Applied to all endpoints accepting company names: /analyze,
/analyze/patent, /analyze/batch, /admin/tracked, and /export.
Includes unit tests covering too-short, too-long, special character,
leading-character, and valid edge cases for both single and batch
endpoints.
Closesleeworks-agents/SPARC#1670
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Move seven completed items from the P1 and P2 sections into the
Completed section: in-memory jobs persistence, export endpoint tests,
tracked company admin tests, webhook integration tests, S3 storage
tests, auto-download path tests, and scheduler DatabaseClient refactor.
The P2 section now only lists the two genuinely open items: cursor-based
pagination (Issue #1669) and request validation (Issue #1670).
Closesleeworks-agents/SPARC#1678
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>