Все статьи
Телеграм-канал

Моя курсовая работа про создание сервиса briene

В настоящее время есть большой спрос на создание личного бренда и блога для продвижения себя на рынке труда или «для души». Компании же всё чаще пользуются услугами копирайтеров и SMM, чтобы наладить контакт с аудиторией путём создания аккаунтов в социальных сетях, специализированных изданий и блогов.

Google Тренды с анализом тенденций

Задача данной работы – рассказать, зачем сервисы для статей и медиа существуют, какие есть на данный момент и почему я не стал использовать их, а создал свой.

В первую очередь я создал его для себя. У меня в том числе присутствует желание заявлять о себе в медиа-пространстве. Для этих целей можно использовать страницу ВКонтакте, сториз в Инстаграм или завести канал в Телеграме. Я перепробовал все эти варианты и в какой-то момент мне стало этого не хватать - не было нужной функциональности, чтобы эффективно донести мысль. Поэтому я решил создать свой сервис для статей и медиа.

Если отойти от высокой цели самореализации и говорить во всеуслышание, то платформа предоставляет возможность публиковать статьи. А это уже открывает простор для манёвров - briene может быть тем самым медиаресурсом, например, как Нож или The Village, движком для личного блога. А ещё здесь можно публиковать научные и образовательные статьи, заметки, учебные конспекты и курсовые (как этот текст).

graph LR
Контент --> Пользователь
Пользователь --> Контент

Ключевой особенностью медиа-платформы, социальной сети – любого публичного пространства – является замкнутый круг «Контент-Пользователь». Это означает, что если на платформе мало авторов и, как следствие, мало контента, то будет мало пользователей-читателей – читатель скажет, что тут нечего читать. А если мало читателей, то у авторов нет желания приходить на эту платформу - автор скажет, что тут некому читать. Чтобы сервис стал успешным, он должен привлечь определённое число пользователей, которое уже после будет расти как снежный ком. Этот эффект известен как эффект критической массы.

Если это замкнутый круг, то как существующие платформы из него выбрались? Предлагаю рассмотреть магазины видеоигр и попытки Epic Games Store закрепиться на нём. Сейчас на рынке есть небольшое число сервисов, к которым игроки привыкли и уход от которых крайне труден: есть Steam для ПК, Microsoft Store для консолей Xbox и PlayStation Store для консолей PlayStation. Нам интересен рынок ПК, где абсолютным лидером является Steam. Поэтому Epic Games приходится вкладывать очень много сил (и денег), чтобы привлечь ту самую критическую массу, которая запустит сетевой эффект и бурный рост, который поможет составить конкуренцию Steam.

Marwell G., Oliver P. The critical mass in collective action. – Cambridge University Press, 1993.

Katz M. L., Shapiro C. Systems competition and network effects //Journal of economic perspectives. – 1994. – Т. 8. – №. 2. – С. 93-115.

ГЛАВА 1. Анализ платформ для публикации медиа-материалов

Критерии сравнения существующих платформ

Для сравнения платформ, которые работают с текстом и медиа-материалами, я определил критерии, которые (по моему мнению) являются ключевыми для увеличения аудитории сервиса.

Платформы

Сравнение

Для всех редакторов справедливо: - Поддерживаются: - Заголовки до 2 уровня. - Модификации шрифта - жирный, курсив и т.п. - Списки нумерованные и ненумерованные. - Текстовые блоки с разделителями. - Блоки с цитированием. У всех выглядят по-разному, но смысл одинаковый. - Удобство: - Комфортная ширина контента.

В таблице приведены только отличительные черты.

