Templates & versions
There are three layers. They sound redundant at first; each does a specific job.
Mapping template
A template is a named recipe scoped to one source platform and one resource type. For example, Magento → Products v1 is a template. Every workspace sees the same default templates as read-only seeds.
Templates ship with sensible defaults for every resource Graftport knows how to move. You don’t create templates from scratch — you fork existing ones.
Mapping version
A version is an immutable snapshot of the JSONata text. Every Publish creates a new version; editing without publishing creates nothing. Past versions stick around so you can always trace exactly which version produced a given Shopify record, and Version history in the editor shows the line-by-line difference between any of them and what you have open.
A template has a current version, and that is what a new migration starts on. A later version of the template does not reach migrations that already exist — they stay on the version they were created with until you publish into them yourself.
Mapping
A mapping is the link between a (migration, resource) pair and a
specific template version. There’s exactly one per pair.
The mapping carries:
- The current version — the source of truth for what this resource produces. Publishing in the editor advances it.
- A pointer back to the template it came from.
- Whether the mapping uses a default template or a fork your workspace owns.
Why this many layers
Three concerns are kept clean:
| Concern | Layer that owns it |
|---|---|
| ”What’s the canonical mapping for Magento products?” | Template + its current version. |
| ”What did this specific run produce?” | The mapping version it was pinned to at run time. |
| ”Which version is this migration on?” | Mapping. |
That separation lets you upgrade one merchant’s mapping without touching the others, and lets you audit a year-old run by looking at its pinned version directly.