Skip to content

Conversation

@SebastianSchuetze
Copy link
Contributor

Summary: This PR hardens paginated blog routing to prevent invalid or duplicate pages and canonicalizes page-1 navigation. It also aligns static route generation with runtime pagination settings.

Changes:

  • Validate pageNumber as digits-only, parse safely, and reject non-positive values in /src/app/(frontend)/posts/page/[pageNumber]/page.tsx.
  • Redirect /posts/page/1 to canonical /posts.
  • Return notFound() when a requested page is out of range (no docs or page > total pages).
  • Introduce POSTS_PER_PAGE = 12 and reuse it for both payload.find and generateStaticParams.
  • Generate static params from page 2 onward to avoid duplicating page 1.
  • Update /src/components/molecules/Pagination/index.tsx to navigate to /posts when target page is 1.
  • Add route-level and molecule-level regression tests for canonical navigation and pagination bounds.

Why:

  • Before this change, pagination could produce duplicate or empty routes (/posts vs /posts/page/1, invalid page numbers, and mismatched static/runtime page calculations). This caused inconsistent navigation behavior and avoidable SEO duplication risk.

Testing:

  • pnpm vitest run tests/unit/components/paginationMolecule.test.tsx tests/unit/app/frontend/posts/paginatedPostsPage.test.ts
  • pnpm exec eslint src/app/'(frontend)'/posts/page/'[pageNumber]'/page.tsx src/components/molecules/Pagination/index.tsx tests/unit/components/paginationMolecule.test.tsx tests/unit/app/frontend/posts/paginatedPostsPage.test.ts
  • pnpm run check currently fails due pre-existing unrelated TypeScript issues in auth tests (missing collection field in fixtures).

Related: None

Breaking changes: None

Copilot AI review requested due to automatic review settings February 9, 2026 21:04
@github-actions github-actions bot added the fix label Feb 9, 2026
@SebastianSchuetze SebastianSchuetze enabled auto-merge (squash) February 9, 2026 21:06
@github-actions
Copy link

github-actions bot commented Feb 9, 2026

Coverage Report for Unit Tests

Status Category Percentage Covered / Total
🔵 Lines 54.1% (🎯 40%) 1298 / 2399
🔵 Statements 53.66% (🎯 40%) 1392 / 2594
🔵 Functions 45.41% (🎯 33%) 223 / 491
🔵 Branches 49.9% (🎯 35%) 1039 / 2082
File Coverage
File Stmts Branches Functions Lines Uncovered Lines
Changed Files
src/app/(frontend)/posts/page.tsx 0% 0% 0% 0% 14-93
src/app/(frontend)/posts/_components/PostsPagination.tsx 33.33% 100% 0% 33.33% 10-12
src/app/(frontend)/posts/page/[pageNumber]/page.tsx 85.18% 52.38% 66.66% 81.81% 60-61, 93-96
Unchanged Files
src/imageConfig.js 22.72% 0% 0% 26.31% 53-84
src/access/anyone.ts 100% 100% 100% 100%
src/access/authenticated.ts 100% 100% 100% 100%
src/access/authenticatedAndAdmin.ts 100% 100% 100% 100%
src/access/authenticatedOrApprovedClinic.ts 100% 100% 100% 100%
src/access/authenticatedOrPublished.ts 100% 100% 100% 100%
src/access/clinicGallery.ts 95% 83.33% 100% 95% 30
src/access/fieldAccess.ts 100% 100% 100% 100%
src/access/isClinicBasicUser.ts 100% 100% 100% 100%
src/access/isPatient.ts 100% 100% 100% 100%
src/access/isPlatformBasicUser.ts 50% 37.5% 50% 50% 10-17
src/access/scopeFilters.ts 100% 100% 100% 100%
src/access/utils/getClinicAssignment.ts 92.59% 74.07% 100% 95.83% 10, 27
src/access/utils/getDoctorClinic.ts 58.33% 50% 100% 63.63% 6, 16, 18, 22-23
src/app/(frontend)/layout.tsx 0% 100% 0% 0% 20-63
src/app/(frontend)/not-found.tsx 0% 100% 0% 0% 9-20
src/app/(frontend)/page.tsx 0% 0% 0% 0% 34-191
src/app/(frontend)/(pages)/[...slug]/page.tsx 0% 0% 0% 0% 14-97
src/app/(frontend)/(sitemaps)/pages-sitemap.xml/route.ts 0% 0% 0% 0% 6-65
src/app/(frontend)/(sitemaps)/posts-sitemap.xml/route.ts 0% 0% 0% 0% 6-52
src/app/(frontend)/_components/PayloadRedirects/index.tsx 0% 0% 0% 0% 14-45
src/app/(frontend)/admin/first-admin/page.tsx 0% 0% 0% 0% 5-17
src/app/(frontend)/admin/login/page.tsx 65% 64.28% 100% 65% 32-42
src/app/(frontend)/admin/logout/page.tsx 0% 100% 0% 0% 10-48
src/app/(frontend)/auth/invite/complete/InviteCompleteForm.tsx 0% 0% 0% 0% 14-152
src/app/(frontend)/auth/invite/complete/page.tsx 0% 100% 0% 0% 1-9
src/app/(frontend)/auth/password/reset/ResetPasswordRequestForm.tsx 24% 35% 25% 25% 23-33, 41-58
src/app/(frontend)/auth/password/reset/page.tsx 0% 100% 0% 0% 5-20
src/app/(frontend)/auth/password/reset/complete/ResetPasswordCompleteForm.tsx 0% 0% 0% 0% 13-138
src/app/(frontend)/auth/password/reset/complete/page.tsx 0% 100% 0% 0% 5-24
src/app/(frontend)/listing-comparison/ListingComparisonFilters.client.tsx 0% 0% 0% 0% 29-75
src/app/(frontend)/listing-comparison/ListingComparisonPage.client.tsx 0% 0% 0% 0% 50-109
src/app/(frontend)/listing-comparison/page.tsx 0% 100% 0% 0% 14-49
src/app/(frontend)/login/patient/page.tsx 0% 0% 0% 0% 4-47
src/app/(frontend)/next/exit-preview/route.ts 0% 100% 0% 0% 4-6
src/app/(frontend)/next/preview/route.ts 0% 0% 0% 0% 15-59
src/app/(frontend)/partners/clinics/page.tsx 0% 0% 0% 0% 42-145
src/app/(frontend)/posts/page.client.tsx 0% 100% 0% 0% 4-5
src/app/(frontend)/posts/[slug]/PostShareActionBar.tsx 0% 0% 0% 0% 16-31
src/app/(frontend)/posts/[slug]/page.client.tsx 0% 100% 0% 0% 4-5
src/app/(frontend)/posts/[slug]/page.tsx 0% 0% 0% 0% 23-156
src/app/(frontend)/posts/page/[pageNumber]/page.client.tsx 50% 100% 0% 50% 5
src/app/(frontend)/register/clinic/page.tsx 0% 100% 0% 0% 4-7
src/app/(frontend)/register/patient/page.tsx 0% 100% 0% 0% 4-7
src/app/(payload)/layout.tsx 0% 100% 0% 0% 15-27
src/app/(payload)/admin/importMap.js 0% 100% 100% 0% 45-89
src/app/(payload)/admin/[[...segments]]/not-found.tsx 0% 100% 0% 0% 18-21
src/app/(payload)/admin/[[...segments]]/page.tsx 0% 100% 0% 0% 18-21
src/app/(payload)/api/[...slug]/route.ts 0% 100% 100% 0% 7-13
src/app/(payload)/api/graphql/route.ts 0% 100% 100% 0% 6-8
src/app/(payload)/api/graphql-playground/route.ts 0% 100% 100% 0% 7
src/app/api/auth/login/route.ts 0% 0% 0% 0% 5-70
src/app/api/auth/password/reset/route.ts 81.25% 83.33% 50% 86.66% 11, 33-34
src/app/api/auth/register/clinic/route.ts 75% 70% 50% 80% 11, 28, 59-63
src/app/api/auth/register/first-admin/route.ts 46.66% 25% 100% 46.66% 25, 39, 45, 49, 80-113
src/app/api/auth/register/patient/cleanup/route.ts 91.3% 100% 100% 91.3% 52-53
src/app/api/auth/register/patient/metadata/route.ts 91.66% 93.75% 100% 91.66% 58-59
src/app/api/forms/[slug]/route.ts 0% 0% 0% 0% 10-35
src/app/auth/callback/route.ts 0% 0% 0% 0% 5-20
src/auth/index.ts 0% 0% 0% 0%
src/auth/config/authConfig.ts 100% 100% 100% 100%
src/auth/strategies/supabaseStrategy.ts 97.5% 78.57% 100% 97.5% 39
src/auth/types/authTypes.ts 0% 0% 0% 0%
src/auth/utilities/accessValidation.ts 100% 91.66% 100% 100%
src/auth/utilities/firstAdminCheck.ts 100% 75% 100% 100%
src/auth/utilities/hydrateSessionFromHash.ts 91.66% 90% 100% 100% 10
src/auth/utilities/jwtValidation.ts 97.22% 92.5% 100% 97.05% 93
src/auth/utilities/loginHandler.ts 0% 0% 0% 0% 9-30
src/auth/utilities/registration.ts 0% 0% 0% 0% 27-91
src/auth/utilities/supaBaseClient.ts 0% 100% 0% 0% 4
src/auth/utilities/supaBaseServer.ts 3.44% 0% 0% 3.84% 7-67
src/auth/utilities/supabaseProvision.ts 78.04% 64% 83.33% 80% 54, 84, 148-154
src/auth/utilities/userCreation.ts 100% 85.71% 100% 100%
src/auth/utilities/userLookup.ts 62.5% 33.33% 100% 62.5% 34-36, 59-61
src/blocks/RenderBlocks.tsx 0% 0% 0% 0% 12-51
src/blocks/ArchiveBlock/config.ts 16.66% 100% 0% 16.66% 14-78
src/blocks/Banner/config.ts 50% 100% 0% 50% 25
src/blocks/BlogHero/config.ts 100% 100% 100% 100%
src/blocks/CallToAction/config.ts 50% 100% 0% 50% 16-21
src/blocks/Content/config.ts 50% 100% 0% 50% 22-84
src/blocks/Form/config.ts 33.33% 100% 0% 33.33% 24-33
src/blocks/Form/fields.tsx 0% 100% 100% 0% 11-21
src/blocks/Form/Checkbox/index.tsx 0% 0% 0% 0% 18-30
src/blocks/Form/Country/index.tsx 0% 0% 0% 0% 18-47
src/blocks/Form/Email/index.tsx 0% 0% 0% 0% 16-36
src/blocks/Form/Error/index.tsx 0% 100% 0% 0% 3-4
src/blocks/Form/Message/index.tsx 0% 0% 0% 0% 7-11
src/blocks/Form/Number/index.tsx 0% 0% 0% 0% 15-29
src/blocks/Form/Select/index.tsx 0% 0% 0% 0% 25-59
src/blocks/Form/State/index.tsx 0% 0% 0% 0% 18-46
src/blocks/Form/Text/index.tsx 0% 0% 0% 0% 16-30
src/blocks/Form/Textarea/index.tsx 0% 0% 0% 0% 17-38
src/blocks/Form/Width/index.tsx 0% 0% 0% 0% 7-11
src/blocks/MediaBlock/config.ts 100% 100% 100% 100%
src/blocks/_shared/CMSLink.tsx 0% 0% 0% 0% 23-52
src/blocks/_shared/utils.ts 100% 100% 100% 100%
src/blocks/_shared/RichText/index.tsx 0% 0% 0% 0% 22-70
src/collections/Accreditation.ts 100% 100% 100% 100%
src/collections/Categories.ts 100% 100% 100% 100%
src/collections/Cities.ts 100% 100% 100% 100%
src/collections/ClinicApplications.ts 40% 0% 33.33% 40% 146-156
src/collections/ClinicStaff.ts 81.25% 63.63% 66.66% 84.61% 24, 53-89
src/collections/Clinics.ts 20% 0% 0% 20% 209-251
src/collections/Countries.ts 100% 100% 100% 100%
src/collections/DoctorSpecialties.ts 100% 100% 100% 100%
src/collections/DoctorTreatments.ts 25% 100% 0% 25% 72-76
src/collections/Doctors.ts 16.66% 0% 0% 22.22% 89-152
src/collections/FavoriteClinics.ts 28.57% 14.28% 50% 25% 32-46
src/collections/MedicalSpecialties.ts 100% 100% 100% 100%
src/collections/PlatformStaff.ts 75% 100% 66.66% 75% 38-40
src/collections/Reviews.ts 17.85% 5.4% 57.14% 18.51% 38-247
src/collections/Tags.ts 100% 100% 100% 100%
src/collections/Treatments.ts 100% 100% 100% 100%
src/collections/BasicUsers/index.ts 100% 100% 100% 100%
src/collections/BasicUsers/hooks/createSupabaseUser.ts 100% 91.66% 100% 100%
src/collections/BasicUsers/hooks/createUserProfile.ts 100% 85.71% 100% 100%
src/collections/BasicUsers/hooks/deleteSupabaseUser.ts 73.07% 50% 100% 73.07% 45-53, 66-83
src/collections/ClinicGalleryEntries/index.ts 90% 88.88% 50% 88.88% 136
src/collections/ClinicGalleryEntries/hooks/beforeChangeClinicGalleryEntry.ts 6.25% 0% 0% 6.25% 13-32, 47-77
src/collections/ClinicGalleryMedia/index.ts 73.68% 88.88% 20% 72.22% 20-21, 140-177
src/collections/ClinicMedia/index.ts 81.25% 72.72% 25% 80% 92-111
src/collections/ClinicTreatments/index.ts 100% 100% 100% 100%
src/collections/ClinicTreatments/hooks/averagePriceUtils.ts 72.72% 66.66% 100% 76.47% 7, 9, 25, 36-37, 57
src/collections/ClinicTreatments/hooks/updateAveragePriceAfterChange.ts 75% 60% 100% 80% 11, 21-26
src/collections/ClinicTreatments/hooks/updateAveragePriceAfterDelete.ts 81.81% 50% 100% 90% 7, 15
src/collections/DoctorMedia/index.ts 85% 100% 25% 83.33% 93-112
src/collections/DoctorMedia/hooks/beforeChangeDoctorMedia.ts 89.28% 72.97% 100% 89.28% 17, 22, 45
src/collections/Pages/index.ts 62.5% 0% 66.66% 62.5% 44-58
src/collections/Pages/hooks/populatePublishedAt.ts 20% 0% 0% 20% 4-12
src/collections/Pages/hooks/revalidatePage.ts 100% 81.25% 100% 100%
src/collections/Patients/index.ts 100% 100% 100% 100%
src/collections/Patients/hooks/patientSupabaseCreate.ts 82.35% 80% 100% 81.25% 32-34
src/collections/Patients/hooks/patientSupabaseDelete.ts 78.57% 66.66% 100% 84.61% 8, 16-18
src/collections/PlatformContentMedia/index.ts 70% 100% 50% 70% 51-70
src/collections/PlatformContentMedia/hooks/beforeChangePlatformContentMedia.ts 100% 83.33% 100% 100%
src/collections/Posts/index.ts 35.71% 0% 40% 35.71% 55-245
src/collections/Posts/hooks/populateAuthors.ts 2.32% 0% 0% 2.43% 7-100
src/collections/Posts/hooks/revalidatePost.ts 100% 100% 100% 100%
src/collections/UserProfileMedia/index.ts 67.64% 60.95% 71.42% 74.68% 20, 24, 32, 38-45, 51, 74, 75, 83-87, 148, 152, 153, 156, 194-232
src/collections/common/mediaPathHelpers.ts 71.11% 72.28% 100% 75% 28, 38-61, 89, 94, 111, 116, 133, 139, 147
src/collections/common/selectionOptions.ts 100% 100% 100% 100%
src/collections/common/stableIdField.ts 50% 0% 50% 40% 25-28
src/components/molecules/Media/types.ts 0% 0% 0% 0%
src/components/organisms/Auth/types/loginTypes.ts 0% 0% 0% 0%
src/components/organisms/Doctors/index.ts 0% 0% 0% 0%
src/components/organisms/Doctors/types.ts 0% 0% 0% 0%
src/components/organisms/Landing/LandingTestimonials.types.ts 0% 0% 0% 0%
src/components/organisms/Landing/index.ts 0% 0% 0% 0%
src/components/organisms/Listing/index.ts 0% 0% 0% 0%
src/endpoints/seed/data/baseline/accreditations.json 0% 0% 0% 0%
src/endpoints/seed/data/baseline/categories.json 0% 0% 0% 0%
src/endpoints/seed/data/baseline/cities.json 0% 0% 0% 0%
src/endpoints/seed/data/baseline/countries.json 0% 0% 0% 0%
src/endpoints/seed/data/baseline/globals.json 0% 0% 0% 0%
src/endpoints/seed/data/baseline/medicalSpecialties.json 0% 0% 0% 0%
src/endpoints/seed/data/baseline/tags.json 0% 0% 0% 0%
src/endpoints/seed/data/baseline/treatments.json 0% 0% 0% 0%
src/endpoints/seed/data/demo/basicUsers.json 0% 0% 0% 0%
src/endpoints/seed/data/demo/clinicTreatments.json 0% 0% 0% 0%
src/endpoints/seed/data/demo/clinics.json 0% 0% 0% 0%
src/endpoints/seed/data/demo/doctorSpecialties.json 0% 0% 0% 0%
src/endpoints/seed/data/demo/doctorTreatments.json 0% 0% 0% 0%
src/endpoints/seed/data/demo/doctors.json 0% 0% 0% 0%
src/endpoints/seed/data/demo/favoriteClinics.json 0% 0% 0% 0%
src/endpoints/seed/data/demo/platformContentMedia.json 0% 0% 0% 0%
src/endpoints/seed/data/demo/posts.json 0% 0% 0% 0%
src/endpoints/seed/data/demo/reviews.json 0% 0% 0% 0%
src/endpoints/seed/data/demo/userProfileMedia.json 0% 0% 0% 0%
src/fields/defaultLexical.ts 9.09% 0% 0% 10% 29-48
src/fields/link.ts 83.33% 88.88% 60% 81.25% 75-85, 117
src/fields/linkGroup.ts 100% 100% 100% 100%
src/globals/Footer/RowLabel.tsx 0% 0% 0% 0% 5-12
src/globals/Footer/config.ts 50% 100% 0% 50% 9
src/globals/Footer/hooks/revalidateFooter.ts 20% 0% 0% 20% 6-12
src/globals/Header/RowLabel.tsx 0% 0% 0% 0% 5-12
src/globals/Header/config.ts 50% 100% 0% 50% 9
src/globals/Header/hooks/revalidateHeader.ts 20% 0% 0% 20% 6-12
src/hooks/createdBy.ts 100% 84.61% 100% 100%
src/hooks/ensurePatientOnAuth.ts 100% 54.54% 100% 100%
src/hooks/immutability.ts 100% 95% 100% 100%
src/hooks/ownership.ts 90% 80.64% 100% 94.44% 15, 19
src/hooks/publishedAt.ts 100% 85.71% 100% 100%
src/hooks/revalidateRedirects.ts 25% 100% 0% 25% 6-10
src/hooks/calculations/updateAverageRatings.ts 2.63% 0% 0% 2.73% 12-89, 94-155, 159-192
src/hooks/media/computeStorage.ts 82.14% 61.72% 100% 84.31% 112-116, 124-127
src/plugins/index.ts 22.72% 43.47% 0% 23.8% 20, 24-26, 79-150
src/plugins/mcp.ts 47.36% 0% 40% 50% 88-113
src/providers/index.tsx 0% 100% 0% 0% 5-6
src/search/beforeSync.ts 28% 13.33% 40% 27.08% 7-17, 72-139
src/search/fieldOverrides.ts 100% 100% 100% 100%
src/security/permission-matrix.config.ts 0% 100% 100% 0% 114-562
src/utilities/buildSearchWhere.ts 96% 86.36% 100% 95.83% 105
src/utilities/canUseDOM.ts 0% 0% 0% 0%
src/utilities/deepMerge.ts 90% 90.9% 100% 90% 24
src/utilities/formatAuthors.ts 100% 100% 100% 100%
src/utilities/formatDateTime.ts 100% 100% 100% 100%
src/utilities/generateMeta.ts 100% 93.33% 100% 100%
src/utilities/generatePreviewPath.ts 100% 100% 100% 100%
src/utilities/getDocument.ts 100% 100% 100% 100%
src/utilities/getForm.ts 100% 100% 100% 100%
src/utilities/getGlobals.ts 100% 100% 100% 100%
src/utilities/getMediaUrl.ts 100% 100% 100% 100%
src/utilities/getRedirects.ts 100% 100% 100% 100%
src/utilities/getURL.ts 75% 78.57% 100% 75% 42-46
src/utilities/mapPostToCardData.ts 100% 81.25% 100% 100%
src/utilities/mergeOpenGraph.ts 100% 100% 100% 100%
src/utilities/nameUtils.ts 100% 100% 100% 100%
src/utilities/normalizeNavItems.ts 94.73% 86.84% 100% 100% 72
src/utilities/requestFileUtils.ts 100% 85% 100% 100%
src/utilities/slugify.ts 100% 100% 100% 100%
src/utilities/submitForm.ts 100% 100% 100% 100%
src/utilities/ui.ts 100% 100% 100% 100%
src/utilities/use-prefers-reduced-motion.ts 77.77% 62.5% 80% 100% 4, 5, 14, 17
src/utilities/useClickableCard.ts 0% 0% 0% 0% 58-132
src/utilities/useDebounce.ts 0% 0% 0% 0% 18-30
src/utilities/blog/calculateReadTime.ts 0% 0% 0% 0% 10-48
src/utilities/blog/formatDate.ts 0% 0% 0% 0% 7-17
src/utilities/blog/normalizePost.ts 0% 0% 0% 0% 39-80
src/utilities/blog/sharePostUrl.ts 80.59% 77.55% 70% 83.63% 26-48, 100, 104, 134-139
src/utilities/listingComparison/filters.ts 90.9% 79.31% 100% 96.29% 12, 57, 63
src/utilities/listingComparison/sort.ts 96% 78.26% 100% 95.83% 70
src/utilities/media/resolveMediaImage.ts 7.69% 0% 0% 8.69% 25-76
src/utilities/placeholders/landingProcess.ts 0% 100% 100% 0% 6-16
src/utilities/placeholders/listingComparison.ts 0% 100% 100% 0% 8-100
Generated in workflow #1513 for commit 6ec4a5a by the Vitest Coverage Report Action

