Skip to content

EmbeddedEra WooCommerce sandbox

Public, non-indexed fictional development sandbox at https://dev.embeddedera.com; not production. Its bounded interactive mode expires 2026-09-27 14:05 UTC and then fails back to read-only review. Cloudflare Access still protects administration and login paths. Project and capability status: projects/embeddedera-store. Source repository /home/angel/embeddedera-store, branch sandbox.

Runtime

  • Compose project embeddedera-store: db (MariaDB), wordpress (WordPress 7.1.1 / WooCommerce 11.1.1), tools-profile wpcli, access-profile ingress (Caddy), workers-profile scheduler (WP-CLI).
  • Application and database use embeddedera-store_internal, Docker internal=true; no direct external route. The credential-free read-only Caddy ingress publishes only 127.0.0.1:8500, resolves wordpress through Docker DNS and has no database credentials or application mounts. Its second bridge permits the loopback publish but disables IP masquerade, so the ingress has no internet route.
  • Plex Cloudflare tunnel routes dev.embeddedera.com to loopback port 8500, with a proxied CNAME. Access app EmbeddedEra Store Development protects dev.embeddedera.com/wp-admin*; EmbeddedEra Store Login protects /wp-login.php. Both use the engineering registry token and remain in hourly access-sync. Canonical WordPress home/siteurl are HTTPS; .env EE_STORE_URL preserves this through bootstrap.
  • Named volumes embeddedera-store_wp_data and embeddedera-store_db_data. Generated configuration/credentials and WooCommerce ZIP under repo .env and .local (ignored); never publish their contents.
  • Image digests and WooCommerce ZIP checksum recorded in dependencies.lock.json. Source is not yet a remote repository.
  • Application mail and WordPress external HTTP intercepted by mu-plugins/sandbox.php; CLI uses same guard mount. Physical printer and payment/shipping providers are not connected.

Operations

From the repo run bash scripts/start-sandbox.sh. Stop named sandbox services with docker compose --profile access --profile workers stop scheduler ingress wordpress db; preserve volumes. Do not run any command against the torrentvpn compose project for this sandbox. No auto-start guarantee or production backup/SOP coverage is claimed. No ERP stock mutation is implemented. The example checkout has shipping disabled and accepts only fictional check/bank instructions.

Verification

2026-09-19: catalog API returned three sample products; actual Store API guest check and bank-transfer checkout created orders 14/15 on hold. External socket attempt from WordPress failed; wp_remote_get returned a blocking error and pre_wp_mail was intercepted. WordPress and database health checks passed. B2B portal passed 17 integration checks and concurrent distinct-key/duplicate-key release tests. Release requests are advisory and do not reserve ERP inventory.

Scheduler and extension checkpoint

2026-09-19: scheduler is a non-root WP-CLI container on the same internal network, with only sandbox DB credentials, read-only root filesystem, temporary /tmp, dropped capabilities, 256 MiB limit and rotated logs. It runs native WP-Cron every 60 seconds; Action Scheduler and cart-recovery callbacks executed and heartbeat became healthy. The start script starts it after bootstrap. Heartbeat does not assert business-job success. HPOS enabled with compatibility sync. Official Stripe 11.0.0 is installed/test-mode/disabled, no keys. Recovery 2.1.3 configured for 4/24-hour native reminders; all mail still intercepted. Fulfillment plugin passed fixture integration/concurrency tests; no carrier, ERP allocator or printer connected. Application/DB/scheduler observed at approximately 146/111/33 MiB; configured caps 384/256/256 MiB. At this checkpoint no public proxy/DNS or production stack had changed. Subsequent dev preview publication is documented above.

Storefront runtime correction — 2026-09-19

The EmbeddedEra child theme is mounted read-only into WordPress/CLI/scheduler. Clean WooCommerce permalinks and real 404 behavior are enabled; default starter pages are draft, default footer replaced, and public company-site links verified. Woo Coming Soon is disabled because it hid the actual order confirmation even behind the development gate; the gate and sandbox guards remain enabled.

