Lewati ke konten

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.

Tab Code generation sebuah properti: penanda dan variabelnya yang dibaca oleh template

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, vars

Referensi 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).

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 propertiPada sebuah modelPada sebuah rute
readOnly · writeOnly · nullabletimestamps · softDelete (boolean)idempotent · deprecated (boolean)
unique · searchable · immutable · piiProfil operasional (nilai): volumetry · accessPattern · traffic · freshness · sensitivity · retentioncacheSeconds (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.

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.

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.