Почему «просто добавить функцию» иногда означает переделать полсистемы

 

 

 

 

 

ПРОЕКТИРОВАНИЕ // DEPENDENCY_IMPACT

Стоимость новых функций

«Добавьте ещё одну функцию».

На уровне бизнес-задачи это может звучать совершенно безобидно. Нужно добавить новый статус заказа, разрешить ещё один способ оплаты, подключить дополнительный канал продаж или дать определённым сотрудникам новый сценарий работы.

Кажется, что речь идёт об одной небольшой доработке.

Но в работающей информационной системе почти не бывает изменений, которые существуют изолированно.

Новая функция ⟳База данныхAPIБизнес-логикаИнтерфейсИнтеграция с ERPУведомленияОтчётностьПрава доступа

Новый статус может затронуть базу данных, API, бизнес-логику, интерфейс, integration с ERP, уведомления, отчётность и права доступа. Новый способ оплаты — финансовый контур, возвраты, сверку платежей, договоры с провайдерами и бухгалтерскую отчётность. Новый тип клиента может повлиять на расчёт цены, CRM, документы и правила маршрутизации.

В результате задача, которая выглядит как «добавить одно поле», превращается в изменение нескольких связанных компонентов.

И чем дольше система развивается без пересмотра архитектуры, тем выше вероятность, что очередная небольшая функция затронет гораздо больше, чем предполагалось.

ДИАГНОЗ // EVOLUTION_LIMITS

Это не обязательно означает, что система плохо написана.

> Чаще проблема в другом: требования бизнеса растут быстрее, чем архитектура успевает адаптироваться к этим изменениям.

 

 

 

 

АРХИТЕКТУРА // COUPLING_COMPLEXITY

Программный продукт меняется не по одному месту

Представим простую систему заказов.

В ней есть: заказ → клиент → товар → оплата → доставка

На раннем этапе всё может быть достаточно просто. Затем бизнес начинает развиваться.

Появляются:

РАСШИРЕНИЕ // EVOLVING_REQUIREMENTS
  • › несколько типов клиентов;
  • › разные способы оплаты;
  • › возвраты;
  • › частичные отгрузки;
  • › несколько складов;
  • › программы лояльности;
  • › интеграция с ERP;
  • › мобильное приложение;
  • › личный кабинет;
  • › новые каналы продаж.

Каждое требование само по себе кажется небольшим.

Но система уже состоит из множества взаимосвязанных решений.

НОВОЕ ТРЕБОВАНИЕБизнес-логикаБаза данныхAPIИнтерфейсОтчётыИнтеграцииКлиентскийсценарийАналитикаERP / CRM

Изменение не обязательно большое.

Большим становится количество зависимостей, которые нужно сохранить после этого изменения.

Именно это принципиально отличает зрелую работающую систему от нового проекта, где ещё можно относительно свободно менять архитектуру.

 

 

 

 

ЭВОЛЮЦИЯ // ARCHITECTURAL_HISTORY

Почему в новой системе изменить что-то проще

Когда продукт только создаётся, архитектура ещё не связана историческими решениями.

Разработчики могут свободно определить:

ПРОЕКТИРОВАНИЕ // GREENFIELD_FREEDOM
  • › структуру данных;
  • › границы модулей;
  • › интерфейсы между компонентами;
  • › правила доступа;
  • › формат API;
  • › способы обработки ошибок;
  • › механизмы интеграции.

Но по мере эксплуатации система накапливает решения.

НАСЛОЕНИЯ // ACCUMULATED_DECISIONS
  • › Некоторые из них были приняты осознанно.
  • › Другие появились как временные.
  • › Третьи были оптимальными несколько лет назад, но перестали соответствовать текущим требованиям.
  • › Четвёртые возникли из-за ограничений внешних систем.
  • › Пятые появились просто потому, что бизнесу нужно было выпустить функцию вчера.

Постепенно архитектура начинает отражать не только первоначальный замысел, но и всю историю развития продукта.

> И именно здесь возникает технический долг.

 

 

 

 

ОПРЕДЕЛЕНИЕ // TECHNICAL_DEBT_NATURE

Технический долг — это не просто «плохой код»

Термин часто используют слишком широко. Иногда техническим долгом называют любой старый код, который не нравится разработчикам. Это неточно.

