Strategy ELC Implementation Reyes Implementation
Strategy ELC Implementation Reyes Implementation
1. Current state 2. The north star 3. The scaling story 4. The strategic case 5. The architecture 6. Current state: codebase coupling 7. Full module catalog 8. Module boundaries 9. Two-phase approach 10. Current vs future 11. Codebase reality 12. First implementation: ELC 13. What's next 14. Open questions
1. Client overview 2. The trajectory 3. Shell configuration 4. Base modules 5. Optional modules 6. Platform phasing 7. Implementation timeline 8. Subsequent markets 9. What this proves 10. Open questions
1. Client overview 2. The trajectory 3. Shell configuration 4. Base modules 5. Optional modules 6. Platform phasing 7. Implementation timeline 8. Subsequent markets 9. What this proves 10. Open questions

DI Commerce
Modular Architecture Proposal

DI Commerce scales linearly today. Each new client and each new market within a client requires independent frontend work. This document proposes a modular architecture that makes new deployments configuration rather than custom development. Each subsequent deployment is faster than the last. Once the module catalog is established, estimated time to deploy can be reduced by 30% or more.

March 31, 2026 · v1.0 · Internal
Prepared by Joe Grout / Kesal Patel

1. Current state

DI Commerce is Tag's B2B ordering platform on Adobe Commerce. The engineering team built sophisticated capabilities: multi-ship checkout handling thousands of addresses via CSV upload, tiered approval workflows with item-level granularity and delegation, queue-based asynchronous order processing. These are not trivial achievements. The platform handles complex B2B workflows that most commerce solutions can't touch.

The challenge is scale. Each new client engagement requires significant custom frontend development to deliver the same caliber of experience. The implementation process includes extended manual configuration phases, and each engagement is independent. The work done for one client doesn't carry over to the next. Effort scales linearly with each new client.

This creates a compounding problem as the commerce practice grows. Each new client in the pipeline represents the same cycle: custom development, manual configuration, independent timelines. The capabilities are there. The delivery mechanism doesn't scale.

The same challenge exists within a single client. A global program like ELC doesn't need one storefront. It needs many. Different markets, different regions, different branding, different pricing, different regulatory requirements. Under the current approach, each market is its own engagement. Under the modular approach, each market is a configuration.

2. The north star

Get the right product to the right location, fast, and stay informed the whole way.

Every architectural decision in this document serves one person: the field representative placing orders for their territory. They don't care about modules or configuration surfaces. They care about execution. Find the product, know what it costs, get it to the right stores, track that it arrived.

The field rep isn't shopping. They're distributing. They usually know what their territory needs. The platform's job is to make the path from "I know what my stores need" to "it's on its way" as short as possible. Every click that isn't serving that path is friction.

The primary mode is execution: "I need the Q2 counter display at 85 stores in the Southeast." The secondary mode is discovery: "What's available in the FY25 Mac Evergreen program?" The platform supports both, but it's optimized for the first.

What good looks like

Vista Print is the benchmark. They're the third-largest commercial printer in the US, competing in B2B. Their buying experience is optimized for someone who knows what they want and needs to execute fast. That's our standard.

InteractionTarget
Evaluate a product from the listing cardUnder 10 seconds
Find any specification on the product detail pageWithin one scroll
Place a routine order (known products, known address)Under 3 minutes
Complete a 200-address multi-ship orderUnder 10 minutes
Answer "where is my order?" from order historyUnder 10 seconds
Upload artwork, preview, proof, and add to cartUnder 5 minutes

How every module serves the north star

ModuleServes the north star by...
NavigationGetting the field rep to the right product fast: category, campaign, brand paths
Search"I know the SKU": instant execution path
CatalogPresenting products clearly so decisions happen in seconds, not minutes
PricingShowing the right price for this region immediately, no ambiguity
OrderingShortest path from cart to confirmed order. Address book, checkout, done.
Multi-ShipOne order, 200 locations, one action. Territory-wide distribution in minutes.
ApprovalAuthorization without blocking. Clear status, fast review, no dead ends.
Print on DemandSee exactly what will be printed before committing. No guesswork.
AnalyticsMeasuring whether the platform is actually fast enough, clear enough.

Clean slate, not an extension of the current implementation. The modular architecture gives us the chance to design the right experience for every module from scratch. The new framework starts with what the field rep needs and works backward to the architecture.

3. The scaling story

The modular architecture doesn't just make client onboarding faster. It makes the entire commerce practice compound. Each deployment, whether it's a new client or a new market for an existing client, makes the next one faster.

The trajectory

ELC is a global program. It doesn't need one storefront. It needs many. Different markets, different regions, different branding, different pricing rules, different currencies, different regulatory requirements. The modular architecture handles this natively: each market is a configured Shell with the same modules, different config values.

DeploymentWhat happensRelative effort
First ELC regionModules built alongside implementation. Shell, base, and optional modules configured for Global/NA/APAC.Highest: the investment
Second ELC marketModules exist. New Shell config (branding, currency, pricing rules). Market-specific catalog and rate card data loaded.Significantly reduced
Fifth ELC marketRefined process. Team knows the checklist. Shell config + data load.Routine
First non-ELC clientModules already work for a global multi-region program. New Shell, same modules, different config.Comparable to a new ELC market
Mature frameworkConfig-file deployment. CLI scaffolding. Build pipeline.30 days from contract to live

The effort curve:

Current model: ~18 weeks per client, independent effort each time
First ELC region
The investment
Second ELC market
Modules exist
Fifth ELC market
Routine
First non-ELC client
Same modules
Mature framework
30 days
The compounding starts within ELC, not after it. Each deployment makes the next one faster.
The compounding starts within ELC, not after it

The first ELC region is where the modules get built. Every subsequent ELC market reuses those modules. By the time the fifth ELC market launches, the team has a refined, repeatable process. The first non-ELC client benefits from everything ELC's program taught us. The trajectory is measurable: each deployment generates data that makes the formula more accurate and the number smaller.

Before and after

DimensionCurrent approachModular approach
Starting pointBlank slate per clientConfigured Shell + base modules = working storefront
ImplementationCustom development per engagementConfiguration from defined module fields
Effort modelLinear: each client is independentCompounding: each deployment makes the next faster
DiscoveryOpen-ended requirementsGuided module selection
AnalyticsNo instrumentationBaked into the base from day one
New market (same client)Nearly the same effort as a new clientShell config + market data
Product roadmapDriven by next SOWModule catalog: build once, deploy to all
RFP responseSlides and promisesWorking demo storefront configured to prospect needs
Timeline predictabilityEstimate that varies per clientFormula: Shell + base + optional modules + client data
TargetRoughly 18 weeks best case30 days at maturity

4. The strategic case

Seven reasons the modular architecture investment is justified.

Engine vs experience layer

The engineering team built the commerce engine: multi-ship, approvals, PO processing, inventory, the full B2B workflow. That engine works. What doesn't exist is a composable experience layer that can present that engine differently for different clients and markets. This project builds that layer. The engine doesn't change. The experience adapts.

Modular architecture

The experience layer starts with a Shell (the branded container) and is composed of modules that live inside it. Base modules are present in every storefront. Optional modules extend per client need. Each module is a self-contained capability with a defined configuration surface. Without this, the rest of the strategy is aspirational. With it, it's mechanically real.

Bespoke through configuration

To the client: "We built this for you." Internally: "We configured this for you." The client gets a tailored commerce experience: their brand, their catalog, their pricing, their approval workflows. They don't know it was assembled from modules. They experience a platform built for their business. Adding capabilities over time is enabling a module, not a new project.

Scale and predictability

Each client engagement builds modules that every subsequent client gets for free. Each ELC market builds process knowledge that the next market gets for free. The timeline becomes a formula, not an estimate. The formula improves with every deployment.

Innovation leverage

New capabilities get developed once and deployed to any client. AI-powered conversational search, smart reordering, visual search: each becomes a premium module that plugs into the Shell. Clients can add capabilities over time without a new SOW. The architecture supports bring-your-own-API-key patterns for AI capabilities.

Demo velocity

Tag maintains a pre-configured demo storefront with all modules active and demo products loaded. Going into an RFP, Tag configures the demo to match the prospect's needs and shows a working storefront, not slides. This collapses the pre-sales cycle and de-risks the implementation promise.

Product roadmap discipline

The product team's roadmap becomes the module catalog. "This quarter we're building the Print on Demand module and the Demand Capture module." Those aren't client-specific deliverables. They're product investments serving the entire portfolio. Bug fix once, deploy everywhere. Feature requests get evaluated as "does this become a config option or a new module?" The one-offs become visible exceptions rather than the default.

5. The architecture

The Shell

The Shell is the configured container that all modules live inside. It is not a module. The Shell provides branding (logo, colors, fonts, design tokens), layout zones (header, content area, footer), and application-level navigation (account menu: My Orders, Address Book, My Approvals, etc.). Active modules register their navigation links dynamically.

Each client market gets its own Shell configuration. ELC North America and ELC APAC share the same modules but have different Shell configs: different branding, different currency, potentially different layout preferences. The Shell is the first thing configured for each market.

Module tiers

Base package (every client, every market)

ModulePurpose
NavigationStructured browse paths: category, campaign collection, brand
CatalogProduct presentation, listings, filters, sort, compare, wishlist
PricingPrice display, regional context, tier pricing, currency
OrderingFull order lifecycle: cart, checkout, history, tracking, reorder, address book
SearchProduct search: keyword, autocomplete, results
AnalyticsEvent pipeline, instrumentation across all modules

Optional modules (per client)

ModulePurposeRegisters in Shell
Multi-ShipMulti-address checkout, CSV upload, address groupsAddress Lists
ApprovalBusiness justification, tier approval, delegationMy Approvals
Print on DemandProduct customization, proofing, templates (PrintXpand)My Print Jobs
BriefingCustom request submission, tracking, quote-to-orderMy Briefs
Demand CaptureBuying windows, availability, queue-for-next-windown/a

Platform modules (separate phase)

ModulePurpose
SSO / IdentityClient HR system, user assignment, approval routing
DAM IntegrationAPI pull from client DAM for product imagery
CAP SyncCommerce-to-CAP bidirectional pricing sync
Punch OutProcurement system integration

Integration patterns

One-way handoff: Module A passes control to Module B. Navigation leads to Catalog. Catalog leads to Ordering via Add to Cart.

Injection: Optional module injects UI into a base module's flow via defined hook points. Approval injects business justification into checkout. Print on Demand injects the Customize button onto the product detail page.

Registration: Module announces its presence to a container. Active modules register navigation links into the Shell. Approval registers an Approval History tab into order detail.

6. Current state: codebase coupling

The diagram below maps actual coupling between DI Commerce codebase modules. Color-coded tags on each module show the type of coupling: core class replacements (red), window globals (orange), DOM/JS coupling (yellow), shared state (blue), and logic duplication (gray). The two green-bordered modules on the right follow the clean module standard. Click any module for details.

Core coupling cluster
Checkout
33 files
DI prefglobalslocalStorageduplication
Multishipping
180 files
DI prefglobalsshared stateduplication
PurchaseOrder
437 files
8 DI prefscoupled triangle
PurchaseOrderItem
104 files
coupled to PO
Company
118 files
window.tabModecoupled triangle
Sales
145 files
duplication target
OutletCheckout
10 files
window globals
AddressListMgr
22 files
receives globals
Periphery
Catalog
71 files
direct helper call
ProductList
12 files
671-line AJAX
Stock
103 files
Manadev LayeredNav
Third-party
bidirectional DOM
Theme
334 files
40+ overrides
Theme Overrides
28+ dirs
hardcoded DOM
Clean module standard (target pattern)
AddressLookup
21 files
own config, own JS, no coupling
OutletValidation
15 files
own config, own JS, no coupling
cacheable="false" disables full-page cache on EVERY page menu.js: 885 lines, hardcoded DOM CSS: 4,404 lines in Magento_Customer alone
Core class replacement Window globals DOM/JS coupling Shared state Logic duplication Clean (target)

7. Full module catalog

Complete module breakdowns following the standard anatomy: purpose, ownership boundaries, configuration surface, API dependencies, module dependencies, current state, UX requirements, success criteria, and open questions. Click any module to expand.

NavigationBase

Purpose: The field rep finds products through structured browse paths that reflect how the client organizes their catalog. They can navigate by product category, by campaign collection, by brand, or by any other taxonomy the client defines. Navigation is the first thing the field rep interacts with after login.

Owns

  • Primary navigation structure (top nav, sidebar, mobile drawer)
  • Browse path definitions (category tree, campaign collections, brand listing)
  • Navigation hierarchy (parent/child, depth levels, flyout/sidebar)
  • Campaign collection browse (curated cross-category groupings)
  • Brand browse as alternative entry point
  • Breadcrumbs
  • Active state indicators
  • Mobile responsive navigation
  • Navigation-level analytics events

Does not own

Product display, filtering, sorting, pagination (Catalog). Search bar, autocomplete, results (Search). Price display (Pricing). Product visibility by customer group (engine via SSO/Identity). Application-level navigation like account menu (Shell).

Configuration surface

Browse paths

SettingTypeDefaultDescription
browse_pathsstructured["category"]Active browse paths: category, campaign_collection, brand, plus client-defined
browse_path_orderstructured["category","campaign_collection","brand"]Display order in navigation
default_browse_pathstring"category"Default browse path on landing

Hierarchy

SettingTypeDefaultDescription
max_depthnumber3Maximum navigation depth levels
navigation_styleenumflyoutSub-level presentation: flyout, sidebar, accordion
show_product_countbooleanfalseDisplay product count per category

Campaign collections

SettingTypeDefaultDescription
campaign_collections_enabledbooleanfalseWhether campaign collections appear as a browse path
campaign_collection_displayenumgridPresentation: grid, list, carousel
show_collection_datesbooleantrueDisplay campaign active dates

Brand browse

SettingTypeDefaultDescription
brand_browse_enabledbooleanfalseWhether brand is a browse path
brand_displayenumalphabeticalOrganization: alphabetical, grid, featured_first

Mobile

SettingTypeDefaultDescription
mobile_breakpointnumber768Pixel width for mobile nav activation
mobile_styleenumdrawerMobile presentation: drawer, overlay, accordion

API dependencies

Reads: Category tree with hierarchy, campaign collection definitions, brand listing with metadata, navigation state for active user.

Writes: None. Navigation is read-only from the frontend.

Events: browse_path_selected, navigation_depth, breadcrumb_click

Module dependencies

Required: Catalog (Navigation leads to product listings).

Integration points: Search (parallel discovery, layout positioning). Analytics (emits browse and hierarchy events).

Current state

Key components: menu.js (885 lines, full jQuery UI Menu replacement), theme.js (440 lines, header cloning and mobile drawer), navigation LESS (400+ lines), DiCommerce_Theme (body class toggles from admin config).

Coupling: Tightly coupled. menu.js assumes specific DOM hierarchy and hardcoded data attributes. theme.js clones elements by class name and hardcodes breakpoints. Cross-module dependency on DiCommerce_Catalog helper.

Estimate: ~80% rebuild. Hardcoded DOM assumptions and global JS coupling make existing components unsuitable for modular architecture. Preservable: responsive breakpoint concept, hierarchy data model, general UX patterns.

UX requirements

Key flows: Initial landing (default browse path active, current campaigns featured). Browse by category (subcategories reveal, breadcrumbs update). Browse by campaign collection (cross-cutting view across categories). Browse by brand. Switch between browse paths seamlessly. Mobile navigation (responsive drawer, all paths accessible).

Key states: Empty (no categories configured), Loading (skeleton nav), Populated (normal), Error (fallback to Search). Edge cases: category with no products, expired campaign collections, single brand, very deep hierarchy, very wide top level.

Benchmark: Vista Print navigation is clean and multi-path. Browse by product type, use case, or industry. Subcategories use flyout with visual icons. Mobile collapses to drawer. Target: find any product within 3 clicks from homepage.

Success criteria

Functional: All browse paths render correctly. Hierarchy matches config. Mobile fully functional. Breadcrumbs accurate. Path switching preserves context.

Adoption: Browse path distribution (category vs campaign vs brand). Navigation depth (target: 3 or fewer clicks to products). Mobile completion rate. Breadcrumb usage frequency.

Open questions

  • Does this config surface cover all navigation scenarios across the client portfolio?
  • How are campaign collections managed? Admin, synced from external, or client config?
  • Are there clients needing custom taxonomies beyond category, campaign, and brand?
  • Should navigation be personalized beyond region?
  • How should expired campaign collections be handled?
  • What happens when a category has zero products?
CatalogBase

Purpose: The field rep sees products presented clearly with the information they need to make a decision: images, descriptions, specifications, availability, labels. They can view listings, compare products, save to wishlist, filter, sort, and drill into detail.

Owns

  • Product listing pages (PLP): grid/list layout, product cards
  • Product detail pages (PDP): images, description, specs, qty selector, add-to-cart
  • Product card content: name, SKU, image, availability, labels
  • Product labels/badges ("New", "Limited", "Seasonal")
  • Filters and faceted navigation
  • Sort controls
  • Pagination
  • Compare (side-by-side attribute comparison)
  • Wishlist (save for later)
  • Campaign collection definitions as data
  • Product type presentation (fixed SKU vs customizable)
  • Availability display
  • Product images (gallery, zoom)

Does not own

How the field rep arrives (Navigation or Search). Price display (Pricing). Cart/checkout/ordering (Ordering). Requisition lists (Ordering). Print on Demand UI on customizable PDPs (Print on Demand). Product data import or admin (engine). Product visibility by customer group (engine via SSO/Identity).

Configuration surface

Product listing

SettingTypeDefaultDescription
default_viewenumgridDefault listing layout: grid or list
allow_view_togglebooleantrueField rep can switch views
products_per_pagenumber24Products per page
show_skubooleantrueSKU displayed on cards
show_availabilitybooleantrueStock indicators shown

Product detail

SettingTypeDefaultDescription
image_gallery_enabledbooleantrueProduct image gallery on PDP
image_zoom_enabledbooleantrueZoom on product images
show_related_productsbooleanfalseRelated products on PDP
qty_selector_styleenuminputQuantity selector: input, stepper, dropdown

Filters

SettingTypeDefaultDescription
filterable_attributesstructured[]Which attributes appear as filters
filter_positionenumsidebarWhere filters render: sidebar, top, drawer
show_active_filtersbooleantrueActive filter chips above results

Compare and wishlist

SettingTypeDefaultDescription
compare_enabledbooleantrueProduct comparison available
compare_max_itemsnumber4Max products in a comparison
wishlist_enabledbooleantrueWishlist functionality

Labels and collections

SettingTypeDefaultDescription
labels_enabledbooleantrueProduct label badges displayed
campaign_collections_enabledbooleanfalseCampaign collection groupings active

API dependencies

Reads: Product listing data (paginated, with attributes/images/availability/labels), product detail data (full record), filterable attribute definitions, campaign collection data, compare data, wishlist data.

Writes: Add/remove from compare, add/remove from wishlist, filter/sort state.

Events: product_viewed, product_listed, compare_initiated, wishlist_add/remove, filter_applied/removed, sort_changed

Module dependencies

Required: None (technically standalone, but always runs with Navigation, Search, Pricing).

Integration points: Navigation (passes category/collection/brand, Catalog renders listing). Search (passes query/results, Catalog renders). Pricing (renders prices within cards/PDP). Ordering ("Add to Cart" bridges to Ordering). Print on Demand (injects "Customize" on customizable PDPs). Analytics (emits product/filter/sort events).

Current state

Key components: DiCommerce_Catalog (71 files), DiCommerce_ProductList (12 files, AJAX refresh), DiCommerce_ProductLabel (10 files), DiCommerce_CustomerProductGroup (15 files, visibility by customer group), Manadev_LayeredNavigation (third-party, 4 sub-modules), DiCommerce_Stock (103 files, real-time stock display).

Coupling: High coupling between ProductList AJAX and Manadev. product-list-ajax.js (671 lines) depends on Manadev DOM selectors bidirectionally. list.phtml calls helpers directly. Stock reinitializes after every AJAX refresh.

Estimate: ~50% rebuild. Backend module structure is reasonable. Frontend glue (AJAX orchestrator, Manadev coupling, direct helper calls) needs rebuilding as clean scoped components.

UX requirements

Key flows: Browse a listing (grid/list, cards with key info). Filter products (instant, no full reload, active filter chips). View product detail (gallery, specs, qty, price, add-to-cart). Compare products (2-4 side by side). Save to wishlist. View campaign collection (cross-category listing).

Key states: Empty listing (meaningful message, alternative browse paths). Loading (skeleton cards). Populated (normal). Error (retry option). Edge cases: single product, no image (placeholder), long name (truncation), single filter option, all out of stock.

Benchmark: Vista Print listings are clean and information-dense without clutter. Cards show image, name, starting price, quick-select. Filtering is fast, no page reload. Target: evaluate a product in under 10 seconds from the card, find any spec on PDP within one scroll.

Success criteria

Functional: Listings render for all browse paths. Filters apply instantly. Compare aligns attributes. Wishlist persists across sessions. Labels display based on conditions. Collections show products regardless of category.

Adoption: Filter usage rate. Compare usage. Wishlist-to-cart conversion. Average time on PDP. Products viewed per session before cart.

Open questions

  • What product attributes are commonly filterable? Does this vary by client?
  • Should Manadev LayeredNavigation be replaced with native Magento?
  • How do campaign collections get created/managed?
  • Are there product types beyond fixed SKU and customizable?
  • How should out-of-stock products display?
PricingBase

Purpose: The field rep sees prices relevant to them: their region, their quantity breaks, their currency. They never see prices for regions or tiers that don't apply. The price displayed reflects exactly what they'll pay based on who they are and how much they're ordering.

Owns

  • Price display on PLP and PDP
  • Tier pricing presentation (quantity break tables)
  • Regional price resolution
  • Currency display formatting
  • Special/promotional price display
  • Price display in cart and order summaries
  • Tax display rules

Does not own

Product organization or display (Catalog). Cart/checkout/ordering (Ordering). Backend price calculation (engine). Region/group assignment (SSO/Identity). Price ingestion (CAP Sync). Approval thresholds (Approval). Shipping cost calculation (Ordering/Multi-Ship).

Configuration surface

Regional settings

SettingTypeDefaultDescription
regional_pricing_enabledbooleantruePrices vary by region
regionsstructured[]Region definitions (ID, name, currency)
show_region_labelbooleanfalseDisplay region name alongside prices

Tier display

SettingTypeDefaultDescription
tier_pricing_enabledbooleantrueQuantity break pricing shown
tier_display_formatenumtablePresentation: table, inline, progressive
tier_countnumber10Maximum pricing tiers
show_savingsbooleantrueShow "you save X%" at higher tiers

Currency and tax

SettingTypeDefaultDescription
currency_codestringUSDISO 4217 currency code
symbol_positionenumbeforeSymbol placement: before or after
tax_display_modeenumexcludingHow tax is shown: including, excluding, both

Visibility

SettingTypeDefaultDescription
require_login_for_pricesbooleantruePrices hidden until authenticated
no_price_messagestring"Login to see pricing"Message when prices hidden

API dependencies

Reads: Product price data by customer group/region (resolved price with tiers, specials, tax). Customer group/region assignment. Tax rules.

Writes: None. Display-only from frontend.

Events: Price change notifications (low priority, for long sessions).

Module dependencies

Required: Catalog (prices attach to products).

Integration points: Ordering (consumes resolved prices for cart/checkout). Multi-Ship (per-address tax display). Analytics (pricing events).

Current state

Key components: DiCommerce_ConfigurableProduct (tax class fix), DiCommerce_Checkout (special price in minicart), DiCommerce_PurchaseOrder (totals excluding rejected items), DiCommerce_Multishipping (currency conversion fix).

Coupling: Low coupling. Cleanest area in the codebase. All pricing delegates to core Magento. Four plugins are small, targeted, independent.

Estimate: ~90% preserve. Backend logic carries forward as-is. Frontend display components are simple renders of price data.

UX requirements

Key flows: Browse with prices (each product shows base price for region, promotional prices with strikethrough). View tier pricing (quantity breaks on PDP, active tier highlights as qty changes). Cart pricing (resolved per-unit price, line totals, subtotal, tax per config).

Key states: Loading (placeholder, no layout shift). Populated (normal). Error (show no_price_message, not $0). Edge cases: no tier pricing, expired special price mid-session, product visible but unavailable in region.

Benchmark: Vista Print shows prices clearly at every touchpoint. Tier pricing as simple quantity-price table with current tier highlighted. Target: the field rep should never wonder "what's my price for this?"

Success criteria

Functional: Displayed prices match backend 100%. Regional isolation complete. Tier pricing updates dynamically. Tax display correct across all touchpoints.

Adoption: Pricing clarity in surveys. Support tickets related to pricing confusion decrease. Tier pricing engagement (orders above minimum tier).

Open questions

  • Are there pricing models beyond regional + tier? Volume discounts, contract, negotiated?
  • How does tax display work across regions?
  • Multiple simultaneous price points ("your price" vs "list price")?
  • How are price changes communicated mid-campaign?
OrderingBase

Purpose: The field rep places orders and manages them through their full lifecycle: cart, checkout, confirmation, tracking, history, reorder, cancellation. They maintain an address book of outlet locations and requisition lists for repeat purchasing.

Owns

  • Cart (minicart, full cart, line items, totals)
  • Checkout flow (base: address > shipping > payment > review > place)
  • Checkout extensibility (hook points for optional modules)
  • Order confirmation
  • Order history (filtering, sorting, pagination)
  • Master order view (multi-ship grouping)
  • Company orders view
  • Order detail (tabbed, extensible by optional modules)
  • Shipment tracking
  • Reorder from history
  • Order cancellation
  • Requisition lists
  • Address book (browse, search, add, edit, delete, outlet validation)
  • Address lookup (REST API)
  • Outlet validation (configurable rules)
  • Custom address fields

Does not own

Product browsing/display (Catalog). Product search (Search). Price display (Pricing). Wishlist (Catalog). Business justification (Approval injects). Multi-address checkout, CSV upload, address groups (Multi-Ship extends). Approval workflows (Approval). Print on Demand design data (Print on Demand attaches). Async PO queue processing (engine). Payment gateway integration (engine).

Configuration surface

Cart

SettingTypeDefaultDescription
minicart_enabledbooleantrueMinicart in Shell header
minicart_max_items_displaynumber5Max items shown before "View Cart"
allow_qty_edit_in_cartbooleantrueQuantities adjustable on cart page

Checkout

SettingTypeDefaultDescription
checkout_stepsstructured["shipping","payment","review"]Steps in order. Optional modules register additional steps via hooks.
guest_checkout_enabledbooleanfalseCheckout without auth (B2B almost always no)
order_comment_enabledbooleanfalseField rep can add order comment

Outlet address

SettingTypeDefaultDescription
outlet_address_enabledbooleantrueOutlet address search/selection in checkout
outlet_validation_enabledbooleanfalseValidation rules active
outlet_validation_numeric_onlybooleanfalseRestrict outlet number to numeric

Address book

SettingTypeDefaultDescription
address_book_enabledbooleantrueAddress book management page available
allow_field_rep_add_addressbooleantrueField reps can add addresses
allow_field_rep_edit_addressbooleantrueField reps can edit addresses
allow_field_rep_delete_addressbooleanfalseTypically admin-only

Order history

SettingTypeDefaultDescription
orders_per_pagenumber20Orders per page in history
show_master_order_viewbooleantrueMulti-ship grouped under master
show_company_ordersbooleanfalseSee other company members' orders

Order detail and actions

SettingTypeDefaultDescription
detail_tabsstructured["items","shipments","info"]Tabs on detail page. Optional modules can register additional tabs.
show_reorder_buttonbooleantrueReorder from past orders
cancellation_enabledbooleantrueOrder cancellation available
requisition_lists_enabledbooleantrueSaved product lists for repeat ordering

API dependencies

Reads: Cart data, checkout config, outlet address search results, order history, master order data, company orders, order detail, shipment tracking, requisition lists, address book data, validation results.

Writes: Cart ops (add/update/remove), place order, outlet address selection, cancel order, requisition list ops, reorder, address book ops (add/edit/delete with validation).

Events: add_to_cart, cart_viewed, checkout_started, checkout_step_completed, order_placed, order_viewed, order_cancelled, reorder_initiated, requisition_list_created/ordered, shipment_tracked, address_added/edited/deleted, address_validated

Module dependencies

Required: Catalog (products to add to cart). Pricing (resolved prices for totals).

Integration points: Approval (injects business justification via hooks, registers Approval History tab). Multi-Ship (transforms checkout into multi-address flow). Print on Demand (attaches design data to line items). Analytics (emits all ordering events). Shell (registers My Orders, Address Book, Requisition Lists).

Current state

Key components: DiCommerce_Checkout (33 files), DiCommerce_OutletCheckout (10 files, 800+ line address popup), DiCommerce_AddressLookup (21 files, clean REST API client), DiCommerce_AddressListManager (22 files, address CRUD), DiCommerce_OutletValidation (15 files, clean validation rules), DiCommerce_Sales (145 files, master order view, company orders, shipment tracking), DiCommerce_OrderHistorySearch (14 files), DiCommerce_RequisitionList (10 files). Theme: 40+ checkout override files.

Coupling: Very high in checkout: 7+ feature flags across 3 ConfigProviders, window globals, localStorage state sharing, 6+ RequireJS mixins. Business justification duplicated between Checkout and Multishipping (moves to Approval). Address popup coupled via window globals. Sales module is monolithic but less coupled.

Bright spots: AddressLookup is a clean REST API client. OutletValidation follows the target module pattern. RequisitionList is thin and focused.

Estimate: ~65% rebuild. Checkout overrides and Sales expansion are the bulk. AddressLookup and OutletValidation preserve as-is.

UX requirements

Key flows: Add to cart (minicart updates in Shell). View cart (editable quantities, design thumbnails if Print on Demand active). Base checkout (address > shipping > payment > review > place). Checkout variations compose: Multi-Ship replaces, Approval injects, Print on Demand attaches. Confirmation. Order history (filter, sort, master order grouping). Order detail (tabbed, extensible). Shipment tracking. Reorder. Requisition lists (create, manage, order from). Address book management (CRUD with outlet validation). Cancellation.

Key states: Cart empty/populated. Checkout loading/in-progress/error. Order placed. History empty/populated. Tracking unavailable. Reorder with unavailable items. Edge cases: 100+ item cart, 50+ shipments in master view, checkout timeout.

Benchmark: Vista Print checkout is streamlined with minimal steps. Order history clean with obvious filtering. Reorder is one click. Target: routine order in under 3 minutes. "Where is my stuff?" answered in under 10 seconds.

Success criteria

Functional: Add to cart works from PLP/PDP. Checkout completes through all steps. Hook points work (optional module steps inject when active, absent when not). Order history accurate. Master order view correct. Tracking accurate. Reorder handles unavailable items. Requisition lists persist. Cancellation updates status. Address book CRUD with validation.