The earlier socat ingress exposed PID exhaustion and long-tail failures under keep-alive load. It was superseded by bounded Caddy connection reuse on 2026-09-19. WordPress retains four Apache/PHP workers and a small spare pool. This is a development budget, not production capacity acceptance.

User timer ee-store-catalog-observe.timer runs scripts/refresh-erp-catalog.py --apply every five minutes with up to 20 seconds jitter. It reads production ERP part 198 via GET using the existing host-only credential and writes only private Woo observed-quantity/timestamp metadata for EE-C-0184. It cannot change price, sellable stock, product release or ERP data. Failures preserve the old observation timestamp and fail the systemd unit; no outbound alert is configured yet. Unit sources: repo config/systemd/. Result and schedule verified. Live ERP allocation/order integration remains pending.

B2B and listing guard checkpoint — 2026-09-19

The ee-listing-guard plugin is mounted read-only in WordPress, CLI and scheduler, activated at bootstrap, and blocks pending products including Store API and inherited variation purchases. Business schema is version 4; migration keeps historical release state values. Native onboarding and staff review work in the gated preview; company labels are explicit mappings, never domain-based access. No production customer membership is assigned. Phone portal rows stack, and portal JavaScript is enqueued outside filtered account content. Development policies remain an explicit preview notice; staff Google-to-WordPress SSO is not installed.

Order synchronization — 2026-09-19

Host user timer ee-store-order-sync.timer runs every minute (systemd coalescing up to one minute), service source in store config/systemd/. Worker scripts/order-sync.py uses private .local/order-sync.env and SQLite ledger .local/order-sync/, guarded by flock. Writes are hard-pinned to existing ERP sandbox http://127.0.0.1:8300; no production ERP writes. New checkout enrollment is enabled; unknown SKU/customer conflicts remain review errors. Staff page: WooCommerce → ERP Order Sync.

On 2026-09-20, durable review states (blocked, unmapped, reconciliation_required, pending) stopped failing the systemd unit on every minute. They remain visible in the staff report and Woo metadata; actual processing state error, shipment failures and import failures still exit nonzero. Live service and 45 unit tests passed.

Native acceptance used fictional Woo orders 79–82 → sandbox SOs 10–13, customer 61 (EE Store Sync Test — fictional), and part 198. Only sandbox part 198 was marked salable; fictional stock 43 (10 cells) funded shipment 1. Probe SO9 was cancelled. Stock/price/release guards remain: battery sale stock zero, pending release. No real money, postage or physical inventory moved. Stop both order timer and active service before sandbox resets; preserve ledger and verify part/customer identities before resuming. SOP-037 documents operation and reconciliation. 45 network-denied tests and native/browser acceptance passed.

Quantity pricing extension — 2026-09-19

Free Tiered Pricing Table7.1.7 installed/activated from pinned local ZIP; dependency lock, downloader and bootstrap include it. Native fixed per-product rules apply quantity pricing to cart/Store API; a small MU display bridge renders its table on held block-template listings without a cart form. Theme table colors follow existing tokens. Retired five-pack URL redirects to single listing; no checkout/stock authority bypass. Battery53 uses units1 and min5 price4.99 (base5.95);78 is draft/hidden and historical5-unit mapping stays. Details in SOP-036 and battery project note.

Explicit fictional checkout — 2026-09-19

User requested testing the real battery listing. Local option ee_test_checkout_enabled=yes plus product53 _ee_test_checkout=yes allows test checkout despite retained pending release. Fictional stock allowance100; orders consume it and cancellations restore it. Retired78 remains blocked. Eligible carts offer only cheque-backed “Test order — no payment”; all-test carts require no shipping; test orders remain unpaid/on-hold with _ee_test_order=yes. No production stock/payment/carrier changes. Database remains MariaDB11.4.13 on named volume embeddedera-store_db_data; native accounts and HPOS orders already exist. SOP-035v4.1 owns operation.

After interruption/restart on 2026-09-19, the former socat ingress retained a stale WordPress address. The later Caddy ingress resolves wordpress through Docker DNS, so the temporary ee-store-ingress-refresh service/timer and script were removed and the installed user timer was disabled.

  • 2026-09-19: Source-mounted MU plugins catalog-navigation.php/assets/catalog-navigation.css add bounded native category links, 12-product first-party session recents and My orders. customer-order-status.php renders authorized native order status; no social provider or carrier map connected. Browser375/1440px14checks passed.

  • 2026-09-19: Ten extra test products101–110 across standard component categories, batch2026-09-19; local pending-release exception only, fictional price1/stock25. ERP read-only observation source; new SKUs remain mapping_required for order sync. Recently viewed now renders after archive collection with honest empty state; mobile/desktop14checks and mixed checkout114 passed (cancelled/restored). See store-test-catalog.

  • 2026-09-19 supersedes earlier recent-history implementation: removed MU history hooks/rendering; catalog-navigation now provides global Products disclosure with public-category query bounds. Header search/account/cart, footer Appearance and native breadcrumbs/grid; help pages115–118 under test-state wording. See store-customer-experience; fixture and browser acceptance recorded in project note.

Public review mode — 2026-09-20

Anonymous catalog browsing and first-party feedback are live on the development hostname. Review mode blocks purchase controls, checkout, account/login/registration content, reviews, waitlists, B2B requests and all anonymous REST writes except /wp-json/ee-preview/v1/feedback. Reports are private ee_feedback WordPress records with page, browser, optional email and Open/Triaged/Resolved state; no source IP is stored. Apache and WordPress emit noindex, nofollow, noarchive. External acceptance verified public 200 responses, Access 302 challenges on both staff paths, feedback 201 and cart mutation 403. SOP-040 owns feedback handling.

Performance checkpoint — 2026-09-19

The free/self-hosted stack now has Redis object caching, warm WP Super Cache files served before PHP, moderate same-origin prerendering, a bounded Caddy loopback proxy, one header-logo download, and an origin policy for safe Cloudflare HTML edge caching. Cart, checkout, account, B2B, feedback, REST, query-string, logged-in, cookie-bearing and error responses explicitly bypass shared HTML caching. Independent acceptance passed 63 host unit tests, 189 WordPress policy checks, 30 live HTTP separation checks, 13 browser performance checks and 172 storefront browser checks. A 1,000-request/25-concurrent warm-origin run completed without failures at 490–511 requests/s and 68–92 ms p99 across three runs. Cloudflare ruleset a6975addc32a4bb9b435a0cec1f4cb72 now applies three documented Cache Rules for public HTML, dynamic bypass and 30-day public static assets; Tiered Cache and Smart Topology are on. External verification observed MISS then HIT on public shop/product HTML and versioned static assets, with DYNAMIC bypasses for all tested private, stateful, catalog-query and API routes. Cloudflare Access still gates WordPress administration and login.

Commit c3caa6c adds automatic WebP product subsizes and a bounded marked regeneration step, conditionally removes gallery enhancements only from single-image simple products, removes frontend jQuery Migrate, and merges navigation CSS into the main theme request. Originals remain and richer product types retain WooCommerce's native gallery. The battery's displayed derivative is7.7KB WebP versus41KB PNG. Warm external product medians are30requests/~133KB with desktop LCP304ms and throttled-mobile LCP1,204ms, down from39requests/~274KB; CLS stayed0. Source/native/browser acceptance and a temporary multi-image fallback test passed. Details and rollback are in the repo performance document.

Automatic edge invalidation and performance gate — 2026-09-20

User timer ee-store-cloudflare-purge.timer is installed, enabled and active every minute. Product, stock, product-category and referenced product-image events write deduplicated SHA-256 exact URLs into a versioned/leased WordPress queue. The host worker alone reads /home/angel/.config/cloudflare/env; API failures do not acknowledge rows and expired leases recover after five minutes. Cloudflare Cache Rules now include internal method PURGE alongside GET/HEAD, while the dynamic bypass excludes PURGE; this was required for exact invalidation. Live proof: product event queued four URLs, worker acknowledged four, and EE-C-0184 changed from HIT to MISS then refill HIT. Queue was empty afterward.

WooCommerce native destroy-empty-sessions and product-instance caching are enabled. scripts/start-sandbox.sh now runs a three-sample public browser/cache budget gate. Verified medians: desktop Shop33 requests/144,792B/LCP396ms; product30/132,519B/LCP260ms; throttled mobile Shop32/136,612B/LCP1,236ms; product30/132,519B/LCP1,188ms; median public TTFB25ms or less and CLS0. The gate also confirmed dynamic routes never became Cloudflare hits. Source and runtime acceptance:74 host tests,16 queue checks,204 WordPress cache checks,30 HTTP checks and172 storefront browser checks.

Stripe test credentials — 2026-09-20

The official Stripe gateway has a validated pk_test_/sk_test_ pair stored in WooCommerce and remains disabled. Host-side Stripe API acceptance created and cancelled a test PaymentIntent successfully. The WordPress container remains on the internal network and cannot resolve or reach Stripe; the sandbox HTTP guard also blocks outbound provider calls. No public Stripe webhook exception exists yet. Restricted provider egress, signed webhook delivery and native checkout/refund acceptance are required before enabling the gateway. The private source copy is /home/angel/.config/embeddedera-store/stripe-test.env, mode 0600; values are not recorded here.

Stripe test payments deployed — 2026-09-20

This supersedes the credential-only checkpoint above. Official Stripe11.0.0 is enabled in test mode only. WordPress/db/Redis remain on the internal Docker network; a pinned credential-free Squid sidecar alone has egress and permits exact host api.stripe.com:443. WordPress policy additionally requires the configured test credential, HTTPS verification and no redirects. General WP HTTP and direct external sockets remain blocked. Proxy-down testing failed closed and recovered after restart.

Stripe test webhook https://dev.embeddedera.com/?wc-api=wc_stripe is public, signed and uncached; invalid live payload returned400/DYNAMIC while /wp-admin/ and /wp-login.php remained Access302. Signed payment/refund events recorded no webhook failure. Native browser order212 charged one fictional battery for$5.95, became processing, then a native full refund succeeded and changed it to refunded. Fictional stock was explicitly restored to100. Order214 used Stripe's decline card, remained failed/unpaid and did not reduce stock. Registered-account ERP sandbox synchronization remained blocked for missing explicit customer mapping; no production ERP, carrier, printer or email action occurred. Source commit79d638d plus pinger-log follow-up; operational steps in SOP-035 and repo docs/STRIPE-TEST-PAYMENTS.md.

Bounded public interactive sandbox — 2026-09-20

Enabled through 2026-09-27 14:05 UTC. Native fictional accounts require unique @example.invalid addresses. The marked test catalog supports bounded cart/checkout, Stripe test cards or no-payment orders, own-order history, pending B2B requests, verified reviews and feedback. Limits are three registrations and three orders per fixed UTC hour per hashed requester identity, twelve allowed Stripe attempts, three cart lines, five units per line, ten units and $100 total. No raw requester IP is stored by the limiter or on marked orders.

Cloudflare Cache Rules bypass /create-account alongside cart/checkout/account routes; external acceptance returned DYNAMIC for public personal routes while /wp-admin* and /wp-login.php remained Access-gated. Public order219 charged $17.85 in Stripe test mode, appeared in its owner's history and was fully refunded; order220 exercised the decline path. Fictional battery stock was checked and restored to100. Both orders carry _ee_public_sandbox=yes and _ee_order_sync_enabled=no; IP/user-agent fields are blank, and no ERP or fulfillment job was created. A five-process database concurrency check admitted exactly three quota slots and stored no raw IP. Operate, report or disable through scripts/configure-public-sandbox.php as documented by SOP-035 v4.6.

EE-C-0184 studio media — 2026-09-20

Product53 now uses a professional white-background labeled sample as its featured image and a matching connector-focused reverse view as a linked detail image. WordPress generated WebP originals and responsive derivatives. The second view remains in the description so the product retains the lightweight single-image WooCommerce gallery. External 375/1440 checks loaded both versioned images with no overflow or JavaScript errors. Product price tiers, fictional stock100, test checkout and pending production release were unchanged. Source commit c02f9b8; factual product and launch state remain in projects/store-battery-1s.

EE-C-0197 / 320 mAh battery preview — 2026-09-20

Production ERP part220 / EE-C-0197 is mapped to development Woo product227, one unit per item. The ERP record is active/purchaseable/component but non-salable; stock item86 records an estimated opening count of about85 at Shop/Shelf A/Bin03 with owner-reported $1.50 unit cost and a recount requirement. Woo pricing is $6.95 for 1–4 and $6.00 each for 5+, with fictional test stock100, _ee_test_checkout=yes and _ee_listing_release=pending. Featured and linked reverse studio images use WebP derivatives while preserving the single-image gallery path. Public375/1440 browser acceptance passed media, price table, checkout notice, no overflow/errors and a five-unit $30.00 cart. Source commit 4fcb2bf; details and release gaps: projects/store-battery-320mah.

Development tax fixture — 2026-09-21

WooCommerce tax calculation is enabled and based on shipping destination. The managed fixture applies 7% to US/NC addresses under the checkout label Sandbox tax — test only; Virginia and other states receive no rate from this fixture. Browser checkout verified $0.91 tax on $12.90 and a $13.81 total. scripts/configure-sandbox-tax.php owns enable/disable/report and refuses non-local WordPress environments. This representative rate must not be promoted: production requires destination-level rates and confirmed registration/collection obligations.

Official Stripe Tax for WooCommerce2.1.0 is active but its automatic calculation switch is off. Existing Stripe test credentials passed connector authentication; local defaults use General — Tangible Goods, and Stripe has an active NC test registration with livemode=false. The connector SDK is restricted through the existing exact-host api.stripe.com proxy. Stripe Tax status remains pending on a missing head-office address. The account support address is CA while the store default is NC, so no address was inferred or mutated. The flat development fixture remains active until the actual business address is supplied and Stripe checkout acceptance passes.

ERP-authoritative inventory plan — 2026-09-21

The next planned development phase extends the existing order-sync ledger with fresh ERP availability and exact stock allocation before Stripe test payment. A private reservation broker will own sandbox ERP credentials and idempotent ensure/inspect/release operations; Woo will retain catalog copy/prices and fail checkout closed for stale availability or ERP outage. Initial staff-only enrollment covers EE-C-0184→part198 and EE-C-0197→part220. Public fictional orders and production ERP remain excluded. Last-unit concurrency and ambiguous-write reconciliation are mandatory gates. Full design and rollback: /home/angel/embeddedera-store/docs/ERP-INVENTORY-DEV-PLAN.md.

ERP inventory Phase 1 — 2026-09-21

The store repo now owns config/erp-mapping-registry.json, mounted read-only into WordPress, scheduler and one-shot WP-CLI. It is the common identity source for order enrollment and read-only catalog observation. Current availability enrollment is EE-C-0184→ERP198 and EE-C-0197→ERP220; historical EE-C-0184-5PACK→ERP198 ×5 remains order-sync-only. scripts/refresh-erp-catalog.py uses .local/order-sync.env, rejects origins other than http://127.0.0.1:8300, and writes only private _ee_erp_observed_* metadata. ERP198 and ERP220 currently expose 85 total/unallocated, salable=false, and therefore zero derived available. Woo fictional stock remains 100 and both releases remain pending. Reservation flags are false until the Phase 2 broker exists.