Технический долг возникает тогда, когда текущее техническое решение создаёт дополнительные будущие затраты.

Компания может сознательно выбрать более быстрый и менее универсальный вариант, чтобы быстрее вывести продукт на рынок. Например, вместо полноценной архитектуры скидок реализовать несколько конкретных правил. В момент запуска это может быть абсолютно рациональным решением.

Проблема появляется позже, когда правил становится двадцать, они начинают пересекаться, а новая акция требует изменения сразу нескольких частей системы.

Первоначально сэкономленное время превращается в будущую стоимость изменений.

Быстрое решениеМеньше затрат сегодняАрхитектура получает ограничениеПоявляются новые требованияИзменение затрагивает больше компонентовРастёт стоимость следующего изменения

Поэтому технический долг — не обязательно ошибка.

Это обязательство, которое система берёт на себя ради текущей выгоды.

Проблемой он становится тогда, когда компания перестаёт контролировать размер и последствия этого обязательства.

 

 

 

 

МЕТРИКИ // CHANGE_COST_DRIVERS

Почему стоимость изменений растёт

Есть важное наблюдение: стоимость функции не определяется только количеством кода.

На неё влияет количество системных ограничений, которые необходимо учесть.

ФОРМУЛА // COST_EQUATION
стоимость изменения = разработка + анализ зависимостей + тестирование + миграция + интеграции + сопровождение риска

На ранней стадии большая часть этой формулы может быть небольшой.

В зрелой системе резко увеличивается другая часть — стоимость проверки того, что изменение ничего не сломало вокруг себя.

Например, изменение поля status может потребовать проверить:

ОБЛАСТЬ_ПРОВЕРКИ // IMPACT_RADIUS_CHECK
  • › бизнес-логику;
  • › API;
  • › мобильное приложение;
  • › отчёты;
  • › интеграцию с CRM;
  • › интеграцию с ERP;
  • › уведомления;
  • › права доступа;
  • › фоновые задачи;
  • › исторические данные.
[ ИЗМЕНЕНИЕ ]
Само изменение может занять несколько часов.
[ ВАЛИДАЦИЯ ]
Но доказать, что система продолжает корректно работать, может потребовать значительно больше времени.

 

 

 

 

ЗАВИСИМОСТИ // COUPLING_IMPACT

Чем больше связей, тем дороже изменение

Представим компонент, который используется только одним сервисом. Изменить его относительно просто.

Теперь представим компонент, которым пользуются:

ПОТРЕБИТЕЛИ_КОМПОНЕНТА // COMPONENT_DEPENDENTS
  • › пять внутренних сервисов;
  • › мобильное приложение;
  • › внешний API;
  • › интеграция с ERP;
  • › аналитический контур.

Любое изменение его поведения требует учитывать всех потребителей.

ЗАКОН_СВЯЗАННОСТИ // ARCHITECTURAL_LAW

Получается принцип:

чем больше зависимостей у компонента, тем выше стоимость изменения этого компонента.

Именно поэтому архитектура — это не только вопрос производительности или красоты кода. Она напрямую влияет на экономику развития продукта.

 

 

 

 

УГРОЗЫ // SHADOW_DEPENDENCIES

Самая опасная зависимость — скрытая

Явную зависимость обычно обнаружить несложно.

Например, сервис A вызывает API сервиса B. Это можно увидеть в архитектурной документации, коде или конфигурации.

Гораздо опаснее скрытая зависимость.

КЕЙСЫ // HIDDEN_CONTRACTS
  • › другой сервис не вызывает API напрямую, но рассчитывает на определённый формат данных в общей таблице;
  • › отчёт предполагает, что определённый статус заказа означает конкретное бизнес-состояние;
  • › внешняя система ожидает, что поле никогда не будет пустым.
АНАЛИЗ_СВЯЗЕЙ // UNTRACKED_COUPLING

Формально компоненты могут выглядеть независимыми.

> Фактически они связаны контрактом, который нигде не описан.

Именно такие связи особенно сильно усложняют развитие системы.

 

 

 

 

ПРОЦЕССЫ // STATE_MACHINE_EVOLUTION

Почему «одно поле» иногда становится большой задачей

Рассмотрим типичный пример.

Бизнес говорит:

«Добавим заказу новый статус — “Ожидает подтверждения”».

В базе данных добавить значение относительно просто. Но что дальше?

