docs: update STATUS.md with teal.fm scrobbling integration (#468)

- add Dec 4 section for PR #467 (teal.fm scrobbling)
- document lexicons, configuration, and code quality improvements
- update now-playing section to reflect native scrobbling
- add teal.fm to "what's working" list
- update last modified date

๐Ÿค– Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude <noreply@anthropic.com>

authored by zzstoatzz.io Claude and committed by GitHub e9e1e592 cf53ab67

Changed files
+33 -5
+33 -5
STATUS.md
··· 47 48 ### December 2025 49 50 #### unified search (PR #447, Dec 3) 51 52 **what shipped**: ··· 180 - returns track metadata, playback position, timestamp 181 - 204 when nothing playing, 200 with track data otherwise 182 183 - **speculative integration with teal.fm**: 184 - - opened draft PR to Piper (teal.fm's scrobbling service): https://github.com/teal-fm/piper/pull/27 185 - - adds plyr.fm as a source alongside Spotify and Last.fm 186 - - **status**: awaiting feedback from teal.fm team 187 188 --- 189 ··· 342 - โœ… copyright moderation system with admin UI 343 - โœ… ATProto labeler for copyright violations 344 - โœ… unified search with Cmd/Ctrl+K (fuzzy matching via pg_trgm) 345 346 **albums** 347 - โœ… album database schema with track relationships ··· 484 485 --- 486 487 - this is a living document. last updated 2025-12-03.
··· 47 48 ### December 2025 49 50 + #### teal.fm scrobbling integration (PR #467, Dec 4) 51 + 52 + **what shipped**: 53 + - native teal.fm scrobbling: when users enable the toggle, plays are recorded to their PDS using teal's ATProto lexicons 54 + - scrobble triggers at 30% or 30 seconds (whichever comes first) - same threshold as play counts 55 + - user preference stored in database, toggleable from portal โ†’ "your data" 56 + - settings link to pdsls.dev so users can view their scrobble records 57 + 58 + **lexicons used**: 59 + - `fm.teal.alpha.feed.play` - individual play records (scrobbles) 60 + - `fm.teal.alpha.actor.status` - now-playing status updates 61 + 62 + **configuration** (all optional, sensible defaults): 63 + - `TEAL_ENABLED` (default: `true`) - feature flag for entire integration 64 + - `TEAL_PLAY_COLLECTION` (default: `fm.teal.alpha.feed.play`) 65 + - `TEAL_STATUS_COLLECTION` (default: `fm.teal.alpha.actor.status`) 66 + 67 + **code quality improvements** (same PR): 68 + - added `settings.frontend.domain` computed property for environment-aware URLs 69 + - extracted `get_session_id_from_request()` utility for bearer token parsing 70 + - added field validator on `DeveloperTokenInfo.session_id` for auto-truncation 71 + - applied walrus operators throughout auth and playback code 72 + - fixed now-playing endpoint firing every 1 second (fingerprint update bug in scheduled reports) 73 + 74 + **documentation**: `backend/src/backend/_internal/atproto/teal.py` contains inline docs on the scrobbling flow 75 + 76 + --- 77 + 78 #### unified search (PR #447, Dec 3) 79 80 **what shipped**: ··· 208 - returns track metadata, playback position, timestamp 209 - 204 when nothing playing, 200 with track data otherwise 210 211 + **teal.fm integration**: 212 + - native scrobbling shipped in PR #467 (Dec 4) - plyr.fm writes directly to user's PDS 213 + - Piper integration (external polling) still open: https://github.com/teal-fm/piper/pull/27 214 215 --- 216 ··· 369 - โœ… copyright moderation system with admin UI 370 - โœ… ATProto labeler for copyright violations 371 - โœ… unified search with Cmd/Ctrl+K (fuzzy matching via pg_trgm) 372 + - โœ… teal.fm scrobbling (records plays to user's PDS) 373 374 **albums** 375 - โœ… album database schema with track relationships ··· 512 513 --- 514 515 + this is a living document. last updated 2025-12-04.