feat: beartype runtime type checking + test infrastructure improvements (#619)
* fix: enable beartype runtime type checking and fix type violations
enables beartype for runtime type checking across the backend package.
this catches type violations at function call time, improving reliability.
**type fixes:**
- `_get_existing_track_order`: accept `str | None` for album_atproto_uri
- `_emit_copyright_label`: use `int` for highest_score (matches db model)
- `ModerationClient.__init__`: accept `int | float` for timeout_seconds
- `UploadProgressTracker`: accept `int | float` for min_time_between_updates
- `hash_file_chunked`: use `BinaryIO | IOBase` (works with BytesIO and file handles)
- `build_track_record` callers: guard against None r2_url before calling
**test fixes:**
- `MockStorage`: inherit from `R2Storage` for proper type compatibility
- `test_update_album_title`: add `r2_url` to track fixture
**refactors:**
- `storage/__init__.py`: import `R2Storage` directly (no lazy forward ref)
- `image.py`, `audio.py`: use `typing.Self` for classmethod return types
- `auth.py`: import `EllipticCurvePrivateKey` directly
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* chore: add beartype as explicit dependency
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: disable automatic perpetual task scheduling in tests
The docket worker's automatic perpetual task scheduling was causing
event loop issues during test teardown. The Worker creates async
connections that get attached to one event loop, but TestClient
teardown runs on a different loop.
Added DOCKET_SCHEDULE_AUTOMATIC_TASKS setting (default: true) and
set it to false in test environment to prevent this issue.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* perf: session-scope TestClient fixture for 5x faster tests
The client fixture was function-scoped, causing the full FastAPI
lifespan (database init, services, docket worker) to run for each
test. Switching to session-scope reduces test_stats.py from 26s to 5s.
Full test suite now runs in ~17s instead of potentially much longer.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* refactor: remove init_db() from lifespan
init_db() called Base.metadata.create_all on every server start.
This was a no-op since all tables already exist in dev/staging/prod.
Tests handle their own table creation via conftest.py.
Dead code removed. Database schema is managed by alembic migrations.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
authored by
zzstoatzz.io
Claude Opus 4.5
and committed by
GitHub
6d1ec368
f10724ce