Decision Matrix

Decision Matrix

Summary: Consolidated decision guide — when to use X vs Y for every major IM choice. Designed for AI agents generating integrations.


Import Method

Condition

Use

Why

CSV import for P, PX, CX, C, LTV, MLTV2

pfx-api:loaddataFile

Default. Streams file to server, much faster for large files

Need Groovy row-level logic per record

pfx-api:loaddata with split+tokenize+pfx-csv:unmarshal

IM parses each row in memory, allows custom processing

PA Data Source (DMDS) import

pfx-api:loaddata with split+tokenize+pfx-csv:unmarshal

DMDS requires flush after loading; loaddataFile not supported

Server-side import (rare)

pfx-api:import

File already on Pricefx server

Batch Size for loaddataFile

Fields per row

Recommended batchSize

< 10

500000

10–20

100000200000

20+

50000 or less

Default batchSize for all methods is 5000. Override explicitly in route URI.

CSV Parsing Method

Condition

Use

Why

With loaddataFile

pfx-csv:streamingUnmarshal

Must be BEFORE split, not inside. Streams without loading full file

With loaddata (inside split)

pfx-csv:unmarshal

Parses batch of lines into List of Maps

Need custom delimiter/header

Add delimiter={char} and header={cols} parameters

Both methods support these

Mapper Type

Condition

Use

Why

Bulk load (replace all data)

loadMapper

Used with loaddata / loaddataFile

Upsert (insert or update by key)

integrateMapper

Used with integrate. Supports predicates

Nested/hierarchical data

multilevelMapper

Multi-level data structures

Object Type for Data Sources

Operation

objectType

Notes

Load data into Data Source

DM

With dsUniqueName=DMDS.{Name}

Fetch from Data Source

DM

With dsUniqueName=DMDS.{Name}

Server-side import

DMDS

With dsUniqueName=Transaction

Flush after DS load

use pfx-api:flush

dataFeedName=DMF.{Name}&dataSourceName=DMDS.{Name}

Calculate/refresh Datamart

DM

With typedId or targetName

PX/CX Table Name

Approach

Correct?

Why

<constant expression="TableName" out="name"/> in mapper

YES

Required. Sets the extension table name

typedId=TableName in route URI

NO

typedId is for entity IDs (e.g., 123.PX), not table names

extensionName=TableName in route URI

NO

This parameter does not exist

File Consumer Locking

Condition

Use

Why

Default (no external signal)

{{read.lock}} (readLock=changed)

Waits until file size stabilizes

Upstream writes .done marker file

{{done.file}} (doneFileName)

Waits for filename.done before reading

Never use both

Causes deadlock — pick one

Never use noop=true

Files must be archived after processing

Always include {{archive.file}} to move processed files to .archive/YYYY/MM/.

Export: Batched vs Non-Batched

Condition

Use

Why

Small dataset (< 50k rows)

pfx-api:fetch (no batching)

Simple, one API call

Large dataset (50k+ rows)

pfx-api:fetch?batchedMode=true&batchSize=5000 + split + pfx-api:fetchIterator

Avoids OutOfMemoryError

Need record count only

pfx-api:fetch?countOnly=true

Returns count, no data

Delta Export: Timestamp Persistence

Step

Component

Pattern

Read last timestamp

pfx-config:get

toD uri="pfx-config:get?name={key}&toHeader=lastExportTimestamp"

Fallback for first run

choice + constant

Set 1970-01-01T00:00:00 if null

Capture current time

setHeader + simple

${date-with-timezone:now:UTC:yyyy-MM-dd'T'HH:mm:ss}

Filter: both bounds

greaterThan + lessOrEqual

Prevents missing records during export

Save new timestamp

pfx-config:set

After successful export only

Scheduling

Condition

Use

Why

One-time run

timer://name?repeatCount=1

Fires once on startup

Periodic run

scheduler://name?delay=60000

Every N milliseconds

Cron schedule

quartz://group/name?cron=0+0+6+*+*+?

Spaces replaced with + in URI

Event-triggered

direct:routeName with event mapping

See events.md

Company Parameter (LTV/MLTV2) Field Names

Table Type

objectType

Key fields

Value fields

SIMPLE

LTV

name

value

RANGE

LTV

name, lowerBound, upperBound

value

MATRIX

MLTV2

name

attribute1attributeN

MATRIX2

MLTV2

key1, key2

attribute1attributeN

MATRIX3

MLTV2

key1key3

attribute1attributeN

MATRIX4

MLTV2

key1key4

attribute1attributeN

MATRIX5

MLTV2

key1key5

attribute1attributeN

Business Key Field per Object Type

objectType

Business key field

businessKeys parameter

P (Product)

sku

businessKeys=sku

PX (Product Extension)

sku + table name

businessKeys=sku

C (Customer)

customerId

businessKeys=customerId

CX (Customer Extension)

customerId + table name

businessKeys=customerId

SL (Seller)

LTV / MLTV2

Uses pricingParameterName instead

DM (Data Source)

No businessKeys for DMDS

Upsert: businessKeys vs integrateMapper

Condition

Use

Why

Bulk load with upsert by single key

pfx-api:loaddata + loadMapper + businessKeys=sku

Simplest approach. Server matches by business key and updates or inserts

Upsert with conditional logic per field

pfx-api:integrate + integrateMapper with <predicate>

Allows field-level conditions (e.g., only update price if new value is higher)

Upsert with composite business key

pfx-api:integrate + integrateMapper + businessKeys=field1,field2

integrate handles multi-field matching better

Simple bulk replace (no upsert needed)

pfx-api:loaddata + loadMapper (no businessKeys)

All existing records are replaced by the new data

Rule of thumb: Use loaddata + businessKeys for straightforward upserts. Use integrate + integrateMapper only when you need field-level predicates or complex multi-key matching.

Error Handling Decision

Scenario

Retried automatically?

Action

ConnectException, ConnectTimeoutException

Yes (10x, exponential)

Wait, check network if persistent

HTTP 409, 503, 504

Yes

Wait, usually resolves

HTTP 400, 401, 404

No

Fix request/credentials/target

NonRecoverableException

No

Fix configuration

FormatException

No

Fix source data or mapper