PolyWood Price Builder

API Routes

All routes are in src/app/api/*, run in Node (runtime = "nodejs"), and disable caching (Cache-Control: no-store).

Products

  • GET /api/products
    • Loads products from S3 CSV via loadProductsFromS3.
    • Returns { products, source }.
    • source includes { bucket, key, exists, lastModified }.
  • POST /api/products/upload
    • Accepts multipart CSV file (file) or raw CSV request body.
    • Parses and normalizes CSV before writing to S3.
    • Returns { products, source } on success.
  • GET /api/products/download
    • Returns text/csv as downloadable response.
    • Falls back to generated CSV from defaults if source object is missing.

Rulesets

  • GET /api/rulesets
    • No query params: list all rulesets with latest snapshot.
    • Query id (+ optional version, default latest): fetch specific ruleset/version.
    • Single ruleset response shape is { meta, version }.
  • POST /api/rulesets
    • Expects body { id, steps, tierPolicy }.
    • id is validated as [a-z0-9-]{2,64}.
    • steps are strictly validated against the live widget catalog.
    • tierPolicy is strictly validated.
    • Uses saveRulesetInS3, which auto-creates v0001 for new IDs or publishes the next version for existing IDs.
    • Returns { meta, version }.
  • DELETE /api/rulesets?id=<rulesetId>
    • Deletes every S3 object under <prefix>/<rulesetId>/.
    • Returns { deleted: true } on success.

Assignments

  • GET /api/rule-assignments
    • Loads product-to-ruleset mapping from <prefix>/assignments/products.json.
    • Returns { assignments, source } where source includes bucket/key/exists/lastModified metadata.
    • If the S3 object is absent, returns assignments: {} with source.exists: false.
  • PUT /api/rule-assignments
    • Expects body { assignments } where each SKU entry is { rulesetId, version }.
    • Validates assignment payload shape (rulesetId must match [a-z0-9-]{2,64}, version required/non-empty).
    • Rejects unknown rulesetId values by checking current rulesets list.
    • Persists mapping JSON and returns { assignments, source }.

Widgets

  • GET /api/widgets
    • Loads widget catalog from S3 (with default seeding behavior).

Removed Route

  • POST /api/rulesets/publish has been removed. Create and publish now share POST /api/rulesets.