feat(permissions): add LIMIT_ONE_SEASON permission#2752
feat(permissions): add LIMIT_ONE_SEASON permission#2752dangerouslaser wants to merge 1 commit intoseerr-team:developfrom
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (5)
✅ Files skipped from review due to trivial changes (1)
🚧 Files skipped from review as they are similar to previous changes (2)
📝 WalkthroughWalkthroughAdds a new Permission.LIMIT_ONE_SEASON flag and enforces a single-season request constraint: backend throws a new SeasonLimitError when applicable; routes map it to HTTP 403; frontend disables/mutates multi-season selection and updates UI/messages accordingly. Changes
Sequence DiagramsequenceDiagram
participant User as User (Limited)
participant Modal as TV Request Modal
participant API as POST /api/v1/request
participant Server as MediaRequest Handler
participant Resp as HTTP Response
User->>Modal: select seasons (attempt >1)
Modal->>Modal: check isOneSeasonLimited
Modal->>Modal: adjust selection / block submit
alt Modal allows submission (client-side)
Modal->>API: POST /api/v1/request (seasons payload)
API->>Server: validate request
Server->>Server: check Permission.LIMIT_ONE_SEASON and management perms
alt multiple seasons & limited
Server->>Server: throw SeasonLimitError
Server->>Resp: 403 Forbidden (error.message)
Resp->>Modal: display error
else valid single season
Server->>Resp: 200 OK
Resp->>Modal: success
end
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
🚥 Pre-merge checks | ✅ 2✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/components/RequestModal/TvRequestModal.tsx (1)
440-465:⚠️ Potential issue | 🟡 MinorFinish threading
isOneSeasonLimitedthrough the remaining quota-only branches.The CTA state now treats limited users like partial-request mode, but the auto-approve alert and
QuotaDisplaybelow still only key offpartialRequestsEnabled. When partial requests are globally off, a limited user can still see over-limit/zero-remaining messaging based on the full unrequested season count even though selecting one season is valid.🔧 Suggested follow-up
) && !( quota?.tv.limit && - !settings.currentSettings.partialRequestsEnabled && + !settings.currentSettings.partialRequestsEnabled && + !isOneSeasonLimited && unrequestedSeasons.length > (quota?.tv.remaining ?? 0) ) && getAllRequestedSeasons().length < getAllSeasons().length && !editRequest && ( @@ <QuotaDisplay mediaType="tv" quota={quota?.tv} remaining={ - !settings.currentSettings.partialRequestsEnabled && + !settings.currentSettings.partialRequestsEnabled && + !isOneSeasonLimited && unrequestedSeasons.length > (quota?.tv.remaining ?? 0) ? 0 : currentlyRemaining } @@ overLimit={ - !settings.currentSettings.partialRequestsEnabled && + !settings.currentSettings.partialRequestsEnabled && + !isOneSeasonLimited && unrequestedSeasons.length > (quota?.tv.remaining ?? 0) ? unrequestedSeasons.length : undefined }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/components/RequestModal/TvRequestModal.tsx` around lines 440 - 465, The UI still treats quota messaging and the QuotaDisplay/auto-approve alert as if only settings.currentSettings.partialRequestsEnabled matters; thread isOneSeasonLimited into those checks so limited users are treated like partial-requests-enabled. Update all conditional checks that currently read settings.currentSettings.partialRequestsEnabled (or its negation) in the quota-only branches (including the auto-approve alert logic and the QuotaDisplay rendering) to use (settings.currentSettings.partialRequestsEnabled || isOneSeasonLimited) (or its negation) and ensure unrequestedSeasons/quota comparisons use the effective mode; keep references to isOneSeasonLimited, quota, unrequestedSeasons, getAllRequestedSeasons, getAllSeasons, selectedSeasons, QuotaDisplay and the auto-approve alert logic in your changes.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@server/entity/MediaRequest.ts`:
- Around line 438-448: The LIMIT_ONE_SEASON check is applied to requestUser in
MediaRequest.request(), which diverges from the frontend (TvRequestModal) that
derives the flag from the logged-in user and is not enforced on edits (PUT
/api/v1/request/:id); extract and centralize this logic into a reusable
validator (e.g., MediaRequest.ensureOneSeasonLimit or
MediaRequest.validateSeasonLimit) that accepts the principal performing the
action (logged-in/acting user) and the request payload (finalSeasons), use
Permission.LIMIT_ONE_SEASON and throw SeasonLimitError when violated, then call
this validator from both MediaRequest.request() and the update handler for PUT
/api/v1/request/:id so on-behalf requests use the same principal and the same
403 behavior.
In `@src/components/PermissionEdit/index.tsx`:
- Around line 190-200: The UI toggle for the permission with id
'limit-one-season' (Permission.LIMIT_ONE_SEASON) only appears when the edited
user has Permission.REQUEST or Permission.REQUEST_TV; update its requires entry
so it also includes 4K-only request permissions (Permission.REQUEST_4K and
Permission.REQUEST_4K_TV) in the permissions array (keeping type: 'or') so users
who only have 4K request bits can be configured from the admin UI.
---
Outside diff comments:
In `@src/components/RequestModal/TvRequestModal.tsx`:
- Around line 440-465: The UI still treats quota messaging and the
QuotaDisplay/auto-approve alert as if only
settings.currentSettings.partialRequestsEnabled matters; thread
isOneSeasonLimited into those checks so limited users are treated like
partial-requests-enabled. Update all conditional checks that currently read
settings.currentSettings.partialRequestsEnabled (or its negation) in the
quota-only branches (including the auto-approve alert logic and the QuotaDisplay
rendering) to use (settings.currentSettings.partialRequestsEnabled ||
isOneSeasonLimited) (or its negation) and ensure unrequestedSeasons/quota
comparisons use the effective mode; keep references to isOneSeasonLimited,
quota, unrequestedSeasons, getAllRequestedSeasons, getAllSeasons,
selectedSeasons, QuotaDisplay and the auto-approve alert logic in your changes.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 9d98ff30-f512-4fd5-af74-81f00ac814b3
📒 Files selected for processing (5)
server/entity/MediaRequest.tsserver/lib/permissions.tsserver/routes/request.tssrc/components/PermissionEdit/index.tsxsrc/components/RequestModal/TvRequestModal.tsx
Add a new user permission that restricts series requests to one season at a time. When enabled, the request modal switches to single-select mode for seasons, hides the select-all toggle, and the backend rejects multi-season requests with a 403. Admins and users with Manage Requests are exempt from the restriction. This is intended to be paired with an external prefetch service (e.g. Prefetcharr) that automatically requests additional seasons based on user watch progress.
523d8d2 to
ca988a6
Compare
|
Thanks, small but impactful feature with a high cost-benefit ratio. This would also partially address #1351. It would be great to see this included in an upcoming release fairly soon, as many users are eagerly waiting for this 👍 |
Summary
LIMIT_ONE_SEASONuser permission (bitmask 2^29) that restricts series requests to one season per requestMotivation
Addresses #1385. Users often request entire series and only watch the first season, wasting storage and bandwidth. This permission lets admins restrict users to one season at a time, which pairs well with an external prefetch service like Prefetcharr to automatically fetch additional seasons as users progress through what they requested.
Changes
server/lib/permissions.tsLIMIT_ONE_SEASONenum valueserver/entity/MediaRequest.tsSeasonLimitErrorclass and enforcement inrequest()server/routes/request.tsSeasonLimitErrorto 403 responsesrc/components/RequestModal/TvRequestModal.tsxsrc/components/PermissionEdit/index.tsxHow it works
Test plan
Summary by CodeRabbit