Skip to content

Item Supply - Incremental Service Requirements

Overview

Change Summary

This document specifies the incremental changes required to extend the ItemService to support multiple ItemSupply entities per Item, enabling a flexible supplier management system that:

  1. Allows multiple (more than 2) potential suppliers for an Item through explicit ItemSupply entities.
  2. Maintains seamless backward compatibility with the existing primarySupply and secondarySupply properties.
  3. Supports user intent capture through ItemMutationQualifier (LAX, STRICT, PROPAGATE) to control how Item mutations affect related ItemSupply entities.
  4. Enables one-off supplies for Items without creating persistent ItemSupply entities.

Target Service/Module

  • Service: ItemService
  • Package: cards.arda.operations.reference.item
  • Repository: operations

Change Type

  • New Capability: Adding new methods or behaviors to existing service
  • Behavior Modification: Changing existing method behavior
  • Entity Extension: Adding properties to existing entities
  • New Child Entity: Adding ItemSupply entity under Item parent
  • Persistence Change: Schema migration for child entity table

Impact Assessment

Area Impact Level Description
API Contract Additive New endpoints for ItemSupply CRUD; new optional fields in Item payloads
Database Schema Migration Required New item_supply table with parent reference
Existing Tests Updates Required Tests must account for new qualifier-based behaviors
Client Applications Optional Update Clients can continue using existing API; new features require adoption

Design & Specification

Document Relevance
Item Create & Update with Item Supplies Domain model and feature context
Item Mutation Intent Detailed qualifier behavior specifications

Current State Analysis

Note

Document the current implementation state that this change will modify.

Existing Entity: Item

Current Properties (properties being modified or relevant to change):

Property Current Type Current Behavior
primarySupply ItemSupplyReference.Value? Embedded value object for primary supplier
secondarySupply ItemSupplyReference.Value? Embedded value object for secondary supplier
defaultSupply String? Name matching preferred supply
defaultSupplyEid EntityId? Points to linked ItemSupply.eId when applicable

Current Validation Rules:

Rule ID Current Condition Current Error
VR-001 name is not blank AppError.ArgumentValidation("name", ...)
VR-002 defaultSupply != null implies match to primary or secondary supply AppError.ArgumentValidation("defaultSupply", ...)

Existing Entity: ItemSupply

The ItemSupply entity currently exists with the following structure:

Property Type Required Description
eId EntityId Yes Unique identifier
supplierEId EntityId? No Reference to BusinessAffiliate entity
supplier String Yes Supplier name
name String? No Supply name (defaults to supplier)
sku String? No Stock Keeping Unit
orderMethod OrderMethod? No Method of ordering
url URL? No URL for online orders
orderQuantity Quantity.Value? No Order quantity
unitCost Money.Value? No Cost per unit
averageLeadTime Duration.Value? No Average lead time

Existing Value: ItemSupplyReference

The ItemSupplyReference.Value contains the same properties as ItemSupply plus:

Property Type Description
supplyEId UUID? Reference to associated ItemSupply entity

Existing Methods

ItemService.create

  • Current Signature: suspend fun create(payload: Item, metadata: ItemMetadata, time: Long, author: String, qualifier: ItemMutationQualifier): Result<EntityRecord<Item, ItemMetadata>>
  • Implementation Status: ✅ Implemented with qualifier support

ItemService.update

  • Current Signature: suspend fun update(payload: Item, metadata: ItemMetadata, time: Long, author: String, qualifier: ItemMutationQualifier): Result<EntityRecord<Item, ItemMetadata>>
  • Implementation Status: ✅ Implemented with qualifier support

ItemService.supplies

  • Current Signature: suspend fun supplies(parentEId: UUID, time: Long): Result<PageResult<ItemSupply, ItemSupplyMetadata>>
  • Implementation Status: ✅ Implemented

