12 KiB
2021-09 · Версионирование API · тройное ревью
Статус: принят к публикации после независимой интеграции. Исходно эта
партия не была подключена к web/data/editorial-revisions.mjs и не изменяла
web/data/articles.json. В revision намеренно нет date и author: overlay
переопределяет только slug, title, excerpt, contentHtml и
readingMinutes у трёх уже существующих архивных записей.
Состав и границы
editorial-2021-09-practice-api-versioning;editorial-2021-09-mechanism-api-versioning;editorial-2021-09-field-api-versioning.
Во всех трёх материалах один и тот же учебный endpoint:
POST /api/orders/{orderId}/confirm. Одна детерминированная fixture работает
в одном Node-процессе и использует только Array, Map и объекты. Она не
поднимает HTTP, базу, SDK, gateway или настоящий deployment.
Вне области пакета: registry, README, articles.json, audit-скрипты, очередь,
общий standard, Git и любые чужие файлы, включая mascot PNG.
Проход 1. Структура, тон и объём — пройдено
Три текста написаны как М4 сентября 2021 года: короткая техническая речь, границы ownership/reader-а, проверяемое условие и осторожный вывод. В первых двух абзацах каждой статьи названы наблюдаемый разрыв и цена. Нет рассказа о реальном клиенте, деплое, SLA, метрике или инциденте.
| Revision | Вопрос статьи | Итоговый body | Редакторский результат |
|---|---|---|---|
| Практика | Как выбрать additive-изменение, объявить поддержку и остановить опасный retirement | 8 274 | endpoint, таблицы, fixture, rollout и маршрут действий есть |
| Механизм | Почему request и response проверяются в разные стороны, а schema diff не ловит смену смысла | 8 944 | explicit policy unknown/absence/null и negative cases есть |
| Полевой разбор | Как собрать evidence и выбрать pause вместо рискованного rollback | 9 241 | матрица симптомов, evidence packet и rollback-safe action есть |
У каждой revision есть не менее пяти смысловых разделов, доступная таблица с
caption/thead, figure с содержательным alt/figcaption, рабочий
JavaScript-пример, нумерованный маршрут «симптом → причина → проверка →
действие» и три первичных источника. Первое срабатывание draft gate показало,
что в начале practice не было слова-маркера проблемы; текст исправлен до
финального запуска, а не исключён из проверки.
Проход 2. Техника, historical scope и fixture — пройдено
Историческая рамка ограничена источниками, доступными не позднее сентября 2021 года:
- OpenAPI Specification 3.0.3 от 20 февраля 2020 года;
- OpenAPI Specification 3.1.0 от 15 февраля 2021 года;
- RFC 8594
Sunsetот мая 2019 года.
Утверждения ограничены тем, что подтверждают эти документы: OpenAPI описывает
интерфейс и форму request/response, а не сертифицирует поведение конкретного
parser-а; Sunset — hint о будущей недоступности, а не гарантия и не замена
плана migration. Не смешиваются версия спецификации OpenAPI, версия API,
сегмент URL, schema compatibility и API compatibility.
Fixture фиксирует следующие проверяемые условия:
- v1 reader переживает добавленное optional response-поле
deliveryWindow, сознательно игнорируя его в своей модели; - v2 reader различает отсутствие поля,
nullи объект окна; - current service принимает v1 request без нового поля и v2 request с
допустимым
deliveryPreference; nullв request означает очистку, отсутствие — отсутствие изменения;- опечатка
deliveryPrefrenceотклоняется как unknown request field; - removal обязательного
totalMinorи semantic changeconfirmed → acceptedне проходят compatibility check; - candidate retirement останавливается до изменения: legacy response остаётся,
data mutation равна
false.
Во внутреннем техпроходе найдено ещё одно несоответствие: v2 reader наследовал
список ignoredFields от v1 и мог одновременно читать deliveryWindow и
показывать его игнорируемым. Reader исправлен: v2 исключает известное поле из
списка неизвестных, затем финальная fixture снова выполнена. Это исправление
не меняет договор v1 и не выдаёт учебную модель за поведение внешнего клиента.
Проход 3. Визуал, источники и выпускной preflight — пройдено
Три SVG самостоятельны: содержат title, desc, role="img", не содержат
JavaScript, foreignObject, inline event handler, external URL или raster data
URI. На мобильном рендере 375 px:
- rollout показывает пять ворот: contract, additive response, v2 request, failed retirement и pause до изменения;
- compatibility-схема отделяет response→client от request→current service;
- diagnosis-схема ведёт от evidence к первому нарушенному правилу и обратимому действию.
В первом Sharp-рендере заголовок compatibility-схемы обрезался справа. Он был сокращён с «Совместимость = направление + reader» до «Совместимость API: reader и поток», SVG повторно отрендерен и просмотрен: обрезания, overlap и горизонтального overflow не осталось.
Реальные команды и результаты
# cwd: /Users/gavrilovdev/tmp/progcode
node --check web/scripts/upgrade-2021-09.mjs
# PASS, code 0
# cwd: /Users/gavrilovdev/tmp/progcode/web
npm run audit:draft -- scripts/upgrade-2021-09.mjs
# PASS: 8 274 / 8 944 / 9 241 body chars
# cwd: /Users/gavrilovdev/tmp/progcode
node web/scripts/upgrade-2021-09.mjs --verify-fixture
# PASS: 12/12 assertions; contract-recorded → additive-response-preflight-passed
# → v2-request-preflight-passed → retirement-candidate-rejected
# → rollback-safe-pause
xmllint --noout \
web/public/assets/editorial/2021/api-versioning-rollout-2021.svg \
web/public/assets/editorial/2021/api-versioning-compatibility-2021.svg \
web/public/assets/editorial/2021/api-versioning-diagnosis-2021.svg
# PASS, code 0
# SVG safety: Node readFile scan for <script, <foreignObject, inline on*=,
# external URL and data:image (xmlns W3C namespace is permitted)
# PASS: none found
# Sharp: resize each SVG to width 375 and save PNG in /private/tmp
# PASS: 375×720, 375×680, 375×710; all three PNG viewed manually
npm run audit:draft вывела старые предупреждения npm о пользовательских
store-dir, cache-dir и public-hoist-pattern; они не относятся к П43 и не
менялись пакетом. Отдельная проверка export подтвердила: ровно три revision, и
в них отсутствуют date/author и иные поля overlay.
До независимой интеграции намеренно не выполнялись registry audit,
production-build, browser/API/database checks, git add, commit или push.
Пакет передаёт только пять разрешённых файлов.
Независимая редактура и интеграция · 31 июля 2026
Основной редактор перепроверил первичные источники, code/figure agreement и подключение overlay.
- OpenAPI 3.0.3 действительно опубликован 20 февраля 2020 года, 3.1.0 —
15 февраля 2021-го. RFC 8594 прямо называет
Sunsethint: он не гарантирует доступность ресурса до указанной даты или недоступность после неё. Источники поэтому остались в исторической рамке сентября 2021 года. - В compatibility SVG была содержательная несогласованность: у semantic
change для v2 стоял
TEST, хотя текущий v2 reader наследует правилоstatus: confirmedи fixture его отвергает. Метка исправлена наSTOP; рисунок снова отрендерен Sharp на 375 px. - Повторная fixture подтвердила 12/12 assertions. Это не HTTP-доказательство: запросы, response, retirement и пауза остаются локальной in-memory моделью.
| Проверка | Результат независимого прохода |
|---|---|
node --check и draft gate |
PASS: 8 274 / 8 944 / 9 241 знаков body |
| Fixture | PASS: 12/12; additive response, absence/null, два направления request, unknown key, structural и semantic break, pause до mutation |
| XML, SVG safety и mobile visual | PASS: три схемы корректны, безопасны и читаемы на 375 px; нет script, foreignObject, внешних URL, data URI, clipping или overflow |
| Strict audit через registry | PASS: объёмы 8 274 / 8 944 / 9 241, в каждой revision есть figure, 2 table и 2–3 code examples |
| Production build | PASS: Next.js сгенерировал 374 статические страницы |
Три revision подключены к web/data/editorial-revisions.mjs; дата, автор и
stable slug продолжают приходить из архива. После интеграции строгий охват —
133 из 358, осталось 225 материалов.
Финальный вердикт: ACCEPTED FOR PUBLICATION.