5643d89236
- 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.
65 lines
3.8 KiB
Markdown
65 lines
3.8 KiB
Markdown
# 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.
|
|
|
|
```json
|
|
{"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.
|