@github-actions
Copy link

github-actions bot commented Feb 9, 2026

Coverage Report for Storybook Tests

Status Category Percentage Covered / Total
🔵 Lines 78.51% (🎯 10%) 1129 / 1438
🔵 Statements 76.13% (🎯 10%) 1187 / 1559
🔵 Functions 85.2% (🎯 10%) 334 / 392
🔵 Branches 64.89% (🎯 10%) 828 / 1276
File Coverage
File Stmts Branches Functions Lines Uncovered Lines
Changed Files
src/components/molecules/Pagination/index.tsx 42.85% 8.33% 12.5% 47.36% 27, 31-33, 44-103
Unchanged Files
src/components/atoms/accordion.tsx 100% 100% 100% 100%
src/components/atoms/alert.tsx 100% 80% 100% 100%
src/components/atoms/button.tsx 100% 87.5% 100% 100%
src/components/atoms/card.tsx 100% 80% 100% 100%
src/components/atoms/carousel.tsx 76.62% 51.06% 93.33% 76.62% 36, 56, 72-86, 96, 185, 226
src/components/atoms/checkbox.tsx 100% 100% 100% 100%
src/components/atoms/combobox.tsx 75% 77.77% 75% 71.42% 67-68
src/components/atoms/command.tsx 100% 100% 100% 100%
src/components/atoms/dialog.tsx 100% 100% 100% 100%
src/components/atoms/input.tsx 100% 80% 100% 100%
src/components/atoms/label.tsx 100% 100% 100% 100%
src/components/atoms/pagination.tsx 100% 100% 100% 100%
src/components/atoms/popover.tsx 100% 100% 100% 100%
src/components/atoms/select.tsx 100% 100% 100% 100%
src/components/atoms/separator.tsx 100% 100% 100% 100%
src/components/atoms/slider.tsx 94.73% 54.16% 80% 94.44% 61
src/components/atoms/tabs.tsx 100% 100% 100% 100%
src/components/atoms/textarea.tsx 100% 100% 100% 100%
src/components/atoms/verification-badge.tsx 100% 71.42% 100% 100%
src/components/atoms/Heading/index.tsx 100% 87.5% 100% 100%
src/components/molecules/Breadcrumb/index.tsx 100% 100% 100% 100%
src/components/molecules/CheckboxGroup/index.tsx 100% 100% 100% 100%
src/components/molecules/CheckboxWithLabel/index.tsx 80% 50% 100% 100% 26
src/components/molecules/ClinicSearchBar/index.tsx 42.85% 100% 33.33% 42.85% 38, 57-102
src/components/molecules/Container/index.tsx 100% 66.66% 100% 100%
src/components/molecules/Link/index.tsx 90.9% 90% 100% 100% 32
src/components/molecules/LocationLine/index.tsx 100% 100% 100% 100%
src/components/molecules/Logo/Logo.tsx 100% 100% 100% 100%
src/components/molecules/Media/index.tsx 100% 100% 100% 100%
src/components/molecules/Media/types.ts 0% 0% 0% 0%
src/components/molecules/Media/ImageMedia/index.tsx 100% 92.85% 100% 100%
src/components/molecules/Media/VideoMedia/index.tsx 90.9% 66.66% 100% 100% 22
src/components/molecules/PageRange/index.tsx 83.33% 83.33% 100% 100% 29, 32
src/components/molecules/PostActionBar/index.tsx 100% 60% 100% 100%
src/components/molecules/PriceSummary/index.tsx 75% 50% 100% 100% 19
src/components/molecules/RatingFilter/index.tsx 100% 100% 100% 100%
src/components/molecules/RatingSummary/index.tsx 100% 100% 100% 100%
src/components/molecules/SectionBackground/SectionBackgroundParallax.client.tsx 87.5% 74.07% 87.5% 90.56% 40, 52-53, 65, 91-96, 123-124
src/components/molecules/SectionBackground/index.tsx 26.56% 34.37% 100% 24.19% 53-59, 65-152
src/components/molecules/SectionHeading/index.tsx 100% 75% 100% 100%
src/components/molecules/SocialLink/index.tsx 100% 100% 100% 100%
src/components/molecules/SortControl/index.tsx 100% 80% 100% 100%
src/components/molecules/TagList/index.tsx 100% 100% 100% 100%
src/components/molecules/WaitTime/index.tsx 100% 100% 100% 100%
src/components/organisms/AdminBar/index.tsx 81.25% 50% 50% 81.25% 69-71
src/components/organisms/Auth/ClinicRegistrationForm.tsx 100% 50% 100% 100%
src/components/organisms/Auth/FirstAdminRegistrationForm.tsx 83.33% 25% 100% 83.33% 19
src/components/organisms/Auth/LoginForm.tsx 86.15% 66.66% 87.5% 88.33% 35, 82-84, 95-98, 146-154
src/components/organisms/Auth/PatientRegistrationForm.tsx 59.09% 55.55% 66.66% 59.09% 13, 27, 33, 44, 48-62
src/components/organisms/Auth/RegistrationForm.tsx 100% 88.23% 100% 100%
src/components/organisms/Auth/types/loginTypes.ts 0% 0% 0% 0%
src/components/organisms/Banner/index.tsx 100% 100% 100% 100%
src/components/organisms/Blog/BlogCard/Enhanced.tsx 100% 87.87% 100% 100%
src/components/organisms/Blog/BlogCard/Overlay.tsx 100% 73.33% 100% 100%
src/components/organisms/Blog/BlogCard/Overview.tsx 100% 87.5% 100% 100%
src/components/organisms/Blog/BlogCard/Simple.tsx 100% 62.5% 100% 100%
src/components/organisms/Blog/BlogCard/index.tsx 100% 100% 100% 100%
src/components/organisms/Blog/BlogCardCollection/index.tsx 100% 91.3% 100% 100%
src/components/organisms/Blog/BlogHero/index.tsx 100% 100% 100% 100%
src/components/organisms/CallToAction/index.tsx 100% 92.3% 100% 100%
src/components/organisms/CollectionArchive/index.tsx 83.33% 70% 100% 83.33% 44
src/components/organisms/Content/index.tsx 100% 88.46% 100% 100%
src/components/organisms/DeveloperDashboard/index.tsx 27.27% 12.5% 50% 27.27% 53-83
src/components/organisms/DeveloperDashboard/Seeding/SeedingCard.tsx 3.92% 0% 0% 4.54% 15-27, 31, 35-53, 68-207
src/components/organisms/DeveloperDashboard/Seeding/SeedingCardView.tsx 56.52% 38.88% 42.85% 63.15% 31-33, 37-41, 114-126
src/components/organisms/Doctors/DoctorCard.tsx 100% 57.89% 100% 100%
src/components/organisms/Doctors/RelatedDoctorSection.client.tsx 81.81% 66.66% 88.88% 90% 21, 31, 42, 48
src/components/organisms/Doctors/RelatedDoctorSection.tsx 100% 100% 100% 100%
src/components/organisms/Doctors/index.ts 0% 0% 0% 0%
src/components/organisms/Doctors/types.ts 0% 0% 0% 0%
src/components/organisms/FAQ/index.tsx 100% 100% 100% 100%
src/components/organisms/Form/index.tsx 42.5% 50% 33.33% 43.58% 74-123, 161
src/components/organisms/Heroes/FeatureHero/index.tsx 100% 92.85% 100% 100%
src/components/organisms/Heroes/LandingHero/LandingHeroSearchBar.client.tsx 75% 100% 50% 75% 21
src/components/organisms/Heroes/LandingHero/index.tsx 100% 100% 100% 100%
src/components/organisms/Heroes/PostHero/index.tsx 100% 92.85% 100% 100%
src/components/organisms/Landing/LandingCategories.tsx 86.3% 64.44% 84% 87.3% 77-80, 88, 95, 97, 148, 240, 262-263
src/components/organisms/Landing/LandingContact.tsx 100% 100% 100% 100%
src/components/organisms/Landing/LandingFeatures.tsx 100% 76% 100% 100%
src/components/organisms/Landing/LandingPricing.tsx 100% 100% 100% 100%
src/components/organisms/Landing/LandingProcess.tsx 87.42% 59.59% 94.59% 92.59% 143-144, 234, 254, 263, 289, 294, 299, 327-345, 351, 367, 375-376, 388, 421
src/components/organisms/Landing/LandingTeam.tsx 88.88% 50% 100% 100% 66
src/components/organisms/Landing/LandingTestimonials.tsx 100% 100% 100% 100%
src/components/organisms/Landing/LandingTestimonials.types.ts 0% 0% 0% 0%
src/components/organisms/Landing/LandingTestimonialsCarousel.tsx 72% 60.24% 100% 79.25% 53, 77, 110, 125, 139, 154, 156, 157, 164-170, 180-183, 221, 223, 224, 233-238, 247, 252-254, 260-268, 272, 401
src/components/organisms/Landing/index.ts 0% 0% 0% 0%
src/components/organisms/Listing/ListingCard.tsx 100% 50% 100% 100%
src/components/organisms/Listing/ListingFilters.tsx 86.11% 66.66% 85.71% 86.11% 23, 59-60, 97-99
src/components/organisms/Listing/index.ts 0% 0% 0% 0%
src/components/organisms/LivePreviewListener/index.tsx 100% 100% 100% 100%
src/components/organisms/MediaBlock/index.tsx 100% 100% 100% 100%
src/components/organisms/TreatmentsStrip/index.tsx 100% 90.9% 100% 100%
src/components/organisms/TrustQualitySection/AnimatedCountUp.tsx 72.91% 64.7% 81.81% 76.08% 51, 58-60, 64, 74-76, 87-88, 94-96
src/components/organisms/TrustQualitySection/index.tsx 100% 85% 100% 100%
src/components/templates/Footer/Component.tsx 100% 100% 100% 100%
src/components/templates/Header/Component.tsx 100% 100% 100% 100%
src/components/templates/Header/Nav/index.tsx 75% 60% 73.91% 75% 22-24, 31-34, 56, 171-172, 176-177, 202-205, 256
src/components/templates/ListingComparison/Component.tsx 100% 76.92% 100% 100%
Generated in workflow #1513 for commit 6ec4a5a by the Vitest Coverage Report Action

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Hardens /posts/page/[pageNumber] routing to avoid invalid/duplicate pagination routes and keep runtime pagination logic aligned with static route generation, improving canonical navigation and reducing SEO duplication.

Changes:

  • Validate and canonicalize paginated posts routes (redirect /posts/page/1/posts, notFound() for invalid/out-of-range pages).
  • Introduce POSTS_PER_PAGE = 12 and reuse it in both find and generateStaticParams (static params start at page 2).
  • Update the Pagination molecule to navigate to /posts when the target page is 1, and add regression tests for routing + molecule navigation.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
src/app/(frontend)/posts/page/[pageNumber]/page.tsx Adds page param validation, canonical redirect for page 1, bounds checking, and aligns static params with runtime page size.
src/components/molecules/Pagination/index.tsx Canonicalizes navigation to /posts when the target page is 1.
tests/unit/components/paginationMolecule.test.tsx Adds molecule-level regression tests for canonical navigation to /posts.
tests/unit/app/frontend/posts/paginatedPostsPage.test.ts Adds route-level tests for redirect/notFound behavior and static param generation consistency.

@github-actions
Copy link

github-actions bot commented Feb 9, 2026

Coverage Report for Integration Tests

Status Category Percentage Covered / Total
🔵 Lines 78.27% (🎯 50%) 746 / 953
🔵 Statements 75.11% (🎯 50%) 785 / 1045
🔵 Functions 86.06% (🎯 50%) 142 / 165
🔵 Branches 65.23% (🎯 50%) 621 / 952
File Coverage
File Stmts Branches Functions Lines Uncovered Lines
Unchanged Files
src/access/anyone.ts 100% 100% 100% 100%
src/access/authenticated.ts 0% 100% 0% 0% 7-8
src/access/authenticatedAndAdmin.ts 0% 0% 0% 0% 10-12
src/access/authenticatedOrApprovedClinic.ts 0% 0% 0% 0% 3-12
src/access/authenticatedOrPublished.ts 0% 0% 0% 0% 3-12
src/access/clinicGallery.ts 85% 66.66% 100% 85% 30, 46, 61
src/access/fieldAccess.ts 100% 100% 100% 100%
src/access/isClinicBasicUser.ts 83.33% 87.5% 100% 100% 10
src/access/isPatient.ts 75% 75% 100% 85.71% 10, 16-20
src/access/isPlatformBasicUser.ts 50% 37.5% 50% 50% 10-17
src/access/scopeFilters.ts 67.39% 61.53% 75% 68.88% 22, 38, 61, 71, 87, 94-100, 109-126
src/access/utils/getClinicAssignment.ts 77.77% 74.07% 100% 79.16% 10, 27, 50-51, 66-67
src/access/utils/getDoctorClinic.ts 58.33% 50% 100% 63.63% 6, 16, 18, 22-23
src/collections/Accreditation.ts 100% 100% 100% 100%
src/collections/Categories.ts 100% 100% 100% 100%
src/collections/Cities.ts 100% 100% 100% 100%
src/collections/ClinicApplications.ts 100% 100% 100% 100%
src/collections/ClinicStaff.ts 81.25% 81.81% 83.33% 84.61% 24, 31, 38
src/collections/Clinics.ts 100% 100% 100% 100%
src/collections/Countries.ts 100% 100% 100% 100%
src/collections/DoctorSpecialties.ts 100% 100% 100% 100%
src/collections/DoctorTreatments.ts 50% 100% 33.33% 50% 75-76
src/collections/Doctors.ts 91.66% 91.66% 100% 100% 151
src/collections/FavoriteClinics.ts 85.71% 78.57% 100% 100% 22, 32
src/collections/MedicalSpecialties.ts 100% 100% 100% 100%
src/collections/PlatformStaff.ts 75% 100% 66.66% 75% 19
src/collections/Reviews.ts 96.42% 78.37% 100% 100% 214
src/collections/Tags.ts 100% 100% 100% 100%
src/collections/Treatments.ts 100% 100% 100% 100%
src/collections/BasicUsers/index.ts 100% 100% 100% 100%
src/collections/BasicUsers/hooks/createSupabaseUser.ts 81.25% 75% 100% 84.61% 7, 23-25
src/collections/BasicUsers/hooks/createUserProfile.ts 76.19% 64.28% 100% 78.94% 23-24, 31-40, 46
src/collections/BasicUsers/hooks/deleteSupabaseUser.ts 61.53% 44.44% 100% 61.53% 20-21, 45-53, 63-83
src/collections/ClinicGalleryEntries/index.ts 80% 66.66% 100% 88.88% 24, 33
src/collections/ClinicGalleryEntries/hooks/beforeChangeClinicGalleryEntry.ts 93.75% 85.71% 100% 93.75% 14, 23
src/collections/ClinicGalleryMedia/index.ts 89.47% 66.66% 100% 94.44% 39, 48
src/collections/ClinicMedia/index.ts 93.75% 63.63% 100% 93.33% 44
src/collections/ClinicTreatments/index.ts 100% 100% 100% 100%
src/collections/ClinicTreatments/hooks/averagePriceUtils.ts 81.81% 86.66% 100% 82.35% 31, 36-37, 57
src/collections/ClinicTreatments/hooks/updateAveragePriceAfterChange.ts 75% 60% 100% 80% 11, 21-26
src/collections/ClinicTreatments/hooks/updateAveragePriceAfterDelete.ts 81.81% 50% 100% 90% 7, 15
src/collections/DoctorMedia/index.ts 85% 72.72% 100% 94.44% 33, 39, 50
src/collections/DoctorMedia/hooks/beforeChangeDoctorMedia.ts 89.28% 81.08% 100% 89.28% 17, 22, 45
src/collections/Pages/index.ts 37.5% 0% 33.33% 37.5% 27, 29-58
src/collections/Pages/hooks/populatePublishedAt.ts 100% 100% 100% 100%
src/collections/Pages/hooks/revalidatePage.ts 47.36% 25% 100% 47.36% 7-23
src/collections/Patients/index.ts 66.66% 50% 100% 85.71% 25, 35, 39
src/collections/Patients/hooks/patientSupabaseCreate.ts 82.35% 80% 100% 81.25% 32-34
src/collections/Patients/hooks/patientSupabaseDelete.ts 64.28% 50% 100% 69.23% 8, 10-11, 16-18
src/collections/PlatformContentMedia/index.ts 90% 100% 83.33% 90% 26
src/collections/PlatformContentMedia/hooks/beforeChangePlatformContentMedia.ts 86.66% 66.66% 100% 86.66% 17-18
src/collections/Posts/index.ts 57.14% 50% 50% 57.14% 32, 34-69, 245
src/collections/Posts/hooks/populateAuthors.ts 76.74% 58.33% 100% 80.48% 7, 42, 71-74, 79, 81-90
src/collections/Posts/hooks/revalidatePost.ts 47.36% 30% 100% 47.36% 7-23
src/collections/UserProfileMedia/index.ts 67.64% 56.19% 100% 78.48% 18-24, 32, 38-45, 50, 51, 74, 75, 83-87, 106, 109, 111, 152, 153, 156, 159, 197, 198, 200
src/collections/common/mediaPathHelpers.ts 71.11% 67.46% 100% 76.38% 28, 38-61, 89, 94, 111, 116, 139, 144, 147
src/collections/common/selectionOptions.ts 100% 100% 100% 100%
src/collections/common/stableIdField.ts 100% 100% 100% 100%
src/hooks/createdBy.ts 100% 84.61% 100% 100%
src/hooks/ensurePatientOnAuth.ts 0% 0% 0% 0% 14-59
src/hooks/immutability.ts 90% 70% 100% 90% 41
src/hooks/ownership.ts 60% 61.29% 100% 61.11% 12-19
src/hooks/publishedAt.ts 84.61% 71.42% 100% 84.61% 35, 37
src/hooks/revalidateRedirects.ts 25% 100% 0% 25% 6-10
src/hooks/calculations/updateAverageRatings.ts 81.57% 68.62% 100% 80.82% 18, 61-62, 89, 97, 129-130, 135-136, 141-152, 162, 189
src/hooks/media/computeStorage.ts 85.71% 62.96% 100% 90.19% 122-127
Generated in workflow #1513 for commit 6ec4a5a by the Vitest Coverage Report Action

@SebastianSchuetze SebastianSchuetze merged commit c3a48cc into main Feb 10, 2026
9 checks passed
@SebastianSchuetze SebastianSchuetze deleted the codex/pagination-consistency-routing branch February 10, 2026 11:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant