-
-
Notifications
You must be signed in to change notification settings - Fork 682
feat(voting): land new feature to enable voting interested/not interested on titles #2642
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from all commits
64abf91
2734ea4
78859d7
e37af39
ab9ffac
9072fdf
71a1c97
3ea5777
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -38,6 +38,8 @@ tags: | |
| description: Endpoints related to getting service (Radarr/Sonarr) details. | ||
| - name: watchlist | ||
| description: Collection of media to watch later | ||
| - name: vote | ||
| description: Vote media as interested or not interested | ||
| - name: blocklist | ||
| description: Blocklisted media from discovery page. | ||
| servers: | ||
|
|
@@ -254,6 +256,9 @@ components: | |
| enableSpecialEpisodes: | ||
| type: boolean | ||
| example: false | ||
| enableVoting: | ||
| type: boolean | ||
| example: false | ||
| NetworkSettings: | ||
| type: object | ||
| properties: | ||
|
|
@@ -710,6 +715,70 @@ components: | |
| initialized: | ||
| type: boolean | ||
| example: false | ||
| enableVoting: | ||
| type: boolean | ||
| example: false | ||
| Vote: | ||
| type: object | ||
| properties: | ||
| id: | ||
| type: number | ||
| example: 1 | ||
| tmdbId: | ||
| type: number | ||
| example: 872585 | ||
| mediaType: | ||
| type: string | ||
| enum: [movie, tv] | ||
| actionType: | ||
| type: string | ||
| enum: [interested, not_interested] | ||
| createdAt: | ||
| type: string | ||
| example: '2020-09-12T10:00:27.000Z' | ||
| updatedAt: | ||
| type: string | ||
| example: '2020-09-12T10:05:27.000Z' | ||
| VoteLookupResponse: | ||
| type: object | ||
| properties: | ||
| vote: | ||
| nullable: true | ||
| allOf: | ||
| - $ref: '#/components/schemas/Vote' | ||
| VoteHistoryResponse: | ||
| type: object | ||
| properties: | ||
| pageInfo: | ||
| $ref: '#/components/schemas/PageInfo' | ||
| results: | ||
| type: array | ||
| items: | ||
| $ref: '#/components/schemas/Vote' | ||
| VoteUpsertRequest: | ||
| type: object | ||
| properties: | ||
| tmdbId: | ||
| type: number | ||
| example: 872585 | ||
| mediaType: | ||
| type: string | ||
| enum: [movie, tv] | ||
| actionType: | ||
| type: string | ||
| enum: [interested, not_interested] | ||
| required: | ||
| - tmdbId | ||
| - mediaType | ||
| - actionType | ||
| VoteUpsertResponse: | ||
| allOf: | ||
| - $ref: '#/components/schemas/Vote' | ||
| - type: object | ||
| properties: | ||
| created: | ||
| type: boolean | ||
| example: true | ||
|
Comment on lines
+721
to
+781
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: wc -l seerr-api.ymlRepository: seerr-team/seerr Length of output: 78 🏁 Script executed: # Check the main range (721-781)
sed -n '721,781p' seerr-api.ymlRepository: seerr-team/seerr Length of output: 1516 🏁 Script executed: # Check other ranges mentioned
sed -n '4896,4908p' seerr-api.ymlRepository: seerr-team/seerr Length of output: 345 🏁 Script executed: # Check path params ranges
sed -n '4953,4956p' seerr-api.yml
sed -n '4976,4979p' seerr-api.ymlRepository: seerr-team/seerr Length of output: 241 🏁 Script executed: # Check discover/popular range
sed -n '6202,6207p' seerr-api.ymlRepository: seerr-team/seerr Length of output: 189 Use The new contract models discrete values like Applies to lines 724-725, 761-763, 4896-4908, 4953-4956, 4976-4979, and 6202-6207. 🤖 Prompt for AI Agents |
||
| MovieResult: | ||
| type: object | ||
| required: | ||
|
|
@@ -4793,6 +4862,124 @@ paths: | |
| responses: | ||
| '204': | ||
| description: Succesfully removed watchlist item | ||
| /vote: | ||
| post: | ||
| summary: Create or update vote | ||
| description: Create a vote for the current user, or update an existing vote for the same media. | ||
| tags: | ||
| - vote | ||
| requestBody: | ||
| required: true | ||
| content: | ||
| application/json: | ||
| schema: | ||
| $ref: '#/components/schemas/VoteUpsertRequest' | ||
| responses: | ||
| '200': | ||
| description: Existing vote updated | ||
| content: | ||
| application/json: | ||
| schema: | ||
| $ref: '#/components/schemas/VoteUpsertResponse' | ||
| '201': | ||
| description: Vote created | ||
| content: | ||
| application/json: | ||
| schema: | ||
| $ref: '#/components/schemas/VoteUpsertResponse' | ||
| /vote/history: | ||
| get: | ||
| summary: Get current user vote history | ||
| tags: | ||
| - vote | ||
| parameters: | ||
| - in: query | ||
| name: take | ||
| schema: | ||
| type: number | ||
| default: 20 | ||
| minimum: 1 | ||
| maximum: 100 | ||
| - in: query | ||
| name: skip | ||
| schema: | ||
| type: number | ||
| default: 0 | ||
| minimum: 0 | ||
| - in: query | ||
| name: filter | ||
| schema: | ||
| type: string | ||
| enum: [all, interested, not_interested] | ||
| default: all | ||
| - in: query | ||
| name: mediaType | ||
| schema: | ||
| type: string | ||
| enum: [all, movie, tv] | ||
| default: all | ||
| - in: query | ||
| name: sort | ||
| schema: | ||
| type: string | ||
| enum: [added] | ||
| default: added | ||
| - in: query | ||
| name: sortDirection | ||
| schema: | ||
| type: string | ||
| enum: [asc, desc] | ||
| default: desc | ||
| responses: | ||
| '200': | ||
| description: Vote history returned | ||
| content: | ||
| application/json: | ||
| schema: | ||
| $ref: '#/components/schemas/VoteHistoryResponse' | ||
| /vote/{mediaType}/{tmdbId}: | ||
| get: | ||
| summary: Get current user vote for media | ||
| tags: | ||
| - vote | ||
| parameters: | ||
| - in: path | ||
| name: mediaType | ||
| required: true | ||
| schema: | ||
| type: string | ||
| enum: [movie, tv] | ||
| - in: path | ||
| name: tmdbId | ||
| required: true | ||
| schema: | ||
| type: number | ||
| responses: | ||
| '200': | ||
| description: Vote lookup returned | ||
| content: | ||
| application/json: | ||
| schema: | ||
| $ref: '#/components/schemas/VoteLookupResponse' | ||
| delete: | ||
| summary: Delete current user vote for media | ||
| tags: | ||
| - vote | ||
| parameters: | ||
| - in: path | ||
| name: mediaType | ||
| required: true | ||
| schema: | ||
| type: string | ||
| enum: [movie, tv] | ||
| - in: path | ||
| name: tmdbId | ||
| required: true | ||
| schema: | ||
| type: number | ||
| responses: | ||
| '204': | ||
| description: Vote removed | ||
| /user/{userId}/watchlist: | ||
| get: | ||
| summary: Get the Plex watchlist for a specific user | ||
|
|
@@ -6005,6 +6192,47 @@ paths: | |
| - $ref: '#/components/schemas/MovieResult' | ||
| - $ref: '#/components/schemas/TvResult' | ||
| - $ref: '#/components/schemas/PersonResult' | ||
| /discover/popular: | ||
| get: | ||
| summary: Popular on this server | ||
| description: Returns a list of popular movies and TV shows based on server vote totals. | ||
| tags: | ||
| - search | ||
| parameters: | ||
| - in: query | ||
| name: page | ||
| schema: | ||
| type: number | ||
| example: 1 | ||
| default: 1 | ||
| - in: query | ||
| name: language | ||
| schema: | ||
| type: string | ||
| example: en | ||
| responses: | ||
| '200': | ||
| description: Results | ||
| content: | ||
| application/json: | ||
| schema: | ||
| type: object | ||
| properties: | ||
| page: | ||
| type: number | ||
| example: 1 | ||
| totalPages: | ||
| type: number | ||
| example: 1 | ||
| totalResults: | ||
| type: number | ||
| example: 20 | ||
| results: | ||
| type: array | ||
| items: | ||
| anyOf: | ||
| - $ref: '#/components/schemas/MovieResult' | ||
| - $ref: '#/components/schemas/TvResult' | ||
| /discover/keyword/{keywordId}/movies: | ||
| get: | ||
| summary: Get movies from keyword | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -23,6 +23,13 @@ class DiscoverSlider { | |
| slider, | ||
| }); | ||
| await sliderRepository.save(new DiscoverSlider(slider)); | ||
| } else if ( | ||
| existingSlider.isBuiltIn && | ||
| typeof slider.order === 'number' && | ||
| existingSlider.order !== slider.order | ||
| ) { | ||
| existingSlider.order = slider.order; | ||
| await sliderRepository.save(existingSlider); | ||
|
Comment on lines
+26
to
+32
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Don't reset persisted built-in slider order during bootstrap.
🤖 Prompt for AI Agents |
||
| } | ||
| } | ||
| } | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Document the voting permission and feature gate in the contract.
These new endpoints/settings are missing the key runtime constraint from the PR: voting depends on both
enableVotingand the new voting permission. As written,/vote*looks like a normal authenticated surface, so API consumers have no documented reason for a 403/disabled response. Please add that requirement to the property/endpoint descriptions and document the expected rejection response(s).📝 Suggested contract shape
enableVoting: type: boolean example: false + description: Enables the voting feature server-wide. Users must still have the `VOTE` permission. /vote: post: summary: Create or update vote - description: Create a vote for the current user, or update an existing vote for the same media. + description: | + Create a vote for the current user, or update an existing vote for the same media. + Requires the `VOTE` permission and `enableVoting` to be enabled. responses: '200': description: Existing vote updated '201': description: Vote created + '403': + description: Voting is disabled or the user lacks the `VOTE` permissionAlso applies to: 718-720, 4865-4982
🤖 Prompt for AI Agents