Skip to main content
0.0.x

ERP Sync

Your team is mid-migration between two ERPs. SAP, the legacy system, is still the system of record — production plans against it every day. Microsoft Dynamics, its replacement, goes live in stages, which means that for months the two run in parallel and Dynamics is only as correct as the sync that feeds it. The integration you are handed is a file export, not an API: SAP drops a nightly file, and your job is to ingest it. This track builds that sync: a back-office service that watches for the SAP export drops, turns each one into a durable background job, transforms legacy rows into Dynamics' shape, absorbs backfill bursts behind a queue, and re-syncs nightly on a cron. It is the durable-processing companion to the main tutorials ladder: where that ladder ends at a request/response service plus a webhook, this one is about everything that happens off the request path.

The differentiator this track proves is durable background processing you did not hand-roll: the file-watch trigger, the job, the queue, and the cron are first-class NetScript primitives wired into one orchestrated runtime — in place of the pile of cron entries, ad-hoc nohup workers, and bespoke glue scripts most teams reach for, the kind that silently drop a file or a row when a process dies mid-run.

  1. 1 · Scaffold
  2. 2 · Import job
  3. 3 · Polyglot transform
  4. 4 · Queue & cron
  5. 5 · Deploy

What you will build

By the end of this five-chapter track you will have my-erp/ on disk: a NetScript workspace with the workers and triggers plugins installed, a file-watch trigger that fires the moment the SAP export job drops a products_*.csv into the hand-off folder, a background job that parses it, a runnable transform task — executed as a sandboxed subprocess — that rewrites the legacy columns and integer-cent prices into Dynamics' shape, a queue sized for backfill bursts, and a cron schedule that re-syncs nightly — all orchestrated locally by Aspire and visible in one dashboard. Along the way you will see how the same task builder targets polyglot (non-TypeScript) runtimes, so a Python or shell step can join the pipeline when TypeScript is not the right tool.

The spine is one idea repeated at every layer: durable background processing. The stakes are concrete: a file the watcher misses is a day of catalog changes Dynamics never sees; a row loaded untransformed puts prices off by a factor of one hundred; a burst that overwhelms a single worker delays the re-sync everyone plans against. An inbound file becomes a queued job; the job runs in an isolated worker; the transform runs in a sandboxed subprocess; recurring work runs on a schedule; and nothing is lost across a restart.

The arc

SAP export job drops products_2024.csv     (a file lands in .data/incoming/products)
        │  defineFileWatch trigger fires on 'create'
        ▼
enqueueJob('import-products')              (a durable worker job)
        │  the job parses + records the raw SAP rows
        ▼
normalize-sap transform task               (sandboxed deno subprocess: SAP shape → Dynamics shape)
        │
        ▼
queue provider (Deno KV → Redis/RabbitMQ)  (sized for backfill bursts in config)
        │
        ▼
cron / scheduled trigger                   (nightly re-sync until cutover)

Every chapter on this spine is hands-on and closes on something you can observe — a JSON body, a log line, a file on disk. Chapter 3 also carries the track's one deliberately forward-looking section: the Python variant of the transform, marked plainly as a step for your own host because non-Deno runtimes are not sandboxed and need their interpreter installed.

The chapters

Before you start

This track assumes the same local toolchain as the main ladder: a recent Deno and the .NET Aspire CLI on your PATH, plus Docker running so Aspire can provision Postgres and Redis. This track uses Postgres (the default; swap --db postgres for mysql, mssql, or sqlite when you scaffold). If NetScript is brand new to you, walk the Storefront tutorial first — it explains every generated directory in more depth than we re-cover here. This track then re-grounds you from a fresh scaffold, so you can start either place.

After this track, keep building in Build › Background jobs — the guides and recipes there pick up where these chapters stop.