Skip to content

Prove native EmDash integration with Medusa v2 product references - #1

Merged
christopherjnelson merged 8 commits into
mainfrom
feat/medusa-proof-of-concept
Sep 30, 2026
Merged

christopherjnelson merged 8 commits into
mainfrom
feat/medusa-proof-of-concept

Conversation

@christopherjnelson

@christopherjnelson christopherjnelson commented Sep 30, 2026 •

Copy link
Copy Markdown
Member

Architectural foundation / proof of concept

This unmerged, unpublished PR establishes a native EmDash → Medusa v2 catalog integration. Medusa owns commerce; EmDash stores stable product references and presentation choices. It is not a production release and adds no cart/checkout work.

The focused cleanup makes product links site-configurable, keeps operational diagnostics private, formalizes public HTTPS deployment, and proves consumption of the installed package instead of relying solely on source-local entries.

Working slice and cleanup

  • Encrypted publishable-key settings, write-only secret reads, native React connection diagnostics/search, key/channel scope and explicit region pricing.
  • Portable Text selection by product title, autosave of reference-only data, and automatic Astro component registration.
  • Anonymous SSR of live, unpriced and missing products through the in-process public plugin route and EmDash ctx.http.fetch.
  • Site-configurable product URLs: productUrlTemplate?: string | null, disabled by default. Root-relative paths or absolute HTTPS storefront URLs accept exactly one :handle path token. Handles are encoded; malformed configuration, credentials, unsafe protocols, scheme-relative URLs, other tokens, query/fragment and dot segments are rejected at both descriptor and runtime creation. The demo explicitly opts into its /products/:handle placeholder route. No package route convention is assumed.
  • Safe operational diagnostics: public lookup errors return product null with the same calm visitor fallback. EmDash plugin logs contain only a stable code and validated product ID. Missing/deleted products use debug NOT_FOUND; failures warn with configuration/network/timeout/response/authentication-context/service codes. No key, raw exception, response body, sensitive headers or backend URL is logged. Missing/pre-route dispatcher failures cannot emit a plugin-context log; that limitation is documented.
  • Repeatable Docker Medusa/Postgres fixture with six products, two variants each, one collection/category, two regions and two scoped sales channels. Existing seed behavior was preserved and rerun successfully.

Supported deployment and intentional limitations

The configured Medusa Store API must be publicly reachable over HTTPS and approved in site plugin configuration. Private-network and localhost endpoints are unsupported under current EmDash network policy and deferred to upstream policy support. The local Cloudflare tunnel is solely a development/testing workaround to a fixed, read-only Store gateway. There is no EmDash patch, unrestricted network access, global-fetch production fallback or production proxy.

The first-100 product block picker remains intentionally unchanged. optionsRoute supplies no remote query/page/current-selection context; native admin search remains separate. A proper searchable/paginated block picker belongs in a future supported EmDash extension/upstream contract. There is no DOM workaround, editor fork, giant preload or catalog replication.

Store catalog prices use explicit region/key/channel context and v2 major units, and represent a coherent minimum variant price. They are not checkout totals or proof of stock availability. The fixture still uses unmanaged inventory. Region is a global default; no visitor-specific context was added. SSR still performs one lookup per block.

Installed-package validation / exports

pnpm package:consumer packs the built plugin locally with scripts disabled, installs the archive into a clean temporary fixture outside this checkout, and validates:

  • Runtime root and /client imports and descriptor option propagation.
  • Root/client declaration consumption with the locked TypeScript/Astro host.
  • Source-distributed /admin and /astro compilation through actual EmDash/Astro integration.
  • SSR site build with the installed descriptor's package entry paths, without local plugin entry overrides or a Medusa backend.
  • Required archive files and exclusion of fixtures/tests/local state/environment files/node_modules.

The fixture locks the complete host/plugin peer graph. The runner substitutes the freshly packed archive’s SHA-512 into a unique integrity marker in the temporary lock copy, then performs one frozen install with an empty pnpm metadata cache. This fixes an offline-add approach that failed on cold CI peer metadata. Temporary files are removed on success/failure. Repeated runs passed in about 17–19 seconds locally. The existing packaging approach (files, exports, main, types, source admin/Astro, compiled client and peers) remains valid and was not redesigned. No production dependency was added.

pnpm check now includes this validation after the package build. The existing CI checks job therefore runs it automatically; no additional workflow or hosted service is required.

Security and validation

Exact HTTPS allowed origins, EmDash SSRF controls, redirect rejection, five-second fetch/body timeout, 1 MiB response normalization bound, secret encryption/write-only reads, authentication/CSRF, escaped rendering and Medusa response validation remain intact. EmDash can buffer to its own larger transport bound before the plugin's limit. Deployment rate/concurrency limits and a deliberate commerce cache/CSP policy remain production hardening work.

96 unit/native-runtime tests and 14 real Store/gateway integration tests passed. Eight browser scenarios passed in both configured-CTA and disabled-CTA modes. Installed-tarball validation, strict typecheck, lint, formatting, declaration build, demo Astro build and Astro check passed. Astro check reports zero errors, warnings and hints; the build retains the upstream large-admin-chunk warning.

Independent GPT-6-Luna Medium agents implemented, tested and reviewed this cleanup. Legitimate strict-template validation, tarball-checksum, stale-count and formatting findings were resolved. Final review found no blocking option-propagation, renderer, export, diagnostic or security issue. The lead independently reviewed the diff and reran validation.

Reproduce

pnpm install --frozen-lockfile
pnpm exec playwright install chromium
pnpm build
pnpm dev:up
pnpm dev:tunnel       # separate terminal, wait for ready
pnpm dev:site         # separate terminal
pnpm dev:configure
pnpm check           # includes installed-tarball consumer validation
pnpm test:integration
pnpm exec astro build --root dev/site
pnpm exec astro check --root dev/site
pnpm test:e2e
pnpm package:consumer

For the no-CTA browser mode, stop the normal dev site and run MEDUSA_DEMO_DISABLE_PRODUCT_LINKS=1 pnpm dev:site and MEDUSA_DEMO_DISABLE_PRODUCT_LINKS=1 pnpm test:e2e in separate terminals. The normal four screenshots remain in docs/screenshots; no-CTA artifacts are in ignored .local/no-cta-screenshots.

See local development, exact validation record, architecture, security review, and twelve findings/estimates.

Screenshots

Native connection/catalog

Bounded product selector

Anonymous Astro rendering

Recommendation and deferred work

Ready to merge as the architectural foundation for PR #2, subject to reviewer approval. Both jobs in final CI run passed at cleanup head 3573409873ea606d55d62f8f507424c4320ca86f, including the cold-cache installed-tarball consumer and fresh Docker Medusa setup/integration suite. It remains unpublished and does not claim production readiness. Keep the next PR focused on supported picker improvements and batched SSR/context design under the public HTTPS deployment contract.

No carts, add-to-cart, checkout, variants UI, inventory/availability, collection/category blocks, grids, webhooks, synchronization, Medusa Admin access in the plugin or visitor-specific commerce context were added. Public-route abuse/cache/CSP/localization hardening and a separate release/deployment gate remain before production publication. Private backend support requires upstream EmDash policy changes rather than a workaround here. This cleanup does not merge or publish the PR.

@christopherjnelson
christopherjnelson merged commit 28997c6 into main Sep 30, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant