Add try/catch around `request.json()` in all POST routes to return a
400 instead of crashing on malformed bodies. Validate `type` as a
strict `"movie" | "tv"` enum in search, discover, import, and resolve
routes. Validate `tmdbId` as a positive integer. Add a
`SORT_BY_PATTERN` regex and page-range check (1–500) to the discover
route. Wrap all outbound TMDB calls in try/catch and return 502 on
failure so clients get a structured error rather than an unhandled
rejection.
Fix optimistic-update rollbacks in `use-title-actions`: capture
`prevStatus` and `prevWatches` before each mutation and restore both
atoms in the catch block for catchUp, handleMarkSeason,
handleUnmarkSeason, and single-episode toggle.
Fix a bug in `getContinueWatchingFeed` where the watchDateMap could
hold a stale date for episodes watched more than once; the map now
keeps the most-recent `watchedAt` per episode.
Navigate instantly to /titles/tmdb-{id}-{type} and show a skeleton
while the new /api/titles/resolve endpoint handles the full import
(TMDB fetch, availability, recommendations, colors). Existing titles
resolve in ~5ms; the URL is replaced with the UUID once resolved.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>