Malens kontekst
Når du genererer kode, sender Restorm hele designet ditt til malen i form av
et ctx-objekt. Modellene dine, enums dine, rutene dine og fremfor alt
intensjonene deres (searchable, PII, cache, og hele den operasjonelle
profilen til modellen: volum, tilgangsprofil, trafikk, ferskhet, sensitivitet,
oppbevaring) er der — en mal leser dem for å bestemme hva som skal genereres.
Ingen variabel er nødvendig for det: informasjonen du allerede har lagt inn i
designet, er direkte tilgjengelig.

Formen på ctx
Section titled “Formen på ctx”ctx├─ design # name, version, description, basePath, defaultAuth, vars├─ enums[] # name, description, values[]├─ models[] # name, description, inherits, identifier, timestamps, softDelete,│ # volumetry, accessPattern, traffic, freshness, sensitivity,│ # retention, properties[], allProperties[], examples[], vars└─ groups[] # name, basePath, versionPrefix, headers[], routes[] └─ routes[] # method, path, fullPath, params[], body, responses[], # auth, pagination, cacheSeconds, idempotent, deprecated, varsReferansene gjøres via navnet (aldri via en intern identifikator):
property.enum er navnet på enumen, property.references.model navnet på den
tilsiktede modellen, model.inherits navnet på forelderen. På en modell lister
properties[] dens egne egenskaper (for deklarasjonen av typen) og
allProperties[] de egne + arvede, utflatede egenskapene (for en komplett
instans: eksempeldata, SQL-kolonner, forespørselskropp).
Les et flagg: den gylne regelen
Section titled “Les et flagg: den gylne regelen”De boolske flaggene er kun til stede i ctx når de er aktivert. Motoren
rendrer i StrictUndefined: man må derfor teste tilstedeværelsen av
nøkkelen, aldri verdien dens.
{# ✅ correct — on teste la présence #}{% if 'searchable' in p %}INDEX({{ p['name'] }}){% endif %}
{# ❌ faux — lève une erreur quand le flag est absent #}{% if p.searchable %}…{% endif %}Kun property.required (boolsk) og route.auth (oppregning) er alltid til
stede. De andre boolske flaggene er «til stede = sann»; feltene med verdi
(volum, operasjonell profil, cache…) bærer verdien sin når de er utfylt, og er
fraværende ellers — samme tilstedeværelsesregel.
| På en egenskap | På en modell | På en rute |
|---|---|---|
readOnly · writeOnly · nullable | timestamps · softDelete (boolske) | idempotent · deprecated (boolske) |
unique · searchable · immutable · pii | Operasjonell profil (verdier): volumetry · accessPattern · traffic · freshness · sensitivity · retention | cacheSeconds (tall) · pagination (objekt) |
Verdiene for den operasjonelle profilen til en modell: accessPattern
(readHeavy / writeHeavy / balanced / appendOnly), traffic
(low / medium / high), freshness (strong / shortCache / longCache),
sensitivity (public / internal / confidential / pii), retention
(permanent / archivable / ephemeral), volumetry (hundreds /
tenThousands / millions).
Eksempel: cache data med høy leseetterspørsel
Section titled “Eksempel: cache data med høy leseetterspørsel”To tilfeller, avhengig av om informasjonen allerede finnes i designet eller ikke.
a) Designet bærer allerede informasjonen
Section titled “a) Designet bærer allerede informasjonen”Hvis du har fylt ut en cachevarighet på en rute, ankommer den i
route['cacheSeconds']; route['idempotent'] forteller deg at den er trygg å
cache (skrivebeskyttet):
{% for group in ctx['groups'] %}{% for route in group['routes'] %}{% if 'cacheSeconds' in route and 'idempotent' in route %}// {{ route['method'] }} {{ route['fullPath'] }}app.use("{{ route['fullPath'] }}", cache({{ route['cacheSeconds'] }}));{% endif %}{% endfor %}{% endfor %}b) «Høy leseetterspørsel» er et innebygd felt på modellen
Section titled “b) «Høy leseetterspørsel» er et innebygd felt på modellen”Ingen variabel nødvendig: «høy leseetterspørsel» er direkte tilgangsprofilen
til modellen. I innstillingene til modellen, gruppen Operasjonell profil,
velger du Lesedominant — malen leser det i model['accessPattern']. Kombiner
det med model['freshness'] (toleranse for ferskhet) for å avgjøre om det skal
caches, og for hvor lenge:
{% for model in ctx['models'] %}{% if model['accessPattern'] == 'readHeavy' and model['freshness'] != 'strong' %}{% set ttl = 3600 if model['freshness'] == 'longCache' else 60 %}registerCache("{{ model['name'] }}", {{ ttl }}); // cache activé ({{ ttl }}s){% endif %}{% endfor %}Merk testen != 'strong': en lesedominant modell men med sterk konsistens
skal ikke caches. Det er nettopp hele poenget med å ha de to intensjonene side
om side i designet.
Reserver genereringsvariablene til det som designet ikke allerede bærer (en mal-egen innstilling): forretningsintensjonene — volum, tilgangsprofil, trafikk, ferskhet, sensitivitet, oppbevaring — er innebygde felt på modellen.
Det komplette kontraktet
Section titled “Det komplette kontraktet”Denne konteksten er versjonshåndtert (ctx['contextVersion']) og beskrevet
uttømmende av et JSON-Schema levert i repositoriet til applikasjonen
(docs/contributing/design-codegen-context.schema.json) — kopier det til malen
din slik at dens CI validerer referansekonteksten. En AI-agent oppnår det samme
kontraktet i farten via MCP-verktøyet get_design_template_contract.