Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion mflix/README-JAVA-SPRING.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ Edit the `.env` file and set your MongoDB connection string:

```env
# MongoDB Connection
MONGODB_URI=mongodb+srv://<username>:<password>@<cluster>.mongodb.net/sample_mflix?retryWrites=true&w=majority
MONGODB_URI="mongodb+srv://<username>:<password>@<cluster>.mongodb.net/sample_mflix?retryWrites=true&w=majority"

# Voyage AI Configuration (optional - required for Vector Search)
VOYAGE_API_KEY=your_voyage_api_key
Expand Down
2 changes: 1 addition & 1 deletion mflix/README-NODE-EXPRESS.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ Edit the `.env` file and set your MongoDB connection string:
```env
# MongoDB Connection
# Replace with your MongoDB Atlas connection string or local MongoDB URI
MONGODB_URI=mongodb+srv://<username>:<password>@<cluster>.mongodb.net/sample_mflix?retryWrites=true&w=majority
MONGODB_URI="mongodb+srv://<username>:<password>@<cluster>.mongodb.net/sample_mflix?retryWrites=true&w=majority"

# Voyage AI Configuration
# API key for Voyage AI embedding model (required for Vector Search)
Expand Down
2 changes: 1 addition & 1 deletion mflix/README-PYTHON-FASTAPI.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ Edit the `.env` file and set your MongoDB connection string:

```env
# MongoDB Connection
MONGODB_URI=mongodb+srv://<username>:<password>@<cluster>.mongodb.net/sample_mflix?retryWrites=true&w=majority
MONGODB_URI="mongodb+srv://<username>:<password>@<cluster>.mongodb.net/sample_mflix?retryWrites=true&w=majority"

# Voyage AI Configuration (optional - required for Vector Search)
VOYAGE_API_KEY=your_voyage_api_key
Expand Down
2 changes: 1 addition & 1 deletion mflix/server/java-spring/.env.example
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# MongoDB Connection
# Replace with your MongoDB Atlas connection string or local MongoDB URI
MONGODB_URI=mongodb+srv://<username>:<password>@<cluster>.mongodb.net/sample_mflix?retryWrites=true&w=majority
MONGODB_URI="mongodb+srv://<username>:<password>@<cluster>.mongodb.net/sample_mflix?retryWrites=true&w=majority"

# OPTIONAL: Voyage AI Configuration (required for Vector Search)
# Get your API key from https://www.voyageai.com/
Expand Down
11 changes: 9 additions & 2 deletions mflix/server/java-spring/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
<scope>provided</scope>
</dependency>

<!-- Force version for Commons Lang used by SpringDoc (CVE-2025-48924) -->
Expand Down Expand Up @@ -118,11 +118,18 @@
</configuration>
</plugin>

<!-- Maven Compiler Plugin - Suppress annotation processing warnings -->
<!-- Maven Compiler Plugin - Process Lombok and suppress annotation processing warnings -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</path>
</annotationProcessorPaths>
<compilerArgs>
<arg>-Xlint:-options</arg>
</compilerArgs>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import java.time.Instant;
import java.util.List;
import java.util.Map;
import org.bson.Document;
Expand Down Expand Up @@ -103,10 +102,8 @@ public ResponseEntity<SuccessResponse<List<Movie>>> getAllMovies(
String message = "Found " + movies.size() + " movies";

SuccessResponse<List<Movie>> response = SuccessResponse.<List<Movie>>builder()
.success(true)
.message(message)
.data(movies)
.timestamp(Instant.now().toString())
.build();

return ResponseEntity.ok(response);
Expand All @@ -122,10 +119,8 @@ public ResponseEntity<SuccessResponse<List<String>>> getDistinctGenres() {
List<String> genres = movieService.getDistinctGenres();

SuccessResponse<List<String>> response = SuccessResponse.<List<String>>builder()
.success(true)
.message("Found " + genres.size() + " distinct genres")
.data(genres)
.timestamp(Instant.now().toString())
.build();

return ResponseEntity.ok(response);
Expand All @@ -142,10 +137,8 @@ public ResponseEntity<SuccessResponse<Movie>> getMovieById(
Movie movie = movieService.getMovieById(id);

SuccessResponse<Movie> response = SuccessResponse.<Movie>builder()
.success(true)
.message("Movie retrieved successfully")
.data(movie)
.timestamp(Instant.now().toString())
.build();

return ResponseEntity.ok(response);
Expand All @@ -162,10 +155,8 @@ public ResponseEntity<SuccessResponse<Movie>> createMovie(
Movie movie = movieService.createMovie(request);

SuccessResponse<Movie> response = SuccessResponse.<Movie>builder()
.success(true)
.message("Movie '" + request.getTitle() + "' created successfully")
.message("Movie '" + request.title() + "' created successfully")
.data(movie)
.timestamp(Instant.now().toString())
.build();

return ResponseEntity.status(HttpStatus.CREATED).body(response);
Expand All @@ -182,10 +173,8 @@ public ResponseEntity<SuccessResponse<BatchInsertResponse>> createMoviesBatch(
BatchInsertResponse result = movieService.createMoviesBatch(requests);

SuccessResponse<BatchInsertResponse> response = SuccessResponse.<BatchInsertResponse>builder()
.success(true)
.message("Successfully created " + result.getInsertedCount() + " movies")
.message("Successfully created " + result.insertedCount() + " movies")
.data(result)
.timestamp(Instant.now().toString())
.build();

return ResponseEntity.status(HttpStatus.CREATED).body(response);
Expand All @@ -210,10 +199,8 @@ public ResponseEntity<SuccessResponse<Movie>> updateMovie(
Movie movie = movieService.updateMovie(id, request);

SuccessResponse<Movie> response = SuccessResponse.<Movie>builder()
.success(true)
.message("Movie updated successfully")
.data(movie)
.timestamp(Instant.now().toString())
.build();

return ResponseEntity.ok(response);
Expand All @@ -235,11 +222,9 @@ public ResponseEntity<SuccessResponse<BatchUpdateResponse>> updateMoviesBatch(
BatchUpdateResponse result = movieService.updateMoviesBatch(filter, update);

SuccessResponse<BatchUpdateResponse> response = SuccessResponse.<BatchUpdateResponse>builder()
.success(true)
.message("Update operation completed. Matched " + result.getMatchedCount() +
" documents, modified " + result.getModifiedCount() + " documents.")
.message("Update operation completed. Matched " + result.matchedCount() +
" documents, modified " + result.modifiedCount() + " documents.")
.data(result)
.timestamp(Instant.now().toString())
.build();

return ResponseEntity.ok(response);
Expand All @@ -257,10 +242,8 @@ public ResponseEntity<SuccessResponse<Movie>> findAndDeleteMovie(
Movie movie = movieService.findAndDeleteMovie(id);

SuccessResponse<Movie> response = SuccessResponse.<Movie>builder()
.success(true)
.message("Movie found and deleted successfully")
.data(movie)
.timestamp(Instant.now().toString())
.build();

return ResponseEntity.ok(response);
Expand All @@ -277,10 +260,8 @@ public ResponseEntity<SuccessResponse<DeleteResponse>> deleteMovie(
DeleteResponse result = movieService.deleteMovie(id);

SuccessResponse<DeleteResponse> response = SuccessResponse.<DeleteResponse>builder()
.success(true)
.message("Movie deleted successfully")
.data(result)
.timestamp(Instant.now().toString())
.build();

return ResponseEntity.ok(response);
Expand All @@ -301,10 +282,8 @@ public ResponseEntity<SuccessResponse<DeleteResponse>> deleteMoviesBatch(
DeleteResponse result = movieService.deleteMoviesBatch(filter);

SuccessResponse<DeleteResponse> response = SuccessResponse.<DeleteResponse>builder()
.success(true)
.message("Delete operation completed. Removed " + result.getDeletedCount() + " documents.")
.message("Delete operation completed. Removed " + result.deletedCount() + " documents.")
.data(result)
.timestamp(Instant.now().toString())
.build();

return ResponseEntity.ok(response);
Expand All @@ -328,7 +307,7 @@ public ResponseEntity<SuccessResponse<List<MovieWithCommentsResult>>> getMoviesW

// Calculate total comments across all movies
int totalComments = results.stream()
.mapToInt(result -> result.getTotalComments() != null ? result.getTotalComments() : 0)
.mapToInt(result -> result.totalComments() != null ? result.totalComments() : 0)
.sum();

String message = movieId != null
Expand All @@ -338,10 +317,8 @@ public ResponseEntity<SuccessResponse<List<MovieWithCommentsResult>>> getMoviesW

SuccessResponse<List<MovieWithCommentsResult>> response =
SuccessResponse.<List<MovieWithCommentsResult>>builder()
.success(true)
.message(message)
.data(results)
.timestamp(Instant.now().toString())
.build();

return ResponseEntity.ok(response);
Expand All @@ -359,10 +336,8 @@ public ResponseEntity<SuccessResponse<List<MoviesByYearResult>>> getMoviesByYear

SuccessResponse<List<MoviesByYearResult>> response =
SuccessResponse.<List<MoviesByYearResult>>builder()
.success(true)
.message(String.format("Aggregated statistics for %d years", results.size()))
.data(results)
.timestamp(Instant.now().toString())
.build();

return ResponseEntity.ok(response);
Expand All @@ -382,10 +357,8 @@ public ResponseEntity<SuccessResponse<List<DirectorStatisticsResult>>> getDirect

SuccessResponse<List<DirectorStatisticsResult>> response =
SuccessResponse.<List<DirectorStatisticsResult>>builder()
.success(true)
.message(String.format("Found %d directors with most movies", results.size()))
.data(results)
.timestamp(Instant.now().toString())
.build();

return ResponseEntity.ok(response);
Expand Down Expand Up @@ -440,10 +413,8 @@ public ResponseEntity<SuccessResponse<SearchMoviesResponse>> searchMovies(
.build();

SuccessResponse<SearchMoviesResponse> response = SuccessResponse.<SearchMoviesResponse>builder()
.success(true)
.message(String.format("Found %d movies matching the search criteria", movies.size()))
.data(searchResponse)
.timestamp(Instant.now().toString())
.build();

return ResponseEntity.ok(response);
Expand All @@ -465,10 +436,8 @@ public ResponseEntity<SuccessResponse<List<VectorSearchResult>>> vectorSearchMov
List<VectorSearchResult> results = movieService.vectorSearchMovies(q, limit);

SuccessResponse<List<VectorSearchResult>> response = SuccessResponse.<List<VectorSearchResult>>builder()
.success(true)
.message(String.format("Found %d similar movies for query: '%s'", results.size(), q))
.data(results)
.timestamp(Instant.now().toString())
.build();

return ResponseEntity.ok(response);
Expand All @@ -489,10 +458,8 @@ public ResponseEntity<SuccessResponse<List<Movie>>> findSimilarMovies(
List<Movie> movies = movieService.findSimilarMovies(movieId, limit);

SuccessResponse<List<Movie>> response = SuccessResponse.<List<Movie>>builder()
.success(true)
.message(String.format("Found %d similar movies", movies.size()))
.data(movies)
.timestamp(Instant.now().toString())
.build();

return ResponseEntity.ok(response);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ public ResponseEntity<ErrorResponse> handleResourceNotFoundException(
logger.error("Resource not found: {}", ex.getMessage());

ErrorResponse errorResponse = ErrorResponse.builder()
.success(false)
.message(ex.getMessage())
.error(ErrorResponse.ErrorDetails.builder()
.message(ex.getMessage())
Expand All @@ -47,7 +46,6 @@ public ResponseEntity<ErrorResponse> handleValidationException(
logger.error("Validation error: {}", ex.getMessage());

ErrorResponse errorResponse = ErrorResponse.builder()
.success(false)
.message("Validation failed")
.error(ErrorResponse.ErrorDetails.builder()
.message(ex.getMessage())
Expand All @@ -67,7 +65,6 @@ public ResponseEntity<ErrorResponse> handleMissingServletRequestParameter(
String message = String.format("Required parameter '%s' is missing", ex.getParameterName());

ErrorResponse errorResponse = ErrorResponse.builder()
.success(false)
.message(message)
.error(ErrorResponse.ErrorDetails.builder()
.message(message)
Expand All @@ -85,7 +82,6 @@ public ResponseEntity<ErrorResponse> handleServiceUnavailableException(
logger.error("Service unavailable: {}", ex.getMessage());

ErrorResponse errorResponse = ErrorResponse.builder()
.success(false)
.message(ex.getMessage())
.error(ErrorResponse.ErrorDetails.builder()
.message(ex.getMessage())
Expand All @@ -103,7 +99,6 @@ public ResponseEntity<ErrorResponse> handleVoyageAuthException(
logger.error("Voyage AI authentication error: {}", ex.getMessage());

ErrorResponse errorResponse = ErrorResponse.builder()
.success(false)
.message(ex.getMessage())
.error(ErrorResponse.ErrorDetails.builder()
.message(ex.getMessage())
Expand All @@ -122,7 +117,6 @@ public ResponseEntity<ErrorResponse> handleVoyageAPIException(
logger.error("Voyage AI API error: {}", ex.getMessage());

ErrorResponse errorResponse = ErrorResponse.builder()
.success(false)
.message("Vector search service unavailable")
.error(ErrorResponse.ErrorDetails.builder()
.message(ex.getMessage())
Expand All @@ -140,7 +134,6 @@ public ResponseEntity<ErrorResponse> handleDatabaseOperationException(
logger.error("Database operation error: {}", ex.getMessage());

ErrorResponse errorResponse = ErrorResponse.builder()
.success(false)
.message("Database operation failed")
.error(ErrorResponse.ErrorDetails.builder()
.message(ex.getMessage())
Expand Down Expand Up @@ -168,7 +161,6 @@ public ResponseEntity<ErrorResponse> handleMongoWriteException(
}

ErrorResponse errorResponse = ErrorResponse.builder()
.success(false)
.message(message)
.error(ErrorResponse.ErrorDetails.builder()
.message(message)
Expand All @@ -187,7 +179,6 @@ public ResponseEntity<ErrorResponse> handleGenericException(
logger.error("Unexpected error occurred", ex);

ErrorResponse errorResponse = ErrorResponse.builder()
.success(false)
.message(ex.getMessage() != null ? ex.getMessage() : "Internal server error")
.error(ErrorResponse.ErrorDetails.builder()
.message(ex.getMessage() != null ? ex.getMessage() : "Internal server error")
Expand Down
Loading
Loading