Add UserMediaList entity, migrations, and GraphQL mutations#91
Add UserMediaList entity, migrations, and GraphQL mutations#91vitorhugo-java merged 5 commits intodevfrom
Conversation
* 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>
…diaCategoryModel 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>
* 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>
…nt (#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>
…Status 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>
* 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>
Qodana for JVM5 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
|
There was a problem hiding this comment.
Pull request overview
This PR adds first-class support for user media libraries and user-defined tracking statuses across the persistence layer (Flyway + JPA), service/controller layer, and the GraphQL schema, along with new repository and GraphQL tests.
Changes:
- Introduces
user_media_list+user_custom_statusestables and expands them with planning date, custom-status linking, and privacy/notes fields. - Adds new JPA models/repositories/services/controllers for
UserMediaListandUserCustomStatus, and extendsMediawith amediaStatusrelation. - Expands the GraphQL schema with new types, queries, and mutations and adds corresponding GraphQL/repository tests.
Reviewed changes
Copilot reviewed 49 out of 49 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| src/test/java/com/espacogeek/geek/services/MediaServicePersistenceIntegrationTest.java | Updates category handling in persistence test to use CategoryType. |
| src/test/java/com/espacogeek/geek/repositories/UserMediaListRepositoryTest.java | Adds JPA repository tests for UserMediaListModel (UUID + unique constraint). |
| src/test/java/com/espacogeek/geek/query/userstatus/UserStatusQueryTest.java | Adds GraphQL query tests for custom statuses. |
| src/test/java/com/espacogeek/geek/query/usermedialist/UserMediaLibraryQueryTest.java | Adds GraphQL query tests for user media library + privacy + filters. |
| src/test/java/com/espacogeek/geek/mutation/userstatus/UserStatusMutationTest.java | Adds GraphQL mutation tests for create/update/delete custom statuses. |
| src/test/java/com/espacogeek/geek/mutation/usermedialist/UserMediaListMutationTest.java | Adds GraphQL mutation tests for add/remove/upsert library entries. |
| src/main/resources/graphql/query.graphqls | Adds findUserMediaLibrary and getUserCustomStatuses queries. |
| src/main/resources/graphql/mutation.graphqls | Adds library and custom-status mutations. |
| src/main/resources/graphql/entity/UserStatus.graphqls | Adds UserStatus GraphQL type. |
| src/main/resources/graphql/entity/UserMediaList.graphqls | Adds UserMediaList GraphQL type and UpdateUserMediaInput input. |
| src/main/resources/graphql/entity/user.graphqls | Exposes privateList on User. |
| src/main/resources/graphql/entity/StatusType.graphqls | Adds StatusType GraphQL enum for tracking status. |
| src/main/resources/graphql/entity/MediaStatus.graphqls | Adds MediaStatus GraphQL type. |
| src/main/resources/graphql/entity/Media.graphqls | Exposes mediaStatus on Media. |
| src/main/resources/db/migration/V20__create_user_media_list_table.sql | Creates user_media_list table (UUID PK + unique constraint). |
| src/main/resources/db/migration/V21__add_media_status.sql | Adds media_status table and medias.status_id FK; normalizes category strings. |
| src/main/resources/db/migration/V22__change_media_status_id_to_int.sql | Changes media_status.id + FK types from BIGINT to INT. |
| src/main/resources/db/migration/V23__add_private_list_to_users.sql | Adds users.private_list. |
| src/main/resources/db/migration/V24__update_status_types_and_add_date_planned.sql | Adds date_planned, migrates status strings, creates user_custom_statuses. |
| src/main/resources/db/migration/V25__add_custom_status_to_user_media_list.sql | Adds custom_status_id FK to user_media_list. |
| src/main/resources/db/migration/V26__add_rewatch_count_is_private_personal_notes.sql | Adds rewatch_count, is_private, personal_notes to user_media_list. |
| src/main/java/com/espacogeek/geek/types/UpdateUserMediaInput.java | Adds Java DTO backing the GraphQL upsert input. |
| src/main/java/com/espacogeek/geek/services/UserMediaListService.java | Adds service interface for library management + filtered queries. |
| src/main/java/com/espacogeek/geek/services/UserCustomStatusService.java | Adds service interface for custom status labels. |
| src/main/java/com/espacogeek/geek/services/MediaStatusService.java | Adds service interface for media statuses. |
| src/main/java/com/espacogeek/geek/services/impl/UserMediaListServiceImpl.java | Implements add/remove/upsert + filter delegation for user library entries. |
| src/main/java/com/espacogeek/geek/services/impl/UserCustomStatusServiceImpl.java | Implements CRUD for user custom status labels with validation. |
| src/main/java/com/espacogeek/geek/services/impl/MediaStatusServiceImpl.java | Implements MediaStatusService. |
| src/main/java/com/espacogeek/geek/repositories/UserMediaListRepository.java | Adds repository with a JPQL filter query + upsert helpers. |
| src/main/java/com/espacogeek/geek/repositories/UserLibraryRepository.java | Adds missing @Repository annotation. |
| src/main/java/com/espacogeek/geek/repositories/UserCustomStatusRepository.java | Adds repository for custom status CRUD scoped by userId. |
| src/main/java/com/espacogeek/geek/repositories/MediaStatusRepository.java | Adds repository for MediaStatusModel. |
| src/main/java/com/espacogeek/geek/models/UserModel.java | Adds privateList column mapping. |
| src/main/java/com/espacogeek/geek/models/UserMediaListModel.java | Adds UserMediaListModel entity (UUID PK + new columns). |
| src/main/java/com/espacogeek/geek/models/UserCustomStatusModel.java | Adds UserCustomStatusModel entity. |
| src/main/java/com/espacogeek/geek/models/StatusType.java | Adds Java enum for tracking statuses. |
| src/main/java/com/espacogeek/geek/models/MediaStatusModel.java | Adds MediaStatusModel entity. |
| src/main/java/com/espacogeek/geek/models/MediaModel.java | Adds mediaStatus relation to MediaModel. |
| src/main/java/com/espacogeek/geek/models/MediaCategoryModel.java | Converts category column to CategoryType enum. |
| src/main/java/com/espacogeek/geek/models/CategoryType.java | Adds Java enum for media categories. |
| src/main/java/com/espacogeek/geek/exception/resolver/GenericExceptionResolver.java | Maps new exceptions to standardized error codes. |
| src/main/java/com/espacogeek/geek/exception/NotFoundException.java | Adds domain exception for 3404. |
| src/main/java/com/espacogeek/geek/exception/MediaAlreadyInLibraryException.java | Adds domain exception for 2005. |
| src/main/java/com/espacogeek/geek/exception/AccessDeniedException.java | Adds domain exception for 3403. |
| src/main/java/com/espacogeek/geek/data/api/impl/TvSeriesApiImpl.java | Updates MediaModel construction to include mediaStatus placeholder. |
| src/main/java/com/espacogeek/geek/data/api/impl/MovieAPIImpl.java | Updates MediaModel construction to include mediaStatus placeholder. |
| src/main/java/com/espacogeek/geek/controllers/UserStatusController.java | Adds GraphQL controller for custom statuses. |
| src/main/java/com/espacogeek/geek/controllers/UserMediaListController.java | Adds GraphQL controller for library query + mutations + privacy checks. |
| README.md | Documents new standardized error codes/exceptions. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| String categoryNameTrimmed = categoryName == null ? null : categoryName.trim(); | ||
| CategoryType categoryType = null; | ||
| if (categoryNameTrimmed != null) { | ||
| try { | ||
| categoryType = CategoryType.valueOf(categoryNameTrimmed.toUpperCase()); | ||
| } catch (IllegalArgumentException e) { | ||
| throw new GenericException("Invalid categoryName: " + categoryNameTrimmed); | ||
| } |
There was a problem hiding this comment.
Invalid categoryName is treated as an internal error: throwing GenericException here will be mapped to errorCode 5000. Since this is client input validation, it should throw InputValidationException (errorCode 2004) with a helpful message, consistent with GenericExceptionResolver's mapping.
| @Enumerated(EnumType.STRING) | ||
| @Column(name = "type_category") | ||
| private String typeCategory; | ||
| private CategoryType name; |
There was a problem hiding this comment.
MediaCategoryModel was changed from a String typeCategory to CategoryType name, but the GraphQL schema still exposes MediaCategory.typeCategory. With the current model, typeCategory will resolve to null (no getTypeCategory()), breaking existing GraphQL clients. Either update the GraphQL schema field to match the new property, or add a compatibility getter/setter (getTypeCategory delegating to the enum) so the existing schema continues to work.
| @Column(name = "rewatch_count", columnDefinition = "INT DEFAULT 0") | ||
| private Integer rewatchCount; | ||
|
|
||
| @Column(name = "is_private", columnDefinition = "TINYINT(1) DEFAULT 0") | ||
| private Boolean isPrivate; |
There was a problem hiding this comment.
rewatch_count and is_private are added as NOT NULL with defaults in V26, but the entity fields allow null and have no default initialization. Hibernate inserts often include null values explicitly, which can violate the DB constraint at runtime when an entry is persisted without these fields set. Initialize defaults in the entity (e.g., rewatchCount = 0, isPrivate = false) and/or enforce non-null via @Column(nullable = false) / @PrePersist to align with the migration.
| @Column(name = "rewatch_count", columnDefinition = "INT DEFAULT 0") | |
| private Integer rewatchCount; | |
| @Column(name = "is_private", columnDefinition = "TINYINT(1) DEFAULT 0") | |
| private Boolean isPrivate; | |
| @Column(name = "rewatch_count", nullable = false, columnDefinition = "INT DEFAULT 0") | |
| private Integer rewatchCount = 0; | |
| @Column(name = "is_private", nullable = false, columnDefinition = "TINYINT(1) DEFAULT 0") | |
| private Boolean isPrivate = false; |
| @Enumerated(EnumType.STRING) | ||
| @Column(name = "name") | ||
| private StatusType name; | ||
|
|
||
| @OneToMany(mappedBy = "mediaStatus") | ||
| @Transient | ||
| private List<MediaModel> medias; |
There was a problem hiding this comment.
@OneToMany(mappedBy = "mediaStatus") combined with @Transient means this association is not mapped/persisted at all, which is confusing and likely not what you want. Either remove @Transient (and, if needed, handle serialization recursion via Jackson annotations) or remove the relationship annotation entirely.
| public UserMediaListModel addMedia(Integer userId, Integer mediaId) { | ||
| if (userMediaListRepository.existsByUserIdAndMediaId(userId, mediaId)) { | ||
| throw new MediaAlreadyInLibraryException(); | ||
| } |
There was a problem hiding this comment.
addMedia() uses an exists-check followed by an insert. With the unique constraint on (user_id, media_id), concurrent requests can still race and trigger a DB unique-constraint violation, which will currently surface as a database error (5001) instead of the intended 2005. Consider relying on the unique constraint and catching DataIntegrityViolationException (or re-checking on failure) to consistently translate it to MediaAlreadyInLibraryException.
| Optional<UserMediaListModel> existing = userMediaListRepository | ||
| .findByUserIdAndMediaId(userId, input.getMediaId()); | ||
|
|
||
| UserMediaListModel entry; | ||
| if (existing.isPresent()) { | ||
| entry = existing.get(); | ||
| } else { | ||
| UserModel user = userRepository.findById(userId) | ||
| .orElseThrow(() -> new NotFoundException("User not found")); | ||
| MediaModel media = mediaRepository.findById(input.getMediaId()) | ||
| .orElseThrow(() -> new NotFoundException("Media not found")); | ||
|
|
There was a problem hiding this comment.
upsertUserMedia() does a read-then-insert when no existing entry is found. Under concurrent requests for the same (userId, mediaId), this can race and hit the unique constraint, surfacing as a DB error (5001). Consider handling DataIntegrityViolationException on save() (e.g., retry by loading the existing row and applying updates) so the operation is robust under concurrency.
This pull request introduces several new features and improvements related to user media libraries, custom status management, and error handling in the API. The most significant changes include new controllers for managing user media lists and custom statuses, enhancements to error handling with new exception types and standardized codes, and the introduction of new models and enums for media categories and statuses.
API and Controller Additions:
UserMediaListControllerto handle querying, adding, updating, and removing media in a user's library, including privacy checks and support for various filters.UserStatusControllerto allow users to create, update, delete, and list their custom media tracking statuses.Error Handling Improvements:
AccessDeniedException,NotFoundException, andMediaAlreadyInLibraryExceptionfor more specific error reporting. [1] [2] [3]GenericExceptionResolverto map these exceptions to standardized error codes (3403 for access denied, 3404 for not found, 2005 for media already in library) and included them in the documentation and error mapping logic. [1] [2] [3] [4]Model and Enum Enhancements:
CategoryTypeandStatusTypeenums for stronger typing of media categories and statuses. [1] [2]MediaCategoryModelto use the newCategoryTypeenum instead of a string for the category name. [1] [2]MediaStatusModelentity for representing media production statuses, linked toMediaModel. [1] [2]UserCustomStatusModelentity for user-defined tracking statuses.Minor Adjustments:
MovieAPIImplandTvSeriesApiImplto account for the newmediaStatusfield inMediaModel. [1] [2]These changes collectively enhance the flexibility and robustness of the user media library and status management features, while improving API error consistency and data modeling.
References: