feat: enhance parental controls with bulk edit, improved cert lookup, trending filtering, and blockAdult#1
Conversation
Admin-enforced content rating limits per user: - Max movie rating (MPAA: G through NC-17) - Max TV rating (US Parental Guidelines: TV-Y through TV-MA) - Block unrated content toggle (fail-closed) Filtering applied to all discover routes and search with parallel TMDB certification lookups. Backfills from next page when filtering drops results below 15. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
0f47a8e to
c2cdbad
Compare
|
Found this while testing — postFilterDiscoverMovies and postFilterDiscoverTv both had an early return gated on blockUnrated: if (!limits.blockUnrated) return filtered; ← skips ALL rating filtering Also fixed filterMovieBatch/filterTvBatch, which hardcoded true for the blockUnrated parameter in shouldFilterMovie/shouldFilterTv, meaning unrated content would be blocked even when the user hadn't enabled that option. Repro: Set a user to PG-13 max, leave "block unrated" unchecked → R-rated movies visible on trending/discover. |
Critical bug: postFilterDiscoverMovies and postFilterDiscoverTv had an early return that only ran the rating post-filter when blockUnrated was enabled. Routes like /trending that lack TMDB certification.lte pre-filter rely entirely on post-filtering, so R-rated movies and TV-MA shows passed through unfiltered when a user had a max rating set but blockUnrated was false. Fixes: postFilterDiscoverMovies runs when maxMovieRating OR blockUnrated is set. postFilterDiscoverTv runs when maxTvRating OR blockUnrated is set. filterMovieBatch and filterTvBatch use actual limits.blockUnrated instead of hardcoded true.
c2cdbad to
415d4ff
Compare
|
Follow-up: pushed a fix for two issues I found during local testing. Bug — R-rated content visible to restricted users Performance — avoid redundant post-filtering on pre-filtered routes Fix: added a |
ba9d386 to
415d4ff
Compare
|
Hey! Sorry, saw your email but it's been a busy week so I didn't get a chance to reply. Just saw your PR, so I'll dig into your comments and review everything this weekend. Thanks for putting this together! |
|
No problem! I'm just really glad someone else wants this as bad as I do! I hope you get to look at it and give it a test. |
f8ee51d to
4621c8d
Compare
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Tip Issue Planner is now in beta. Read the docs and try it out! Share your feedback on Discord. Comment |
|
should i close this? |

Hey! Following up on my comment on seerr-team#2415 — here are the enhancements I mentioned, built on top of your branch.
What this adds
Enhanced certification lookup
The existing
filterMovieBatchgrabs the first US release date cert it finds. This can pick up an "NR" from an unrated director's cut instead of the theatrical "R" rating. This change collects all US release date certifications, excludes NR/unrated entries, and returns the most restrictive one. Falls back to international ratings if no US cert exists. SamegetMovie()API call — just smarter parsing of the response.Trending route filtering
/trendingwas the only discover route without parental controls filtering. This splits trending results into movies/tv/other, runs the existingpostFilterDiscoverMoviesandpostFilterDiscoverTvon the respective sets. Only activates when the user has parental controls set — zero overhead otherwise.Block Adult content (optional)
Adds a
blockAdultboolean checkbox alongsideblockUnrated. This filters on TMDB'sadultflag, which covers explicit/pornographic content and is separate from the MPAA rating system. It's a free in-memoryresults.filter(m => !m.adult)— no extra API calls since the field is already in every TMDB response.Bulk edit parental controls
Admins can now set parental controls (movie rating, TV rating, block unrated, block adult) on multiple users at once via the existing bulk edit modal in the user list. The backend creates
UserSettingsif needed and only updates the fields that are provided.Debug logging
Blocked items now log the title, ID, certification, and max rating at debug level for easier troubleshooting.
Files changed
server/constants/contentRatings.ts— addedblockAdultto interfaceserver/entity/UserSettings.ts— addedblockAdultcolumnserver/interfaces/api/userSettingsInterfaces.ts— addedblockAdultto response typeserver/routes/discover.ts— enhanced cert lookup, adult pre-filter, trending filtering, loggingserver/routes/user/index.ts— bulk edit with parental controlsserver/routes/user/usersettings.ts—blockAdultin GET/POST endpointsserver/migration/postgres/1770627987305-AddBlockAdult.ts— new migrationserver/migration/sqlite/1770627987305-AddBlockAdult.ts— new migrationsrc/components/UserList/BulkEditModal.tsx— parental controls UI in bulk editsrc/components/UserProfile/UserSettings/UserParentalControlsSettings/index.tsx— blockAdult checkbox