Перейти до вмісту

Контекст шаблону

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

Вкладка Code generation властивості: її прапорці та її змінні, прочитані шаблоном

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 · nullabletimestamps · softDelete (булеві)idempotent · deprecated (булеві)
unique · searchable · immutable · piiОпераційний профіль (значення): volumetry · accessPattern · traffic · freshness · sensitivity · retentioncacheSeconds (число) · 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': модель з переважним читанням, але із сильною узгодженістю не повинна кешуватися. У цьому вся суть того, щоб мати обидва наміри поряд у проєкті.

Залиште змінні генерації для того, чого проєкт ще не несе (налаштування, властиве самому шаблону): бізнес-наміри — обсяг, профіль доступу, трафік, свіжість, чутливість, збереження — це нативні поля моделі.

Цей контекст версіонований (ctx['contextVersion']) і вичерпно описаний JSON-Schema, що постачається в репозиторії застосунку (docs/contributing/design-codegen-context.schema.json) — скопіюйте його у ваш шаблон, щоб його CI валідував еталонний контекст. AI-агент отримує той самий контракт на льоту через MCP-інструмент get_design_template_contract.