ItemService.createItemSupply

  • Current Signature: suspend fun createItemSupply(parentEId: UUID, itemSupply: ItemSupply, time: Long, author: String, qualifier: ItemMutationQualifier): Result<EntityRecord<ItemSupply, ItemSupplyMetadata>>
  • Implementation Status: ✅ Implemented

ItemService.updateItemSupply

  • Current Signature: suspend fun updateItemSupply(parentEId: UUID, itemSupply: ItemSupply, time: Long, author: String, qualifier: ItemMutationQualifier): Result<EntityRecord<ItemSupply, ItemSupplyMetadata>>
  • Implementation Status: ✅ Implemented

ItemService.removeItemSupply

  • Current Signature: suspend fun removeItemSupply(parentEId: UUID, supplyEId: UUID, time: Long, author: String): Result<EntityRecord<ItemSupply, ItemSupplyMetadata>>
  • Implementation Status: ✅ Implemented

Proposed Changes

Entity Modifications

Note

Document changes to existing entities or additions of new entities.
Use class diagrams to visualize structural changes (before/after).

Entity Modification Diagram

uml diagram

EM-ISU-001: ItemSupplyReference Properties

  • Change Type: Existing structure, documented for completeness
Properties
Property Type Required Default Description
supplyEId UUID? No null Reference to associated ItemSupply
supplierEId UUID? No null Reference to BusinessAffiliate entity
supplier String Yes - Supplier name
name String? No null Supply name (defaults to supplier)
sku String? No null Stock Keeping Unit
orderMethod OrderMethod? No null Order method enum
url URL? No null URL for online ordering
orderQuantity Quantity.Value? No null Order quantity
unitCost Money.Value? No null Unit cost
averageLeadTime Duration.Value? No null Average lead time

EM-ISU-002: ItemSupply Entity

  • Parent Entity: Item
  • Relationship: Child entity bound by parentEId
Properties
Property Type Required Default Description
eId EntityId Yes Generated Unique identifier
parentEId EntityId Yes From parent Entity ID of parent Item
supplierEId EntityId? No Resolved Reference to BusinessAffiliate
supplier String Yes - Supplier name
name String Yes supplier Supply name (natural key within Item)
sku String? No null Stock Keeping Unit
orderMethod OrderMethod? No null Order method
url URL? No null URL for online orders
orderQuantity Quantity.Value? No null Order quantity
unitCost Money.Value? No null Unit cost
averageLeadTime Duration.Value? No null Average lead time
Validation Rules
Rule ID Condition Error
VR-ISU-001 name is not null or blank after defaulting AppError.ArgumentValidation("name", ...)
VR-ISU-002 supplier is not blank AppError.ArgumentValidation("supplier", ...)
VR-ISU-003 name is unique within parent Item AppError.Duplicate(...)
VR-ISU-004 orderMethod == ONLINE implies url != null AppError.ArgumentValidation("url", ...)
VR-ISU-005 orderQuantity.amount > 0 when provided AppError.ArgumentValidation("orderQuantity", ...)
VR-ISU-006 unitCost.value >= 0 when provided AppError.ArgumentValidation("unitCost", ...)

Method Modifications

Note

Document changes to existing methods or additions of new methods.
Use sequence diagrams to illustrate modified interaction flows.

Method Overview Diagram

uml diagram

MM-ISU-001: Item Creation with Qualifier

  • Method: ItemService.create(payload, metadata, time, author, qualifier)
  • Implementation Status: ✅ Implemented
General Validation and Defaulting
Rule Condition Error/Behavior
Supplier Required primarySupply != null or secondarySupply != null supplier field must be non-blank
No SupplyEId on Create Creating new Item supplyEId must be null (supplies don’t exist yet)
Name Defaulting name == null Default to supplier value
Name Uniqueness Both supplies present primarySupply.name != secondarySupply.name
DefaultSupply Validation defaultSupply != null Must match primarySupply.name or secondarySupply.name
DefaultSupply Defaulting defaultSupply == null Set to first non-null name of primary or secondary
Behavior by Qualifier
Qualifier ItemSupply Creation Item.supplyEId Fields Item.defaultSupplyEid
LAX None (one-off supplies) Set to null Set to null
STRICT Created for each supply ref Set to new eId Set to matching supply eId
PROPAGATE Created for each supply ref Set to new eId Set to matching supply eId

