ни в продукте, ни в макете, ни в базе данных
на этом стоит весь продукт
Заверяем, что человек сказал, а не что человек заплатил.
Правило помогает проверить любую новую идею за секунду.
Защита «мы общий инструмент ведения записи» держится, пока продукт действительно общий. Турнир без всяких призов должен быть полноценным, массовым сценарием, а не отговоркой в оферте. Это не только правовое требование — лига коллег без призов и есть наш основной случай применения.
Всем
Проект не на старте. Работающего кода много, и участник приходит не на пустое место.
Маркетологу, продакту
Продукт существует, а понимания, как приводить людей, почти нет. Нужен человек, который превратит догадки в проверяемые гипотезы.
Это не воронка, а разговоры. Наш клиент — человек, который уже ведёт прогнозную лигу вручную и мучается: собирает ответы по чату, считает по выходным, спорит с участниками о том, кто что написал до матча.
Где они: телеграм-каналы о футболе с прогнозами в комментариях, Discord-серверы, сообщества фэнтези-лиг, форумы болельщиков клубов, корпоративные чаты.
Первые десять находятся вручную, по одному, и им всё настраивается за них. Это не провал воронки, а её форма: мы привлекаем не игроков, а тех, кто приводит игроков.
Таблица, недельный ритм, уведомление о том, что тебя обошли, и возможность показать результат другим. Последнее — единственный органический канал: после тура игрок должен получать что-то, что не стыдно кинуть в чат. И это «что-то» у нас может быть подтверждённым, чего нет ни у кого.
Платная реклама на игроков — это покупка не-клиентов. Привлечение обещанием призов возвращает правовую рамку и ломает мотив. Партнёрские ссылки на букмекеров: продукт, зарабатывающий отправкой людей в контору, и есть контора. Массовая холодная рассылка сожжёт единственный канал, который у нас есть.
Ось выбрана: тарифицируется ёмкость организатора — например, 4 турнира в месяц против 16. Границ нет. Что ещё входит в тариф: размер турнира, длительность, число рынков, свои правила подсчёта, брендинг, история, экспорт? Что происходит, когда ёмкость исчерпана — турнир не заводится, заводится в режиме только-чтение, или переносится на следующий месяц? Бесплатный первый турнир — это приманка или его нет вовсе?
По исходным требованиям полный рейтинг открыт только обладателю платного аккаунта. Для сервиса, продающего статус, это логично. Для соревнования между людьми рейтинг — главная причина прийти, и закрывать его значит прятать ровно то, ради чего человек регистрировался. Оставляем как есть или открываем всем?
Формула «проигравшие делятся между угадавшими» измеряет, насколько неочевиден был ответ. Становится ли она прямо множителем очков, или очки считаются иначе? Риск: если очки равны коэффициенту напрямую, выгодно охотиться за редкими исходами вместо прогноза. И второе: на тонкой линии коэффициент прыгал от 2,9 до 7,0 — неделя с малым числом матчей перевесит неделю с большим.
Дизайнеру
Четырнадцать новых страниц и один новый сложный элемент — таблица турнира. Плюс пересборка главной: сейчас она говорит «играй», а должна говорить «собери своих».
Организатор — не четвёртая поверхность, а раздел внутри игры: у него та же палитра и навигация, и он почти всегда и сам играет.
Это не пожелания, а работающие договорённости, подкреплённые кодом.
На странице матча предполагается расклад: сколько участников ответили так и сколько иначе. Это честная информация. Но показанный заранее, он сдвигает поведение: человек видит, где ответов мало, и идёт туда, а не туда, где считает исход вероятным. Варианты: показывать всегда; только после закрытия приёма; показывать доли без абсолютных чисел.
Соревнование требует, чтобы человек был виден: точность, серии, разрез по видам вопросов, последние туры. Сейчас всё это считается только для себя. Какие поля публичны, виден ли профиль без входа, спрашивается ли согласие, и что происходит с отказом — выпадает из рейтинга или показывается под псевдонимом?
Платформа приз не считает, не держит и не выдаёт. Но что-то показать надо: участник должен понимать, за что играет. Приз одним текстовым полем, структурой без денежных полей, или текстом плюс отметка «выдано»? Структура с полем «сумма» выглядит как призовой фонд, даже если мы к деньгам не прикасаемся, — а как это выглядит, имеет значение.
Программисту
Три новых модуля на backend, четырнадцать страниц на frontend, и до этого — вывод существующего в интернет и получение результатов матчей из внешних источников.
Часть первая: вывести то, что есть, в интернет и прожить на нём неделю. Публичный стенд, настоящие данные, боты, играющие в реальном времени, неделя без вмешательства руками. Это проверка того, что построенное живёт само: планировщик срабатывает по расписанию, провайдер отвечает когда хочет, очередь переживает перезапуск, неделя кончается сама.
Часть вторая: турниры, подписка, заверение записи.
Вторая часть меняет надстройку, а не фундамент. Если фундамент не живёт неделю сам, переделка надстройки это не исправит, а скроет.
Получение результатов матчей — самая большая и блокирующая. Сейчас внешний интерфейс интеграции объявляет единственный метод: получить расписание на дату. Результатов нет в самом контракте, не только в реализациях. Отдельная фоновая задача переводит матч в статус «идёт» по времени, но счёта не забирает. Голы, угловые и карточки вносит оператор руками.
Работа: расширить интерфейс, реализовать в двух адаптерах, завести фоновую задачу, писать результат через доменный метод, а не записью в базу, вести журнал как у импорта расписания, показать оператору расхождение, когда провайдер говорит одно, а в базе другое.
Включить непрерывную сборку. Сейчас она выключена намеренно: стоит задание-заглушка, которое падает сразу, и весь граф висит на нём. Выкладка идёт руками.
Эмулятор игроков. Существующий симулятор вызывает сервисы напрямую — он проверяет экономику и годится для этого. Эмулятор стенда должен ходить по HTTP под токенами игроков: иначе прогон не проверит ни авторизацию, ни права, ни защиту от двойной отправки, ни поведение под параллельными запросами — то есть ровно то, ради чего он затевается.
Еженедельная выдача билетов. Решение принято, код не написан. Это и есть бесплатный режим, на котором держится вся модель.
Известные долги. Выбор текущего тура смотрит на время создания, а не на календарь, — открытый тур следующей недели перехватит расписание. Проверка правил слоёв на frontend падает: 26 нарушений. Публичность стенда поднимает вес вопроса о защите от накруток.
В системе не должно появиться поля, описывающего взнос участника, призовой фонд числом, кошелька организатора или выплаты через систему.
Это не пожелание, а граница модели; к этому нужен тест, который падает, если такое поле завелось.
Главная архитектурная развилка. В первом варианте матчи те же, расчёт тот же, турнир лишь отбирает подмножество матчей и считает свою таблицу по своим участникам. Во втором — у турнира свой календарь, своё начало и конец, свой расчёт. Разница в объёме работы — между неделей и двумя месяцами. Во втором варианте у билета появляется второй владелец, и становится неоднозначным, по какому расчёту его разбирать.
Что заверяем: ответ, результат матча, итоговую таблицу? Чем: ключом платформы, организатора, игрока? Где участник проверяет — внутри продукта или независимо от него? Подпись ключом платформы доказывает только отсутствие правок задним числом и ничего не доказывает про саму платформу. Если проверить можно лишь внутри продукта, функция почти декоративна.
Три модуля построены под модель, от которой продукт отказывается, и к ним есть страницы, покрытые тестами. Удалить, заморозить (код остаётся, маршруты закрыты, страницы спрятаны) или переосмыслить — баланс как счётчик билетов участия, без покупки и без вывода? Удалённое вернуть дорого, если правовая оценка изменится.
Менеджеру
Нужен человек, который держит горизонт, разводит развилки по владельцам и не даёт работе расползтись. Открытых вопросов сейчас больше тридцати, и часть из них блокирует код.
Модель выбрана и описана, но юристом по игорному законодательству не проверена. Проверить надо: держится ли конструкция в выбранных юрисдикциях; работает ли бесплатный способ участия рядом с платным и при каких условиях; квалификация подписки, дающей возможности, но не шансы, — нет ли риска, что её сочтут завуалированным взносом; налоговый агент по призам. Нужен именно профильный юрист: общий корпоративный ошибается в обе стороны.
Юристу, аналитику
Нужны тексты, которые можно предъявить, и проверка модели специалистом. Обязательные страницы в продукте есть и покрыты тестами, но тексты в них — заглушки.
Формулировка, которой стоит придерживаться во всех документах:
Сервис ведёт заверенный журнал прогнозов в соревнованиях, которые организуют пользователи. Сервис фиксирует, какой прогноз дал участник и когда, и делает запись неизменяемой и проверяемой независимо.
Сервис не принимает и не переводит средства, не формирует призовой фонд, не определяет и не выплачивает призы и не удерживает долю. Плата — фиксированная подписка организатора за объём ведения журнала, не зависящая от числа участников и от того, есть ли в соревновании приз.
Признак того, что описание собрано правильно: денег в нём нет вовсе.
Положение о соревновании, правила подсчёта (не маркетинг, а описание механики: как считаются очки, что с переносами и отменами матчей), пользовательское соглашение, политика конфиденциальности, правила для организаторов — включая прямой запрет собирать взносы с участников — и раздел об ответственной игре.
Последний — не формальность. Платёж у нас добровольный и игра бесплатная, и именно поэтому самоограничение стоит описать своими словами, а не скопировать у других.