CROP
ProjectsCROP Frontend

Architecture Overview

Updated: 2026-01-09 (covers commit HEAD)

Architecture Overview

Updated: 2026-01-09 (covers commit HEAD)

Stack

  • Framework: Next.js 16 App Router with cacheComponents, reactCompiler, typedRoutes, and Bun runtime.
  • UI runtime: React 19.2, Tailwind tokens, custom design system components under components/ui.
  • Data source: Search Service v3 (see lib/search-service/*) instead of direct MongoDB access.
  • State tooling: Client components lean on lightweight hooks (useCatalogNavigation, analytics helpers) rather than global stores.

Routing & caching

  • / is the AI Assistant home page (app/page.tsx) with full-screen chat interface using vLLM backend.
  • /parts (app/parts/page.tsx) is the primary catalog view. It calls unstable_noStore() to opt out of caching because filters/search params must stay live.
  • /parts/[id] explicitly exports cache = "no-store" and hydrates items on demand, including fallbacks for slug and part-number navigation.
  • app/(design) contains prototype routes (tokens, typography) that are excluded from navigation but useful for design QA.

Search service integration

  • lib/search-service/client.ts wraps all HTTP calls with a 10s timeout and exposes:
    • searchParts, fetchFilters, fetchAutocomplete, getPartById, getPartBySlug, health helpers.
    • Custom errors (SearchServiceTimeoutError, SearchServiceApiError) consumed in the catalog and API routes.
  • lib/search-service/adapters.ts normalizes upstream payloads into the UnifiedCatalogPart shape and enriches media using manufacturer config + fallback image builders.
  • Manufacturer metadata lives in lib/db/manufacturer-config.ts and is shared between server routes and UI components.

API routes

  • app/api/search-service/autocomplete validates queries with Zod, short-circuits when the upstream client is disabled, and calls enhanceAutocompleteResponse before returning.
  • app/api/search-service/resolve-part performs a tiny search and returns the best matching id/slug for quick navigations.
  • app/api/admin/revalidate guards on ADMIN_REVALIDATE_TOKEN and revalidates any supplied cache tags with optional profile (max | quarterly | navLong). Pair with scripts/revalidate.ts for CLI automation.

Parts catalog rendering

  • app/parts/page.tsx parses query params, normalizes them into SearchParams, and routes the response to PartsCatalogClient.
  • PartsCatalogClient (client component) owns UI state:
    • Uses useCatalogNavigation to keep filters/page/sort in sync with the URL.
    • Applies light client-side post-filters via applyClientPostfilters when equipment fitment rules need to run on the fly.
    • Renders PartsFiltersSidebar, SearchModeToggle, ActiveFiltersBar, SortDropdown, ViewModeSwitch, PartCard, and PaginationBar from the catalog/ui folder.
  • Feature docs for PartsSearchBar and PartsFiltersSidebar live under docs/search-bar.md and docs/sidebar-filters.md respectively.

Environment & configuration

  • Required env vars are validated in lib/env.ts:
    • SEARCH_API_URL (server) and NEXT_PUBLIC_SEARCH_API_URL (client) default to http://localhost:3001 if unspecified.
    • EQUIPMENT_MODE_ENABLED and SEARCH_SERVICE_ENABLED only accept truthy/falsey toggles (true/false, 1/0, etc.).
    • NEXT_PUBLIC_APP_URL is optional but recommended for canonical URLs.
  • Secrets stay in .env.local (ignored). ADMIN_REVALIDATE_TOKEN is read directly via process.env inside app/api/admin/revalidate and by scripts/revalidate.ts.

Cache tags & invalidation

  • cacheLife profiles come from next.config.ts and currently define quarterly (mostly for catalog summaries) and navLong (marketing surfaces). Use cacheTag() inside cached server components (app/home/page.tsx emits nav:home).
  • To invalidate cached entries, run bun run revalidate:tags -- <tag...> with ADMIN_REVALIDATE_TOKEN exported in your shell; the script POSTs to /api/admin/revalidate.

Keep this document updated whenever routing, caching, or API touchpoints change.

On this page