Product Catalog & Browsing
Relevant source files
The following files were used as context for generating this wiki page:
The Product Catalog & Browsing system provides the core interface for users to discover, view, and filter products within the application. It acts as the central repository for product metadata, brand relationships, and technical specifications. The system is designed as a Phoenix modular monolith on the backend, serving data via GraphQL to a React-based frontend.
The scope of this system includes managing product taxonomies (categories and use-cases), handling technical specification claims, and presenting a searchable browse interface. It integrates closely with the Pricing and Compare modules to provide a comprehensive product overview.
Sources: README.md:12-21, ARCHITECTURE.md:12-16, 2026-03-03-product-compare-backend-mvp-plan.md:10-15
System Architecture & Data Flow
The catalog follows a decoupled architecture where the frontend utilizes React Router loaders to pre-fetch GraphQL data before rendering. The data flow begins with a user request to the /products route, which triggers a standardized loading sequence to fetch product summaries and brand details.
Catalog Data Request Flow
The following diagram illustrates the sequence of operations when a user accesses the product catalog:
The frontend uses a browseLoader function to initiate loadBrowseProducts, which executes a GraphQL query against the backend. The results are parsed into a typed BrowseProduct interface before being passed to the UI components.
Sources: assets/src/routes/catalog/api.ts:46-59, assets/src/routes/catalog/browse.tsx:4-8
Backend Contexts & Data Modeling
The catalog is supported by several distinct backend boundaries that manage specific aspects of product data. These boundaries ensure that product definitions remain separate from pricing or social interactions.
| Context | Responsibility | Key Entities |
|---|---|---|
Catalog | Core product anchors and brand management. | Product, Brand, ExternalProduct, Source |
Taxonomy | Category trees and use-case tagging. | Taxon, Taxonomy, TaxonClosure |
Specs | Technical attributes and normalized values. | Attribute, Claim, Unit, Dimension |
Sources: README.md:14-17, 2026-03-03-product-compare-backend-mvp-plan.md:101-118
Taxonomy & Categorization
Products are organized using a closure table-based taxonomy system. This allows for deep hierarchical structures (e.g., Electronics -> Displays -> TV) and fast recursive lookups for filtering. Products are assigned a primary_type_taxon_id to define their main category and can be tagged with multiple "use-case" taxons.
Sources: 2026-03-03-product-compare-backend-mvp-plan.md:86-90, 2026-03-03-product-compare-backend-mvp-plan.md:129-138
Frontend Implementation
The frontend implements the catalog through a "Browse" route and a "Detail" route. The browse interface focuses on a list-based view with support for pagination and basic brand summaries.
Browse API Data Structures
The frontend utilizes specific TypeScript interfaces to handle the GraphQL responses for the catalog:
// assets/src/routes/catalog/api.ts:7-12
export interface BrowseProduct {
id: string;
name: string;
slug: string;
brandName: string | null;
}
export interface BrowseProductsLoaderData {
status: "ready" | "error";
products: BrowseProduct[];
}
Sources: assets/src/routes/catalog/api.ts:7-12, assets/src/routes/catalog/api.ts:38-41
Product Detail & Offers
When a user selects a specific product, the system transitions to the ProductDetailRoute. This view aggregates core product information with active merchant offers. The productDetailLoader performs two sequential data fetches: one for the product's technical details and description, and another for current merchant listings (offers).
Sources: assets/src/routes/products/api.ts:117-140, assets/src/routes/products/api.ts:25-33
The system is designed to be resilient; if merchant offers fail to load, the core product details are still displayed to the user with an "Offers unavailable" message.
Sources: assets/src/routes/products/api.ts:133-150
GraphQL Interface
The catalog is queried using standard Relay-style GraphQL patterns, including global IDs and edge/node connections for lists.
Primary Queries
- BrowseProducts: Fetches a paginated list of products for the main catalog.
- Parameters:
first(Int) - Number of items to retrieve. - Fields:
id,name,slug,brand { name }.
- Parameters:
- ProductDetail: Retrieves comprehensive information for a single product via its slug.
- Parameters:
slug(String!) - Unique product identifier. - Fields:
id,name,description,brand { name }.
- Parameters:
Sources: assets/src/routes/catalog/api.ts:14-29, assets/src/routes/products/api.ts:37-50
Filtering & Search
Filtering logic is implemented on the backend through a specialized Catalog.Filtering module. It supports:
- Type Filtering: Using the
taxon_closureto find products in a category and all its sub-categories. - Range Filtering: Joins against
product_attribute_currentto filter by numeric specifications (e.g., Refresh Rate). - Boolean/Enum Filtering: Filtering by discrete product specs (e.g., HDR support, Panel Tech).
Sources: 2026-03-03-product-compare-backend-mvp-plan.md:162-168, 2026-03-03-product-compare-backend-mvp-plan.md:120-128
Conclusion
The Product Catalog & Browsing system serves as the foundational data layer for the Product Compare application. By utilizing a strict modular boundary for backend logic and a typed GraphQL interface for the frontend, the system maintains high data integrity while providing the flexibility needed for complex multi-product comparisons and detailed technical specifications.