Репозиторий: /Users/n.baryshnikov/Projects/avito_python_api.
Цель новой архитектуры: заменить старую inventory-архитектуру машинно-проверяемой canonical coverage map на базе:
- Swagger/OpenAPI спецификаций из
docs/avito/api/*.json. @swagger_operation(...)bindings на публичных SDK domain methods.swagger-lint, который строит и валидирует карту покрытия.
docs/avito/inventory.md считается артефактом старой архитектуры. Он не должен быть источником истины и не должен участвовать в новых проверках покрытия.
Текущий Swagger corpus:
- 23 файла в
docs/avito/api. - 204 операции.
- 7 deprecated операций.
Ключевой инвариант новой архитектуры:
Swagger operation
<-> exactly one @swagger_operation SDK method
-> SwaggerFakeTransport validates actual HTTP request/response
-> contract tests validate all statuses and errors from Swagger
Важные локальные точки:
STYLEGUIDE.mdявляется нормативным документом и имеет приоритет.- Публичный фасад:
avito/client.py, классAvitoClient. - Публичные domain methods:
avito/<domain>/domain.py. - Section clients:
avito/<domain>/client.py. - Старые inventory-ссылки в
CLAUDE.md, README, docs и генераторах документации мигрированы на binding discovery. Makefileсейчас имеетcheck: test typecheck lint swagger-lint build; strictswagger-lintуже входит в общий gate.
Ограничения архитектуры:
- Декоратор не должен дублировать Swagger-контракт.
- В binding запрещены response/request schemas, statuses, content types, response models, request models, error models.
- Swagger остаётся единственным источником HTTP method/path/parameters/body/status/schema/deprecated state.
- Binding описывает только соответствие SDK method операции Swagger и способ построить SDK-вызов для contract tests.
docs/avito/inventory.mdretired. Новая canonical coverage map строится только из Swagger specs и discovered bindings.- Canonical bindings ставятся на публичные domain methods в
avito/<domain>/domain.py. - Section clients в
avito/<domain>/client.pyне являются canonical public binding target, кроме заранее описанного legacy-исключения. - Summary/helper methods в
AvitoClientне получают Swagger bindings, если они не соответствуют одной конкретной upstream Swagger operation. - Private methods,
_require_*helpers и internal serialization helpers не участвуют в discovery. - Discovery не должен создавать
AvitoClient, читать обязательные env vars, ходить в сеть или выполнять реальные HTTP calls. avito/core/swagger.pyне должен загружать Swagger files на import time.operation_idявляется дополнительной проверкой, но не primary identity. Primary identity:spec + method + normalized_path.- Allowlist для deprecated/legacy/completeness исключений по умолчанию запрещён. Если он понадобится, запись должна иметь причину и дату удаления.
deprecatedв binding сверяется только с operation-leveldeprecatedиз Swagger operation. Deprecated schema fields, enum values и properties не влияют на operation binding.
Модуль:
avito/core/swagger.py
Публичный декоратор:
@swagger_operation(
method: str,
path: str,
*,
spec: str | None = None,
operation_id: str | None = None,
factory: str | None = None,
factory_args: Mapping[str, str] | None = None,
method_args: Mapping[str, str] | None = None,
deprecated: bool = False,
legacy: bool = False,
)Binding model:
@dataclass(frozen=True, slots=True)
class SwaggerOperationBinding:
method: str
path: str
spec: str | None
operation_id: str | None
factory: str | None
factory_args: Mapping[str, str]
method_args: Mapping[str, str]
deprecated: bool
legacy: boolДекоратор записывает metadata в func.__swagger_binding__, не меняет поведение метода и не читает Swagger files на import time.
Class-level metadata на публичных domain objects:
__swagger_domain__: str
__swagger_spec__: str
__sdk_factory__: str
__sdk_factory_args__: Mapping[str, str]Section clients могут иметь binding metadata только как заранее описанное legacy-исключение.
Правила normalizing для identity и линтера:
methodприводится к uppercase.pathхранится в Swagger format:/path/{param}.- Trailing slash удаляется, кроме path
/. - Path parameter syntax кроме
{name}запрещён. - Path остаётся case-sensitive.
- Primary operation key:
spec + method + normalized_path. - Если
specне указан, auto-resolve поmethod + normalized_pathразрешён только при ровно одном совпадении среди всех Swagger files.
scripts/lint_swagger_bindings.py должен поддерживать несколько режимов, чтобы внедрение можно было вести поэтапно:
- Default / non-strict mode:
- валидирует Swagger files;
- валидирует только уже найденные SDK bindings;
- не требует покрытия всех 204 операций;
- подходит для Этапов 1-5.
- Strict mode:
- включает все default-проверки;
- требует, чтобы каждая Swagger operation имела ровно один SDK binding;
- включается в
make checkтолько после завершения доменной разметки.
- JSON report mode:
- отдаёт machine-readable отчёт по операциям, bindings, missing/duplicate/ambiguous cases;
- используется docs/reference generator и coverage badge;
- заменяет старые inventory-derived reports.
CLI contract:
poetry run python scripts/lint_swagger_bindings.py
poetry run python scripts/lint_swagger_bindings.py --strict
poetry run python scripts/lint_swagger_bindings.py --json
poetry run python scripts/lint_swagger_bindings.py --json --output swagger-bindings-report.jsonExit codes:
0: ошибок нет;1: найдены validation errors;2: ошибка CLI usage, чтения specs или некорректной среды запуска.
JSON report должен быть стабильным API для docs/reference generator и badge.
Минимальная структура:
{
"summary": {
"specs": 23,
"operations_total": 204,
"deprecated_operations": 7,
"bound": 0,
"unbound": 204,
"duplicate": 0,
"ambiguous": 0
},
"operations": [],
"bindings": [],
"errors": []
}operations[] содержит spec, method, path, operation_id, deprecated, status, binding.
bindings[] содержит module, class, method, operation_key, factory, factory_args, method_args.
errors[] содержит code, message, operation_key, sdk_method.
Критерии готовности этапов:
- Этап 0 готов, когда в документации больше нет утверждения, что inventory является canonical source of truth.
- Этап 1 готов, когда unit-тесты декоратора проходят, а
avito/core/swagger.pyне импортирует и не читаетdocs/avito/api. - Этап 2 готов, когда registry стабильно извлекает 23 specs, 204 operations и 7 deprecated operations.
- Этап 3 готов, когда discovery на пустой/частичной разметке не требует env vars, сети и создания
AvitoClient. - Этап 4 готов, когда
make swagger-lintработает в non-strict режиме и возвращает стабильные actionable error codes. - Этап 5 готов по домену, когда все его public operation methods имеют bindings и проходят
make swagger-lintв non-strict режиме. - Этап 6 готов, когда strict mode подтверждает ровно один binding на каждую из 204 Swagger operations.
- Этап 7 готов, когда все
factory_argsиmethod_argsпроходят validation against Swagger parameters/request body. - Этап 8 готов, когда contract tests проверяют generated SDK calls через
SwaggerFakeTransportбез реального HTTP. - Этап 9 готов, когда
make checkвключаетswagger-lint --strictи проходит полностью.
- Обновить
CLAUDE.md, README и docs: заменить “inventory is canonical mapping” на “Swagger bindings are canonical coverage map”. - Проверить, что старые
check_inventory_*скрипты и ссылки больше не участвуют вMakefile, docs или CI. - Зафиксировать, что documentation/reference должны генерироваться из binding discovery, а не из markdown inventory.
- Создать
avito/core/swagger.py. - Реализовать
SwaggerOperationBinding:@dataclass(frozen=True, slots=True);methodnormalizes to uppercase;factory_argsиmethod_argsstored as immutable mappings;- без загрузки Swagger на import time.
- Реализовать
swagger_operation(...)с публичной сигнатурой из разделаDecorator Contract. - Экспортировать публичный API из
avito/core/__init__.py, если это соответствует локальному паттерну. - Добавить unit-тесты:
- metadata пишется в
func.__swagger_binding__; - поведение decorated method не меняется;
- mappings immutable;
- лишние/запрещённые kwargs невозможны через сигнатуру.
- metadata пишется в
- Создать импортируемый parser/helper-модуль для registry и discovery.
- Оставить
scripts/lint_swagger_bindings.pyтонким CLI wrapper-ом. - Загружать все
docs/avito/api/*.json. - Извлекать операции в структуру:
spec;method;path;operation_id;deprecated;- path/query/header parameters;
- request body metadata.
- Проверять базовую валидность specs:
- JSON валиден;
- есть
paths; - operation keys уникальны;
- path parameters из URL совпадают с описанными параметрами.
- В discovery-коде импортировать пакет
avitoбез созданияAvitoClient. - Обойти публичные domain-классы из
avito/<domain>/domain.pyи найти методы с__swagger_binding__. - Для каждого binding вычислить effective metadata:
- method-level values;
- class-level
__swagger_spec__,__sdk_factory__,__sdk_factory_args__; - auto-resolve только если совпадение однозначно.
- Сформировать canonical map:
Swagger operation key -> SDK method. - Явно игнорировать section clients, private methods, summary methods и internal helpers.
- Реализовать non-authoritative baseline report на базе Swagger registry и binding discovery.
- Для каждой операции показать:
spec;method;path;operation_id;deprecated;- binding status:
bound,unbound,duplicate,ambiguous.
- Если возможно безопасно угадать SDK target, показывать guessed domain/class/method как подсказку, но не как источник истины.
- Использовать report как рабочий инструмент разметки доменов.
- Не возвращать
docs/avito/inventory.mdи не делать markdown inventory canonical.
- Реализовать проверки:
- binding указывает на существующую Swagger operation;
specсуществует;operation_id, если указан, совпадает;- duplicate bindings запрещены;
deprecated/legacyсогласованы со Swagger;- factory существует на
AvitoClient.
- Добавить signature validation для factory и decorated SDK method:
factory_argsсоответствуют сигнатуре factory;method_argsсоответствуют сигнатуре SDK method;- required параметры покрыты mapping-ом;
- лишние mapping keys запрещены.
- Сделать actionable ошибки с кодами вида
[SWAGGER_BINDING_NOT_FOUND]. - Добавить
make swagger-lint, запускающий non-strict mode. - Пока не включать strict completeness в
make check, если binding-и ещё не расставлены на все 204 операции.
- Зафиксировать policy для 7 operation-level deprecated Swagger operations.
- Определить, когда binding обязан иметь
legacy=True. - Проверить, что deprecated public methods имеют runtime deprecation behavior, если это требуется STYLEGUIDE.
- Запретить
legacy=Trueна non-deprecated operation без явного исключения. - Если исключения всё же понадобятся, создать отдельный allowlist-файл с причиной и датой удаления.
Policy:
- Operation-level
deprecated: trueиз Swagger требуетdeprecated=Trueиlegacy=Trueв binding. - Deprecated binding обязан указывать на public SDK method с runtime
DeprecationWarningчерезdeprecated_method(...). legacy=Trueна non-deprecated Swagger operation запрещён без отдельного allowlist-исключения.- Deprecated schema fields, properties и enum values не создают deprecated/legacy binding requirement.
- Текущие operation-level deprecated операции:
CPAАвито.json GET /cpa/v1/call/{call_id},CPAАвито.json POST /cpa/v2/balanceInfo,CPAАвито.json POST /cpa/v2/callById,Автозагрузка.json GET /autoload/v1/profile,Автозагрузка.json POST /autoload/v1/profile,Автозагрузка.json GET /autoload/v2/reports/last_completed_report,Автозагрузка.json GET /autoload/v2/reports/{report_id}.
- Построить рабочую таблицу
AvitoClient factory -> domain class -> spec candidates. - Проверить, что каждый factory можно introspect-ить без создания
AvitoClient. - Выявить операции, которые сейчас представлены summary/helper methods и не должны получать direct binding.
- Использовать таблицу как подготовку к доменной разметке, но не делать её source of truth.
Результат этапа хранится как non-authoritative factory_mapping section в JSON report. Она помогает расставлять domain bindings, но canonical coverage по-прежнему считается только из Swagger operations и discovered @swagger_operation bindings.
Делать маленькими PR/commit-ами по одному домену:
accounts,tariffs,ratingsкак самые маленькие.messenger.promotion.ads/ autoload legacy.orders/ delivery / stock.jobs.cpa/ calltracking.autoteka.realty.
Для каждого домена:
- добавить class-level metadata;
- расставить
@swagger_operation; - описать
factory_argsиmethod_args; - запускать
make test,make typecheck,make lint,make swagger-lint; - не добавлять request/response schemas в decorators.
Для каждого домена в changelog фиксировать:
- сколько операций стало bound;
- сколько осталось unbound;
- какие deprecated/legacy решения приняты;
- какие проверки запускались.
- Включить проверку: каждая из 204 Swagger operations имеет ровно один binding.
- Включить проверку: каждый binding уникален.
- Перевести
make swagger-lintна strict mode. - Сделать
make swagger-lintчастьюmake check. - Обновить badge/docs покрытия: coverage теперь считается из Swagger registry + binding discovery.
- Перевести generated reference/coverage docs на JSON report или импортируемый discovery API.
- Удалить или переписать оставшиеся inventory-derived docs paths.
- Обновить README badge/description: coverage считается из Swagger bindings.
- Проверить, что
docs/site/reference/coverage.mdи related pages не называют inventory источником истины.
- Проверять
path.<name>против path params. - Проверять
query.<name>против query params. - Проверять
header.<name>против header params. - Проверять
bodyиbody.<field>против request body. - Ввести test constants registry для
constant.<name>. - Запретить любые expressions вне whitelist.
- Реализовать
SwaggerFakeTransport. - На основе binding-а строить SDK вызов из generated request data.
- Request-contract tests: проверять, что SDK делает HTTP request, соответствующий Swagger:
- method;
- path;
- path/query/header params;
- body shape;
- content type.
- Response-contract tests: проверять happy-path response mapping в typed SDK models.
- Error-contract tests: проверять statuses и exception mapping из Swagger.
- Отдельно проверить deprecated/legacy операции.
- Начать с read-only операций, потом расширить на write-операции и idempotency.
- Запустить:
make test;make typecheck;make lint;make swagger-lint;make build.
- Затем
make check, гдеswagger-lintуже должен быть включён. - Проверить, что старый inventory нигде не упоминается как источник истины.
Цель: отдельным новым этапом закрыть несоответствия, найденные после выполнения Этапов 0-9, не переписывая историю уже выполненных пунктов.
Не входит в этот этап:
- дефект публичного Swagger corpus с несовпадением
{userId}/{itemId}иpathUserId/pathItemId; - patch/override pipeline для upstream specs.
Требование: несколько Swagger bindings на один SDK method запрещены. Каждая Swagger operation должна иметь собственный discovered SDK method target.
- Найти все SDK methods, на которых discovery видит больше одного Swagger binding.
- Для каждого случая выбрать явное разделение:
- отдельные public SDK methods, если операции являются разными пользовательскими действиями;
- отдельные documented wrappers, если один сценарий раньше скрывал несколько upstream modes;
- отдельные low-level auth SDK targets для token operations, если они остаются non-domain binding exception.
- Удалить поддержку stacked
@swagger_operation(...)из декоратора:- не накапливать
func.__swagger_bindings__; - повторная установка binding на метод должна быть ошибкой или должна явно запрещаться тестом.
- не накапливать
- Обновить discovery:
- читать только
func.__swagger_binding__; - считать
__swagger_bindings__или несколько bindings на одном method ошибкой совместимости.
- читать только
- Обновить linter:
- добавить error code
SWAGGER_BINDING_METHOD_MULTIPLE; - падать, если один
sdk_methodсвязан больше чем с одной operation; - не вводить allowlist для multi-binding methods.
- добавить error code
- Обновить JSON report:
- оставить
bindings[]как плоский список one binding per sdk_method; - добавить ошибку в
errors[], если обнаружено legacy__swagger_bindings__.
- оставить
- Обновить docs:
docs/site/explanations/swagger-binding-subsystem.md;STYLEGUIDE.md;CLAUDE.md;- убрать формулировки, допускающие multi-operation SDK methods.
- Добавить тесты:
- декоратор запрещает stacked bindings;
- discovery/linter ловят legacy
__swagger_bindings__; - strict report остаётся
204/204 bound,0 duplicate,0 ambiguous,0 errors.
Требование: body.<field> должен проверяться против request body schema/properties, а не только против наличия requestBody.
- Расширить
SwaggerRequestBodyвavito/core/swagger_registry.py:- хранить
content_types; - хранить top-level body field names/properties;
- хранить флаг, что schema была успешно извлечена.
- хранить
- Добавить schema resolver для локальных
$ref:#/components/schemas/<name>;- object schemas с
properties; allOf/oneOf/anyOfтолько если можно безопасно извлечь top-level properties; иначе фиксировать unsupported schema state.
- В
swagger_linter.pyизменить проверкуbody.<field>:- если
requestBodyотсутствует — текущая ошибкаSWAGGER_BINDING_BODY_MISSING; - если schema/properties доступны и поля нет — новая ошибка
SWAGGER_BINDING_BODY_FIELD_NOT_FOUND; - если schema не поддержана для field-level validation — новая actionable ошибка
SWAGGER_BINDING_BODY_SCHEMA_UNSUPPORTED.
- если
- Добавить tests для registry:
- inline object schema;
$refschema;- missing properties;
- unsupported schema shape.
- Добавить tests для linter:
- valid
body.<field>; - invalid
body.missing; body.<field>при unsupported schema;bodyостаётся валидным при любом request body.
- valid
- Обновить JSON report/errors contract, если добавляются новые error codes.
- Обновить
docs/site/explanations/swagger-binding-subsystem.md, убрав оговорку, что field-level validation ещё не реализована.
Требование: contract tests должны параметризованно покрывать все discovered bindings и все Swagger error status contracts, а не только representative samples/status categories.
- Добавить parametrized request-contract test по всем discovered bindings:
- загрузить registry;
- загрузить discovery;
- для каждого binding зарегистрировать success response;
- вызвать SDK method через
SwaggerFakeTransport.invoke_binding; - проверить, что request matched Swagger method/path и прошёл validation path/query/header/body/content-type.
- Добавить deterministic payload generator:
- использовать Swagger response schema, где она доступна;
- использовать controlled payload registry для операций, где mapper требует доменно-специфичную форму;
- запрещать неописанные silent fallbacks, которые маскируют отсутствие payload contract.
- Добавить parametrized error-contract test по всем Swagger error responses:
- для каждой operation и каждого numeric error status зарегистрировать
error_payload(status); - вызвать соответствующий binding;
- проверить exception type по transport error mapping;
- проверить, что message/metadata не нарушают публичный error contract.
- для каждой operation и каждого numeric error status зарегистрировать
- Добавить coverage assertions:
- количество request-contract cases равно количеству discovered bindings;
- количество error-contract cases равно количеству numeric Swagger error responses;
- deprecated operations входят в общий набор и дополнительно проверяют
DeprecationWarning.
- Если generated call невозможен для отдельной операции, тест должен падать. Allowlist для contract gaps не вводить без отдельного решения.
- Обновить
SwaggerFakeTransport, если нужно:- добавить schema-aware success payload generation helpers;
- расширить test constants registry;
- улучшить diagnostics при невозможности построить вызов.
- Обновить docs/testing notes:
docs/site/explanations/swagger-binding-subsystem.md;docs/site/explanations/testing-strategy.md;STYLEGUIDE.md, если меняется обязательный verification set.
pytest tests/core/test_swagger.py tests/core/test_swagger_discovery.py tests/core/test_swagger_linter.py tests/core/test_swagger_report.py
pytest tests/core/test_swagger_registry.py tests/contracts/test_swagger_contracts.py
make swagger-lint
mypy avito
ruff check avito tests/core tests/contracts/test_swagger_contracts.py
make docs-strict
make checkНе начинать с SwaggerFakeTransport. Сначала нужна стабильная карта Swagger operation -> SDK method.
Самый безопасный MVP:
- Декоратор.
- Swagger registry.
- Binding discovery.
- Baseline coverage report.
- Линтер в non-strict режиме.
- Deprecated/legacy policy.
- Factory/domain mapping inventory.
- Доменные binding-и.
- Strict completeness.
- Documentation migration.
- Contract tests.
Записи добавляются при выполнении или изменении плана.
Формат:
| Date | Change | Status | Verification |
|---|---|---|---|
| 2026-04-29 | Создан action_plan.md с контекстом, этапами реализации и changelog. |
Done | Manual review |
| 2026-04-29 | Добавлены design decisions, execution modes, definition of done, baseline report, deprecated/legacy policy и documentation migration. | Done | Manual review |
| 2026-04-29 | Удалены ссылки на внешний контекст, добавлены decorator contract, path normalization, CLI/JSON report contract, factory inventory и разбиение contract tests. | Done | Manual review |
| 2026-04-29 | Выполнен Этап 0: README, CLAUDE/AGENTS, docs и PR template переведены на Swagger bindings; inventory checks удалены из docs CI. | Done | rg по inventory/check_inventory/canonical source; manual review |
| 2026-04-29 | Выполнен Этап 1: добавлен avito/core/swagger.py, экспорт core API и unit-тесты декоратора. |
Done | pytest tests/core/test_swagger.py; pytest; mypy avito; ruff check |
| 2026-04-29 | Выполнен Этап 2: добавлен Swagger registry/parser, тонкий lint_swagger_bindings.py wrapper и тесты на corpus 23/204/7. |
Done | pytest tests/core/test_swagger_registry.py; python scripts/lint_swagger_bindings.py; mypy avito; ruff check |
| 2026-04-29 | Выполнен Этап 3: добавлен discovery публичных domain bindings с class-level defaults, auto-resolve spec и canonical map. | Done | pytest tests/core/test_swagger_discovery.py; pytest; mypy avito; ruff check |
| 2026-04-29 | Выполнен Этап 3.5: добавлен baseline JSON report по Swagger registry + binding discovery, статусы bound/unbound/duplicate/ambiguous и JSON-режим CLI. |
Done | pytest tests/core/test_swagger.py tests/core/test_swagger_registry.py tests/core/test_swagger_discovery.py tests/core/test_swagger_report.py; ruff check avito/core/swagger_report.py scripts/lint_swagger_bindings.py tests/core/test_swagger_report.py; mypy avito; python scripts/lint_swagger_bindings.py --json --output /tmp/swagger-bindings-report.json |
| 2026-04-29 | Выполнен Этап 4: добавлен MVP Swagger binding linter, validation ошибок binding/spec/operation_id/duplicate/deprecated/legacy/factory/signature, make swagger-lint и исправлены 2 path parameter mismatch в локальном Swagger corpus. |
Done | pytest tests/core/test_swagger.py tests/core/test_swagger_registry.py tests/core/test_swagger_discovery.py tests/core/test_swagger_report.py tests/core/test_swagger_linter.py; make swagger-lint; pytest; mypy avito; ruff check .; python scripts/lint_swagger_bindings.py --json --output /tmp/swagger-bindings-report-stage4.json |
| 2026-04-29 | Выполнен Этап 4.5: зафиксирована deprecated/legacy policy для 7 operation-level deprecated operations, runtime deprecation metadata добавлена в deprecated_method, linter требует legacy=True и runtime warning для deprecated bindings. |
Done | pytest tests/core/test_swagger_registry.py tests/core/test_swagger_linter.py; make swagger-lint; pytest; mypy avito; ruff check . |
| 2026-04-29 | Выполнен Этап 4.75: добавлен non-authoritative factory/domain mapping report для AvitoClient factory -> domain class -> spec candidates, introspection без создания клиента и список summary/helper methods без direct binding. |
Done | pytest tests/core/test_swagger_factory_map.py tests/core/test_swagger_report.py tests/core/test_swagger_linter.py; python scripts/lint_swagger_bindings.py --json --output /tmp/swagger-bindings-report-stage475.json; make swagger-lint; pytest; mypy avito; ruff check . |
| 2026-04-29 | Выполнен Этап 5: расставлены Swagger bindings на все публичные domain operation methods: accounts 8, tariffs 1, ratings 4, messenger 18, promotion 24, ads/autoload 28, orders/delivery/stock 44, jobs 22, cpa/calltracking 13, autoteka 26, realty 7. Coverage report: bound 195, unbound 9, duplicate 0, ambiguous 0. Unbound остались только token operations и альтернативные ветки существующих мульти-режимных методов (version=1, ids, extended=True). |
Done | make swagger-lint; poetry run python scripts/lint_swagger_bindings.py --json --output /tmp/swagger-stage5-after.json; AST-check public domain methods without bindings; pytest; mypy avito; ruff check . |
| 2026-04-29 | Выполнен Этап 6: strict completeness включён в CLI и make check; временные multi-binding targets для альтернативных upstream modes и OAuth token operations закрыли coverage до 204/204 bound, 0 unbound, 0 duplicate, 0 ambiguous. |
Done | poetry run python scripts/lint_swagger_bindings.py --json --strict --output /tmp/swagger-stage6.json; make swagger-lint; make check |
| 2026-04-29 | Выполнен Этап 6.5: generated reference/coverage переведены на Swagger binding report, docs CI/docs-report используют strict report, оставшиеся ссылки на удалённые docs-report scripts убраны. | Done | make docs-strict; make docs-report; rg по inventory/check_inventory/удалённым docs scripts; manual review generated site/reference/coverage и site/reference/operations |
| 2026-04-29 | Выполнен Этап 7: linter валидирует path.<name>, query.<name>, header.<name>, body/body.<field> и constant.<name> expressions; class-level factory defaults фильтруются по Swagger operation; исправлены bindings для autoload query/upload и Autoteka token. |
Done | pytest tests/core/test_swagger*.py; poetry run python scripts/lint_swagger_bindings.py --json --strict --output /tmp/swagger-stage7.json; make swagger-lint; mypy avito; ruff check avito tests/core/test_swagger_linter.py |
| 2026-04-29 | Выполнен Этап 8: добавлен SwaggerFakeTransport, generated SDK call invocation по discovered bindings, request validation для method/path/path-query-header params/body/content-type, response happy-path mapping, error status mapping для всех Swagger error status categories и deprecated/legacy runtime warning contract. |
Done | poetry run pytest tests/contracts/test_swagger_contracts.py tests/core/test_swagger_registry.py tests/core/test_swagger_linter.py tests/contracts/test_public_surface.py; poetry run python scripts/lint_swagger_bindings.py --strict; poetry run mypy avito; poetry run ruff check avito tests/contracts/test_swagger_contracts.py tests/contracts/test_public_surface.py tests/core/test_swagger_registry.py; poetry run pytest; make check |
| 2026-04-29 | Выполнен Этап 9: финальный gate пройден отдельными командами и через make check; проверено, что старый markdown inventory не упоминается как источник истины. |
Done | make test; make typecheck; make lint; make swagger-lint; make build; make check; rg по inventory/check_inventory/source of truth |
| 2026-04-29 | Добавлен новый Этап 10 для устранения несоответствий после выполнения плана: запрет нескольких bindings на один SDK method, schema-aware validation для body.<field>, усиление contract tests до полного binding/status coverage. Upstream Swagger mismatch не входит в этап и остаётся отдельной задачей. |
Planned | Manual review |
| 2026-04-29 | Выполнен Этап 10.1: multi-binding SDK methods разделены на отдельные discovered targets, stacked decorators запрещены, discovery/linter ловят legacy __swagger_bindings__, docs больше не допускают multi-operation SDK methods. |
Done | poetry run pytest tests/core/test_swagger.py tests/core/test_swagger_discovery.py tests/core/test_swagger_linter.py tests/core/test_swagger_report.py; poetry run python scripts/lint_swagger_bindings.py --json --strict --output /tmp/swagger-10-1.json; jq check for duplicate sdk_method; make swagger-lint; poetry run mypy avito; poetry run ruff check avito tests/core docs/site/assets/_gen_reference.py |
| 2026-04-29 | Выполнен Этап 10.2: SwaggerRequestBody хранит content types, top-level schema fields и schema extraction flag; registry извлекает inline/$ref/composed object properties; linter проверяет body.<field> и выдаёт SWAGGER_BINDING_BODY_FIELD_NOT_FOUND / SWAGGER_BINDING_BODY_SCHEMA_UNSUPPORTED; bindings приведены к schema-aware expressions. |
Done | poetry run pytest tests/core/test_swagger_registry.py tests/core/test_swagger_linter.py; poetry run python scripts/lint_swagger_bindings.py --json --strict --output /tmp/swagger-10-2.json; make swagger-lint; poetry run mypy avito; poetry run ruff check avito tests/core docs/site/assets/_gen_reference.py; make check |
| 2026-04-29 | Выполнен Этап 10.3: contract tests усилены до полного request coverage по 204 discovered bindings и полного error coverage по 639 numeric Swagger error responses; SwaggerFakeTransport получил generated success invocation для auth/domain bindings, controlled success payload registry и дополнительные SDK argument builders; исправлены выявленные Swagger request drift в query/header параметрах. |
Done | poetry run pytest tests/contracts/test_swagger_contracts.py; full verification по 10.4 |
| 2026-04-29 | Выполнен Этап 10.4: пройден полный verification set после усиления contract tests; strict binding report подтверждает 204/204 bound, 0 unbound, 0 duplicate, 0 ambiguous, 0 validation errors. | Done | poetry run pytest tests/core/test_swagger.py tests/core/test_swagger_discovery.py tests/core/test_swagger_linter.py tests/core/test_swagger_report.py; poetry run pytest tests/core/test_swagger_registry.py tests/contracts/test_swagger_contracts.py; make swagger-lint; poetry run mypy avito; poetry run ruff check avito tests/core tests/contracts/test_swagger_contracts.py; make docs-strict; make check |