Products Pipeline
Product Model
src/data/products.ts defines Product with:
skunameparentSkuproductClassificationt1CogslumberGradefinishcost
UI + Hook Path
src/lib/use-products.tsfetches/api/productswithcache: "no-store".- On fetch failure, hook falls back to
DEFAULT_PRODUCTSand exposes an error. src/app/page.tsxrenders:- source metadata (
s3://bucket/key, last modified) - CSV upload and download controls
- filtered products table
- per-product ruleset assignment controls
- computed T1-T5 price columns based on assigned rulesets
- source metadata (
Products + Ruleset Assignment Bridge
src/app/page.tsx also loads rules data in parallel:
/api/rulesets/api/rule-assignments/api/widgets
For each assigned product:
- base pipeline output is computed with
applyPipeline(product.cost, steps, widgetsById) - tier outputs are computed with
computeTierPrices(basePipelineOutput, tierPolicy) - results are displayed as T1/T2/T3/T4/T5 table columns
Assignments are saved via PUT /api/rule-assignments and currently write version: "latest".
CSV Parsing and Validation
src/lib/products-csv.ts:
- Handles quoted cells and escaped quotes.
- Normalizes header names (case/spacing/underscore tolerant).
- Requires:
sku,product classification,parent sku, and one ofcogs | t1 cogs | cost. - Enforces:
- non-empty required text fields
- numeric fields are finite and non-negative
- unique
sku
productsToCsvemits canonical header:sku,product classification,parent sku,cogs.
S3 Adapter
src/lib/s3-products.ts:
- Reads and writes
products.csv(or configured key) inPRODUCTS_S3_BUCKET. - Uses
DEV_AWS_*credentials and region variables. - Returns source metadata (
exists,lastModified, bucket/key).
API Routes
GET /api/products: returns{ products, source }.POST /api/products/upload: accepts multipart file (file) or raw CSV text.GET /api/products/download: returns CSV from S3; if absent, returns CSV built from defaults.