Нужно определить:

АНАЛИЗ_СОСТОЯНИЯ // STATE_IMPACT_CHECKLIST
  • › кто может установить этот статус;
  • › из каких состояний в него можно перейти;
  • › в какие состояния можно перейти после него;
  • › что происходит с оплатой;
  • › нужно ли уведомлять клиента;
  • › появляется ли задача у сотрудника;
  • › что показывает CRM;
  • › что передаётся в ERP;
  • › учитывается ли заказ в отчётах;
  • › можно ли отгрузить такой заказ;
  • › что увидит мобильное приложение;
  • › как обрабатываются старые заказы.

Получается уже не изменение поля.

Это изменение состояния бизнес-процесса.

БЫЛО:Новый → В работе → Оплачен → Отгружен → ЗавершёнСТАЛО:НовыйВ работеОжидает подтвержденияОплаченОтгружен

Добавилось одно состояние.

Но изменился граф переходов, а значит, изменился сам процесс.

 

 

ЭВОЛЮЦИЯ_РИСКОВ // ACCUMULATED_CONSTRAINTS

Архитектурные ограничения появляются постепенно

Система редко просыпается однажды утром с полностью неправильной архитектурой.

Обычно ограничения накапливаются.

Сначала появляется небольшое исключение. Потом второе. Потом третье. Затем оказывается, что новый функционал приходится реализовывать через специальные условия.

Первоначальная модельНовое требованиеНебольшое исключениеЕщё одно требованиеВторое исключениеНовый каналДополнительная логикаСложная система условийИзменения становятся дорогими

Каждое отдельное решение может казаться разумным.

Проблема возникает на уровне их комбинации.

 

 

 

 

ОГРАНИЧЕНИЯ_КОНТУРА // ARCHITECTURAL_MISALIGNMENT

Архитектура может перестать соответствовать бизнесу

Особенно часто это происходит с продуктами, которые начинались как относительно простые. Компания могла стартовать с одной моделью бизнеса.

Через несколько лет она уже работает с:

БИЗНЕС_МАСШТАБИРОВАНИЕ // ENTERPRISE_REALITY
  • › несколькими рынками;
  • › разными типами клиентов;
  • › несколькими юридическими лицами;
  • › несколькими каналами продаж;
  • › сложными тарифами;
  • › партнёрами;
  • › внешними API;
  • › большим количеством интеграций.

А внутри продолжает жить архитектура, рассчитанная на первоначальный сценарий.

Тогда разработчики вынуждены постоянно добавлять исключения.

КРИТИЧЕСКИЙ_СИГНАЛ // BOTTLENECK_DETECTED

Это важный сигнал:

> если новый бизнес-процесс приходится постоянно «приспосабливать» под старую архитектуру, возможно, ограничением уже является сама архитектура.

 

 

 

 

ЭКОНОМИКА_ДОЛГА // DEBT_REFAC_MANAGEMENT

Не всякий технический долг нужно погашать

Здесь тоже легко впасть в крайность. Увидеть старый код и решить «сначала всё перепишем» — не обязательно хорошая стратегия.

Полная переписывание системы редко является целью само по себе.

У технического долга должна быть экономическая оценка. Стоит спросить:

АУДИТ_ДОЛГА // REFACTORING_QUESTIONS
  • › Как часто этот участок меняется?
    Если компонент практически не меняется, его несовершенная архитектура может не создавать существенных затрат.
  • › Сколько изменений он блокирует?
    Если один старый компонент мешает развитию нескольких ключевых функций, его приоритет значительно выше.
  • › Насколько дорого каждое изменение?
    Если каждое новое требование требует недельного анализа и тестирования, это уже заметный бизнес-фактор.
  • › Какой риск несёт существующее решение?
    Иногда проблема не в скорости разработки, а в надёжности, безопасности или невозможности масштабирования.
  • › Есть ли понятный момент для изменения архитектуры?
    Иногда правильнее не делать отдельный большой проект, а менять проблемный участок постепенно вместе с развитием функциональности.

 

 

 

 

РИСКИ // PATCH_OVERLOADING

Когда «ещё одна заплатка» становится опасной

Допустим, команда знает, что определённая часть системы архитектурно устарела. Но каждый новый запрос решается небольшим обходным механизмом.