MM-ISU-002: Item Update with Qualifier

  • Method: ItemService.update(payload, metadata, time, author, qualifier)
  • Implementation Status: ✅ Implemented
General Validation and Defaulting
Rule Condition Error/Behavior
Supplier Required primarySupply != null or secondarySupply != null supplier field must be non-blank
EId+Name Consistency name and supplyEId both provided Must match existing ItemSupply
Name Defaulting name == null && supplyEId != null Default to ItemSupply.name
Name Defaulting name == null && supplyEId == null Default to supplier
SupplyEId Resolution supplyEId == null && name matches existing supply Populate with matching ItemSupply.eId
Swap Detection Primary/secondary swapped No change to defaultSupply/defaultSupplyEid
Behavior by Qualifier
Qualifier Matching Supply Exists + Values Match Matching Supply Exists + Values Differ No Matching Supply Supply Cleared
LAX Update succeeds Validation Error Update succeeds Default to remaining or null
STRICT Update succeeds Validation Error Validation Error Default to remaining or null
PROPAGATE Update succeeds ItemSupply updated ItemSupply created Default to remaining or null
Side Effects
Effect Entities Affected Condition
Create ItemSupply ItemSupply PROPAGATE + no matching supply
Update ItemSupply ItemSupply PROPAGATE + values differ
Update defaultSupply* fields Item Supply cleared

Note

ItemSupply entities are never deleted as a consequence of an Item Update. They must be explicitly deleted via removeItemSupply.


MM-ISU-003: Item Deletion

  • Method: ItemService.delete(eId, ...)
  • Implementation Status: Verify cascade behavior
Behavior (All Qualifiers)
Effect Description
Delete Item Item entity is deleted
Cascade Delete All ItemSupply entities with matching parentEId are deleted

MM-ISU-004: Create ItemSupply

  • Method: ItemService.createItemSupply(parentEId, itemSupply, time, author, qualifier)
  • Implementation Status: ✅ Implemented
Pre-conditions
Condition Error on Violation
Parent Item exists AppError.NotFound("Item", ...)
supplier is not blank AppError.ArgumentValidation("supplier", ...)
name unique within parent AppError.Duplicate(...)
Behavior by Qualifier
Qualifier No Item References Supply Item Has Matching Supply (same values) Item Has Matching Supply (diff values)
LAX/STRICT Supply created Supply created, Item backfilled with null fields Validation Error
PROPAGATE Supply created Supply created, Item updated Supply created, Item updated
Defaulting
Property Condition Default Value
name Not provided Value of supplier
supplierEId Not provided Resolved from BusinessAffiliate with vendor role

MM-ISU-005: Update ItemSupply

  • Method: ItemService.updateItemSupply(parentEId, itemSupply, time, author, qualifier)
  • Implementation Status: ✅ Implemented
Pre-conditions
Condition Error on Violation
eId is provided AppError.ArgumentValidation("eId", ...)
ItemSupply exists AppError.NotFound("ItemSupply", ...)
supplier is not blank AppError.ArgumentValidation("supplier", ...)
Behavior (Uniform across qualifiers)

Note

All qualifiers behave identically for updateItemSupply. The rationale is that when information is already in the system (linked supplies), behavior becomes predictable.

Condition Effect
Parent Item has no matching primary/secondary Update succeeds
Parent Item has matching supplyEId, values match Update succeeds, propagates to parent Item
Parent Item has matching supplyEId, values differ Validation Error

MM-ISU-006: Remove ItemSupply

  • Method: ItemService.removeItemSupply(parentEId, supplyEId, time, author)
  • Implementation Status: ✅ Implemented
Pre-conditions
Condition Error on Violation
eId is provided AppError.ArgumentValidation("eId", ...)
ItemSupply exists AppError.NotFound("ItemSupply", ...)
Behavior (Uniform across qualifiers)
Condition Effect
Supply referenced by primarySupply.supplyEId AppError.IncompatibleState
Supply referenced by secondarySupply.supplyEId AppError.IncompatibleState
Supply not referenced by primary/secondary ItemSupply entity deleted

MM-ISU-007: List Supplies

  • Method: ItemService.supplies(parentEId, time)
  • Implementation Status: ✅ Implemented
Return Value
  • Success: Result.success(PageResult<ItemSupply, ItemSupplyMetadata>) - all supplies for parent Item

Persistence Changes

Note

Document database schema changes and migration requirements.

PC-ISU-001: ItemSupply Table

  • Status: ✅ Implemented

The item_supply table exists as a child table under item with bitemporal versioning.

Schema
Column Type Nullable Description
eid UUID No Entity ID (primary key with time coords)
parent_eid UUID No Parent Item entity ID
supplier_eid UUID Yes BusinessAffiliate reference
supplier VARCHAR(255) No Supplier name
name VARCHAR(255) No Supply name (natural key)
sku VARCHAR(255) Yes Stock Keeping Unit
order_method VARCHAR(50) Yes OrderMethod enum value
url TEXT Yes URL for online orders
order_qty_amount DECIMAL Yes Order quantity amount
order_qty_unit VARCHAR(50) Yes Order quantity unit
unit_cost_value DECIMAL Yes Unit cost value
unit_cost_currency VARCHAR(3) Yes Unit cost currency code
avg_lead_time VARCHAR(50) Yes Duration ISO format
Indexes
Index Columns Purpose
idx_item_supply_parent parent_eid Fast lookup by parent Item
idx_item_supply_name_unique parent_eid, name Enforce uniqueness constraint

API Changes

Note

Document REST API contract changes.

AC-ISU-001: Item Create/Update with Qualifier

  • Endpoint: POST /v1/item and PUT /v1/item/{eId}
  • Change Type: New query parameter
Request Changes
Field Change Type Required Notes
qualifier NEW Query param String No Default: LAX. Values: LAX, STRICT, PROPAGATE
Versioning Strategy
  • Additive change - backward compatible

AC-ISU-002: ItemSupply CRUD Endpoints

  • Change Type: New endpoints
Method Endpoint Description
GET /v1/item/{parentEId}/supply List supplies for an Item
POST /v1/item/{parentEId}/supply Create a new ItemSupply
PUT /v1/item/{parentEId}/supply/{supplyEId} Update an ItemSupply
DELETE /v1/item/{parentEId}/supply/{supplyEId} Remove an ItemSupply
Request Body (POST/PUT)
{
  "eId": "uuid (required for PUT)",
  "supplier": "string (required)",
  "name": "string (optional, defaults to supplier)",
  "sku": "string (optional)",
  "orderMethod": "enum (optional)",
  "url": "string (optional)",
  "orderQuantity": { "amount": "number", "unit": "string" },
  "unitCost": { "value": "number", "currency": "string" },
  "averageLeadTime": "ISO-8601 duration (optional)"
}
Response
{
  "eId": "uuid",
  "parentEId": "uuid",
  "supplier": "string",
  "name": "string",
  "supplierEId": "uuid or null",
  "sku": "string or null",
  "orderMethod": "enum or null",
  "url": "string or null",
  "orderQuantity": { ... },
  "unitCost": { ... },
  "averageLeadTime": "string or null"
}

Requirements Summary

The following table provides a consolidated summary of all requirements specified in this document.

Entity Requirements

ID Title Description
EM-ISU-001 ItemSupplyReference Properties Documents the value object properties for embedding supply info in Item primary/secondary slots
EM-ISU-002 ItemSupply Entity Child entity bound to Item via parentEId, with name as natural key within parent scope

Method Requirements

