{
 "feeds": {
  "feed-name": {
   "acl": 4,
   "date": 1321223195545
  },
  "second-feed": {
   "acl": 6,
   "date": 0
  }
 }
}

Данные фидов начинаются с корневого класса "feed".
Имена фидов определяются именами вложенных классов, например "feed-name" и "second-feed".

Обязательные поля для заголовка фида это "acl", оно определяет права доступа
для конкретного пользователя или для всех пользователей сразу.
Если у пользователя отсутствуют права на фид, то он его не получит.
Формат этого поля число если этого права для конкретного пользователя либо класс
содержащий полную информацию о правах доступа.
TODO: Разработать формат хранения прав доступа.

Следующее обязательное поле это "date", определяет время последней модификации фида.
Формат число миллисекунд с 1970-01-01T00:00:00 UTC. ВНИМАНИЕ могут быть проблемы со
сторонними реализациями JSON, т.к. это поле больше 32 битного целого числа.

Остальные поля могут использоватся для данных фида.


*** Выборка данных фидов ***
За выборку данных отвечает класс Feeds.
Выборка должна осуществляется для списка конкретных фидов либо всех фидов,
в случае если при выборке указан пользователь получатель, должны проверятся права доступа.
Должна быть возможность получить только заголовки так и полные данные.

Заголовок фида формируется в классе FeedHeader.
Тело фидов должно получатся из класса Feed на основе внутреннего представления данных.
Возможно, стоит добавить специальную виртуальную функцию, чтобы переопределить вывод
в классах наследниках.

Если пользователь имеет права на чтение, то он может получить полное тело фида.
Для прав на запись или редактирование пользователь может получить только заголовок фида.


=== Хранение фидов сервером ===
Данные обычных каналов должны хранится в таблице channels в столбце feeds.
Данные персональных пользовательских каналов, должны хранится в таблице users в столбце feeds.
Формат данных JSON.


=== Загрузка фидов ===
1. Загрузить JSON данные.
2. Получить имена фидов.
3. С помощью класса фабрики начать создавать фиды передавая в качестве параметров имя фида
   и соответствующий кусок JSON данных.

Класс Feed должен содержать виртуальный метод для создания себя из исходных данных.


=== Подключение к каналу ===
Сервер посылает список заголовков фидов, клиент должен отправить запрос
данные каких фидов его интересуют.


=== Минимальные данные канала ===
* Имя/Ник.
* Уникальный идентификатор канала.
* Таблица фидов.
* Список идентификаторов каналов-подписчиков.
* (quint8) Пол и цвет иконки.
* (quint8) Статус.
? Права доступа.

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

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

Вход в обычный канал происходит по стандартной схеме.
Идентификатор пользователя добавляется в список подписчиков этого канала.

=== Новый механизм нормализации ===
Для нормализации имени канала используется отдельный статический класс.
Само нормализованное имя теперь хранится в виде идентификатора.
Каждый пользователь теперь резервирует для себя 1 ник, вне зависимости от подключения к серверу.

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

Возможное решение:
Считать ник пригодным к повторному использованию, при длительной неактивности пользователя владельца.
Для зарегистрированного пользователя ник резервируется пожизненно.

== Работа клиента с фидами ==
"edit" - Редактирование заголовка фида.

Запросы клиента:
"headers" - Запрос на получение заголовков всех фидов.
"get"     - Запрос на получение тела фида, имя фида передаётся как текст.
"update"  - Запрос на обновление данных фида, имя фида передаётся как текст, новые данные как JSON. Старое тело фида будет слито с новыми данными.
"clear"   - Запрос на очистку данных фида, имя фида передаётся как текст.
"query"   - Запрос специфичных данных фида, имя фида передаётся как текст, параметры запроса как JSON.
"add"     - Запрос на добавление фида, имя фида передаётся как текст, параметры запроса как JSON.
"remove"  - Запрос на удаление фида, имя фида передаётся как текст.
"revert"  - Запрос на откат текущей ревизии фида, опционально может быть передан номер ревизии, на которую нужно вернуться.

Ответы сервера:
"headers" - Ответ на запрос "headers".
"feed"    - Ответ на запрос "get", в случае если произошла ошибка, статус пакета будет отличаться от 200.
"update"  - Ответ на запрос "update", в случае успеха статус пакета равен 200.
"clear"   - Ответ на запрос "clear", в случае успеха статус пакета равен 200.
"reply"   - Ответ на запрос "query", в случае успеха статус пакета равен 200.
"add"     - Ответ на запрос "add", в случае успеха статус пакета равен 200.
"remove"  - Ответ на запрос "remove".
"revert"  - Ответ на запрос "revert".

Данные хранимые в виде "links":
Уникальный идентификатор пользователя.
Тип операционной системы.
Имя хоста.
Время последней активности.
Версия клиента.
Последний ip адрес.
Временная зона.