|Характеристика|ВКонтакте|Telegram (Telegraph)|Хабр|Комитет|Medium| |-|-|-|-|-|-| |Популярность (млн/месяц)|73|500|33|15|100| |Редактор|- Мультимедиа (фото, видео, музыка, GIF)
- Опросы
- Товары|- Мультимедиа (фото; видео, твиты по ссылке)| - Мультимедиа (фото; видео, твиты, музыка по ссылке)
- Опросы (в конце статьи)
- Формулы (в формате Tex)
- Скрываемый текстовый блок
- Редактор таблиц
- Якорные ссылки
- Листинги с кодом
- Теги|- Мультимедиа (загружаемые фото, видео, аудио)
- Опросы
- Якорные ссылки
- Листинги с кодом
- Теги
Предпросмотр материала|- Мультимедиа (загружаемое фото, фото из Unspash, видео, встроенное медиа как YouTube или SoundCloud)
- Теги
- Приватные заметки| |Удобство чтения|Плюсы: ночной режим, просмотр фото на весь экран. Минусы: статья заканчивается рекомендациями других статей.|Плюсы: минималистичный просмотр. Минусы: нет просмотра фото во весь экран.|Плюсы: есть просмотр фото во весь экран. возможности комментирования. Минусы: контент сильно смещён влево, фиксированный блок с рекомендациями.|Плюсы: есть просмотр фото во весь экран, возможности комментирования.|Плюсы: есть просмотр фото во весь экран, заметки в тексте статьи. Минусы: контент сильно смещён влево, фиксированный блок с рекомендациями, статья заканчивается рекомендациями.| |Платные возможности для авторов|Для статей нет, донаты для групп.|Для статей нет, донаты для каналов.|Нет.|Для статей нет, донаты для авторов.|Членство в Medium - часть стоимости отчисляется автору.| |Дополнительно||Тесная интеграция с клиентом Telegram|Мегапосты, система рейтинга (кармы)|Система рейтинга|Подписка на автора по электронной почте|

Источники с данными об аудитории:

Пресс-релиз ВК

ВК подвел итоги первого квартала 2022 года

Аудитория Telegram превысила 500 млн пользователей в месяц — это на 100 млн больше, чем в апреле 2020 года

Исследование площадок для публикации статей IT-тематики (русскоязычных и мульти-язычных)

Медиакит «Комитета»

Статистика 7 Медиа-Платформ

Лично я бы расположил платформы в следующем порядке: 1. Комитет. Крайне гибкая и дружелюбная для пользователя система, а самоорганизация в виде рейтинга позволяет прозрачным и естественным образом продвигать контент. 2. ВКонтакте. Акцент - на контенте, но статьи теряются из-за работы алгоритмов рекомендаций. 3. Хабр. Гибкая и дружелюбная система с хорошей системой рейтингов, но не ценит читателя. Боковая панель рекомендаций перетягивает на себя внимание и подталкивает уйти из статьи. 4. Telegraph. Минимализм, перетекающий в бедность. Сам по себе Telegram не имеет систему рекомендаций – это просто мессенджер. Более того, Telegraph – сервис для написания и просмотра статей. По функциональности это больше редактор, чем медиа-платформа. 5. Medium. Удобная платформа, но не ценит читателя. Очень часто при открытии статьи появляется платёжное окно (paywall), которое не даёт прочитать статью, из-за чего возникает вопрос «а так ли мне хочется прочитать, чтобы за это платить?».

ГЛАВА 2. Разработка платформы

Итак, мы разобрались с существующими платформами, определили ориентиры для копирования, референсы, определили слабые места, которые стоит избегать. Можно приступать к написанию своей платформы.

Формат

Первым делом надо определить, как авторы будут создавать контент. Я остановился на формате Markdown. Этот формат особенно популярен среди разработчиков, т.к. позволяет написать что угодно, не отрываясь от клавиатуры. Формат интегрирован в редакторы систем контроля версий (GitLab и GitHub), трекеры задач (Jira) и средства повышения продуктивности (например, Obsidian). Подробнее про формат можно прочитать здесь: справочник Дока о Markdown.

Сам по себе синтаксис Markdown невыразителен и скучен:

