Контекст шаблону
Коли ви генеруєте код, Restorm передає весь ваш проєкт шаблону у формі
об’єкта ctx. Ваші моделі, ваші enum-и, ваші маршрути й насамперед їхні
наміри (searchable, PII, cache, і весь операційний профіль моделі: обсяг,
профіль доступу, трафік, свіжість, чутливість, збереження) — там; шаблон читає їх,
щоб вирішити, що генерувати. Для цього не потрібна змінна: інформація, яку ви вже
ввели в проєкт, безпосередньо доступна.

Форма ctx
Section titled “Форма 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, varsПосилання робляться за назвою (ніколи за внутрішнім ідентифікатором):
property.enum — це назва enum, property.references.model — назва цільової
моделі, model.inherits — назва батька. У моделі properties[] перелічує її
власні властивості (для оголошення типу), а allProperties[] — власні +
успадковані, сплощені властивості (для повного екземпляра: приклади даних,
стовпці SQL, тіло запиту).
Читання прапорця: золоте правило
Section titled “Читання прапорця: золоте правило”Булеві прапорці присутні в ctx лише коли вони увімкнені. Рушій рендерить у
StrictUndefined: отже, потрібно перевіряти наявність ключа, ніколи не його
значення.
{# ✅ правильно — перевіряємо наявність #}{% if 'searchable' in p %}INDEX({{ p['name'] }}){% endif %}
{# ❌ хибно — викликає помилку, коли прапорець відсутній #}{% if p.searchable %}…{% endif %}Лише property.required (булевий) і route.auth (перелічення) присутні
завжди. Інші булеві прапорці — «присутній = істина»; поля зі значенням
(обсяг, операційний профіль, cache…) несуть своє значення, коли заповнені, і
відсутні інакше — те саме правило наявності.
| На властивості | На моделі | На маршруті |
|---|---|---|
readOnly · writeOnly · nullable | timestamps · softDelete (булеві) | idempotent · deprecated (булеві) |
unique · searchable · immutable · pii | Операційний профіль (значення): volumetry · accessPattern · traffic · freshness · sensitivity · retention | cacheSeconds (число) · pagination (об’єкт) |
Значення операційного профілю моделі: 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).
Приклад: кешування даних з високим попитом на читання
Section titled “Приклад: кешування даних з високим попитом на читання”Два випадки, залежно від того, чи інформація вже існує в проєкті, чи ні.
а) Проєкт уже несе інформацію
Section titled “а) Проєкт уже несе інформацію”Якщо ви заповнили тривалість кешу на маршруті, вона надходить у
route['cacheSeconds']; route['idempotent'] каже вам, що його безпечно кешувати
(лише читання):
{% 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 %}б) «Високий попит на читання» — це нативне поле моделі
Section titled “б) «Високий попит на читання» — це нативне поле моделі”Не потрібна змінна: «високий попит на читання» — це безпосередньо профіль
доступу моделі. У налаштуваннях моделі, група Операційний профіль, ви
вибираєте Переважно читання — шаблон читає це в model['accessPattern'].
Поєднайте його з model['freshness'] (толерантність до свіжості), щоб вирішити,
чи потрібно кешувати і на який час:
{% 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 }}); // кеш увімкнено ({{ ttl }}s){% endif %}{% endfor %}Зверніть увагу на перевірку != 'strong': модель з переважним читанням, але
із сильною узгодженістю не повинна кешуватися. У цьому вся суть того, щоб мати
обидва наміри поряд у проєкті.
Залиште змінні генерації для того, чого проєкт ще не несе (налаштування, властиве самому шаблону): бізнес-наміри — обсяг, профіль доступу, трафік, свіжість, чутливість, збереження — це нативні поля моделі.
Повний контракт
Section titled “Повний контракт”Цей контекст версіонований (ctx['contextVersion']) і вичерпно описаний
JSON-Schema, що постачається в репозиторії застосунку
(docs/contributing/design-codegen-context.schema.json) — скопіюйте його у ваш
шаблон, щоб його CI валідував еталонний контекст. AI-агент отримує той самий
контракт на льоту через MCP-інструмент get_design_template_contract.