Любой айтишник проводит значительную часть жизни сидя перед компьютером (привет КО!). Особенно тяжко приходится тем, кто работает удаленно или фрилансит. На работу идти не нужно, и бывают дни, когда по несколько дней не выходишь из дома.
Википедия и исследования намекают, что за все надо платить. Если вы сидите за компьютером по 12-14 часов в день, к 50 годам (а может и раньше) качество вашей жизни может значительно снизиться.
Решение – перерывы в работе и физическая активность. Плюс, если вы работаете дома, а не в коллективе, то для бодрого психического состояния было бы неплохо, чтобы выбранный вид физической активности был групповым и предполагал социальные взаимодействия. Но найти с кем и где поиграть в футбол — не такая уж простая задача.
Мы решили создать сайт, на котором будут собраны все футбольные, баскетбольные, волейбольные и хоккейные игры. Постараться с помощью технологий облегчить жизнь как игрокам, так и организаторам игр. Под хаброкатом расскажу о сути проекта, архитектуре и используемых технологиях.
Игрокам
Для игроков критически важным является расположение спортивной площадки. Если вам придется потратить полтора часа на дорогу до спортзала, то поработать в этот день будет уже не так просто. Поэтому, на главной странице сайта размещена google-карта с маркерами расположения игр и их список. Список игр отсортирован по дате.
Поиск по играм ведётся по видам спорта и по краям вьюпорта карты. Вьюпорт — видимая область карты google maps. Сейчас в поиске отображаются только премодерированные игры, для которых в базе выставлен флаг Trusted.
Не менее важен уровень игроков. Если вы хорошо умеете играть, с новичками будет неинтересно. У себя в профиле можно выставить уровень игры от 1 до 10, для каждой игры указан предполагаемый уровень, чтобы можно было сориентироваться.
Организаторам
Для организаторов главная проблема – это те, кто заявляется и не приходит. Мы даем возможность организатору собирать с игроков предоплату за зал. Она является гарантией, что человек придет. Если игрок решает ранее, чем за 12 часов до игры отказаться от участия, то предоплата возвращается ему на счет. Если до игры осталось менее 12 часов, то предоплата уходит организатору.
У организатора есть личный кабинет со списком его игр, размеченный по статусам. Кроме того, организатор видит список игроков, которые посмотрели страницу оплаты игры, но столкнулись с какими-то проблемами и оплату не сделали.
Статусы игр
В зависимости от трех главных параметров, игра имеет ряд состояний. Каждый параметр принимает одно из трех значений:
Организатор создает повторяющуюся серию игр:
Каждый день на основе записей о созданных повторяющихся сериях игры, по cron создаются игры на неделю вперед. Используемая нами платежная система Stripe.com может держать деньги в статусе uncaptured только 7 дней, после этого либо делает refund, либо capture денег. Поэтому, мы не создаем сразу игры на длительный срок вперед.
Вновь созданная игра имеет статусы:
MONEY_NOT_YET — пока мы не делали запрос на refund или capture предоплаченных денег
LESS_THEN_MIN_PLAYERS — пока не набралось минимальное количество игроков
BEFORE_LOCKPERIOD — до игры осталось еще более 12 часов
Если организатор указал, что игра состоится, при минимум 8 записавшихся игроках, то как только набирается 8 игроков, LESS_THEN_MIN_PLAYERS меняется на ALREADY_MIN_NOT_MAX_PLAYERS
Следующий важный этап — это наступление lockperiod за 12 часов до начала игры. Если к этому моменту у нас есть статус ALREADY_MIN_NOT_MAX_PLAYERS или MAX_PLAYERS, то игра состоится, отправляем stripe.com запрос на capture предоплат, а игра меняет статус на: CAPTURED, ALREADY_MIN_NOT_MAX_PLAYERS, LOCKPERIOD. В обратном случае — делаем refund и отправляем уведомления по смс и почте, что игра не состоится.
Абонементы
Главное — побороть в себе лень и заниматься регулярно. Для этого мы добавили позможность покупки абонементов — купил и не отвертишься. Регулярно играешь — выше эффективность на работе, да и радости в жизни будет гораздо больше, не до депрессий.
Абонементы делают каждое занятие для игроков дешевле, а игры организаторов стабильнее набираются.
В базе хранится стоимость N игр для конкретной серии игр. Если игрок покупает абонемент на 8 игр начиная со вторника, то мы его в базе записываем на вторник, помечая, что у него еще 8-1=7 игр. Ищем следующую игру этой серии, если она есть, то записываем его и помечаем, что у него еще 7-1=6 игр и тд.
При создании по cron новой игры этой серии, ищем в прошлой игре записи об абонементах. Если они есть, то переносим их в новую игру, снижая на единицу оставшееся у игрока число игр.
Чат
Чтобы игроки могли выяснить подробности, а организатор мог ответить на их вопросы с минимальными трудозатратами, нужно было сделать внутреннюю систему обмена сообщениями. Честно говоря, чат пока работает нестабильно (как и некоторые другие фичи), но уже позволяет решать задачи пользователей, а нам — бороться с его нестабильностью.
Реализован достаточно тривиально, весь функционал на php, в качестве хранилища данных используется база данных. Для ускорения работы применяется кеш. Кеш работает следующим образом: при создании новых сообщений и комнат, другим пользователям кроме самого автора в кеш пишется запись о новом событии. Это позволяет нам лишний раз не дёргать базу данных для получения новых событий для пользователя.
Во фронтенде тоже все просто — ajax запросы на получение комнат, отправку сообщений и прочего. В определённый интервал времени происходит запрос к скрипту “наблюдателя”, который уведомляет о новых сообщениях. В дальнейшем для чата скорее всего будет использована node.js прослойка.
Технологии и архитектура
Так получилось, что самая первая версия Топика была написана на Livestreet cms. Это было наследием нашего предыдущего проекта, довольно крупного блогового сайта. Основные гипотезы было проще протестировать продолжая разрабатывать на Livestreet.
Но Livestreet заточен совсем под другие задачи и скорость разработки оставляла желать лучшего, разработка новых фич занимало значительное время. Поэтому, как только мы поняли, что проект по-тихоньку полетел, мы решили перейти на что-то более подходящее.
Выбор пал на Yii2. Разработка с примением пространства имён и всех плюшек php 5.4 заметно эффективнее и интереснее. Альфа версия фреймворка имеет свои минусы и риски, необходимо постоянно быть в курсе изменений в api, иногда переписывать некоторые участки кода при рефакторинге фреймворка. Но мы эти риски хорошо осознавали и решили сделать выбор в пользу производительности и интересности разработки.
Как базис для приложения используется advanced application template. С разделением на 4 основные части сайта, frontend, admin, console и api. В шаблоне имеется базовое пространство имён common. В ней лежат модели с минимальной функциональностью для использования его в частях приложения, базовые модули, компоненты и расширения. Также там хранится базовая конфигурация всего сайта, общие для всех частей.
Практически весь функционал поделен на модули, это весьма распространенная практика, если же модулю требуется свой уникальный функционал базовых моделей и компонентов, они расширяются в контексте модуля.
В качестве тестирования применятся юнит и приёмочные тесты в окружении codeception через прослойку-extension yii2 — для корректного воспроизведения окружения фреймворка, работы с фикстурами и прочее. Более подробно о тестировании в yii2 можно почитать тут и тут. В целом уже сейчас фреймворк имеет весьма подробную, хоть и в некоторых местах неточную документацию по базовому API.
Фидбэк
Мы совсем недавно начали работать над этой концепцией, еще многое надо сделать и отполировать, но уже есть положительный фидбэк от пользователей и первая выручка.
Хочу попросить уважаемое читатели высказать свое мнение, что бы вам хотелось, чтобы было в таком сервисе? Какие препятствия могут остановить вас от организации своей игры / от присоединения к такой игре? А что может подтолкнуть?
Призываю всех попробовать добавить площадку около своего дома и попробовать собрать игру уже на эти выходные, а мы всеми силами постараемся помочь. Будем очень рады, если получится возродить добрую традицию хабрафутбола.
Автор: kravets