164 lines
12 KiB
Markdown
164 lines
12 KiB
Markdown
# 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 change `confirmed → 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 не осталось.
|
||
|
||
## Реальные команды и результаты
|
||
|
||
```text
|
||
# 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.
|
||
|
||
1. OpenAPI 3.0.3 действительно опубликован 20 февраля 2020 года, 3.1.0 —
|
||
15 февраля 2021-го. RFC 8594 прямо называет `Sunset` hint: он не гарантирует
|
||
доступность ресурса до указанной даты или недоступность после неё. Источники
|
||
поэтому остались в исторической рамке сентября 2021 года.
|
||
2. В compatibility SVG была содержательная несогласованность: у semantic
|
||
change для v2 стоял `TEST`, хотя текущий v2 reader наследует правило
|
||
`status: confirmed` и fixture его отвергает. Метка исправлена на `STOP`;
|
||
рисунок снова отрендерен Sharp на 375 px.
|
||
3. Повторная 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**.
|