26 KiB
Черновик дополнений каналов и типов сообщений SHiNE
Статус документа
Этот файл является рабочим черновиком первой итерации.
Важно:
- это не финальная спецификация;
- формат блокчейна этим документом пока не меняется автоматически;
- документ фиксирует согласованную на текущий момент концепцию;
- в первую итерацию входят только
TEXTиSTATUS_ACTION; - всё, что касается
CHANNEL_MEMBERSHIP, вынесено в отдельный отложенный черновик:Черновик_CHANNEL_MEMBERSHIP_для_каналов.md
Цель
Нужно расширить текущую модель каналов SHiNE так, чтобы канал был не только лентой обычных постов, но и пространством:
- материалов;
- упражнений;
- услуг / процедур;
- курсов;
- входных страниц каналов;
- истории действий пользователей по этим материалам.
При этом важно:
- не ломать существующий блокчейн без отдельного согласованного шага;
- минимально менять верхнеуровневые
type; - по возможности переиспользовать уже существующий текстовый тип сообщений;
- отделять собственно контент от событий состояния.
Базовая идея первой итерации
На текущий момент согласована следующая модель:
- старый
type=1, который раньше называлсяTEXT, по коду можно не менять; - в документации и логике его можно трактовать шире как основной контентный тип сообщений;
- все новые смысловые материалы каналов добавляются как новые
subTypeвнутриtype=1; - отдельным верхнеуровневым
typeв первой итерации становится только:type=5— действия пользователя по материалам.
Иначе говоря:
type=1= сообщения и материалы;type=5= статусные действия пользователя;type=6= тема вынесена в отдельный отложенный черновик и в первую итерацию не входит.
Текущие старые верхнеуровневые типы
Они сохраняются:
type=0—TECHtype=1—TEXTtype=2—REACTIONtype=3—CONNECTIONtype=4—USER_PARAM
Верхнеуровневые типы первой итерации
Используются:
0—TECH1—TEXT2—REACTION3—CONNECTION4—USER_PARAM5—STATUS_ACTION
Отдельно:
6—CHANNEL_MEMBERSHIP- зарезервирован как следующая тема;
- вынесен в отдельный черновик;
- в текущую реализацию не входит.
Подтипы внутри type=1
Согласованная таблица первой итерации:
subType=10—TEXT_POSTsubType=11—TEXT_EDIT_POSTsubType=20—TEXT_REPLYsubType=21—TEXT_EDIT_REPLYsubType=30—TEXT_RATINGsubType=50—TEXT_REPOSTsubType=90—TEXT_CHANNEL_METAsubType=100—TEXT_ENTRYPOINTsubType=110—TEXT_EXERCISEsubType=120—TEXT_SERVICEsubType=130—TEXT_COURSE
Принцип форматов внутри type=1
Line-based сообщения
Следующие подтипы считаются line-based и используют тот же body, что и обычный TEXT_POST:
TEXT_POSTTEXT_REPOSTTEXT_CHANNEL_METATEXT_ENTRYPOINTTEXT_EXERCISETEXT_SERVICETEXT_COURSE
Target-based сообщения
Следующие подтипы считаются target-based:
TEXT_REPLYTEXT_EDIT_REPLYTEXT_RATING
Edit для TEXT
В первой итерации согласовано оставить в коде два технических edit-подтипа:
TEXT_EDIT_POST- edit для сообщений линии канала;
TEXT_EDIT_REPLY- edit для reply-сообщений.
То есть в документации больше не используется старое упрощённое описание “один общий TEXT_EDIT”.
Смысл подтипов type=1
TEXT_POST
Обычный текстовый пост в канале.
TEXT_EDIT_POST
Редактирование line-based текстового сообщения канала.
Принцип:
- edit всегда ссылается на оригинальный блок;
- edit не должен ссылаться на предыдущий edit;
- фактический тип и правила берутся из оригинального сообщения.
TEXT_REPLY
Обычный ответ / комментарий на сообщение.
Важно:
- reply остаётся единым;
- отвечать можно на
post,rating,exercise,service,course,entrypoint,status_action; - reply сам является target-based сообщением.
TEXT_EDIT_REPLY
Редактирование reply-сообщения.
TEXT_RATING
Текстовый отзыв / мнение / оценка на конкретный блок.
Смысл:
- это не line-based пост;
- это target-based сообщение-отзыв;
- оно всегда ссылается на конкретный блок, который оценивает;
- оценку пользователя как отдельную сущность в эту итерацию не включаем.
TEXT_REPOST
Отложенная будущая заготовка.
На текущем этапе:
- код зарезервирован;
- бизнес-логика не входит в первую итерацию;
- детальная реализация может быть возвращена позже.
TEXT_CHANNEL_META
Специальное скрытое сообщение метаданных канала.
Через него задаются:
- красивое имя канала;
- аватар;
- описание;
- и другие общие channel meta.
Оно:
- не является обычным пользовательским сообщением;
- не должно показываться в ленте как обычный пост;
- должно парситься по отдельным техническим правилам.
TEXT_ENTRYPOINT
Входная / главная страница канала.
Смысл:
- это не отдельный верхнеуровневый тип;
- это специальный line-based текстовый материал;
- он служит входной страницей канала;
- он может объяснять структуру канала, давать ссылки, вводить человека в тему.
Принцип:
TEXT_ENTRYPOINTне редактируется черезTEXT_EDIT_POST;- новая версия создаётся новым сообщением
TEXT_ENTRYPOINT; - если в канале несколько
entrypoint, актуальным считается последний.
TEXT_EXERCISE
Упражнение или комплекс упражнений.
Смысл:
- материал, который можно выполнять много раз;
- материал, который можно выучить;
- по нему удобно строить статистику выполнений и освоения.
TEXT_SERVICE
Услуга / процедура.
Смысл:
- материал, который пользователь проходит;
- обычно не “учится выполнять”, а именно получает / проходит;
- прохождение фиксируется отдельным
STATUS_ACTION.
TEXT_COURSE
Курс.
Смысл:
- материал, по которому есть путь обучения;
- пользователь может заинтересоваться, начать, учиться, завершить, бросить.
Канал 0
Согласована новая трактовка канала 0.
Канал 0 становится:
- обычным каналом публикаций пользователя по умолчанию;
- местом его основной ленты;
- местом его главной страницы, если там есть
entrypoint.
Что это значит
Если у пользователя в канале 0 существует TEXT_ENTRYPOINT, тогда:
- ссылка
SHiNE/<login>открывает именно этот последнийentrypoint.
Если entrypoint в канале 0 нет, тогда:
SHiNE/<login>открывает обычную ленту публикаций канала0.
Правила открытия каналов и ссылок
Согласована следующая логика:
SHiNE/<login>- главная страница пользователя, то есть канал
0;
- главная страница пользователя, то есть канал
SHiNE/<login>/<channel>- основная ссылка канала.
Как открывается SHiNE/<login>/<channel>
Если у канала есть хотя бы один TEXT_ENTRYPOINT, тогда:
- по умолчанию открывается последний актуальный
entrypoint; - UI показывает, сколько после него было новых сообщений;
- UI показывает кнопку перехода в конец канала.
Если entrypoint нет:
- открывается обычная лента канала.
Для подписанного пользователя:
- логичнее вести его в место новых непрочитанных сообщений;
- а не всегда принудительно открывать entrypoint;
- при этом сверху можно показывать кнопку
Открыть entrypoint.
Ссылки на конкретные сообщения
Остаются обычные формы:
SHiNE/<login>/<channel>/<messageNumber>SHiNE/<login>/<channel>/<messageNumber>/<hash>
Если нужно показать старую конкретную версию entrypoint, даётся ссылка именно на номер нужного сообщения.
Новый тип STATUS_ACTION
type=5 вводится для действий пользователя по контенту.
Принцип STATUS_ACTION
Согласовано:
STATUS_ACTIONвсегда является target-based сообщением;- статусное действие всегда ссылается на конкретный блок-материал;
- это не обычный пост в канале;
- из таких сообщений можно собирать виртуальную ленту пользователя.
Как трактуется текст в STATUS_ACTION
Основной смысл блока задаётся самим статусным событием.
Текст внутри такого блока:
- это комментарий пользователя к действию, если он есть;
- не является главным смыслом записи;
- служит пояснением.
Примеры:
- “Начал сегодня”
- “Решил пройти серьёзно”
- “Сделал это после практики”
- “Выучил базовый комплекс”
Подтипы STATUS_ACTION
Предлагаемая таблица:
subType=10—STATUS_DONE_ONCEsubType=20—STATUS_INTERESTEDsubType=30—STATUS_STARTEDsubType=40—STATUS_IN_STUDYsubType=50—STATUS_COMPLETEDsubType=60—STATUS_ABANDONEDsubType=70—STATUS_LEARNEDsubType=80—STATUS_CONFIRMED
Смысл подтипов STATUS_ACTION
STATUS_DONE_ONCE
Факт одного выполнения / прохождения.
Это накопительное событие.
STATUS_INTERESTED
Пользователя заинтересовал материал.
STATUS_STARTED
Пользователь начал.
Это начальный статус процесса, но ещё не “устойчивое обучение”.
STATUS_IN_STUDY
Пользователь уже полноценно находится в обучении.
Смысл:
- не просто попробовал;
- а реально учится;
- это отдельный статус, более сильный, чем
started.
STATUS_COMPLETED
Пользователь завершил курс / прохождение.
STATUS_ABANDONED
Пользователь бросил.
STATUS_LEARNED
Пользователь выучил упражнение или комплекс и знает, как его делать.
Это не то же самое, что “сделал один раз”.
STATUS_CONFIRMED
Подтверждение чужого status-события.
Важно:
- подтверждается не курс вообще;
- не упражнение вообще;
- а конкретный
STATUS_ACTIONконкретного пользователя.
Кто ставит статусы
Согласовано правило:
- любой базовый статус ставит сам пользователь от своего имени;
- другие люди не ставят статус за него;
- другие люди могут только подтверждать его status-событие через
STATUS_CONFIRMED.
То есть:
INTERESTED,STARTED,IN_STUDY,COMPLETED,ABANDONED,LEARNED,DONE_ONCE- ставит сам пользователь;
CONFIRMED- ставят другие люди на конкретный статусный блок.
Вес подтверждений
В базовой версии веса подтверждений не вводятся.
Но в будущем можно добавить:
- более значимое подтверждение от создателя курса;
- более значимое подтверждение от создателя упражнения;
- весовые коэффициенты от близких / доверенных людей;
- слабые подтверждения от обычных пользователей.
Матрица допустимости статусов по типам контента
Для TEXT_SERVICE
Разрешены:
STATUS_DONE_ONCESTATUS_CONFIRMED
Не разрешены:
INTERESTEDSTARTEDIN_STUDYCOMPLETEDABANDONEDLEARNED
Для TEXT_EXERCISE
Разрешены:
STATUS_DONE_ONCESTATUS_LEARNEDSTATUS_CONFIRMED
Логика:
- упражнение можно выполнять много раз;
- упражнение можно выучить;
LEARNEDиDONE_ONCEне конфликтуют и живут параллельно.
Для TEXT_COURSE
Разрешены:
STATUS_INTERESTEDSTATUS_STARTEDSTATUS_IN_STUDYSTATUS_COMPLETEDSTATUS_ABANDONEDSTATUS_CONFIRMED
Для TEXT_ENTRYPOINT
Статусные действия не ставятся.
Для TEXT_POST, TEXT_REPLY, TEXT_RATING, TEXT_CHANNEL_META
Статусные действия не ставятся.
Накопительные и текущие состояния
Нужно различать:
- накопительные события;
- текущий статус.
Накопительные события
К ним относится:
STATUS_DONE_ONCE
Они могут встречаться сколько угодно раз.
Текущий статус
Для некоторых статусов есть “актуальное состояние”.
Например:
INTERESTEDSTARTEDIN_STUDYCOMPLETEDABANDONEDLEARNED
Текущий статус определяется как последнее событие соответствующей оси.
Для упражнения
У упражнения есть две независимые оси:
- количественная: сколько раз выполнено;
- качественная: выучено или нет.
Это значит:
STATUS_DONE_ONCEнакапливается;STATUS_LEARNEDживёт как отдельный качественный статус.
Для курса
У курса текущий статус вычисляется по последнему из:
INTERESTEDSTARTEDIN_STUDYCOMPLETEDABANDONED
Виртуальная лента достижений пользователя
Согласована важная идея:
- не нужно создавать отдельный физический канал для истории выполнений пользователя;
- вместо этого строится виртуальная лента из его
STATUS_ACTION.
Что это даёт
Можно одновременно получить:
- историю человека;
- статистику по самому материалу.
Например, по упражнению можно увидеть:
- сколько разных людей его выполняли;
- сколько всего выполнений было;
- сколько раз конкретный человек его выполнял;
- кто его выучил.
Что попадает в виртуальную ленту
Попадают status-события пользователя:
- выполненные упражнения;
- выученные упражнения;
- интерес к курсам;
- начатые курсы;
- обучение в процессе;
- завершённые курсы;
- брошенные курсы;
- прохождения услуг;
- подтверждения к этим событиям.
Можно ли это обсуждать
Да.
Такие статусные сообщения остаются обычными объектами обсуждения:
- на них можно отвечать;
- их можно комментировать;
- на них можно писать отзывы;
- их можно подтверждать.
То есть:
- лента виртуальная;
- но сами записи реальные и обсуждаемые.
Как это должно выглядеть в интерфейсе
В каналах
Для разных типов сообщений UI должен понимать роль сообщения.
Например:
- у
TEXT_EXERCISEможно показать кнопки:ВыполнилВыучил
- у
TEXT_SERVICE:Прошёл
- у
TEXT_COURSE:ИнтересноНачалУчусьЗавершилБросил
Для entrypoint
Если канал открывается по основной ссылке и у него есть entrypoint, UI:
- показывает сам последний
entrypoint; - показывает число новых сообщений после него;
- показывает кнопку перехода в конец канала.
Если пользователь уже подписан на канал:
- открывать лучше место новых непрочитанных сообщений;
- но с кнопкой открытия последнего
entrypoint.
Для виртуальной ленты достижений
В профиле пользователя UI может показывать:
- отдельную вкладку / раздел;
- где лента строится из его
STATUS_ACTION.
Что именно не нужно делать в первой итерации
Не нужен отдельный физический канал достижений
Технически не нужен.
Не нужны отдельные edit-подтипы для каждого вида контента
Не нужны:
TEXT_EDIT_EXERCISETEXT_EDIT_SERVICETEXT_EDIT_COURSE
Достаточно текущего разделения:
TEXT_EDIT_POSTTEXT_EDIT_REPLY
Не нужен отдельный верхнеуровневый тип для entrypoint
Он остаётся подтипом type=1.
Не нужен EDIT для status-событий
STATUS_ACTION не редактируются.
Если нужно изменить смысл, пишется новое событие.
Не нужен CHANNEL_MEMBERSHIP в первой итерации
Эта тема отложена в отдельный черновик.
Сводная таблица
Верхнеуровневые type
| Код | Имя | Статус |
|---|---|---|
| 0 | TECH | старый |
| 1 | TEXT | старый код, новое расширенное смысловое описание |
| 2 | REACTION | старый |
| 3 | CONNECTION | старый |
| 4 | USER_PARAM | старый |
| 5 | STATUS_ACTION | первая итерация |
| 6 | CHANNEL_MEMBERSHIP | вынесено в отдельный отложенный черновик |
Подтипы type=1
| subType | Имя | Смысл |
|---|---|---|
| 10 | TEXT_POST | обычный post в линии канала |
| 11 | TEXT_EDIT_POST | edit line-based сообщения |
| 20 | TEXT_REPLY | target-based reply |
| 21 | TEXT_EDIT_REPLY | edit reply |
| 30 | TEXT_RATING | target-based отзыв на конкретный блок |
| 50 | TEXT_REPOST | отложенная будущая заготовка |
| 90 | TEXT_CHANNEL_META | скрытые метаданные канала |
| 100 | TEXT_ENTRYPOINT | входная страница канала |
| 110 | TEXT_EXERCISE | упражнение |
| 120 | TEXT_SERVICE | услуга / процедура |
| 130 | TEXT_COURSE | курс |
Подтипы type=5
| subType | Имя | Смысл |
|---|---|---|
| 10 | STATUS_DONE_ONCE | выполнил / прошёл один раз |
| 20 | STATUS_INTERESTED | заинтересовался |
| 30 | STATUS_STARTED | начал |
| 40 | STATUS_IN_STUDY | учится полноценно |
| 50 | STATUS_COMPLETED | завершил |
| 60 | STATUS_ABANDONED | бросил |
| 70 | STATUS_LEARNED | выучил |
| 80 | STATUS_CONFIRMED | подтверждение status-события |
Что ещё нужно отдельно утвердить перед реализацией
Перед началом реальной реализации желательно отдельно утвердить:
- точный байтовый формат новых line-based
subTypeвнутриtype=1; - точный байтовый формат
TEXT_RATINGкак target-based отзыва; - точный байтовый формат
STATUS_ACTION; - правила target-ссылок для status-событий;
- правила target-ссылок для отзывов на status-события;
- поведение удаления:
- можно ли логически удалять
TEXT_EXERCISE/TEXT_SERVICE/TEXT_COURSE; - можно ли удалять старые
entrypointили только оставлять их в истории;
- можно ли логически удалять
- серверные read-model таблицы и индексы.
Предварительная оценка готовности к реализации
На текущий момент концепция уже достаточно зрелая, чтобы начинать проектирование реализации первой итерации.
Реализовывать это уже можно, если дополнительно утвердить:
- байтовые форматы;
- правила валидации;
- API чтения новых сущностей;
- UI-матрицу действий по каждому типу контента.
Краткий итог
Согласованная модель первой итерации сейчас такая:
- почти всё новое содержимое каналов живёт внутри
type=1; entrypoint— это специальное текстовое сообщение, а не отдельный верхнеуровневый тип;entrypointне редактируется, а версионируется новыми сообщениями;- канал
0становится каналом публикаций пользователя и его главной страницей; - действия пользователя по материалам выносятся в
STATUS_ACTION; TEXT_RATINGтрактуется как target-based отзыв на конкретный блок;CHANNEL_MEMBERSHIPотложен в отдельный черновик и в первую итерацию не входит.