Inventory & suppliers
Multi-Source Inventory (MSI)
Indicative price, not an offer: $599–1,299/year
Generated from docs/plan/paid/multi-source-inventory/PLAN.md in the AstroBaaS repository. Nothing described below is implemented — it is the written plan for it.
A paid inventory module for multi-location merchants (warehouses, retail stores, fulfillment centers) that splits inventory into named sources, tracks qty per source, and recommends fulfillment paths. Replaces single-qty inventory with a matrix: product × source = qty. Essential for omnichannel merchants who ship from multiple locations and need intelligent routing.
The problem
I have 3 warehouses and a shop floor. My one-qty-per-product system sees total stock but cannot allocate fulfillment. I want to route orders intelligently: ship from closest warehouse, leave store floor for walk-in customers, or sell from full warehouse when store is low. Today, I manually update qty when stock moves between locations.
What it does
- Source (warehouse) entity: name, address, priority, fulfillment_algorithm (closest, fullest, priority-list)
- Per-source qty tracking: inventory splits into (product_id, source_id) → available_qty, reserved_qty, on_hand_qty
- Stock total aggregation: GET /api/products/:id/qty returns sum of all sources (for legacy API compatibility)
- Fulfillment suggestion endpoint: GET /api/fulfillment-suggestion/:orderId ranks sources by priority, returns [{ source_id, suggested_qty, lead_time_days }]
- Source priority config: per-product rules or global rule; e.g., ‘always ship from Warehouse A if qty > 10’
- Source-selection override: staff can manually assign fulfillment source before shipping
- Stock transfer workflow: move qty from source A to source B, logged as transfer event
- Reserved qty tracking: prevent overbooking by deducting reserved_qty from available_qty in fulfillment suggestion
- Source availability view: admin dashboard showing qty per source, visual matrix (products × warehouses)
- Rebalance report: identify low-stock sources and over-stocked sources, suggest transfers
What it deliberately does NOT do
Each boundary carries its reason. A boundary without a reason gets crossed by the next person who reads this.
- Shipping integration or label generation — fulfillment suggestion stops at source assignment; shipping API calls are separate
- Transfer orders or inter-warehouse movements — stock transfers are logged but not a full workflow (no approval, no tracking in-transit)
- Advanced routing algorithms (ML, distance optimization) — uses merchant-defined priority lists only; no AI routing
- Fulfillment cost optimization — suggests source but does not calculate shipping cost or profit impact; merchants decide based on speed/cost
Data model
New tables: sources (id, shop_id, name, address, priority_rank, fulfillment_algorithm enum(closest, fullest, priority_list)), stocks (id, product_id, source_id, available_qty, reserved_qty, on_hand_qty, last_counted_at), stock_transfers (id, from_source_id, to_source_id, product_id, qty_transferred, transfer_date, approved_by, status enum(pending, completed, cancelled)), source_fulfillment_rules (id, product_id, source_id, min_qty_threshold, rule_priority). Inventory table remains for legacy API; synced from stocks table.
API
- GET /api/sources
- POST /api/sources
- PATCH /api/sources/:id
- GET /api/stocks/:productId
- GET /api/stocks/:productId/:sourceId
- PATCH /api/stocks/:productId/:sourceId
- POST /api/fulfillment-suggestion/:orderId
- POST /api/stock-transfers
- GET /api/stock-transfers/:id
- GET /api/sources/rebalance-report
- POST /api/orders/:id/assign-source/:sourceId
Every route added here must also appear in src/pages/openapi.json.ts — a test
fails the build if it does not.
Admin
Source management UI: list of sources with priority, edit dialog. Stock matrix view: products on rows, sources on columns, qty cells color-coded (red=low, yellow=medium, green=full). Order detail: shows fulfillment suggestion, dropdown to override source choice. Rebalance report: list of over/under-stocked sources, transfer suggestions.
The seam — why this is paid
Core owns the multi-qty interface and stock aggregation. Paid owns fulfillment-selection algorithm, source priority logic, transfer workflows, and support for complex routing rules across multiple locations.
Operational complexity requiring per-deployment configuration, warehouse selection logic, and source-management workflows. Already designated as paid tier. Support commitment includes ongoing warehouse topology management.
Dependencies
- product module (SKU)
- inventory module (extends with sources)
- order module (order lines linked to source)
- settings system (global fulfillment algorithm)
Acceptance checks
Each of these must be able to fail. Before claiming this is done, break the code deliberately and watch each one go red.
- GET /api/products/:id/qty returns sum of all available_qty across all sources
- GET /api/stocks/:productId returns array of { source_id, available_qty, reserved_qty, on_hand_qty }
- Fulfillment suggestion ranks sources by priority, top source first
- POST stock-transfer creates transfer record, deducts from_source available_qty, adds to_source on_hand_qty
- Reserved_qty is deducted from available_qty in fulfillment calculation (prevents overbooking)
- Source priority rule override on product: if set, takes precedence over global algorithm
- Rebalance report flags sources with available_qty < safety_stock or > max_capacity (both configurable)
Risks
Schema migration: adding source_id to existing inventories is multi-step (copy to stocks table, update orders.source_id, deprecate old inventory.qty); reserved_qty conflicts with order hold logic if not synchronized; fulfillment suggestion O(n) query on millions of stock records times out; partial fulfillment: what if source runs out mid-shipment (no refund logic here); transfer-in-flight orphans stock if not committed atomically.
Commercial context
| Suggested price | $599–1,299/year |
| Rival anchor | Magento ships MSI free: sources, stocks, per-website stock mapping, and a source-selection algorithm that recommends fulfillment paths. |
The anchor is what the nearest equivalent charges on Shopify or Magento today. It is context for a pricing decision, not the decision.
Generated from the commerce plan. See docs/COMMERCE-PLAN.md for the full
catalogue and ../../AI-GUIDE.md for how to work on this repository.