Поставка софта Поставка софта: карта трека и почему это инженерный вопрос
0%

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

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

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

Первое. «Поднимем себе инстанс it-tools на поддомене, чтобы не бегать по десяти сайтам ради base64 и JWT». Инструмент открытый, GPL-3.0, ставится одной командой. Через месяц выясняется: браузеру каждого посетителя уезжает собранный бандл — то есть объектный код, — а GPL-3.0 требует сопроводить объектный код доступом к исходникам ровно той версии, которую вы отдаёте. Поддомен превратил команду в распространителя.

Второе. «Продадим цифровой набор за фиксированную цену, ссылку на архив пришлём почтой». Через неделю всплывают вопросы, которых не было в задаче: ссылка одноразовая или вечная? покупатель просит возврат, а файл уже скачан — возврат отзывает право пользования или нет? Отзывает — значит, нужен статус права, умеющий становиться «отозванным», и выданные ссылки обязаны переставать работать. У продукта внезапно появилась доменная модель.

Третье. «Сделаем помесячную и годовую подписку, годовая на два месяца дешевле». Выглядит строчкой в прайсе, а оказывается пропорциональным пересчётом при переходе посреди периода, идемпотентной обработкой вебхуков (провайдер пришлёт одно событие дважды — это норма, а не сбой), логикой неудачных списаний, суммой налога на момент продажи и выгрузкой для бухгалтерии.

Ни одно из решений не выглядело инженерным, но все три стали кодом, который содержат годами:

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

Что такое поставка и где проходит её граница

Три слова, которые в разговоре сливаются в одно, а отвечают за разное:

Слово Что означает Где разбирается
Сборка превращение исходников в артефакт: бинарь, образ, пакет, бандл devops, platform-engineering
Выкат перевод вашего продакшна на новую версию так, чтобы ничего не упало sre: безопасные релизы
Поставка переход артефакта и права им пользоваться к тому, кто вам платит или кого вы этим обязали этот трек

Разница видна на одном вопросе: что происходит, если получатель не хочет обновляться? Для выката такого вопроса нет — прод один и он ваш. Для поставки это центральный вопрос: у клиента стоит версия трёхлетней давности, она в поддержке или нет, кто чинит уязвимость в ней и что вы делаете, если он отказывается ставить новую.

Цепочка поставки: шесть шагов от сборки до поддержки и обязательства, которые включаются на каждом

Слева от границы — территория конвейеров, справа — этого трека. Цикл замыкается: вторая версия проходит те же шесть шагов, но теперь у вас уже есть получатели с первой.

Почему это инженерный вопрос, а не «вопрос продажников»

Потому что коммерческая формулировка почти всегда содержит скрытое техническое требование, и оно дороже самой формулировки:

  • «Первые 14 дней бесплатно» → нужно понятие пробного права, различие «пробник закончился» и «оплата не прошла», защита от бесконечных пробников и решение про данные после окончания (удалить нельзя — человек вернётся; хранить вечно — это ваши деньги).
  • «Цена за пользователя» → нужно определить, кто такой активный пользователь и когда его считать (пик за период? на конец периода? среднее?); метрика цены становится частью схемы данных.
  • «Продаём через маркетплейс облака» → нужен второй путь выдачи прав: подтверждение приходит не от вашей формы оплаты, а от площадки, по её протоколу и с её идентификаторами.

Правило: любое обещание покупателю — это состояние в вашей системе, переход между состояниями и операция отката этого перехода. Обещаний, которые «просто есть», не бывает.

Цена владения: рамка, через которую трек смотрит на всё

Каждая модель разбирается по трём колонкам — не «SaaS современнее коробки», а конкретно: что получает покупатель (какую работу перестаёт делать и какой риск снимает), во что это обходится поставщику (что придётся построить и содержать) и какие обязательства создаёт. Третья колонка недооценена сильнее всего: от расхода можно отказаться, от обязательства — нет, и не даром.

Модель Покупателю Поставщику Обязательства
Коробка (артефакт у клиента, разовая оплата) контроль, работа без сети, независимость от вашей аптайм-статистики сборка под каждую платформу, инсталлятор, подпись, поддержка старых версий вслепую чинить уязвимости в версиях, которые вы уже не разрабатываете; не ломать совместимость данных
SaaS (код у вас, подписка) нулевая установка, обновления сами, предсказуемый расход инфраструктура, дежурства, изоляция тенантов, биллинг, экспорт данных доступность, сохранность чужих данных, возможность уйти с ними, честный статус инцидентов
Self-hosted (артефакт у клиента, подписка на право и поддержку) данные не покидают контур, соответствие внутренним требованиям воспроизводимая установка в чужой среде, диагностика без доступа, лицензионный контроль поддержка версий, которые клиент не спешит обновлять; работа в средах, которые вы не видите
Гибрид (управляющий слой у вас, обработка у клиента) компромисс по данным при удобстве управления две поставки вместо одной плюс контракт совместимости между ними совместимость управляющего слоя со всеми живыми агентами

