Item Mutation Intent
Intent Definitions¶
LAX (The “Upsert & Trust” Mode)¶
- Intent: Flexibility and Idempotency. It prioritizes completing the operation over strict data validation.
- Validation:
- Partial Consistency Check: It verifies that if explicit fields (like Supplier or SKU) are provided in the reference, they match the existing database record for that Supply ID to prevent data corruption.
- Missing IDs: Allows creating items with missing supply references or partial data, often relying on later enrichment. - Behavior:
- Creation/Linking: If a Supply ID is provided, it links to it blindly.
- Sub-Entity Handling: In createItemSupply, it acts as an Upsert. If the supply exists, it updates it; if not, it creates it. - Use Case: Automated scripts, CSV imports, or “Add/Edit” forms where data might be partial or the ID is considered the absolute source of truth.
STRICT (The “Verify” Mode)¶
- Intent: Data Integrity and Consistency. It ensures that the user’s view of the data matches the system’s state before allowing a link.
- Validation:
- Consistency Check: If a Supply ID is provided, it must exist in the database.
- Field Matching: The provided Name and Supplier in the payload must exactly match the values currently stored in the database for that ID.
- Failure: If there is any drift (e.g., the user thinks ID 100 is “Apple”, but the DB says “Banana”), the operation fails with AppError.ArgumentValidation. - Behavior:
- No Side Effects: It will never implicitly update a sub-entity. It only links to existing, verified records. - Use Case: UI operations where a user selects a Supply from a list. Ensures the user isn’t linking to a record that has changed meaning/content since they loaded the page.
PROPAGATE (The “Cascade” Mode)¶
- Intent: Deep Persistence and Automation. It treats the payload as the master definition of the object graph.
- Validation:
- Relaxed: Like LAX, it skips the strict consistency check because it assumes differences are intentional updates. - Behavior:
- Cascading Creation: If a Supply is defined in the payload without an ID (or matches specific “creation” criteria in PersistencePreparer), the service creates the new ItemSupply
entity and links it to the Item automatically.
- Cascading Updates: If a Supply ID is provided but the fields (Name, Supplier) differ from the DB, the service updates the actual ItemSupply entity to match the payload. - Use Case: Complex editors where a user can edit an Item and its Supply details simultaneously, or imports where the goal is to synchronize the database with an external dataset completely.
Summary Table¶
| Qualifier | Supply Check | Behavior on Mismatch | Sub-Entity Creation | Use Case |
|---|---|---|---|---|
| LAX | Partial (Supplier/SKU) | Fails on Mismatch if provided | Upsert (Create or Update) | Scripts, Imports |
| STRICT | Exists + Matches Fields | Fails Operation | Atomic on Item Create, else Manual | UI Linking, Safety |
| PROPAGATE | None | Updates Database to match Payload | Automated (Deep Insert) | Deep Editing, Sync |
Operation Behaviors¶
Item Creation¶
From
ItemService.createmethod
The user provides Item information and primarySupply, secondarySupply contents.
General Validations and Defaulting Behavior for primarySupply and secondarySupply¶
supplieris a required field ifprimarySupplyorsecondarySupplyvalues are present.- No
supplyEidcan be provided - If
nameis not provided, it is defaulted to the value ofsupplier name(after default if applicable) should be different betweenprimarySupplyandsecondarySupplyif both are provided.supplyEId(after default if applicable) should be different betweenprimarySupplyandsecondarySupplyif both are provided.- The
Item.defaultSupply, if provided, it must match the name of either theprimarySupplyorsecondarySupplyafter defaults. - If
Item.defaultSupplyis not provided, it is defaulted to the name of the first non-nullnamevalue ofprimarySupplyorsecondarySupplyornullif none is provided.
LAX Behavior¶
Itemis created with one-off supplies. NoItemSupplyentities are created.Item.defaultSupplyEid,primarySupply.supplyEIdandsecondarySupply.supplyEIdare set to null if applicable (object is present)
STRICT and PROPAGATE Behavior¶
ItemSupplyentities are created with the values provided (after defaulting) forprimarySupplyandsecondarySupplyItemis enriched with the newly createdItemSupply.eIdvalues forprimarySupplyandsecondarySupplyrespectively.Item.defaultSupplyEidis set to theeIdof theItemSupplyentity that matches thedefaultSupplyname.
Note
Why STRICT behaves like PROPAGATE during creation: ItemSupply entities exist in a composition
relationship with their parent Item. Since no ItemSupply can exist before its parent Item is created,
STRICT mode ensures data integrity by atomically creating the supplies alongside the Item. The
“verify existing” semantic of STRICT applies only to Item updates where supplies may already exist.
Item Update¶
From
ItemService.updatemethod
General Validation and Defaulting Behavior for primarySupply and secondarySupply¶
supplieris a required field ifprimarySupplyorsecondarySupplyvalues are present.- IF
nameandsupplyEIdare provided, anItemSupplywith those values must exist. - If
nameis not provided, it is defaulted to:- If
supplyEIdis provided, thenamevalue of the identifiedItemSupplyentity - If
supplyEIdis not provided, the value ofsupplier
- If
name(after defaulting if applicable) should be different betweenprimarySupplyandsecondarySupplyif both are provided.supplyEIdif not provided and anItemSupplyfor the item exists with the same name, it is populated with theeIdof the matchingItemSupplyentity.- All other
non-nullprovided properties must match the values of a name matchingItemSupplyif it exists after an update. - The
Item.defaultSupplyvalue, if provided, it must match the name of either theprimarySupplyorsecondarySupplyafter defaults. - If
Item.defaultSupplyis not provided, it is defaulted to the name of the first non-nullnamevalue ofprimarySupplyorsecondarySupplyornullif none is provided. Item.defaultSupplyEidvalue, if provided, must match theeIdof theItemSupplyentity that matches thedefaultSupplyname.- Swapping
primarySupplyandsecondarySupplyis allowed and should not cause an update of thedefaultSupplyordefaultSupplyEidvalues in the parentItementity.
LAX Behavior¶
| Condition | Effect |
|---|---|
ItemSupply matching name or supplyEid exists |
Validation Error if any non-null provided value does not match the values of the matching ItemSupply entity |
ItemSupply matching name or supplyEid does not exist |
Item is Updated |
primarySupply or secondarySupply is cleared |
defaultSupply and defaultSupplyEid are set to the remaining value if not null, otherwise they are set to null |
STRICT Behavior¶
| Condition | Effect |
|---|---|
matching ItemSupply exists with matching non-null values |
Item is Updated |
matching ItemSupply does not exist or exists with different non-null values |
Validation Error |
primarySupply or secondarySupply is cleared |
defaultSupply and defaultSupplyEid are set to the remaining value if not null, otherwise they are set to null |
PROPAGATE Behavior¶
| Condition | Effect |
|---|---|
matching ItemSupply exists with matching non-null values |
Item is Updated |
matching ItemSupply does not exist |
Item is Updated, ItemSupply is created subject to uniqueness and other validations |
matching ItemSupply exists with different non-null values |
Item is Updated, ItemSupply is updated with the new values, including nullifying values and name (subject to uniqueness validation) |
primarySupply or secondarySupply is cleared |
defaultSupply and defaultSupplyEid are set to the remaining value if not null, otherwise they are set to null |
Note that ItemSupply entities are never deleted as a consequence of an Item Update, they need to be explicitly deleted by the user.
Item Deletion¶
From
ItemService.deletemethod
In all cases, all ItemSupply entities associated with the Item are deleted.
ItemSupply Creation¶
From
ItemService.createItemSupplymethod
General Validation and Defaulting.¶
supplieris a required field.- If
nameis not provided, it is defaulted tosupplier - No pre-existing
ItemSupplywith the samenamefor a givenItem(identified byparentEId) is allowed. (name is optional in input but it is provided/defaulted by the system before persisting the entities) supplierEIdis optional. If not provided, it is resolved fromsupplierby matchingBusinessAffiliateentities withvendorrole if it exists.
LAX, STRICT behavior¶
| Condition | Effect |
|---|---|
No ItemSupply exists with same name or eId |
ItemSupply is created |
ItemSupply matching by eId exists |
ItemSupply is updated (Upsert behavior in LAX) |
Parent Item has one-off reference (no supplyEId), matching the new ItemSupply by name or supplier |
ItemSupply is created, and the parent Item reference is updated to link to it |
Parent Item has reference with matching name but different non-null fields (e.g. supplier) |
Validation Error |
PROPAGATE¶
| Condition | Effect |
|---|---|
No ItemSupply exists with same name or eId |
ItemSupply is created |
Parent Item reference matches new ItemSupply by name or supplier |
ItemSupply is created, parent Item is updated to link to it |
ItemSupply Update¶
From
ItemService.updateItemSupplymethod
Validation and Defaulting¶
supplieris a required fieldeIdneeds to be provided.- if no
ItemSupplywith the giveneIdis found, result is aNotFounderror
LAX, STRICT, PROPAGATE¶
Note that all intents result in the same behavior for update operations. The intent is that as information is added to the system, its behavior becomes more predictable. Update operations on ItemSupply entities already have enough information to determine a unique consistent behavior across intents.
Furthermore, when a parent Item primary or secondary supply is already linked to an ItemSupply entity, the values should be the same due to previous create or update operations and propagation becomes the default behavior in the absence of validation errors.
| Condition | Effect |
|---|---|
Parent Item with primarySupply.name or secondarySupply.name or corresponding supplyEId does not exist |
Update succeeds |
Parent Item with matching supplyEid for primary or secondary supply, other values, including name do not match previous values |
Validation Error |
Parent Item with matching supplyEid for primary or secondary supply, other values, including name match previous values |
Update succeeds, update propagates to parent Item entity |
ItemSupply Delete¶
From
ItemService.removeItemSupplymethod
Validation and Defaulting¶
eIdneeds to be provided.- if no
ItemSupplywith the giveneIdis found, result is aNotFounderror
LAX, STRICT, PROPAGATE¶
| Condition | Effect |
|---|---|
Supply is referenced by parent’s primarySupply |
Fails with AppError.IncompatibleState |
Supply is referenced by parent’s secondarySupply |
Fails with AppError.IncompatibleState |
| Supply is not referenced by parent’s primary/secondary | Deletes ItemSupply entity |