Codebase Health Scorecard

vercel/commerce

Generated by Inkwell Forge — automated codebase documentation analysis. Based on analysis of 5 screens. Subject matter expert review is recommended before distribution.

May 5, 2026

Commerce — Codebase Health Scorecard

Document Title: Codebase Health Scorecard Date: May 2026 Assessment Basis: Documentation Review — 5 screens


Dimension Scores

# Dimension Score Grade Status Key Finding
1 Code Maintainability 4.0 B 🟢 Consistent RSC-first compositor pattern with clean separation of concerns; one recurring double-fetch anti-pattern across two screens.
2 Reliability & Error Handling 3.0 C 🟡 notFound() guards are consistently applied, but no error boundaries wrap Suspense blocks and a null-dereference bug exists on Product Detail.
3 Security Posture 4.0 B 🟢 Server Component isolation keeps all credentials server-side; one unescaped JSON.stringify in JSON-LD injection warrants hardening.
4 Performance Efficiency 4.0 B 🟢 Excellent RSC architecture with PPR, streaming Suspense, and AVIF/WebP images; no pagination on Search or Collection screens is a latent scalability gap.
5 Test Coverage & Quality 1.0 F (Provisional) 🟡 Provisional Provisional — No co-located tests found in any of the 5 documented screens; no test runner beyond Prettier is present in package.json.
6 Documentation Quality 4.0 B 🟢 All 5 screens carry thorough per-section documentation including known issues, glossaries, and recommended testing strategies.
7 Architecture & Scalability 4.0 B 🟢 Next.js 15 App Router with PPR, useCache, and Shopify abstraction layer demonstrates a well-structured, scalable foundation.
8 Dependency Health 4.0 B 🟢 Lean, modern dependency set on React 19 and Next.js 15 canary; canary channel introduces upgrade risk that should be monitored.
9 Accessibility Compliance 2.0 D 🔴 Missing <h1> on Search Detail, no <time> elements, Suspense fallbacks lack ARIA busy states, and <span> used where <strong> is semantically required.
10 Operational Readiness 2.0 D (Provisional) 🟡 Provisional Provisional — No observability SDK identifiable from the provided project context; Toaster (Sonner) provides user-facing feedback but no error-tracking instrumentation is visible.

1. Code Maintainability

Score: 4.0 / B. The codebase applies a consistent compositor pattern across all five screens — page components act as pure layout orchestrators with zero business logic, delegating data fetching and interactivity to named child components. TypeScript strict mode is enabled (strict: true, noUncheckedIndexedAccess: true in tsconfig.json), which enforces type safety across the codebase. The Shopify integration is cleanly abstracted behind lib/shopify, preventing API coupling from leaking into page components. The one recurring maintainability concern is the double-invocation of getProduct / getPage in both generateMetadata and the page component — documented in §17 of two screens — which should be resolved with React.cache(). Prettier is enforced via CI ("test": "pnpm prettier:check"), ensuring consistent formatting.

Evidence: tsconfig.json strict flags; §4 and §17 of Item Detail and Product Detail screens; package.json test script.


2. Reliability & Error Handling

Score: 3.0 / C. All five screens consistently call notFound() when Shopify returns a falsy value, providing a reliable 404 boundary for missing resources. However, no ErrorBoundary components wrap the Suspense blocks on Product Detail, meaning a rendering failure in Gallery or ProductDescription propagates to the root Next.js error boundary rather than being contained. A documented null-dereference bug exists: product.featuredImage.url in the JSON-LD block on Product Detail has no null guard, unlike the equivalent code in generateMetadata on the same screen. The Item Detail screen also conflates "page not found" and "API error" into a single notFound() call, making outage diagnosis harder. No error differentiation or structured error logging is present at the page-component level across any screen.

Evidence: §10 and §17 of Product Detail; §10 of Item Detail; §10 of Search and Search Detail.


3. Security Posture

Score: 4.0 / B. The Server Component architecture is the primary security strength: all Shopify API credentials remain server-side and are never included in the client bundle across all five screens. No screen accepts user-supplied data that is rendered without React's automatic JSX escaping — the one exception is the JSON-LD <script> block on Product Detail, which uses dangerouslySetInnerHTML with JSON.stringify. As documented in §14 of that screen, JSON.stringify does not escape <, >, or &, creating a theoretical script-injection vector if a product title contains </script>. The params.page and params.collection URL segments are passed directly to Shopify service functions without component-level sanitization, though parameterized GraphQL queries at the lib/shopify layer mitigate injection risk. CSP headers and rate limiting are not visible in the provided project context.

Evidence: §14 of all screens; §14 of Product Detail (JSON-LD); next.config.ts (no security headers configured); ROOT LAYOUT (no middleware visible).


4. Performance Efficiency

Score: 4.0 / B. The project configuration (next.config.ts) enables three experimental Next.js 15 performance features: Partial Pre-Rendering (ppr: true), inline CSS (inlineCss: true), and the new useCache API — all of which reduce TTFB and client bundle size. AVIF and WebP image formats are configured, and GridTileImage uses Next.js fill with responsive sizes. Suspense streaming boundaries on Product Detail allow the page shell to reach the browser before data-heavy components resolve. The primary performance gap is the absence of pagination on both the Search and Search Detail screens: all matching products are fetched in a single Shopify API call, which will degrade for large catalogs. The duplicate getProduct/getPage API calls (one per generateMetadata, one per page render) are a secondary concern that React.cache() would resolve.

Evidence: next.config.ts; §12 of Product Detail (Suspense, prefetch); §12 and §17 of Search and Search Detail (no pagination); §17 of Item Detail and Product Detail (double fetch).


5. Test Coverage & Quality

Score: 1.0 / F (Provisional). No co-located test files were found in any of the five documented screens. The package.json "test" script runs only prettier:check — there is no Jest, Vitest, Playwright, or Cypress configuration present in the project manifest. This means the project has no automated functional test coverage from the evidence available. Each screen's §16 provides a detailed recommended testing strategy (unit, integration, and E2E), indicating team awareness of the gap. All five screens document this absence explicitly.

Provisional score — grade-swing disclosure: This score is based on observable evidence in the 5 documented screens and the project manifest. If a test suite (e.g., a __tests__/, e2e/, or cypress/ directory) exists outside the per-screen files and is not reflected in package.json, the dimension would be rated D. Resolve before treating this dimension's grade as final.

[Not documented — WHO: Engineering lead; WHAT: Does a test directory (__tests__/, e2e/, cypress/, vitest.config.ts) exist in the repository outside the documented screen files?; WHERE: Update Test Coverage & Quality score and provisional disclosure above if yes.]

Evidence: §16 of all 5 screens; package.json scripts block (no test runner present).


6. Documentation Quality

Score: 4.0 / B. All five screens are documented to a high standard across 18 consistent sections covering UI layout, data flow, API calls, business rules, security, accessibility, testing strategy, and known issues. Known issues and technical debt are explicitly called out in §17 of every screen, demonstrating active team awareness rather than silent accumulation. The glossary sections are thorough and domain-appropriate. The primary gap is that the documentation covers page-level components only — child components (Gallery, ProductDescription, ThreeItemGrid, Carousel, lib/shopify) are referenced but not documented, meaning a developer must read multiple undocumented files to understand full screen behavior. The hardcoded SEO description placeholder noted in §17 of the Home screen is a minor content quality issue.

Evidence: §17 and §18 of all screens; §13 of all screens (undocumented child components); §17 of Home (placeholder metadata).


7. Architecture & Scalability

Score: 4.0 / B. The application uses Next.js 15 App Router with React Server Components throughout, which is the current industry-leading pattern for e-commerce storefronts. The Shopify integration is fully abstracted behind lib/shopify, enabling the API client to be swapped without touching page components. PPR (ppr: true) in next.config.ts enables static shell delivery with dynamic data streaming — a strong scalability pattern for high-traffic storefronts. The useCache experimental flag signals adoption of Next.js's next-generation caching model. The primary architectural gap is the absence of pagination on collection and search result pages, which creates a hard scalability ceiling for large catalogs. The lack of error boundaries at the component level is also an architectural concern for fault isolation.

Evidence: next.config.ts (PPR, useCache); ROOT LAYOUT (CartProvider, streaming cart); §4 of all screens (RSC pattern); §17 of Search and Search Detail (no pagination).


8. Dependency Health

Score: 4.0 / B. The dependency set is intentionally lean: 8 runtime dependencies covering the framework (Next.js, React), UI utilities (Headless UI, Heroicons, clsx), fonts (Geist), and toast notifications (Sonner). There are no heavy client-side data-fetching libraries, no redundant utility packages, and no deprecated dependencies. TypeScript 5.8, Tailwind CSS 4, and React 19 are all current major versions. The one notable risk is next: "15.6.0-canary.60" — a canary (pre-release) build of Next.js. Canary builds can introduce breaking changes between patch versions and are not recommended for production without a pinned upgrade strategy. The experimental flags (ppr, inlineCss, useCache) are tied to this canary channel and may change API shape before stable release.

Evidence: package.json dependencies and devDependencies; next.config.ts experimental flags.


9. Accessibility Compliance

Score: 2.0 / D. Multiple accessibility gaps are documented across the five screens. The most significant is the absence of an <h1> heading on the Search Detail screen (§17), leaving users without a page-level landmark. The Item Detail screen uses a plain <p> tag for the last-updated date rather than a semantic <time datetime="..."> element (§15, §17). The Search screen uses <span> for the bolded search term where <strong> would convey semantic emphasis to assistive technologies (§15). The Product Detail screen's Suspense fallbacks carry no aria-busy or role="status" attributes, providing no loading feedback to screen readers (§15). The ROOT LAYOUT correctly sets lang="en" on the <html> element, which is a positive baseline. Carousel accessibility (keyboard navigation, aria-live) is delegated to child components and not verifiable from the documented screens.

Evidence: §15 and §17 of Search Detail (missing h1); §15 and §17 of Item Detail (no <time>); §15 of Search (<span> vs <strong>); §15 of Product Detail (Suspense ARIA); ROOT LAYOUT (lang="en").


10. Operational Readiness

Score: 2.0 / D (Provisional). No observability SDK (error tracking, APM, or analytics) is identifiable from the project manifest (package.json) or ROOT LAYOUT. The ROOT LAYOUT mounts Sonner's <Toaster> for user-facing toast notifications and a <WelcomeToast> component, but these are UX features, not operational instrumentation. All five screens' §10 sections explicitly state that no error tracking service calls (Sentry, Datadog, etc.) are present at the page-component level. The "test" script in package.json runs only Prettier, confirming no CI test gate. Deployment target (Vercel) is referenced in screen documentation and implied by the Next.js configuration, which would provide platform-level logging, but no application-level instrumentation is visible.

Provisional score — grade-swing disclosure: This score is based on observable evidence in the 5 documented screens and the project manifest. If infrastructure-level observability (e.g., Sentry, Datadog, or a Next.js instrumentation file at instrumentation.ts) is configured outside the per-screen scope, the dimension would be rated C. Resolve before treating this dimension's grade as final.

[Not documented — WHO: DevOps / Platform engineer; WHAT: Is there an instrumentation.ts file, a Sentry DSN, or equivalent error-tracking configuration in the repository outside the documented screen files?; WHERE: Update Operational Readiness score and provisional disclosure above if yes.]

Evidence: package.json (no observability SDK); ROOT LAYOUT (Sonner only, no error SDK); §10 of all 5 screens (explicit "no error tracking" statements).


Arithmetic: Sum = 4.0 + 3.0 + 4.0 + 4.0 + 1.0 + 4.0 + 4.0 + 4.0 + 2.0 + 2.0 = 32.0. Scored 10 of 10 dimensions. Mean = 32.0 / 10 = 3.2. Grade = C (3.2 falls in the 3.0–3.4 range → C).


Overall Health Summary

╔══════════════════════════════════════════╗
║  OVERALL CODEBASE HEALTH: C             ║
║  Score: 3.2 / 5.0                        ║
║  Assessment Date: May 2026               ║
║  Screens Assessed: 5                     ║
║  Assessment Basis: Documentation Review  ║
╚══════════════════════════════════════════╝