Разбор — в главе Модели поставки; граница ответственности внутри облачных уровней — в IaaS, PaaS, SaaS, FaaS; цена изоляции при общей инфраструктуре — в Многотенантности. Сам выбор редко бывает свободным — чаще его определяют три ограничения:

На выходе не «модель», а список умений, которые придётся построить: модель поставки — это в первую очередь обязательство перед собой.

Право пользования — объект вашей системы, а не строчка в договоре

Ключевая абстракция трека: entitlement, право пользования — ответ системы на вопрос «что получателю сейчас разрешено», выраженный данными, а не намерением. Право есть в любой модели: у коробки это ключ и срок, у SaaS — подписка и план, у self-hosted — файл лицензии с лимитом узлов, у магазина — покупка, подтверждённая площадкой. Автомат почти не зависит от модели:

  • «Отменено» и «Истекло» — разные состояния. Отменил вчера, но период оплачен до конца месяца — доступ есть. Путаница здесь превращается в возвраты и тикеты поддержки.
  • «Просрочено» — не «Истекло». Между ними живёт механика повторных списаний и напоминаний (карта истекла, лимит, случайный отказ банка); разбор — в Биллинге.
  • «Отозвано» существует отдельно, потому что возврат — не «отмена задним числом». На портале записано прямо: полный возврат за цифровой продукт отзывает право, и выданные ссылки перестают работать — правило невыполнимо, если ссылки не привязаны к состоянию права.
  • «Архив» — обязательство хранить и удалить одновременно: слишком рано — потеряли вернувшегося клиента, слишком поздно — храните чужие персональные данные без основания (ограничения, приватность).

То же самое во времени — покупка и возврат через внешнего провайдера платежей:

Источник истины о деньгах — вебхук, а не редирект браузера. Пользователь закроет вкладку, потеряет сеть, нажмёт «назад»; провайдер пришлёт событие дважды или с задержкой в минуты. Значит, подпись проверяется, идентификатор события хранится, повторная обработка не выдаёт второе право — та же дисциплина, что и в распределённых системах. Минимальный набор полей, который пишут с первого дня и потом не восстановить: кто получатель, что куплено (SKU и версия условий), срок действия права, сумма и валюта на момент продажи, ставка и сумма налога на момент продажи, принятая редакция оферты, канал продажи и его идентификатор заказа, текущее состояние права и история переходов.

Деньги: конкретика вместо слова «монетизация»

Пробный период. Одним словом называют три разные вещи: бесплатный тариф навсегда (freemium), пробник с картой и автопродлением, пробник без карты. Экономика разная: freemium — постоянная себестоимость на неплатящих, пробник с картой — высокая конверсия и поток возвратов, пробник без карты — низкая конверсия и спокойная поддержка. Инженерно тоже: freemium требует лимитов и деградации функций, пробник с картой — предупреждения до списания.

Апгрейд посреди периода. Клиент заплатил за месяц вперёд, на восемнадцатый день переходит на дорогой тариф. Вариантов три, выбрать надо один, записать в оферту и реализовать: (а) пропорциональный пересчёт — неиспользованный остаток идёт в зачёт нового тарифа, дата продления не меняется; (б) новый период начинается сразу, остаток сгорает — просто в коде, скандально в поддержке; (в) остаток превращается в кредит на балансе. Пересчёт требует единицы времени (секунда или день), правила округления и решения про копейки. Даунгрейд откладывают до конца периода — иначе получаете отрицательный счёт.

Возврат. Это три операции, а не одна: вернуть деньги, отозвать право, поправить налоговый учёт. На портале все три описаны явно: возврат идёт на тот же платёжный инструмент, заказ переходит в «деньги возвращены», исходный чек аннулируется или отражается как возврат. Отдельно живёт спорная операция (chargeback), когда деньги забирает банк покупателя без вашего согласия: право отзывают, а доказательства поставки (логи выдачи, время скачивания, принятая редакция оферты) — предъявляют.

