diff --git a/adr/014-trusted-openapi-input.md b/adr/014-trusted-openapi-input.md new file mode 100644 index 0000000..deb67a0 --- /dev/null +++ b/adr/014-trusted-openapi-input.md @@ -0,0 +1,39 @@ +# 014. Актуальная OpenAPI-схема как вход frontend + +**Статус:** принято 2026-09-13; docs, specs и frontend-инструкции приведены +к решению. Настройка remote issues и branch protection выполняется отдельно. + +## Контекст + +Frontend и backend — независимые репозитории. Знание путей и команд backend +в frontend связывает их внутреннее устройство. Для текущего процесса разработки +владелец проекта принимает актуальность переданной OpenAPI-схемы как допущение; +проверка пары revisions и дополнительное сравнение схем не требуются. + +## Решение + +Backend остаётся источником HTTP-контракта согласно [ADR 002](002-nest-generated-openapi-contract.md). +Frontend принимает предоставленную OpenAPI-схему как актуальную и генерирует +из неё типы локально. Его команды не читают файлы соседнего backend checkout +и не запускают backend-скрипты. Подготовка и доставка схемы находятся вне frontend. + +Не требуется фиксировать пару SHA frontend/backend или сравнивать frontend-схему +с runtime OpenAPI backend. Локальная проверка соответствия generated types +входной схеме сохраняется: она не проверяет актуальность схемы относительно backend. +Обычные CI checks по-прежнему должны проверять текущий commit изменения. + +## Последствия + +Задача frontend #3 ограничивается локальной генерацией из предоставленной схемы; +экспорт backend не становится обязанностью frontend. Из frontend #2 исключается +требование проверки явно выбранной пары revisions. Требования безопасности +frontend #4 этим решением не меняются. + +Рассинхронизацию предоставленной схемы и backend отдельный gate не обнаруживает: +её отсутствие принято как допущение. Тесты HTTP-поведения, валидации и авторизации +остаются нужны. + +Решение заменяет прежнее требование сравнения runtime OpenAPI с frontend +snapshot в [OpenAPI contract flow](../development/runtime-openapi-verification.md) +и [спецификации генерации API](../../specs/openspec/specs/api-contract-generation/spec.md). +Связанные remote issues и настройки защиты ветки требуют отдельного обновления. diff --git a/adr/README.md b/adr/README.md index 3ce1e7d..c554511 100644 --- a/adr/README.md +++ b/adr/README.md @@ -21,3 +21,4 @@ - [011 — Native OpenSpec lifecycle и repository gates](011-native-openspec-lifecycle-with-repository-gates.md) — заменён ADR 012 в части обязательного lifecycle. - [012 — Прямая разработка с контекстом по задаче](012-task-driven-development-with-scoped-context.md) - [013 — НКР как первый источник кредитных рейтингов облигаций](013-nkr-bond-credit-ratings.md) +- [014 — Актуальная OpenAPI-схема как вход frontend](014-trusted-openapi-input.md) diff --git a/architecture/containers.md b/architecture/containers.md index 33a8362..41a6377 100644 --- a/architecture/containers.md +++ b/architecture/containers.md @@ -53,10 +53,12 @@ T-Bank в форме и отправляет его для сохранения, загрузка публичного изображения из CDN не проходит через эту финансовую границу. -Типизированный frontend-клиент производится из OpenAPI backend во время -разработки. В runtime SPA вызывает API, а не генератор или OpenAPI endpoint. -Форма запросов и ошибок описана в [HTTP API](http-api.md); направление -генерации принято в [ADR 002](../adr/002-nest-generated-openapi-contract.md). +Типизированный frontend-клиент производится из предоставленного OpenAPI snapshot +во время разработки. В runtime SPA вызывает API, а не генератор или OpenAPI +endpoint. Форма запросов и ошибок описана в [HTTP API](http-api.md); направление +генерации принято в [ADR 002](../adr/002-nest-generated-openapi-contract.md), +а доверие frontend к предоставленному snapshot — в +[ADR 014](../adr/014-trusted-openapi-input.md). ## Хранимые данные и границы доступа diff --git a/architecture/http-api.md b/architecture/http-api.md index f1edf10..8a7e826 100644 --- a/architecture/http-api.md +++ b/architecture/http-api.md @@ -3,8 +3,9 @@ ## Источник контракта Backend генерирует OpenAPI из собственного публичного API. Frontend использует -производное описание контракта и типизированный клиент. Изменения проходят -[contract workflow](../development/runtime-openapi-verification.md). +предоставленный OpenAPI snapshot как актуальный вход и локально генерирует +типизированный клиент. Направление описано в +[OpenAPI contract flow](../development/runtime-openapi-verification.md). API имеет prefix `/api/v1`; Swagger публикуется для локальной разработки по environment policy, а не используется frontend в runtime. @@ -55,10 +56,10 @@ T-Bank token failure и временная недоступность имеют ## Граница доказательства -Сравнение OpenAPI подтверждает согласованность схем, а не результат каждого -запроса. Безопасная обработка неожиданной ошибки проверяется отдельно. -Валидация, доступ, статусы и cookie требуют проверки полного HTTP-потока; -атомарность хранения — проверки с изолированной реальной базой. +OpenAPI snapshot задаёт frontend transport types, но сам по себе не доказывает +результат каждого запроса. Безопасная обработка неожиданной ошибки проверяется +отдельно. Валидация, доступ, статусы и cookie требуют проверки полного +HTTP-потока; атомарность хранения — проверки с изолированной реальной базой. Известное ограничение сквозных проверок описано в [проверке backend](../development/verification.md). diff --git a/development/README.md b/development/README.md index f37a466..aea25f2 100644 --- a/development/README.md +++ b/development/README.md @@ -6,7 +6,7 @@ - [Локальное окружение](local-workspace.md) — предпосылки работы, первый пользовательский сценарий и диагностика. - [Проверки системы](verification.md) — что доказывают проверки интерфейса, API и хранения данных, известные ограничения. -- [HTTP contract](runtime-openapi-verification.md) — направление генерации OpenAPI и проверка совместимости. +- [HTTP contract](runtime-openapi-verification.md) — направление генерации OpenAPI и локальная проверка snapshot/types. - [Дизайн-система](design-system.md) / [UI-каталог](ui-catalog.md) — визуальные роли, реальные состояния и ограничения примеров. - [Принципы изменений](engineering-governance.md) — связность системы, риск и доказательства результата. - [Ведение документации](../CONTRIBUTING.md) — самостоятельные объяснения и их обновление вместе с системой. diff --git a/development/engineering-governance.md b/development/engineering-governance.md index d205a91..5bd42a2 100644 --- a/development/engineering-governance.md +++ b/development/engineering-governance.md @@ -41,9 +41,9 @@ OpenSpec остаётся [необязательным средством со Результат оценивается по исходной задаче: сохранены ли смысл данных и контракты, правильно ли разграничен доступ, учтены ли ошибки и доступность интерфейса. -Проверки приложений и документации дополняются -[согласованием HTTP-контракта](runtime-openapi-verification.md), если он меняется. -Общего CI сейчас нет. +При изменении HTTP-контракта backend обновляет публичный OpenAPI, а frontend +проверяет соответствие generated types полученному snapshot согласно +[OpenAPI contract flow](runtime-openapi-verification.md). Общего CI сейчас нет. Успешная проверка применима к тому состоянию системы и тем предпосылкам, на которых выполнена. При их изменении старое свидетельство не доказывает diff --git a/development/local-workspace.md b/development/local-workspace.md index 7f3b97b..75740bf 100644 --- a/development/local-workspace.md +++ b/development/local-workspace.md @@ -127,5 +127,5 @@ HTTP-запросы связываются с безопасными журна Успешная сборка, запуск и прохождение сценария — разные доказательства. Границы [проверок системы](verification.md) и -[HTTP-контракта](runtime-openapi-verification.md) рассматриваются отдельно. +[OpenAPI contract flow](runtime-openapi-verification.md) рассматриваются отдельно. Завершённость результата учитывает фактические проверки и остающиеся ограничения. diff --git a/development/runtime-openapi-verification.md b/development/runtime-openapi-verification.md index b8d32ad..22740a3 100644 --- a/development/runtime-openapi-verification.md +++ b/development/runtime-openapi-verification.md @@ -1,14 +1,18 @@ -# Проверка runtime OpenAPI +# OpenAPI contract flow ## Назначение -Проверка сравнивает OpenAPI, сформированный настроенным backend-приложением, -с описанием API, на котором основан frontend. Backend остаётся единственным -источником исполняемого HTTP-контракта; frontend-клиент является производным. -Причины выбора описаны в [ADR 002](../adr/002-nest-generated-openapi-contract.md). +Backend остаётся источником HTTP-контракта и формирует OpenAPI из публичного +API. Frontend принимает предоставленный `openapi.json` как актуальный вход, +хранит его snapshot и генерирует из него transport types локально. Причины +выбора backend-generated контракта описаны в +[ADR 002](../adr/002-nest-generated-openapi-contract.md), отказ от frontend +проверки backend runtime-схемы — в [ADR 014](../adr/014-trusted-openapi-input.md). -Эта проверка подтверждает согласованность публичного контракта, но не заменяет -проверки каждого приложения и наблюдаемого HTTP-поведения. +Frontend не проверяет, что переданный snapshot совпадает с текущим backend +runtime OpenAPI, не фиксирует пару frontend/backend SHA и не зависит от пути к +соседнему backend checkout. Подготовка и доставка актуального OpenAPI-документа +находятся вне frontend. ## Выбор и направление изменения @@ -16,28 +20,27 @@ статуса либо формы ошибки. Внутреннее изменение представления без изменения API не требует нового описания контракта. -Направление согласования: публичный API backend → OpenAPI → производное -описание и типизированный клиент frontend. Две независимо редактируемые версии +Направление согласования: публичный API backend → предоставленный OpenAPI → +frontend snapshot → generated types. Две независимо редактируемые версии контракта создавали бы риск расхождения. Перед изменением, влияющим на совместимость, учитываются существующие потребители и сохранность данных. Семантика запросов и ошибок описана в [HTTP API](../architecture/http-api.md). ## Границы и результат -Сравнение выполняется на границе настроенного приложения, нормализует порядок -ключей JSON-объектов и сохраняет порядок массивов. Оно не обновляет сравниваемые -описания и клиент автоматически и не обращается к T-Bank или другим внешним -источникам. Несовпадение указывает на рассогласование контракта. +Frontend-команда генерации читает только committed snapshot и обновляет +generated types. Frontend-проверка генерирует types из этого snapshot во +временный каталог и сравнивает результат с committed generated artifact. +Несовпадение означает, что snapshot и generated types в frontend расходятся. -Равенство схем не доказывает фактическую работу валидации, авторизации, -статусов, cookie и обработки ошибок: для этого нужны наблюдения полного -HTTP-потока. Согласованность описаний и функциональная корректность — -разные доказательства. +Эта проверка не доказывает актуальность snapshot относительно backend. Это +принятое допущение, а не свойство frontend gate. Она также не доказывает +фактическую работу валидации, авторизации, статусов, cookie и обработки ошибок: +для этого нужны наблюдения полного HTTP-потока. -## Граница e2e +## Граница runtime -`npm run test:openapi-contract` подготавливает отдельную временную SQLite-базу -через общий runner и выполняет только сравнение OpenAPI. Соседний frontend -checkout нужен для snapshot. Полные HTTP-сценарии запускает `test:e2e`; -миграция перед сравнением не подменяет проверку поведения приложения. -Подробности — в [сквозной проверке](verification.md#известное-ограничение-сквозной-проверки). +Работающий frontend использует сгенерированные types и обычные HTTP-запросы к +API. Swagger или OpenAPI endpoint не являются runtime-зависимостью SPA. +Полные HTTP-сценарии и хранение данных проверяются отдельными backend-gates; +локальный frontend gate выполняется без backend. diff --git a/development/verification.md b/development/verification.md index dbc3c32..d05de81 100644 --- a/development/verification.md +++ b/development/verification.md @@ -25,11 +25,13 @@ автоматическое форматирование выполняется отдельно и не является доказательством. Диагностика покрытия доступна без общего числового порога. -Равенство OpenAPI подтверждает согласованность публичного описания с клиентом. -Валидация, cookie, авторизация счёта, статусы и ошибки требуют полного HTTP-потока; -целостность и конкурентные изменения данных — проверки с изолированной реальной -базой. Подставной ответ базы не доказывает её транзакционные свойства. -Направление генерации и границы сравнения — в [проверке OpenAPI](runtime-openapi-verification.md). +Frontend OpenAPI check подтверждает только соответствие generated types +сохранённому snapshot. Актуальность snapshot относительно backend принимается +как входное допущение. Валидация, cookie, авторизация счёта, статусы и ошибки +требуют полного HTTP-потока; целостность и конкурентные изменения данных — +проверки с изолированной реальной базой. Подставной ответ базы не доказывает её +транзакционные свойства. Направление генерации описано в +[OpenAPI contract flow](runtime-openapi-verification.md). ### Известное ограничение сквозной проверки