Устаревание и апгрейды
Блок живёт дольше страницы, на которую его поставили. Эта страница — про то, как выглядит его старение с обеих сторон: для автора блока и для владельца страниц, на которых блок стоит.
Устаревший блок
Заголовок раздела «Устаревший блок»У глобального блока есть флаг «устаревший» (is_deprecated). Он не удаляет блок,
а убирает его с витрины:
- блок пропадает из списка блоков и из поиска;
- уже добавленные экземпляры продолжают работать и публиковаться как прежде;
- администратор видит такие блоки с явной пометкой «Устаревший».
Флаг ставит администратор и только глобальному блоку. Свой приватный блок пометить устаревшим нельзя — его достаточно удалить или перестать использовать.
Что делать, если нужный вам блок устарел:
- Посмотреть, нет ли в каталоге блока на замену.
- Форкнуть устаревший блок, пока он ещё доступен, — форк станет вашим приватным блоком и от чужих решений больше не зависит.
- Перевести страницы на замену — это ручная миграция, см. ниже.
Обновление блока на странице
Заголовок раздела «Обновление блока на странице»Экземпляр блока закреплён за ревизией, с которой его добавили (почему). Обновление — явное действие, и вариантов ровно два.
Minor: обновляется одним запросом
Заголовок раздела «Minor: обновляется одним запросом»Если у библиотечного блока выросла только минорная часть версии (1.2 → 1.5),
экземпляр переводится на свежую ревизию без потери значений:
POST /api/v1/pages/{pageId}/blocks/{pbId}/upgradeЭкземпляру проставляется новая ревизия, версия и свежий снимок схемы;
placeholder_values остаются как были. Поля, которые появились в новой версии,
берут значения по умолчанию.
Всю страницу разом обновляет:
POST /api/v1/pages/{pageId}/blocks/upgrade-allОтвет разложен на три группы:
| Поле ответа | Что там |
|---|---|
upgraded |
обновлённые экземпляры с версиями «из» и «в» |
skipped_major |
пропущенные из-за ломающего изменения, с removed_fields |
already_up_to_date |
те, кому обновление не требовалось |
Операция атомарная: либо применились все minor-обновления, либо ни одно.
Major: апгрейд заблокирован
Заголовок раздела «Major: апгрейд заблокирован»Если у блока сменилась мажорная версия, автоматический апгрейд не выполняется — из схемы исчезли поля, и молча перенести значения некуда. Запрос вернёт 422:
{ "error": "major_upgrade_blocked", "message": "Block has breaking changes (v1.2 → v2.0). Migrate manually…", "current_pin": { "major": 1, "minor": 2 }, "library_version": { "major": 2, "minor": 0 }, "removed_fields": ["subtitle", "cta"]}removed_fields — это и есть план миграции: список того, чему в новой схеме
нет соответствия.
Ручная миграция через major
Заголовок раздела «Ручная миграция через major»Порядок действий:
- Прочитать новую схему блока —
GET /api/v1/blocks/{id}/placeholder-schemaдаёт готовый контракт значений и минимальный валидный пример. - Сопоставить старые значения с новыми полями. Для полей из
removed_fieldsрешить, куда переносится содержимое (или что оно больше не нужно). - Заменить экземпляр на странице, передав новые значения:
PUT /api/v1/pages/{pageId}/blocks/{pbId}/replace{ "block_id": 7, "placeholder_values": { … } }Замена сохраняет позицию блока на странице: старый экземпляр удаляется, новый встаёт на его место и закрепляется за актуальной ревизией.
Эквивалентный путь — вставить новый экземпляр на ту же позицию
(POST /api/v1/pages/{pageId}/blocks) и удалить старый
(DELETE /api/v1/pages/{pageId}/blocks/{pbId}). Разница только в количестве
запросов.
Массовая проверка: где что устарело
Заголовок раздела «Массовая проверка: где что устарело»Аудит удобно делать в два шага:
- Найти страницы с неактуальными блоками:
GET /api/v1/pages?has_outdated=1. - Для каждой вызвать
upgrade-allи разобратьskipped_major— это очередь ручной работы.
Так автоматическая часть закрывается одним проходом, а внимание тратится только на действительно ломающие изменения.
Со стороны автора блока
Заголовок раздела «Со стороны автора блока»- Ломающее изменение стоит дорого: после major никто не обновится автоматически. Каждый пользователь блока будет мигрировать руками.
- Хотите убрать поле — сначала перестаньте использовать его в шаблоне, оставив в схеме. Удалить его можно будет позже, когда это перестанет кого-либо касаться.
- Меняете смысл поля при том же имени — это minor, автоматика ничего не заподозрит. Пишите об этом в changelog явно.
- Блок стал не нужен — не удаляйте глобальный блок, а попросите пометить его устаревшим: страницы пользователей останутся живыми.
Источники: backend/src/Entity/Block.php (isDeprecated),
backend/src/Service/Block/UpdateBlockService.php,
backend/src/Repository/BlockRepository.php,
backend/src/Service/Page/{UpgradePageBlockService,BulkUpgradePageBlocksService,ReplacePageBlockService}.php,
backend/src/Controller/V1/PageBlock/**,
backend/src/Service/BlockVersionService.php (computeUpdateStatus, detectRemovedFields).