Keep this document focused on actual architecture decisions for the repository.
This repository is a small Marketplace extension template. It is intentionally minimal, but it now has stable backend and frontend examples that should stay documented here.
backend/mpt_extension_python_template/app.pycreates theExtensionAppand registers all routers.backend/mpt_extension_python_template/settings.pydefinesExtensionSettingsand the required environment variables (for exampleMPT_PRODUCTS_IDS).backend/mpt_extension_python_template/routers/api/exposes extension API endpoints.backend/mpt_extension_python_template/routers/events/declares Marketplace event handlers.backend/mpt_extension_python_template/flows/pipelines/contains simple order and agreement pipelines.backend/mpt_extension_python_template/flows/steps/contains reusable pipeline steps.backend/mpt_extension_python_template/context/contains context adapters (for exampleEventAgreementContext) used by pipelines.backend/mpt_extension_python_template/routers/plugs/declares Marketplace Portal plug metadata.frontend/src/modules/contains the React plug entry points.static/contains generated frontend bundles served by the backend.
This document covers how the backend and frontend layers fit together in this repository; for the SDK APIs themselves, see the SDK references in README.md.
The extension currently registers:
- agreement API routes under
/api/v2/agreements - order event route
/events/v2/orders/purchase - agreement event route
/events/v2/agreements/complete - Marketplace Portal plugs that load bundles from
/static/: the agreement plug, socketless modal plugs opened by id, and a UI SDK showcase (an examples app, a guide, and per-socket "add a plug" demos)
Agreement API handlers read Marketplace agreement data through the SDK API service and return SDK APIResponse objects.
Event handlers receive Marketplace event payloads, log the event context, and execute a small pipeline. The pipelines are deliberately simple examples and should remain focused on extension-layer behavior rather than SDK internals.
Portal plugs are declared by backend metadata. The frontend build writes JavaScript bundles into static/; those bundles are referenced by plug href values and mounted into the backend container.
Frontend authoring rules — SDK usage, module structure, styling, and iframe compatibility shims — live in the shared frontend standard. This section only covers what is specific to this repository:
- Module layout: each directory under
frontend/src/modules/<name>/is a plug with anindex.tsxentry point; the esbuild config (frontend/esbuild.config.js) emits one IIFE bundle per module intostatic/<name>/index.js. - Shared layer:
frontend/src/shared/holds reusable building blocks —components/(presentational UI, includingAddPlugShowcasereused by theadd-*modules),hooks/(for exampleuseAgreement, which fetches/api/v2/agreements/{id}through the SDKhttpclient and exposes load/error/ready states), andmodel.ts(response types and formatters). - Build output: the build emits bundles plus sourcemaps, and TypeScript
declarations under
static/types/.
The static-asset bridge is the contract between the layers: the frontend writes
into static/, the backend serves it at /static, and the dev/prod image stages
differ in whether static/ is bind-mounted or baked in (see
docs/deployment.md). The iframe styling shims under
frontend/src/fixes/ exist for the reasons described in the shared standard's
iframe-compatibility section.
Migration examples live in backend/migrations/ and are managed by mpt-tool; see docs/migrations.md.
- Avoid fictional or speculative architecture.
- Put workflow details in the other topic-specific documents under
docs/. - Update this file when the repository gains stable components or non-trivial design rules.