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.
43 lines
2.3 KiB
Markdown
43 lines
2.3 KiB
Markdown
# Inventory and Merchandising API
|
|
|
|
All routes use the `/api/v1` prefix. Admin routes require authentication and the named Phase 5 permission.
|
|
|
|
## Inventory and warehouses
|
|
|
|
- `GET /admin/inventory` (`inventory.read`)
|
|
- `GET /admin/inventory/:variantId` (`inventory.read`)
|
|
- `GET /admin/inventory/ledger` (`inventory.read`)
|
|
- `GET /admin/inventory/low-stock` (`inventory.read`)
|
|
- `POST /admin/inventory/adjustments` (`inventory.adjust`); send `Idempotency-Key`
|
|
- `POST /admin/inventory/transfers` (`inventory.transfer`); send `Idempotency-Key`
|
|
- `GET /admin/warehouses` (`inventory.read`)
|
|
- `POST /admin/warehouses`, `PATCH /admin/warehouses/:id` (`inventory.warehouses.manage`)
|
|
- `GET /availability/:variantId` returns only `IN_STOCK`, `LOW_STOCK`, or `OUT_OF_STOCK` and `availableForSale`; it never exposes warehouse quantities.
|
|
|
|
Inventory mutations are internal service operations: `reserveStock`, `releaseReservation`, and `consumeReservation`. Reservations default to `INVENTORY_RESERVATION_TTL_MINUTES=15`. The minute reconciliation job expires bounded batches of 100; the database remains authoritative.
|
|
|
|
## Business pricing
|
|
|
|
- `GET /admin/business-pricing` (`pricing.business.read`)
|
|
- `POST /admin/business-pricing` (`pricing.business.manage`)
|
|
|
|
Rules support exactly one tier or customer audience, effective dates, MOQ, and non-overlapping volume ranges. Precedence is customer override, business tier, then retail. Money is stored as DECIMAL and calculated using integer-scaled helpers.
|
|
|
|
## Promotions and coupons
|
|
|
|
- `GET|POST /admin/promotions` (`promotions.read` / `promotions.manage`)
|
|
- `GET|POST /admin/coupons` (`promotions.read` / `promotions.manage`)
|
|
|
|
The quote boundary resolves retail/business base price, then the highest-priority eligible automatic promotion, then a coupon only when stacking permits. Discounts floor at zero. Coupon codes are canonical uppercase. Usage redemption is intentionally deferred until orders exist.
|
|
|
|
## Banners
|
|
|
|
- `GET /banners?placement=&locale=` returns active, scheduled, audience-eligible localized banners.
|
|
- `GET|POST /admin/banners` requires `merchandising.banners.manage`.
|
|
|
|
Banner media reuses Upload records and only returns safe upload identifiers, never bucket/object keys.
|
|
|
|
## Not implemented
|
|
|
|
Cart, checkout, orders, coupon redemption, shipping, tax, payment, and delivery remain outside Phase 5.
|