examples/storefront Public
Seed a local catalog and write the local development guide
1 check passednpm run db:seed loads six products, one out of stock, into the local D1. The guide covers running all three Workers together, forwarding Stripe events and triggering the expiry cron by hand.
Changed files
5 files changed70 additions4 deletionsagainst 5c7d155
Added.rebasely/kb/guides/local-dev.md+51−0
| @@ -0,0 +1,51 @@ | ||
| +--- | ||
| +id: local-dev | ||
| +type: guide | ||
| +owner: justin | ||
| +describes: | ||
| + - wrangler.jsonc | ||
| + - workers/*/wrangler.jsonc | ||
| + - scripts/seed.sql | ||
| +reviewed: 2026-10-12 | ||
| +--- | ||
| +# Running the shop locally | ||
| + | ||
| +You need Node 24 and, for checkout, a Stripe account in test mode. Everything else runs in wrangler's local mode. | ||
| + | ||
| +## The API | ||
| + | ||
| +```bash | ||
| +npm install | ||
| +npm run db:migrate # applies migrations/ to the local D1 | ||
| +npm run db:seed # six products, one of them out of stock | ||
| +echo 'ADMIN_TOKEN=dev-admin-token' > .dev.vars | ||
| +npm run dev # storefront-api on localhost:8787 | ||
| +``` | ||
| + | ||
| +`curl localhost:8787/products` lists all six; the candle is out of stock, so adding it to a cart fails. Add `STRIPE_SECRET_KEY` (a test mode secret key) to `.dev.vars` to try checkout. | ||
| + | ||
| +Image URLs point at `IMAGES_URL` from `wrangler.jsonc`. Locally the upload works but the URL does not resolve, because the custom domain serves the production bucket ([[product-images]]). Set `IMAGES_URL` in `.dev.vars` to another origin if you want working links. | ||
| + | ||
| +## The other Workers | ||
| + | ||
| +Each has its own config, so run it in a second terminal from the repository root: | ||
| + | ||
| +```bash | ||
| +npx wrangler dev -c workers/stripe-webhook/wrangler.jsonc --port 8788 | ||
| +npx wrangler dev -c workers/fulfilment/wrangler.jsonc --port 8789 | ||
| +``` | ||
| + | ||
| +wrangler connects the `ORDERS` service bindings to the storefront-api you started first, and the `order-events` queue between storefront-api and fulfilment. See [[payment-webhook]] for forwarding Stripe's test events and [[fulfilment]] for the warehouse settings. | ||
| + | ||
| +## Cron | ||
| + | ||
| +The unpaid order expiry runs on a cron trigger. To run it once by hand: | ||
| + | ||
| +```bash | ||
| +npx wrangler dev --test-scheduled | ||
| +curl 'localhost:8787/__scheduled?cron=*/5+*+*+*+*' | ||
| +``` | ||
| + | ||
| +## Tests | ||
| + | ||
| +The tests need none of this; see [[testing]]. | ||
Changed.rebasely/kb/index.md+1−0
| @@ -26,4 +26,5 @@ | ||
| ## Guides | ||
| +- [[local-dev]]: running the three Workers on your machine. | ||
| - [[testing]]: how the tests run the real SQL without workerd. | ||
ChangedREADME.md+4−3
| @@ -20,17 +20,18 @@ | ||
| npm run typecheck | ||
| ``` | ||
| -To run the Worker locally: | ||
| +To run the API locally with a small seeded catalog: | ||
| ```bash | ||
| -npx wrangler d1 migrations apply storefront --local | ||
| +npm run db:migrate | ||
| +npm run db:seed | ||
| echo 'ADMIN_TOKEN=dev-admin-token' > .dev.vars | ||
| npm run dev | ||
| ``` | ||
| Product images are served from the bucket's custom domain, `IMAGES_URL` in `wrangler.jsonc`. Checkout needs Stripe: add `STRIPE_SECRET_KEY` to `.dev.vars` with a secret key from your Stripe account's test mode. | ||
| -Then add a product and look at the catalog: | ||
| +The guide in `.rebasely/kb/guides/local-dev.md` covers the other two Workers and the cron trigger. To add a product and look at the catalog: | ||
| ```bash | ||
| curl -X PUT localhost:8787/admin/products/wool-socks \ | ||
Changedpackage.json+2−1
| @@ -12,7 +12,8 @@ | ||
| "test": "node --disable-warning=ExperimentalWarning --test \"test/**/*.test.ts\"", | ||
| "typecheck": "tsc", | ||
| "dev": "npx wrangler dev", | ||
| - "db:migrate": "npx wrangler d1 migrations apply storefront --local" | ||
| + "db:migrate": "npx wrangler d1 migrations apply storefront --local", | ||
| + "db:seed": "npx wrangler d1 execute storefront --local --file scripts/seed.sql" | ||
| }, | ||
| "devDependencies": { | ||
| "@cloudflare/workers-types": "^5.20261016.1", | ||
Addedscripts/seed.sql+12−0
| @@ -0,0 +1,12 @@ | ||
| +-- A small catalog for local development: npm run db:seed (after npm run db:migrate). | ||
| +-- Re-running it resets these products' prices and stock. | ||
| +INSERT INTO products (id, name, description, price_cents, stock, active, created_at, updated_at) VALUES | ||
| + ('wool-socks', 'Merino wool socks', 'Midweight crew socks in undyed merino. Sold as a pair.', 1800, 40, 1, 1759276800000, 1759276800000), | ||
| + ('canvas-tote', 'Waxed canvas tote', 'A 20 litre tote in waxed cotton canvas with leather handles.', 4800, 12, 1, 1759276800000, 1759276800000), | ||
| + ('enamel-mug', 'Enamel camp mug', 'A 350 ml steel mug with a rolled rim. Goes on a stove.', 1600, 60, 1, 1759276800000, 1759276800000), | ||
| + ('linen-apron', 'Linen work apron', 'Heavy linen with two front pockets and cross-back straps.', 5200, 8, 1, 1759276800000, 1759276800000), | ||
| + ('beeswax-candle', 'Beeswax pillar candle', 'Hand-poured, about 40 hours of burn time.', 2200, 0, 1, 1759276800000, 1759276800000), | ||
| + ('field-notebook', 'Field notebook, 3 pack', 'Pocket notebooks with dot grid pages and a kraft cover.', 1400, 100, 1, 1759276800000, 1759276800000) | ||
| +ON CONFLICT (id) DO UPDATE SET | ||
| + name = excluded.name, description = excluded.description, price_cents = excluded.price_cents, | ||
| + stock = excluded.stock, active = excluded.active, updated_at = excluded.updated_at; | ||
Checks
1 check passed| Status | Check | Reported by | Description | Details |
|---|---|---|---|---|
| Success | duragit/ci/test | Rebasely Actions | succeeded | Run |
Runs
| Status | Workflow | Event | Started |
|---|---|---|---|
| Success | ci | Push |