Store per-user 5-star ratings with averages and surface them in the player. Refresh movie list layout to show ratings and details in a cleaner card layout.
Note
Introduces per-user ratings and surfaces them across API and UI.
New MovieRating model with unique (movieId,userId) and 1–5 validation
Backend: add GET/PUT /api/movies/:id/ratings (auth) and augment movie list/detail responses with user_rating_avg, user_rating_count, user_rating
Movies list (app_movies.js + CSS): refreshed card layout; show user average and own rating, improved IMDb/metadata blocks
Player (player.html/app_player.js): star widget to set rating, saves via PUT and reflects average/count; minor header/quality alignment tweaks
Caching: reuse base movie list payload, then join rating aggregates and per-user ratings
Written by Cursor Bugbot for commit fe21a12c82. This will update automatically on new commits. Configure here.
Store per-user 5-star ratings with averages and surface them in the player. Refresh movie list layout to show ratings and details in a cleaner card layout.
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> Introduces per-user ratings and surfaces them across API and UI.
>
> - New `MovieRating` model with unique `(movieId,userId)` and 1–5 validation
> - Backend: add `GET/PUT /api/movies/:id/ratings` (auth) and augment movie list/detail responses with `user_rating_avg`, `user_rating_count`, `user_rating`
> - Movies list (`app_movies.js` + CSS): refreshed card layout; show user average and own rating, improved IMDb/metadata blocks
> - Player (`player.html`/`app_player.js`): star widget to set rating, saves via PUT and reflects average/count; minor header/quality alignment tweaks
> - Caching: reuse base movie list payload, then join rating aggregates and per-user ratings
>
> <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit fe21a12c82f019c26a9d05a25b199d6b20887300. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
cursor[bot]
(Migrated from github.com)
left a comment
Copy Link
Copy Source
Cursor Bugbot has reviewed your changes and found 2 potential issues.
Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.
This is the final PR Bugbot will review for you during this billing cycle
Your free Bugbot reviews will reset on February 22
Details
You are on the Bugbot Free tier. On this plan, Bugbot will review limited PRs each billing cycle.
To receive Bugbot reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
<sup>Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the [Cursor dashboard](https://www.cursor.com/dashboard?tab=bugbot).</sup>
### This is the final PR Bugbot will review for you during this billing cycle
Your free Bugbot reviews will reset on February 22
<details>
<summary>Details</summary>
You are on the Bugbot Free tier. On this plan, Bugbot will review limited PRs each billing cycle.
To receive Bugbot reviews on all of your PRs, visit the [Cursor dashboard](https://www.cursor.com/dashboard?tab=bugbot) to activate Pro and start your 14-day free trial.
</details>
The starting object in initUserRating captures the initial page-load rating state but is never updated after a successful save. If a user successfully saves a rating (e.g., changes from 3 to 4 stars) and then a subsequent save fails (e.g., trying to change to 5 stars), the UI reverts to the original page-load state (3 stars) instead of the last successfully saved state (4 stars). This causes the displayed rating to be inconsistent with the actual server state.
### Stale fallback state after successful rating save
**Medium Severity**
<!-- DESCRIPTION START -->
The `starting` object in `initUserRating` captures the initial page-load rating state but is never updated after a successful save. If a user successfully saves a rating (e.g., changes from 3 to 4 stars) and then a subsequent save fails (e.g., trying to change to 5 stars), the UI reverts to the original page-load state (3 stars) instead of the last successfully saved state (4 stars). This causes the displayed rating to be inconsistent with the actual server state.
<!-- DESCRIPTION END -->
<!-- BUGBOT_BUG_ID: ref1_2599e9bb-7d25-4f43-a0f6-0f5dfc6622f0 -->
<!-- LOCATIONS START
public/js/app_player.js#L601-L606
public/js/app_player.js#L636-L639
LOCATIONS END -->
<details>
<summary>Additional Locations (1)</summary>
- [`public/js/app_player.js#L636-L639`](https://github.com/quoije/oscars-pool/blob/fe21a12c82f019c26a9d05a25b199d6b20887300/public/js/app_player.js#L636-L639)
</details>
<a href="https://cursor.com/open?data=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImJ1Z2JvdC12MiJ9.eyJ2ZXJzaW9uIjoxLCJ0eXBlIjoiQlVHQk9UX0ZJWF9JTl9DVVJTT1IiLCJkYXRhIjp7InJlZGlzS2V5IjoiYnVnYm90OjMyMGYxZjc5LWIwMmYtNGYyNy04ZGNmLTZlOGFlY2NhNTJkYiIsImVuY3J5cHRpb25LZXkiOiJDWGpxMXp6Z3dpUllTQjlsZ1lhaFU5UmtlWmFtaVdVY2JrN09rQ2Q4d1NRIiwiYnJhbmNoIjoiMjAyNiJ9LCJpYXQiOjE3NjkzNzk2MzYsImV4cCI6MTc3MTk3MTYzNn0.pCsGqL8yGkNCfJzG4c5wX9WrJ1dRzUi49CRBk1IYaxXauBwlCR13tuHHmI65YGwh8KkfrmRX1x2CzHvC1_P7cowcwDkSZpZ8Pufn1BrabWAnVHxkGWQ6BWjtuS34OVwNyQcyYKaGcW9YGW85_VcMidnXyJa8dH7QOp5_9Vi6Hi5RHpmTA6TvD0K6ByikriVxOHFuH0bhY2ynAUwPFx1OGj6RTbCjFJ-oqEiwErGJ-Nj41FeCIKf-xhP4r9WVfso2WkI44KN1eNz82eCJqMmzWPsLR0i4aN1iMQx8aHIVefuAB1Ab78QBkrcYabUWoXAjmd8sLcmGAiAIWQuXq0TW3g" target="_blank" rel="noopener noreferrer"><picture><source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/fix-in-cursor-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://cursor.com/fix-in-cursor-light.svg"><img alt="Fix in Cursor" src="https://cursor.com/fix-in-cursor.svg"></picture></a> <a href="https://cursor.com/agents?data=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImJ1Z2JvdC12MiJ9.eyJ2ZXJzaW9uIjoxLCJ0eXBlIjoiQlVHQk9UX0ZJWF9JTl9XRUIiLCJkYXRhIjp7InJlZGlzS2V5IjoiYnVnYm90OjMyMGYxZjc5LWIwMmYtNGYyNy04ZGNmLTZlOGFlY2NhNTJkYiIsImVuY3J5cHRpb25LZXkiOiJDWGpxMXp6Z3dpUllTQjlsZ1lhaFU5UmtlWmFtaVdVY2JrN09rQ2Q4d1NRIiwiYnJhbmNoIjoiMjAyNiIsInJlcG9Pd25lciI6InF1b2lqZSIsInJlcG9OYW1lIjoib3NjYXJzLXBvb2wiLCJwck51bWJlciI6NzQsImNvbW1pdFNoYSI6ImZlMjFhMTJjODJmMDE5YzI2YTlkMDVhMjViMTk5ZDZiMjA4ODczMDAiLCJwcm92aWRlciI6ImdpdGh1YiJ9LCJpYXQiOjE3NjkzNzk2MzYsImV4cCI6MTc3MTk3MTYzNn0.TgHApQFuDMLY0HjPgfm4VaeOz3bZ2zm9DsWMnhBaJvocdu0Ig2FA7RCstx9651iTTifhgsxR29U_j8zYuSzIylzP6c-x1y3P3zflfv4zY8vrT8VH0Kn8WODGGjFmpfyk_oPa_R8Cm5toHZfN_GaOe3zcWtW76os9NFjRUuKcl8xxK6jF1gaULBwnd2WgT4vtZZgdwWXLW-pWl2DnbIOSQdW7FiLzlnGuiBI26F4cuzElawb9_tcsrmn_ym1sWZLgvoh3UlbgQVwcUVrEKQsDioYLRVb_HMNRSGRchyV7--mq1fPCuKkbvaq_4ePfDZ4s_HJexqF5XlXKZnnXt9wqsg" target="_blank" rel="noopener noreferrer"><picture><source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/fix-in-web-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://cursor.com/fix-in-web-light.svg"><img alt="Fix in Web" src="https://cursor.com/fix-in-web.svg"></picture></a>
Public caching enabled for user-specific rating data
High Severity
The GET /api/movies endpoint now includes user-specific user_rating data (each user's personal movie rating) in the response payload, but still sets Cache-Control: public, max-age=30. This allows shared caches (CDNs, proxies) to cache one user's personal ratings and serve them to other users, leaking private data. The caching should be changed to private and include Vary: Authorization to match other user-specific endpoints in this file.
### Public caching enabled for user-specific rating data
**High Severity**
<!-- DESCRIPTION START -->
The GET `/api/movies` endpoint now includes user-specific `user_rating` data (each user's personal movie rating) in the response payload, but still sets `Cache-Control: public, max-age=30`. This allows shared caches (CDNs, proxies) to cache one user's personal ratings and serve them to other users, leaking private data. The caching should be changed to `private` and include `Vary: Authorization` to match other user-specific endpoints in this file.
<!-- DESCRIPTION END -->
<!-- BUGBOT_BUG_ID: 775354fd-1d01-41c7-922f-e040ab80d00b -->
<!-- LOCATIONS START
routes/movies.js#L354-L356
routes/movies.js#L342-L353
LOCATIONS END -->
<details>
<summary>Additional Locations (1)</summary>
- [`routes/movies.js#L342-L353`](https://github.com/quoije/oscars-pool/blob/fe21a12c82f019c26a9d05a25b199d6b20887300/routes/movies.js#L342-L353)
</details>
<a href="https://cursor.com/open?data=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImJ1Z2JvdC12MiJ9.eyJ2ZXJzaW9uIjoxLCJ0eXBlIjoiQlVHQk9UX0ZJWF9JTl9DVVJTT1IiLCJkYXRhIjp7InJlZGlzS2V5IjoiYnVnYm90OjVlMDM2MDBkLWE0ZjUtNGM1MC04YWQ4LWIwYmMzMTQzYTQ0NyIsImVuY3J5cHRpb25LZXkiOiJ3akVCRFZlSW9QOGxVS0NWSDRoZE1FWlJaUjMxZ3pZclVhMHFtaXFBRUdrIiwiYnJhbmNoIjoiMjAyNiJ9LCJpYXQiOjE3NjkzNzk2MzYsImV4cCI6MTc3MTk3MTYzNn0.WoAMwVsUi2asoGLeahM4cRutBECyNTGNc72-QRb47z9Tlg6iF1krz8Dxvg1_uaeMqnCoQpdN7Fw7juczy-IIchiqZzUUpHxCGZp3BuGm3IObFYfGEZKyPNuHbhAsHI24TjNjquasOLKtmMODXxf1d6LjY2DkMc0X9JEZfVF-_cox8-ekg3w0Ydk0DtV5-2kMSa606ZtI7J1pmc-MMfbdEPZfPlNfTo7YrUWCdMt0e60u7R4MIwvfQ-BKFlo9CzwNVnKJB4E_ytx6SMOxaS6fnF8bAvS_1YaKbnuayA3usNqk5WZu-F6G0jWXLdVztr9GYbM9rZmSzZRTifFIQyCKhA" target="_blank" rel="noopener noreferrer"><picture><source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/fix-in-cursor-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://cursor.com/fix-in-cursor-light.svg"><img alt="Fix in Cursor" src="https://cursor.com/fix-in-cursor.svg"></picture></a> <a href="https://cursor.com/agents?data=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImJ1Z2JvdC12MiJ9.eyJ2ZXJzaW9uIjoxLCJ0eXBlIjoiQlVHQk9UX0ZJWF9JTl9XRUIiLCJkYXRhIjp7InJlZGlzS2V5IjoiYnVnYm90OjVlMDM2MDBkLWE0ZjUtNGM1MC04YWQ4LWIwYmMzMTQzYTQ0NyIsImVuY3J5cHRpb25LZXkiOiJ3akVCRFZlSW9QOGxVS0NWSDRoZE1FWlJaUjMxZ3pZclVhMHFtaXFBRUdrIiwiYnJhbmNoIjoiMjAyNiIsInJlcG9Pd25lciI6InF1b2lqZSIsInJlcG9OYW1lIjoib3NjYXJzLXBvb2wiLCJwck51bWJlciI6NzQsImNvbW1pdFNoYSI6ImZlMjFhMTJjODJmMDE5YzI2YTlkMDVhMjViMTk5ZDZiMjA4ODczMDAiLCJwcm92aWRlciI6ImdpdGh1YiJ9LCJpYXQiOjE3NjkzNzk2MzYsImV4cCI6MTc3MTk3MTYzNn0.eXp2e2_c34OIKw8r77eTdgXBB5PYi10YAPHSuzLYYhv20IINwGj8roZqR29jwxCpE69bFdPxSqZQmLbUhoScxqbiQDFcPGO19zjEtabQ8ROnfBbyvSRcLn9v9lKQD5DTPr1gMF2DwirFNhc0CtMxlN_IiI6Bfm1ZZBKAFJJtcEl1PMDTdnfCInkI7c0MFA4yRV9izcJFOIRs0rf-NVpkGFKriqQBTraGHBgN2VkXCsI7MIlHd9b37Wmx_SEdRNUMAVTx91nvMe-yuEX0z1Y-XQUlptUi1mRHyiCj06cpNq8K_RfZn63sWL1WGFsxB-dAKs-mAJyR_QaX8UdqOmbSzw" target="_blank" rel="noopener noreferrer"><picture><source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/fix-in-web-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://cursor.com/fix-in-web-light.svg"><img alt="Fix in Web" src="https://cursor.com/fix-in-web.svg"></picture></a>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Store per-user 5-star ratings with averages and surface them in the player. Refresh movie list layout to show ratings and details in a cleaner card layout.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.
This is the final PR Bugbot will review for you during this billing cycle
Your free Bugbot reviews will reset on February 22
Details
You are on the Bugbot Free tier. On this plan, Bugbot will review limited PRs each billing cycle.
To receive Bugbot reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.
@@ -549,0 +603,4 @@averageRating: initial?.averageRating ?? null,ratingsCount: initial?.ratingsCount ?? 0,userRating: initial?.userRating ?? null,};Stale fallback state after successful rating save
Medium Severity
The
startingobject ininitUserRatingcaptures the initial page-load rating state but is never updated after a successful save. If a user successfully saves a rating (e.g., changes from 3 to 4 stars) and then a subsequent save fails (e.g., trying to change to 5 stars), the UI reverts to the original page-load state (3 stars) instead of the last successfully saved state (4 stars). This causes the displayed rating to be inconsistent with the actual server state.Additional Locations (1)
public/js/app_player.js#L636-L639Public caching enabled for user-specific rating data
High Severity
The GET
/api/moviesendpoint now includes user-specificuser_ratingdata (each user's personal movie rating) in the response payload, but still setsCache-Control: public, max-age=30. This allows shared caches (CDNs, proxies) to cache one user's personal ratings and serve them to other users, leaking private data. The caching should be changed toprivateand includeVary: Authorizationto match other user-specific endpoints in this file.Additional Locations (1)
routes/movies.js#L342-L353