Adoption: Cart-to-checkout conversion. Checkout completion rate. Average checkout time (target: under 3 minutes). Requisition list usage. Reorder rate. History search usage. Tracking engagement.

Open questions

  • How does the checkout hook mechanism work technically in Phase 1?
  • What payment methods are supported?
  • Should requisition lists support scheduled reorder?
  • What determines cancellation eligibility?
  • How do checkout variations compose when multiple optional modules are active?
  • Should order detail tabs be extensible by optional modules?
SearchBase

Purpose: The field rep types what they're looking for and gets results. Search is the unstructured counterpart to Navigation's structured browse paths. When the field rep knows what they want but doesn't know where it lives in the category tree, Search gets them there directly.

Owns

  • Search bar (input field, placement, focus behavior)
  • Autocomplete/typeahead (product and category suggestions)
  • Search results page
  • Search query handling (min characters, debounce)
  • Recent searches
  • "Did you mean" / spelling correction
  • Search-level analytics events

Does not own

How products display in results (Catalog renders cards, filters, sort). Structured browse paths (Navigation). Search engine configuration (engine/OpenSearch). Price display (Pricing). Application navigation (Shell).

Configuration surface

SettingTypeDefaultDescription
search_bar_positionenumheaderWhere search renders: header, nav_inline, below_nav
min_charactersnumber3Characters before search triggers
debounce_msnumber300Delay after typing before querying
autocomplete_enabledbooleantrueTypeahead suggestions
autocomplete_max_resultsnumber5Max suggestions
results_per_pagenumber24Products per page on results
show_did_you_meanbooleantrueSpelling correction suggestions
recent_searches_enabledbooleantrueRecent search history shown

API dependencies

Reads: Search results (product data with relevance ranking), autocomplete suggestions, spelling corrections.

Writes: Search query submission, recent search history (may be client-side).

Events: search_submitted, search_autocomplete_selected, search_zero_results (critical for catalog gap identification), search_result_clicked

Module dependencies

Required: Catalog (renders product cards in search results).

Integration points: Navigation (parallel discovery, layout coordination via Shell). Pricing (prices in autocomplete and results). Analytics (search events, zero-result tracking).

Current state

Key components: Manadev_LayeredNavigation (search integrated with layered nav), DiCommerce_ProductList (AJAX search results via same orchestrator as category pages), theme search templates and form-mini-mixin.

Coupling: Coupled to Manadev through shared ProductList AJAX mechanism. No standalone search component exists.

Estimate: ~60% rebuild. Search input is simple and preservable. Results rendering is entangled with ProductList/Manadev coupling. Backend OpenSearch integration stays as-is.

UX requirements

Key flows: Quick search (type, autocomplete, click suggestion or submit). Full results (Catalog listing components). Zero results (helpful message, suggestions, recent searches). Recent searches on focus.

Benchmark: Vista Print search is fast and forgiving. Autocomplete shows products with images immediately. Typos corrected. Target: find what you're looking for in one attempt 90%+ of the time.

Success criteria

Functional: Relevant results for names, SKUs, descriptions, attributes. Autocomplete within debounce window. Zero-result pages offer paths forward. Works across devices. Spelling correction activates.

Adoption: Search vs browse ratio. Zero-result rate. Autocomplete click-through rate. Search-to-cart rate.

Open questions

  • Should search support searching within a category or brand?
  • What search engine long-term? Native OpenSearch or dedicated service?
  • What does the AI-powered search premium module look like?
AnalyticsBase

Purpose: Every interaction is tracked, measured, and available for analysis. The field rep doesn't see or interact with Analytics directly. It operates silently behind every other module, providing the event pipeline that all modules emit into.

Owns

  • Event pipeline (mechanism for all modules to emit events)
  • Event schema (standardized format)
  • Provider integration (GA4, Adobe Analytics, or other)
  • Consent management (opt-in/opt-out per legal requirements)
  • Page-level tracking (views, session, device)
  • Event forwarding to analytics destinations
  • Analytics admin config

Does not own

What events get emitted (each module defines its own). Reporting dashboards (analytics platform). Business intelligence (out of scope). User identity resolution (SSO/Identity).

Configuration surface

SettingTypeDefaultDescription
providerenumgoogle_analyticsPlatform: google_analytics, adobe_analytics, custom
tracking_idstringnullProvider tracking/measurement ID
consent_requiredbooleanfalseUser consent required before tracking
consent_modeenumopt_outConsent: opt_in (track after consent) or opt_out (track until declined)
track_page_viewsbooleantrueBasic page view tracking
debug_modebooleanfalseEvents logged to console
event_batchingbooleantrueBatch events before sending
batch_interval_msnumber2000Milliseconds between batch sends

API dependencies

Reads: User context (region, role, customer group from session).

Writes: Event dispatch to configured provider (client-side).

Events: Analytics doesn't emit events. It receives them. All other modules emit into the pipeline.

Module dependencies

Required: None. Provides the pipeline; other modules emit into it.

Integration points: Every module. Navigation (browse events), Catalog (product/filter events), Pricing (price events), Ordering (cart/checkout/order events), Search (query/zero-result events). Optional modules emit their own events when active.

Current state

Key components: Does not exist. CSP whitelist includes GA and Adobe DTM domains, but no actual event tracking implementation exists. No analytics JS, no data layer, no tag manager integration.

Estimate: 100% net-new.

UX requirements

No direct user-facing flows. Technical flow: page loads, Analytics initializes, checks consent, begins capturing, listens for module events, batches, dispatches. Analytics failures must never affect storefront functionality.

Benchmark: Operational: every client instrumented from day one, data flowing within 24 hours, success criteria for all modules have data within the first week.

Success criteria

Functional: Loads on every page under 50ms. Events from all modules captured and dispatched. Consent management works correctly. Failures never block storefront. Schema consistent across all modules.

Adoption: Measured indirectly. Success = are the criteria for all other modules measurable? Data completeness. Time to data. Event coverage.

Open questions

  • Which providers supported? GA4, Adobe Analytics, both?
  • What consent management approach?
  • Event naming convention standardization?
  • Privacy/legal requirements per region?
Multi-ShipOptional

Purpose: The field rep ships one order to multiple outlet locations: 10, 50, 200+ stores in a single checkout. They select outlets from the address book or upload via CSV, assign items to each address, and submit a single master order split into individual shipments per location.

Owns

  • Multi-ship checkout variation (replaces single-address checkout)
  • Multi-address selection (DataTables grid, search, sort, filter)
  • CSV/XLSX address upload (parse, validate, add to address book)
  • Per-address item assignment (default all-to-all, override per address)
  • Master order creation (single order grouping all shipments)
  • Address group management (save/load groups for repeat orders)
  • Address autocomplete (ShipperHQ, coded but not activated)
  • Multi-ship progress indicator

Does not own

Address book itself (browse, search, CRUD, validation) belongs to Ordering. Address lookup API (Ordering). Outlet validation rules (Ordering). Base checkout flow (Ordering). Master order display in history (Ordering displays; Multi-Ship creates). Business justification (Approval injects). Async PO queue processing (engine). Admin address pre-loading (engine). Price display (Pricing).

Configuration surface

Checkout

SettingTypeDefaultDescription
multi_ship_enabledbooleanfalseReplaces single-address checkout when on
max_addressesnumber500Max ship-to addresses per order
default_assignmentenumall_to_allDefault: all_to_all or manual

Address selection grid

SettingTypeDefaultDescription
grid_page_sizenumber100Addresses per page
grid_searchablebooleantrueSearch in address grid
show_select_allbooleantrue"Select All" available
show_region_filterbooleantrueFilter by region/state

CSV upload

SettingTypeDefaultDescription
csv_upload_enabledbooleantrueCSV/XLSX upload available
csv_max_rowsnumber5000Max rows in upload
csv_template_downloadbooleantrueDownloadable CSV template

Address groups and processing

SettingTypeDefaultDescription
address_groups_enabledbooleantrueSaved address groups
async_processingbooleantrueAsync PO creation
batch_sizenumber20Addresses per batch

API dependencies

Reads: Address book data (from Ordering), address group data, shipping methods per address.

Writes: CSV address import, save address group, place master order, per-address item assignment.

Events: multiship_started, multiship_addresses_selected, multiship_csv_uploaded, multiship_address_group_used, multiship_assignment_changed, multiship_order_placed

Module dependencies

Required: Ordering (checkout variation, address book, cart, order infrastructure). Catalog (products). Pricing (per-address totals).

Integration points: Approval (business justification injects into multi-ship flow). Print on Demand (design data replication per address). Analytics (multi-ship events). Shell (registers "Address Lists").

Current state

Key components: DiCommerce_Multishipping (180 files, largest frontend footprint). 14 PHTML templates, 25 JS files, 11 controllers. DataTables address grid, CSV upload with bundled xlsx.js, business justification (duplicated, moves to Approval), shipping/overview mixins, address autocomplete (ShipperHQ, coded not activated). Replaces core Magento class via DI preference (highest-risk coupling). 8 async PO queue consumers.

Coupling: Hardest area. Bidirectional coupling with PurchaseOrder. Core class replacement creates upgrade risk. Business justification duplicated. localStorage caching. DataTables and xlsx bundled directly.

Estimate: ~75% rebuild. CSV upload and DataTables concept preservable. DI preference, business justification duplication, global coupling all need rebuilding.

UX requirements

Key flows: Initiate multi-ship (progress bar shows steps). Select addresses from book (DataTables grid with search/sort/filter, select all, selection count). Select from saved group (pre-select group addresses). CSV upload (parse, validate, summary of valid/invalid). Assign items (default all-to-all, override per address). Business justification (Approval injects). Review (summary stats + scrollable detail). Place master order (async PO creation). Track (master order in history, per-address shipment status). Manage address groups.

Key states: Address selection (empty/loading/populated/selected). CSV (processing/complete/failed). Assignment (default/custom). Review (summary). Processing (async). Error at each step.

Benchmark: Vista Print multi-recipient flows. Clean address management, fast bulk selection, scannable review. Target: 200-address order in under 10 minutes. Default all-to-all under 5 minutes.

Success criteria

Functional: Completes for 1-500 addresses. CSV parses and validates correctly. Assignment works for both default and custom. Master order groups correctly and triggers async PO. Address groups persist. Grid performant at 500 addresses. Composes with Approval and Print on Demand.

