От набора инструментов к единой экосистеме
Изначально продукт состоял из нескольких независимых AI-функций: генератора изображений по текстовому описанию, конвертера фото в эскиз татуировки, инструмента для генерации надписей и шрифтов, а также модуля виртуальной примерки. Каждый инструмент работал корректно, но существовал в вакууме. Его работа завершалась на собственном результате — изображении или эскизе, после чего пользователю приходилось начинать весь процесс заново при переходе к следующему шагу.
По мере развития продукта стало очевидно, что пользовательский путь не является линейным. После получения любого результата человек хотел совершить одни и те же действия: модифицировать изображение, сохранить его, скачать, поделиться с друзьями или «примерить» эскиз на теле. Повторение этих опций после каждого инструмента создавало ощущение разрозненности и неудобства. Стало ясно, что задача сместилась от добавления новых функций к созданию бесшовного опыта между ними.
Смена парадигмы: результат важнее инструмента
Ключевой проблемой была архитектура, в которой каждый инструмент «владел» своим результатом. Это приводило к слабой интеграции. Если пользователь генерировал черновой вариант татуировки и хотел его доработать, следующий шаг ощущался как запуск совершенно нового приложения. То же самое происходило, если точкой входа служила фотография или набросок от руки — источник был разным, но последующие шаги должны были быть идентичными.
Решением стал переход к централизованной модели данных. Вместо того чтобы думать о страницах и инструментах, которые владеют результатами, фокус сместился на сам результат как на единый объект, который циркулирует внутри продукта. Любой инструмент теперь рассматривается просто как способ произвести этот объект.
Была сформулирована упрощенная структура объекта TattooResult, которая описывает не то, как было создано изображение, а то, что с ним можно сделать дальше:
type TattooResult = {
imageUrl: string;
source: "generator" | "image-to-tattoo" | "lettering";
canModify: boolean;
canTryOn: boolean;
canSave: boolean;
canDownload: boolean;
canShare: boolean;
}
Хотя реальная реализация в коде сложнее, именно эта ментальная модель изменила подход к разработке. Универсальный стандарт результата позволил легко подключать любые downstream-действия (модификацию, примерку, сохранение) независимо от того, какой инструмент был использован на входе.
Image to Tattoo: от финала к стартовой точке
Наиболее ярко преимущество новой архитектуры проявилось в работе с инструментом преобразования фотографий в эскизы. Ранее этот модуль часто становился тупиком рабочего процесса. Теперь он воспринимается как равноправная точка входа. Пользователь загружает свое фото, система создает объект TattooResult, и далее этот эскиз беспрепятственно передается в другие части системы: его можно доработать в редакторе, изменить стиль линий или сразу перейти к виртуальной примерке на своей фотографии.
Такой подход устраняет барьеры между инструментами. Продукт перестает быть набором отдельных утилит и превращается в единую среду для работы над проектом татуировки. Пользователю больше не нужно заботиться о том, в каком модуле он находится; он работает с одним объектом, последовательно применяя к нему различные операции. Главным итогом этой архитектурной перестройки стало не улучшение отдельных алгоритмов, а кардинальное повышение удобства и непрерывности всего творческого процесса.