Generated by Inkwell Forge — automated codebase documentation analysis. Subject matter expert review is recommended before distribution.

[Diagram: radar/spider chart showing scores across all 10 health dimensions — Code Maintainability 4.0, Reliability 3.0, Security 4.0, Performance 4.0, Test Coverage 1.0, Documentation 4.0, Architecture 4.0, Dependency Health 4.0, Accessibility 2.0, Operational Readiness 2.0]

Executive Summary: The Commerce storefront demonstrates a technically strong foundation — consistent React Server Component architecture, a lean modern dependency set, and thorough per-screen documentation place it solidly above average across most quality dimensions. The critical gaps pulling the overall score to C are the complete absence of automated testing (no test runner in package.json), weak accessibility compliance across multiple screens, and no identifiable operational observability instrumentation. Immediate investment in a test suite and accessibility remediation would have the highest impact on production readiness; the architecture and security posture are already well-positioned for scale.


Screen Health Overview

[Diagram: heat map of screen health scores across 5 screens and 4 dimensions]

Screen Route Overall Maintainability Reliability Security Performance Notes
Home / 🟢 🟢 🟡 🟢 🟢 Cleanest screen; error handling fully delegated to child components with no fallback visibility.
Item Detail /[page] 🟡 🟢 🟡 🟢 🟡 Double getPage fetch and locale-dependent date rendering are documented debt items.
Product Detail /product/[handle] 🟡 🟢 🔴 🟡 🟢 Null-dereference bug on featuredImage.url in JSON-LD and unescaped JSON.stringify are the highest-risk issues in the assessed scope.
Search /search 🟡 🟢 🟡 🟢 🟡 No pagination and unsafe searchParams type cast are the primary concerns.
Search Detail /search/[collection] 🔴 🟡 🟡 🟢 🟡 Missing <h1>, no pagination, and potential searchParams null-dereference are compounding issues.

Top Risks

# Risk Dimension Impact Urgency Recommendation
1 No automated test suite — package.json test script runs only Prettier; no Jest, Vitest, or Playwright configured Test Coverage High Immediate Add Vitest for unit/integration tests and Playwright for E2E; prioritize Product Detail and Search screens first.
2 Null-dereference on product.featuredImage.url in JSON-LD block (Product Detail) — crashes page render for products without a featured image Reliability High Immediate Add null guard: product.featuredImage?.url consistent with the guard already present in generateMetadata on the same screen.
3 No observability instrumentation identifiable in project manifest — errors in production are invisible without platform-level logging Operational Readiness Medium Short-term Add an error-tracking SDK (e.g., Sentry) and a Next.js instrumentation.ts file; confirm with DevOps whether platform-level logging covers the gap.
4 Multiple accessibility gaps across screens: missing <h1> on Search Detail, no <time> elements, <span> used instead of <strong>, Suspense fallbacks without ARIA states Accessibility Medium Short-term Audit all five screens against WCAG 2.1 AA; fix Search Detail <h1>, Item Detail <time datetime>, and Search <strong> as quick wins.
5 No pagination on Search (/search) and Search Detail (/search/[collection]) — all products fetched in a single Shopify API call Performance / Architecture Medium Medium-term Implement cursor-based pagination or infinite scroll using Shopify's after cursor; add a PRODUCTS_PER_PAGE constant to lib/constants.

Top Strengths

# Strength Dimension Evidence Recommendation
1 Consistent React Server Component architecture across all 5 screens — zero client-side JS at the page level Architecture All screens §4: no useState, no "use client" in page components Maintain the pattern; enforce via ESLint rule prohibiting "use client" in app/ page files.
2 Clean Shopify abstraction layer — all API calls mediated through lib/shopify, no direct Storefront API calls in page components Code Maintainability §13 of all screens; no third-party SDKs imported directly in page files Document lib/shopify to the same standard as the screen files; add integration tests for the service layer.
3 TypeScript strict mode with noUncheckedIndexedAccess — highest-safety compiler configuration Code Maintainability tsconfig.json: strict: true, noUncheckedIndexedAccess: true Ensure skipLibCheck: true does not mask type errors in lib/shopify; consider enabling exactOptionalPropertyTypes.
4 Next.js 15 performance features enabled: PPR, inline CSS, useCache, AVIF/WebP images Performance next.config.ts: ppr: true, inlineCss: true, useCache: true, formats: ["image/avif", "image/webp"] Monitor canary-to-stable migration path; pin the Next.js version and review experimental API changes before upgrading.
5 Thorough per-screen documentation with explicit known-issues tracking in §17 Documentation Quality §17 of all 5 screens documents debt items, not just features Extend documentation to cover lib/shopify, child components (Gallery, ProductDescription, ThreeItemGrid), and the cart context.