Effectiveness: Average checkout time (target: under 10 min for 200 addresses). CSV vs manual selection ratio. Address group reuse rate. Assignment override rate. Abandonment by step. CSV error rate. Addresses per order distribution.

Open questions

  • Ideal address selection UX for 200+ addresses? Map-based, tree/hierarchy, search-first?
  • Per-address item assignment at scale: exceptions-based or explicit?
  • Should CSV support address updates (upsert) or only adding new?
  • How do address groups relate to org structure?
  • DI preference on core Magento class: Phase 1 resolution strategy?
  • Should review include "download summary" for 200+ addresses?
ApprovalOptional

Purpose: Orders above a configured threshold require approval before fulfillment. The requester provides business justification during checkout. The approver reviews, approves or rejects at order or item level, and can delegate. Rejected orders can be revised and resubmitted.

Owns

  • Business justification injection (single source, injects into both base and Multi-Ship checkout)
  • Approval routing (consumes HR mapping from SSO/Identity)
  • My Approvals dashboard (approver queue)
  • Order-level approve/reject
  • Item-level approve/reject with mass actions
  • Tier-based sequential approval (Tier 1 before Tier 2)
  • Rejection with required reason + resubmission
  • Delegation (temporary transfer of authority)
  • Auto-rejection (configurable timeout via cron)
  • Approval status visibility (requester sees tier, approver, time pending)
  • Approval history (audit trail, registers as tab in order detail)
  • Notifications (pending, approved, rejected, delegation expiry)

Does not own

Checkout flow (Ordering provides hooks). Multi-ship flow (Multi-Ship). Cart/order placement/history/detail layout (Ordering). PO creation (engine). Master order grouping (Ordering displays, Multi-Ship creates). Approver assignment and org hierarchy (SSO/Identity from HR system). Price display (Pricing).

Configuration surface

Approval rules

SettingTypeDefaultDescription
approval_enabledbooleanfalseApproval workflow active
approval_tiersstructured[]Tier definitions: threshold + approval level. Sequential.
auto_approve_belownumber0Orders below this value auto-approved
item_level_approval_enabledbooleanfalseApprove/reject individual items

Business justification

SettingTypeDefaultDescription
justification_requiredbooleantrueJustification required during checkout
justification_formatenumbothFormat: predefined, freeform, both
justification_categoriesstructured[]Predefined categories (e.g., Seasonal campaign, New store)
justification_file_uploadbooleanfalseSupporting document attachments

Rejection, delegation, auto-rejection

SettingTypeDefaultDescription
resubmission_enabledbooleantrueRevise and resubmit rejected orders
rejection_comment_requiredbooleantrueApprover must provide rejection reason
delegation_enabledbooleantrueApprovers can delegate authority
delegation_max_duration_daysnumber30Maximum delegation duration
auto_rejection_enabledbooleanfalseAuto-reject after timeout
auto_rejection_daysnumber14Days before auto-rejection

API dependencies

Reads: Pending approvals, approval history, approval rules, approver assignment (from HR via SSO/Identity), delegation status, order data.

Writes: Approve/reject order, approve/reject items, resubmit, create/revoke delegation, submit business justification.

Events: approval_required, order_approved, order_rejected, order_resubmitted, item_approved/rejected, delegation_created/expired, justification_submitted, auto_rejection_triggered, approval_time

Module dependencies

Required: Ordering (injects into checkout, manages approval status on orders).

Integration points: Multi-Ship (justification injects into multi-ship flow; master order approved as a whole). Ordering (Approval History tab in order detail). Print on Demand (design thumbnails visible in approval review). Analytics (approval events). Shell (registers "My Approvals"). SSO/Identity (provides approver mapping).

Current state

Key components: DiCommerce_PurchaseOrder (437 files, 8 core Magento PO classes replaced via DI preferences, 49 templates, 15 layouts, 3 UI components). DiCommerce_PurchaseOrderItem (104 files, item-level grid with mass actions). DiCommerce_PurchaseOrderRule (24 files, thin rule extension). DiCommerce_Company (118 files, approval-related: tier config, role mappings, delegation system). Business justification duplicated between Checkout and Multishipping.

Coupling: High coupling in PO/Multi-Ship/Company triangle. 8 DI preference class replacements (high upgrade risk). Business justification duplicated (consolidates here). Role name string coupling is fragile.

Bright spots: PoDraft is standalone. PurchaseOrderRule is thin. Delegation system is self-contained. ViewModel pattern (RoleInfo, ApprovalProducts) is clean.

Estimate: ~60% rebuild. DI preferences need plugin-based replacement. Business justification consolidates. Delegation preservable. UI component grids need scoping. Role name coupling replaced with HR-based assignment.

UX requirements

Requester flows: Business justification during checkout (categories + text + files). Order pending approval (status with tier, approver, time). Order approved (notification, status update). Order rejected (notification with reason, "Revise and Resubmit" visible). Revise and resubmit (modify and resubmit, full audit trail). Track approval status in history.

Approver flows: My Approvals dashboard (pending orders, filterable, urgent highlighted). Review order (full details + justification + attachments; master orders for Multi-Ship). Approve (with optional comment). Reject (with required reason). Item-level approve/reject with mass actions. Delegate authority (date range, expiry warning). Manage delegations.

Benchmark: Approver should review and act in under 2 minutes. Requester should always know where their order is and why it was rejected. Revise-and-resubmit should be as fast as modifying a cart.

Success criteria

Functional: Justification injects correctly into both checkout flows. Orders route to correct approver. Actions update status and trigger notifications. Rejection reason visible. Resubmit works. Item-level handles partial approval. Delegation works with expiry. Auto-rejection triggers. Composes with Multi-Ship.

Effectiveness: Average approval time (target: under 24 hours). Rejection rate. Resubmission rate (healthy = flow works). Auto-rejection rate (high = approvers not reviewing). Item-level usage. Delegation usage. Queue depth per approver.

Open questions

  • On resubmission, does approval start from Tier 1 or resume at rejecting tier?
  • What predefined justification categories are needed?
  • How does HR integration provide approver mapping? Periodic sync or real-time lookup?
  • What about partially approved items in multi-ship master orders?
  • Phase 1 resolution for the 8 DI preference class replacements?
Print on DemandOptional

Purpose: The field rep customizes products with their own artwork: uploading designs, placing them on templates, previewing what the finished product looks like with fold lines/bleed/safe zones, and proofing before ordering. Powered by PrintXpand integration.

PrintXpand contract confirmed (signed February 2026)

The contract confirms B2B template governance (per-customer and per-customer-group assignment), brand compliance validation (node-level locking, DPI validation, prevention of unauthorized modifications), SVG-to-PDF rendering up to 240x22" at 300 DPI, and S3 delivery of production files.

Owns

  • Product designer experience (powered by PrintXpand)
  • Template library (per product, with design zones, bleed, fold, safe)
  • Interactive viewer (2D/3D, fold lines, bleed zones, safe zones)
  • Artwork upload (drag-drop, file validation)
  • Design tools (text, color, shapes, clipart, constrained to brand palette/fonts)
  • Proofing flow (high-res preview, approve/reject before cart)
  • Dynamic pricing (per-element, live updates during design)
  • Print on Demand status tracking and My Print Jobs
  • "Customize" button injection on PDP
  • Design data in cart/checkout (via PrintXpand observers)
  • Production-ready output (PDF/PNG at 300 DPI, CMYK)

Does not own

PDP layout (Catalog). Cart/checkout/order lifecycle (Ordering). Base pricing (Pricing). Template creation (PrintXpand admin). DAM for artwork assets (platform module). Production fulfillment (engine).

Configuration surface

Templates and tools

SettingTypeDefaultDescription
enable_product_designerbooleanfalsePer-product toggle for "Customize" button
template_library_enabledbooleantruePre-designed templates available
text_tool_enabledbooleantrueText placement
clipart_enabledbooleantrueClipart library
image_upload_enabledbooleantrueArtwork file upload
brand_color_palettestructured[]Brand-approved colors (restricts available palette)
font_librarystructured[]Available fonts (Google Fonts + custom .ttf)

Viewer

SettingTypeDefaultDescription
show_fold_linesbooleantrueFold line overlays
show_bleed_zonebooleantrueBleed area highlighting
show_safe_zonebooleantrueSafe zone highlighting
enable_3d_previewbooleanfalse3D rotatable preview (requires model)

Proofing and pricing

SettingTypeDefaultDescription
proofing_requiredbooleantrueProof approval required before ordering
max_proofing_roundsnumber2Max proof iterations
auto_approve_reordersbooleanfalseReorders of approved artwork skip proofing
dynamic_pricing_enabledbooleanfalsePrice adjusts based on customization
allow_artwork_reusebooleantrueReuse previously approved designs

API dependencies

Reads: Template library (from PrintXpand), submission data and statuses, production status, past artwork for reuse.

Writes: Upload artwork, save design, submit for proofing, approve/reject proof.

Events: artwork_uploaded, template_selected, viewer_interaction, proof_submitted, proof_approved, proof_rejected, artwork_reused, design_completed

Module dependencies

Required: Catalog ("Customize" injects into PDP). Ordering (design data flows into cart/checkout).

Integration points: Pricing (base price + customization surcharge = total, two layers). Approval (proofing is pre-cart, business justification is post-cart, no conflict). Multi-Ship (design data must replicate per address). Analytics (design events). Shell (registers "My Print Jobs").

Current state

Key components: Does not exist in current codebase. PrintXpand integration is being built by the engineering team. The work has not landed in staging yet.

What PrintXpand provides (~80%): HTML5 canvas editor, admin template management, SVG-based design zones, bleed/cut/safe lines, design tools (text, images, clipart, shapes), per-element dynamic pricing, 2D/3D preview, print-ready output (PDF/PNG/CF2/DDES/DXF, CMYK), cart integration via Magento observers, full-screen editing, multi-language, printable color restrictions.

