refactor: decompose lists.py and albums.py into subpackages (#1276)
* refactor: decompose lists.py and albums.py into subpackages, fix PDS URL healing
Split two monolithic API files into subpackages following the existing
api/tracks/ pattern:
- lists.py (1149 lines) → lists/{router,schemas,reorder,resolver,playlists}.py
- albums.py (995 lines) → albums/{router,schemas,cache,listing,mutations}.py
Also moves PDS URL healing from lazy per-request side effects (copy-pasted
in 5 API endpoints) to the jetstream identity event handler, where it
belongs. Identity events fire on both handle changes and PDS migrations,
so resolving the DID there keeps the cached pds_url warm proactively
instead of discovering staleness at request time.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: correct mock targets for decomposed module paths
- AsyncDidResolver: patch at source (atproto_identity.did.resolver)
since ingest.py uses a deferred import
- get_async_redis_client: update to backend.api.albums.cache
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: hoist deferred imports to top-level in decomposed modules
Move ~15 deferred imports to module-level where they don't risk circular
dependencies. The only remaining deferred import in the new packages is
backend.api.tracks.mutations.delete_track (cross-package API call).
Also keeps the AsyncDidResolver import in ingest.py deferred — it's a
heavy external dependency in a background task module.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: update mock targets for hoisted imports in album tests
With imports at top-level, mocks must target the importing module's
namespace, not the source module.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
authored by