[Business Events] inventory: add business events
- Dominant language
- PHP
- Stars
- 3.4k
- Forks
- 1.2k
- Avg merge
- 3d 55m
- Merged PRs (30d)
- 436
Description
### User story
Catalog, stock, pricing and feed integrations have no first-class signal for what changed
in the product catalog. The only triggers available today are the generic
`product.written` / `product_price.written` webhooks, whose payload is `entity` +
`operation` + `primaryKey` — so to learn a product's name, stock level, price, availability
or visibility, a consumer must issue a follow-up API call on every write. There is also no
distinct signal for the moments that matter: a stock crossing zero, a product going live,
a price change.
This issue adds named `inventory` business events with rich payloads for those moments:
product lifecycle (create / update / delete), stock and availability transitions (stock
changed, out of / back in stock), publish state (`active` flipping on/off),
visibility / sales-channel assignment, and advanced-price changes. Each fires from every
write path — admin, Sync API and import — so ERP stock sync, low-stock alerts,
"notify when back in stock" signups and repricing/feed jobs can react straight from the
event payload without a fetch.
## Events to add
| Event | Fires when | Payload |
|-------|------------|---------|
| `inventory.product.created` | A product is created on any path | productId, + full product |
| `inventory.product.updated` | A product or its translations change | productId, changedFields, + full product |
| `inventory.product.deleted` | A product is deleted | productId, productNumber, deletedAt |
| `product.stock.changed` | A product's stock changes (order-driven or direct write) | productId, stock change (delta / new value) |
| `product.out_of_stock` | A product becomes unavailable | productId, available=false |
| `product.back_in_stock` | A product becomes available again | productId, available=true |
| `product.published` | A product's `active` flag flips on | productId, active=true |
| `product.unpublished` | A product's `active` flag flips off | productId, active=false |
| `product.visibility.changed` | A product's sales-channel visibility assignment changes | productId, salesChannelId, visibility |
| `product_price.changed` | A product (advanced) price is created or changed | productId, price, currencyId, ruleId, quantityStart |
| `product_price.deleted` | A product price is removed | productId, ruleId, deletedAt |
`product.out_of_stock` / `product.back_in_stock` fire only for **closeout-managed**
products — non-closeout products are always "available" regardless of stock.
### Acceptance criteria
-
### Definition of Done
- [ ] Fulfills all acceptance criteria defined during discovery.
- [ ] Integration/E2E testing in staging is done.
- [ ] All integration/E2E/unit tests passing; all critical or high-priority bugs are resolved.
- [ ] Fulfills compliance, performance, security, and cloud-readiness needs.
- [ ] Observability—includes monitoring, alerting, and logging; incident response handbooks updated.
- [ ] Documentation—developer docs are written or updated, including information on how the feature or change is adopted and tested. If new functionality, end user documentation is written or updated.
- [ ] (conditional) All new API endpoints have a defined API schema.
- [ ] (conditional) If the change affects the Storefront, it has been tested in the latest three versions of Firefox, Chrome, Edge, IE11, and Safari, as well as the different viewports and devices (Desktop / Tablet / Mobile).
- [ ] (conditional) If the change affects the Administration, it has been tested in current versions of Firefox, Chrome, and Edge.
- [ ] (conditional) Functionality that includes new API routes are callable via the Store-API (/store-api/[version]/).
- [ ] (conditional) If a new Admin module is created, the access control layer is provided, and permissions can be managed via the Users & Permissions module.
- [ ] (conditional) If a new UI input field or interactive element is introduced, the ACL wrapper is added.
- [ ] (conditional) Performance testing done if the change has a high performance impact, such as affecting scalability, load balancing, or query optimization.
Contributor guide
Research direction
Start by defining the missing acceptance criteria for the listed inventory events and tracing the admin, Sync API, import, and order-driven write paths. Establish integration, E2E, and unit tests for each event, including closeout availability transitions; done means all listed payloads and firing conditions work across every named path and the documentation is updated.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- php
- Domain
- api, backend
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100