### Формат
Первым делом надо определить, как авторы будут создавать контент. Я остановился
на формате **Markdown**. Этот формат особенно популярен среди разработчиков, т.к. позволяет 
написать что угодно, не отрываясь от клавиатуры. Формат интегрирован в редакторы систем 
контроля версий (GitLab и GitHub), трекеры задач (Jira) и средства повышения продуктивности 
(например, [Obsidian](https://obsidian.md/)). Подробнее про формат можно прочитать здесь: 
[справочник Дока о Markdown](https://doka.guide/tools/markdown/).

Чтобы его было комфортно читать, он переводится в HTML-код и вставляется на страницу. С этим мне помогает библиотека Vue Markdown Editor.

Т.к. синтаксис переводится в HTML, то можно сразу писать в нём - редактор при трансляции просто пропустит этот фрагмент:

<div style="text-align:right">
Это текст, который будет "липнуть" к правому краю
<br><br>
</div>
Это текст, который будет "липнуть" к правому краю

Таким образом, Markdown легко пользоваться и он позволяет «писать красиво из коробки». Поэтому вокруг него я и решил построить редактор статей. Получилось так, что авторам просто писать, а читателям – приятно читать.

Основная функциональность

Мы разобрались, как писать на платформе. Теперь посмотрим, что она умеет и как этим пользоваться.

Публикация статей

Любую статью можно опубликовать в двух режимах: черновик и публикация. Черновики может просматривать и редактировать только их автор. Публикации же доступны только всем, но только для чтения.

редактор с подписанными кнопками

Редактор позволяет сохранить черновик и создать публикацию


После нажатия любой из этих кнопок будет предложено задать краткое описание статьи (Summary) и проставить теги, чтобы читатели быстрее нашли Вашу статью.

описание и теги

Краткое описание и теги


После публикации статью можно найти на странице со свежими статьями.

список опубликованных статей

Так выглядят опубликованные статьи


Карточка содержит самую базовую информацию о статье: автор, название, дата публикации, теги и краткое описание.

список моих черновиков

А так выглядят мои черновики


Черновики тоже представлены в виде карточек, но рядом с автором отмечен тип статьи - черновик или публикация. В контекстном меню доступны быстрые действия: редактировать статью и удалить.

Управление закладками

Пользователь может добавить опубликованную статью в закладки, нажав на иконку закладки. Список закладок доступен из личного кабинета пользователя в соответствующем разделе.

добавить в закладки

Как добавить статью в закладки


мои закладки

Список моих закладок


Цитирование статьи

Читатель может выделить фрагмент статьи и превратить его в цитату. Цитата выглядит как специальный код, который ссылается на выделенный фрагмент.

Вот так создаётся цитата:

создание цитаты

Выделенный текст может стать цитатой


Так она выглядит для читателя:

контекст важнее факта.

- Контекст

А вот так она выглядит для автора:

>контекст важнее факта.
>
><p>- <a target="_blank" href="https://briene.herokuapp.com/articles/9aaa88eb-9042-4eaa-b818-bb4472d4d144/#:~:text=%D0%BA%D0%BE%D0%BD%D1%82%D0%B5%D0%BA%D1%81%D1%82%20%D0%B2%D0%B0%D0%B6%D0%BD%D0%B5%D0%B5%20%D1%84%D0%B0%D0%BA%D1%82%D0%B0."><i>Контекст</i></a></p>

Панель администратора

Чтобы попасть в панель администратора, надо перейти в личный кабинет и, если Вы - администратор - нажать на ссылку Admin.

личный кабинет

Личный кабинет и вход в панель администратора


Администратор может управлять пользователями – менять их роли: «заблокирован», «пользователь» «администратор». Также он может видеть, редактировать и удалять все статьи.

панель администратора

Панель администратора


Поиск

В верхней части страницы сервиса всегда есть строка поиска. Благодаря ей можно получить список статей, которые будут содержать набранный запрос.

строка поиска

Строка поиска


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

результаты поиска

Результаты поиска


Реализация

Мы разобрались, как создавать статьи, что с ними можно делать и что можно делать в сервисе в принципе. Дело осталось за малым - сделать сам сервис.

Бэкенд

  1. Spring - бэкенд-фреймворк. Я выбрал этот фреймворк, т.к. в нём у меня больше всего компетенции. А ещё по этому фреймворку очень много документации и готовых лучших практик.
  2. PostgreSQL - хранилище данных. Было выбрано по той же причине, что и фреймворк.
  3. JSON Web Token - подход к авторизации пользователей. При данном подходе у каждого пользователя есть уникальная строка, которая называется токен. Эта строка хранится у пользователя в браузере и у платформы на сервере. Когда пользователь входит в свою учётную запись на сайте в первый раз, то создаётся новый токен и отправляется пользователю и серверу. В следующий раз, когда пользователь зайдёт на сайт, то он предъявит свой токен, и сервер его узнает.
  4. Bonsai - поиск. Этот инструмент - расширение для хостинга Heroku. Построен на базе ElasticSearch и предоставляет инструментарий для полнотекстового поиска, без которого не обойтись в сервисе, где есть текстовые материалы.
  5. Прочие инструменты
    • Для сокращения и упрощения кода использовался Lombok. Для создания скрипта быстрого запуска и миграции базы данных - Flyway. Для проверки сохраняемых сущностей на соответствие требованиям (непустое имя, формат почты, непустой заголовок и т. п.) - Hibernate Validator .

Фронтенд

  1. Vue - фронтенд-фреймворк. Главное (во всяком случае для меня) преимущество этого фреймворка - реактивность. Это означает, что изменение данных сразу вызывает перерисовку интерфейса без необходимости специального вызова. Это требует, например, React и Flutter, поэтому я не стал их использовать.
  2. Vue markdown editor. Редактор платформы построен именно на этой библиотеке. Стиль редактора можно настроить как обычными web-средствами с помощью CSS, так и с помощью плагинов. Например, один плагин позволяет установить тему, как у GitHub, другой - добавляет синтаксис для создания формул Katex, третий - синтаксис для создания диаграмм Mermaid.
  3. Bootstrap. Инструмент позволяет создавать адаптивный интерфейс. Т.е. такой интерфейс, который будет меняться в зависимости от устройства - будь то компьютер, смартфон или планшет. Также этот инструмент предоставил стили для базовых элементов: шрифт, меню, формы.
  4. Прочие инструменты
    • Moment - форматирование даты. Axios - http-клиент, который отправляет запросы на бэкенд. Vuex - менеджер состояния пользователя.

Диаграммы классов

Небольшая оговорка - все поля всех классов приватные. Для полей сделаны getter'ы и setter'ы - методы для получения и проставления полей.

На картинке ниже диаграмма классов для entities - сущностей, которые хранятся в базе данных. Центром платформы и диаграммы является Статья. У статьи есть Состояние типа enum (перечисление констант), где есть три значения - «Опубликована», «Черновик» и «Все». Последнее состояние - программная заглушка для запросов, которые просят показать все статьи.

У каждой статьи есть Автор - Пользователь, который её написал. Пользователь имеет массив из Ролей. Роли определяют уровни доступа к функциям платформы и помогают определить, заблокирован пользователь или нет.

Также Пользователь имеет список статей-закладок. Возникает угроза рекурсии - если запросить статью, то ответом будет статья с автором с закладками, у которых тоже есть авторы и т.д. Чтобы такого не происходило, при запросах отправится только имя автора, т.е. ответ вида статья + имя автора.

диаграмма классов базы данных

Диаграмма классов для сущностей, которые хранятся в базе данных


У Роли есть программная заглушка в виде RoleEnum. Это позволяет не создавать объект каждый раз, а вызывать константу, которая уже имеет готовый объект. Помимо этого, константа содержит служебную информацию: краткое описание роли и действие, приводящее к этому состоянию.

Но сущности - сырой формат данных, который надо преобразовать в лёгкие для браузера объекты - DTO, Data Transfer Objects.

диаграмма классов ответов

Диаграмма классов для ответов


Ключевым классом является PageResponseDTO, который отвечает за постраничные ответы. Это могут быть страницы как со Статьями (ArticleDTO), так и с Пользователями (UserDTO) - поэтому применяется наследование и генерализация. Например, на главной странице будут показаны страницы со Статьями, а в кабинете Администратора - с Пользователями, но под капотом это всё - один класс.

SearchResponseDTO - объект для поисковых ответов. Помимо страниц с релевантными статьями содержит предложения к поиску.

AuthorDTO содержит информацию про автора - имя, описание и страницу со статьями.

ArticleDTO хранит только самую необходимую информацию, которая может быть расположена на соответствующей карточке. Этот объект не хранит контент, т.к. если нужно получить список статей, то у всех надо загрузить контент, а он может быть большим и в карточке он не показывается.

Для просмотра статьи контент, разумеется, нужен и поэтому существует класс-потомок ArticleWithContent, который, как гласит название, содержит контент. При этом контент в сыром виде - в виде Markdown - т.к. перевод в HTML происходит в браузере.

Диаграммы последовательностей

Теперь посмотрим, как происходят некоторые - на мой взгляд самые интересные - процессы.

диаграмма регистрации пользователя

Диаграмма последовательности регистрации пользователя


Регистрация пользователя. Пользователь вводит свои данные, нажимает кнопку Зарегистрироваться (Sign Up), браузер отправляет данные на сервер, чтобы тот сохранил пользователя. В процессе, если пользователь с указанными именем или почтой обнаружены есть в базе, то отправляется ответ с ошибкой. Если пришли новые данные, то пользователь сохраняется с ролью User по умолчанию перенаправляется на страницу входа, где использует данные, которые только что ввёл при регистрации.

диграмма получения статьи для чтения

Диаграмма последовательности получения статьи для чтения


Получение статьи для просмотра. Для чтения статьи отправляется запрос без флага raw. Этот флаг используется только для вставки текста в редактор. Запрос с флагом raw=true отличается механизмом проверки, может ли пользователь редактировать статью.

Итак, пользователь кликает на ссылку со статьёй. Запрос отправляется на сервер, где происходит поиск статьи. Если нужная статья не найдена, то будет показана страница с ошибкой 404 - «не найдено». Если статья есть, то проверяется, может ли пользователь её смотреть. А смотреть он её может если он администратор (он вправе смотреть любые статьи), автор этой статьи (и это статья-черновик) или статья опубликована. Если хотя бы одно требование выполнено, то происходит отправка Markdown-контента и рендер статьи в HTML. Иначе будет показана страница «Статья не найдена».

диаграмма страница автора'

Диаграмма последовательности получения страницы автора

Для получения информации об авторе и его статьях нужно перейти по ссылке, которая содержит его имя - оно есть в карточке статьи и в её полном виде для чтения. Получение информации осуществляется в два запроса. Первый получает данные автора-пользователя, и, если его нет, перенаправляет на страницу ошибки. Если же автор-пользователь есть, то отправляется второй запрос, который собирает все его опубликованные статьи. В конце всё это агрегируется и отправляется одним ответом на страницу.

Страница с автором поддерживает постраничные запросы. При нажатии на кнопку «Загрузить больше» (Load more) отправляется запрос, похожий на тот, что описан выше, но с другим смещением. Т.е. если в первом случае было запрошено, например, «5 статей, начиная с 0», то второй будет - «5 статей, начиная с 5-й». Статьи из ответа будут соединены с теми, что уже есть на странице.

Заключение

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

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

Приложения

  1. Исходные файлы: Github проекта
  2. Сам сервис: Briene

Официальная курсовая, которую я отправил научнику и вузу, отличается более скучной стилизацией, строгостью в выражениях, оформлением по ГОСТу. Эта статья - моя курсовая работа, какой она задумывалась. Почти вся работа была написана в этом же сервисе.