Konteks template
Ketika Anda menghasilkan kode, Restorm meneruskan seluruh desain Anda ke template dalam
bentuk sebuah objek ctx. Model, enum, rute Anda, dan terutama
maksudnya (searchable, PII, cache, serta seluruh profil operasional
model: volume, profil akses, lalu lintas, kesegaran, sensitivitas, retensi)
ada di sana — sebuah template membacanya untuk memutuskan apa yang akan dihasilkan. Tidak perlu sebuah
variabel untuk itu: informasi yang telah Anda masukkan ke dalam desain
langsung tersedia.

Bentuk ctx
Section titled “Bentuk 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, varsReferensi dilakukan menurut nama (tidak pernah menurut pengenal internal):
property.enum adalah nama enum, property.references.model nama model
yang dituju, model.inherits nama induk. Pada sebuah model, properties[]
mendaftar propertinya sendiri (untuk deklarasi tipe) dan
allProperties[] properti sendiri + warisan, yang diratakan (untuk sebuah
instans lengkap: data contoh, kolom SQL, bodi permintaan).
Membaca sebuah penanda: aturan emas
Section titled “Membaca sebuah penanda: aturan emas”Penanda boolean hanya hadir di ctx ketika ia diaktifkan.
Mesin merender dalam StrictUndefined: jadi Anda harus menguji kehadiran
kunci, bukan nilainya.
{# ✅ benar — kita menguji kehadiran #}{% if 'searchable' in p %}INDEX({{ p['name'] }}){% endif %}
{# ❌ salah — memunculkan galat ketika penanda tidak ada #}{% if p.searchable %}…{% endif %}Hanya property.required (boolean) dan route.auth (enumerasi) yang
selalu hadir. Penanda boolean lainnya bersifat « hadir = benar »; bidang
ber-nilai (volume, profil operasional, cache…) membawa nilainya
ketika diisi, dan absen jika tidak — aturan
kehadiran yang sama.
| Pada sebuah properti | Pada sebuah model | Pada sebuah rute |
|---|---|---|
readOnly · writeOnly · nullable | timestamps · softDelete (boolean) | idempotent · deprecated (boolean) |
unique · searchable · immutable · pii | Profil operasional (nilai): volumetry · accessPattern · traffic · freshness · sensitivity · retention | cacheSeconds (angka) · pagination (objek) |
Nilai profil operasional sebuah model: 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).
Contoh: meng-cache data dengan permintaan baca tinggi
Section titled “Contoh: meng-cache data dengan permintaan baca tinggi”Dua kasus, tergantung apakah informasi sudah ada di desain atau tidak.
a) Desain sudah membawa informasinya
Section titled “a) Desain sudah membawa informasinya”Jika Anda telah mengisi sebuah durasi cache pada sebuah rute, ia tiba di
route['cacheSeconds']; route['idempotent'] memberi tahu Anda bahwa ia aman untuk
di-cache (baca-saja):
{% 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) « Permintaan baca tinggi » adalah bidang bawaan model
Section titled “b) « Permintaan baca tinggi » adalah bidang bawaan model”Tidak perlu variabel: « permintaan baca tinggi » langsung merupakan profil
akses model. Di pengaturan model, grup Profil operasional,
Anda memilih Baca dominan — template membacanya di
model['accessPattern']. Gabungkan dengan model['freshness'] (toleransi
kesegaran) untuk memutuskan apakah perlu di-cache, dan untuk berapa lama:
{% 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 diaktifkan ({{ ttl }}s){% endif %}{% endfor %}Perhatikan tes != 'strong': sebuah model dengan baca dominan tetapi dalam
konsistensi kuat tidak boleh di-cache. Inilah seluruh manfaat memiliki
kedua maksud berdampingan di dalam desain.
Sisakan variabel generasi untuk apa yang desain belum bawa (sebuah pengaturan khusus template): maksud bisnis — volume, profil akses, lalu lintas, kesegaran, sensitivitas, retensi — adalah bidang bawaan model.
Kontrak lengkap
Section titled “Kontrak lengkap”Konteks ini terversi (ctx['contextVersion']) dan dideskripsikan secara menyeluruh oleh
sebuah JSON-Schema yang disertakan di repositori aplikasi
(docs/contributing/design-codegen-context.schema.json) — salin ke dalam
template Anda agar CI-nya memvalidasi konteks referensi. Sebuah agen AI memperoleh
kontrak yang sama secara langsung melalui alat MCP get_design_template_contract.