ID Title Description
MM-ISU-001 Item Creation with Qualifier Create Item with LAX (one-off supplies), STRICT/PROPAGATE (creates ItemSupply entities)
MM-ISU-002 Item Update with Qualifier Update Item with qualifier-dependent validation and ItemSupply create/update side effects
MM-ISU-003 Item Deletion Delete Item with cascade deletion of all associated ItemSupply entities
MM-ISU-004 Create ItemSupply Create new supply under parent Item with name defaulting and uniqueness validation
MM-ISU-005 Update ItemSupply Update supply with propagation to parent Item’s primary/secondary references if linked
MM-ISU-006 Remove ItemSupply Delete supply; fails if referenced by parent’s primarySupply or secondarySupply
MM-ISU-007 List Supplies Retrieve all ItemSupply entities for a given parent Item

Persistence Requirements

ID Title Description
PC-ISU-001 ItemSupply Table Schema Bitemporal child table with parent reference, supplier info, and supply details

API Requirements

ID Title Description
AC-ISU-001 Qualifier Parameter New qualifier query parameter on Item create/update endpoints (default: LAX)
AC-ISU-002 ItemSupply CRUD Endpoints REST endpoints for list, create, update, and delete operations on ItemSupply entities

Validation Rules

ID Title Description
VR-ISU-001 Name Required ItemSupply name must not be blank after defaulting from supplier
VR-ISU-002 Supplier Required ItemSupply supplier field must not be blank
VR-ISU-003 Name Uniqueness ItemSupply name must be unique within the parent Item scope
VR-ISU-004 URL Required for Online When orderMethod == ONLINE, the url field is required
VR-ISU-005 Order Quantity Positive When provided, orderQuantity.amount must be greater than zero
VR-ISU-006 Unit Cost Non-Negative When provided, unitCost.value must be zero or positive

Testing Requirements

Existing Test Modifications

Test File Test Name Modification Required
ItemServiceTest.kt Create/Update tests Add qualifier-based behavior variations
ItemApiTest.bru CRUD operations Add qualifier parameter tests

New Test Cases

Unit Tests

Test ID Description Validates
UT-ISU-001 Create Item with LAX qualifier creates no supplies MM-ISU-001
UT-ISU-002 Create Item with PROPAGATE creates supplies MM-ISU-001
UT-ISU-003 Create Item with STRICT creates supplies MM-ISU-001
UT-ISU-004 Update Item with LAX validates matching supplies MM-ISU-002
UT-ISU-005 Update Item with STRICT fails on missing supply MM-ISU-002
UT-ISU-006 Update Item with PROPAGATE creates missing supply MM-ISU-002
UT-ISU-007 Update Item with PROPAGATE updates differing supply MM-ISU-002
UT-ISU-008 Delete Item cascades to supplies MM-ISU-003
UT-ISU-009 Create supply with LAX upserts existing MM-ISU-004
UT-ISU-010 Create supply with STRICT fails on duplicate MM-ISU-004
UT-ISU-011 Update supply propagates to parent Item MM-ISU-005
UT-ISU-012 Remove supply fails when referenced MM-ISU-006
UT-ISU-013 Remove supply succeeds when not referenced MM-ISU-006
UT-ISU-014 Supply name defaults to supplier VR-ISU-001
UT-ISU-015 Supply name uniqueness enforced within parent VR-ISU-003

Integration Tests

Test ID Description Setup Validates
IT-ISU-001 Full CRUD cycle with PROPAGATE qualifier Item + Supplies All methods
IT-ISU-002 Supplier resolution from BusinessAffiliate BusinessAffiliate setup MM-ISU-004

API Tests (Bruno)

