These environment variables were already supported in config.py but
were not documented in .env.example, making them hard to discover.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds a step to install Node.js and run tsc --noEmit in the frontend
directory, catching TypeScript type errors before images are built.
Ruff was already present; this completes issue #260.
Closesleeworks-agents/SPARC#260
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add a new /export/{company_name}/pdf endpoint that generates a formatted
PDF report using reportlab, including a summary table and all analysis
results. Add the corresponding frontend Export PDF button alongside the
existing Export CSV button on the Analysis page.
Closesleeworks-agents/SPARC#85
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Send HTTP POST notifications to configured webhook URLs when batch
jobs complete or when scheduled analysis detects significant changes.
- Add SPARC/webhooks.py with retry logic (3 attempts, exponential backoff)
- Support generic HTTP POST and Slack-compatible text payloads
- Integrate into batch job completion handler in api.py
- Configure via WEBHOOK_URLS env var (comma-separated)
- Payload includes event type, job ID, status, and summary
Closesleeworks-agents/SPARC#23
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add APScheduler-based background task that periodically re-analyzes
tracked companies and alerts on significant patent count changes.
- Add tracked_companies and alerts tables to database schema
- Add SPARC/scheduler.py with configurable interval and threshold
- Add admin endpoints: GET/POST/DELETE /admin/tracked, GET /admin/alerts
- Scheduler starts at app startup; interval via SCHEDULE_INTERVAL_HOURS
- Change threshold configurable via CHANGE_THRESHOLD_PERCENT env var
- apscheduler is optional; graceful fallback if not installed
Closesleeworks-agents/SPARC#22
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Allow users to choose the LLM model on a per-analysis basis. The
model field is optional in both single and batch analysis requests,
defaulting to the server-configured MODEL env var. The model used
is recorded in the analysis result and database.
- Add model parameter to LLMAnalyzer.analyze_patent_content and
analyze_patent_portfolio
- Add model field to CompanyAnalysisResult and API response
- Add model field to BatchAnalysisRequest
- Add GET /models endpoint listing supported models and the default
- Store model in llm_messages metadata for attribution
Closesleeworks-agents/SPARC#37
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add openapi-typescript devDependency and npm scripts for generating
typed TypeScript schema from the FastAPI OpenAPI spec. Include a
static openapi.json snapshot for offline generation.
- npm run generate: fetch schema from running backend and generate types
- npm run generate:local: generate types from the bundled openapi.json
Closesleeworks-agents/SPARC#26
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add GET /analytics/trends endpoint returning per-company analysis
counts by month and analysis type distribution over time. Render
these as a line chart (analyses per company) and stacked bar chart
(analysis types) on the Analytics page using recharts.
Closesleeworks-agents/SPARC#24
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add /compare route with two-panel layout for comparing company patent
portfolios. Each panel shows patent count, analysis timestamp, and
full LLM narrative. The page is responsive (stacks vertically on
mobile) and supports URL params (?a=nvidia&b=intel) for shareability.
Closesleeworks-agents/SPARC#21
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add GET /export/{company_name} backend endpoint that returns analysis
records as a downloadable CSV file. Add Export CSV button to the
Analysis page that triggers the download via the API.
Closesleeworks-agents/SPARC#20
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add a cursor query parameter to GET /jobs and return a next_cursor
field in the response envelope. Existing clients using only limit
continue to work without modification. The cursor is an opaque token
encoding created_at and job_id for stable keyset pagination.
Closesleeworks-agents/SPARC#25
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Introduce a StorageBackend abstraction (local filesystem and S3) for
patent PDF storage. When STORAGE_BACKEND=s3, PDFs are read/written via
boto3 to an S3-compatible bucket instead of the local filesystem.
- Add SPARC/storage.py with LocalStorageBackend and S3StorageBackend
- Update serp_api.py save_patents and parse_patent_pdf to use storage
- Add storage config vars to config.py and .env.example
- Add optional MinIO service to docker-compose.yml (--profile s3)
- Add boto3 to requirements.txt
Closesleeworks-agents/SPARC#38
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Enable Tailwind "class" dark mode strategy
- Use CSS custom properties for theme colors (bg, text, border)
- Add ThemeProvider context with toggle and localStorage persistence
- Add Sun/Moon toggle button in the header navigation
- Inline script in index.html prevents FOUC on page load
- All pages (Layout, Login, Register, ProtectedRoute) support both modes
- Default theme follows system preference (prefers-color-scheme)
Closesleeworks-agents/SPARC#33
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Analytics page now shows skeleton loaders (cards and chart placeholders)
while data loads, and displays a retry button when the API call fails.
Batch page error state now shows the actual error message and suggests
user action.
Closesleeworks-agents/SPARC#16
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When the PDF is not on disk, analyze_single_patent now looks up the
cached PDF link from the database and downloads it automatically.
If no link is cached, a clear FileNotFoundError is raised. Also adds
a GET /analyze/patent/{patent_id} API endpoint that exposes this
functionality and returns 404 when the PDF cannot be obtained.
Closesleeworks-agents/SPARC#36
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add module-level logger to serp_api.py with INFO-level messages for
patent queries and PDF downloads, and DEBUG-level messages for cache
hits and parsing details. All three target files (analyzer.py,
serp_api.py, llm.py) now use structured logging with no print() calls.
Closesleeworks-agents/SPARC#46
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Upgrade lucide-react to v1.7.0 for proper TypeScript declarations and
add a TypeScript type check step to the test workflow. Both ruff (Python)
and tsc --noEmit (TypeScript) now block merging on failure.
Closesleeworks-agents/SPARC#52
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add test job to build.yaml that runs pytest and ruff before building images
- Add standalone test.yaml workflow for PRs
- Add ruff.toml with E/F/I rules configured
- Fix all ruff lint errors: sort imports, remove unused imports, fix re-exports
- Build jobs now depend on test job passing (needs: test)
Closesleeworks-agents/SPARC#18Closesleeworks-agents/SPARC#19
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Replace get_db_client() creating new DatabaseClient on every call with a
module-level singleton initialized once at startup via init_db_client()
- Add init_db_client() and close_db_client() lifecycle functions called
from FastAPI lifespan handler
- Migrate all DatabaseClient methods from legacy self.connect()/self.conn
to pooled self.get_conn() context manager for thread-safe connection reuse
- Pool is properly torn down on application shutdown
Closesleeworks-agents/SPARC#7
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Make LLM model configurable via MODEL env var, default anthropic/claude-3.5-sonnet (#12)
- Expose SERP cache TTL as SERP_CACHE_TTL_HOURS env var, default 24 hours (#13)
- Fix Patent.patent_id type annotation from int to str in types.py (#14)
- Replace all print() calls with structured logging in analyzer.py and llm.py (#11)
- Add LOG_LEVEL config with basicConfig setup in config.py
- Add model and serp_cache_ttl_hours to config.py
Closesleeworks-agents/SPARC#11Closesleeworks-agents/SPARC#12Closesleeworks-agents/SPARC#13Closesleeworks-agents/SPARC#14
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>