Я написал свой DTF, чтобы вам не пришлось 2.0. Ну и не только...
Приветствую!
Это будет рассказ про открытый код, self-hosted и о создании сообщества.
Когда-то давно, во времени редизайн бунта, видел похожий пост, но там просто запускали готовое, чужое решение, поэтому решил сделать отсылку к тому посту в названии. В прочем, не об этом.
История начинается в году 2019, когда мы вели дискорд каналы по world of warcraft на десятки тысяч человек и нужно было как-то вести документацию с руководствами по классам. Так появилась первая идея о сайте с руководствами.
В последствии идея превратилась в сайт на wordpress, а в дальнейшем он был переписан на классический стак html+css+js, с обновлениями ю текста руководств на GitHub. Это работало, но было неудобно обновлять руководства и начались поиски чего-то большего, чем просто html странички с руководствами, что-то на чем можно построить свое сообщество, даже без дискорда. Было перепробовано много разного open source софта, но все было не то: либо все выглядело приветом из 2007 года, либо темы к каким-то cms.
Лезть в cms и снова крутиться вокруг легаси кода, как правило php-шного и придумывать какие-то патчи для этого не хотелось от слова совсем. Было ощущение, что ты запускаешь софт в котором у тебя под капотом крутится огромное количество ненужного кода, каких-то модулей, которые ты не собираешься использовать и т.д. Так мысль о том, что стоит написать все самому становилась все более навязчивой. И тут совершается первая ошибка:
Первая итерация - безголовая cms. Хотелось сделать как можно быстрее и поэтому идея о том, чтобы взять безголовую cms (payloadcms в данном случае), написать к нему веб клиент на nextjs и начать использовать - казалась заманчивой. Так и сделал. Запустил первую версию и это оказалось ошибкой. Чувство, что я не контролирую полностью то, что происходит под капотом никуда не делось. Да, весь бэк работает так, как я хочу, ничего лишнего, но все построенно на конфиг-файлах и есть ограничения которые зависят от того, когда разработчики захотят это реализовать в своем roadmap. Например, корректную работу вебсокетов без костылей. Быстро стало понятно, что лично для меня это тупик и время на эту реализацию потрачено зря. К тому же приходилось думать не о том, как улучшить платформу, а о том как та или иная вещь работает в cms.
Изначально я хотел реализовать все на фулстак nextjs. Однако, в это время я начал увлекаться языком GoLang и решил, что вот тут звёзды и сошлись: мы пишем клиент на nextjs, а бэк мы будем писать на go. Так и началась вторая итерация, которая тоже до релиза не дожила.
Вторая попытка: nextjs+golang.
Впрочем, тут все прошло быстро. Основная работа предстояла с сервером, потому что клиент то у меня уже был, его нужно было просто переключить от запросов к cms на запросы к go бэкэнду. Поскольку я только начинал разбираться с go, то было выбрано самое простое - обычный монолит. Однако, когда я реализовал примерно половину функционала, я понял что начинаю плавать в своем же коде - нарушаю архитектуру, направление зависимостей и т.д., я начал понимать что код превращается в кашу, в которой я сам уже мало что понимаю, не говоря уже о потенциальных будущих контрибьюторах. Параллельно с этим я ходил на всякие митапы Яндекса, озона и Авито, слушал видео-доклады, зарисовывал схемы архитектур, выписывал основные паттерны, как должны идти зависимости и вообще впитывал все, что касается архитектуры, был только один нюанс: все разговоры были только об одном - микросервисы. И я подумал: а может это и есть решение? Понятное дело, что оверкил, нужно контролировать межсервисное общение, доступность, идемпотентность, гарантию доставки и т.д. Однако, написать шаблон микросервиса один раз, разобраться один раз с этим микросервисным оверхэдом, но потом иметь по 10-15 юзкейсов на один микросервис и в этом достаточно сложно запутаться. Каждый сервис самодостаточный, он не знает о других микросервисах, код выглядит чисто и вообще это звучит достаточно здорово. Так началась третья и финальная итерация.
Финальная реализация: nextjs + go микросервисы.
Тут все достаточно быстро начало складываться. Быстро отказался от orm типа gorm, потому что мне не хотелось опять таки иметь какую-то магию, которую нужно отдельно учить и которая при этом не самая быстрая, хоть и самая популярная. Взял прекрасный sqlc для работы с бд, postgresql и grpc. Написал шаблон микросервиса с логированием, восстановлением после паники, рейт лимитером и всем остальным по заветам бигтеха. Ну а дальше все пошло бодро и прям даже лучше, чем я ожидал. Моя ставка на малое количество юзкейсов на каждый микросервис сыграла и все встало на свои места. А оверхэд микросерсивов уже никак не мешал. Этот путь и привел меня в настоящее время, когда я пишу этот пост.
Stormic - первая фаза большого плана.
На данный момент, Stormic вам будет крайне знаком. Он представляет из себя всем знакомый концепт мультиблоговой платформы. Однако, уже сейчас, отличия в концепции имеются. Основное - сообщества управляются пользователями.
Редакция не создаёт категории для постов. Любой пользователь может создать сообщество, развивать его, модерировать, а также назначать модераторов. Это ближе к сабреддитам.
Второе - это роли и права доступа.
Есть два типа ролей: роли всей платформы и роли внутри каждого сообщества. Тут вы можете ориентироваться на систему ролей из дискорда: есть пользователь с ролью owner для всей платформы, он может создавать новые роли на платформе, задавать какие права будет иметь эта роль и назначать эту роль любым пользователям.
У каждого юзера на платформе есть роль everyone, через которую овнер может контролировать что могут делать рядовые участники. Например можно снять ползунок с права создания сообществ у роли everyone и больше нико не сможет создавать сообщества, кроме тех у кого есть другая, вышестоящая роль в иерархии, которая уже разрешает создание сообществ.
Точно так же и для сообществ: пользователь создаёт сообщество и ему сразу присваивается две роли: owner и everyone, он может создавать роли в своем сообществе и задавать права для каждой роли и назначать эти роли только тем пользователям, которые состоят в его сообществе.
Дальше, пользователь с ролью в сообществе которая даёт право на удаление постов может удалять посты только в том сообществе, где у него эта роль выдана. Если у пользователя есть роль на всей платформе на удаление постов, то он может удалять посты в любом сообществе. Тут все просто.
Ну и конечно же, open source и self-hosting. На данный момент вы можете установить Stormic на vps с docker. Устанавливается достаточно просто командой
curl -sSL https://stormhead.org/stormic/install.sh | bash
Вот тут в анонсирующем посте есть немного больше про установку, подробное руководство я ещё не написал, но вы можете ознакомиться:
Что дальше?
Текущий функционал я объединяю в один модуль - модуль мультиблога. Будет ещё два: модуль базы знаний и модуль хабов сообществ.
Да, Stormic по плану состоит из трёх модулей и первый - модуль мультиблогов сейчас запустился. Следующим будет модуль базы знаний.
Что это?
Это решение той проблемы, о которой я говорил в самом начале. Каждому развитому сообществу нужно как-то хранить, систематизировать и управлять знаниями, которые это сообщество в себе хранит. Из моей проблемы описанной в начале поста - это было написание и поддержание руководств по world of warcraft в актуальном состоянии. Можно накинуть ещё пару десятков, для чего это можно использовать: первое конечно же - не только world of warcraft, второе - документация какого-то вашего проекта, третье - что-то, что вам интересно, любое - кино, музыка, история, что угодно. Как мы знаем, Википедия тоже границ практически не имеет.
Сейчас, когда пользователь создаёт сообщество, то создаётся только сообщество. А будет создаваться и сообщество и база знаний к этому сообществу, для базы знаний можно назначать отдельных модераторов, которые будут заниматься ее модерацией. У каждого сообщества своя база знаний. И тут есть ещё одна особенность: в базу знаний сообщества можно добавлять свои кастмные js скрипты, чтобы расширять его функционал. Например по сообществу для world of warcraft можно добавить js скрипт от wowhead и при написании руководств, вставлять ссылку на способность класса. В тексте базы знаний эта ссылка будет преобразовываться в подсвеченное название способности, при наведение на который будет появляться подсказка с описанием этой способности. Это как пример. Вторая особенность - это конечно же глубокая интеграция базы знаний и сообщества. Уведомления, создание снипетов из абзацев базы знаний и отправка их в сообщество хоткеями.
В общем, больше никакой токсичности с яростной отправкой ссылок на десяток разных ресурсов, чтобы пользователь сам все прочитал. Все в одном месте, все под рукой.
Третий модуль: хабы сообществ.
Тут все просто. Есть дискорд, как пример пользовательского опыта. Мы возьмём этот пользовательский опыт и перенесем в Stormic третьим модулем. В итоге при создании сообщества будет создаваться сообщество, база знаний этого сообщества и аналог Дискорд сервера, где опять таки создатель сообщества является владельцем нового хаба сообщества. Там внутри все просто: каналы, роли, аудио и видеовызовы, групповые звонки и т.д. все то, с чем у вас ассоциируется дискорд функционально.
Все это глубоко интегрировано между собой, в едином приложении.
Заключение
Мой план создать лучший пользовательский опыт по созданию и ведению сообществ, которого ещё не было. Да, я начал с малого - с модуля мультиблогов. Однако, модуль базы знаний достаточно простой и уже на этапе проектирования архитектуры. До его появления не так уж и много времени. Дальше останется огромный и сложный модуль с хабами сообществ.
Планов конечно же бесконечно много и за пределы этих трёх модулей, но пока обозначим только их и будем к ним стремиться. Главное, что стэк технологий выбран и устаканился, вектор развития ясен и остаётся самое главное: ваша поддержка и участие в этом проекте.
Я предлагаю вам присоединиться сейчас, на ранних стадиях к тому, что в будущем займет свою нишу в нашем обществе.
Давайте фидбэк
Задавайте вопросы
Предлагайте улучшения
Пишите о том, что вам интересно
Комментируйте
Создавайте сообщества
Рассказывайте друзьям
И вместе мы сможем создать что-то новое, что подарит нам совершенно новый пользовательский опыт.
Спасибо всем, кто прочитал этот пост до конца.
Жду вас на новой платформе и до встречи 🔥