Test ID Description Endpoint Validates
AT-ISU-001 Create Item with qualifier=PROPAGATE POST /v1/item?qualifier=PROPAGATE AC-ISU-001
AT-ISU-002 List supplies for Item GET /v1/item/{id}/supply AC-ISU-002
AT-ISU-003 Create supply under Item POST /v1/item/{id}/supply AC-ISU-002
AT-ISU-004 Update supply PUT /v1/item/{id}/supply/{sid} AC-ISU-002
AT-ISU-005 Delete supply DELETE /v1/item/{id}/supply/{sid} AC-ISU-002
AT-ISU-006 Delete supply fails when referenced DELETE /v1/item/{id}/supply/{sid} MM-ISU-006

Migration & Deployment

Deployment Order

  1. Deploy database migration (if any schema changes pending)
  2. Deploy backend service with updated ItemService
  3. Update frontend clients to use qualifier parameter (optional)

Rollback Plan

Scenario Action
Service failure Rollback to previous service version
Data inconsistency Audit item_supply table; remove orphaned records

Requirements Summary

Note

This table provides a quick reference to all changes specified in this document. Keep this synchronized as requirements are added or updated.

All Changes Index

ID Category Change Type Description Status
EM-ISU-001 Entity Modification DOCUMENT ItemSupplyReference properties Implemented
EM-ISU-002 Entity Modification NEW ItemSupply entity Implemented
MM-ISU-001 Method Modification MODIFY Item creation with qualifier Implemented
MM-ISU-002 Method Modification MODIFY Item update with qualifier Implemented
MM-ISU-003 Method Modification VERIFY Item deletion cascade Verify
MM-ISU-004 Method Modification NEW Create ItemSupply Implemented
MM-ISU-005 Method Modification NEW Update ItemSupply Implemented
MM-ISU-006 Method Modification NEW Remove ItemSupply Implemented
MM-ISU-007 Method Modification NEW List Supplies Implemented
PC-ISU-001 Persistence Change NEW ItemSupply table schema Implemented
AC-ISU-001 API Change MODIFY Qualifier parameter on Item endpoints Verify
AC-ISU-002 API Change NEW ItemSupply CRUD endpoints Verify

Validation Rules Changes

Rule ID Entity Change Condition Error Type
VR-ISU-001 ItemSupply NEW name not blank after default AppError.ArgumentValidation
VR-ISU-002 ItemSupply NEW supplier not blank AppError.ArgumentValidation
VR-ISU-003 ItemSupply NEW name unique within parent AppError.Duplicate
VR-ISU-004 ItemSupply NEW ONLINE requires URL AppError.ArgumentValidation
VR-ISU-005 ItemSupply NEW orderQuantity > 0 AppError.ArgumentValidation
VR-ISU-006 ItemSupply NEW unitCost >= 0 AppError.ArgumentValidation

Summary by Change Category

Category Total NEW MODIFY DOCUMENT
Entity Modifications (EM) 2 1 0 1
Method Modifications (MM) 7 4 2 0
Persistence Changes (PC) 1 1 0 0
API Changes (AC) 2 1 1 0
Total 12 7 3 1

Test Coverage

Change ID Unit Test Integration Test API Test
MM-ISU-001 UT-ISU-001-003 IT-ISU-001 AT-ISU-001
MM-ISU-002 UT-ISU-004-007 IT-ISU-001 AT-ISU-001
MM-ISU-003 UT-ISU-008 - -
MM-ISU-004 UT-ISU-009-010 IT-ISU-002 AT-ISU-003
MM-ISU-005 UT-ISU-011 - AT-ISU-004
MM-ISU-006 UT-ISU-012-013 - AT-ISU-005-006
AC-ISU-002 - - AT-ISU-002-006

Open Questions

ID Question Owner Status Resolution
Q-001 Verify Item deletion properly cascades to ItemSupply entities Dev Open -
Q-002 Confirm API endpoints for ItemSupply are fully exposed in Routes Dev Open -
Q-003 STRICT mode on Create - should it require pre-existing supplies? Design Open Currently creates supplies like PROPAGATE

Revision History

Version Date Author Changes
1.0.0 2026-01-30 Claude/Gemini Initial draft based on spec analysis


Copyright: © Arda Systems 2025-2026, All rights reserved

Comments