Add UserMediaList entity, Flyway migration, and persistence tests#86
Conversation
Agent-Logs-Url: https://github.com/EspacoGeek-Teams/SpringAPI_EspacoGeek/sessions/89ca0c56-ce40-4c65-acba-470f45c07fc0 Co-authored-by: AbigailGeovana <142514517+AbigailGeovana@users.noreply.github.com>
There was a problem hiding this comment.
Remove media type field, it's unnecessary because media already has a field "category".
Add data time field to when the media started be consumed, also a finish datatime.
Add a time field to user or/and the application record how much time the user spend consuming this media.
Add note field with 2000 characters of limit.
This changes can be made at the same migration file sql used on this PR.
| @@ -0,0 +1,14 @@ | |||
| CREATE TABLE IF NOT EXISTS `user_media_list` ( | |||
| `id_user_media_list` INT NOT NULL AUTO_INCREMENT, | |||
There was a problem hiding this comment.
Change to BINARY(16), keep it as a PK.
There was a problem hiding this comment.
Changed to BINARY(16) in commit a1735b4.
| @Id | ||
| @GeneratedValue(strategy = GenerationType.IDENTITY) | ||
| @Column(name = "id_user_media_list") | ||
| private Integer id; |
There was a problem hiding this comment.
Utilize UUID v7 (e.g. @uuidgenerator(style = UuidGenerator.Style.TIME). Also need to check if the application is using Hibernate 6.2 or superior.
There was a problem hiding this comment.
Updated in commit a1735b4. Spring Boot 3.4.11 ships with Hibernate 6.6.x, so @UuidGenerator(style = UuidGenerator.Style.TIME) is fully supported. The PK is now UUID mapped to BINARY(16).
…ish date, time_spent and note fields Agent-Logs-Url: https://github.com/EspacoGeek-Teams/SpringAPI_EspacoGeek/sessions/f4eedc95-d767-47f2-9b4b-bdd6a2a7ebcc Co-authored-by: AbigailGeovana <142514517+AbigailGeovana@users.noreply.github.com>
Done in commit a1735b4:
All changes are in the same migration file |
There was a problem hiding this comment.
Pull request overview
Adds persistence support for a per-user media engagement list by introducing a new UserMediaListModel JPA entity, its Flyway migration, and a Spring Data repository.
Changes:
- Create
user_media_listtable with FK constraints tousersandmedias, plus indexes. - Add
UserMediaListModelentity mapped to the new table (type/status/score/progress fields). - Add
UserMediaListRepositoryas aJpaRepositoryfor CRUD access.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| src/main/resources/db/migration/V20__create_user_media_list_table.sql | Creates the new user_media_list table, FKs, and indexes to persist user engagement per media item. |
| src/main/java/com/espacogeek/geek/models/UserMediaListModel.java | Introduces the JPA entity mapping for user_media_list with relationships to UserModel and MediaModel. |
| src/main/java/com/espacogeek/geek/repositories/UserMediaListRepository.java | Adds a Spring Data repository to access UserMediaListModel records. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| import lombok.Getter; | ||
| import lombok.NoArgsConstructor; | ||
| import lombok.Setter; |
There was a problem hiding this comment.
Consider enforcing the intended uniqueness at the JPA level too (via @table(uniqueConstraints=...)) so the constraint is discoverable in code and stays aligned with the DB. There’s a precedent for this pattern in DailyQuoteArtworkModel.
There was a problem hiding this comment.
Added in commit ce65993 — @Table now declares the unique constraint matching the DB's uniq_user_media_list_user_media key:
@Table(name = "user_media_list", uniqueConstraints = {
@UniqueConstraint(name = "uniq_user_media_list_user_media", columnNames = {"user_id", "media_id"})
})| @Getter | ||
| @Setter | ||
| @AllArgsConstructor | ||
| @NoArgsConstructor | ||
| public class UserMediaListModel implements Serializable { |
There was a problem hiding this comment.
There are JPA persistence integration tests in this repo (e.g., @DataJpaTest). Adding a small DataJpaTest covering basic persistence of UserMediaListModel (and any uniqueness constraint you add) would help catch mapping/migration regressions early.
There was a problem hiding this comment.
Added in commit fd06f72 — UserMediaListRepositoryTest is a @DataJpaTest that covers:
- Basic persistence — saves a
UserMediaListModeland verifies it can be retrieved by the generated UUID with correct field values. - Uniqueness constraint — attempts to save a duplicate
(user_id, media_id)pair and asserts aDataIntegrityViolationExceptionis thrown.
Also fixed UserMediaListRepository to use UUID as the ID type (was incorrectly Integer).
…ble.sql Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…ble.sql Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Qodana for JVM4 new problems were found
View the detailed Qodana reportTo be able to view the detailed Qodana report, you can either:
To get - name: 'Qodana Scan'
uses: JetBrains/qodana-action@v2025.3.2
with:
upload-result: trueContact Qodana teamContact us at qodana-support@jetbrains.com
|
…e key Agent-Logs-Url: https://github.com/EspacoGeek-Teams/SpringAPI_EspacoGeek/sessions/ebac41f8-5141-4192-9a6b-7b4b159c7e68 Co-authored-by: AbigailGeovana <142514517+AbigailGeovana@users.noreply.github.com>
…pe to UUID Agent-Logs-Url: https://github.com/EspacoGeek-Teams/SpringAPI_EspacoGeek/sessions/8bd217c1-398c-45a6-b66b-7e28bdd3e4b6 Co-authored-by: AbigailGeovana <142514517+AbigailGeovana@users.noreply.github.com>
* Add UserMediaList entity, Flyway migration, and persistence tests (#86) * Initial plan * Create UserMediaList entity, migration V20, and repository Agent-Logs-Url: https://github.com/EspacoGeek-Teams/SpringAPI_EspacoGeek/sessions/89ca0c56-ce40-4c65-acba-470f45c07fc0 Co-authored-by: AbigailGeovana <142514517+AbigailGeovana@users.noreply.github.com> * Address review feedback: UUID v7 PK, remove media_type, add start/finish date, time_spent and note fields Agent-Logs-Url: https://github.com/EspacoGeek-Teams/SpringAPI_EspacoGeek/sessions/f4eedc95-d767-47f2-9b4b-bdd6a2a7ebcc Co-authored-by: AbigailGeovana <142514517+AbigailGeovana@users.noreply.github.com> * Update src/main/resources/db/migration/V20__create_user_media_list_table.sql Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update src/main/resources/db/migration/V20__create_user_media_list_table.sql Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Add @table uniqueConstraints to UserMediaListModel mirroring DB unique key Agent-Logs-Url: https://github.com/EspacoGeek-Teams/SpringAPI_EspacoGeek/sessions/ebac41f8-5141-4192-9a6b-7b4b159c7e68 Co-authored-by: AbigailGeovana <142514517+AbigailGeovana@users.noreply.github.com> * Add UserMediaListRepositoryTest @DataJpaTest and fix repository ID type to UUID Agent-Logs-Url: https://github.com/EspacoGeek-Teams/SpringAPI_EspacoGeek/sessions/8bd217c1-398c-45a6-b66b-7e28bdd3e4b6 Co-authored-by: AbigailGeovana <142514517+AbigailGeovana@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: AbigailGeovana <142514517+AbigailGeovana@users.noreply.github.com> Co-authored-by: Vitor Hugo <vitorhugoalvesferreira@gmail.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Add MediaStatus entity and CategoryType/StatusType enums; refactor MediaCategoryModel name field (#87) * Initial plan * Add MediaStatus entity, CategoryType and StatusType enums, refactor MediaCategoryModel Agent-Logs-Url: https://github.com/EspacoGeek-Teams/SpringAPI_EspacoGeek/sessions/351aff6c-9b13-4dca-aef3-e683b0ea4838 Co-authored-by: vitorhugo-java <65777252+vitorhugo-java@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: vitorhugo-java <65777252+vitorhugo-java@users.noreply.github.com> * feat: GraphQL query for user media library (findUserMediaLibrary) (#88) * Initial plan * Implement GraphQL queries for MediaStatus Agent-Logs-Url: https://github.com/EspacoGeek-Teams/SpringAPI_EspacoGeek/sessions/966cc80e-e90b-49a2-9d9a-b85e965a0d61 Co-authored-by: vitorhugo-java <65777252+vitorhugo-java@users.noreply.github.com> * Replace findAllMediaStatuses with findUserMediaLibrary query Agent-Logs-Url: https://github.com/EspacoGeek-Teams/SpringAPI_EspacoGeek/sessions/84a154b0-59cd-4de9-a7f8-41a3a6ae9ce6 Co-authored-by: vitorhugo-java <65777252+vitorhugo-java@users.noreply.github.com> * Add statusId, genreId, mediaId, categoryName filters to findUserMediaLibrary Agent-Logs-Url: https://github.com/EspacoGeek-Teams/SpringAPI_EspacoGeek/sessions/b6f2c08a-c3ac-49e3-a959-88a442a3d3fe Co-authored-by: vitorhugo-java <65777252+vitorhugo-java@users.noreply.github.com> * Change MediaStatusModel.id to Integer, add V22 migration, fix Javadoc Agent-Logs-Url: https://github.com/EspacoGeek-Teams/SpringAPI_EspacoGeek/sessions/bbdd08fd-8299-45d3-9df2-a15df46d6d4d Co-authored-by: AbigailGeovana <142514517+AbigailGeovana@users.noreply.github.com> * Fix CAST enum comparison and trim string filters in controller Agent-Logs-Url: https://github.com/EspacoGeek-Teams/SpringAPI_EspacoGeek/sessions/431e8586-ce41-497c-8ad3-9f342e15e524 Co-authored-by: AbigailGeovana <142514517+AbigailGeovana@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: vitorhugo-java <65777252+vitorhugo-java@users.noreply.github.com> Co-authored-by: AbigailGeovana <142514517+AbigailGeovana@users.noreply.github.com> * Implement GraphQL mutations and query for user media library management (#89) * Initial plan * Implement GraphQL mutations addMediaToUserLibrary and removeMediaFromUserLibrary with tests Agent-Logs-Url: https://github.com/EspacoGeek-Teams/SpringAPI_EspacoGeek/sessions/18f5c822-c6fb-49ea-9fe5-aae0c61b4a39 Co-authored-by: AbigailGeovana <142514517+AbigailGeovana@users.noreply.github.com> * Update src/main/java/com/espacogeek/geek/services/impl/UserLibraryServiceImpl.java Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Merge 75-the-heart-of-the-tracker: refactor to UserMediaListModel, add private_list, add mutations and privacy-aware userId support Agent-Logs-Url: https://github.com/EspacoGeek-Teams/SpringAPI_EspacoGeek/sessions/05f2c046-5eb1-4e38-b149-5c9d578ba82c Co-authored-by: AbigailGeovana <142514517+AbigailGeovana@users.noreply.github.com> * Update src/main/resources/graphql/mutation.graphqls Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Add AccessDeniedException (3403) and NotFoundException (3404); update resolver, README, and tests Agent-Logs-Url: https://github.com/EspacoGeek-Teams/SpringAPI_EspacoGeek/sessions/f1182947-602f-4761-9667-4bfd55668bab Co-authored-by: vitorhugo-java <65777252+vitorhugo-java@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: AbigailGeovana <142514517+AbigailGeovana@users.noreply.github.com> Co-authored-by: Vitor Hugo <vitorhugoalvesferreira@gmail.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: vitorhugo-java <65777252+vitorhugo-java@users.noreply.github.com> * Implement upsertUserMedia mutation, update StatusType, add UserCustomStatus CRUD, link custom statuses to media library entries, and add new UserMediaList fields (#90) * Initial plan * Implement GraphQL mutation for user media progress and custom status CRUD Agent-Logs-Url: https://github.com/EspacoGeek-Teams/SpringAPI_EspacoGeek/sessions/ad983dcd-9d2c-4f14-b46f-713fd081da3b Co-authored-by: AbigailGeovana <142514517+AbigailGeovana@users.noreply.github.com> * Update src/main/java/com/espacogeek/geek/services/impl/UserMediaListServiceImpl.java Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update src/main/java/com/espacogeek/geek/services/impl/UserMediaListServiceImpl.java Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update src/main/java/com/espacogeek/geek/services/impl/UserCustomStatusServiceImpl.java Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update src/main/java/com/espacogeek/geek/services/impl/UserMediaListServiceImpl.java Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * fix: update Javadoc status example from WATCHING to IN_PROGRESS Agent-Logs-Url: https://github.com/EspacoGeek-Teams/SpringAPI_EspacoGeek/sessions/26a2018d-bdf3-431b-a7f1-8a7807dfebba Co-authored-by: vitorhugo-java <65777252+vitorhugo-java@users.noreply.github.com> * fix: use InputValidationException for validation errors; validate custom status name; atomic delete Agent-Logs-Url: https://github.com/EspacoGeek-Teams/SpringAPI_EspacoGeek/sessions/5e4e945f-eb96-4619-8347-1da8d030d410 Co-authored-by: vitorhugo-java <65777252+vitorhugo-java@users.noreply.github.com> * feat: add custom status list relationship to UserMediaList and update userMediaProgress Agent-Logs-Url: https://github.com/EspacoGeek-Teams/SpringAPI_EspacoGeek/sessions/95adaabd-b150-4134-a469-96ce8b907866 Co-authored-by: AbigailGeovana <142514517+AbigailGeovana@users.noreply.github.com> * Rename mutations, add StatusType enum, add UserMediaList fields - Rename userMediaProgress → upsertUserMedia in controller, service, schema, and tests - Rename UserStatus CRUD mutations/query → UserCustomStatus variants - Change UpdateUserMediaInput.status from String to StatusType enum - Create StatusType.graphqls enum definition - Remove validateStatus() (GraphQL schema now enforces enum validity) - Use .name() instead of .toUpperCase() in applyUpdates() - Add rewatchCount, isPrivate, personalNotes to UserMediaListModel - V26 migration to add columns to user_media_list - Add fields to UserMediaList.graphqls type and UpdateUserMediaInput - Handle new fields in UserMediaListServiceImpl.applyUpdates() - Update tests: unquote enum values, add new-fields test, replace invalid-status test Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: AbigailGeovana <142514517+AbigailGeovana@users.noreply.github.com> * Fix personalNotes column type: use VARCHAR(2000) to match model length constraint Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: AbigailGeovana <142514517+AbigailGeovana@users.noreply.github.com> * Update src/main/java/com/espacogeek/geek/services/impl/UserMediaListServiceImpl.java Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update src/main/resources/graphql/entity/UserMediaList.graphqls Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: AbigailGeovana <142514517+AbigailGeovana@users.noreply.github.com> Co-authored-by: Vitor Hugo <vitorhugoalvesferreira@gmail.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: vitorhugo-java <65777252+vitorhugo-java@users.noreply.github.com> --------- Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com> Co-authored-by: AbigailGeovana <142514517+AbigailGeovana@users.noreply.github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Add UserMediaList entity, Flyway migration, and persistence tests (#86) * Initial plan * Create UserMediaList entity, migration V20, and repository Agent-Logs-Url: https://github.com/EspacoGeek-Teams/SpringAPI_EspacoGeek/sessions/89ca0c56-ce40-4c65-acba-470f45c07fc0 * Address review feedback: UUID v7 PK, remove media_type, add start/finish date, time_spent and note fields Agent-Logs-Url: https://github.com/EspacoGeek-Teams/SpringAPI_EspacoGeek/sessions/f4eedc95-d767-47f2-9b4b-bdd6a2a7ebcc * Update src/main/resources/db/migration/V20__create_user_media_list_table.sql * Update src/main/resources/db/migration/V20__create_user_media_list_table.sql * Add @table uniqueConstraints to UserMediaListModel mirroring DB unique key Agent-Logs-Url: https://github.com/EspacoGeek-Teams/SpringAPI_EspacoGeek/sessions/ebac41f8-5141-4192-9a6b-7b4b159c7e68 * Add UserMediaListRepositoryTest @DataJpaTest and fix repository ID type to UUID Agent-Logs-Url: https://github.com/EspacoGeek-Teams/SpringAPI_EspacoGeek/sessions/8bd217c1-398c-45a6-b66b-7e28bdd3e4b6 --------- * Add MediaStatus entity and CategoryType/StatusType enums; refactor MediaCategoryModel name field (#87) * Initial plan * Add MediaStatus entity, CategoryType and StatusType enums, refactor MediaCategoryModel Agent-Logs-Url: https://github.com/EspacoGeek-Teams/SpringAPI_EspacoGeek/sessions/351aff6c-9b13-4dca-aef3-e683b0ea4838 --------- * feat: GraphQL query for user media library (findUserMediaLibrary) (#88) * Initial plan * Implement GraphQL queries for MediaStatus Agent-Logs-Url: https://github.com/EspacoGeek-Teams/SpringAPI_EspacoGeek/sessions/966cc80e-e90b-49a2-9d9a-b85e965a0d61 * Replace findAllMediaStatuses with findUserMediaLibrary query Agent-Logs-Url: https://github.com/EspacoGeek-Teams/SpringAPI_EspacoGeek/sessions/84a154b0-59cd-4de9-a7f8-41a3a6ae9ce6 * Add statusId, genreId, mediaId, categoryName filters to findUserMediaLibrary Agent-Logs-Url: https://github.com/EspacoGeek-Teams/SpringAPI_EspacoGeek/sessions/b6f2c08a-c3ac-49e3-a959-88a442a3d3fe * Change MediaStatusModel.id to Integer, add V22 migration, fix Javadoc Agent-Logs-Url: https://github.com/EspacoGeek-Teams/SpringAPI_EspacoGeek/sessions/bbdd08fd-8299-45d3-9df2-a15df46d6d4d * Fix CAST enum comparison and trim string filters in controller Agent-Logs-Url: https://github.com/EspacoGeek-Teams/SpringAPI_EspacoGeek/sessions/431e8586-ce41-497c-8ad3-9f342e15e524 --------- * Implement GraphQL mutations and query for user media library management (#89) * Initial plan * Implement GraphQL mutations addMediaToUserLibrary and removeMediaFromUserLibrary with tests Agent-Logs-Url: https://github.com/EspacoGeek-Teams/SpringAPI_EspacoGeek/sessions/18f5c822-c6fb-49ea-9fe5-aae0c61b4a39 * Update src/main/java/com/espacogeek/geek/services/impl/UserLibraryServiceImpl.java * Merge 75-the-heart-of-the-tracker: refactor to UserMediaListModel, add private_list, add mutations and privacy-aware userId support Agent-Logs-Url: https://github.com/EspacoGeek-Teams/SpringAPI_EspacoGeek/sessions/05f2c046-5eb1-4e38-b149-5c9d578ba82c * Update src/main/resources/graphql/mutation.graphqls * Add AccessDeniedException (3403) and NotFoundException (3404); update resolver, README, and tests Agent-Logs-Url: https://github.com/EspacoGeek-Teams/SpringAPI_EspacoGeek/sessions/f1182947-602f-4761-9667-4bfd55668bab --------- * Implement upsertUserMedia mutation, update StatusType, add UserCustomStatus CRUD, link custom statuses to media library entries, and add new UserMediaList fields (#90) * Initial plan * Implement GraphQL mutation for user media progress and custom status CRUD Agent-Logs-Url: https://github.com/EspacoGeek-Teams/SpringAPI_EspacoGeek/sessions/ad983dcd-9d2c-4f14-b46f-713fd081da3b * Update src/main/java/com/espacogeek/geek/services/impl/UserMediaListServiceImpl.java * Update src/main/java/com/espacogeek/geek/services/impl/UserMediaListServiceImpl.java * Update src/main/java/com/espacogeek/geek/services/impl/UserCustomStatusServiceImpl.java * Update src/main/java/com/espacogeek/geek/services/impl/UserMediaListServiceImpl.java * fix: update Javadoc status example from WATCHING to IN_PROGRESS Agent-Logs-Url: https://github.com/EspacoGeek-Teams/SpringAPI_EspacoGeek/sessions/26a2018d-bdf3-431b-a7f1-8a7807dfebba * fix: use InputValidationException for validation errors; validate custom status name; atomic delete Agent-Logs-Url: https://github.com/EspacoGeek-Teams/SpringAPI_EspacoGeek/sessions/5e4e945f-eb96-4619-8347-1da8d030d410 * feat: add custom status list relationship to UserMediaList and update userMediaProgress Agent-Logs-Url: https://github.com/EspacoGeek-Teams/SpringAPI_EspacoGeek/sessions/95adaabd-b150-4134-a469-96ce8b907866 * Rename mutations, add StatusType enum, add UserMediaList fields - Rename userMediaProgress → upsertUserMedia in controller, service, schema, and tests - Rename UserStatus CRUD mutations/query → UserCustomStatus variants - Change UpdateUserMediaInput.status from String to StatusType enum - Create StatusType.graphqls enum definition - Remove validateStatus() (GraphQL schema now enforces enum validity) - Use .name() instead of .toUpperCase() in applyUpdates() - Add rewatchCount, isPrivate, personalNotes to UserMediaListModel - V26 migration to add columns to user_media_list - Add fields to UserMediaList.graphqls type and UpdateUserMediaInput - Handle new fields in UserMediaListServiceImpl.applyUpdates() - Update tests: unquote enum values, add new-fields test, replace invalid-status test * Fix personalNotes column type: use VARCHAR(2000) to match model length constraint * Update src/main/java/com/espacogeek/geek/services/impl/UserMediaListServiceImpl.java * Update src/main/resources/graphql/entity/UserMediaList.graphqls --------- --------- Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com> Co-authored-by: AbigailGeovana <142514517+AbigailGeovana@users.noreply.github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Introduces the
UserMediaListentity to track a user's engagement with individual media items, including status, score, progress, timestamps, time spent, and notes.Changes
UserMediaListModel— new JPA entity mapped touser_media_listwith:id— UUID v7 PK (BINARY(16)) generated via@UuidGenerator(style = UuidGenerator.Style.TIME)(requires Hibernate 6.2+)user/media—@ManyToOneFKs tousersandmedias(cascade delete)status—VARCHAR(50)(e.g."watching","completed","dropped")score—DECIMAL(3,1)progress—INTstartDate/finishDate—DATETIMEtimestamps for when consumption started and finishedtimeSpent—INT(minutes spent consuming the media)note—VARCHAR(2000)free-text note@Table(uniqueConstraints = ...)enforcing uniqueness on(user_id, media_id)at the JPA level, mirroring the DB constraintV20__create_user_media_list_table.sql— Flyway migration creating the table withBINARY(16)PK,DECIMAL(3,1)score, FK constraints, indexes on both FK columns, and aUNIQUE KEYon(user_id, media_id)UserMediaListRepository—JpaRepository<UserMediaListModel, UUID>following existing repository conventionsUserMediaListRepositoryTest—@DataJpaTestcovering basic persist/retrieve (verifying UUID generation and field mapping) and uniqueness constraint violation (assertingDataIntegrityViolationExceptionon duplicate(user_id, media_id))🔒 GitHub Advanced Security automatically protects Copilot coding agent pull requests. You can protect all pull requests by enabling Advanced Security for your repositories. Learn more about Advanced Security.