Это кажется дешевле. И иногда действительно дешевле.

Проблема начинается, когда временное решение становится постоянным.

Через несколько итераций появляется слой условий:

СЛОЙ_УСЛОВИЙ // ACCUMULATED_IF_STATEMENTS
  • › если клиент такого типа — делаем так;
  • › если заказ пришёл из этого канала — делаем иначе;
  • › если старая интеграция — используем отдельный сценарий;
  • › если дата раньше определённого момента — применяем старое правило.

Система продолжает работать.

Но стоимость понимания этой системы начинает расти.

А это тоже технический долг.

 

 

 

 

ЭКСПЛУАТАЦИЯ // HIDDEN_RESOURCES_COST

Самый дорогой ресурс — иногда не разработка

В зрелом enterprise-продукте значительная часть стоимости изменения может приходиться не на написание кода.

Необходимо:

ПРОЦЕССЫ_ИЗМЕНЕНИЯ // OVERHEAD_OPERATIONS
  • › понять существующую архитектуру;
  • › найти зависимости;
  • › проверить контракты;
  • › согласовать изменение;
  • › подготовить миграцию;
  • › обновить интеграции;
  • › провести регрессионное тестирование;
  • › проверить данные;
  • › организовать релиз;
  • › проконтролировать работу после внедрения.

Поэтому две системы с одинаковым объёмом кода могут иметь совершенно разную стоимость развития.

[ ПЕРВАЯ СИСТЕМА ]
Одна имеет понятные границы и слабую связанность.
[ ВТОРАЯ СИСТЕМА ]
Другая представляет собой сеть исторически сложившихся зависимостей.

Во второй любое изменение становится расследованием.

 

 

 

 

ДИАГНОСТИКА // DEGRADATION_SIGNALS

Как понять, что architecture уже начинает мешать

Есть несколько характерных признаков.

СИМПТОМЫ // ARCHITECTURAL_RED_FLAGS
  • › Новая функция регулярно затрагивает несколько несвязанных модулей:
    Если практически любое изменение требует правок в пяти-десяти местах, стоит проверить границы компонентов.
  • › Разработчики боятся менять старый код:
    Не потому, что код старый, а потому, что неизвестно, что от него зависит.
  • › Регрессионное тестирование растёт быстрее функциональности:
    Каждая новая функция требует всё большего набора проверок.
  • › Появляются специальные исключения:
    Вместо общей бизнес-логики постоянно добавляются условия для отдельных клиентов, каналов или сценариев.
  • › Интеграции становятся хрупкими:
    Изменение одного внутреннего объекта неожиданно ломает внешний обмен.
  • › В компании есть «незаменимые» специалисты:
    Если только один человек знает, почему определённый компонент работает именно так, это не только кадровый риск. Это архитектурный сигнал.
КРИТИЧЕСКИЙ_СИМПТОМ // DANGEROUS_PATTERN

> Разработка всё чаще начинается с фразы «там лучше не трогать» — это, пожалуй, один из самых характерных симптомов.

 

 

 

 

ПРОЕКТИРОВАНИЕ // CHANGE_RESILIENCE

Архитектура должна выдерживать изменения

Хорошая архитектура — не та, которая идеально предсказывает будущее.

Предсказать все будущие требования невозможно.

ЗАДАЧА // DESIGN_GOAL

Задача архитектуры другая:

— сделать наиболее вероятные изменения относительно дешёвыми и локальными.

ПРИНЦИПЫ_ИЗОЛЯЦИИ // CHANGE_LOCALIZATION
  • › Если изменение каталога товаров не должно затрагивать механизм авторизации, эти части системы желательно разделить.
  • › Если новый канал продаж не должен переписывать финансовый контур, между ними должен существовать понятный контракт.
  • › Если изменение внутренней реализации сервиса не должно ломать десятки клиентов API, интерфейс сервиса должен быть отделён от его внутреннего устройства.

Это и есть одна из главных задач архитектуры — управлять стоимостью изменений.

 

 

 

 

ПРОЕКТИРОВАНИЕ // COUPLING_TYPES

Слабая связанность — не абстрактная теория

Термин «слабая связанность» иногда звучит как академическая архитектурная теория.

На практике это очень конкретная экономическая характеристика.

Если изменение компонента A требует обязательно менять B, C, D и E, система сильно связана.