What we build around it (~20%): Shell registration (My Print Jobs), analytics event emission, proofing workflow verification, B2B template governance verification (contract confirms it's in scope), multi-ship design replication, checkout flow integration testing, CSP whitelisting, production routing.

UX requirements

Key flows: Select customizable product (PDP shows "Customize"). Enter designer (PrintXpand editor, template selection). Upload artwork (drag-drop, validation). Interactive preview (fold/bleed/safe overlays, zoom, rotate, 3D). Design tools (text, colors, clipart constrained to brand). Dynamic pricing (live updates). Submit for proofing (high-res preview). Add to cart (design thumbnail on line item). Track status (My Print Jobs). Reuse artwork on new orders.

Key states: No customizable products (dormant). Designer loading. Template selection. Upload in progress/failed. Design active. Proofing in progress/ready/rejected/approved. In production. Error.

Benchmark: Vista Print. Interactive template viewer with fold/bleed/safe, live preview, zoom/rotate, 3D, clear proofing. Target: upload, preview, proof in under 5 minutes. Never wonder "will this look right?"

Success criteria

Functional: Editor loads reliably. Upload validates correctly. Viewer renders accurately with fold/bleed/safe. Proofing matches final output. Design data flows through cart/checkout/multi-ship. Production files generated with CMYK accuracy. Dynamic pricing correct.

Adoption: Customization completion rate (click "Customize" to cart). Proof approval rate by round. Artwork reuse rate. Time to completion (target: under 5 min upload, under 10 min design tools). Upload failure rate. Design tool engagement.

Open questions

  • PrintXpand integration status: what's built, what's remaining?
  • Magento 2.4.8-p3 compatibility verified?
  • How does design data attach to cart items? Critical for multi-ship replication.
  • Does PrintXpand proofing meet the pre-order approval requirement?
  • Per-customer-group template restrictions needed?
  • Production routing pipeline: manual download or automated?

8. Module boundaries

Every capability in the storefront belongs to exactly one module. When two modules touch, that's an integration point: a defined handoff, not shared ownership. Clear boundaries prevent the coupling issues that made the current implementation difficult to scale.

Click any module for boundary detail: what it owns, what it does not own, and where it connects to other modules.

Key boundary decisions

DecisionOwnerRationale
Address bookOrdering (base)Even single-ship clients use it. Multi-Ship extends with bulk operations but doesn't own it.
Wishlist vs requisition listsWishlist = Catalog, Requisition = OrderingWishlist is browsing (interested). Requisition lists are action (committed to repeat ordering).
Business justificationApproval (optional)Single source. Injects into both base and Multi-Ship checkout. No duplication.
Approval routingApproval, consuming SSO/IdentityOrg hierarchy from client HR system. No self-approval. Approval applies rules; it doesn't define the org chart.
Filters and sortCatalogOperate on product attributes within a listing. Not Navigation, not Search.
SearchOwn base moduleDifferent pattern from Navigation. Creates extension path to AI search.
Campaign collectionsCatalog = data, Navigation = browse pathCollection is a product grouping (Catalog). Nav link to it is a browse path (Navigation).
Master order displayOrdering displays, Multi-Ship createsMulti-Ship creates grouped data. Ordering renders it in history/detail.
Customization pricingPrint on Demand (PrintXpand)Base price from Pricing + surcharge from PrintXpand. Two layers, no conflict.
Rejected ordersApproval: revise and resubmitRequester sees reason, modifies, resubmits. Not a dead end.

Boundary diagrams

Click any module in the architecture diagram below for boundary detail.

Module boundary architecture

Base (every client)
Optional (per client)
Platform (separate phase)
SHELL: branding, layout zones, account navigation
Discovery: how the field rep finds products
Navigation
Category, campaign, brand browse paths
Catalog
Listing, detail, filters, sort, compare, wishlist
Transaction: how the field rep orders
Pricing
Regional, tier, currency, tax display
Ordering
Cart, checkout, order history, detail, tracking, reorder, address book, requisition lists
Shell: My Orders, Address Book
Optional: extend per client need (inject into base modules)
Multi-Ship
Multi-address, CSV upload, address groups
Shell: Address Lists
Approval
Business justification, tier approval, delegation
Shell: My Approvals
Print on Demand
PrintXpand editor, proofing, templates
Shell: My Print Jobs
Instrumentation: silent, every module emits into it
Analytics
Event pipeline, provider integration, consent. Receives events from all modules.
Platform modules (separate phase: client IT dependency)
SSO / Identity
HR integration, approval routing
DAM Integration
Product imagery
CAP Sync
Pricing data
Punch Out
Procurement
Engine / backend (not frontend modules)
Admin catalog management, admin address pre-loading, DI CAP rate card sync, async PO queue (8 consumers), email templates, cron jobs, customer restriction, CSP config, product import/export
Owns
Does not own
Integration points
✓ No class replacements ✓ No window globals ✓ No spaghetti ✓ Own config per module

Checkout flow boundary map

Base flow in purple. Optional module injections in teal (dashed = only when active).

ORDERING (base) OPTIONAL MODULES CartAdd items, adjust qty, review Address selectionPick one outlet from address book Multi-Ship replacesMulti-address grid, CSV upload,per-address item assignment,address groups replaces Shipping method Business justificationCategories + freeform + files Approval injectsOnly when Approval is active injects Payment Order review Print on Demand attachesDesign data rides as line itemmetadata throughout checkout attaches Place order Confirmation Approval routes orderHR integration, tier matchingapprove/reject, resubmit routes Order history + detailTrack, reorder, cancel Modules register tabsApproval: Approval History tab registers Address bookBrowse, add, edit, delete, validateOrdering infrastructure Multi-Ship extendsCSV bulk upload, multi-select,address groups extends

9. Two-phase approach

Phase 1: Foundation

Rebuild the experience layer as clean, well-bounded Adobe Commerce modules within the existing Magento stack. Each module follows a consistent standard: own admin config section scoped per website, data through defined interfaces, own scoped frontend components, no cross-module coupling.

What Phase 1 delivers

Clean, reusable modules across all client websites. Defined config surfaces per module so the implementation team knows exactly what to configure. Modules that don't break each other. A repeatable process: same checklist, same modules, same fields for every client and every market. Dramatically faster onboarding. And Phase 2 readiness, because every module is internally decoupled, so migrating to headless later is module-by-module.

What Phase 1 does not deliver

Config-file-driven deployment (it's admin panel config instead). CLI scaffolding (it's manual setup instead). The 30-day target (it's "dramatically faster" instead of a formula).

Phase 2: Acceleration

Migrate the clean Phase 1 modules into a headless frontend. The Shell becomes a deployable container. Client instances become config files consumed by a build pipeline. CLI scaffolding. 30-day deployment target as a formula, not an aspiration.

Phase 2 is only possible because Phase 1 produces modules with clean boundaries. There's nothing to migrate if the modules are still coupled. Phase 1 is the foundation that makes Phase 2 achievable.

Why Phase 1 first

Phase 1 is faster to deliver. It uses the stack the engineering team already knows. It produces measurable improvement immediately: the first ELC region benefits from Phase 1 modules. And it builds the clean boundaries that Phase 2 requires. Going straight to headless means building the Shell container, the composition layer, the API surfaces, and the modules all at once. Phase 1 is the investment that makes Phase 2 the acceleration.

10. Current state vs future state

The current implementation process includes extended phases of manual configuration work, with each client starting from scratch. Under the modular approach, each phase either compresses, stays manual but improves, or disappears entirely.

Current phaseWhat it becomes
Site creation (manual environment provisioning)Create a new Magento Website. Standardized process, same every time.
Site branding (custom CSS, iterative feedback)Shell config: design tokens (logo, colors, fonts). Defined fields, not custom theme work.
Discovery (open-ended requirements gathering)Guided module selection. "Here's the base. Which optional modules do you need?" Weeks become days.
DI CAP preparation (rate card, pricing sync)Standardized data schema. Client provides data in a known format. Eventually automated via IngestIQ.
Commerce Configuration (the densest phase)Walk through the module config checklist. Defined fields per module. The single biggest compression.
Config replication to production (manual UAT-to-LIVE)Disappears. Per-website config scoping handles environments.
SSO (blocks the whole timeline if client IT is slow)Platform module: can be added post-launch. Storefront goes live without it.
Punch Out (same client IT dependency)Platform module: added when client IT is ready. Doesn't block launch.
UAT (testing custom code)Testing validates configuration, not custom code. Fewer surprises.
Training (custom materials per client)Standardized per module. Same training, different screenshots.

11. Codebase reality

The existing codebase has been audited comprehensively. The platform runs Adobe Commerce 2.4.8-p3 Enterprise on Cloud with 37 custom modules. The engineering work is substantial. The preserve/rebuild estimates below reflect what it takes to bring each module up to the target standard: properly scoped boundaries, defined interfaces, and per-website configuration.

ComponentEstimateKey finding
Navigation~80% rebuild885-line menu.js tightly coupled to theme
Catalog~50% rebuildBackend reasonable; frontend glue (AJAX + Manadev coupling) needs rebuilding
Pricing~90% preserveCleanest area: 4 small plugins delegating to core Magento
Ordering~65% rebuild40+ checkout overrides, 145-file Sales module. Address lookup and outlet validation modules preserve as-is.
Search~60% rebuildCoupled to Manadev LayeredNavigation
Analytics100% net-newNo existing instrumentation
Multi-Ship~75% rebuildHardest area. Core Magento class replacement. Business justification duplication.
Approval~60% rebuildSpans 3 codebase modules. 8 DI preference class replacements.
Print on DemandIntegrationPrintXpand contract signed. ~20% custom build around it.

Module standard

The target pattern for every module: own config section, own JavaScript, no plugins on other modules, no template overrides, integration via defined interfaces. Some modules in the current codebase already follow this pattern. Phase 1 brings the rest up to the same standard.

Key coupling issues to resolve

Window globals for cross-module communication. localStorage state sharing across checkout steps. Core Magento class replacements (DI preferences) creating upgrade risk. Direct helper calls in templates. DOM selector coupling between JavaScript modules. Feature flags scattered across multiple config providers. A single cacheable="false" attribute disabling full-page cache on every frontend page.

12. First implementation: ELC

ELC is a global program, not a single storefront. The first implementation covers three initial regions (Global, North America, APAC), with subsequent markets following as the framework matures.

Module selections

ModuleTierStatus
NavigationBaseON category + campaign collection + brand
CatalogBaseON two product types (fixed SKU + customizable)
PricingBaseON 3 regions, 10-tier, region-restricted
OrderingBaseON address book, requisition lists, master order view
SearchBaseON standard with autocomplete
AnalyticsBaseON provider TBD, consent opt-in
Multi-ShipOptionalON CSV upload, address groups, async PO
ApprovalOptionalON tier thresholds TBD, HR-based routing
Print on DemandOptionalON PrintXpand, SVG templates, proofing
BriefingOptionalTBD needs input
Demand CaptureOptionalTBD needs input

Platform module phasing

ModuleDay 60 (Fixed SKU)Day 90 (Bespoke)Post-launch
DAM IntegrationActiveActiveActive
CAP SyncActiveActiveActive
SSO / IdentityActiveActiveActive
Punch OutDeferredTBDActive

Timeline milestones

MilestoneTargetWhat's live
Shell + DiscoveryWeeks 1-2Brand assets received, module configs confirmed, platform integrations initiated
Base configurationWeeks 3-6All base modules configured, DAM/CAP/SSO integrations complete, catalog loaded
Optional modules + UATWeeks 7-8Multi-Ship and Approval configured, UAT with ELC users
Go-live: Fixed SKUWeek 9 (~Day 60)Field reps live. Browse, search, price, order, multi-ship, approval, tracking.
Print on DemandWeeks 10-13PrintXpand integration, templates created, proofing operational
Go-live: Bespoke~Day 90Customizable products with Print on Demand live

Subsequent ELC markets

After the first three regions launch, each subsequent ELC market follows a compressed path. The modules are already built. The process is already refined.

New Shell configuration: Market branding, currency, language preferences. Defined fields.

Module configuration: Same modules, market-specific values. Pricing regions, tax rules, catalog subset, category structure.

Market data: Rate card, product catalog, outlet addresses for this market.

Platform connections: SSO for this market's users, DAM for market-specific imagery, CAP sync for market pricing.

The variable is client data, not Tag development

For subsequent ELC markets, the bottleneck shifts from Tag development effort to ELC data readiness: rate card data, product catalog, outlet addresses, brand assets for that market, SSO configuration from ELC IT. Tag's configuration work compresses to days. The timeline is driven by how fast ELC can provide market-specific data.

13. What's next

PriorityStatusNotes
Module catalog: base + Multi-Ship, Approval, Print on DemandComplete (draft)Full entries with config surfaces, boundaries, UX requirements
Module Boundary MapComplete (draft)Territory definitions, 12 boundary disputes resolved, integration patterns
ELC Implementation SpecificationComplete (draft)Shell + module configs + phasing + timeline
Module catalog: Briefing, Demand CaptureNeeds inputRequires team discussion on requirements
Module standard documentNot startedTarget pattern, anti-patterns, consistency checklist
ELC subsequent market playbookNot startedCompressed process for new ELC markets
Adobe Commerce feasibility assessmentNot startedPer-module: what's native, extension, custom
Tag demo storefrontNot startedPre-configured Shell with demo data for RFPs
Prototype scaffoldNot startedLight frontend validating the ELC module composition
Phase 2 roadmapNot startedHeadless migration path, API surface gap analysis

14. Open questions

CategoryQuestionStatus
ELCApproval tier thresholds: what dollar amounts trigger each tier?Needed
ELCPredefined justification categoriesNeeded
ELCAuto-rejection policy: should orders auto-reject after timeout?Needed
ELCItem-level approval: needed, or is order-level sufficient?Needed
ELCAnalytics provider preference: GA4 or Adobe Analytics?Needed
ELCTax display rules per region: inclusive vs exclusive?Needed
ELCBrand assets (logo, colors, fonts, guidelines)Needed
ELCWhich products will be customizable (Print on Demand)?Needed
ELCOutlet validation rules for address book?Needed
ELCDoes ELC need Briefing? Demand Capture?Discovery
EngineeringPrintXpand integration status: what's built, what's remaining?Needed
EngineeringMagento 2.4.8-p3 compatibility with PrintXpand: verified?Needed
EngineeringHow does PrintXpand design data attach to cart items?Needed
EngineeringDI preference class replacements (8 in PO, 1 in Multi-Ship): resolution strategy?Needed
EngineeringDoes PrintXpand proofing meet the pre-order approval requirement?Needed
ProductBriefing module requirements: what should the workflow cover?Needed
ProductDemand Capture requirements: buying window mechanics?Needed
ArchitectureMulti-Ship address selection: best UX for 200+ outlets?Discussion
ArchitectureCheckout hook mechanism in Phase 1 (Magento)?Discussion
ArchitectureHow do checkout variations compose when multiple modules are active?Discussion
ArchitecturePer-address item assignment at scale: exceptions-based or explicit?Discussion
ArchitectureConfig schema format: YAML, JSON? Build pipeline details?Phase 2
ArchitectureAPI surface gap: which DiCommerce capabilities need new endpoints?Phase 2

1. Client overview

ELC is a global program, not a single storefront. Different markets, different regions, different branding, pricing, currency, and regulatory requirements, each needing their own commerce experience. The modular architecture handles this natively: each market is a configured Shell with the same modules and different config values.

This spec defines the first ELC implementation (three initial regions) and the path to subsequent markets. The first region is the investment: modules built alongside the implementation. Every market after that reuses those modules. The compounding starts here.

ParameterValue
ClientEstee Lauder Companies (ELC)
Contract effectiveApril 1, 2026
Program scopeGlobal multi-market, starting with 3 regions
Initial regionsGlobal, North America, APAC
Product typesFixed SKU (standard evergreen) + Customizable (bespoke with Print on Demand)
Regional pricing4 prices per region, 10-tier quantity pricing per item
Timeline targetsDay 60 for fixed SKU, Day 90+ for bespoke with Print on Demand
BenchmarkVista Print: the buying experience must match or exceed their UX

2. The trajectory

DeploymentWhat happensRelative effort
First ELC region (Global/NA/APAC)Modules built alongside implementation. Shell, base, and optional modules configured.Highest: the investment
Second ELC marketModules exist. New Shell config (branding, currency, pricing rules). Market-specific catalog and rate card data loaded.Significantly reduced
Fifth ELC marketRefined process. Team knows the checklist. Shell config + data load.Routine
First non-ELC clientModules already work for a global multi-region program. New Shell, same modules, different config.Comparable to a new ELC market
Mature frameworkConfig-file deployment. CLI scaffolding. Build pipeline.30 days from contract to live
The compounding starts within ELC, not after it

The first ELC region is where the modules get built. Every subsequent ELC market reuses those modules. By the time the fifth market launches, the team has a refined, repeatable process. The first non-ELC client benefits from everything ELC's program built.

3. Shell configuration

The ELC Shell is the branded container. ELC's visual identity applied to the storefront frame. Each ELC market gets its own Shell: same module composition, different branding and locale values.

SettingELC valueNotes
client_nameEstee Lauder CompaniesDisplayed in Shell where applicable
logo_urlTBDFrom ELC brand assets. May vary per market.
color_primaryTBDFrom ELC brand guidelines
color_secondaryTBDFrom ELC brand guidelines
font_primaryTBDHeadings, navigation, buttons
font_secondaryTBDBody text
header_layoutstandardLogo, navigation, search, minicart, account menu
show_language_selectorfalseEnglish only at launch. Per-market Shell can enable later.
session_timeout_minutes60Standard timeout

Shell account menu (auto-populated by active modules)

LinkSource moduleActive
My OrdersOrdering (base)Always
Address BookOrdering (base)Always
Browse ProductsNavigation (base)Always
Address ListsMulti-Ship (optional)Yes
My ApprovalsApproval (optional)Yes
My Print JobsPrint on Demand (optional)Yes
Requisition ListsOrdering (base, if enabled)Yes
Dependency: ELC brand guidelines and assets. The Shell can't be configured until brand assets arrive. In the modular architecture, branding is filling in config fields, not custom CSS.

4. Base module configurations

All six base modules are active for every client and every market. These are the ELC-specific config values for the initial three regions.

Navigation

Three browse paths: product category, campaign collection, and brand. Campaign collections are central to ELC's business: a collection like "FY25 Mac Evergreen" groups products across categories for a specific campaign.

SettingELC valueNotes
browse_by_categorytruePrimary browse path
browse_by_brandtrueMAC, Clinique, Estee Lauder, etc.
browse_by_campaign_collectiontrueCore ELC workflow
category_depth3Category > subcategory > product type
mobile_nav_styledrawerHamburger with slide-out drawer
show_breadcrumbstrue

Catalog

Two product types need distinct presentation: fixed SKU (standard items with images and specs) and customizable (items that show a "Customize" button for Print on Demand).

SettingELC valueNotes
default_viewgridGrid layout for product listings
allow_view_toggletrueField reps can switch to list view
products_per_page24
show_skutrueSKU visible on product cards
show_availabilitytrueStock indicators on listings
compare_enabledtrueSide-by-side product comparison
wishlist_enabledtrueSave for later
campaign_collections_enabledtrueCampaign collection groupings active
labels_enabledtrueProduct labels ("New", "Seasonal", etc.)

Pricing

Three regions with four regional prices each and 10-tier quantity breaks. The field rep is assigned to a region via SSO/Identity and sees only their region's prices. Subsequent ELC markets may introduce additional pricing regions without code changes.

SettingELC valueNotes
regions["Global", "North America", "APAC"]Three pricing regions. Subsequent markets add their own.
regional_prices_per_item4Four price points per region
tier_pricing_enabledtrue10-tier quantity pricing
tier_count10Ten quantity break tiers per item
currency_displayRegional defaultUSD for NA, varies by APAC and Global
tax_displayTBDInclusive or exclusive, configurable per region
price_visibilityregion_restrictedField rep sees only their assigned region
show_tier_tabletrueTier pricing table visible on PDP
Dependency: Rate card data from DI CAP. The 3-region, 4-price, 10-tier structure must be built in DI CAP first, then synced to Commerce. 3-4 weeks, driven by the rate card team.

Ordering

Standard checkout flow with address book. The base checkout handles single-address orders. Multi-Ship extends it for multi-address.

SettingELC valueNotes
checkout_steps["shipping", "payment", "review"]Approval injects business justification. Multi-Ship replaces address selection.
outlet_validation_enabledtrueOutlet validation active
address_book_enabledtrueAddress book management page
allow_field_rep_add_addresstrueField reps can add addresses
allow_field_rep_edit_addresstrueField reps can edit addresses
allow_field_rep_delete_addressfalseAdmin-only deletion
show_master_order_viewtrueMulti-ship orders grouped under master view
show_company_orderstrueVisibility into company-wide orders
requisition_lists_enabledtrueSaved product lists for repeat ordering
show_reorder_buttontrueOne-click reorder from history

Search

Standard product search with autocomplete. Extension path to AI conversational search as a future premium module.

SettingELC valueNotes
autocomplete_enabledtrueTypeahead suggestions
show_recent_searchestrue
min_characters2Search triggers after 2 characters
results_per_page24Matches Catalog listing

Analytics

Every ELC interaction instrumented from day one. Data scoped per Magento website: each ELC market's analytics are independent but can be aggregated at the property level.

SettingELC valueNotes
providerTBDGA4 or Adobe Analytics, client preference
tracking_idTBDELC's analytics property ID
consent_requiredtrueGDPR for Global, CCPA for NA
consent_modeopt_inTrack only after consent (GDPR compliance)
Dependency: Analytics provider selection and tracking ID from ELC's marketing/analytics team.

5. Optional module selections

Multi-Ship ON

ELC field reps order to multiple retail locations per order. Multi-Ship replaces the single-address checkout with multi-address selection and master order creation.

SettingELC valueNotes
max_addresses500Standard max
default_assignmentall_to_allAll items to all selected addresses
csv_upload_enabledtrueBulk address upload via CSV/XLSX
csv_max_rows5000
address_groups_enabledtrueSaved address groups for repeat multi-ship
address_autocomplete_enabledfalseEvaluate ShipperHQ integration later
async_processingtrueAsync PO creation for large orders
batch_size20Standard batch

Approval ON

ELC orders require business justification and threshold-based approval. Routing comes from ELC's HR system via SSO/Identity.

SettingELC valueNotes
approval_tiersTBDTier thresholds from ELC. Expected: at least 2 tiers.
auto_approve_belowTBDOrders below this value skip approval
item_level_approval_enabledTBDApprove/reject individual line items?
justification_requiredtrueBusiness justification required
justification_formatbothPredefined categories + freeform text
justification_categoriesTBDe.g. "Seasonal campaign", "New store opening", "Replenishment"
justification_file_uploadtrueAttachments allowed
resubmission_enabledtrueRejected orders can be revised and resubmitted
delegation_enabledtrueApprovers can delegate
auto_rejection_enabledTBDAuto-reject after timeout?
Dependency: Approval tier thresholds, justification categories, and auto-rejection policy from ELC. HR integration for approver mapping from SSO/Identity.

Print on Demand ON

ELC has customizable products where field reps customize using templates and proof before ordering. PrintXpand is the confirmed integration (contract signed February 2026).

PrintXpand contract confirmed

The signed contract confirms B2B template governance (per-customer and per-customer-group assignment), brand compliance validation (node-level locking, DPI validation, prevention of unauthorized modifications), SVG-to-PDF rendering up to 240x22" at 300 DPI, and S3 delivery of production files. These capabilities are in scope.

SettingELC valueNotes
enable_product_designerPer productToggle on customizable products in PrintXpand admin
template_library_enabledtruePre-designed templates available
brand_color_paletteTBDPer brand (MAC, Clinique, etc.)
font_libraryTBDPer brand
show_fold_linestrueFold line overlays on templates
show_bleed_zonetrueBleed area highlighting
show_safe_zonetrueSafe zone highlighting
proofing_requiredtrueMust proof before ordering
max_proofing_rounds2Two proof iterations
allow_artwork_reusetrueReuse previously approved designs
Dependency: PrintXpand integration completion from Tag engineering. ELC brand color palettes and font libraries per brand. Template creation for ELC product types.

Briefing TBD

May be needed for bespoke product requests that go beyond template customization. Needs team input.

Demand Capture TBD

May be needed if ELC has buying windows or seasonal availability. Needs team input.

6. Platform module phasing

Platform modules depend on client IT availability. Phased so the storefront can go live without waiting for every integration.

Phase 1: Go live (Day 60)

The storefront goes live with the Shell, all base modules, and the three optional modules. Platform integrations at launch:

ModuleStatus at launchNotes
DAM IntegrationActiveProducts need images. Must be live.
CAP SyncActiveRate card data drives pricing. Must be live.
SSO / IdentityActiveLogin, region assignment, approval routing. Must be live.
Punch OutDeferredELC IT provides integration docs on their timeline.

Phase 2: Bespoke (Day 90+)

ModuleStatusNotes
Print on DemandActivePrintXpand integration live. Templates created. Proofing operational.
Punch OutTBDMay be live depending on ELC IT timeline

Phase 3: Extensions (post-launch)

ModuleStatusNotes
Punch OutActiveWhen ELC IT is ready
BriefingTBDIf needed, enable and configure
Demand CaptureTBDIf needed, enable and configure

7. Implementation timeline

First ELC region (Global/NA/APAC). Two milestones: Day 60 (fixed SKU live) and Day 90 (bespoke with Print on Demand).

Weeks 1-2: Shell + Discovery

ActivityOwnerDependency
Receive ELC brand assetsELCClient deliverable
Configure Shell with ELC brandingTagBrand assets
Guided Discovery: confirm module configs and selectionsTag + ELC
Confirm approval thresholds and justification categoriesELCBusiness rules
Initiate DAM, SSO, and CAP integrationsTag + ELC ITIT availability
Begin DI CAP rate card constructionRate card teamELC rate card data

Weeks 3-6: Base configuration + platform integration

ActivityOwner
Configure Navigation: categories, campaign collections, brand pathsTag
Configure Catalog: product types, filters, labels, campaign groupingsTag
Configure Pricing: 3 regions, 10-tier, tax display per regionTag
Configure Ordering: checkout flow, address book, outlet validationTag
Complete DAM Integration: product imagery flowingTag + ELC IT
Complete CAP Sync: pricing data every 4 hoursTag + rate card
Complete SSO/Identity: login, region assignment, HR approval mappingTag + ELC IT
Load ELC product catalogTag
Admin pre-load outlet addressesTag

Weeks 7-8: Optional modules + UAT

ActivityOwner
Configure Multi-Ship: address groups, CSV upload, batch processingTag
Configure Approval: tiers, justification, delegation, notificationsTag
UAT with ELC users: all base and optional module flowsELC + Tag
Adjustments based on UAT feedbackTag

Week 9: Go-live (Day 60: fixed SKU)

Fixed SKU storefront live. Field reps can log in via SSO, browse products by category/campaign/brand, see regional prices, place orders with Multi-Ship and Approval, and track everything. Every interaction instrumented.

Weeks 10-13: Print on Demand (Day 90: bespoke)

ActivityOwner
PrintXpand integration completionTag engineering
Create ELC product templates in PrintXpand adminTag + ELC
Configure Print on Demand: proofing, brand palettes, fonts per brandTag
UAT: print on demand flows (customize, preview, proof, order)ELC + Tag
Go-live: bespoke products with Print on DemandTag

8. Subsequent ELC markets

After the first three regions launch, each new ELC market follows a compressed path. The modules are already built. The process is already refined.

PhaseActivitiesEstimated duration
Shell + DiscoveryNew Shell config (branding, currency, language). Guided module selection: likely same optional modules, confirm per market.1 week
Market dataRate card for this market. Product catalog subset. Outlet addresses. DAM imagery for market-specific products.2-3 weeks (client data dependent)
Module configurationPricing regions and tax rules for this market. Category structure adjustments if needed. Approval thresholds if market-specific.1 week
Platform connectionsSSO for this market's users. DAM and CAP sync configured for market scope.1-2 weeks (ELC IT dependent)
UAT + Go-liveTesting validates configuration, not custom code. Standardized training materials with market screenshots.1-2 weeks
The variable is client data, not Tag development

For subsequent ELC markets, the bottleneck shifts from Tag development effort to ELC data readiness: rate card data, product catalog, outlet addresses, brand assets for that market, SSO configuration from ELC IT. Tag's configuration work compresses to days. The timeline is driven by how fast ELC can provide market-specific data.

9. What this proves

This spec is the first test of the modular architecture. What it demonstrates:

Every config value references a defined module field. Nothing is ad hoc. The Navigation module's config surface says browse_by_campaign_collection is a boolean. ELC's value is true.

The optional modules are composable. Multi-Ship replaces the checkout flow. Approval injects business justification. Print on Demand attaches design data. They don't conflict because the integration patterns (replace, inject, attach) are defined.

The timeline is module-driven. Day 60 maps to "Shell + base + Multi-Ship + Approval, with DAM/CAP/SSO live." Day 90 adds Print on Demand. Each milestone is defined by which modules are live.

Multi-market scaling is built in. The first three regions are the investment. Each subsequent ELC market reuses the modules and follows a compressed path. The effort curve bends down with every deployment.

TBD items are explicit. Every TBD has a named dependency. Nothing is vaguely open.

Platform modules are phased independently. The storefront can go live without Punch Out. Platform modules operate on the client IT's timeline, not ours.

The compounding starts within ELC. The first non-ELC client benefits from everything the ELC program built and refined. By that point, the modules work, the process is proven, and the timeline is a formula.

10. Open questions

CategoryQuestionStatus
ELCApproval tier thresholds: what dollar amounts trigger each tier?Needed
ELCPredefined justification categoriesNeeded
ELCAuto-rejection policy: should orders auto-reject after timeout?Needed
ELCItem-level approval: needed, or is order-level sufficient?Needed
ELCAnalytics provider preference: GA4 or Adobe Analytics?Needed
ELCTax display rules per region: inclusive vs exclusive?Needed
ELCBrand assets (logo, colors, fonts, guidelines)Needed
ELCWhich products will be customizable (Print on Demand)?Needed
ELCOutlet validation rules for address book?Needed
ELCDoes ELC need Briefing? Demand Capture?Discovery
ELCCurrency display per region: market defaults or specific preference?Needed
ELCHow many subsequent markets are in the pipeline? Which are prioritized?Discovery
EngineeringPrintXpand integration status: what's built, what's remaining?Needed
EngineeringMagento 2.4.8-p3 compatibility with PrintXpand: verified?Needed
EngineeringHow does PrintXpand design data attach to cart items?Needed
EngineeringDoes ELC need 3D preview for any product types?Needed
EngineeringDo brand color palettes and font libraries differ per ELC brand within Print on Demand?Needed
ProductBriefing module requirements: what should the workflow cover?Needed
ProductDemand Capture requirements: buying window mechanics?Needed

1. Client overview

Content for Reyes client overview is in progress.

2. The trajectory

Content for Reyes trajectory is in progress.

3. Shell configuration

Content for Reyes Shell configuration is in progress.

4. Base module configurations

Content for Reyes base module configurations is in progress.

5. Optional module selections

Content for Reyes optional module selections is in progress.

6. Platform module phasing

Content for Reyes platform module phasing is in progress.

7. Implementation timeline

Content for Reyes implementation timeline is in progress.

8. Subsequent markets

Content for Reyes subsequent markets is in progress.

9. What this proves

Content for what the Reyes implementation proves is in progress.

10. Open questions

Content for Reyes open questions is in progress.