[upstream #4628] [RFC] feat(core): Add partitionKey to StockLevel for sub-location stock tracking - #37
Open
ayim wants to merge 9 commits into
Open
[upstream #4628] [RFC] feat(core): Add partitionKey to StockLevel for sub-location stock tracking#37ayim wants to merge 9 commits into
ayim wants to merge 9 commits into
Conversation
- Default partitionKey to '' instead of omitting from where clause,
preventing non-deterministic cross-partition matches
- Add JSDoc documenting default partition behavior, asymmetric
creation semantics, and stockLevelId/partitionKey precedence rule
- Add GraphQL description to StockLevelInput.partitionKey field
- Fix non-deterministic unit test assertion
- Capture initial stock values in E2E test for precise comparison
The documented precedence rule (stockLevelId > partitionKey) was not implemented in the service layer. Rather than adding complexity, remove stockLevelId entirely — partitionKey alone is sufficient to identify a specific StockLevel partition.
StockMovement records now track which stock partition they affect, enabling per-batch/lot movement history and full traceability.
…eview feedback Replace hardcoded empty-string defaults with a named constant as suggested by @DanielBiegler. Exported from @vendure/core for use in custom StockLocationStrategy implementations.
The MultiChannelStockLocationStrategy.forAllocation() previously used find() to get a single StockLevel per location, ignoring other partitions. Now uses filter() to iterate over all partitions at each location, allocating from each until the requested quantity is fulfilled. Updated BaseStockLocationStrategy.getLocationsBasedOnAllocations() to group by locationId+partitionKey for correct sale/release/cancellation. Added 8 unit tests covering multi-partition allocation, partition-aware sale/release/cancellation, and single-partition backward compatibility.
StockLocationService.delete() now matches and creates StockLevel records by partitionKey when transferring stock to another location, preventing partition merge and preserving batch traceability.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Mirrored from vendurehq#4628 for the Overwatch review demo.
Original author: @niko91i
Context
This PR is a working proof-of-concept related to a discussion on Discord:
https://discord.com/channels/1100672177260478564/1488690570296692909
The current
StockLevelentity enforces a unique constraint on[productVariantId, stockLocationId],meaning only one stock record can exist per variant per location. This forces use cases like batch/lot
tracking, serial number management, or expiration-based stock rotation to create one
StockLocationper batch — polluting a table designed for physical locations.
At scale (e.g. 10,000 vendors × 30 products × 6 batches/year = 1.8M rows/year), the
stock_locationtable becomes unmanageable for its original purpose.
Proposed solution
Add an optional
partitionKeycolumn toStockLevel, allowing multiple stock records for the samevariant+location pair, each identified by a unique key.
partitionKeydefaults to''(empty string) — existing behavior is 100% unchanged[productVariantId, stockLocationId, partitionKey]LocationWithQuantitygains optionalpartitionKeyandstockLevelIdfieldsStockLevelServicemethods accept an optionalpartitionKeyparameterStockMovementServicepropagatespartitionKeythrough all allocation/sale/release/cancellation flowsChanges
stock-level.entity.ts— NewpartitionKeycolumn (default'') + updated unique indexstock-location-strategy.ts— OptionalstockLevelIdandpartitionKeyonLocationWithQuantitystock-level.service.ts— OptionalpartitionKeyparameter ongetStockLevel,updateStockOnHand,updateStockAllocatedstock-movement.service.ts— PropagatepartitionKeythrough 5 call sitespartitionKeyonStockLeveltype andStockLevelInputWhat does NOT change
StockLocationentity — untouchedStockLocationStrategyinterface — method signatures unchangedDefaultStockLocationStrategy/MultiChannelStockLocationStrategy— no modificationspartitionKeywork identicallyTest plan
StockLevelServicewith/withoutpartitionKey