72 lines
4.4 KiB
Markdown
72 lines
4.4 KiB
Markdown
# Changelog
|
|
|
|
All notable changes to this project will be documented in this file.
|
|
|
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|
|
|
## [2.0.0] - 2026-06-22
|
|
|
|
### Security
|
|
- API Key hashing now uses SHA-256 + pepper (SECRET_KEY) with timing-safe comparison via `secrets.compare_digest()`
|
|
- CORS validation rejects `["*"]` when `allow_credentials=True` (Pydantic model_validator)
|
|
- Scope validation: `ClientCreate.scopes` rejects invalid values via `field_validator`
|
|
- Master key comparison uses constant-time compare
|
|
|
|
### Added
|
|
- **Dead Letter Queue (DLQ)**: Failed ARQ jobs pushed to Redis DLQ after `PIPELINE_MAX_RETRIES` attempts. Admin endpoints to list/retry/clear dead jobs (`GET/POST/DELETE /admin/api/queue/dead`)
|
|
- **Circuit Breaker AI**: All AI calls wrapped with `asyncio.wait_for()` + exponential backoff retry (configurable via `AI_REQUEST_TIMEOUT`, `AI_MAX_RETRIES`)
|
|
- **Request ID Middleware**: `X-Request-ID` header injected in all responses + bound to structlog context
|
|
- **Rate Limiting per Plan**: Dynamic rate limits based on client plan (free/standard/premium) via ContextVar
|
|
- **Redis Rate Limit Storage**: Optional persistence via `RATE_LIMIT_STORAGE_URL`
|
|
- **Worker script**: `worker.py` for standalone ARQ worker launch
|
|
- **Docker Compose stack**: PostgreSQL 16 + Redis 7 + MinIO + API + Worker
|
|
- **`.env.example`**: All configuration variables documented
|
|
- **Grafana Dashboard**: `docs/grafana-dashboard.json` with 10 panels (images, tokens, pipeline, storage, WebSocket, errors)
|
|
- **Database indexes**: Composite indexes `(client_id, uploaded_at)` and `(client_id, processing_status)` on images table
|
|
|
|
### Changed
|
|
- `APP_VERSION` aligned to `2.0.0` in config (was `1.0.0`)
|
|
- `delete_files()` now fully async — uses `await backend.delete()` instead of fire-and-forget `ensure_future()`
|
|
- Upload flow: files deleted on DB commit failure (no orphaned S3 files)
|
|
- Gemini client: cached with TTL — recreated if `GEMINI_API_KEY` changes
|
|
- `parse_redis_url()` extracted to `app/workers/redis_client.py` (DRY — was duplicated in main.py and image_worker.py)
|
|
- Rate limit key function encodes plan for per-plan bucket isolation
|
|
- `_FallbackArqPool` moved to `app/workers/arq_fallback.py` (avoids circular imports)
|
|
- ARQ worker: configurable `PIPELINE_TIMEOUT` and `PIPELINE_MAX_RETRIES`, `on_shutdown` handler
|
|
- Pipeline: `push_dead_job()` on final retry failure marks image as `ERROR` with DLQ metadata
|
|
- Admin panel: VITE_API_BASE_URL changed from internal Docker hostname to `http://localhost:8000`
|
|
|
|
### Fixed
|
|
- ARQ fallback now returns explicit warning in `UploadResponse.message` instead of silently ignoring
|
|
- Removed obsolete comment in `ai_vision.py` about `StorageBackend.read`
|
|
- Removed signal handler instability in test fixtures
|
|
- Fixed Docker Compose admin connectivity (browser couldn't resolve internal `backend` hostname)
|
|
|
|
## [1.0.0] - Previous
|
|
|
|
### Added (Phase 3: DX)
|
|
- **WebSockets / Real-Time**:
|
|
- Subscriptions on per-image workflows (`/ws/pipeline/{image_id}`).
|
|
- Redis 60-second Event Buffering for reconnections.
|
|
- Admin Monitor WebSocket feed (`/ws/admin/monitor`).
|
|
- **REST API Versioning**:
|
|
- Global `/api/v1/` prefix for structural stability.
|
|
- Added strict API Sunset Date tracking middleware.
|
|
- **Python SDK (`imago-client`)**:
|
|
- Publishable PyPI-ready package located inside `sdk/`.
|
|
- Automatic `httpx` HTTP reconnects, WebSockets streaming natively wrapped, and robust generic Error classes (`ImagoError`, `AuthError`, etc.).
|
|
- **Admin Backend APIs**:
|
|
- Complete JSON statistics (`/admin/api/stats`), global client configurations (`/admin/api/clients/*`) and Queue observability natively piped to the existing React Interface.
|
|
- **Shaarli Integrations**:
|
|
- Skeleton integration middleware (`integration/shaarli`) capable of bridging Shaarli's events right into Imago using the official SDK.
|
|
- **Extensive Documentation**:
|
|
- Modular guides provided inside `docs/` detailing WebSockets, Integrations, and SDK consumption.
|
|
|
|
### Changed
|
|
- All API routing endpoints have been moved behind the `/api/v1` namespace. Existing API Clients must update base URLs from `/` to `/api/v1/`.
|
|
|
|
### Fixed
|
|
- Fixed unawaited coroutines in async mocks causing `TypeError` on Pytest environments.
|
|
- Fixed an incorrect payload key mapping in `APIClient` responses causing 500s (`AttributeError`).
|
|
- Mocked S3 and ARQ correctly globally to ensure local automated tests pass completely isolated from network logic.
|