Налоги и валюты. Ставка зависит от того, где находится покупатель и что именно продаётся, поэтому в момент продажи система обязана зафиксировать признаки местонахождения и применённую ставку — потом это не восстановить. Цены в разных валютах не пересчитывают по курсу на лету: курс скачет, «1043 рубля» выглядит как ошибка, а привычные границы цен в странах разные. Держат таблицу цен по валютам и правило пересмотра, например раз в квартал. Сколько налога и в какой стране платить — вопрос не к этому треку.

Считать до запуска стоит маржу на одном платящем за период:

$$ m = p \cdot (1 - c) - s - r $$

где p — цена периода, c — суммарная доля канала (комиссия площадки, эквайринг, платёжные сервисы), s — прямая себестоимость обслуживания одного получателя, r — ожидаемые потери на возвратах и спорах. Пример: подписка 1000 рублей в месяц, канал забирает 30 процентов, себестоимость 180 рублей, потери 3 процента. Тогда m = 1000 · 0,7 − 180 − 30 = 490 рублей, а при комиссии 15 процентов — 640 рублей: на 30 процентов больше маржи при той же цене на витрине. Спор о комиссии — не эмоция, а арифметика.

Отсюда порог, за которым свой канал выигрывает у магазина. Пусть F — постоянные расходы своего канала за период (эквайринг с абонентской платой, налоговый сервис, антифрод, доработки), c_1 — доля магазина, c_2 — доля своего канала:

$$ N > \frac{F}{p \cdot (c_1 - c_2)} $$

При F = 40 000 рублей в месяц, p = 1000 рублей, c_1 = 0,3 и c_2 = 0,05 порог равен 160 платящим в месяц: ниже — дешевле магазин, выше — свой канал. Это единственный честный способ говорить о комиссиях. Подробности — Ценообразование, Биллинг, Каналы поставки. Экономика вокруг работы инженера — счета, налоговые режимы, юнит-экономика услуг — лежит в business и собственном продукте, а готовность платить исследуют в product-management.

Лицензии как инженерное ограничение

Лицензия — не юридическая экзотика в отдельном файле, а условие сборки. Она отвечает на вопрос «что мне запрещено сделать с этим кодом в моём артефакте», и ответ зависит от того, что именно вы с кодом сделали: слинковали, изменили, отдали пользователю, выставили по сети.

Класс Примеры Что реально ограничивает
Разрешительные MIT, BSD-2/3-Clause, Apache-2.0 почти ничего, кроме сохранения текста лицензии и уведомлений об авторстве; Apache-2.0 вдобавок даёт патентную лицензию и требует файла NOTICE и пометки об изменениях
Слабый копилефт LGPL, MPL-2.0 изменения в файлах самой библиотеки открываются, ваш код рядом — нет; у LGPL есть техническое требование: получатель должен иметь возможность заменить библиотеку своей версией
Сильный копилефт GPL-2.0, GPL-3.0, AGPL-3.0 производное произведение распространяется на тех же условиях и с доступом к исходникам; накладывать на получателя дополнительные ограничения нельзя

Статическая линковка копилефтной библиотеки в закрытый бинарь. Компоновщик про лицензии не спрашивает, сборка зелёная, артефакт уехал клиенту — а получившийся бинарь оказывается единым произведением с GPL-кодом внутри, и требование раскрыть исходники распространяется на него целиком. Контроль здесь — не память разработчика, а SBOM и проверка лицензий в конвейере (цепочка поставок ПО).

Клиентское веб-приложение под GPL. Живой случай портала. Инстанс it-tools на поддомене выглядит «удобством для себя», но это фронтенд: браузеру каждого посетителя уезжает собранный бандл, то есть объектный код, а GPL-3.0 требует сопроводить его доступом к соответствующим исходникам. Поэтому в подвале сайта стоит явная ссылка на форк с указанием GPL-3.0. Та же логика у второго сервиса: Digitable Chat под GPL-2.0-or-later, браузер получает бандл — нужна ссылка на исходники. Триггером стало не «мы что-то продаём», а сам факт передачи объектного кода.

Серверное приложение: GPL против AGPL. Классическая GPL говорит про распространение копий. Если сервер использует GPL-код внутри, а наружу отдаёт только HTTP-ответы, копия никуда не уезжает. Эту дыру закрывает AGPL-3.0, добавляя случай взаимодействия с пользователем по сети. Следствие жёсткое: AGPL в зависимостях SaaS — не «такая же открытая лицензия», а другой режим, и во многих компаниях она поэтому запрещена политикой.

