Files
Sathira Sri Sathara 5643d89236 feat: implement business pricing service and money utilities
- Added `businessPricing.service.js` to handle business customer pricing logic.
- Introduced `money.js` for money parsing, formatting, and calculations.
- Created `pricing.service.js` to manage variant quoting and promotion application.
- Updated validation schemas in `catalogue.schemas.js` and `inventoryMerchandising.schemas.js` for new pricing and inventory features.
- Implemented cron job for inventory reservation expiry in `inventoryReservationExpiry.cron.js`.
- Created database migrations for catalogue and inventory structures.
- Added unit tests for catalogue localization, validation, and inventory merchandising functionalities.
2026-09-03 19:25:13 +05:30

3.8 KiB

ZUMRI Catalogue API

Catalogue reads use /api/v1; /api remains compatible. Public endpoints require no authentication. Administrative endpoints require Phase 1 permissions. Examples use placeholders.

Localization

Locale priority is ?locale=en|si|ta, X-Locale, authenticated profile preference, Accept-Language, then English. Missing requested content falls back to English and then the first available translation.

Public products

  • GET /api/v1/products
  • GET /api/v1/products/:slug
  • POST /api/v1/products/:productId/reviews — authenticated customer

List query parameters: page, limit (maximum 100), category, brand, search, minPrice, maxPrice, featured, newArrival, locale, and sort=newest|price_asc|price_desc|name|featured. Unsupported sorts return 400. Stock and wholesale availability are intentionally absent.

{"data":[{"id":"<product-id>","slug":"<slug>","name":"<localized-name>","primaryImage":{"url":"<short-lived-url>"},"minPrice":"1000.00","maxPrice":"1200.00","currency":"LKR","featured":false,"newArrival":true}]}

Detail returns localized content/SEO, brand, categories, active variants, options, descriptive attributes, signed gallery media, a structured size guide, rating summary, and approved review preview. DRAFT, INACTIVE, ARCHIVED, and HIDDEN products always return 404 publicly.

Review body is {"rating":5,"title":"<title>","body":"<review>"}. status, verifiedPurchase, moderator, and user IDs are rejected. One review per user/product is enforced. Purchase verification defaults false until order integration exists.

Categories, brands, and collections

  • GET /api/v1/categories — tree; add flat=true for a flat list
  • GET /api/v1/categories/:slug
  • GET /api/v1/brands
  • GET /api/v1/brands/:slug
  • GET /api/v1/collections
  • GET /api/v1/collections/:slug

Only active categories/brands and currently scheduled active collections are returned.

Administrative products

  • GET /api/v1/admin/products — catalogue.products.read
  • POST /api/v1/admin/products — catalogue.products.create
  • GET /api/v1/admin/products/:id — read permission
  • PATCH /api/v1/admin/products/:id — catalogue.products.update
  • DELETE /api/v1/admin/products/:id — catalogue.products.delete; archives instead of deleting
  • POST /api/v1/admin/products/:productId/variants
  • PATCH /api/v1/admin/products/:productId/variants/:variantId
  • POST /api/v1/admin/products/:productId/options
  • POST /api/v1/admin/products/:productId/media
  • POST /api/v1/admin/products/:productId/relations

Product creation atomically persists translations, category joins, variants, and owned Phase 2 uploads. Prices are decimal strings. Publishing requires English content, a brand, an active variant, and primary media. Published slugs are immutable.

Administrative content

  • POST|PATCH /api/v1/admin/brands[/:id] — catalogue.brands.manage
  • POST|PATCH /api/v1/admin/categories[/:id] — catalogue.categories.manage
  • POST /api/v1/admin/collections — catalogue.collections.manage
  • POST /api/v1/admin/size-guides — catalogue.size-guides.manage
  • GET /api/v1/admin/reviews — catalogue.reviews.read
  • PATCH /api/v1/admin/reviews/:id/status — catalogue.reviews.moderate

Categories cannot parent themselves or form cycles. Referenced categories/brands have no hard-delete API. Collections use deterministic join ordering and publish windows. Size guides accept structured columns/rows, never HTML.

Media and prices

Media must be an AVAILABLE upload owned by the acting administrator. Linking transfers metadata ownership to the catalogue Product. Public responses contain short-lived signed URLs but never object keys, bucket names, or credentials. basePrice and optional compareAtPrice are display catalogue prices only; promotions and authoritative shopping pricing are deferred.