Priority Action Dimension Effort Expected Impact
1 Add Vitest (unit/integration) and Playwright (E2E) to package.json; update "test" script to run both; implement tests for Product Detail and Search screens first Test Coverage High Establishes a safety net for all future changes; unblocks CI quality gates
2 Fix null-dereference: add product.featuredImage?.url guard in productJsonLd on Product Detail (app/product/[handle]/page.tsx) Reliability Low Prevents page crash for products without a featured image
3 Escape JSON-LD output: replace JSON.stringify(productJsonLd) with an HTML-safe serializer that escapes <, >, and & characters Security Low Closes theoretical XSS vector in structured data injection
4 Resolve double-fetch pattern on Item Detail and Product Detail using React.cache() to wrap getPage and getProduct calls Code Maintainability / Performance Low Eliminates redundant Shopify API calls per request; improves render latency
5 Fix accessibility quick wins: add <h1> to Search Detail, replace <span> with <strong> on Search, add <time datetime> to Item Detail, add aria-busy to Product Detail Suspense fallback Accessibility Low Addresses WCAG 2.1 AA violations; improves screen reader experience
6 Add error-tracking instrumentation (instrumentation.ts + SDK) and co-locate error.tsx files with Search and Search Detail routes Operational Readiness Medium Provides production visibility into API failures and rendering errors
7 Implement cursor-based pagination on Search and Search Detail screens using Shopify's after cursor parameter Performance / Architecture High Removes scalability ceiling for large product catalogs

Methodology

Score Grade Status
4.5–5.0 A 🟢 Excellent
3.5–4.4 B 🟢 Good
2.5–3.4 C 🟡 Adequate
1.5–2.4 D 🔴 Below Standard
1.0–1.4 F 🔴 Critical

Glossary

Term Definition
RSC (React Server Component) A React component that runs exclusively on the server; ships no JavaScript to the client. All 5 assessed screens are RSCs.
PPR (Partial Pre-Rendering) A Next.js 15 feature that statically pre-renders a page shell and streams dynamic content into it, combining static and dynamic rendering.
App Router The Next.js 13+ routing system based on the app/ directory, where page.tsx files define route segments.
Compositor component A component whose sole responsibility is to arrange child components with no logic, state, or data fetching of its own.
notFound() A Next.js function that triggers the nearest not-found.tsx boundary, returning a 404 HTTP response.
generateMetadata A Next.js App Router export that generates <head> metadata (title, description, Open Graph) for a route.
JSON-LD JavaScript Object Notation for Linked Data — structured data embedded in a <script> tag for search engine rich results.
Storefront API Shopify's public-facing GraphQL API for building custom storefronts; used for all product and collection data in this application.
HIDDEN_PRODUCT_TAG A Shopify product tag that marks a product as non-indexable by search engines while keeping it URL-accessible.
Canary build A pre-release software version (here: next@15.6.0-canary.60) that may contain breaking changes before stable release.
WCAG 2.1 AA Web Content Accessibility Guidelines version 2.1, Level AA — the industry-standard accessibility compliance target for commercial web applications.
React.cache() A React API that memoizes the result of a function call within a single server render pass, preventing duplicate data fetches.
DORA metrics DevOps Research and Assessment metrics: Deployment Frequency, Lead Time for Changes, Change Failure Rate, and Time to Restore Service — used as a framework for delivery performance.
ISO/IEC 25010:2023 International standard defining software product quality characteristics, used as the quality model for this scorecard's 10 dimensions.
Provisional score A dimension score based on observable evidence where a [Not documented] marker identifies external information that could change the letter grade.