Turning a backlog of unread retailer POS exports into live SKU-level margin and honest promo-lift measurement — the parser survival kit for retailer portals, and the baseline trap that flatters every promotion. Public excerpt; the full teardown lives in the Builder library.
Most brands in retail distribution are sitting on years of POS data they've never systematically read. This pipeline turns that standing backlog into a live asset: margin by SKU by retailer, velocity at whatever grain the feeds allow, and promo lift measured honestly. Four stages, and the fourth is where the money conversation changes.
Stage 1 — Harvest, defensively. Retailer portals and distributor reports deliver POS data in gloriously inconsistent formats — different layouts per retailer, occasional unannounced changes, files designed for humans rather than parsers. Every source gets its own adapter with schema validation on ingest: a file that doesn't match its expected shape quarantines and alerts rather than parsing wrong. Keep every raw file forever; you will re-parse history the day you discover what a column actually meant.
Stage 2 — Normalize to one sales fact. Retailer item codes resolve through the product-identity mapping to your SKUs; units, weeks, and store identifiers normalize to one schema. Retailer fiscal calendars deserve explicit handling — several run non-standard week boundaries, and joining their "week" to your calendar without translation smears every weekly stat.
Stage 3 — Join the cost side. Your product costs, freight, deductions, and trade spend attach to the sales facts — producing SKU-by-retailer margin that no retailer report will ever show you, because your costs are none of their business. This join is what converts "velocity data" into "the account that's quietly margin-negative."
Stage 4 — Measure promotions against honest baselines. Lift = promoted-period sales versus what would have sold anyway — and everything hinges on the baseline. Same SKU, same stores, seasonality respected, and windows uncontaminated by adjacent promotions. Then net the incremental units against what the promotion cost. Most brands have never seen that final number for their own trade spend; it changes renewal conversations permanently.
A portal changed its export format on a Tuesday. No announcement — a reordered column set that happened to keep the same column count. A naive parser would have loaded units into the dollars field and poisoned weeks of history before anyone noticed. Schema validation caught it at quarantine instead. Rule since hardened: parsers assert on header content, never on position, and every load reconciles totals against the file's own summary rows when the format provides them. Retailer portals are an adversarial data source that doesn't know it's adversarial.
A promotion measured brilliant against a poisoned baseline. The lift calculation for one event used trailing weeks that included the previous promotion's tail — depressing the baseline (post-promo dip) and inflating the measured lift. The promo renewed on those numbers once before the contamination rule existed: baseline windows exclude a buffer around any adjacent event, and thin-baseline SKUs get flagged as unmeasurable rather than measured wrong. An honest "insufficient data" beats a confident fiction — that's the whole pipeline's ethic in one sentence.
The full teardown — the per-retailer adapter pattern, the fiscal-calendar translation table, the deduction-attribution approach, and the baseline-selection rules — lives in the Builder library.
Implementation detail, checklists, and the parts we'd rather not have public — for members.
Unlock with Builder