Systems Architecture¶
How PopSockets' systems connect. This is the 30,000-foot view — what talks to what, what data flows where, and why.
The Big Picture¶
Storefronts generate orders, OMS manages them, fulfillment partners ship them, and confirmations flow back. Product data comes from Arena PLM and fans out to every system that needs it. EDI handles the B2B retail channel. Almost every inter-system hop runs through the Camel integration layer — the middleware — shown below as dashed edges.
Click the diagram to zoom.
Order Flows¶
B2C — Direct to Consumer¶
Customer places an order on popsockets.com. OMS picks it up, NAV allocates inventory (asynchronously, on its own clock), and only after NAV releases the order does it go to Cirro for fulfillment. When it ships, OMS notifies NAV and closes the loop with the storefront — marking the order shipped and capturing payment in one call.
sequenceDiagram
participant Store as SFCC / Shopify
participant OMS
participant NAV
participant Camel
participant Cirro as Cirro 3PL
OMS->>Store: Poll for new orders (cron)
Store-->>OMS: New orders
OMS->>NAV: Create sales order (direct SOAP)
Note over NAV: Allocates inventory (async)
NAV--)Camel: nav-order-release (ASB queue)
Camel->>OMS: RELEASED_FROM_NAV
OMS->>Camel: Fulfillment request (encrypted, ASB)
Camel->>Cirro: Create order
Cirro--)Camel: Acceptance webhook
Camel->>OMS: EXPORTED_TO_TPL
Note over Cirro: Order ships
Cirro--)Camel: Shipping webhook (tracking)
Camel->>OMS: SHIPPED
OMS->>NAV: Shipment notice (direct SOAP, cron)
OMS->>Store: Mark shipped + capture payment (one call)
See B2C Order Flow for the full walkthrough.
B2B — Retail / EDI¶
Retailer sends a purchase order (EDI 850) via SPS Commerce. Camel relays it to NAV, which acknowledges it (855) and generates the warehouse order (940). Camel routes the 940 to Cirro — prepacking first if required. When Cirro's shipment webhook lands, cm-edi-prc generates the 856 ship notice back to the retailer and the 945 shipping advice back to NAV; NAV then invoices (810). Cirro never authors EDI documents — a missing 856/945 is a Camel/edi_docs problem, not a Cirro one.
sequenceDiagram
participant SPS as SPS Commerce
participant Camel as Camel (cm-edi-prc / cm-order-prc)
participant NAV
participant Cirro as Cirro 3PL
SPS->>Camel: 850 Purchase Order (SFTP poll)
Camel->>NAV: 850 forwarded (PS SFTP)
NAV->>NAV: Process 850, generate 940
NAV->>SPS: 855 PO Ack (via Camel + SPS SFTP)
NAV->>Camel: 940 dropped on PS SFTP (polled)
Camel->>NAV: Fetch packing instructions (SOAP)
opt RequiresPrepack
Camel->>Cirro: Prepack order
Cirro-->>Camel: Prepack complete
end
Camel->>Cirro: Create B2B order
Cirro--)Camel: ONE shipment webhook
Note over Camel: cm-edi-prc GENERATES 856 + 945<br/>from stored 850/940 records
Camel->>SPS: 856 ASN (SPS SFTP → retailer)
Camel->>NAV: 945 Ship Advice (PS SFTP)
NAV->>SPS: 810 Invoice (via Camel + SPS SFTP)
See the EDI Pipeline for stage-by-stage detail.
Custom Print¶
Custom/personalized orders detour through BatchStation — operator-driven batching — before rejoining the normal Cirro fulfillment flow. OMS is notified as soon as an order is batched (before printing): that notification unblocks the Cirro export, and the physical print run happens after.
sequenceDiagram
participant OMS
participant BS as BatchStation
participant OP as Operator
participant PS as PrintStation
participant Cirro
OMS->>BS: Printable orders (ASB topic)
BS->>BS: Image validation
OP->>BS: Stage + generate batch (manual gates)
BS->>PS: Batch dispatch (ASB + Camel-proxied HTTP)
PS->>OMS: Order batched (direct HTTPS POST)
Note over OMS: PRINT_STATION_BATCHED →<br/>CIRRO_READY_FOR_FULFILLMENT
OMS->>Cirro: Fulfillment export (rejoins B2C flow)
Note over PS: Physical print production
See PrintStation & BatchStation for the full pipeline.
Product Data Flow¶
Product information originates in Arena PLM and fans out to every system that needs it.
sequenceDiagram
participant Arena as Arena PLM
participant OMS
participant PS as PrintStation
participant JK as Jackyun (China)
Arena->>OMS: Item updates
Arena->>PS: Print batching updates
Arena->>JK: SKU sync to China warehouse
Inventory Flow¶
cm-snowflake-sys pulls order + inventory data from Cirro on a schedule, stages it through Azure Blob, and writes it to Snowflake. Snowflake is a passive destination — it doesn't request anything.
sequenceDiagram
participant Camel as cm-snowflake-sys
participant Cirro as Cirro 3PL
participant Blob as Azure Blob
participant Snow as Snowflake
Camel->>Cirro: Pull order + inventory data (scheduled)
Camel->>Blob: Stage
Camel->>Snow: Write to warehouse
Snowflake also gets a direct OMS feed
Separate from the Cirro pull above, OMS order data lands in Snowflake via a direct database-to-database sync that runs outside the Camel integration layer. Both feeds are slated to move to Microsoft Fabric, which is replacing Snowflake as the warehouse.
Systems Reference¶
Storefronts & Order Sources¶
| System | What It Does | Protocol |
|---|---|---|
| SFCC (Salesforce Commerce Cloud) | popsockets.com storefront | REST API → OMS |
| Shopify | Additional storefront | REST API → OMS |
| Discopify | B2B order portal | REST API → OMS |
Order Management¶
| System | What It Does | Protocol |
|---|---|---|
| OMS / OSOR | Central order management — validation, inventory, status | REST API (Diff Agency hosted) |
| Gladly | Customer service CRM, pulls order details from OMS — being replaced by Richpanel | REST API via cm-osor-sys |
Fulfillment¶
| System | What It Does | Protocol |
|---|---|---|
| Cirro | Primary 3PL — AMER lanes (US B2C + retail B2B). The China 3PL is KH, via Jackyun | REST API via cm-cirro-sys |
| BatchStation | Custom-order staging and batch assembly — operator-driven, feeds PrintStation | ASB + REST (Camel-proxied) |
| PrintStation | Custom print production — batch callback to OMS unblocks Cirro export | REST API via cm-printprod-sys |
ERP & EDI¶
| System | What It Does | Protocol |
|---|---|---|
| NAV (Dynamics NAV) | ERP — generates 940s from 850s, receives 945 ship advice | SOAP over HTTPS |
| SPS Commerce | Retailer EDI gateway — 850 inbound; 855/856/810 outbound | SFTP (port 10022) |
| PS SFTP | Internal file exchange for NAV and EDI documents | SFTP (10.45.0.100:22) |
Product & Data¶
| System | What It Does | Protocol |
|---|---|---|
| Arena PLM | Product lifecycle management — source of truth for items | REST API (session-based auth) |
| Snowflake | Data warehouse — ingests Cirro order + inventory data via cm-snowflake-sys, plus a direct OMS database sync outside the integration layer — being replaced by Microsoft Fabric | JDBC (JWT auth) |
| Azure Data Explorer | Operational analytics and audit logging | REST API (Kusto ingest) |
Infrastructure¶
| System | What It Does | Protocol |
|---|---|---|
| Azure Service Bus | Message backbone — topics per flow per environment | AMQP |
| PostgreSQL | Persistent storage — EDI docs, order tracking | JDBC |
| Azure Blob Storage | EDI document archive and bulk data staging | REST API |
| Hazelcast | Distributed cache — Arena tokens, locking | In-memory clustering |
Notifications¶
| System | What It Does | Protocol |
|---|---|---|
| Microsoft Teams | Alerts for EDI processing, order errors | Webhook (Power Automate) |
| Image Validator | AI-powered image classification for custom prints | REST API (OAuth) |
Integration Microservices¶
The integration layer is a set of Camel-based microservices in the cm-* namespace. Each has a specific role:
| Service | Role |
|---|---|
| cm-edi-prc | EDI document processing — 850/940/856/945 generation, SFTP polling, routing |
| cm-order-prc | Order routing and transformation — determines B2B vs pre-pack; consumes nav-order-release |
| cm-fulfill-prc | Fulfillment request handling — decrypts, transforms, sends to 3PL |
| cm-ext-service-exp | External webhook receiver — Cirro shipment confirmations |
| cm-int-service-exp | Internal REST for other PopSockets services — delegates to cm-int-service-sys |
| cm-fulfill-exp | Legacy fulfillment REST — retiring, use cm-int-service-exp / cm-ext-service-exp for new work |
| cm-int-service-sys | Internal service layer — DB operations, watermarks, audit logging |
| cm-cirro-sys | Cirro API proxy — adds auth, routes to Cirro endpoints |
| cm-osor-sys | OMS proxy — order confirmation, Gladly integration |
| cm-product-sys | Arena PLM wrapper — item events, specs, search |
| cm-product-prc | Product distribution — fans Arena updates to downstream systems |
| cm-jackyun-sys | Jackyun/Qimen API wrapper — Arena product/SKU/BOM sync (live); order polling built but disabled in prod |
| cm-batching-prc | Batch processing — groups custom print orders |
| cm-printprod-sys | Print production proxy — sends batches to PrintStation |
| cm-snowflake-sys | Snowflake integration — Cirro order + inventory data pipeline |