Put the Routing Decision on the Item, Not the Pipeline
A single item-level tag can replace scattered routing rules, keeping downstream systems consistent, testable, and easier to inspect.
The problem starts in a familiar place: a catalog item that should only appear on the web store, not at the physical point of sale. Somewhere in the pipeline, a handful of conditional statements decide where it goes. The item ships to the web store. The point-of-sale system should never see it. And when inventory information flows back, nothing should overwrite the item with the wrong status.
Every one of those conditions lives in a different part of the pipeline. One check sits in the ingestion step. Another lives in the catalog sync job. A third is buried in the inventory-update handler. Changing how routing works means finding all of them, editing each one, and hoping nothing was missed.
This article is about a simpler pattern: put the routing decision on the item itself. One keyword becomes the single source of truth, and every downstream system reads the same tag instead of maintaining its own version of the rule.
Why scattered routing rules fail
Routing logic spread across multiple pipeline stages has the same weakness regardless of which systems are involved: there is no single place where the decision is made.
Consider a typical setup. A catalog system receives a new item, and the ingestion step checks whether the item belongs on the web store. Later, the POS sync process checks again. Then the inventory reconciliation job checks a third time. Each check is written separately, which means each one can drift.
What actually goes wrong is predictable. A developer adds a new product type and updates the check in ingestion but forgets the one in the sync job. Or the web-store-only rule is changed in one place, and the inventory handler now behaves inconsistently with the catalog publisher. The item ends up on the wrong shelf, and someone on the operations team has to manually correct it.
The correction itself is often manual. A person finds the misrouted item, changes a status field, and re-runs a sync. That works for one item but does nothing to prevent the next misrouting. The same failure repeats because the underlying architecture still distributes the rule across the pipeline.
There is also a subtler problem: ambiguity. When the rule lives in multiple places, it is unclear which version is authoritative. Is the item excluded from POS because of the ingestion check, the sync check, or the reconciliation check? The answer is "all of them," which means any one of them being wrong breaks the whole flow.
Put the decision on the item
The alternative is to make the item itself carry the routing decision. Instead of asking each pipeline stage to re-evaluate a rule, the item arrives with a tag that already says where it belongs.
A tagging field on the item becomes the authoritative routing signal. Downstream systems read the tag and act accordingly rather than re-deriving the decision from their own logic.
This pattern works because it removes duplication. The rule exists once, as data on the item, instead of existing once per pipeline stage as code.
What the tag actually controls
A grading tag on an item can control several behaviors at once. Consider what happens when an item is marked with the keyword GRADE_WEB_ONLY.
First, the item is created normally in the catalog. It gets its product information, pricing, and metadata like any other item. The "normal" part matters: the item should not be treated as exceptional during creation.
Second, the item stays out of the POS feed. The POS sync reads the tag and skips the item, so the physical store never lists it.
Third, the item is pinned to the web store. The catalog publisher uses the tag to include the item in the web storefront feed.
Fourth, the POS-update flag is cleared. This prevents the inventory system from sending POS-related updates for the item, which would otherwise create noise or conflicting statuses.
Fifth, an internal grading field is written. This field documents that the item was routed this way, giving the operations team a way to inspect why the item behaves the way it does.
All five behaviors derive from the same tag. There is one decision point, not five.
Why a tag works better than a condition
The tag approach works because it moves the decision from pipeline-specific code to the data layer. This changes several properties of the system at once.
The behavior is uniform. Every downstream system reads the same field, so there is no risk of one system deriving a different conclusion than another.
The behavior is discoverable. Anyone inspecting the item can see the tag and understand why it is routed the way it is. There is no need to trace through multiple code paths to reconstruct the logic.
The behavior is testable. The tag can be set at the source, in tests, and in staging environments without requiring pipeline-specific setup. A test that inserts the tag and verifies the POS feed excludes the item is straightforward.
The behavior is auditable. The internal grading field records the routing decision alongside the item, which helps answer "why did this item behave that way" questions later.
None of these properties require a complex orchestration layer. The change is contained to how the item is structured and how downstream consumers interpret one field.
A closer look at the implementation
The implementation involves two sides: enforcing the tag at entry, and honoring it at each consumer.
On the entry side, the system that creates or imports items must support the grading tag. Typically this means the schema accepts an optional grading field. The field is not required for every item; most items route normally, and the tag only matters when a routing decision needs to be made.
Consider how a new item is processed:
def create_item(payload):
item = catalog.create(payload)
if item.grading == "GRADE_WEB_ONLY":
item.store_status = "web_pinned"
item.pos_enabled = False
item.pos_update_flag = False
item.internal_grading_field = "web_only_grade"
return item
On the consumer side, each system checks the tag rather than maintaining its own copy of the routing rule. The POS sync reads the flag and skips the item:
def sync_pos():
for item in get_items_for_pos():
if item.pos_enabled:
push_to_pos(item)
The key point is that the same field drives all consumers. The POS sync, the web catalog publisher, and the inventory reconciliation all read from the item's own state rather than re-deriving the decision.
What this removes
The visible result is a reduction in the number of routing rules scattered through the codebase. Each pipeline stage no longer needs its own conditional that knows about web-store-only items. The condition moves to the data, and the pipeline stages become simpler.
The other thing this removes is the class of bug where one stage is updated and the others are not. Because there is only one field to read, there is only one thing that can be wrong. If the field is set correctly, all consumers agree. If the field is wrong, fixing the field fixes every consumer at once.
Signals that routing is working
There are observable signs that this pattern is working as intended.
Fewer misroutes
Misrouted items decline. Items that should be web-only no longer appear in POS feeds, and vice versa. When they do appear, the cause is a bad tag value rather than a missing conditional, which is much easier to diagnose.
Fewer manual fixes
Manual corrections become less frequent. The operations team no longer needs to fix items that were routed incorrectly by half-updated pipeline logic. In engagements where we've applied this, misroute-related corrections typically decline noticeably once the tag is the single source of truth.
Easier additions
New pipeline stages are easier to add. When a new consumer needs to know whether an item is web-only, it reads the same field. There is no risk of forgetting to update a rule in a new place because the new place reads the item's state directly.
Faster inspection
Inspection is faster. When someone asks why an item is not on the store shelf, the answer is on the item itself. The tag and the internal grading field tell the story without tracing code.
Where this gets tricky
The pattern is not a universal fix, and there are situations where it creates new problems.
The first is stakeholder conflict. If the web-store-only rule is contested — say, marketing wants the item on the web store, but inventory wants it in physical stores too — the tag becomes a point of conflict. That's a business decision, not a technical one. The tag cannot resolve who should be able to change it. Put a review or approval step around the tag if the routing authority is contested.
The second is tag sprawl. If routing decisions multiply — web-only, store-group-A-only, clearance-only, staff-discount-only — the single tag starts to carry too much meaning. The pattern still works, but it becomes harder to read. At some point, a structured set of routing fields or a separate routing table may serve better than one free-form keyword.
The third is data quality at the source. The tag only works if it is set correctly when the item is created or imported. If the entry system allows a bad tag value — a typo, an outdated value, a value the consumers do not recognize — the item fails silently or routes incorrectly. Validation at entry is not optional; it is the price of enjoying a single source of truth.
The fourth is migration. Existing items that have never carried the tag will default to the old behavior. If a legacy item was already misrouted, adding the tag to the schema does not retroactively fix it. The migration needs an explicit pass to tag existing items or to confirm that the default behavior is correct.
When this pattern makes sense
This approach fits best when the routing decision belongs to the data, not the pipeline. If the same classification is consumed by several systems, and the decision boundary is the item itself rather than context around it, a tag is the simplest mechanism.
It makes less sense when the routing decision depends on context that is not on the item — for example, a regional rule, a customer segment, or a time-limited promotion. In those cases the routing logic is genuinely pipeline-level, and forcing it into a static tag would either be wrong or require constant tag updates.
It also makes less sense when the systems involved refuse to honor the field. If an external POS platform does not support the concept of a "web-only" item, the tag cannot override the platform's own constraints. The pattern works within the boundaries of what the downstream systems can express, not beyond them.
Where to start
If you are looking at a pipeline where the same routing rule appears in more than two places, this pattern is worth evaluating. Map the workflow first: list every stage that currently decides where items go, and identify which of those decisions are truly about the item itself versus the stage that processes it.
Then inspect one item that should be routing one way and check whether every stage agrees. If they do not, you have found the concrete cost of the distributed rule. If they do, changing that rule in the future will still require finding all the places it lives.
The pattern is deliberately small: one field, read consistently. It does not require new infrastructure, new platforms, or a rewrite. It requires moving the decision to where it can be seen, changed, and tested as a single fact — the item itself.
Ready to Implement These Strategies?
Let's discuss how to apply these insights to your specific business challenges.
Schedule Consultation