# Обсуждение предметной область виджетов
## TL;DR
Вопросы:
1. Мы поняли, как уместить в модель страницы (PageWidget) и фиды (FeedWidget). Как будет выглядить социальный фид?
2. Хотим не делать категории. Что этому противоречит?
3. Хотим обойтись одним сорцом, не массивом. Что этому противоречит?
Все обсуждения дальше.
## Доменная модель (без социальных фидов)
Виджеты делятся сейчас (в нашем сознании) на два типа:
- для фидов
- для страниц
Последние обсуждения привели к такому видению виджета
```
Widget {
id
title
isHidden: Boolean // hide if not delete
isSystem: Boolean // true for Discuss and Followed (why?)
type = "feed" | "page"
data = { ... }
}
FeedWidget {
...
type: "feed"
data: {
sources: Source[]
}
}
PageWidget {
...
type: "page"
data: {
url = String
}
}
```
## Вопросы с примерами
### Вопрос 1. как будут выглядеть и работать социальные фиды?
Это самый большой вопрос. Все варианты несут с собой противоречия.
Ситуация:
- Мы знаем, как показать RSS/fulldive-фид — FeedWidget с сорцом.
- Мы знаем, как показать произвольный сайт — PageWidget.
- Мы не понимаем, что именно создавать для социальных фидов.
Кроулеры и социальные фиды далее используются как синонимы.
Если мы хотим показать социальный фид как страницу и заодно показать вставки в новостях, то надо выбрать:
- совместить кроулер со страницей в одну сущность
- явно выделить новую сущость
- разделить фичи совсем, то есть вынести социальные фиды из концепции домашнего экрана
Начнем со встраивания в виджеты.
#### Вариант с виджетом №1: совмещаем кроулинг и PageWidget
Когда клиент видит кроулер «со схемой», он создает PageWidget с опциональным конфигом кроулинга. А если кроулер без схемы, то PageWidget создается без нее.
Например, со схемой будет так:
```
PageWidget {
...
type: "page"
data: {
url = String
crawling?: {
parseStrategy = "instagram" // for the script
isAuthRequired = boolean
authUrl = "..."
}
}
}
```
Противоречия:
1. Такой виджет несет в себе не только адрес страницы, но и конфиг парсинга. В итоге виджет страницы сам становится сорцом. От чего мы изначально уходили.
2. Клиент должен разделять, есть ли схема парсинга в кроулере или ее нет. На сервере валидация требует схему, поэтому она всегда есть. Надо придумывать очередной флажок.
3. Представим, что пользователь открывает в табе Инстаграм и добавляет его себе как виджет. А не через наш каталог сайтов. Должен ли клиент отловить эту ситуацию, чтобы создать не обычный PageWidget, а PageWidget с кроулером? Если да, как он должен заранее знать про конфигурацию кроулера именно для инстаграма? Если нет, то мы частично теряем кейс социальных вставок в новости.
#### Вариант с виджетом №2: отдельная сущность CrawlerPageWidget
Виджет совмещает две задачи и получает свой тип. И сам становится сорцом.
```
PageCrawlerWidget {
...
type: "crawler"
data: {
url = String
parseStrategy = "instagram" // for the script
isAuthRequired = boolean
authUrl = "..."
}
}
```
Противоречия:
1. Размытая ответственность с сорцами
2. Размытая ответственность с другими типами виджетов
2. Это уже и так работает, и весь сыр-бор только ради коллекции сорцов, которая и так не страдает.
#### Вариант разделить фичи
Если мы перестанем думать о кроулере как о части виджета, то проблема перетекает в задачу к клиентам. Парсинг определяется клиентом, а на сервере/фаербейзе лежит статический конфиг стратегий
Мы уже концептуально отказались от кроулера как от фида. Осталось сделать это технически.
Задача — сохранить социальные вставки в новостях при этом не усложнить показ страниц на главном экране.
Решение — фича «социальные посты в ленте» отделяется от фичи «сайты на главном экране». Они становятся независимыми.
Этого можно достичь, если мы удаляем кроулеры из доменной модели. Совсем.
Представим, что инстаграм с твиттером лежат среди всех других ссылок на равных, просто как обычные заготовки для PageWidget. Нас интересует в них только адрес страницы и больше ничего.
Пользователь нажимает на вытянутую кнопку инстаграма. У него появляется страница на домашнем экране. Фича «страница на экране» сработала. Конец этой фичи.
Параллельно работает другая фича — «социальные посты в ленте». Как она работает? Приложение обнаруживает на домашнем экране знакомый домен (instagram.com), берет кроулер и парсит нужный фид с нужной стратегией.
Очевидно, что второй фиче неважно, откуда появилась страница — из нашего каталога или прямо из браузерной вкладки.
Максимальное количество виджетов — 100. Итерироваться по 100 ссылкам просто. Скрипт остается жить. Откуда брать стратегии парсинга и знание про домены?
На сервере или фаербейзе лежит конфиг. Как сейчас с «social feeds», только с мелкими добавлениями.
Плюсы:
- У нас нет противоречия между сраницей и фидом в виджетах. У нас есть четко фиды (rss, fulldive) и страницы, они разные и понятные.
- Мы не думаем о том, откуда пользователь добавил социальные фиды — из вкладки или из каталога платформ. Их посты всегда появляется в новостях при первой возможности.
- Разделение фич уменьшит энтропию, на сервере будет меньше сценариев. Мы перестаем смешивать в кашу мало связанные штуки, с этим проще работать всем.
- Статический контракт конфигурации гораздо проще, чем бизнес-логика целой сущности.
- Тип «crawler» или занозы «social crawler» больше не мешается общему кейсу ради пяти частных случаев.
Минусы:
- Не знаю, хочу услышать остальных. Я сам не догадался о противоречиях.
- Стоимость — работа на клиентах, конечно. Не представляю, насколько удобно и просто это сделать. Понятно, что изменится триггер кроулинга фидов. Понятно, что добавится поиск доменов в ссылках. А конфиг надо будет один раз скачивать одновременно со скриптом.
### Вопрос 2. Хотим не делать категории. Что этому противоречит?
У них нет практического смысла. Пользователь может задать категорию деке, но категория не дает никакого видимого эффекта. Поэтому мы бы хотели про них забыть до тех пор, пока от них не появится польза.
- Категории нужны только в публичных сущностях, например, сорцах, а виджеты/деки не публичные
- У пользователя нет мотивации отмечать категорию, это не несет ему пользы.
- Категории и ранжирование всегда де-факто контролируются бизнесом, а не пользователями, поэтому старый механизм автоподсчета категорий сорцов не актуален.
Работа для клиентов состоит в том, чтобы убрать кнопки категорий из виджетов/дек. Есть ли что-то, что этому противоречит?
### Вопрос 3. Хотим обойтись одним сорцом, не массивом. Что этому противоречит?
«Мультифиды» не используются в приложениях уже долгое время. Можно упростить контракт, если решить использовать только один фид на виджет.
```
FeedWidget {
...
type: "feed"
data: {
source: Source // the one and the only
}
}
```
## F.A.Q.
### Почему новая сущность
Деки все равно надо переделывать с нуля. Деки в в4 основаны целиком на в2. Запросы на запись проксируются в в2. Сделать в разделение дек на подтипы в рамках в4 означает их реализацию с нуля, при этом еще нужно заботиться о корректной частичной синхронизации с в2 или с ее логикой.
У дек есть много ненужного в контракте. На ненужное необходимо потратить время. Что лишнее:
- публикация и модерация (+ивент и пуш на это)
- реферирование дек
- чтобы поднимать популярную деку в выдаче
- категории дек
- чтобы искать популярные деки по категориям
- чтобы ранжировать сорцы из всех дек по категориям
- в итоге все значимые сорцы имеют искусственные очки
- очки в деках, что следует из бесполезности категорий
Итого, текущее состояние дек неудобно для того, чтобы в ней реализовать новый тип дек. В в2 мы не хотим добавлять новый функционал. Потому что это сложно, долго и потому что мы рискуем совместимостью, и вообще мы все за в4.
Если все равно писать с нуля, то проще писать с нуля только нужное. Поэтому новая сущность дешевле, чем дека.
### Почему названа виджетами
Сущность что-то показывает на главном экране — поэтому это «виджеты». Пока самое удачное название.
В будущем к страницам и фидам добавятся виджеты погоды и котировок, блэкджека и томагочи. Они будут ходить в отдельно подготовленные апи (наши или сторонние). Поэтому подобрал название такое общее.
До этого была идея «home section», но оно громозкое, и не факт что коснется только домашнего экрана.