mirror of
https://github.com/screentinker/screentinker.git
synced 2026-08-13 22:03:13 -06:00
Players replay a cached playlist, so the id reported on play_start can outlive the row it names. play_logs.content_id carries a foreign key to content(id), and the id went straight into the INSERT — so deleting a piece of content made every subsequent play of it throw, and the whole event was discarded by a catch that logged no identifiers. On production this fired roughly 360 times in six hours and wrote zero rows in 24h: Reports was recording nothing at all, for everyone. Widgets had a quieter version of the same bug. play_logs.widget_id exists and was never written, so a widget play could not be attributed even when it did insert, and play_end matched on content_id alone and so could never close a widget's open row. The reported id is now looked up before use and written to whichever column it belongs to. An id matching neither degrades to null references rather than losing the event — content_name still records what played. A play event for a device that does not exist is still refused; that foreign key is a real invariant, not an obstacle. play_end matches on either column, and breaks ties on id: started_at has second granularity, so two plays inside one second tie on it and the wrong row could be closed. The new tests caught exactly that as flakiness before it was pinned. The catch now logs the event, device, content and zone. Without them this was undiagnosable in production. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|---|---|---|
| .. | ||
| config | ||
| db | ||
| lib | ||
| middleware | ||
| player | ||
| routes | ||
| scripts | ||
| services | ||
| test | ||
| ws | ||
| .gitignore | ||
| config.js | ||
| package-lock.json | ||
| package.json | ||
| server.js | ||
| version.js | ||