You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
CRUD Service Features Map — Gap Analysis & Roadmap
Generated: 2026-02-28 | Last Reviewed: 2026-04-12 Scope: All 27 agent/service apps, shared lib schemas Purpose: Document every capability gap between the CRUD service and the agent ecosystem, propose new Postgres models, adapter integrations, and issues for feature parity.
The CRUD service currently manages 11 JSONB-backed Postgres tables and exposes 36 REST endpoints. However, the 21 agent services operate on 6 domain connector types (CRM, Product, Inventory, Logistics, Pricing, Funnel) backed by mock adapters only. The enterprise integration contracts define 8 additional connector ABCs (PIM, DAM, Commerce, Analytics, Integration, Identity, Workforce, CRM-enterprise). There are 59 open issues spanning infrastructure bugs, connector requests, and architecture enhancements.
Key Findings
Category
Gap Severity
Summary
Inventory
Critical
No dedicated inventory table/endpoints. All 4 inventory agents rely on mocks.
CRM
Critical
No contacts, accounts, or interactions tables. All 4 CRM agents use mocks.
Pricing
High
No pricing table. Checkout and cart agents can't resolve real prices.
Logistics
High
Shipment table is read-only. No write path for agent-produced tracking data.
Funnel/Campaign
High
No campaign or funnel tables. Campaign intelligence agent fully mocked.
Product Management
High
No CRUD integration for any of the 4 product-management agents.
Payments
Medium
Payment processing persists API-created payment records and GET /api/payments/{id} now supports role/ownership checks. Refund/history gaps remain.
Tickets
Medium
Staff/admin ticket lifecycle is mutable (create, update, resolve, escalate) with audit metadata. Customer-facing creation remains a gap.
PIM/DAM
Medium
Issue #34 proposes a full Product Graph + DAM workflow — no CRUD models exist.
Schema alignment
Medium
id vs sku, name vs title, category_id vs category mismatches throughout.
2. Current CRUD Service Inventory
2.1 Postgres Tables (JSONB-backed)
All tables share the universal schema: (id TEXT PK, partition_key TEXT, data JSONB, created_at TIMESTAMPTZ, updated_at TIMESTAMPTZ).
Table
Repository
CRUD Endpoints
Write Ops
products
ProductRepository
GET /api/products, GET /api/products/{id}, POST /api/products/{id}/trigger-enrichment
Seed + enrichment trigger
users
UserRepository
GET /api/users/me, PATCH /api/users/me
Auto-create from JWT
cart
CartRepository
GET /api/cart, POST /api/cart/items, DELETE /api/cart/items/{id}, DELETE /api/cart
Full CRUD
orders
OrderRepository
GET /api/orders, GET /api/orders/{id}, POST /api/orders, PATCH /api/orders/{id}/cancel
Create + Cancel
checkout_sessions
CheckoutSessionRepository
POST /acp/checkout/sessions, GET .../{id}, PATCH .../{id}, POST .../complete, DELETE .../{id}
Full CRUD
payment_tokens
PaymentTokenRepository
POST /acp/payments/delegate
Create only
categories
Inline CategoryRepository
GET /api/categories, GET /api/categories/{id}
Seed only
reviews
Inline ReviewRepository
GET /api/reviews, POST /api/reviews, DELETE /api/reviews/{id}
Create + Delete
tickets
Inline TicketRepository
GET /api/staff/tickets, GET /api/staff/tickets/{id}, POST /api/staff/tickets, PATCH /api/staff/tickets/{id}, POST /api/staff/tickets/{id}/resolve, POST /api/staff/tickets/{id}/escalate
Create + Update + Resolve + Escalate
returns
Inline ReturnRepository
GET /api/staff/returns, PATCH /api/staff/returns/{id}/approve
Approve only
shipments
Inline ShipmentRepository
GET /api/staff/shipments, GET /api/staff/shipments/{id}
Read-only
brand_shopping
ProductRepository + UserRepository + AgentClient
GET /api/catalog/products/{sku}, GET /api/customers/{customer_id}/profile, POST /api/pricing/offers, POST /api/recommendations/rank, POST /api/recommendations/compose
Contract-only, additive
2.2 Agent Integrations (via AgentClient)
AgentClient Method
Target Agent
CRUD Route That Calls It
semantic_search()
ecommerce-catalog-search
GET /products (search fallback)
get_user_recommendations()
ecommerce-cart-intelligence
GET /cart/recommendations
get_product_enrichment()
ecommerce-product-detail-enrichment
GET /products/{id}
calculate_dynamic_pricing()
ecommerce-checkout-support
GET /products/{id}
get_inventory_status()
inventory-health-check
POST /checkout/validate
validate_reservation()
inventory-reservation-validation
POST /cart/items
get_order_status()
ecommerce-order-status
GET /orders/{id}
get_delivery_eta()
logistics-eta-computation
GET /orders/{id}
get_carrier_recommendation()
logistics-carrier-selection
GET /orders/{id}
get_return_plan()
logistics-returns-support
GET /orders/{id}/returns
get_customer_profile()
crm-profile-aggregation
GET /users/me/crm
get_personalization()
crm-segmentation-personalization
GET /users/me/crm
Missing integrations (agents with no AgentClient method):
Agents that consume product data: ecommerce-catalog-search, ecommerce-product-detail-enrichment, ecommerce-cart-intelligence, ecommerce-checkout-support, all 4 product-management agents (8 agents total).
Field Mapping: CRUD ProductResponse vs Lib CatalogProduct
Field
CRUD ProductResponse
Lib CatalogProduct
Status
id / sku
id: str
sku: str
Mismatch — different field names
name / title
name: str
name: str
Match
description
description: str
description: Optional[str]
Match
price
price: float
price: Optional[float]
Match (type differs slightly)
category_id / category
category_id: str
category: Optional[str]
Mismatch — FK vs string
image_url
image_url: str?
image_url: Optional[str]
Match
in_stock
in_stock: bool
—
Missing from CatalogProduct
rating
rating: float?
rating: Optional[float]
Match
review_count
review_count: int?
—
Missing from CatalogProduct
features
features: list[str]?
—
Missing from CatalogProduct (goes in attributes)
media
media: list[dict]?
—
Missing from CatalogProduct
inventory
inventory: dict?
—
Missing from CatalogProduct (separate schema)
related
related: list[dict]?
—
Missing from CatalogProduct (in ProductContext)
brand
—
brand: Optional[str]
Missing from ProductResponse
currency
—
currency: Optional[str]
Missing from ProductResponse
tags
—
tags: list[str]
Missing from ProductResponse
attributes
—
attributes: dict
Missing from ProductResponse
variants
—
variants: list[dict]
Missing from ProductResponse
ACP Format Mismatch
The catalog-search agent returns ACP-formatted products with item_id, title, price as string ("10.00 usd"). CRUD's product list route passes these directly to ProductResponse validation, which expects id, name, price: float. This will fail Pydantic validation.
Seed data is minimal: Only id, name, description, price, category_id, image_url, in_stock are seeded. No brand, currency, tags, attributes, variants.
No product write endpoints: No POST /api/products or PATCH /api/products/{id} — products are seed-only.
No product event publishing: Product CRUD changes don't publish to product-events Event Hub. All 4 product-management agents subscribe to product-events but nothing publishes to it.
ACP search results require mapping layer before CRUD can serve them.
No inventory table — Critical. All 4 inventory agents are non-functional with real data.
No warehouse_stock table — health-check agent flags "no_warehouse_stock" but there's no source.
No inventory CRUD endpoints — No GET/POST/PATCH /api/inventory/{sku}.
No reservation persistence — Reservation validation is ephemeral.
BaseCRUDAdapter._get_inventory() fallback is broken — reads product's .inventory sub-field which is only populated by agent enrichment, not stored natively.
Reservation field name mismatch — Agent returns approved, CRUD cart route checks for valid.
No inventory event publishing from CRUD — publish_inventory_reserved() method exists but is never called.
No alerts/replenishment agent URL settings in CRUD — Only inventory_health_agent_url and inventory_reservation_agent_url exist.
The CRUD users table stores: id, email, name, phone, entra_id, created_at — a flat user profile with no CRM-level data (accounts, interactions, marketing preferences, segments, lifecycle stages).
Gaps
No CRM tables at all — This is the biggest gap for CRM agents.
User ↔ Contact mapping is implicit — AgentClient passes user_id as contact_id with no formal mapping.
No account entity — B2B scenarios (tiers, industries, lifecycle stages) have no backing store.
No interaction history — Agents can't retrieve real interaction data for sentiment, support briefs, or segmentation.
No agent URL settings for campaign and support agents — Only crm_profile_agent_url and crm_segmentation_agent_url exist.
No persistence for agent enrichments — Segments, engagement scores, personalization rules, support briefs, campaign ROI are all transient.
sku, active (PriceEntry), offers (list[PriceEntry])
No
CRUD stores price: float directly on the product document. There is no price history, promotional pricing, currency support, regional pricing, or discount management.
Gaps
No pricing table — Agents can't resolve real dynamic prices, promotional offers, or multi-currency amounts.
No pricing CRUD endpoints — No GET/POST/PATCH /api/pricing/{sku}.
Zero CRUD integration for all 4 product-management agents — No AgentClient methods, no settings URLs.
Agent outputs are fire-and-forget — ACP payloads, assortment scores, validation results, normalization/classification data are all logged but never persisted.
No product write path — Agents can't update product data (normalized names, classifications) back through CRUD.
No ProductData/AssetData tables — Issue #34's Product Graph and DAM requests have no backing models.
No product versioning or audit trail — Issue #34 requires immutable snapshots and rollback.
No confidence scoring model — Issue #34 requires per-field confidence scores for HITL workflows.
5. New Postgres Tables Required
Based on the full gap analysis, these tables should be added to the CRUD service. All follow the existing JSONB pattern: (id TEXT PK, partition_key TEXT, data JSONB, created_at TIMESTAMPTZ, updated_at TIMESTAMPTZ).
Priority 1 — Critical (Unblocks agents from mocks)
Each lib connector currently binds to a mock adapter. To make agents production-ready, adapters that call CRUD API endpoints should be created.
Connector
New Adapter
Calls CRUD Endpoint
Replaces
ProductConnector
CRUDProductAdapter
GET /api/products/{sku}
MockProductAdapter
InventoryConnector
CRUDInventoryAdapter
GET /api/inventory/{sku} (new)
MockInventoryAdapter
PricingConnector
CRUDPricingAdapter
GET /api/prices/{sku} (new)
MockPricingAdapter
LogisticsConnector
CRUDLogisticsAdapter
GET /api/staff/shipments/{id} + GET /api/shipment-events/{id} (new)
MockLogisticsAdapter
CRMConnector
CRUDCRMAdapter
GET /api/contacts/{id}, GET /api/accounts/{id}, GET /api/interactions (all new)
MockCRMAdapter
FunnelConnector
CRUDFunnelAdapter
GET /api/funnel-metrics, GET /api/campaigns/{id} (all new)
MockFunnelAdapter
6.2 Enterprise Connector Implementations
These implement the ABCs defined in integrations/contracts.py. They are not CRUD adapters but external system connectors. Each maps to one or more open connector issues (#36-#78).
Contract
Priority Implementations
Relevant Issues
PIMConnectorBase
Akeneo (#48), Salsify (#46)
#46-49, #74-75
DAMConnectorBase
Cloudinary (#50), Bynder (#52)
#50-52, #76
InventoryConnectorBase
SAP S/4HANA (#36), Dynamics 365 (#40)
#36-40, #77
CRMConnectorBase
Salesforce (#41), Dynamics 365 (#42)
#41-45, #78
CommerceConnectorBase
Shopify Plus (#53), commercetools (#54)
#53-59
AnalyticsConnectorBase
Azure Synapse (#60), Snowflake (#61)
#60-64
IntegrationConnectorBase
Confluent Kafka (#66)
#65-68
IdentityConnectorBase
Okta/Auth0 (#69)
#69
WorkforceConnectorBase
UKG/Kronos (#71)
#71-73
6.3 Architecture Issues for Adapter Infrastructure
Issue
Description
#79 — Connector Registry Pattern
Runtime discovery + DI for adapters (partially exists as ConnectorRegistry)
#80 — Event-Driven Connector Sync
CDC-based sync between connectors and CRUD data; implemented with typed connector events, webhook ingress, consumer idempotency, dead-letter, and replay endpoints
#81 — Multi-Tenant Connector Config
Per-tenant adapter configuration
#82 — Protocol Interface Evolution
Versioning strategy for connector contracts
#83 — Internal Data Enrichment Guardrails
Quality gates for agent-produced enrichments
#84 — Reference Architecture Patterns
Documentation of connector + adapter patterns
7. New Agents to Consider
Based on gap analysis and open issues, these new agents would fill functional gaps:
This section validates every proposed CRUD table and lib schema from Sections 4–5 against real enterprise ecommerce API data models. Each domain cross-references multiple platforms, identifies convergent field patterns, and recommends schema adjustments grounded in production-grade systems.
14.1 Methodology & Sources
Platforms Analyzed
Platform
Domain
API Style
Auth
Connector Issue
Shopify Plus
Commerce, Inventory, Orders
REST + GraphQL (Admin API)
OAuth 2.0
#53
commercetools
Commerce, Inventory, Orders, Customer
REST + GraphQL (Composable Commerce)
OAuth 2.0 (client_credentials)
#54
SAP S/4HANA
Inventory, SCM
OData v4
OAuth 2.0
#36
Oracle Fusion Cloud SCM
Inventory, Orders, Shipments
REST JSON
OAuth 2.0 JWT
#37
Manhattan Active Omni
Inventory, Orders, Fulfillment
REST + Events
OAuth 2.0
#38
Salesforce
CRM (Contact, Account, Case)
REST + GraphQL
OAuth 2.0 JWT
#41
Dynamics 365 CE
CRM (Contact, Account, Incident)
OData v4
Azure AD OAuth
#42
Salsify PXM
PIM (Products, Assets, Catalogs)
REST
API Key
#46
Akeneo PIM
PIM (Products, Attributes, Families)
REST
OAuth 2.0
#48
Cloudinary
DAM (Images, Transformations)
REST
API Key + Secret
#50
Azure Synapse Analytics
Analytics (SQL Pools, Pipelines)
REST + SQL
Azure AD
#60
Schema Retrieval
Primary sources: Shopify Admin REST API docs, commercetools HTTP API docs (fetched via web), SAP OData entity definitions from issue #36, Oracle Fusion endpoint specs from issue #37.
Secondary sources: Connector issue bodies (#36–#60) which contain endpoint specifications, entity structures, and protocol requirements.
Validation approach: Each proposed CRUD table is checked for (1) field-level coverage against ≥2 enterprise platforms, (2) naming convention alignment, and (3) missing enterprise-standard fields.
Upgrade category to category_path: list[str] — Both commercetools (categories[] references) and Akeneo (category trees) model hierarchical categories. A flat string loses the path context needed by assortment-optimization and normalization-classification agents.
Upgrade image_url to images: list[dict] — Every platform stores multiple images with metadata (position, dimensions, variant association). The single-URL approach prevents DAM workflows (issue #34).
Add status field — Shopify (active/draft/archived), commercetools (published/unpublished), Salsify, and Akeneo all have product lifecycle status. Essential for PIM agents.
Add version: int — commercetools requires this for optimistic concurrency. Essential for multi-agent writes to avoid conflicts.
Add source_system: str — Already on ProductData contract. Required when products come from multiple enterprise connectors simultaneously.
Add slug: str — Shopify handle and commercetools slug are used for SEO-friendly URLs. Needed when CRUD serves the frontend catalog.
⚠️ Enterprise distinguishes warehouse ID from location name. Split into location_name
Rename to location_name
updated_at
✅ Universal
Confirmed
—
on_hand_qty separate from available (SAP, Oracle)
Missing — Add on_hand_qty
—
location_type (warehouse, store, distribution center)
Missing — Add location_type for Manhattan/Oracle patterns
Recommendations
Add on_hand_qty to inventory table — Enterprise platforms (SAP, Oracle, Manhattan) distinguish between total on-hand stock and available-to-promise. Formula: available = on_hand - reserved - allocated. This is critical for inventory-health-check agent accuracy.
Add on_order_qty — Oracle and Manhattan track in-transit inventory. The jit-replenishment agent needs this to avoid over-ordering.
Add unit_of_measure — SAP and Oracle enforce UoM. Without it, the CRUD layer can't normalize quantities from different connectors (one reports "EA", another "CASE").
Add lot_number — SAP Batch, Oracle LotNumber. Required for traceability in regulated retail (food, pharma).
Rename safety_stock to reorder_point — Better alignment with SAP/Oracle naming. The InventoryData contract already uses reorder_point.
Add location_type to warehouse_stock — Manhattan Active Omni distinguishes facility types (DC, store, vendor-direct). Essential for carrier-selection and fulfillment routing agents.
14.4 Customer & CRM — Enterprise Comparison
Cross-Platform Customer/CRM Entity Comparison
Field Concept
Salesforce Contact
Dynamics 365 contact
commercetools Customer
Lib CRMContact
Lib CustomerData
Primary ID
Id (18-char)
contactid (GUID)
id (UUID)
contact_id
customer_id
External ID
ExternalId__c (custom)
—
externalId, customerNumber
—
—
Email
Email
emailaddress1
email (unique per Project/Store)
email
email
First Name
FirstName
firstname
firstName
first_name
first_name
Last Name
LastName
lastname
lastName
last_name
last_name
Phone
Phone, MobilePhone
telephone1, mobilephone
— (in addresses)
phone
phone
Title
Title
jobtitle
title
title
—
Date of Birth
Birthdate
birthdate
dateOfBirth
—
—
Company
via Account.Name
via parentcustomerid
companyName
—
—
Locale
—
—
locale
locale
—
Marketing Opt-In
HasOptedOutOfEmail (inverse)
donotemail (inverse)
— (via custom fields)
marketing_opt_in
consent{}
Segments
via Campaign Members
via Marketing Lists
customerGroup, customerGroupAssignments[]
tags[]
segments[]
Loyalty Tier
custom field
msdyn_loyaltyprogram (D365 extension)
customerGroup
—
loyalty_tier
Lifetime Value
custom / calculated
calculated
—
—
lifetime_value
Addresses
MailingAddress, OtherAddress
address1_*, address2_*
addresses[] (array, with default shipping/billing)
—
—
Preferences
custom fields
custom fields
custom (CustomFields)
preferences{}
preferences{}
Verified Email
—
—
isEmailVerified
—
—
Stores
—
—
stores[] (multi-store assignment)
—
—
Auth Mode
—
—
authenticationMode (Password/ExternalAuth)
—
—
Last Activity
LastActivityDate
lastusedincampaign
lastModifiedAt
—
last_activity
Tags
via Topics / Tags
via Tags
—
tags[]
—
Created/Modified
CreatedDate, LastModifiedDate
createdon, modifiedon
createdAt, lastModifiedAt
—
—
Account Entity Comparison
Field Concept
Salesforce Account
Dynamics 365 account
Lib CRMAccount
ID
Id
accountid
account_id
Name
Name
name
name
Industry
Industry
industrycode
industry
Region
BillingState/BillingCountry
address1_stateorprovince
region
Owner
OwnerId
ownerid
owner
Tier
Custom/Rating
customertypecode
tier
Lifecycle Stage
StageName (Opportunity-based)
statecode
lifecycle_stage
Revenue
AnnualRevenue
revenue
—
Employee Count
NumberOfEmployees
numberofemployees
—
Website
Website
websiteurl
—
Parent Account
ParentId
parentaccountid
—
Interaction Entity Comparison
Field Concept
Salesforce Task/Event
Dynamics 365 task/phonecall
Lib CRMInteraction
ID
Id
activityid
interaction_id
Contact Ref
WhoId
regardingobjectid
contact_id
Account Ref
AccountId
via contact relationship
account_id
Channel
Type (Call, Email, Meeting)
entity type (task, phonecall, email)
channel
Occurred At
ActivityDate
actualstart
occurred_at
Duration
CallDurationInSeconds
actualdurationminutes
duration_seconds
Outcome
CallDisposition
statuscode
outcome
Subject
Subject
subject
subject
Summary
Description
description
summary
Sentiment
— (custom)
— (custom)
sentiment
Priority
Priority
prioritycode
—
Validation of Proposed CRUD Tables
contacts table:
Proposed JSONB Field
Enterprise Coverage
Status
contact_id
✅ Universal
Confirmed
account_id
✅ Salesforce AccountId, Dynamics via relationship
Confirmed
email
✅ Universal
Confirmed
phone
✅ Universal (Salesforce has multiple phone fields)
Confirmed
locale
✅ commercetools locale
Confirmed
timezone
⚠️ Only Salesforce has native timezone (user-level)
✅ Universal (Dynamics uses minutes — normalize in adapter)
Confirmed
outcome
✅ Salesforce CallDisposition, Dynamics statuscode
Confirmed
subject
✅ Universal
Confirmed
summary
✅ Universal (Description)
Confirmed
sentiment
⚠️ Not native — typically computed by AI agents
Confirmed (agent-enriched)
metadata
✅ Custom fields on all platforms
Confirmed
—
priority (Salesforce, Dynamics)
Missing — Add priority
—
direction (inbound/outbound — standard CRM pattern)
Missing — Add direction
Recommendations
Add addresses[] to contacts — commercetools stores a full address array with default shipping/billing IDs. Salesforce has MailingAddress and OtherAddress. Addresses are critical for logistics agents (carrier-selection, ETA) and checkout.
Add loyalty_tier and lifetime_value to contacts — Already on CustomerData contract. Dynamics 365 has native loyalty support (msdyn_loyaltyprogram). Required by segmentation-personalization agent.
Add segments[] and consent{} to contacts — Already on CustomerData contract. commercetools has customerGroup/customerGroupAssignments. Required by campaign-intelligence and GDPR compliance.
Add external_id to contacts — When multiple CRM connectors coexist, the external system's ID must be preserved alongside the internal contact_id. commercetools supports externalId + customerNumber natively.
Add parent_account_id to accounts — Both Salesforce and Dynamics support account hierarchies. Essential for B2B enterprise retail with subsidiary relationships.
Add priority and direction to interactions — Standard CRM fields. Salesforce Priority and all CRM platforms distinguish inbound vs outbound interactions. Improves support-assistance agent triage.
Add customer_group — commercetools natively supports customer-group-specific prices. SAP uses CustomerGroup in condition records. Essential for B2B tiered pricing.
Add quantity_tiers[] — commercetools tiers allow different prices at quantity thresholds (e.g., buy 10+ at $5.00 each). Common in wholesale/B2B retail.
Add price_type — Distinguishes between standard, promotional, clearance, and employee pricing. Helps checkout-support agent apply correct pricing logic.
Note: Enterprise discount management (Shopify Discount API, commercetools Cart Discounts, SAP Condition Types) is deep enough to warrant a separate discounts table rather than overloading PriceEntry.discount_code.
The orders table already exists but uses a generic JSONB model. Comparing with enterprise schemas:
Enterprise Standard
CRUD Status
Gap
Multi-status model (financial + fulfillment + shipment)
Single status field in JSONB
⚠️ Enterprise uses compound status — consider financial_status, fulfillment_status, shipment_status
Currency as explicit field
Stored in JSONB data
⚠️ Should be a first-class field for multi-currency support
Structured line items with variant/sku references
In JSONB data
✅ Flexible via JSONB
Shipping + billing addresses
In JSONB data
✅ Flexible via JSONB
Order number / confirmation number
Not explicit
⚠️Missing — Add order_number for human-readable reference
Fulfillment tracking
Not linked
⚠️Missing — Add fulfillment_status or link to shipments table
Discount/coupon references
Not modeled
⚠️Missing — Add discount_codes[]
Refund tracking
Not modeled
⚠️Missing — Required by returns-support agent
Recommendations
Add compound status fields — Shopify separates financial_status and fulfillment_status. commercetools separates orderState, paymentState, and shipmentState. The order-status agent currently returns a single status string but needs granular states for accurate tracking.
Add order_number — Every enterprise platform assigns a human-readable order number (Shopify #1001, commercetools orderNumber). Currently, the CRUD service only has the internal UUID id.
Add currency — All enterprise platforms include currency at the order level. Essential for multi-region retail.
Link orders to shipments — Shopify fulfillments[] and Manhattan fulfillmentOrders[] create an explicit order → shipment relationship. The CRUD shipments table has order_id but there's no reverse lookup endpoint.
Unlock shipment writes — This is the most critical logistics gap. Every enterprise OMS (Manhattan, Oracle) provides full CRUD on shipments. Without write access, carrier-selection and ETA-computation agents can't persist recommendations.
Add line_items[] to shipments — Shopify fulfillments and Manhattan shipments track which line items are in each shipment. Enables partial fulfillment (split shipments), which is standard in enterprise retail.
Add carrier_code to shipment_events — When route-issue-detection agent processes events from multiple carriers, each carrier uses different event code systems. A raw carrier_code alongside the normalized code enables debugging.
family / product_type (Akeneo families, defining required attributes)
Missing — Add family
digital_assets table (proposed for Issue #34):
Proposed JSONB Field
Enterprise Coverage
Status
asset_id
✅ Cloudinary public_id, Salsify asset ID
Confirmed
sku
✅ Product association
Confirmed
url
✅ Universal
Confirmed
content_type
✅ Universal
Confirmed
alt_text
✅ Cloudinary context.alt
Confirmed
quality_score
⚠️ Agent-computed (not native to DAM platforms)
Confirmed (agent enrichment)
processed_variants
⚠️ Cloudinary generates variants via URL transforms, not stored variants
Adjust — store as transform_presets{} map
cdn_url
✅ Cloudinary auto-generates; standard for DAMs
Confirmed
—
filename (Universal)
Missing — Add filename
—
size_bytes (Cloudinary bytes)
Missing — Add size_bytes
—
width, height (Cloudinary, standard)
Missing — Add width, height
—
format (jpg, png, webp — Cloudinary format)
Missing — Add format
—
folder (Cloudinary folder)
Missing — Add folder for asset organization
Recommendations
Add completeness_score to product_graph_nodes — Akeneo's completeness metric (% of required attributes filled per locale/channel) is the industry standard for PIM quality. The consistency-validation agent should compute and persist this.
Add locale_data{} — Akeneo scopes every attribute by locale and channel. The normalization-classification agent needs this to handle localized product data from multi-region connectors.
Add full AssetData fields to digital_assets — The AssetData contract already defines filename, size_bytes, width, height. Cloudinary provides all of these. They should be persisted for asset management UI and DAM agent workflows.
Rename processed_variants to transform_presets{} — Cloudinary and modern DAMs handle image variants via transformation rules (e.g., thumbnail: w_200,h_200), not pre-generated files. Storing the preset definitions rather than output URLs is more maintainable.
14.9 Cross-Platform Convergence Summary
This matrix shows which proposed fields are confirmed by multiple enterprise platforms suggesting they are industry-standard and should be prioritized.
Partial fulfillment support (Shopify multiple fulfillments, Manhattan split shipments)
Order compound status (financial_status, fulfillment_status, shipment_status)
orders
Shopify, commercetools both use multi-dimensional status
Order human-readable number (order_number)
orders
Every platform assigns a display number (#1001, ORD-2024-001)
Implementation priority: Tier 1 fields should be included in the initial table creation PRs proposed in Section 12. Tier 2 fields should be filed as follow-up issues. Tier 3 patterns should be tracked in the architecture roadmap (issues #79–84) and implemented when multi-region/multi-channel support is prioritized.