Skip to content

Commit d7c83d3

Browse files
authored
Merge pull request #28 from jordan-smith721/express-updates
feat: add searches and aggregation to express backend
2 parents 0a238d6 + 24b407a commit d7c83d3

File tree

11 files changed

+1777
-155
lines changed

11 files changed

+1777
-155
lines changed

client/app/lib/api.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,7 @@ export async function fetchMoviesWithComments(
410410
const queryParams = new URLSearchParams();
411411
queryParams.append('limit', limit.toString());
412412
if (movieId) {
413-
queryParams.append('movie_id', movieId);
413+
queryParams.append('movieId', movieId);
414414
}
415415

416416
console.log(`Fetching comments from: ${API_BASE_URL}/api/movies/aggregations/reportingByComments?${queryParams}`);

client/app/lib/constants.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ export const APP_CONFIG = {
77
description: 'Browse movies from the sample MFlix database',
88
defaultMovieLimit: 20,
99
maxMovieLimit: 100,
10+
vectorSearchPageSize: 20, // Fixed page size for vector search results display
1011
imageFormats: ['image/avif', 'image/webp'],
1112
} as const;
1213

client/app/movies/page.tsx

Lines changed: 64 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -239,16 +239,18 @@ export default function Movies() {
239239
let result;
240240

241241
if (searchParams.searchType === 'vector-search') {
242-
// Vector Search: Fetch all results and implement client-side pagination
242+
// Vector Search: Use the limit from search params as the fetch limit
243243
const vectorSearchParams = {
244244
q: searchParams.q!,
245-
limit: searchParams.limit || 50, // Get more results for better pagination experience
245+
limit: searchParams.limit || 50, // This is how many results to fetch from backend
246246
};
247+
247248
result = await vectorSearchMovies(vectorSearchParams);
248249

249250
if (result.success) {
250251
const allResults = result.movies || [];
251-
const pageSize = searchParams.limit || 20;
252+
const pageSize = APP_CONFIG.vectorSearchPageSize; // Fixed page size for UI display
253+
252254
setAllVectorSearchResults(allResults);
253255
setVectorSearchPage(1);
254256
setVectorSearchPageSize(pageSize);
@@ -257,10 +259,7 @@ export default function Movies() {
257259
const firstPageResults = allResults.slice(0, pageSize);
258260
setSearchResults(firstPageResults);
259261

260-
// Set pagination state based on total results
261-
const totalPages = Math.ceil(allResults.length / pageSize);
262-
setSearchHasNextPage(totalPages > 1);
263-
setSearchHasPrevPage(false);
262+
// Set pagination state for vector search
264263
setSearchTotalCount(allResults.length);
265264
}
266265
} else {
@@ -352,15 +351,19 @@ export default function Movies() {
352351
return { paginatedResults: [], hasNext: false, hasPrev: false, totalPages: 0 };
353352
}
354353

354+
const totalResults = allVectorSearchResults.length;
355+
const totalPages = Math.ceil(totalResults / vectorSearchPageSize);
356+
const hasNext = vectorSearchPage < totalPages;
357+
const hasPrev = vectorSearchPage > 1;
358+
355359
const startIndex = (vectorSearchPage - 1) * vectorSearchPageSize;
356360
const endIndex = startIndex + vectorSearchPageSize;
357361
const paginatedResults = allVectorSearchResults.slice(startIndex, endIndex);
358-
const totalPages = Math.ceil(allVectorSearchResults.length / vectorSearchPageSize);
359362

360363
return {
361364
paginatedResults,
362-
hasNext: vectorSearchPage < totalPages,
363-
hasPrev: vectorSearchPage > 1,
365+
hasNext,
366+
hasPrev,
364367
totalPages
365368
};
366369
};
@@ -653,55 +656,60 @@ export default function Movies() {
653656
/* Vector search results with client-side pagination */
654657
(() => {
655658
const { hasNext, hasPrev, totalPages } = getVectorSearchPageData();
656-
return totalPages > 1 ? (
657-
<nav className={movieStyles.pagination} aria-label="Vector search results pagination">
658-
<div className={movieStyles.paginationContainer}>
659-
{/* Previous Button */}
660-
{hasPrev ? (
661-
<button
662-
onClick={() => handleVectorSearchPageChange(vectorSearchPage - 1)}
663-
className={movieStyles.pageButton}
664-
aria-label="Go to previous page"
665-
>
666-
← Previous
667-
</button>
668-
) : (
669-
<span className={`${movieStyles.pageButton} ${movieStyles.disabled}`}>
670-
← Previous
671-
</span>
672-
)}
673-
674-
{/* Current Page Info */}
675-
<div className={movieStyles.pageInfo}>
676-
Page {vectorSearchPage} of {totalPages}
659+
660+
if (totalPages > 1) {
661+
return (
662+
<nav className={movieStyles.pagination} aria-label="Vector search results pagination">
663+
<div className={movieStyles.paginationContainer}>
664+
{/* Previous Button */}
665+
{hasPrev ? (
666+
<button
667+
onClick={() => handleVectorSearchPageChange(vectorSearchPage - 1)}
668+
className={movieStyles.pageButton}
669+
aria-label="Go to previous page"
670+
>
671+
← Previous
672+
</button>
673+
) : (
674+
<span className={`${movieStyles.pageButton} ${movieStyles.disabled}`}>
675+
← Previous
676+
</span>
677+
)}
678+
679+
{/* Current Page Info */}
680+
<div className={movieStyles.pageInfo}>
681+
Page {vectorSearchPage} of {totalPages}
682+
</div>
683+
684+
{/* Next Button */}
685+
{hasNext ? (
686+
<button
687+
onClick={() => handleVectorSearchPageChange(vectorSearchPage + 1)}
688+
className={movieStyles.pageButton}
689+
aria-label="Go to next page"
690+
>
691+
Next →
692+
</button>
693+
) : (
694+
<span className={`${movieStyles.pageButton} ${movieStyles.disabled}`}>
695+
Next →
696+
</span>
697+
)}
677698
</div>
678699

679-
{/* Next Button */}
680-
{hasNext ? (
681-
<button
682-
onClick={() => handleVectorSearchPageChange(vectorSearchPage + 1)}
683-
className={movieStyles.pageButton}
684-
aria-label="Go to next page"
685-
>
686-
Next →
687-
</button>
688-
) : (
689-
<span className={`${movieStyles.pageButton} ${movieStyles.disabled}`}>
690-
Next →
691-
</span>
692-
)}
693-
</div>
694-
695-
{/* Additional Info */}
696-
<div className={movieStyles.additionalInfo}>
697-
{vectorSearchPageSize} movies per page • {allVectorSearchResults.length} total results
700+
{/* Additional Info */}
701+
<div className={movieStyles.additionalInfo}>
702+
{vectorSearchPageSize} movies per page • {allVectorSearchResults.length} total results
703+
</div>
704+
</nav>
705+
);
706+
} else {
707+
return (
708+
<div className={movieStyles.searchInfo}>
709+
Showing {allVectorSearchResults.length} results (vector search)
698710
</div>
699-
</nav>
700-
) : (
701-
<div className={movieStyles.searchInfo}>
702-
Showing {allVectorSearchResults.length} results (vector search)
703-
</div>
704-
);
711+
);
712+
}
705713
})()
706714
)
707715
) : (

client/tsconfig.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
"moduleResolution": "bundler",
1616
"resolveJsonModule": true,
1717
"isolatedModules": true,
18-
"jsx": "react-jsx",
18+
"jsx": "preserve",
1919
"incremental": true,
2020
"plugins": [
2121
{

server/express/package.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@
1212
"dev": "ts-node src/app.ts",
1313
"test": "jest",
1414
"test:watch": "jest --watch",
15-
"test:coverage": "jest --coverage"
15+
"test:coverage": "jest --coverage",
16+
"test:unit": "jest tests/controllers",
17+
"test:verbose": "jest --verbose",
18+
"test:silent": "jest --silent"
1619
},
1720
"dependencies": {
1821
"cors": "^2.8.5",

0 commit comments

Comments
 (0)