Если A можно изменить независимо, потому что взаимодействие с другими компонентами проходит через стабильные контракты, связанность ниже.

СИЛЬНАЯ СВЯЗАННОСТЬ:
ABCDE
СЛАБАЯ СВЯЗАННОСТЬ:
APIABCDE

Во втором случае внутреннее изменение одного компонента не обязательно требует изменения всех остальных.

Но слабая связанность тоже имеет цену: нужны хорошие интерфейсы, контракты, обработка ошибок, версионирование и дисциплина взаимодействия.

ПРАВИЛО // COMPLEXITY_MANAGEMENT

Архитектура не убирает сложность.

— Она переносит её в управляемое место.

 

 

 

 

ИНТЕГРАЦИИ // INTEGRATION_OVERHEAD

Почему интеграции особенно быстро увеличивают стоимость изменений

Каждая внешняя система добавляет контракт.

РАЗНОРОДНОСТЬ_КОНТРАКТОВ // EXTERNAL_CONTRACTS
CRM ожидает:
один формат.
ERP —
другой.
Платёжная система —
третий.

Мобильное приложение использует API.

Партнёр подключён к ещё одному интерфейсу.

РАДИУС_ПОРАЖЕНИЯ // INTERNAL_CHANGE_RISK

Теперь изменение внутренней модели данных нельзя рассматривать только внутри одного приложения.

> Нужно проверить, какие внешние потребители от неё зависят.

Поэтому при росте количества интеграций особенно важны:

ТРЕБОВАНИЯ // COMPONENT_STABILITY
  • › стабильные API;
  • › версионирование;
  • › чёткие контракты;
  • › преобразование данных на границах систем;
  • › обработка ошибок;
  • › мониторинг;
  • › обратная совместимость.

Без этого каждая новая интеграция увеличивает не только функциональность системы, но и стоимость последующих изменений.

 

 

 

 

ПРОЕКТИРОВАНИЕ // BOUNDARY_REFACTORING

Иногда проблему нужно решать не кодом, а изменением границ

Это важный момент для больших систем.

Если определённый модуль постоянно меняется независимо от остальных, возможно, он должен иметь более чёткую границу. Например:

РАЗДЕЛЕНИЕ // BOUNDARY_EXAMPLES
  • › каталог товаров может развиваться отдельно от расчёта платежей;
  • › Управление клиентами — отдельно от логистики;
  • › Уведомления — отдельно от основного бизнес-процесса.

Но выделять отдельный сервис только потому, что «микросервисы — это современно», тоже неправильно.

Каждая дополнительная граница создаёт собственную сложность:

СЛОЖНОСТЬ_ИНФРАСТРУКТУРЫ // OVERHEAD_COSTS
  • › сетевые вызовы;
  • › отказоустойчивость;
  • › мониторинг;
  • › согласованность данных;
  • › управление версиями;
  • › диагностику;
  • › эксплуатацию.

Поэтому архитектурное разделение оправдано не количеством компонентов, а характером изменений и ответственностью за бизнес-функции.

 

 

 

 

МЕТОДОЛОГИЯ // RECOVERY_STRATEGY

Что делать, когда требования уже обогнали архитектуру

Первый шаг — не переписывать всё.

Сначала нужно понять, где именно находится ограничение. Полезно построить карту:

Бизнес-функцииКомпоненты системыЗависимостиИнтеграцииДанные и контракты

После этого можно увидеть участки, которые:

ПРИОРИТЕТЫ // FOCUS_AREAS
  • › меняются чаще всего;
  • › имеют слишком много зависимостей;
  • › блокируют развитие;
  • › содержат большое количество исключений;
  • › создают высокий операционный риск.

Именно они обычно заслуживают архитектурного внимания в первую очередь.

 

 

МЕТОДОЛОГИЯ // REFACTORING_STRATEGY

Рефакторинг и переписывание — не одно и то же

Если архитектурный участок действительно мешает развитию, это не означает, что его необходимо удалить и написать заново.

Часто безопаснее идти постепенно.

Например:

старый компонент → новый интерфейс → постепенный перенос логики → переключение потребителей → вывод старого компонента из эксплуатации

Такой подход позволяет менять архитектуру одновременно с развитием продукта.

Он сложнее, чем «сделать новую систему с нуля», но существенно снижает риск остановить бизнес-процессы.