GPL в магазине приложений. Копилефт запрещает накладывать на получателя дополнительные ограничения, а правила магазинов ровно это и делают: число устройств, способы использования, привязка к учётной записи. Отсюда известные истории, когда приложения на GPL-коде снимали с продажи после обращений правообладателей и возвращали лишь после перелицензирования частей кода. Вывод: лицензия зависимости может закрыть вам целый канал поставки, и узнать об этом лучше до ревью, а не после.

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

Каналы и магазины: механизм вместо таблицы процентов

Канал — это не «где скачать», а кто владеет отношениями с покупателем: кто выставляет счёт, кто знает почту клиента, кто решает споры и кто может отключить вас завтра.

Комиссии и правила меняются, иногда по решению суда или регулятора, поэтому таблица процентов в учебном тексте устареет быстрее, чем вы её прочитаете. Полезен механизм:

  • Ставка не одна. Она зависит от типа товара (разовая покупка, подписка, внутриигровая валюта), объёма вашей выручки на площадке, срока жизни подписки, участия в программах для малых разработчиков и юрисдикции покупателя. «Комиссия магазина» — функция, а не константа.
  • Порядок величин. На май 2026 года базовая ставка крупных магазинов приложений и игр держится около 30 процентов, льготные режимы (малые разработчики, подписки со второго года, отдельные площадки) — около 15 процентов и ниже. Перед решением проверяйте условия в документации площадки: это единственный источник, которому имеет смысл верить.
  • Комиссия — не единственная плата. Есть взнос за участие в программе разработчика, требования к сборке (версия SDK, размер, формат), затраты на ревью, локализацию и возрастную классификацию, а где-то — схемы с платой за установку вместо процента.
  • Регуляторика меняется быстрее продуктовых планов. Правила о сторонних способах оплаты и альтернативных магазинах переписывались не раз, поэтому канал не должен быть вшит в код: выдача прав обязана принимать подтверждение покупки из нескольких источников.

Отдельная недооценённая часть — ревью и отказы: внешняя зависимость релизного цикла с недетерминированной задержкой и правом сказать «нет». Отсюда решения: функциональные флаги, чтобы спорную функцию выключали без новой сборки; запас времени до маркетинговых обещаний; умение выпустить срочное исправление по ускоренной процедуре. Разбор — Магазины приложений, мобильный релизный цикл — в mobile.

Игры — тот же вопрос, только без права на ошибку

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

  • магазин как единственный практичный канал и его комиссия;
  • возрастная классификация: анкета в системе вроде IARC порождает набор рейтингов для разных регионов, а неверно заполненная анкета — снятие с продажи;
  • консоли: закрытая платформа, договор и комплект разработчика, сертификация каждой сборки вместе с патчами;
  • региональные цены: разная покупательная способность плюс арбитраж — покупка там, где дешевле;
  • жёсткая дата релиза с маркетинговыми обязательствами, а ревью площадки посередине.

Каждый пункт — частный случай общих тем трека, поэтому Дистрибуция игр идёт после магазинов приложений, а не вместо них.

Обновления — обязательство, а не функция

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

  • Какие версии в поддержке. «Последняя и предыдущая мажорная» — политика; «стараемся поддерживать всё» — её отсутствие. Публичные графики релизов Node.js или LTS-политика дистрибутивов полезны не технологией, а видом сформулированного обязательства.
  • Каналы. Стабильный, бета, ранний доступ — не маркетинг, а способ ограничить радиус поражения; это те же канареечные выкаты (безопасные релизы), где «трафик» — доля установок.
  • Откат. В SaaS откат делаете вы, в коробке и self-hosted — получатель, и он должен быть возможен: неоткатываемая миграция данных превращает любой баг в катастрофу.
  • Принудительность и совместимость. Иногда обязаны заставить обновиться (уязвимость), иногда не имеете права (клиент сертифицировал версию). Версия артефакта, версия протокола и версия формата данных — три разные вещи, и семантическое версионирование помогает, только если честно сказано, что именно версионируется.

Разбор — Обновления и версии, форматы и подпись — Упаковка и установка, криптография подписи — в security.

Где кончается инженер и начинается юрист

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

  • «Мы отдаём браузеру собранный бандл приложения под GPL-3.0 со своего домена, код не меняли. Достаточно ли ссылки на публичный форк с точной версией сборки, или нужен другой способ предоставления исходников?»
  • «Мы продаём цифровой архив физлицам в стране N через платёжного агента. Какие реквизиты обязаны быть в документе покупателя и когда возникает обязанность сформировать чек?»

