- Add health check endpoint at GET /api/diagnostic/health
- Auth-protected via @require_login (no-op when AUTH_ENABLED=False)
- Checks database (SELECT 1) and Redis (ping) with 2s timeouts
- Returns healthy/degraded/unhealthy with per-check detail
- Returns HTTP 503 when database is down, 200 otherwise
- 7 new unit tests covering all status scenarios
- Update docs/API.md with Grafana/monitoring integration notes
- Fixes test_cors_headers_absent_when_disabled CI timeout
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
- Add release_names.json mapping version ranges to codenames
- Add release_name property to Settings in app/config.py
- Update build metadata script to include codename in RUNTIME_INFO
- Display release codename in status dashboard and page footer
- Inject release_name globally via template response wrapper
- Update ROADMAP.md with codenames for all milestone releases
- Add docs/ReleaseNaming.md with naming guide and best practices
- Add comprehensive tests for release name resolution
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
The Docker container failed to start because the Alembic migrations
directory was not being copied into the image. The init_db() function
calls _run_alembic_upgrade() which requires /app/migrations to exist.
Added COPY instructions for ./migrations and ./alembic.ini to both
Dockerfile and Dockerfile.local.
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
- Change default per_page from 50 to 25
- Rename total_items → total, total_pages → pages in pagination response
- Add next/previous URL fields to pagination response
- Update view and template to use new field names
- Update tests and API docs
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
- Replace bare Exception catches with sa.exc.OperationalError in migration 007
- Use ScriptDirectory.get_heads() for dynamic revision ID assertions in tests
- Make migration count assertion flexible (>= 8 instead of == 8)
- Rewrite pending migrations test to actually test upgrade from revision 006
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
- Add pytest-timeout>=2.3.0 to requirements-dev.txt with 120s global default
- Fix test_fallback_file_id_lookup: add missing _should_upload_* mocks that
caused .delay() calls to hang on Redis broker connection
- Split CI test job into two stages:
- Quick Tests (timeout: 10min, ~2min run): unit + basic integration
- Integration Tests (timeout: 20min): Docker containers, external services
- Quick tests gate integration tests for fast-fail feedback
- Build job now depends on both test stages
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
redis.Redis.scan() returns a tuple at runtime but mypy infers
Awaitable[Any] from the generic ResponseT return type, causing
a "not iterable" error on tuple unpacking.
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
_ensure_indexes() now verifies the target column exists in the table
before executing CREATE INDEX IF NOT EXISTS. This prevents failures
when migrating legacy database schemas that don't yet have all columns
(e.g. files table without created_at or mime_type).
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>