# 2. Product Sorting with JS Aggregation

Date: 2026-08-16

## Status

Accepted

## Context

The storefront needs advanced sorting options (Price Asc/Desc, Discount Asc/Desc, Best Seller). `Product` represents a catalog item, but actual prices and discounts live on its multiple `Variant` children. Prisma ORM does not support ordering a parent list by an aggregate (like minimum or maximum) of its relational children natively without raw SQL or dedicated shadow fields.

## Decision

1.  **Best Seller**: Added a `salesCount` column directly to the `Product` model to track units sold dynamically, making "Best Seller" sorting natively fast via Prisma's `orderBy`.
2.  **Price & Discount Sorting**: Implemented an in-memory aggregation fallback for these specific sorts. We fetch the matching (filtered) products, calculate the lowest price or highest discount for each in JS, sort the array in memory, and then manually paginate.
3.  **Sold Out**: Treated as a filter (`hideSoldOut`), not a sort. We hide `Product`s where all `Variant`s have `stockQuantity <= 0`.

## Consequences

*   **Pro**: Fast time-to-market. Avoids complex raw SQL queries that make maintenance hard, staying true to Prisma's intended usage where possible.
*   **Con**: In-memory sorting for price and discount fetches all matches from the DB before paginating. For a very large catalog (tens of thousands of items matching a single category filter), this will cause memory and performance issues. This is an accepted technical debt (a deliberate Ponytail shortcut) to be revisited if catalog size scales drastically.