Каждый вопрос — следствие инженерного решения: заметить его ваша работа, ответить — не ваша. Живые примеры документов лежат на самом портале: публичная оферта, правила отмены и возврата, политика обработки персональных данных и отдельное согласие — раздел «Легальные документы» в подвале сайта написан ровно под описанную здесь модель поставки.

Карта трека

Глава Вопрос, на который она отвечает
01. Модели поставки Коробка, SaaS, self-hosted, гибрид — что каждая даёт покупателю и во что обходится вам
02. Облачные уровни IaaS, PaaS, SaaS, FaaS: где кончается ваша ответственность и начинается чужая
03. Многотенантность Сколько стоит изоляция клиентов и почему «общая база» — решение с последствиями
04. Лицензии Что копилефт запрещает делать в вашей сборке и чем от него отличаются разрешительные лицензии
05. Открытый код Что даёт открытая поставка, чего она стоит и почему это не бизнес-модель сама по себе
06. Ценообразование Подписка, потребление, места, freemium — и как выбор модели цены меняет схему данных
07. Биллинг Пробный период, апгрейд посреди периода, возврат, налоги, валюты — механика до копейки
08. Каналы поставки Свой сайт, маркетплейсы облаков, партнёры: кто владеет отношениями с покупателем
09. Магазины приложений Правила, комиссии, ревью и отказы как часть релизного цикла
10. Дистрибуция игр Магазины, консоли, возрастные рейтинги, региональные цены — самый жёсткий случай
11. Обновления и версии Каналы обновлений, откат, поддержка старых версий, сроки жизни
12. Упаковка и установка Пакеты, контейнеры, инсталляторы, подпись — форма, в которой артефакт доезжает
13. Ограничения Юрисдикции, экспорт, персональные данные: где поставка запрещена или ограничена

Маршруты, если весь трек подряд не нужен: свой небольшой продукт с продажей своими руками — 01 → 06 → 07 → 08 → 12 → 11; платформа для организаций — 01 → 02 → 03 → 06 → 07 → 13; приложение или игра в магазине — 09 → 10 → 11 → 12 → 06; открытый проект — 04 → 05 → 12 → 11.

Типичные ошибки, которые видны заранее

  1. Считать поставку продолжением деплоя. Деплой заканчивается, когда прод работает; поставка — когда истёк срок поддержки последней версии у последнего клиента.
  2. Хранить право пользования булевым флагом. «Оплачено: да» не отвечает ни на один реальный вопрос: до какого числа, по какому тарифу, что делать при возврате.
  3. Доверять редиректу браузера вместо вебхука. Проявляется как «клиент заплатил, доступа нет» ровно тогда, когда денег стало много.
  4. Не фиксировать условия на момент продажи. Цена, валюта, налог и редакция оферты меняются; без снимка сделки вы не восстановите, что человеку обещали.
  5. Узнавать про лицензию зависимости на релизе. Проверка стоит минуту в конвейере и недели переписывания в конце.
  6. Обещать «поддерживаем все версии». Это бессрочное обязательство с нулевым бюджетом.
  7. Вшивать канал в код. Один захардкоженный магазин — и второй канал означает переписывание выдачи прав.

Мини-итог

Поставка — шесть шагов от сборки до поддержки, и на каждом включается обязательство, которое кто-то содержит годами. Модель выбирают по трём колонкам: что получает покупатель, во что обходится поставщику, какие обязательства создаёт. Право пользования — объект системы со своим жизненным циклом, источник истины о деньгах — подписанный вебхук, а не редирект браузера. Лицензия — условие сборки, и триггером обязательств становится факт передачи объектного кода, а не продажи. Комиссии — функция, а не константа: считайте порог, за которым свой канал дешевле магазина. А где вопрос перестаёт быть инженерным, ваша работа — задать юристу точный вопрос.

Источники

Что дальше

Модели поставки: коробка, SaaS, self-hosted, гибрид — разберём каждую модель по трём колонкам цены владения: что она даёт покупателю, во что обходится поставщику в людях и деньгах, какие обязательства создаёт на годы вперёд. Там же — почему self-hosted дороже, чем кажется, и когда гибрид оказывается двумя поставками по цене трёх.

Нашли неточность? Выделите фрагмент текста — рядом появится жучок.

Нужен разбор именно вашей ситуации?

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

Доска запросов