01 The Challenge
Soci, Inc. supplies natural
stone, tile, and surfacing products to the North American floor covering trade. Its customers are
flooring dealers — and dealers do not shop a supplier’s website. They buy inside their own
business-management software, and they expect their vendors’ product catalogs and price
agreements to arrive in that software automatically.
The floor covering industry standardized that exchange under fcB2B, built on
EDI X12 v4010. The relevant document is the 832 Product/Price Catalog:
the supplier drops an 832 into a dedicated FTP folder for each dealer, and the dealer’s system
polls that folder and ingests the catalog — RFMS, the dominant platform in the segment, checks
every two hours. It is a direct supplier-to-dealer connection with no intermediary and no
second chances: the file is either well-formed and correctly priced, or the dealer quotes the
wrong number.
Soci had no way to produce that document. Price agreements moved by spreadsheet, phone, and fax,
with the pricing errors and order errors that implies — and, more importantly, being off the
B2B network shut Soci out of the buying groups where its dealers lived. Getting on it meant
building a real EDI distribution system, and then keeping it running every week
indefinitely, because a price catalog that stops updating is worse than one that never
existed.
02 Version 1 — Price List Manager
Leopard Data built Price List Manager: a C#/.NET desktop application over a
MariaDB catalog, backed by a Linux FTP estate, with the whole thing hosted on Google Cloud. A
Soci merchandiser loaded a price list, made the adjustments the sheet needed, picked a customer,
and clicked once. The application generated a conforming X12 4010 832 — ISA/GS envelopes,
BCT header, N1/REF trading-partner identification, and a LIN/PID/MEA/CTP/SLN loop per item
carrying SKU, description, material code, unit of measure, and list price — and delivered
it into that dealer’s FTP folder for pickup.
The unglamorous half of the work was the trading-partner estate. Every dealer got
an isolated FTP account with its own credentials, its own inbox/outbox directories, and correct
ownership and permissions, mapped to the account number and sender/receiver IDs the dealer’s
system expected. Leopard Data ran dealer onboarding as a standing service for the life of the
system: Soci sold a new B2B account, Leopard Data provisioned it, and catalogs started flowing.
03 Version 2 — Driven Straight from NetSuite
A few years in, Soci centralized its operation on NetSuite ERP, and that changed
the problem. Pricing now lived in NetSuite — base pricing, buying-group levels, fabricator
levels, and customer-specific special pricing — and the desktop workflow had become a
five-step manual relay: build the price list in NetSuite, export to Excel, import to Price List
Manager, finish edits by hand, transmit. Worse, anyone who changed pricing in the ERP silently
put the transmitted catalogs out of sync with the system of record.
Leopard Data rebuilt the platform from the ground up as a cloud-hosted web system. An
Angular single-page application replaced the desktop client, sitting on an
ASP.NET Core Web API whose TypeScript client was generated directly from the
API’s OpenAPI contract so the two could never drift. A dedicated NetSuite integration
library talked to SuiteTalk web services, mapping item search results and pricing
joins into a normalized catalog model — SKU, sales description, manufacturer, material code,
product group, price level, unit price.
Behind the UI, the system became a set of scheduled workers rather than a program someone drives.
Three sync jobs pulled customers, items, and price lists from NetSuite into
MariaDB on a twice-daily cron, and an FTP queue processor ran every minute,
draining a transmission queue, generating each 832, and delivering it to the right dealer folder.
The whole stack was containerized with Docker and Docker Compose, with images published to
Google Cloud Container Registry, and nginx fronting both the Angular app and the API on the
Google Cloud VM.
The most consequential design decision was a deletion: V2 removed price editing
entirely. Once NetSuite was the single source of truth, letting a second system mutate
prices was the bug, not the feature. Catalog line de-duplication moved into 832 generation at the
same time, closing the one class of malformed output V1 had shipped.
04 Eight Years of Running It
The build was the small part. Leopard Data hosted and operated the system for eight
years as a managed service — the Google Cloud VM, the MariaDB catalog, the FTP
estate, nginx, the cron fleet, the deployments, and the on-call for a pipeline that dealers
across the US and Canada polled around the clock.
Operationally that meant onboarding new dealers as Soci won them, adapting to NetSuite version
upgrades on the ERP side, absorbing catalog and price-level changes as the product line evolved,
and keeping an EDI integration correct against trading partners Leopard Data did not control. The
measure of success for this kind of system is that nobody talks about it: for eight years, price
catalogs left Soci’s ERP and landed in dealers’ purchasing systems without anyone at
Soci thinking about how.
05 The Outcome
- Soci onto the fcB2B network as an EDI-enabled vendor, able to sell into dealer channels that require B2B connectivity.
- Price catalogs delivered as conforming X12 4010 832 documents to per-dealer FTP endpoints, picked up automatically by dealer purchasing systems.
- A five-step manual relay from ERP to dealer collapsed to: log in, pick a customer, transmit — with the ERP as the only source of pricing truth.
- Spreadsheet-and-fax price distribution — and the pricing errors that came with it — retired.
- Eight years of continuous production operation on Google Cloud, designed, built, hosted, and run by Leopard Data.
- Cleanly decommissioned in 2026 when Soci took its commerce strategy a different direction.
06 Tech Stack
EDI X12 4010
832 Product/Price Catalog
fcB2B
NetSuite ERP
SuiteTalk Web Services
Google Cloud
ASP.NET Core
C# / .NET
Angular
TypeScript
WPF
MariaDB
Docker / Compose
Container Registry
nginx
Linux / cron
FTP / vsftpd
OpenAPI / Swagger