Удалить старый мусор из документации
This commit is contained in:
parent
c93cc6c522
commit
c397c28acb
@ -1,255 +0,0 @@
|
|||||||
# DAO_запуск
|
|
||||||
|
|
||||||
Рабочий документ по тому, что ещё нужно сделать для первого запуска DAO-сценария SHiNE.
|
|
||||||
|
|
||||||
Логика документа:
|
|
||||||
|
|
||||||
- `этап1` — то, без чего нельзя считать сценарий первого запуска собранным даже в тестовом виде;
|
|
||||||
- `этап2` — то, что полезно и, вероятно, потребуется дальше, но это можно делать после старта `этап1` или параллельно без блокировки первого результата.
|
|
||||||
|
|
||||||
Базовая среда первого прохода:
|
|
||||||
|
|
||||||
- сеть `Solana devnet`;
|
|
||||||
- модель синхронизации: `server-to-server`;
|
|
||||||
- `Solana + Arweave` используются как якорь и архив;
|
|
||||||
- DAO понимается как стандартный governance/smart-contract контур, который управляет отдельными программами SHiNE, приносящими деньги.
|
|
||||||
|
|
||||||
## Краткий вывод
|
|
||||||
|
|
||||||
Для первого запуска DAO в тестовом виде текущего списка в целом хватает, но только если понимать запуск как:
|
|
||||||
|
|
||||||
- можно развернуть и проверить базовый DAO-контур;
|
|
||||||
- можно зарегистрировать пользователей и ключевые сущности;
|
|
||||||
- можно провести тестовую покупку билета через smart contract;
|
|
||||||
- можно завести тестовый денежный поток в программы, управляемые DAO;
|
|
||||||
- можно проверить опорную межсерверную синхронизацию и фиксацию состояния в архивный слой.
|
|
||||||
|
|
||||||
Если же под "запуском" понимать уже полностью устойчивую production-схему с ротацией ключей, восстановлением любого сервера из архива, железными устройствами подписи и полным циклом администрирования, то текущий список нужно будет ещё расширять.
|
|
||||||
|
|
||||||
## Этап1
|
|
||||||
|
|
||||||
Цель этапа: собрать минимально жизнеспособный DAO-сценарий в `devnet`, который можно пройти руками от регистрации до базовой экономики и проверки архитектуры.
|
|
||||||
|
|
||||||
### 1. Переписать и стабилизировать регистрацию пользователей без Anchor
|
|
||||||
|
|
||||||
Что сделать:
|
|
||||||
|
|
||||||
- довести `shine_users` в чистом Rust/Solana SDK до рабочего и проверенного состояния;
|
|
||||||
- убедиться, что `shine_login_guard` и связанный сценарий регистрации совместимы с новым ABI;
|
|
||||||
- проверить создание и чтение `user_pda`;
|
|
||||||
- проверить update пользовательской записи и связанные экономические параметры;
|
|
||||||
- синхронизировать сервер, UI и lazy-import с новым форматом и seed'ами.
|
|
||||||
|
|
||||||
Почему это в `этап1`:
|
|
||||||
|
|
||||||
- без стабильной пользовательской регистрации дальше нельзя строить ни DAO-сценарий, ни привязку устройств, ни платёжные сценарии.
|
|
||||||
|
|
||||||
### 2. Проверить полный сценарий регистрации и базовой Solana-интеграции
|
|
||||||
|
|
||||||
Что сделать:
|
|
||||||
|
|
||||||
- руками прогнать регистрацию нового пользователя;
|
|
||||||
- руками прогнать создание и update server PDA там, где это требуется текущему сценарию;
|
|
||||||
- убедиться, что сервер читает новые PDA без anchor-зависимостей и без старых discriminator'ов;
|
|
||||||
- зафиксировать, какие именно части сценария уже подтверждены руками, а какие ещё нет.
|
|
||||||
|
|
||||||
Почему это в `этап1`:
|
|
||||||
|
|
||||||
- сейчас в проекте уже есть признаки перехода на pure Rust, но без ручной проверки это нельзя считать завершённым.
|
|
||||||
|
|
||||||
### 3. Создать стандартный DAO smart contract / governance-контур
|
|
||||||
|
|
||||||
Что сделать:
|
|
||||||
|
|
||||||
- определить и реализовать стандартный DAO-контур, который будет управлять программами SHiNE;
|
|
||||||
- зафиксировать, какие права сразу передаются DAO, а какие временно остаются на отдельных ключах;
|
|
||||||
- подготовить тестовую DAO-структуру в `devnet`.
|
|
||||||
|
|
||||||
Минимум для первого запуска:
|
|
||||||
|
|
||||||
- DAO существует как управляемая сущность;
|
|
||||||
- DAO может владеть или контролировать ключевые права управления денежными программами;
|
|
||||||
- есть понятный путь, как DAO влияет на доходные программы SHiNE.
|
|
||||||
|
|
||||||
Почему это в `этап1`:
|
|
||||||
|
|
||||||
- без этого "DAO-запуск" будет только запуском отдельных Solana-программ, но не запуском управляемой DAO-системы.
|
|
||||||
|
|
||||||
### 4. Доработать смарт-контракт выплат с третьей очередью
|
|
||||||
|
|
||||||
Что сделать:
|
|
||||||
|
|
||||||
- добавить в `shine_payments` третью очередь, о которой уже принято решение;
|
|
||||||
- проверить совместимость с текущей моделью тикетов, выплат и DAO-управления;
|
|
||||||
- убедиться, что логика очередей соответствует ожидаемой экономике проекта.
|
|
||||||
|
|
||||||
Почему это в `этап1`:
|
|
||||||
|
|
||||||
- по текущей постановке это нужно именно для сценария регистрации DAO и дальнейшей экономики.
|
|
||||||
|
|
||||||
### 5. Сделать UI для покупки билетов и просмотра очереди
|
|
||||||
|
|
||||||
Что сделать:
|
|
||||||
|
|
||||||
- добавить UI-сценарий покупки билетов через smart contract;
|
|
||||||
- показать пользователю, сколько перед ним человек в очереди;
|
|
||||||
- убедиться, что UI отражает актуальное состояние контрактной логики, а не локальные предположения.
|
|
||||||
|
|
||||||
Почему это в `этап1`:
|
|
||||||
|
|
||||||
- покупка билетов у тебя обозначена как часть DAO-сценария, а не как побочная функция;
|
|
||||||
- без UI можно тестировать контракт вручную, но нельзя считать сценарий запуска достаточно собранным для нормальной проверки.
|
|
||||||
|
|
||||||
### 6. Реализовать базовую синхронизацию серверов
|
|
||||||
|
|
||||||
Что сделать:
|
|
||||||
|
|
||||||
- сделать обмен состоянием между серверами по модели `server-to-server`;
|
|
||||||
- определить минимальный набор данных, который обязан синхронизироваться;
|
|
||||||
- предусмотреть фиксацию синхронизированного состояния в `Arweave`, а `Solana` использовать как якорь и ссылочный слой;
|
|
||||||
- описать, какой сервер считается источником истины в спорных случаях или как решается конфликт.
|
|
||||||
|
|
||||||
Почему это в `этап1`:
|
|
||||||
|
|
||||||
- без межсерверной синхронизации трудно обосновать архитектуру сети как воспроизводимую и переносимую;
|
|
||||||
- это напрямую связано с идеей, что любой сможет поднять свой сервер.
|
|
||||||
|
|
||||||
### 7. Подготовить базовый сценарий архивирования и восстановления
|
|
||||||
|
|
||||||
Что сделать:
|
|
||||||
|
|
||||||
- описать и частично реализовать схему: серверы синхронизируются между собой, архив состояния уходит в `Arweave`, ссылка/якорь фиксируется через `Solana`;
|
|
||||||
- определить минимальный сценарий восстановления блоков или состояния из архивного слоя;
|
|
||||||
- подтвердить, что новый сервер может получить достаточно данных для старта.
|
|
||||||
|
|
||||||
Почему это в `этап1`:
|
|
||||||
|
|
||||||
- это один из ключевых признаков независимой и воспроизводимой DAO-инфраструктуры.
|
|
||||||
|
|
||||||
## Этап2
|
|
||||||
|
|
||||||
Цель этапа: усилить безопасность, автономность и удобство системы после того, как минимальный DAO-сценарий уже запустился и проверен в `devnet`.
|
|
||||||
|
|
||||||
### 1. Смена ключей цифровой подписи
|
|
||||||
|
|
||||||
Что сделать:
|
|
||||||
|
|
||||||
- продумать и реализовать смену `root key`, `client key`, `blockchain key`;
|
|
||||||
- описать ограничения, кто и в каком сценарии может менять каждый тип ключа;
|
|
||||||
- продумать, как не потерять доступ и как обновлять доверие к новым ключам.
|
|
||||||
|
|
||||||
Почему это в `этап2`:
|
|
||||||
|
|
||||||
- для production это очень важно;
|
|
||||||
- для первого тестового запуска можно временно использовать фиксированный набор ключей.
|
|
||||||
|
|
||||||
### 2. Полная повторная перепроверка всех сценариев
|
|
||||||
|
|
||||||
Что сделать:
|
|
||||||
|
|
||||||
- повторно прогнать регистрацию, DAO, выплаты, билеты, синхронизацию и архивирование после стабилизации `этап1`;
|
|
||||||
- оформить итоговый чек-лист ручной проверки;
|
|
||||||
- отдельно проверить пограничные сценарии и восстановление после ошибок.
|
|
||||||
|
|
||||||
Почему это в `этап2`:
|
|
||||||
|
|
||||||
- это обязательный шаг перед переходом от "собрали" к "доверяем".
|
|
||||||
|
|
||||||
### 3. Устройство на ESP32 как homeserver с ключами
|
|
||||||
|
|
||||||
Что сделать:
|
|
||||||
|
|
||||||
- дописать прошивку, чтобы устройство могло выступать homeserver с ключами;
|
|
||||||
- дать ему возможность регистрироваться и подключаться к серверу;
|
|
||||||
- определить, какие операции устройство подписывает и где хранит ключевой материал.
|
|
||||||
|
|
||||||
Почему это в `этап2`:
|
|
||||||
|
|
||||||
- это очень сильное развитие архитектуры, но оно не должно блокировать первый DAO-запуск.
|
|
||||||
|
|
||||||
### 4. Логин и подпись через коробочки / устройства
|
|
||||||
|
|
||||||
Что сделать:
|
|
||||||
|
|
||||||
- реализовать сценарий входа через устройство или хотя бы сценарий подписи сообщений и ключей через устройство;
|
|
||||||
- определить, как это встраивается в регистрацию DAO и подтверждение действий;
|
|
||||||
- проверить, можно ли через это безопасно регистрировать DAO или подписывать критичные команды.
|
|
||||||
|
|
||||||
Почему это в `этап2`:
|
|
||||||
|
|
||||||
- это следующий уровень безопасности и UX, но не минимальный блокер первого старта.
|
|
||||||
|
|
||||||
### 5. Создание тестового DAO с использованием устройств подписи
|
|
||||||
|
|
||||||
Что сделать:
|
|
||||||
|
|
||||||
- после готовности устройств собрать тестовый DAO-сценарий уже с аппаратным участием;
|
|
||||||
- проверить, где устройство достаточно, а где всё ещё нужен обычный кошелёк или управляющий ключ.
|
|
||||||
|
|
||||||
Почему это в `этап2`:
|
|
||||||
|
|
||||||
- это проверка усиленной модели, а не базового старта.
|
|
||||||
|
|
||||||
### 6. Расписание синхронизации серверов
|
|
||||||
|
|
||||||
Что сделать:
|
|
||||||
|
|
||||||
- определить периодичность и правила фоновой синхронизации;
|
|
||||||
- продумать ручной и автоматический режим;
|
|
||||||
- решить, как часто публиковать архивные снимки и якоря.
|
|
||||||
|
|
||||||
Почему это в `этап2`:
|
|
||||||
|
|
||||||
- сначала важнее добиться самой работающей синхронизации, а потом уже делать её регулярной и автономной.
|
|
||||||
|
|
||||||
### 7. Полное восстановление блоков из Solana/Arweave
|
|
||||||
|
|
||||||
Что сделать:
|
|
||||||
|
|
||||||
- довести процедуру восстановления до сценария "любой может поднять свой сервер";
|
|
||||||
- определить минимальный bootstrap-набор;
|
|
||||||
- проверить восстановление на чистом окружении.
|
|
||||||
|
|
||||||
Почему это в `этап2`:
|
|
||||||
|
|
||||||
- для концепции сети это критично, но как полноценная задача обычно идёт после появления базового архива и первичной синхронизации.
|
|
||||||
|
|
||||||
## Что блокирует первый запуск сильнее всего
|
|
||||||
|
|
||||||
Если расставить приоритет внутри `этап1`, то самый жёсткий порядок сейчас выглядит так:
|
|
||||||
|
|
||||||
1. pure Rust регистрация пользователей и ручная проверка сценария;
|
|
||||||
2. DAO/gov-контур и его права управления;
|
|
||||||
3. доработка выплат с третьей очередью;
|
|
||||||
4. покупка билетов через smart contract и UI-проверка очереди;
|
|
||||||
5. межсерверная синхронизация;
|
|
||||||
6. архивирование в `Arweave` с якорем в `Solana`;
|
|
||||||
7. минимальное восстановление состояния новым сервером.
|
|
||||||
|
|
||||||
## Что уже частично похоже на готовое
|
|
||||||
|
|
||||||
По текущим документам и следам в проекте уже видно, что:
|
|
||||||
|
|
||||||
- переход `shine_users` и `shine_login_guard` на pure Rust уже начат и в значительной степени сделан;
|
|
||||||
- архитектура DAO, `shine_users` и `shine_payments` уже описана;
|
|
||||||
- часть Solana-структуры и PDA-форматов уже формализована;
|
|
||||||
- тема ESP32 уже отдельно присутствует в проекте как направление.
|
|
||||||
|
|
||||||
Это хорошо, потому что документ получается не "с нуля", а как сборка того, что уже назрело в коде и планах.
|
|
||||||
|
|
||||||
## Вопросы, которые всё ещё стоит уточнить
|
|
||||||
|
|
||||||
1. Какой именно стандарт DAO планируется использовать в первом проходе: готовый governance-стек Solana или собственная минимальная обвязка вокруг управляющих кошельков?
|
|
||||||
2. Третья очередь в `shine_payments` уже точно определена по смыслу, или пока есть только решение "она нужна", но без финальной экономики?
|
|
||||||
3. Что именно считается единицей синхронизации между серверами: блоки SHiNE, агрегированные снапшоты, PDA-состояния, или смесь этих вариантов?
|
|
||||||
4. Нужен ли для `этап1` уже полноценный автоматический recovery нового сервера, или достаточно доказать это в полу-ручном сценарии?
|
|
||||||
5. Покупка билетов должна в первом проходе работать только через web/UI, или также нужен отдельный сценарий из серверного UI или скриптов?
|
|
||||||
|
|
||||||
## Рекомендуемый следующий практический шаг
|
|
||||||
|
|
||||||
Если идти без распыления, то следующим рабочим фокусом стоит считать:
|
|
||||||
|
|
||||||
1. закрыть ручную проверку pure Rust регистрации;
|
|
||||||
2. после этого формализовать минимальный DAO-контур;
|
|
||||||
3. затем переходить к третьей очереди выплат и к UI покупки билетов;
|
|
||||||
4. после этого делать синхронизацию, архив и восстановление.
|
|
||||||
@ -1,62 +0,0 @@
|
|||||||
0. ПЕРЕДЕЛАТЬ ВСЁ НА НОВЫЙ ФОРМАТ!!
|
|
||||||
|
|
||||||
ВЫНЕСТИ ЭТИ ТРИ ВЕЩИ В ОБЩИЙ ПАРСЕР
|
|
||||||
* [2] type - тип соощения
|
|
||||||
* [2] Sиbtype - субтип сообщения
|
|
||||||
* [2] version - версия формата соощения
|
|
||||||
|
|
||||||
А ОСТАЛЬНОЕ В РЕАЛИЗАЦИЮ
|
|
||||||
|
|
||||||
|
|
||||||
ПЕРЕДЕЛАЕМ БД
|
|
||||||
|
|
||||||
1. СДЕЛАЕМ ЛИНИЮ ТОЛЬКО ДЛЯ ТЕХ ТИПОВ КОМУ НАДО (ЛАЙКАМ И ОТВЕТАМ НЕ НАДО)
|
|
||||||
(НОМЕР СООБЩЕНИЯ В ЛИНИИ ХРАНИТЬ В БЛОКАХ ВРОДЕ И НЕ НАДО ТЕМ БОЛЕЕ ЕГО ПОТОМ ПЕРЕПРОВЕРЯТЬ ВСЁ РАВНО)
|
|
||||||
А МОЖЕТ И НАДО ТК КАК ПО ОДНОМУ БЛОКУ ( ИЛИ ЧАСТИ БЛОКОВ ПОНЯТЬ КАКАЯ ЭТО ЧАСТЬ ПЕРЕПИСКИ - ВЕДЬ ГЛОБАЛ НОМЕР ВООБЩЕ НЕ ПОКАЗАТЕЛЬ)
|
|
||||||
|
|
||||||
В БД ПОМЕЧАТЬ ЧТО БЛОК ИЗ ЭТОЙ ЛИНИИ (ДЛЯ БЫСТРОГО ПОИСКА)
|
|
||||||
|
|
||||||
А УНИКАЛЬНЫЙ НОМЕР ЛИНИИ ЭТО ПО СУТИ НОМЕР СООБЩЕНИЯ СОЗДАВШЕГО ЛИНИЮ КАНАЛ (НУ И ФОРМАТ СООБЩЕНИЯ НАЧАЛА ЛИНИИ - КАНАЛА)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
3. СООТВЕТСТВЕННО удалить НАПИСАТЬ/ПЕРОВЕРИТЬ НОРМАЛЬНЫЙ SubscriptionsDAO - ТК СТАРЫЙ РАБОТАЛ НО НА ДРУГОМ ФОРМАТЕ И ТИПО КРИВО
|
|
||||||
|
|
||||||
и дальше:
|
|
||||||
ЗДЕЛАТЬ ТРИ ЗАПРОСА:
|
|
||||||
СПИСОК КАНАЛОВ НА КОГО ПОДПИСАН И ПО СКОЛЬКО СООБЩЕНИЙ И ПОСЛДНИЙ ТЕКСТ
|
|
||||||
ДОДЕЛАТЬ И СВЯЗ ПОДПИСАН УЖЕ НЕ ТОЛЬКО НА ЧЕЛА НО И НА КАНАЛ. (И ПОЛУЧАЕТСЯ ЕСТЬ ОБЩИЙ КАНАЛЛ ПОСТОВ (НО НЕКОТОРЫЕ ПОСТЫ В НИКУДА-
|
|
||||||
А НЕКОТОРЫЕ ПОСТЫ ОБЪЯВЛЕНИЕ КАНАЛА
|
|
||||||
|
|
||||||
СПИСОК СООБЩЕНИЙ В КАНАЛЕ
|
|
||||||
|
|
||||||
ОПСИСАНИЕ ОДНОГО СОООБЩЕНИЯ (С ИСТОРИЕЙ ДО НАЧАЛА ВЕТКИ И СО ВСЕМИ ОТВЕТАМИ НА НЕГО)
|
|
||||||
|
|
||||||
(НУ И В БУДУЩЕМ четвёртый ИСТОРИЮ сообщения ПО ЕДИТУ)
|
|
||||||
|
|
||||||
|
|
||||||
И ПОМЯТКА
|
|
||||||
ВСЕГДА СЧИТАЕМ ПО ПОСЛЕДНЕМУ БЛОКЧЕЙНУ ДОСТУПНОМУ ПОЛЬЗОВАТЕЛЮ
|
|
||||||
ХОТЯ ССЫЛКА ПО НОМЕРУ БЛОКЧЕЙНА КУДА ДОБАВИЛИ
|
|
||||||
|
|
||||||
ЛАЙКИ И ОТВЕТЫ ПИШЕМ НА НОМЕР СООБЩЕНИЯ ЕДИТА
|
|
||||||
(СЧИТАЕМ ТРИГЕРОМ И НА ОРИГИНАЛЬНЫЙ СУМАРНОЕ И ОТДЕЛЬНО НА НЕГО, И НА КАЖДЫЙ ЕДИТ ОТДЕЛЬНО)
|
|
||||||
|
|
||||||
ОТВЕТЫ ПОКАЗЫВАЕМ ВСЕ ВРАЗ
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -1,10 +0,0 @@
|
|||||||
Сделать возможность убрать свой лайк. (пока не надо а сложность что надо больше проверок) - хотя можно и без проверки, просто за двойной лайк или за снятие двойное лайка. Будет двойное проникновение :)) тому кто изменил код клиента и убрал проверку на клиенте - и блокчейн заблокируется и всё.
|
|
||||||
поэтому просто на каждую реакцию добавиться убрать эту ракцию .
|
|
||||||
- это просто
|
|
||||||
|
|
||||||
сделатьпотом что бы в солану_юзерс хранилось имя текущего блокчейна пользователя. Что бы потом можно было грузить именно актуальный ТО ЕСТЬ потом можно будет менять блокченый!
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
сделать сессион пасворд тоже ключём подписи устройства!!
|
|
||||||
@ -1,22 +0,0 @@
|
|||||||
Перечень библиотек и их краткое описание
|
|
||||||
|
|
||||||
shine-server-log
|
|
||||||
Статический “сиренный” метод для максимально заметного критического лога администратору
|
|
||||||
|
|
||||||
shine-server-config
|
|
||||||
Минимальный конфиг-лоадер, который один раз читает application.properties и даёт доступ к параметрам.
|
|
||||||
|
|
||||||
shine-server-geo
|
|
||||||
Утилиты, которые вытаскивают IP/язык/UA из Jetty WebSocket и (опционально) резолвят гео по IP с кэшем в БД.
|
|
||||||
|
|
||||||
shine-server-crypto
|
|
||||||
Базовые крипто-утилиты для SHA-256 и Ed25519 (BouncyCastle) + проверка подписи/хэша для .bch сущностей и маленький self-test.
|
|
||||||
|
|
||||||
shine-server-bd
|
|
||||||
Библиотека реалезующая всю работу с БД:
|
|
||||||
|
|
||||||
shine-server-blockchain
|
|
||||||
Библиотека, которая задаёт единый бинарный формат блоков (RAW+signature+hash), парсит/валидирует “тело” блока по type/version, и проверяет целостность/подпись цепочки через SHA-256 + Ed25519 с привязкой к login и предыдущим хэшам.
|
|
||||||
|
|
||||||
shine-server-protocol
|
|
||||||
Библиотека JSON-протокол поверх WebSocket для взаимодействия с клиентами.
|
|
||||||
@ -1,209 +0,0 @@
|
|||||||
SHiNE — структура БД (актуальная версия)
|
|
||||||
|
|
||||||
Перечень таблиц и назначение
|
|
||||||
|
|
||||||
solana_users
|
|
||||||
Справочник пользователей: логин + ключ устройства + (опционально) Solana-ключ.
|
|
||||||
Базовая таблица, используется как FK почти везде.
|
|
||||||
|
|
||||||
active_sessions
|
|
||||||
Активные сессии авторизации/работы клиента: секреты, тайминги, WebPush-данные, IP и информация о клиенте.
|
|
||||||
|
|
||||||
users_params
|
|
||||||
Хранилище актуальных параметров пользователя.
|
|
||||||
Для каждой пары (login, param) хранится только самая новая версия по time_ms.
|
|
||||||
|
|
||||||
ip_geo_cache
|
|
||||||
Кеш геолокации по IP для снижения нагрузки на внешние сервисы.
|
|
||||||
|
|
||||||
blockchain_state
|
|
||||||
Агрегированное состояние блокчейна по blockchain_name:
|
|
||||||
лимиты, текущий размер, последний глобальный блок и состояние линий 0..7.
|
|
||||||
|
|
||||||
blocks
|
|
||||||
Журнал всех блоков и сообщений.
|
|
||||||
Содержит историю событий: тексты, реакции, ответы, связи.
|
|
||||||
PRIMARY KEY намеренно отсутствует.
|
|
||||||
|
|
||||||
connections_state ⭐
|
|
||||||
Актуальное состояние связей между пользователями
|
|
||||||
(друг / контакт / подписка).
|
|
||||||
Обновляется автоматически на основе событий из blocks.
|
|
||||||
|
|
||||||
message_stats ⭐
|
|
||||||
Агрегированные счётчики лайков и ответов на конкретные сообщения.
|
|
||||||
Поддерживается триггерами из blocks.
|
|
||||||
|
|
||||||
Таблицы подробно
|
|
||||||
|
|
||||||
solana_users
|
|
||||||
login — TEXT PK — уникальный логин пользователя
|
|
||||||
client_key — TEXT NOT NULL — публичный ключ устройства (Base64(32) / HEX(64))
|
|
||||||
solana_key — TEXT NULL — публичный ключ Solana-аккаунта
|
|
||||||
|
|
||||||
active_sessions
|
|
||||||
session_id — TEXT PK — идентификатор сессии
|
|
||||||
login — TEXT NOT NULL, FK → solana_users(login)
|
|
||||||
session_pwd — TEXT NOT NULL — секрет сессии
|
|
||||||
storage_pwd — TEXT NOT NULL — секрет storage
|
|
||||||
session_created_at_ms — INTEGER NOT NULL
|
|
||||||
last_authirificated_at_ms — INTEGER NOT NULL
|
|
||||||
push_endpoint — TEXT NULL
|
|
||||||
push_p256dh_key — TEXT NULL
|
|
||||||
push_auth_key — TEXT NULL
|
|
||||||
client_ip — TEXT NULL
|
|
||||||
client_info_from_client — TEXT NULL
|
|
||||||
client_info_from_request — TEXT NULL
|
|
||||||
user_language — TEXT NULL
|
|
||||||
|
|
||||||
users_params
|
|
||||||
login — TEXT NOT NULL, FK → solana_users(login)
|
|
||||||
param — TEXT NOT NULL
|
|
||||||
time_ms — INTEGER NOT NULL
|
|
||||||
value — TEXT NOT NULL
|
|
||||||
client_key — TEXT NULL
|
|
||||||
signature — TEXT NULL
|
|
||||||
|
|
||||||
Ограничение:
|
|
||||||
UNIQUE(login, param)
|
|
||||||
|
|
||||||
Логика:
|
|
||||||
обновление принимается только если excluded.time_ms > users_params.time_ms
|
|
||||||
|
|
||||||
ip_geo_cache
|
|
||||||
ip — TEXT PK
|
|
||||||
geo — TEXT NULL
|
|
||||||
updated_at_ms — INTEGER NOT NULL
|
|
||||||
|
|
||||||
blockchain_state
|
|
||||||
blockchain_name — TEXT PK
|
|
||||||
login — TEXT NOT NULL, FK → solana_users(login)
|
|
||||||
blockchain_key — TEXT NOT NULL
|
|
||||||
size_limit — INTEGER NOT NULL
|
|
||||||
file_size_bytes — INTEGER NOT NULL
|
|
||||||
last_global_number — INTEGER NOT NULL (-1 = genesis)
|
|
||||||
last_global_hash — TEXT NOT NULL
|
|
||||||
updated_at_ms — INTEGER NOT NULL
|
|
||||||
|
|
||||||
Линии 0..7:
|
|
||||||
для каждой линии:
|
|
||||||
lineX_last_number
|
|
||||||
lineX_last_hash
|
|
||||||
|
|
||||||
blocks
|
|
||||||
login — TEXT NOT NULL
|
|
||||||
bch_name — TEXT NOT NULL
|
|
||||||
block_global_number — INTEGER NOT NULL
|
|
||||||
block_global_pre_hash — TEXT NOT NULL
|
|
||||||
block_line_index — INTEGER NOT NULL
|
|
||||||
block_line_number — INTEGER NOT NULL
|
|
||||||
block_line_pre_hash — TEXT NOT NULL
|
|
||||||
msg_type — INTEGER NOT NULL
|
|
||||||
msg_sub_type — INTEGER NOT NULL
|
|
||||||
block_bytes — BLOB NULL
|
|
||||||
|
|
||||||
Ссылка на другой блок (nullable):
|
|
||||||
to_login
|
|
||||||
to_bch_name
|
|
||||||
to_block_global_number
|
|
||||||
to_block_hash
|
|
||||||
|
|
||||||
connections_state ⭐
|
|
||||||
Текущее агрегированное состояние связей.
|
|
||||||
|
|
||||||
login — TEXT NOT NULL
|
|
||||||
rel_type — INTEGER NOT NULL
|
|
||||||
10 = FRIEND
|
|
||||||
20 = CONTACT
|
|
||||||
30 = FOLLOW
|
|
||||||
to_login — TEXT NOT NULL
|
|
||||||
to_bch_name — TEXT NOT NULL
|
|
||||||
to_block_global_number — INTEGER NULL
|
|
||||||
to_block_hash — TEXT NULL
|
|
||||||
|
|
||||||
Ограничение:
|
|
||||||
UNIQUE(login, rel_type, to_login)
|
|
||||||
|
|
||||||
message_stats ⭐
|
|
||||||
Счётчики активности по целевому сообщению.
|
|
||||||
|
|
||||||
to_login — TEXT NOT NULL
|
|
||||||
to_bch_name — TEXT NOT NULL
|
|
||||||
to_block_global_number — INTEGER NOT NULL
|
|
||||||
to_block_hash — TEXT NOT NULL
|
|
||||||
likes_count — INTEGER NOT NULL DEFAULT 0
|
|
||||||
replies_count — INTEGER NOT NULL DEFAULT 0
|
|
||||||
|
|
||||||
UNIQUE:
|
|
||||||
(to_login, to_bch_name, to_block_global_number, to_block_hash)
|
|
||||||
|
|
||||||
Триггеры БД (полная логика)
|
|
||||||
|
|
||||||
3.1 Связи пользователей
|
|
||||||
trg_blocks_connection_state_ai
|
|
||||||
AFTER INSERT ON blocks
|
|
||||||
|
|
||||||
Условие:
|
|
||||||
msg_type = 3 (connection)
|
|
||||||
|
|
||||||
Добавление / обновление связи
|
|
||||||
msg_sub_type IN (10,20,30)
|
|
||||||
выполняется UPSERT в connections_state
|
|
||||||
|
|
||||||
Удаление связи
|
|
||||||
msg_sub_type IN (11,21,31)
|
|
||||||
удаляется соответствующая связь:
|
|
||||||
11 → 10
|
|
||||||
21 → 20
|
|
||||||
31 → 30
|
|
||||||
|
|
||||||
Итог:
|
|
||||||
blocks — журнал событий
|
|
||||||
connections_state — всегда актуальное состояние
|
|
||||||
|
|
||||||
3.2 Подсчёт лайков ⭐
|
|
||||||
trg_blocks_message_stats_like_ai
|
|
||||||
AFTER INSERT ON blocks
|
|
||||||
|
|
||||||
Условие:
|
|
||||||
msg_type = 2 (reaction)
|
|
||||||
msg_sub_type = 1 (like)
|
|
||||||
|
|
||||||
Действие:
|
|
||||||
определяется цель по to_bch_name, to_block_global_number, to_block_hash
|
|
||||||
to_login вычисляется как
|
|
||||||
substr(to_bch_name, 1, length(to_bch_name) - 3)
|
|
||||||
выполняется UPSERT в message_stats
|
|
||||||
likes_count += 1
|
|
||||||
|
|
||||||
3.3 Подсчёт ответов ⭐
|
|
||||||
trg_blocks_message_stats_reply_ai
|
|
||||||
AFTER INSERT ON blocks
|
|
||||||
|
|
||||||
Условие:
|
|
||||||
msg_type = 1 (text)
|
|
||||||
msg_sub_type = 2 (reply)
|
|
||||||
|
|
||||||
Действие:
|
|
||||||
цель определяется аналогично лайкам
|
|
||||||
выполняется UPSERT в message_stats
|
|
||||||
replies_count += 1
|
|
||||||
|
|
||||||
Индексы (смысл)
|
|
||||||
|
|
||||||
idx_solana_users_login — поиск пользователя
|
|
||||||
idx_active_sessions_login — сессии пользователя
|
|
||||||
idx_users_params_login — параметры пользователя
|
|
||||||
idx_ip_geo_cache_updated_at — чистка кеша
|
|
||||||
idx_blockchain_state_login — блокчейны пользователя
|
|
||||||
idx_blockchain_state_updated_at — обслуживание
|
|
||||||
idx_blocks_chain_global — чтение цепочки
|
|
||||||
idx_blocks_to_target — реакции / ответы
|
|
||||||
idx_message_stats_target — быстрый доступ к счётчикам
|
|
||||||
|
|
||||||
Итоговая модель мышления
|
|
||||||
|
|
||||||
blocks — неизменяемый журнал событий
|
|
||||||
connections_state — проекция связей
|
|
||||||
message_stats — проекция активности
|
|
||||||
всё вычисляется детерминированно через триггеры
|
|
||||||
@ -1,75 +0,0 @@
|
|||||||
# Протокол звонков (MVP)
|
|
||||||
|
|
||||||
Версия: browser-to-browser, runtime-only signaling.
|
|
||||||
|
|
||||||
## Цели
|
|
||||||
- Технические сообщения звонка не сохраняются в БД direct_messages.
|
|
||||||
- Первый INVITE рассылается всем активным сессиям получателя и дублируется web push.
|
|
||||||
- Последующие сигналы идут только в конкретную sessionId и не дублируются в push.
|
|
||||||
|
|
||||||
## Операции API
|
|
||||||
|
|
||||||
### 1) CallInviteBroadcast
|
|
||||||
Отправляет общий вызов пользователю.
|
|
||||||
|
|
||||||
Запрос payload:
|
|
||||||
- `toLogin: string`
|
|
||||||
- `callId: string`
|
|
||||||
- `type: 100` (INVITE)
|
|
||||||
|
|
||||||
Поведение сервера:
|
|
||||||
- Рассылает `IncomingCallInvite` во все активные WS-сессии `toLogin`.
|
|
||||||
- В payload события передаёт:
|
|
||||||
- `fromLogin`
|
|
||||||
- `fromSessionId` (session инициатора)
|
|
||||||
- `toLogin`
|
|
||||||
- `callId`
|
|
||||||
- `type=100`
|
|
||||||
- `timeMs`
|
|
||||||
- Отправляет web push уведомление о входящем вызове.
|
|
||||||
|
|
||||||
Ответ payload:
|
|
||||||
- `callId`
|
|
||||||
- `deliveredWsSessions`
|
|
||||||
- `deliveredFcmSessions`
|
|
||||||
|
|
||||||
### 2) CallSignalToSession
|
|
||||||
Отправляет технический сигнал в конкретную сессию.
|
|
||||||
|
|
||||||
Запрос payload:
|
|
||||||
- `toLogin: string`
|
|
||||||
- `targetSessionId: string`
|
|
||||||
- `callId: string`
|
|
||||||
- `type: int`
|
|
||||||
- `data: string` (для SDP/ICE/служебных строк)
|
|
||||||
|
|
||||||
Поведение сервера:
|
|
||||||
- Ищет только `targetSessionId`.
|
|
||||||
- Проверяет, что сессия принадлежит `toLogin`.
|
|
||||||
- Отправляет `IncomingCallSignal` только в эту сессию.
|
|
||||||
- В БД ничего не сохраняет.
|
|
||||||
- Push не отправляет.
|
|
||||||
|
|
||||||
Ответ payload:
|
|
||||||
- `delivered: boolean`
|
|
||||||
|
|
||||||
## Коды type
|
|
||||||
- `100` INVITE
|
|
||||||
- `110` RINGING
|
|
||||||
- `120` ACCEPT
|
|
||||||
- `130` DECLINE_BUSY
|
|
||||||
- `140` TIMEOUT
|
|
||||||
- `150` HANGUP
|
|
||||||
- `200` OFFER
|
|
||||||
- `210` ANSWER
|
|
||||||
- `220` ICE
|
|
||||||
|
|
||||||
## Правила UI/логики
|
|
||||||
- Если уже есть активный звонок и пришел новый INVITE -> автоответ `DECLINE_BUSY` без UI.
|
|
||||||
- После ACCEPT `callId` остаётся во всех OFFER/ANSWER/ICE сообщениях до конца звонка.
|
|
||||||
- При параллельных звонках A<->B допускается детерминированное правило, кто создаёт OFFER.
|
|
||||||
|
|
||||||
## Тайминги MVP
|
|
||||||
- Ожидание подтверждения/реакции после INVITE: до 5с (у инициатора).
|
|
||||||
- Ожидание принятия у входящего звонка: 20с.
|
|
||||||
- Общий лимит ожидания до соединения: 22с.
|
|
||||||
@ -1,9 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
Дальше делать:
|
|
||||||
Описание форматов.
|
|
||||||
Запросы клиент-сервер.
|
|
||||||
Промт на клиента.
|
|
||||||
|
|
||||||
---
|
|
||||||
Потом в сервак дописать синхронизацию серверов.
|
|
||||||
@ -1,53 +0,0 @@
|
|||||||
# SHiNE Deployment Servers Inventory
|
|
||||||
|
|
||||||
## Scope
|
|
||||||
This folder contains all deployment-related notes and server records for SHiNE.
|
|
||||||
|
|
||||||
## Legacy Production Server
|
|
||||||
- Name: `VPS-02` (legacy)
|
|
||||||
- Access: `root@194.87.0.247`
|
|
||||||
- Current role: old production server
|
|
||||||
- Confirmed services:
|
|
||||||
- `coturn` is installed and active (`systemd: active/running`)
|
|
||||||
- `caddy` is installed (reported by project context; verify version on host if needed)
|
|
||||||
- TURN configuration observed on host:
|
|
||||||
- `listening-port=3478`
|
|
||||||
- `external-ip=194.87.0.247`
|
|
||||||
- `relay-ip=194.87.0.247`
|
|
||||||
- auth mode: `use-auth-secret` + `static-auth-secret`
|
|
||||||
- SHiNE deployment note:
|
|
||||||
- This host is used as current/legacy runtime for SHiNE.
|
|
||||||
- Gradle-based deployment is used in this project (see repository deploy tasks and scripts).
|
|
||||||
|
|
||||||
## Target Production Server (Migration)
|
|
||||||
- Name: `VPS-05` (new)
|
|
||||||
- Access: `root@45.136.124.227`
|
|
||||||
- Planned role: new primary production server for gradual migration
|
|
||||||
- Baseline setup done:
|
|
||||||
- `ripgrep` installed
|
|
||||||
- user `player` created
|
|
||||||
- user `player` added to `sudo` group
|
|
||||||
- deployment directory created: `/home/player/SHiNE`
|
|
||||||
- Rule:
|
|
||||||
- All SHiNE-related runtime files and deployments on VPS-05 should be placed under `/home/player/SHiNE`.
|
|
||||||
|
|
||||||
## Additional TURN Node
|
|
||||||
- Name: `promo-node-93`
|
|
||||||
- Access: `ubuntu@93.170.12.154` (and `player` user for SHiNE operations)
|
|
||||||
- Role: additional TURN node for SHiNE calls
|
|
||||||
- TURN setup:
|
|
||||||
- `coturn` installed and active
|
|
||||||
- `listening-port=3478`
|
|
||||||
- `tls-listening-port=5349`
|
|
||||||
- `use-auth-secret` + shared `static-auth-secret`
|
|
||||||
- relay UDP port range: `49152-50152`
|
|
||||||
- Runtime files:
|
|
||||||
- `/etc/turnserver.conf`
|
|
||||||
- `/home/player/SHiNE/coturn/turnserver.conf`
|
|
||||||
- Cleanup done:
|
|
||||||
- Disabled old reverse SSH tunnel (`reverse-ssh.service`) that exposed `0.0.0.0:1200 -> localhost:22` to `194.87.0.247`.
|
|
||||||
|
|
||||||
## Next Migration Steps (recommended)
|
|
||||||
1. Install and configure runtime dependencies (JDK, Caddy, DB, TURN if required).
|
|
||||||
2. Mirror SHiNE deployment process from VPS-02 using existing Gradle deployment flow.
|
|
||||||
3. Move traffic gradually and validate logs/metrics before final cutover.
|
|
||||||
@ -1,13 +0,0 @@
|
|||||||
# Будущие фичи
|
|
||||||
|
|
||||||
Эта папка оставлена как архивный указатель. Активный backlog теперь ведётся в корневой папке `TODO/`.
|
|
||||||
|
|
||||||
## Что здесь осталось
|
|
||||||
|
|
||||||
- `README.md` - краткое объяснение, что раньше хранилось в `Future_Features/`.
|
|
||||||
- `far/README.md` - архивное описание дальнего горизонта.
|
|
||||||
|
|
||||||
## Куда смотреть теперь
|
|
||||||
|
|
||||||
- Ближайшие и среднесрочные планы перенесены в `TODO/`.
|
|
||||||
- Если нужен список следующих шагов, читать сначала `TODO/README.md`.
|
|
||||||
@ -1,8 +0,0 @@
|
|||||||
# Дальнее будущее
|
|
||||||
|
|
||||||
Архивный файл. Раньше здесь лежали задачи дальнего горизонта, но теперь активный backlog перенесён в `TODO/`.
|
|
||||||
|
|
||||||
## Что делать дальше
|
|
||||||
|
|
||||||
- смотреть `TODO/README.md`;
|
|
||||||
- если потребуется вернуть этот горизонт отдельно, обновить соответствующий список задач в `TODO/`.
|
|
||||||
@ -1,42 +0,0 @@
|
|||||||
# TODO: доработка персональных сообщений для агентов
|
|
||||||
|
|
||||||
Статус: отложено.
|
|
||||||
|
|
||||||
## Что хотели сделать
|
|
||||||
|
|
||||||
Добавить упрощённую маршрутизацию персональных сообщений через служебную инструкцию в начале текстового payload (внутри подписанного DM-блока), чтобы:
|
|
||||||
|
|
||||||
- отличать сообщения человеку от сообщений агенту;
|
|
||||||
- отличать сообщения от человека и от агента;
|
|
||||||
- скрывать в обычном UI сообщения, адресованные агенту (`target=agent`);
|
|
||||||
- поддержать сценарий «сообщения самому себе между своими клиентами/устройствами», где один клиент/агент пишет другому в рамках одного логина.
|
|
||||||
|
|
||||||
## Базовая идея формата (черновик)
|
|
||||||
|
|
||||||
Пример префикса:
|
|
||||||
|
|
||||||
```text
|
|
||||||
@shine:pm:v1 {"target":"agent","agentId":"assistant","author":"human"}
|
|
||||||
Текст сообщения...
|
|
||||||
```
|
|
||||||
|
|
||||||
Пример ответа агента:
|
|
||||||
|
|
||||||
```text
|
|
||||||
@shine:pm:v1 {"target":"user","author":"agent","agentId":"assistant","agentLabel":"My Bot"}
|
|
||||||
Ответ агента...
|
|
||||||
```
|
|
||||||
|
|
||||||
## Почему отложено
|
|
||||||
|
|
||||||
- нужно отдельно согласовать финальный формат инструкции;
|
|
||||||
- нужно определить строгие правила UI-фильтрации и fallback;
|
|
||||||
- нужно определить, нужен ли позднее отдельный серверный роутинг для agent-сессий.
|
|
||||||
|
|
||||||
## Что сделать при возвращении к задаче
|
|
||||||
|
|
||||||
1. Зафиксировать окончательный формат префикса и JSON-полей.
|
|
||||||
2. Описать правила парсинга/валидации (включая битые/неполные префиксы).
|
|
||||||
3. Добавить UI-логику показа/скрытия agent-сообщений.
|
|
||||||
4. Добавить маркировку «ответ агента» в диалоге.
|
|
||||||
5. Продумать режим self-chat (между своими клиентами/агентом) в рамках одного логина.
|
|
||||||
@ -1,2 +1,2 @@
|
|||||||
client.version=1.2.281
|
client.version=1.2.282
|
||||||
server.version=1.2.261
|
server.version=1.2.262
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user