Skip to main content
Alpha

Run it locally under Aspire

You have built the whole ERP sync: a file-watch import job, a queue, and a cron schedule, plus an understanding of polyglot transform tasks. This final chapter runs all of it together — workers, triggers, queue, and cron processors — on one machine under aspire start, and shows you how to read the running system from the dashboard. It is the local orchestration story: one command, one observable stack, throwaway infrastructure.

  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 chapter you will bring the full my-erp/ resource graph up with a single aspire start — Postgres, Redis, the workers API + processor, and the triggers API + processor (which runs your file-watch and cron triggers) — initialize the database through the running AppHost, and read the live import pipeline in the Aspire dashboard: resources, console logs, and the traces that stitch a file drop to its job execution.

Before you begin

You need the complete my-erp/ workspace from Chapter 4: the workers and triggers plugins, the import-products job, the product-import-trigger file watch, and the daily-resync-schedule cron. Docker must be running so Aspire can provision Postgres and Redis. Confirm the AppHost was scaffolded (it is a TypeScript/Node program, not C#):

ls aspire/apphost.mts aspire/aspire.config.json

Expected: both files exist. netscript init generated them in Chapter 1; you never hand-write them.

Step 1 — Understand the graph you are about to run

The resource graph is derived from your installed plugins at boot via composeAppHost — add a plugin and its API plus background processor appear; remove it and they vanish, no edit to apphost.mts. With workers and triggers installed, a single aspire start stands up this graph:

What aspire start brings up for the ERP sync
NameTypeDescription
aspire (dashboard) https://localhost:18888 / http://localhost:18889 Live resource list, console logs, structured logs and traces. A login token is printed on start.
OTLP collector http://localhost:4318 OpenTelemetry endpoint the dashboard runs; framework spans and structured logs land here automatically.
postgres Container Throwaway Docker Postgres. The database netscript db commands target — reachable only while Aspire is up.
redis Container (cache) Redis cache — the default --cache-backend; Redis-compatible. Backs the KV/queue workloads — this is what auto-discovery resolves the queue to once it is up.
workers API + processor :8091 (PLUGIN_API range) + executable The :8091 API enqueues; a separate background processor drains the queue and runs your import job.
triggers API + processor :8093 (PLUGIN_API range) + executable The :8093 API plus the processor that runs your file-watch and cron triggers.

Step 2 — Restore and run

The AppHost runs on its own isolated Node runtime inside aspire/ so its dependencies never leak into your Deno workspace. Restore once per machine, then run — both from inside aspire/:

cd aspire
aspire restore   # one-time SDK restore (and after an SDK bump)
aspire start       # boots the whole graph; prints the dashboard URL + a login token

aspire start brings up infrastructure first, then the plugin APIs and background processors, with cross-references resolved into injected environment variables. Leave it running.

Step 3 — Initialize the database through the running AppHost

With Aspire up, Postgres is live and the netscript db commands can reach it. Run them from the workspace root in a second terminal (leave aspire start going in the first):

netscript db init --name init   # create + apply the first migration
netscript db generate           # generate the Prisma client
netscript db seed               # optional: seed development data

These talk to the Postgres container Aspire provisioned. Run them with no Aspire up and they fail — there is no Postgres for them to reach.

Step 4 — Watch the pipeline run end to end

With the full stack up, exercise the pipeline you built and read it from the dashboard. Drop a file:

cat > .data/incoming/products_live.csv <<'CSV'
name,sku,price
Anvil,ANV-9,49.99
CSV
mv .data/incoming/products_live.csv .data/incoming/products/products_live.csv

Then open https://localhost:18888, paste the login token aspire start printed, and use the three dashboard surfaces:

Reading the running ERP sync in the Aspire dashboard
NameTypeDescription
Resources tab Every container and executable with status and the port it bound. Confirm workers, triggers, postgres, and redis are all green.
Console logs tab stdout/stderr per resource. Open the workers processor to read your import job's log lines; the triggers processor shows the file-watch event.
Structured logs + Traces tab Spans correlated by traceparent. The framework instruments job dispatch and execution automatically, so a file drop → job run trace appears with no extra wiring.

Because Aspire starts each resource with an OTLP endpoint pointed at http://localhost:4318, framework-level spans (job dispatch, job execution, scheduler runs) surface in the Traces view on their own.

Verify your progress

Confirm the whole graph is healthy and the pipeline ran:

# Both plugin APIs answer.
curl http://localhost:8091/health
curl http://localhost:8093/health

# The dropped file produced an import execution.
curl 'http://localhost:8091/api/v1/workers/executions?limit=10'

Expected: both health checks return healthy JSON, and the executions feed shows a completed import-products run for products_live.csv.

  • [ ] aspire start is up; the dashboard lists postgres, redis, workers, and triggers all green.
  • [ ] netscript db init/generate succeeded against the Aspire Postgres.
  • [ ] curl :8091/health and curl :8093/health both return healthy.
  • [ ] A file drop produced an import-products execution and a dispatch/execution trace in the dashboard.

What you built

You ran the complete ERP sync — workers, triggers, queue, and cron — on one machine under a single aspire start, initialized the database through the running AppHost, and watched a file drop flow into a durable job execution with its trace in the dashboard. You now have an end-to-end durable background-processing backend, and you know exactly where the local story ends and a production deployment begins.

Where to go next

You have finished the ERP Sync track. From here, branch into task-oriented and reference docs: