Inventory publish path
Stock mutation or product allocation change
-> outbox stock.sync.requested
or in-process product.channel-allocation.changed
-> StockSyncService / ProductStockSyncListener
-> InventoryPublishBuffer
-> inventory_publish_queue
flush-channel:SHOPIFY
flush-channel:WOOCOMMERCE
flush-channel:FLIPKART
flush-channel:AMAZON
flush-channel:DEFAULT
channel-feed-poll
reconcile-channel-batch
-> IMarketplaceInventoryService
Synchronous versus asynchronous
The stock transaction commits the movement and the outbox row. The channel HTTP call happens on the worker. The original stock request does not wait for Shopify or Amazon.
Feeds
Amazon-style connectors persist ChannelInventoryFeedSubmission and update ChannelInventoryState only after the poll result is downloaded. ChannelFeedPollReaperScheduler (*/10 * * * *) requeues stuck polls.
Partial success
BulkPublishResult is per item. A chunk can mix success and failure. The processor’s exact persist rules were not fully read. Do not describe the flush as all-or-nothing.
Rate limits
InventoryRateLimiterService and per-channel flush concurrency exist. WooCommerce bulk publish can consume the limiter itself (selfPacesRateLimit). Numeric budgets are in inventory-publish.constant.ts. Copy them from that file when you need the numbers. They are not restated here because they were not re-read line by line for this page.
Reconciliation
InventoryReconciliationScheduler has two crons: 0 * * * * and */2 * * * *. Which method each cron calls was not mapped.
Quantity formula
Unknown at line level. Channel fields cover allocation mode, buffer, min/max publish quantity, and zero-quantity behaviour. The formula that combines them is in stock-sync.service.ts. Until that function is written up from source, do not publish a formula on this page.
Idempotency
Bull job ids on flush were not verified. A duplicate stock.sync.requested can enqueue another flush if the listener does not dedupe.