Для работающего enterprise-продукта это часто критически важно.

 

 

 

 

ИТОГ // CHANGE_COST_CONTROL

Стоимость изменения можно контролировать

Нельзя сделать систему, в которой любое будущее изменение будет дешёвым.

Но можно сделать так, чтобы стоимость изменений росла предсказуемо, а не скачкообразно.

Для этого архитектуру необходимо регулярно проверять по нескольким направлениям:

НАПРАВЛЕНИЯ_ПРОВЕРКИ // ARCHITECTURAL_HEALTH_DIRECTIONS
  • › Изменяемость.
    Какие компоненты меняются чаще всего?
  • › Связанность.
    Сколько других компонентов приходится затрагивать?
  • › Контракты.
    Насколько безопасно менять внутреннюю реализацию?
  • › Данные.
    Можно ли изменить модель без разрушительных миграций?
  • › Интеграции.
    Есть ли стабильные интерфейсы между системами?
  • › Тестируемость.
    Можно ли быстро доказать, что изменение не сломало существующее поведение?
  • › Наблюдаемость.
    Можно ли понять, что произошло после релиза?

Это уже не просто технические характеристики.

Это показатели того, насколько бизнес способен развивать свой цифровой продукт без постоянного увеличения стоимости изменений.

 

 

ИТОГ // FINAL_RESOLUTION

Главное — не путать рост продукта с деградацией архитектуры

Большая система не обязана быть плохой.

Сложный бизнес закономерно приводит к сложной информационной системе.

Проблема начинается не тогда, когда в системе много компонентов.

КРИЗИС // ARCHITECTURAL_COMPLEXITY

> Проблема начинается, когда её сложность перестаёт соответствовать структуре бизнеса и становится препятствием для изменений.

Поэтому фраза «нам нужно добавить ещё одну функцию» должна восприниматься не как вопрос количества кода.

Нужно понимать:

СПИСОК_КОНТРОЛЯ // IMPACT_ANALYSIS_LIST
  • › что именно меняется в бизнес-процессе;
  • › какие компоненты отвечают за этот процесс;
  • › какие зависимости существуют;
  • › какие контракты затрагиваются;
  • › какие данные изменятся;
  • › и насколько локальным может остаться изменение.

Если функция действительно локальна — её и нужно делать локально.

Если она затрагивает фундаментальную модель продукта, лучше признать это на этапе проектирования, чем маскировать архитектурную проблему ещё одним исключением.

Потому что технический долг редко становится дорогим в момент своего появления.

Он становится дорогим тогда, когда каждое следующее изменение начинает платить за решения, принятые раньше.

Именно поэтому архитектуру стоит оценивать не только по тому, насколько хорошо система работает сегодня.

ФУНДАМЕНТ // CORE_QUESTION

Не менее важный вопрос:

— «сколько будет стоить изменить её завтра?»

 

 

НАВИГАЦИЯ // SUGGESTED_READING
 
[ Модуль // ИНТЕГРАЦИИ ]

API, Webhook или очередь сообщений?

 
[ Модуль // ИНТЕГРАЦИИ ]

Когда API есть, а интеграция всё равно не работает

 
[ Модуль // АВТОМАТИЗАЦИЯ ]

Как соединить производство и корпоративные системы

 
[ EXPERTISE JOURNAL ]

Все инженерные материалы и экспертные статьи

 
[ CORE GLOSSARY ]

Полный алфавитный справочник ИТ-терминов

 

[ DIRECT EMAIL LINE ]
info@log-ai.ru

 

🔒 Данные и доступ к системам заказчика обрабатываются в соответствии с согласованными требованиями к безопасности и конфиденциальности. Условия доступа, хранения и обработки данных определяются архитектурой проекта и договором.

Сайт носит исключительно информационный характер и не является публичной офертой в соответствии со статьёй 437 Гражданского кодекса РФ. Цены, состав и условия предоставления услуг уточняются при проектировании решения и фиксируются в договоре. Условия технического сопровождения и уровень сервиса могут дополнительно определяться отдельным соглашением (SLA).

© 2026 Log-AI Москва
Автоматизация бизнеса и ИИ-решения под ключ
Самозанятый Скопец Антон Викторович ИНН 741709260870
Политика конфиденциальности Пользовательское соглашение
AI Ассистент
×