From 95bbd2852e44163362f98b611b7ee3bc7853d1ccda1bc48ddcaa24a5c76ea4e7 Mon Sep 17 00:00:00 2001 From: AidarKC Date: Tue, 11 Aug 2026 20:19:46 +0400 Subject: [PATCH] =?UTF-8?q?=D0=A0=D0=B5=D0=B3=D0=B8=D1=81=D1=82=D1=80?= =?UTF-8?q?=D0=B0=D1=86=D0=B8=D1=8F:=20=D0=BF=D0=BE=D0=BF=D0=BE=D0=BB?= =?UTF-8?q?=D0=BD=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=B2=20=D1=82=D0=BE=D0=BC=20?= =?UTF-8?q?=D0=B6=D0=B5=20=D0=BE=D0=BA=D0=BD=D0=B5=20=D0=B8=20=D1=82=D0=B5?= =?UTF-8?q?=D1=81=D1=82=D0=BE=D0=B2=D1=8B=D0=B9=20top-up?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...-06-26_1810_подключение_устройств_по_qr.md | 29 - ...026-06-26_1815_esp32_файловое_хранилище.md | 28 - TODO/README.md | 61 -- ...er_technical_commands_and_file_transfer.md | 114 --- .../2026-05-25_1106_shine_balance_wallet.md | 62 -- .../2026-05-26_0029_esp32s3_file_storage.md | 44 -- .../2026-06-02_сессионные_homeserver_в_pda.md | 105 --- ...3_подключение_других_устройств_через_qr.md | 44 -- ...-28_send_signal_перенос_старых_сигналов.md | 29 - ...26-07-22_переход_с_sqlite_на_postgresql.md | 57 -- ...-05-25_1106_wallet_topup_solana_arweave.md | 71 -- ...брать_временную_очистку_signed_messages.md | 33 - ..._переделать_на_sendsignal_и_client_key.md} | 0 ...новить_полную_логику_shine_login_guard.md} | 8 + ...ок_с_адремаси_програм_и_счетов_в_Солане.md | 0 ...испроверки_актуальных_голосований_в_ДАО.md | 0 ..._полноценные_инвестиционные_инструменты.md | 1 + .../Децентрализация/ИТХ/README.md | 0 .../ИТХ/Спецификация_ИТХ_v1.md | 0 ...от минимум что нужен для работы сияния.md | 0 ... нескольких залогиненных аккаунтов враз.md | 0 ...ера_за_30с_чтобы_все_задачи_доделались.md} | 10 - ...ков и сделать отправку ошибки на сервер.md | 0 ...щем_сделать_репосты_в_каналах_и_тредах.md} | 0 ..._дороботать_для_максимальной_надёжности.md | 0 ...erver_как_хранилище_файлов_пользователя.md | 5 + ...26-06-26_1805_межсерверный_ws_и_dm_sync.md | 43 -- TODO/Децентрализация/README.md | 16 - .../realtime_pda_solana_sync.md | 30 - .../запись_блокчейнов_в_arweave.md | 29 - .../межсерверная_передача_сообщений.md | 30 - TODO/Децентрализация/межсерверные_звонки.md | 29 - .../односерверный_production_режим.md | 23 - ...ждения и добавление участников в канал.md | 0 TODO/Новые типы связей пользователей.md | 0 .../01_Презентация_для_людей.md | 275 ------- .../02_ТЗ_новых_типов_блоков.md | 670 ------------------ ...ервер на две части что бы работал с VPS.md | 0 ...Разместить на гитхаб с AGPLv3 лицензией.md | 0 TODO/межсерверные_звонки.md | 7 + VERSION.properties | 2 +- docs/Figma/README.md | 33 - docs/Figma/TRANSFER_UI_SCREENS.md | 222 ------ .../Спецификация_DM_v0.5_устаревшая.md | 230 ------ docs/libs/shine-server-bd/DOC.md | 12 - .../POSTGRES_RUNTIME_SCHEMA_V1.md | 91 --- .../Solana-audit-2-by-Claude-11июня2026.md | 0 .../Solana-audit-3-by-Claude-12июня2026.md | 0 .../Solana-audit-by-Claude-File5-9июня2026.md | 0 .../js/pages/registration-payment-view.js | 10 +- shine-UI/js/pages/topup-view.js | 59 +- 51 files changed, 67 insertions(+), 2445 deletions(-) delete mode 100644 TODO/2026-06-26_1810_подключение_устройств_по_qr.md delete mode 100644 TODO/2026-06-26_1815_esp32_файловое_хранилище.md delete mode 100644 TODO/README.md delete mode 100644 TODO/far/2026-06-20_1639_homeserver_technical_commands_and_file_transfer.md delete mode 100644 TODO/medium/2026-05-25_1106_shine_balance_wallet.md delete mode 100644 TODO/medium/2026-05-26_0029_esp32s3_file_storage.md delete mode 100644 TODO/medium/2026-06-02_сессионные_homeserver_в_pda.md delete mode 100644 TODO/medium/2026-06-03_подключение_других_устройств_через_qr.md delete mode 100644 TODO/medium/2026-06-28_send_signal_перенос_старых_сигналов.md delete mode 100644 TODO/medium/2026-07-22_переход_с_sqlite_на_postgresql.md delete mode 100644 TODO/near/2026-05-25_1106_wallet_topup_solana_arweave.md delete mode 100644 TODO/near/2026-07-07_дм_v11_убрать_временную_очистку_signed_messages.md rename TODO/{medium/2026-08-09_esp32_переход_на_sendsignal_и_client_key.md => Близкое/ESP32/В_клшельке_и_esp32_переделать_на_sendsignal_и_client_key.md} (100%) rename TODO/{near/2026-07-01_2205_восстановить_полную_логику_shine_login_guard.md => Близкое/Solana_смарт_контракты/Восстановить_полную_логику_shine_login_guard.md} (98%) create mode 100644 TODO/Близкое/Solana_смарт_контракты/Навести_порядок_с_адремаси_програм_и_счетов_в_Солане.md create mode 100644 TODO/Близкое/Solana_смарт_контракты/Передать_все_права_обновления_ДАО_И_сделат_сервиспроверки_актуальных_голосований_в_ДАО.md create mode 100644 TODO/Близкое/Solana_смарт_контракты/Сделать_полноценные_инвестиционные_инструменты.md rename TODO/{ => Близкое}/Децентрализация/ИТХ/README.md (100%) rename TODO/{ => Близкое}/Децентрализация/ИТХ/Спецификация_ИТХ_v1.md (100%) create mode 100644 TODO/Близкое/Еовести порядок с кошельками и отображением баланса_ тот минимум что нужен для работы сияния.md create mode 100644 TODO/Близкое/Сделать поддержку нескольких залогиненных аккаунтов враз.md rename TODO/{2026-06-26_1800_корректное_завершение_за_30с.md => Близкое/Сделать_возможность_корректного_завершения_работы_сервера_за_30с_чтобы_все_задачи_доделались.md} (74%) create mode 100644 TODO/Близкое/Убрать разные тестовые штуки для звонков и сделать отправку ошибки на сервер.md rename TODO/{medium/2026-05-24_1140_репосты_в_каналах_и_тредах.md => В_отдалённом_Будущем/В будущем_сделать_репосты_в_каналах_и_тредах.md} (100%) create mode 100644 TODO/В_отдалённом_Будущем/ДЦ_личную_переписку_дороботать_для_максимальной_надёжности.md create mode 100644 TODO/В_отдалённом_Будущем/Предложения_к_рассмотрению_в_будущее/Как_вариант_можно_сделать_hameserver_как_хранилище_файлов_пользователя.md delete mode 100644 TODO/Децентрализация/2026-06-26_1805_межсерверный_ws_и_dm_sync.md delete mode 100644 TODO/Децентрализация/README.md delete mode 100644 TODO/Децентрализация/realtime_pda_solana_sync.md delete mode 100644 TODO/Децентрализация/запись_блокчейнов_в_arweave.md delete mode 100644 TODO/Децентрализация/межсерверная_передача_сообщений.md delete mode 100644 TODO/Децентрализация/межсерверные_звонки.md delete mode 100644 TODO/Децентрализация/односерверный_production_режим.md create mode 100644 TODO/Доделать в блокчейн - подтверждения и добавление участников в канал.md create mode 100644 TODO/Новые типы связей пользователей.md delete mode 100644 TODO/Новые фишки которые надо доделать/Новая_контентная_модель_блокчейна/01_Презентация_для_людей.md delete mode 100644 TODO/Новые фишки которые надо доделать/Новая_контентная_модель_блокчейна/02_ТЗ_новых_типов_блоков.md create mode 100644 TODO/Поделить сервер на две части что бы работал с VPS.md create mode 100644 TODO/Разместить на гитхаб с AGPLv3 лицензией.md create mode 100644 TODO/межсерверные_звонки.md delete mode 100644 docs/Figma/README.md delete mode 100644 docs/Figma/TRANSFER_UI_SCREENS.md delete mode 100644 docs/Personal_Messages/Спецификация_DM_v0.5_устаревшая.md delete mode 100644 docs/libs/shine-server-bd/DOC.md delete mode 100644 docs/libs/shine-server-bd/POSTGRES_RUNTIME_SCHEMA_V1.md rename docs/{audit => старый_аудит_смартконтрактов_в_claud_fable}/Solana-audit-2-by-Claude-11июня2026.md (100%) rename docs/{audit => старый_аудит_смартконтрактов_в_claud_fable}/Solana-audit-3-by-Claude-12июня2026.md (100%) rename docs/{audit => старый_аудит_смартконтрактов_в_claud_fable}/Solana-audit-by-Claude-File5-9июня2026.md (100%) diff --git a/TODO/2026-06-26_1810_подключение_устройств_по_qr.md b/TODO/2026-06-26_1810_подключение_устройств_по_qr.md deleted file mode 100644 index 2e8419c2..00000000 --- a/TODO/2026-06-26_1810_подключение_устройств_по_qr.md +++ /dev/null @@ -1,29 +0,0 @@ -# Подключение других устройств по QR и типизированные сессии - -## Зачем - -QR-подключение других устройств сейчас есть как заготовка, но сценарий нужно довести до устойчивого состояния. Параллельно надо аккуратно оформить типизированные сессии homeserver-ов в PDA. - -## Что сделать - -1. Довести QR-сценарий до стабильного подключения нового устройства. -2. Нормально описать и хранить устройство как отдельную типизированную сессию. -3. Согласовать это с серверной и UI-логикой. -4. Проверить, что подключение работает одинаково на новом и повторном устройстве. - -## Что уже есть - -- в планах есть `сессионные homeserver-ы в PDA`; -- в планах есть `подключение других устройств через QR`; -- базовая заготовка уже существует, но сценарий считается нестабильным. - -## Откуда продолжать - -- от текущих документов в `TODO/medium/`; -- отдельно проверить, какие поля уже есть в PDA и UI. - -## Какие документы потом обновить - -- `docs/Solana_Architecture/README.md`; -- `TODO/medium/2026-06-03_подключение_других_устройств_через_qr.md`; -- `TODO/medium/2026-06-02_сессионные_homeserver_в_pda.md`. diff --git a/TODO/2026-06-26_1815_esp32_файловое_хранилище.md b/TODO/2026-06-26_1815_esp32_файловое_хранилище.md deleted file mode 100644 index a1aadca2..00000000 --- a/TODO/2026-06-26_1815_esp32_файловое_хранилище.md +++ /dev/null @@ -1,28 +0,0 @@ -# ESP32 как личное файловое хранилище - -## Зачем - -Планируется использовать ESP32 как личное файловое хранилище SHiNE для переписок и вложений. - -## Что сделать - -1. Продумать формат хранения файлов на устройстве. -2. Согласовать загрузку и чтение файлов между UI, сервером и устройством. -3. Проверить, как устройство показывает статусы и ошибки. -4. Свести это с существующим homeserver/UI-прототипом. - -## Что уже есть - -- в списке будущих фич уже есть отдельная задача по ESP32S3 file storage; -- для UI homeserver уже есть отдельная документация и скетч должны держаться синхронно. - -## Откуда продолжать - -- от `TODO/medium/2026-05-26_0029_esp32s3_file_storage.md`; -- от документации по ESP32 UI homeserver. - -## Какие документы потом обновить - -- `TODO/medium/2026-05-26_0029_esp32s3_file_storage.md`; -- `TODO/README.md`; -- документацию по ESP32 UI homeserver, если добавятся экраны или статусы. diff --git a/TODO/README.md b/TODO/README.md deleted file mode 100644 index 43d0b4dc..00000000 --- a/TODO/README.md +++ /dev/null @@ -1,61 +0,0 @@ -# TODO - -Папка для короткого списка ближайших и среднесрочных задач, которые уже обсуждались и пока отложены. - -## Как использовать - -- Один markdown-файл = одна задача. -- В файле коротко фиксируем: - - зачем это нужно; - - что именно сделать; - - что уже есть в коде; - - откуда продолжать; - - какие документы потом надо обновить. -- Это не активная разработка. Тут только план и контекст. -- Старую папку `docs/Future_Features/` считать архивной и больше не использовать как источник новых задач. - -## Текущие задачи - -- `2026-06-26_1800_корректное_завершение_за_30с.md` - дать сервису до 30 секунд на корректное завершение опасных операций перед рестартом. -- `2026-06-26_1810_подключение_устройств_по_qr.md` - довести подключение других устройств по QR и перевести это в нормальные типизированные сессии. -- `2026-06-26_1815_esp32_файловое_хранилище.md` - использовать ESP32 как личное файловое хранилище для переписок и вложений. - -## Децентрализация - -Текущий production-режим SHiNE считается односерверным. Задачи по нескольким серверам, Arweave и realtime PDA/Solana sync вынесены в `Децентрализация/` и не блокируют выкладку текущей версии на GitHub. - -- `Децентрализация/односерверный_production_режим.md` - границы текущей production-версии с одним сервером. -- `Децентрализация/запись_блокчейнов_в_arweave.md` - будущая запись/архивация блокчейнов в Arweave. -- `Децентрализация/realtime_pda_solana_sync.md` - будущая онлайн-синхронизация PDA и Solana. -- `Децентрализация/межсерверная_передача_сообщений.md` - будущая доставка сообщений между серверами. -- `Децентрализация/межсерверные_звонки.md` - будущая маршрутизация звонков между серверами. -- `Децентрализация/2026-06-26_1805_межсерверный_ws_и_dm_sync.md` - перенесённый старый план постоянного server-to-server WS и DM sync. - -## Новые фишки которые надо доделать - -- `Новые фишки которые надо доделать/Новая_контентная_модель_блокчейна/` - отложенная новая контентная модель блокчейна, не входящая в текущий односерверный production-релиз. - -## Перенесённые планы из `docs/Future_Features/` - -### near - -- `near/2026-05-25_1106_telegram_agent_players.md` - разрешённые пользователи Telegram для агента, отдельные папки игроков, персональные истории и публикация краткого вопроса/ответа в общий канал. -- `near/2026-05-25_1106_wallet_topup_solana_arweave.md` - пополнение Solana и Arweave через внешний сервис покупки с подсказкой и копированием адреса. - -### medium - -- `medium/2026-05-24_1140_репосты_в_каналах_и_тредах.md` - репосты в каналах и тредах. -- `medium/2026-05-25_1106_shine_balance_wallet.md` - кошелёк и пополнение баланса сияния через блокчейн. -- `medium/2026-05-26_0029_esp32s3_file_storage.md` - ESP32S3 как личное файловое хранилище SHiNE для файлов переписок и вложений. -- `medium/2026-06-02_сессионные_homeserver_в_pda.md` - несколько homeserver-ов пользователя как типизированные сессии в PDA с версией записи. -- `medium/2026-06-03_подключение_других_устройств_через_qr.md` - довести подключение других устройств через QR: сейчас заготовка есть, но сценарий работает нестабильно и его нужно будет отдельно доделать. -- `medium/2026-08-09_esp32_переход_на_sendsignal_и_client_key.md` - перевести ESP32 и wallet-extension на единый `SendSignal`, обязательный `client key` и подготовить почву для будущего E2E-шифрования payload. -- `medium/2026-07-22_переход_с_sqlite_на_postgresql.md` - завершить зачистку хвостов после перевода серверной БД с `SQLite` на `PostgreSQL`. - -### dao_запуск - -- `dao_запуск/2026-06-05_esp32_hardware_wallet_device_session.md` - ESP32 как аппаратный кошелёк: постоянная device-сессия на сервере, подтверждение операций на экране, делегированные сессии для браузера/телефона. - -### far - -- `far/2026-06-20_1639_homeserver_technical_commands_and_file_transfer.md` - технические команды для homeserver через SHiNE/WebRTC DataChannel и обмен файлами по чанкам с адресацией по `SHA-256`. diff --git a/TODO/far/2026-06-20_1639_homeserver_technical_commands_and_file_transfer.md b/TODO/far/2026-06-20_1639_homeserver_technical_commands_and_file_transfer.md deleted file mode 100644 index 3b328cb8..00000000 --- a/TODO/far/2026-06-20_1639_homeserver_technical_commands_and_file_transfer.md +++ /dev/null @@ -1,114 +0,0 @@ -# Homeserver: технические команды и передача файлов через SHiNE/WebRTC - -## Зачем нужна фича - -Идея на дальнее будущее: дать возможность обращаться к homeserver не только как к участнику сети SHiNE, но и как к удалённой технической точке управления. - -Цели: -- отправлять на homeserver технические команды в текстовом виде; -- получать текстовый ответ на команду; -- при наличии WebRTC DataChannel передавать части файлов в обе стороны; -- хранить полученные файлы на SD-карте homeserver; -- использовать единый механизм доставки как через сервер SHiNE, так и напрямую через DataChannel. - -## Горизонт - -`far` - идея без ближайшего срока реализации. Сейчас приоритет ниже, чем запуск и стабилизация основного проекта. - -## Что именно имеется в виду - -### 1. Единая модель технической команды - -Техническая команда должна иметь единый смысл независимо от транспорта доставки: -- через любой доступный сервер SHiNE; -- через уже установленный WebRTC DataChannel. - -Если конкретный транспорт недоступен, ответ по нему может не прийти. Это считается нормальным поведением протокола. - -### 2. Команда как короткоживущий подписанный сигнал - -У команды должны быть: -- `commandId`; -- временная метка; -- TTL около 10 секунд; -- криптографическая подпись. - -Смысл такой: -- если команда быстро дошла, homeserver подтверждает принятие; -- если не дошла вовремя, команда считается протухшей; -- отправитель может безопасно послать повтор; -- при повторе homeserver отвечает либо `команда принята`, либо `уже выполнено ранее`. - -Это даёт дедупликацию и безопасный resend без повторного выполнения действия. - -### 3. Текстовые технические команды - -Базовый сценарий похож на короткий удалённый shell-протокол, но на уровне строго ограниченных команд: -- отправил строку-команду; -- получил строку-ответ. - -Команды не обязаны исполнять произвольный shell. Предпочтительная модель - белый список операций с контролируемым форматом аргументов и ответа. - -### 4. Передача файлов только при наличии DataChannel - -Если между устройствами есть WebRTC DataChannel, через него можно передавать технические сообщения для файлового обмена. - -Предварительная модель: -- имя файла = `SHA-256` содержимого; -- можно запросить диапазон байт `from..to`; -- можно отправить диапазон байт `from..to`; -- homeserver хранит полученные данные на SD-карте; -- если DataChannel нет, на запрос файловой передачи возвращается ответ в духе `не могу передать, нет data channel`. - -Фактически файл-обмен должен быть частным случаем общего протокола технических команд. - -### 5. Установка data-соединения по явной команде - -Нужна техническая команда уровня: -- `установить data-соединение`. - -Ответ: -- либо `да`, после чего запускается обычная процедура `offer/answer/ICE`; -- либо `нет` и причина отказа. - -### 6. Доставка на пользовательские сессии - -Логика должна быть совместима с общей моделью SHiNE, где технические сигналы можно отправлять на конкретные активные сессии пользователя. - -Идея: -- на любую активную сессию пользователя можно посылать техническую команду; -- контакт пользователя может инициировать такую техническую коммуникацию так же, как он уже инициирует звонок или другой служебный сигнал. - -## Что нужно будет сделать при возврате к задаче - -- Спроектировать отдельный формат технических команд и ack-ответов. -- Решить, будет ли это новый тип служебных сообщений в существующем протоколе блокчейн/сигналинга или отдельная ветка поверх уже имеющихся transport-операций. -- Отдельно продумать авторизацию: кто именно из контактов и какие команды имеет право слать. -- Ограничить набор допустимых команд, чтобы не превратить механизм в небезопасный удалённый shell. -- Спроектировать протокол чанков файлов: размер чанка, нумерация, повторная отправка, контроль целостности, дозагрузка, завершение файла. -- Продумать хранение на SD-карте: временные файлы, сборка чанков, проверка итогового `SHA-256`, очистка мусора. -- Продумать поведение при отсутствии DataChannel, таймаутах и дублирующихся командах. -- Проверить, как это лучше встраивать в текущие клиентские сессии, звонки и homeserver-логику. - -## Вопросы для будущего уточнения - -- Это должен быть строго служебный протокол или пользователь сможет вызывать его и вручную из UI. -- Нужен ли доступ только к заранее разрешённым каталогам/файлам. -- Нужна ли двусторонняя синхронизация файлов или достаточно ручных команд `запросить кусок` / `отправить кусок`. -- Нужно ли разрешать передачу файлов через сервер SHiNE как fallback, или файл-обмен должен идти только через DataChannel. -- Какой максимальный размер файлов и допустимый объём хранения на SD-карте. - -## Что уже сделано - -Пока только зафиксирована идея и базовая концепция. Реализация не начиналась. - -## Какие документы нужно будет обновить при реализации - -- `docs/Blockchain/README.md` и связанные файлы, если изменятся типы служебных сообщений или форматы блокчейн-команд. -- `docs/API/` если изменится публичный серверный API или появятся новые операции. -- `docs/Personal_Messages/Протокол_DM_v1.md` если часть маршрутизации или подтверждений будет встроена в существующую логику доставки/сессий. -- Документацию по homeserver/ESP32, если появится пользовательская или сервисная файловая логика на устройстве. - -## С какого места продолжать позже - -Возвращаться к задаче только после стабилизации запуска проекта и базовых текущих функций. Начинать с проектирования протокола команд и матрицы прав доступа, а уже потом переходить к DataChannel-файлообмену. diff --git a/TODO/medium/2026-05-25_1106_shine_balance_wallet.md b/TODO/medium/2026-05-25_1106_shine_balance_wallet.md deleted file mode 100644 index cb735c8b..00000000 --- a/TODO/medium/2026-05-25_1106_shine_balance_wallet.md +++ /dev/null @@ -1,62 +0,0 @@ -# Кошелёк и пополнение баланса сияния - -- Горизонт: - `medium` -- Ориентир: - среднесрочно -- Статус: - `proposal` - -## Кратко - -Нужно добавить кошелёк для внутреннего баланса сияния и пополнение этого баланса через блокчейн-логику проекта. Задача связана с регистрацией пользователя и будущим учётом баланса. - -## Предполагаемый сценарий - -1. Пользователь регистрируется и получает/подключает нужные кошельки. -2. В интерфейсе появляется баланс сияния. -3. Пользователь открывает пополнение баланса сияния. -4. Система создаёт или принимает блокчейн-операцию пополнения. -5. После подтверждения баланса UI обновляет значение. - -## Что нужно продумать - -1. Что именно является единицей баланса сияния. -2. Где хранится состояние баланса: в существующем блокчейне SHiNE, Solana-модуле или комбинированно. -3. Какая операция отвечает за пополнение. -4. Нужно ли делать отдельную регистрацию кошелька сияния или использовать существующую регистрацию пользователя. -5. Как баланс восстанавливается после перезагрузки клиента. -6. Какие права нужны для пополнения и списания. -7. Нужна ли история операций баланса. - -## Вопросы перед реализацией - -1. Пополнение баланса сияния должно идти через основной блокчейн SHiNE или через Solana-программу. -2. Нужна ли конвертация из SOL/AR в сияние. -3. Кто может выпускать или начислять сияние. -4. Нужно ли поддерживать перевод сияния между пользователями. -5. Нужны ли лимиты, комиссии или статусы подтверждения. -6. Какой экран должен показывать баланс: регистрация, профиль, кошелёк или отдельная страница. -7. Нужно ли отображать неподтверждённый баланс отдельно от подтверждённого. - -## Важное ограничение - -Если для баланса сияния потребуется новый формат блокчейн-блока или изменение существующего формата, перед реализацией нужно отдельно предупредить пользователя и получить явное подтверждение на изменение формата блокчейна. - -Если потребуется новый серверный API или изменение существующих `op`, перед реализацией нужно отдельно предупредить пользователя и получить явное подтверждение на изменение API. - -## Документы, которые обновить при реализации - -- `docs/Blockchain/`, если появятся или изменятся блоки баланса. -- `docs/Blockchain/CHANGELOG.md`, если меняется блокчейн-формат. -- `docs/API/`, если меняется серверный API. -- после реализации отдельно согласовать ручную проверку. -- Документацию Solana-регистрации, если баланс будет связан с Solana-модулем. - -## Минимальная проверка в будущем - -1. Новый пользователь видит корректный начальный баланс. -2. Пополнение создаёт правильную операцию. -3. Баланс обновляется после подтверждения. -4. После перезагрузки UI баланс остаётся корректным. -5. Ошибочные или повторные операции не начисляют баланс дважды. diff --git a/TODO/medium/2026-05-26_0029_esp32s3_file_storage.md b/TODO/medium/2026-05-26_0029_esp32s3_file_storage.md deleted file mode 100644 index a9b7f457..00000000 --- a/TODO/medium/2026-05-26_0029_esp32s3_file_storage.md +++ /dev/null @@ -1,44 +0,0 @@ -# ESP32S3 как личное файловое хранилище SHiNE - -## Горизонт - -Среднесрочный: ближайшие недели или 1-2 месяца. - -## Зачем нужна фича - -Нужно проработать маленький физический сервер на ESP32S3 как персональное или доверенное файловое хранилище SHiNE. - -Идея: при обмене сообщениями пользователи смогут использовать такой сервер для хранения своих файлов, вложений, файлов общих переписок и связанных данных. - -## Что нужно сделать - -- Описать роль ESP32S3-сервера в общей архитектуре ключей и сессий. -- Определить, какие ключи может хранить такое устройство. -- Решить, хранит ли устройство только файлы или также подписывает пользовательские операции. -- Описать протокол загрузки, скачивания и удаления файлов. -- Определить правила шифрования файлов до отправки на устройство. -- Продумать индексацию файлов для личных и общих переписок. -- Решить, как устройство авторизуется на основном сервере SHiNE. - -## Вопросы перед реализацией - -- ESP32S3 должен работать как полностью локальное устройство или как публично доступный мини-сервер? -- Нужен ли внешний relay, если устройство находится за NAT? -- Какие ограничения по размеру файла считаем допустимыми? -- Хранит ли устройство метаданные переписок или только зашифрованные blob-файлы? -- Как восстанавливать доступ, если устройство потеряно или заменено? - -## Что уже сделано - -Код не реализован. Идея зафиксирована как будущая задача после описания модели ключей. - -## Документы, которые нужно обновить при возврате - -- `docs/Keys/README.md` -- `docs/Personal_Messages/Протокол_DM_v1.md` -- `docs/API/` -- `docs/Blockchain/`, если появятся новые блоки или команды для файлов. - -## С какого места продолжать - -Начать с короткого протокольного документа: роли устройства, авторизация, шифрование файлов, минимальные API-операции и сценарии восстановления. diff --git a/TODO/medium/2026-06-02_сессионные_homeserver_в_pda.md b/TODO/medium/2026-06-02_сессионные_homeserver_в_pda.md deleted file mode 100644 index 4b1af4c2..00000000 --- a/TODO/medium/2026-06-02_сессионные_homeserver_в_pda.md +++ /dev/null @@ -1,105 +0,0 @@ -# Сессионные homeserver-ы в PDA пользователя - -- Статус: - `future` - -- Горизонт: - `medium` - -- Ориентир: - после завершения первого этапа по пользовательским сессиям - -- Основание: - Идея зафиксирована после обсуждения архитектуры пользовательских сессий и внутренних homeserver-ов. Сейчас задача сознательно отложена: сначала нужно аккуратно ввести базовую модель сессий, а затем возвращаться к расширенной серверной роли. - -## Зачем нужна фича - -У одного пользователя может быть несколько доверенных внутренних homeserver-ов, и каждый из них должен жить как отдельная пользовательская сессия, а не как отдельная особая сущность вне общей модели. - -Это нужно, чтобы: - -- хранить несколько homeserver-ов у одного пользователя одновременно; -- различать обычные клиентские сессии и серверные сессии по явному типу; -- дать расширяемый формат записи с версией; -- использовать единый подход для DM, звонков и внутренних команд между сессиями. - -## Целевая идея - -В пользовательском PDA должен появиться список записей сессий, где каждая запись содержит как минимум: - -- `sessionType` (`u8`); -- `sessionVersion` (`u8`); -- `sessionName`; -- `sessionPubKey`. - -Предварительные значения: - -- тип `1` - обычная пользовательская сессия; -- тип `100` - homeserver пользователя; -- версия `1` - первая рабочая версия формата записи сессии. - -На текущем этапе под это уже зарезервирован отдельный блок `SessionsBlock` с `block_type = 55`, а `TrustedStateBlock` остаётся на `50`. - -Важно: homeserver-ов у одного пользователя может быть несколько. - -## Архитектурный принцип - -Внутренний протокол взаимодействия должен оставаться транспортным. - -То есть SHiNE-сервер не должен разбирать прикладной смысл внутренней нагрузки homeserver-а, а должен: - -- доставлять сообщения между сессиями; -- доставлять сигналы звонков между сессиями; -- хранить и маршрутизировать адресацию; -- не принимать на себя бизнес-логику содержимого внутренних команд. - -## Что уже подтверждается текущим кодом - -- Личные сообщения уже доставляются по всем сессиям целевого пользователя с отдельным учётом доставки на каждую сессию. -- Подтверждение доставки DM уже идёт отдельно по каждой сессии. -- Вызов звонка уже рассылается по нескольким активным сессиям пользователя. -- Сигналы звонка уже адресуются конкретной сессии, а stop-сигналы дублируются на остальные сессии того же пользователя. - -Иными словами, текущая серверная логика ближе к модели "сервер доставляет между сессиями", чем к модели "сервер понимает внутренний протокол homeserver-а". - -## Что нужно сделать при возврате к задаче - -1. Согласовать финальный бинарный формат записи сессии в PDA пользователя. -2. Проверить, не меняет ли это уже опубликованный формат пользовательской PDA-записи. -3. Если формат PDA меняется, заранее предупредить пользователя и получить отдельное подтверждение. -4. Решить, где именно хранится массив сессий: - - в основной записи пользователя; - - в отдельной PDA-структуре расширения; - - или в смешанной схеме с базовой записью и внешними индексами. -5. Зафиксировать ограничения: - - максимальное число сессий; - - максимальную длину `sessionName`; - - правила удаления и обновления записи; - - правила ротации `sessionPubKey`. -6. Продумать, как UI и сервер будут отличать тип `1` и тип `100`. -7. Определить, какие внутренние сообщения homeserver-а останутся полностью прозрачными для SHiNE-сервера, а какие потребуют только технической маршрутизации. -8. Добавить API/операции чтения и обновления списка сессий, если для этого не хватит существующих механизмов. -9. После реализации обязательно обновить документацию. - -## Что нужно обновить при реализации - -- `shine-solana/shine/doc/formats/shine-user-pda-format-v.1.0.md` -- `docs/Solana_Architecture/README.md` -- `docs/Инициализация_Solana_регистрации/README.md` -- `docs/Keys/README.md` -- `docs/Personal_Messages/Протокол_DM_v1.md`, если изменится адресация DM по типам сессий -- `docs/API/`, если появятся новые серверные операции или изменятся ответы - -## Что пока не делать - -- Не включать это автоматически в основной deploy сервера. -- Не менять сейчас Solana PDA-формат без отдельного подтверждения. -- Не добавлять временные поля в публичный API "на всякий случай". - -## С какого места продолжать - -Продолжать после завершения первой части: - -1. описать минимальный формат записи пользовательской сессии; -2. отдельно решить, живут ли homeserver-ы в том же списке, что и обычные сессии; -3. затем уже проектировать операции регистрации, обновления и отключения таких сессий. diff --git a/TODO/medium/2026-06-03_подключение_других_устройств_через_qr.md b/TODO/medium/2026-06-03_подключение_других_устройств_через_qr.md deleted file mode 100644 index 12d561b6..00000000 --- a/TODO/medium/2026-06-03_подключение_других_устройств_через_qr.md +++ /dev/null @@ -1,44 +0,0 @@ -# Подключение других устройств через QR - -- Горизонт: - `medium` -- Ориентир: - позже, не сейчас -- Статус: - `future` - -## Зачем нужна фича - -Нужно нормально довести подключение другого устройства через QR-код. Сейчас есть полуготовая заготовка, но сценарий работает нестабильно и требует отдельной доработки. - -## Что уже есть - -- В UI уже есть экраны: - - `shine-UI/js/pages/connect-device-view.js` - - `shine-UI/js/pages/device-qr-view.js` -- Есть сервис переноса ключей через QR: - - `shine-UI/js/services/qr-key-transfer-service.js` -- Логика частично собрана, но её нельзя считать завершённой или надёжной. - -## Что нужно будет сделать потом - -1. Проверить и довести формат QR-передачи. -2. Проверить сканирование и ручной ввод QR-текста. -3. Проверить перенос `device`, `blockchain`, `root` ключей только по реальному наличию на исходном устройстве. -4. Проверить, что после переноса очищается старая история нужного логина и не ломается вход. -5. Отдельно проверить сценарий без `BarcodeDetector`. -6. Довести экран подтверждения на втором устройстве. - -## Что сейчас важно - -- Не считать эту часть готовой. -- Не возвращать её в активную разработку без отдельной команды пользователя. -- Если вернёмся к задаче, сначала нужно понять, что именно уже работает, а что нет, и потом починить целиком. - -## Что обновить при возврате - -- после реализации отдельно согласовать ручную проверку -- `shine-UI/js/pages/connect-device-view.js` -- `shine-UI/js/pages/device-qr-view.js` -- `shine-UI/js/services/qr-key-transfer-service.js` -- документацию по ключам, если формат переноса меняется diff --git a/TODO/medium/2026-06-28_send_signal_перенос_старых_сигналов.md b/TODO/medium/2026-06-28_send_signal_перенос_старых_сигналов.md deleted file mode 100644 index 2f695b6e..00000000 --- a/TODO/medium/2026-06-28_send_signal_перенос_старых_сигналов.md +++ /dev/null @@ -1,29 +0,0 @@ -# Перенести старые сессионные сигналы на `SendSignal` - -## Контекст - -В проект добавлен новый общий межсессионный transport `SendSignal`. - -Первое текущее применение: - -- `remote AddBlock via homeserver session` - -Старые сценарии пока оставлены на прежнем транспорте, чтобы не ломать уже работающий код. - -## Что перенести позже - -1. Звонковые сигналы, которые сейчас идут через `CallSignalToSession`. -2. Старый wallet/ESP32 обмен, где технические команды всё ещё привязаны к call-like транспорту. -3. Остальные доверенные межсессионные команды одного пользователя. - -## Что важно учесть при переносе - -- не ломать обратную совместимость работающих звонков; -- сохранить текущую маршрутизацию по `sessionId`; -- договориться о едином `signalType`; -- отдельно описать миграцию клиентских обработчиков событий: - - `IncomingCallSignal` -> `IncomingSignal` - -## С какого сценария продолжать - -Начинать перенос со звонков, но только после отдельной ручной проверки того, что `SendSignal` стабильно отработал на `remote AddBlock`. diff --git a/TODO/medium/2026-07-22_переход_с_sqlite_на_postgresql.md b/TODO/medium/2026-07-22_переход_с_sqlite_на_postgresql.md deleted file mode 100644 index 72c097a1..00000000 --- a/TODO/medium/2026-07-22_переход_с_sqlite_на_postgresql.md +++ /dev/null @@ -1,57 +0,0 @@ -# Переход с SQLite на PostgreSQL - -## Зачем - -Переход runtime-сервера на `PostgreSQL` уже выполнен, но после него остались хвосты в документации, именах, комментариях и части прямых SQL-запросов. - -Этот TODO теперь нужен не для самого перехода, а для доведения проекта до полностью консистентного состояния после ухода от `SQLite`. - -## Что сделать - -- Дочистить документацию, где ещё описан `SQLite` как текущий runtime. -- Убрать или переименовать legacy-названия и комментарии, которые уже не соответствуют PostgreSQL runtime. -- Постепенно перенести оставшиеся прямые SQL-запросы из хэндлеров в DAO/service. -- Проверить case-insensitive сравнения, уникальные ограничения и индексы уже в чисто PostgreSQL модели. -- Отдельно пройтись по TODO/служебным документам и убрать ссылки на удалённые SQLite-классы как на актуальный код. - -## Что уже есть в коде - -- Доступ к БД в основном проходит через DAO-слой, а не полностью размазан по проекту. -- Основная серверная логика уже разделена по модулям. -- Runtime-сервер уже работает только с `PostgreSQL`. -- Пустая БД инициализируется автоматически через `schema_v1`. - -## Откуда продолжать - -- Продолжать с зачистки legacy-документации и комментариев. -- Затем добрать оставшиеся прямые SQL-запросы вне DAO. -- После этого можно отдельно решать вопрос косметического переименования `*V2`, `DbController` и других переходных сущностей. - -## Что потом обновить - -- Серверную документацию по БД и миграциям. -- Инструкции по локальному запуску сервера. -- Скрипты деплоя и настройки окружения. - -## Что временно отключено и что вернуть потом - -- В серверном runtime временно снята проверка `channelName must not contain only digits` - в `SHiNE-server/shine-server-db/src/main/java/shine/db/channels/ChannelNameRules.java`. -- Причина: на боевой истории уже есть блоки с числовыми именами каналов, и сервер - должен уметь с нуля восстановить `blockchain_state` и `.bch`, подтягивая старые - блоки от других sync-серверов. -- Что осталось как текущее поведение: - - UI по-прежнему не даёт создать новый канал только из цифр; - - сервер принимает такие имена, чтобы не ломать replay старых блоков. -- Что нужно сделать отдельным следующим шагом: - - вернуть серверное продуктовое правило для новых каналов; - - сделать это совместимо со старой историей, чтобы импорт/реплей существующих - блоков не падал на старых числовых channel name. -- Какие документы обновить при возврате: - - `docs/libs/shine-server-bd/POSTGRES_RUNTIME_SCHEMA_V1.md`; - - UI/серверные документы по правилам имён каналов, если появится отдельная спецификация. -- С какого сценария продолжать: - - повторить cold start тест на `t2`: пустая PostgreSQL schema, удалённые `.bch`, - новый запуск, ожидание полной синхронизации от `t1`/`t3`. -- Последняя полная рабочая точка с этим временным компромиссом: - - ветка `migration-postgres`, коммит будет создан после этой записи. diff --git a/TODO/near/2026-05-25_1106_wallet_topup_solana_arweave.md b/TODO/near/2026-05-25_1106_wallet_topup_solana_arweave.md deleted file mode 100644 index 4de664eb..00000000 --- a/TODO/near/2026-05-25_1106_wallet_topup_solana_arweave.md +++ /dev/null @@ -1,71 +0,0 @@ -# Пополнение Solana и Arweave через внешний сервис покупки - -- Горизонт: - `near` -- Ориентир: - сегодня/завтра -- Статус: - `proposal` - -## Кратко - -Нужно добавить удобное пополнение кошельков на экране регистрации/кошелька: для Solana и Arweave дать отдельные действия `Пополнить`, которые ведут на международный сервис покупки криптовалюты с карты и помогают пользователю скопировать адрес кошелька. - -## Пользовательский сценарий - -1. Пользователь видит адрес кошелька Solana или Arweave. -2. Нажимает `Пополнить`. -3. Открывается промежуточное окно с инструкцией: - - сейчас пользователь перейдёт на страницу покупки/пополнения; - - нужно указать или проверить адрес кошелька; - - после оплаты нужно закрыть внешнюю страницу и вернуться назад; - - Solana обычно приходит быстро, ориентир 10-15 секунд после подтверждения сети; - - Arweave может идти дольше, точное время нужно уточнить по выбранному сервису. -4. В окне есть кнопки: - - `Скопировать адрес и перейти`; - - `Перейти без копирования`. -5. Для Solana и Arweave используются разные окна/инструкции и, возможно, разные внешние ссылки. - -## Что нужно сделать - -1. Найти текущий экран, где показываются кошельки при регистрации и пополнении. -2. Найти текущую ссылку покупки Arweave, если она уже есть в UI. -3. Выбрать международный сервис покупки Solana с карты, не российский. -4. Проверить, поддерживает ли сервис deep link с предзаполненным адресом кошелька. -5. Если deep link невозможен, реализовать промежуточное окно с копированием адреса. -6. Добавить отдельные действия для Solana и Arweave. -7. Сделать текст инструкции коротким и понятным. -8. Проверить, что адрес копируется в буфер обмена в браузере. -9. Проверить мобильный сценарий и desktop-сценарий. - -## Вопросы перед реализацией - -1. Какой сервис покупки Solana использовать: тот же провайдер, что для Arweave, или другой международный on-ramp. -2. Нужно ли разрешать покупку только SOL или также USDC/SPL-токены на Solana. -3. Где именно показывать кнопку `Пополнить`: только регистрация, настройки кошелька или оба места. -4. Нужно ли показывать предупреждение о комиссиях и стороннем сервисе. -5. Нужно ли открывать внешнюю страницу в новой вкладке или в текущем окне. -6. Нужно ли логировать факт нажатия `Пополнить` на сервере. -7. Какой точный текст использовать для времени прихода Arweave. - -## Риски и ограничения - -- On-ramp-сервисы меняют ссылки и параметры, поэтому deep link нужно проверять перед реализацией. -- Clipboard API может требовать HTTPS и пользовательский жест. -- Нельзя обещать точное время поступления средств: лучше писать ориентир и зависимость от сети/провайдера. -- Внешний сервис может быть недоступен в отдельных странах или для отдельных карт. - -## Документы, которые обновить при реализации - -- Документацию UI/кошельков, если такая есть. -- после реализации отдельно согласовать ручную проверку. -- `docs/API/`, только если появится новый серверный API или логирование. - -## Минимальная проверка - -1. На Solana-кошельке открывается правильное окно пополнения. -2. Кнопка `Скопировать адрес и перейти` копирует Solana-адрес и открывает внешний сервис. -3. Кнопка `Перейти без копирования` открывает внешний сервис без копирования. -4. Аналогичный сценарий работает для Arweave. -5. На мобильном экране текст и кнопки не перекрываются. -6. Возврат назад в приложение не ломает состояние регистрации/кошелька. diff --git a/TODO/near/2026-07-07_дм_v11_убрать_временную_очистку_signed_messages.md b/TODO/near/2026-07-07_дм_v11_убрать_временную_очистку_signed_messages.md deleted file mode 100644 index 2b04642a..00000000 --- a/TODO/near/2026-07-07_дм_v11_убрать_временную_очистку_signed_messages.md +++ /dev/null @@ -1,33 +0,0 @@ -# Убрать временную очистку `signed_messages_v2` в миграции БД v11 - -## Зачем это нужно - -При переходе на новый DM-протокол `SHiNE_DM v1` была добавлена временная миграция БД `v11`, которая при первом старте на старой базе полностью очищает: - -- `signed_messages_v2` -- `signed_message_session_delivery` - -Это сделано как защитный reset, потому что старые DM-строки и backlog могли быть несовместимы с новым форматом, новой логикой tombstone и новым клиентским E2EE-разбором. - -## Что именно потом сделать - -- найти историческое место, где была добавлена временная миграция `migrateToV11()`, и убрать её остатки из runtime-логики/документации; -- удалить helper `clearLegacySignedMessagesForDmV11(...)`; -- поднять версию схемы дальше обычным образом уже без destructive-cleanup; -- при необходимости заменить это на нормальную точечную миграцию старых DM-записей или совсем убрать поддержку старой истории. - -## Что уже есть в коде - -- `LATEST_SCHEMA_VERSION = 11`; -- при миграции в `v11` выполняется полная очистка DM-таблиц; -- в коде прямо оставлен комментарий, что это временная мера. - -## Откуда продолжать - -Продолжать от коммита, в котором была добавлена миграция `v11` для очистки DM-таблиц после перехода на `SHiNE_DM v1`. - -## Какие документы потом обновить - -- `docs/Personal_Messages/Протокол_DM_v1.md`, если изменится стратегия миграции старой истории; -- `docs/Personal_Messages/Формат_DM_v1.md`, если появится отдельное правило совместимости/конвертации; -- при необходимости `docs/API/12_Direct_Messages_Push_Calls_API.md`, если затронется поведение backlog/доставки. diff --git a/TODO/medium/2026-08-09_esp32_переход_на_sendsignal_и_client_key.md b/TODO/Близкое/ESP32/В_клшельке_и_esp32_переделать_на_sendsignal_и_client_key.md similarity index 100% rename from TODO/medium/2026-08-09_esp32_переход_на_sendsignal_и_client_key.md rename to TODO/Близкое/ESP32/В_клшельке_и_esp32_переделать_на_sendsignal_и_client_key.md diff --git a/TODO/near/2026-07-01_2205_восстановить_полную_логику_shine_login_guard.md b/TODO/Близкое/Solana_смарт_контракты/Восстановить_полную_логику_shine_login_guard.md similarity index 98% rename from TODO/near/2026-07-01_2205_восстановить_полную_логику_shine_login_guard.md rename to TODO/Близкое/Solana_смарт_контракты/Восстановить_полную_логику_shine_login_guard.md index 70f6d862..283d410d 100644 --- a/TODO/near/2026-07-01_2205_восстановить_полную_логику_shine_login_guard.md +++ b/TODO/Близкое/Solana_смарт_контракты/Восстановить_полную_логику_shine_login_guard.md @@ -1,5 +1,13 @@ # Восстановить полную логику `shine_login_guard` + +Тоесть сделать что бы нормально проверялись логины пользователей + + + + + + Статус: отложено. ## Зачем это нужно diff --git a/TODO/Близкое/Solana_смарт_контракты/Навести_порядок_с_адремаси_програм_и_счетов_в_Солане.md b/TODO/Близкое/Solana_смарт_контракты/Навести_порядок_с_адремаси_програм_и_счетов_в_Солане.md new file mode 100644 index 00000000..473a0f4c diff --git a/TODO/Близкое/Solana_смарт_контракты/Передать_все_права_обновления_ДАО_И_сделат_сервиспроверки_актуальных_голосований_в_ДАО.md b/TODO/Близкое/Solana_смарт_контракты/Передать_все_права_обновления_ДАО_И_сделат_сервиспроверки_актуальных_голосований_в_ДАО.md new file mode 100644 index 00000000..473a0f4c diff --git a/TODO/Близкое/Solana_смарт_контракты/Сделать_полноценные_инвестиционные_инструменты.md b/TODO/Близкое/Solana_смарт_контракты/Сделать_полноценные_инвестиционные_инструменты.md new file mode 100644 index 00000000..3b475e87 --- /dev/null +++ b/TODO/Близкое/Solana_смарт_контракты/Сделать_полноценные_инвестиционные_инструменты.md @@ -0,0 +1 @@ +Передачу билетов владельцами со счёта на счёт diff --git a/TODO/Децентрализация/ИТХ/README.md b/TODO/Близкое/Децентрализация/ИТХ/README.md similarity index 100% rename from TODO/Децентрализация/ИТХ/README.md rename to TODO/Близкое/Децентрализация/ИТХ/README.md diff --git a/TODO/Децентрализация/ИТХ/Спецификация_ИТХ_v1.md b/TODO/Близкое/Децентрализация/ИТХ/Спецификация_ИТХ_v1.md similarity index 100% rename from TODO/Децентрализация/ИТХ/Спецификация_ИТХ_v1.md rename to TODO/Близкое/Децентрализация/ИТХ/Спецификация_ИТХ_v1.md diff --git a/TODO/Близкое/Еовести порядок с кошельками и отображением баланса_ тот минимум что нужен для работы сияния.md b/TODO/Близкое/Еовести порядок с кошельками и отображением баланса_ тот минимум что нужен для работы сияния.md new file mode 100644 index 00000000..473a0f4c diff --git a/TODO/Близкое/Сделать поддержку нескольких залогиненных аккаунтов враз.md b/TODO/Близкое/Сделать поддержку нескольких залогиненных аккаунтов враз.md new file mode 100644 index 00000000..473a0f4c diff --git a/TODO/2026-06-26_1800_корректное_завершение_за_30с.md b/TODO/Близкое/Сделать_возможность_корректного_завершения_работы_сервера_за_30с_чтобы_все_задачи_доделались.md similarity index 74% rename from TODO/2026-06-26_1800_корректное_завершение_за_30с.md rename to TODO/Близкое/Сделать_возможность_корректного_завершения_работы_сервера_за_30с_чтобы_все_задачи_доделались.md index c525498b..da6a618a 100644 --- a/TODO/2026-06-26_1800_корректное_завершение_за_30с.md +++ b/TODO/Близкое/Сделать_возможность_корректного_завершения_работы_сервера_за_30с_чтобы_все_задачи_доделались.md @@ -27,13 +27,3 @@ - `BlockchainTmpRecoveryOnStartup` и `BlockchainResyncRecoveryOnStartup` уже умеют добирать незавершённые хвосты после старта. - `AddBlock` уже стал crash-safe через `tmp_bch` / `write_check` / `write_pending`. - -## Откуда продолжать - -- начать с `systemd`-юнита и базового shutdown-hook в сервере; -- затем проверить, что текущие операции реально завершаются в отведённые 30 секунд. - -## Какие документы потом обновить - -- `deploy/`; -- `docs/Blockchain/sync-between-servers.md`, если изменится поведение остановки/восстановления. diff --git a/TODO/Близкое/Убрать разные тестовые штуки для звонков и сделать отправку ошибки на сервер.md b/TODO/Близкое/Убрать разные тестовые штуки для звонков и сделать отправку ошибки на сервер.md new file mode 100644 index 00000000..473a0f4c diff --git a/TODO/medium/2026-05-24_1140_репосты_в_каналах_и_тредах.md b/TODO/В_отдалённом_Будущем/В будущем_сделать_репосты_в_каналах_и_тредах.md similarity index 100% rename from TODO/medium/2026-05-24_1140_репосты_в_каналах_и_тредах.md rename to TODO/В_отдалённом_Будущем/В будущем_сделать_репосты_в_каналах_и_тредах.md diff --git a/TODO/В_отдалённом_Будущем/ДЦ_личную_переписку_дороботать_для_максимальной_надёжности.md b/TODO/В_отдалённом_Будущем/ДЦ_личную_переписку_дороботать_для_максимальной_надёжности.md new file mode 100644 index 00000000..473a0f4c diff --git a/TODO/В_отдалённом_Будущем/Предложения_к_рассмотрению_в_будущее/Как_вариант_можно_сделать_hameserver_как_хранилище_файлов_пользователя.md b/TODO/В_отдалённом_Будущем/Предложения_к_рассмотрению_в_будущее/Как_вариант_можно_сделать_hameserver_как_хранилище_файлов_пользователя.md new file mode 100644 index 00000000..ddfd59ee --- /dev/null +++ b/TODO/В_отдалённом_Будущем/Предложения_к_рассмотрению_в_будущее/Как_вариант_можно_сделать_hameserver_как_хранилище_файлов_пользователя.md @@ -0,0 +1,5 @@ +Как_вариант_можно_сделать_hameserver_как_хранилище_файлов_пользователя +И всё это можно сделать внутри ESP32 + +Хотя не понятно надо ли так делать - потому что вроде удобно, +но тем не менее и сложно как то объяснить такой функционал людям diff --git a/TODO/Децентрализация/2026-06-26_1805_межсерверный_ws_и_dm_sync.md b/TODO/Децентрализация/2026-06-26_1805_межсерверный_ws_и_dm_sync.md deleted file mode 100644 index 362db242..00000000 --- a/TODO/Децентрализация/2026-06-26_1805_межсерверный_ws_и_dm_sync.md +++ /dev/null @@ -1,43 +0,0 @@ -# Постоянный server-to-server WS и DM sync - -## Зачем - -Текущий production-режим SHiNE рассчитан на один основной сервер. Межсерверная синхронизация относится к будущей децентрализации и не должна блокировать выкладку односерверной production-версии. - -Сейчас синхронизация между серверами работает в основном как periodic sync и one-shot push. Для нормальной репликации в будущем ещё нужен постоянный межсерверный канал: - -- живое подключение к партнёру; -- push новых блоков; -- push DM; -- ACK на доставку; -- backoff/reconnect; -- стартовый backfill. - -## Что сделать - -1. Поднять постоянное WebSocket-соединение между партнёрскими серверами. -2. Сделать push новых блоков сразу после `AddBlock`. -3. Сделать push DM-блоков между серверами. -4. Добавить ACK и повторную отправку при сбое. -5. Ввести стартовый обмен курсорами и добор хвоста. - -## Что уже есть - -- `ListBlockchainHeads`; -- `GetBlockchainBlock`; -- `GetSyncUserProfile`; -- базовый periodic sync; -- базовый backfill хвоста; -- базовый full resync при divergence. - -## Откуда продолжать - -- от текущего `sync_servers` bootstrap и `PeriodicBlockchainSyncService`; -- дальше выделить отдельный межсерверный transport layer. - -## Какие документы потом обновить - -- `docs/Blockchain/sync-between-servers.md`; -- `docs/Personal_Messages/Протокол_DM_v1.md`; -- `docs/Personal_Messages/Формат_DM_v1.md`; -- `docs/API/`. diff --git a/TODO/Децентрализация/README.md b/TODO/Децентрализация/README.md deleted file mode 100644 index 2236815c..00000000 --- a/TODO/Децентрализация/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# Децентрализация - -Папка для задач, которые нужны для будущего режима с несколькими серверами, Solana/PDA-синхронизацией и внешним хранением данных. - -## Текущий статус - -Сейчас production-режим SHiNE считается односерверным: один сервер обслуживает пользователей, сообщения, звонки и запись данных. Задачи из этой папки не являются блокерами для выкладки текущего репозитория на GitHub и запуска одного production-сервера. - -## Задачи - -- `односерверный_production_режим.md` - зафиксировать границы текущей production-версии. -- `запись_блокчейнов_в_arweave.md` - вынести долговременную запись блокчейнов в Arweave. -- `realtime_pda_solana_sync.md` - сделать онлайн-синхронизацию PDA/Solana в реальном времени. -- `межсерверная_передача_сообщений.md` - реализовать доставку сообщений между серверами. -- `межсерверные_звонки.md` - реализовать маршрутизацию звонков между серверами. -- `2026-06-26_1805_межсерверный_ws_и_dm_sync.md` - старый план постоянного server-to-server WS и DM sync, перенесённый в контекст децентрализации. diff --git a/TODO/Децентрализация/realtime_pda_solana_sync.md b/TODO/Децентрализация/realtime_pda_solana_sync.md deleted file mode 100644 index cf036690..00000000 --- a/TODO/Децентрализация/realtime_pda_solana_sync.md +++ /dev/null @@ -1,30 +0,0 @@ -# Realtime-синхронизация PDA и Solana - -## Зачем - -В будущем PDA-записи и Solana-состояние должны автоматически и быстро синхронизироваться с серверным состоянием, чтобы данные пользователей, homeserver-сессии и связанные записи не расходились. - -## Что сделать - -1. Определить, какие серверные события должны обновлять PDA. -2. Добавить очередь/воркер для надёжной отправки изменений в Solana. -3. Добавить периодическую сверку серверного состояния с PDA. -4. Добавить обработку ошибок, повторов и конфликтов версий. -5. Добавить мониторинг задержек и неуспешных Solana-транзакций. - -## Что учесть - -- Solana/Anchor-модуль находится в `shine-solana/shine/` и ведётся отдельно от основного server/UI deploy. -- Перед изменениями внутри Solana-модуля нужно читать `shine-solana/shine/AGENTS.md`. -- Основная инструкция по Solana-регистрации находится в `docs/Инициализация_Solana_регистрации/README.md`. -- Формат пользовательской PDA-записи описан в `shine-solana/shine/doc/formats/shine-user-pda-format-v.1.0.md`. - -## Документы, которые потом нужно обновить - -- `docs/Инициализация_Solana_регистрации/README.md`; -- `docs/Solana_Architecture/README.md`; -- `shine-solana/shine/doc/formats/shine-user-pda-format-v.1.0.md`, если меняется формат PDA. - -## Статус - -Отложено до этапа децентрализации. diff --git a/TODO/Децентрализация/запись_блокчейнов_в_arweave.md b/TODO/Децентрализация/запись_блокчейнов_в_arweave.md deleted file mode 100644 index 1d702707..00000000 --- a/TODO/Децентрализация/запись_блокчейнов_в_arweave.md +++ /dev/null @@ -1,29 +0,0 @@ -# Запись блокчейнов в Arweave - -## Зачем - -Для будущей децентрализации нужно долговременное внешнее хранение блокчейнов, чтобы данные не зависели только от одного серверного диска. - -## Что сделать - -1. Определить, какие блокчейны и какие диапазоны блоков записываются в Arweave. -2. Зафиксировать формат пачки блоков, метаданных, ссылок и контрольных хэшей. -3. Добавить безопасный механизм публикации без хранения приватного JWK в git. -4. Добавить проверку уже загруженных диапазонов, чтобы не плодить дубли. -5. Описать восстановление блокчейна из Arweave при потере локальных данных. - -## Важные ограничения - -- Любое изменение формата блокчейна требует отдельного предупреждения и явного подтверждения пользователя. -- Добавление данных в блокчейн должно выполняться только через `AddBlock`. -- Секреты Arweave нельзя хранить в репозитории. - -## Документы, которые потом нужно обновить - -- `docs/Blockchain/README.md`; -- `docs/Blockchain/CHANGELOG.md`; -- документы deploy/секретов в `deploy/`, если появятся новые параметры. - -## Статус - -Отложено до этапа децентрализации. diff --git a/TODO/Децентрализация/межсерверная_передача_сообщений.md b/TODO/Децентрализация/межсерверная_передача_сообщений.md deleted file mode 100644 index 6f45c7b0..00000000 --- a/TODO/Децентрализация/межсерверная_передача_сообщений.md +++ /dev/null @@ -1,30 +0,0 @@ -# Межсерверная передача сообщений - -## Зачем - -Когда у SHiNE появится несколько серверов, пользователи на разных серверах должны получать личные сообщения без ручной синхронизации и без привязки к одному центральному узлу. - -## Что сделать - -1. Определить протокол server-to-server доставки DM. -2. Добавить маршрутизацию получателя по серверу, user id, публичному ключу или PDA. -3. Добавить ACK, повторы, дедупликацию и backfill пропущенных сообщений. -4. Разделить realtime-доставку и восстановление истории. -5. Описать поведение при недоступности удалённого сервера. - -## Что учесть - -- Логика DM должна соответствовать документам в `docs/Personal_Messages/`. -- При изменении формата signed DM-блока или правил доставки нужно обновлять протокол и байтовый формат DM. -- Если появятся новые server API/WebSocket операции, нужно обновить `docs/API/`. - -## Документы, которые потом нужно обновить - -- `docs/Personal_Messages/Протокол_DM_v1.md`; -- `docs/Personal_Messages/Формат_DM_v1.md`; -- `docs/API/`; -- `docs/API/09_Operations_Index.md`, если добавляются новые `op`. - -## Статус - -Отложено до этапа децентрализации. diff --git a/TODO/Децентрализация/межсерверные_звонки.md b/TODO/Децентрализация/межсерверные_звонки.md deleted file mode 100644 index 0bae8762..00000000 --- a/TODO/Децентрализация/межсерверные_звонки.md +++ /dev/null @@ -1,29 +0,0 @@ -# Межсерверные звонки - -## Зачем - -В будущем пользователи на разных серверах должны иметь возможность устанавливать звонки так же, как пользователи одного сервера. - -## Что сделать - -1. Определить протокол межсерверной сигнализации звонков. -2. Добавить маршрутизацию offer/answer/ICE-кандидатов между серверами. -3. Добавить обработку статусов занятости, отказа, таймаута и ошибок маршрута. -4. Добавить диагностику доставки сигналов между серверами. -5. Проверить совместимость с текущими логами `CallDeliveryReport`. - -## Что учесть - -- Специальная диагностика установки звонков идёт через `CallDeliveryReport`. -- На production важно сохранять поля `reason`, `failureStage`, `pcConnectionState`, `pcIceConnectionState`, `routeLabel`, `configuredTurnHosts*`, `reachableTurnHosts*`. -- Межсерверные звонки не должны ломать текущий односерверный сценарий. - -## Документы, которые потом нужно обновить - -- `docs/API/`, если добавляются или меняются операции сигнализации; -- документы по звонкам/диагностике, если они будут выделены отдельно; -- deploy-документы, если появятся новые параметры TURN/server-to-server маршрутизации. - -## Статус - -Отложено до этапа децентрализации. diff --git a/TODO/Децентрализация/односерверный_production_режим.md b/TODO/Децентрализация/односерверный_production_режим.md deleted file mode 100644 index c0cb9718..00000000 --- a/TODO/Децентрализация/односерверный_production_режим.md +++ /dev/null @@ -1,23 +0,0 @@ -# Односерверный production-режим - -## Зачем - -Перед выкладкой репозитория на GitHub и запуском production нужно явно зафиксировать, что текущая стабильная версия работает как один основной сервер. - -## Что считаем текущей нормой - -- Один production-сервер обслуживает пользователей, сообщения, звонки и серверные данные. -- Децентрализованные сценарии не считаются обязательными для первого production-релиза. -- Межсерверная доставка сообщений, межсерверные звонки, realtime PDA/Solana sync и запись блокчейнов в Arweave вынесены в отдельные будущие задачи. -- Код и документация текущего production не должны создавать ожидание, что несколько серверов уже работают как единая realtime-сеть. - -## Что сделать перед возвратом к децентрализации - -1. Проверить актуальные документы по API, blockchain, DM и deploy. -2. Выделить минимальный протокол server-to-server взаимодействия. -3. Решить, какие данные остаются локальными, какие реплицируются между серверами, а какие записываются во внешнее долговременное хранилище. -4. После изменения API, blockchain-форматов или DM-протокола обновить соответствующие документы по правилам проекта. - -## Статус - -Отложено. Текущий production работает как один сервер. diff --git a/TODO/Доделать в блокчейн - подтверждения и добавление участников в канал.md b/TODO/Доделать в блокчейн - подтверждения и добавление участников в канал.md new file mode 100644 index 00000000..473a0f4c diff --git a/TODO/Новые типы связей пользователей.md b/TODO/Новые типы связей пользователей.md new file mode 100644 index 00000000..473a0f4c diff --git a/TODO/Новые фишки которые надо доделать/Новая_контентная_модель_блокчейна/01_Презентация_для_людей.md b/TODO/Новые фишки которые надо доделать/Новая_контентная_модель_блокчейна/01_Презентация_для_людей.md deleted file mode 100644 index 5a1d35a2..00000000 --- a/TODO/Новые фишки которые надо доделать/Новая_контентная_модель_блокчейна/01_Презентация_для_людей.md +++ /dev/null @@ -1,275 +0,0 @@ -# Новая логика контента в блокчейне SHiNE - -## Зачем это нужно - -Сейчас блокчейн SHiNE хорошо умеет хранить обычные сообщения, ответы, лайки и связи между людьми. - -Новая модель добавляет поверх этого более понятный смысл контента: - -- обычный текст; -- упражнение; -- услуга / процедура; -- курс; -- стартовая страница канала (`entrypoint`). - -Это нужно для того, чтобы канал стал не просто лентой постов, а полноценным пространством знаний, практик, услуг и сообществ. - -## Что меняется для людей - -### 1. В канале появятся понятные виды материалов - -Сообщение можно будет создать не только как обычный текст, но и как: - -- упражнение; -- услугу / процедуру; -- курс; -- стартовую страницу канала. - -Смысл в том, что приложение и сервер будут понимать, что это за материал, а не просто показывать любой текст одинаково. - -### 2. У канала будет стартовая страница - -У канала появится отдельное стартовое сообщение `entrypoint`. - -Это не курс и не оглавление, а именно главная точка входа в канал: - -- короткое объяснение, о чём канал; -- описание структуры; -- ссылки на нужные материалы; -- удобное начало для новых людей. - -У канала в каждый момент времени будет только одна актуальная стартовая страница. -Если её исправляют, то сохраняется история версий. -Если её удаляют, для интерфейса считается, что стартовой страницы у канала сейчас нет. - -### 3. Курс, упражнение и услуга / процедура будут отличаться по смыслу - -Это важно для логики и статистики. - -- `Упражнение` — то, что человек может делать много раз. -- `Услуга / процедура` — то, что тоже можно проходить много раз, но обычно с участием другого человека. -- `Курс` — то, что можно начать, закончить или бросить. - -За счёт этого сервер сможет честно считать активность, а интерфейс сможет показывать человеку именно те действия, которые подходят к данному типу материала. - -### 4. Появятся статусные действия - -На контент можно будет не только ответить или поставить лайк, но и отметить свой путь: - -- сделал один раз; -- заинтересовался и рассматривает; -- начал; -- закончил / освоил / знаю; -- бросил. - -При этом: - -- для упражнений и услуг / процедур будет отдельно считаться, сколько раз человек сделал / прошёл; -- для упражнений и курсов будет храниться текущий статус. - -Текущий статус определяется просто: - -- последнее статусное действие и считается актуальным. - -Например: - -- если последнее действие “заинтересовался и рассматривает”, значит человек присматривается, но ещё не начал; -- если последнее действие `started`, значит материал сейчас в процессе; -- если последнее действие `abandoned`, значит человек бросил; -- если последнее действие `completed`, значит для системы он завершил / освоил материал. - -### 5. К действиям можно добавлять живой текст - -Практически любое статусное действие можно будет сопровождать коротким комментарием. - -Например: - -- “Начал изучать, потому что давно хотел разобраться”; -- “Бросил, пока нет времени”; -- “Прошёл процедуру, стало заметно легче”. - -Это важно, потому что сам блокчейн будет хранить не только формальный статус, но и живую человеческую причину или заметку. - -### 6. Появится подтверждение статуса другими людьми - -Отдельный человек сможет подтвердить чей-то статус. - -Примеры: - -- подтвердить, что человек действительно занимался; -- подтвердить, что он реально прошёл услугу; -- подтвердить, что он освоил материал. - -Подтверждение — это не замена статуса, а отдельное мнение / свидетельство со стороны. - -### 7. Появится отдельный тип «мнение» - -На любое сообщение можно будет ответить не только обычным ответом, но и специальным типом ответа: `мнение`. - -Это по сути тоже текстовый ответ, но с отдельным смыслом: - -- это отзыв; -- это оценка; -- это мнение о материале; -- это явная метка для будущего анализа нейронками. - -То есть: - -- обычный ответ нужен для разговора; -- `мнение` нужно для отзыва, оценки и анализа реакции людей. - -## Что остаётся как раньше - -### Комментарии - -Обычные ответы на сообщения остаются. -То есть обсуждение материалов не ломается и не меняется концептуально. - -### Лайки контента - -Лайк на сообщение, курс, упражнение или услугу остаётся обычной реакцией на конкретный блок. - -### Лайк пользователю - -Лайк пользователю не будет считаться реакцией на сообщение. -Он относится к графу связей между людьми. - -Это удобно, потому что: - -- лайк человека — это отношение к человеку; -- лайк материала — это отношение к контенту. - -## Сообщество вокруг канала - -Канал сможет работать не только как лента, но и как сообщество. - -Для этого появятся простые действия: - -- заявка на вступление; -- самостоятельный выход; -- принятие; -- исключение. - -Сервер сможет понимать: - -- кто только подал заявку; -- кто уже принят; -- кто вышел; -- кто был исключён. - -## Личный канал и лента достижений - -У каждого человека по смыслу появляется два важных пространства: - -- канал его обычных постов; -- отдельная лента его тренировок и достижений. - -В обычном канале человек сможет: - -- писать посты; -- делиться мыслями; -- публиковать материалы; -- обсуждать темы как раньше. - -А в ленте достижений будут видны его реальные действия: - -- какие упражнения он делал; -- какие услуги / процедуры проходил; -- какие курсы его заинтересовали; -- какие курсы он начал; -- какие курсы он закончил; -- что он бросил. - -То есть блокчейн SHiNE сможет хранить не только слова человека, но и его путь, активность и историю практики. - -## Что смогут делать авторы контента - -Создатели контента в своих каналах смогут публиковать не только обычные посты, но и: - -- упражнения; -- курсы; -- стартовую страницу канала; -- услуги / процедуры, которые они оказывают. - -Это превращает канал в сочетание: - -- блога; -- базы знаний; -- пространства обучения; -- каталога услуг и практик. - -## Что увидит человек в интерфейсе - -На специальных сообщениях в UI можно будет показывать отдельные кнопки действий. - -Например: - -- `Выполнил упражнение` -- `Прошёл процедуру` -- `Заинтересовало` -- `Начал курс` -- `Закончил курс` - -То есть материал можно будет не просто прочитать, а сразу отметить реальное действие. - -Также при ответе на любое сообщение можно будет выбрать: - -- обычный ответ; -- `мнение / отзыв`. - -## Как будет работать лента достижений - -Если кто-то зайдёт в твою ленту достижений, он сможет: - -- прочитать, что ты делал; -- оставить мнение / отзыв; -- подтвердить, что это действительно было. - -Это даёт основу для мягкой “сертификации” внутри SHiNE. - -Например: - -- человек прошёл курс и получил подтверждения; -- человек прошёл процедуру и получил отзыв; -- человек регулярно делает упражнения, и это видно в его истории. - -Так постепенно у пользователя появляется не только лента постов, но и лента достижений, подтверждений и репутации. - -## Ссылки внутри SHiNE - -Для переходов между материалами вводятся простые внутренние адреса: - -- обычная ссылка: `SHiNE/alice-001/157` -- особополная ссылка: `SHiNE/alice-001/157/ХЭШ` - -Первая форма — основная и каноническая. -Вторая нужна там, где хочется добавить ещё и точную проверку по хэшу. - -## Что это даёт в итоге - -После внедрения новая блокчейн-логика позволит: - -- строить каналы как структурированные пространства, а не просто как поток постов; -- выделять упражнения, услуги и курсы как отдельные сущности; -- показывать стартовую страницу канала; -- хранить путь человека по материалу; -- хранить отдельную ленту его действий и достижений; -- считать активность и статусы; -- подтверждать результаты другими людьми; -- развивать сообщество вокруг канала. - -И самое важное: всё это можно добавить как расширение уже существующего блокчейна SHiNE, не разрушая старую модель сообщений. - -## Отдельный вопрос для будущего - -Отзывы о людях как о людях — полезная идея, но её стоит дополнительно обдумать. - -Например, на вкладке связей в будущем можно: - -- писать человеку отзыв; -- смотреть все отзывы о человеке; -- выводить сначала отзывы близких друзей, родственников, друзей и контактов, а уже потом остальные. - -Но этот слой нужно делать осторожно, чтобы он не стал слишком жёстким или неприятным для людей. - -Поэтому отзывы о людях как отдельная социальная механика требуют дополнительного обсуждения и проектирования. diff --git a/TODO/Новые фишки которые надо доделать/Новая_контентная_модель_блокчейна/02_ТЗ_новых_типов_блоков.md b/TODO/Новые фишки которые надо доделать/Новая_контентная_модель_блокчейна/02_ТЗ_новых_типов_блоков.md deleted file mode 100644 index 6fafb893..00000000 --- a/TODO/Новые фишки которые надо доделать/Новая_контентная_модель_блокчейна/02_ТЗ_новых_типов_блоков.md +++ /dev/null @@ -1,670 +0,0 @@ -# ТЗ: новая контентная модель блокчейна SHiNE - -## Статус документа - -Этот документ описывает предлагаемые новые типы блоков и правила их обработки. - -Цель: - -- добавить новую семантику контента; -- не ломать существующие блоки `type=0..4`; -- внедрить всё как расширение блокчейна за счёт новых форматов. - -Документ является проектным ТЗ на реализацию в сервере, БД, API чтения и UI. - -## 1. Базовые принципы - -### 1.1. Совместимость - -Старые типы не меняются: - -- `type=0` — TECH -- `type=1` — TEXT -- `type=2` — REACTION -- `type=3` — CONNECTION -- `type=4` — USER_PARAM - -Новые сущности и действия добавляются только как новые `type` и новые `body`. - -Это означает: - -- старые блоки продолжают читаться как раньше; -- старые `TEXT_POST`, `TEXT_REPLY`, `REACTION_LIKE` и остальные форматы не ломаются; -- существующий блокчейн остаётся валидным; -- новый функционал появляется только там, где клиент и сервер умеют его понимать. - -### 1.2. Общая стратегия - -Новая модель делится на четыре слоя: - -1. контентные сущности; -2. текстовые отзывы и мнения; -3. статусные действия пользователей; -4. community-события вокруг канала. - -### 1.3. Редактирование и удаление - -Для новых контентных сущностей сохраняется действующий принцип SHiNE: - -- редактирование всегда ссылается на оригинальный блок; -- тип сущности edit не меняет; -- удаление выполняется через `edit` с пустым текстом; -- отдельный `DELETE`-подтип не вводится. - -Это правило особенно важно для: - -- `plain_text` -- `exercise` -- `service` -- `course` -- `entrypoint` - -В пользовательских текстах и UI желательно использовать русские названия: - -- обычный текст; -- упражнение; -- услуга / процедура; -- курс; -- стартовое сообщение канала. - -## 2. Канонические внутренние ссылки - -В новой модели поддерживаются только две формы внутренней ссылки: - -- каноническая: `SHiNE//` -- особополная: `SHiNE///` - -Примеры: - -- `SHiNE/alice-001/157` -- `SHiNE/alice-001/157/abcd1234...` - -Правила: - -- канонической считается именно короткая форма без хэша; -- форма с хэшем используется как усиленный вариант для точной проверки; -- внутри UI и серверной логики ссылка должна приводиться как минимум к паре: - - `blockchainName` - - `blockNumber` -- если хэш присутствует, он участвует в дополнительной валидации ссылки. - -## 3. Новые контентные сущности - -## 3.1. Новый `type=5` — `CONTENT` - -Назначение: - -- хранение новых смысловых материалов канала; -- сохранение линии канала; -- поддержка edit-версий и логического удаления. - -### 3.1.1. Подтипы `CONTENT` - -- `subType=10` — `CONTENT_PLAIN` -- `subType=11` — `CONTENT_EDIT_PLAIN` -- `subType=20` — `CONTENT_EXERCISE` -- `subType=21` — `CONTENT_EDIT_EXERCISE` -- `subType=30` — `CONTENT_SERVICE` -- `subType=31` — `CONTENT_EDIT_SERVICE` -- `subType=40` — `CONTENT_COURSE` -- `subType=41` — `CONTENT_EDIT_COURSE` -- `subType=50` — `CONTENT_ENTRYPOINT` -- `subType=51` — `CONTENT_EDIT_ENTRYPOINT` - -### 3.1.2. Семантика подтипов - -- `CONTENT_PLAIN` — обычный текст нового поколения. -- `CONTENT_EXERCISE` — упражнение, которое можно выполнять многократно. -- `CONTENT_SERVICE` — услуга / процедура, которую можно проходить многократно. -- `CONTENT_COURSE` — курс / оглавление. -- `CONTENT_ENTRYPOINT` — стартовое сообщение канала. - -### 3.1.3. Почему `entrypoint` отдельный тип - -`entrypoint` не считается курсом. - -Это отдельная сущность, потому что: - -- она описывает вход в канал; -- по ней нельзя делать `started / completed / abandoned`; -- у канала в каждый момент времени должна быть только одна актуальная стартовая страница. - -### 3.1.4. Ограничение на `entrypoint` - -Для одного канала допускается только один исходный блок `CONTENT_ENTRYPOINT`. - -Правила: - -- если entrypoint уже существует, создать второй нельзя; -- изменять можно только через `CONTENT_EDIT_ENTRYPOINT`; -- если entrypoint логически удалён, UI должен считать, что стартовой страницы больше нет; -- исторический блок при этом остаётся в цепочке. - -### 3.1.5. Формат body для `CONTENT_*` - -Для `version=1` рекомендуется использовать формат, максимально совместимый по логике с текущими `TEXT_POST` / `TEXT_EDIT_POST`. - -#### Создающие блоки - -Для: - -- `CONTENT_PLAIN` -- `CONTENT_EXERCISE` -- `CONTENT_SERVICE` -- `CONTENT_COURSE` -- `CONTENT_ENTRYPOINT` - -body: - -```text -ContentLineBody_v1 -- lineCode: int32 -- prevLineNumber: int32 -- prevLineHash32: [32] -- thisLineNumber: int32 -- textLenBytes: uint16 -- text UTF-8 -``` - -#### Edit-блоки - -Для: - -- `CONTENT_EDIT_PLAIN` -- `CONTENT_EDIT_EXERCISE` -- `CONTENT_EDIT_SERVICE` -- `CONTENT_EDIT_COURSE` -- `CONTENT_EDIT_ENTRYPOINT` - -body: - -```text -ContentEditBody_v1 -- lineCode: int32 -- prevLineNumber: int32 -- prevLineHash32: [32] -- thisLineNumber: int32 -- toBlockGlobalNumber: int32 -- toBlockHash32: [32] -- textLenBytes: uint16 -- text UTF-8 -``` - -Правила: - -- edit всегда ссылается на оригинальный блок соответствующего типа; -- `toBlockchainName` в edit не хранится; -- `textLen=0` означает логическое удаление содержимого; -- тип исходной сущности edit не меняет. - -### 3.1.6. Что считается комментарием - -Комментарии не требуют нового формата. - -Для обсуждения новых контентных сущностей продолжают использоваться уже существующие: - -- `TEXT_REPLY` -- `TEXT_EDIT_REPLY` - -Это позволяет не ломать старую reply-механику и reuse текущую модель тредов. - -## 4. Текстовые отзывы - -## 4.1. Новый `type=6` — `TEXT_RATING` - -Назначение: - -- текстовая оценка / отзыв на объект; -- без числовой шкалы; -- с возможностью редактирования и логического удаления. - -Смысл `TEXT_RATING`: - -- это текст; -- это специальный отзыв / мнение / оценка; -- это явный сигнал, что перед нами не просто комментарий, а осмысленный отзыв; -- в будущем это поле можно отдельно анализировать нейронками. - -### 4.1.1. Подтипы - -- `subType=10` — `TEXT_RATING_POST` -- `subType=11` — `TEXT_RATING_EDIT` - -### 4.1.2. Где разрешён `TEXT_RATING_POST` - -Разрешён на target: - -- `HEADER` пользователя; -- контентный блок `type=5`; -- при необходимости в будущем — на другие target-блоки по отдельному решению. - -Сейчас в данном ТЗ: - -- отзыв / оценка на пользователя — да; -- отзыв / оценка на контент — да; -- отзыв / лайк на канал целиком — не вводится, только оставляется как будущая возможность. - -### 4.1.3. Где и как используется `TEXT_RATING_POST` - -`TEXT_RATING_POST` можно создавать: - -- как отзыв на контентный блок; -- как отзыв на пользователя через target на `HEADER`; -- как специальный ответ вместо обычного комментария. - -Практическое правило для UI: - -- при ответе на любое сообщение пользователь может выбрать: - - обычный ответ; - - `мнение / отзыв`. - -### 4.1.4. Формат body - -#### Создание - -```text -TextRatingBody_v1 -- toBlockchainNameLen: uint8 -- toBlockchainName UTF-8 -- toBlockGlobalNumber: int32 -- toBlockHash32: [32] -- textLenBytes: uint16 -- text UTF-8 -``` - -#### Редактирование - -```text -TextRatingEditBody_v1 -- toBlockGlobalNumber: int32 -- toBlockHash32: [32] -- textLenBytes: uint16 -- text UTF-8 -``` - -Правила: - -- edit ссылается на оригинальный `TEXT_RATING_POST`; -- пустой текст в edit означает логическое удаление отзыва. - -## 5. Статусные действия и накопительные события - -## 5.1. Новый `type=7` — `STATUS_ACTION` - -Назначение: - -- хранение действий пользователя по отношению к контенту; -- вычисление текущего статуса; -- накопительный учёт повторных прохождений; -- подтверждение статусов другими людьми. - -### 5.1.1. Подтипы - -- `subType=10` — `STATUS_DONE_ONCE` -- `subType=20` — `STATUS_INTERESTED` -- `subType=30` — `STATUS_STARTED` -- `subType=40` — `STATUS_COMPLETED` -- `subType=50` — `STATUS_ABANDONED` -- `subType=60` — `STATUS_CONFIRMED` - -### 5.1.2. Матрица допустимости по контенту - -`STATUS_DONE_ONCE` разрешён только для: - -- `CONTENT_EXERCISE` -- `CONTENT_SERVICE` - -`STATUS_INTERESTED`, `STATUS_STARTED`, `STATUS_COMPLETED`, `STATUS_ABANDONED` разрешены только для: - -- `CONTENT_EXERCISE` -- `CONTENT_COURSE` - -`CONTENT_ENTRYPOINT` не поддерживает: - -- `interested` -- `started` -- `completed` -- `abandoned` - -### 5.1.3. Как считать текущее состояние - -Для пары: - -- `actorLogin` -- `targetBlock` - -актуальным статусом считается последнее по времени статусное событие из набора: - -- `STATUS_INTERESTED` -- `STATUS_STARTED` -- `STATUS_COMPLETED` -- `STATUS_ABANDONED` - -Следствия: - -- у одного пользователя по одному объекту в каждый момент времени только один актуальный статус; -- если последним пришёл `interested`, статус считается “заинтересовался / рассматривает, но ещё не начал”; -- если последним пришёл `started`, статус считается “в процессе”; -- если последним пришёл `completed`, статус считается “завершён / освоен / знаю”; -- если последним пришёл `abandoned`, статус считается “брошен”. - -### 5.1.4. Как считать количество прохождений - -`STATUS_DONE_ONCE` не меняет текущий статус. - -Он считается отдельно как накопительное событие. - -Сервер должен уметь считать: - -- сколько раз пользователь сделал упражнение; -- сколько раз пользователь прошёл услугу / процедуру. - -### 5.1.5. Дополнительный текст действия - -Каждое действие `STATUS_*` может содержать дополнительный текст-комментарий. - -Примеры: - -- как именно делал упражнение; -- чем заинтересовал курс; -- с какими мыслями начал курс; -- почему бросил; -- что именно подтверждает подтверждающий человек. - -### 5.1.6. Подтверждение статуса - -`STATUS_CONFIRMED` разрешён только на target-статусы: - -- `STATUS_DONE_ONCE` -- `STATUS_INTERESTED` -- `STATUS_STARTED` -- `STATUS_COMPLETED` -- `STATUS_ABANDONED` - -Это значит: - -- подтверждение не ставится прямо на курс или упражнение; -- подтверждение ставится на конкретный статусный блок другого человека. - -Подтверждение: - -- не меняет основной статус автора; -- не меняет счётчик `done_once`; -- хранится как отдельное мнение / свидетельство. - -### 5.1.7. Формат body - -Для `STATUS_DONE_ONCE`, `STATUS_INTERESTED`, `STATUS_STARTED`, `STATUS_COMPLETED`, `STATUS_ABANDONED`: - -```text -StatusActionBody_v1 -- toBlockchainNameLen: uint8 -- toBlockchainName UTF-8 -- toBlockGlobalNumber: int32 -- toBlockHash32: [32] -- noteLenBytes: uint16 -- note UTF-8 -``` - -Для `STATUS_CONFIRMED`: - -```text -StatusConfirmBody_v1 -- toBlockchainNameLen: uint8 -- toBlockchainName UTF-8 -- toBlockGlobalNumber: int32 -- toBlockHash32: [32] -- noteLenBytes: uint16 -- note UTF-8 -``` - -На уровне бинарного формата тело можно оставить одинаковым. -Различие задаётся `subType` и правилами валидации target. - -## 6. Community-события - -## 6.1. Новый `type=8` — `COMMUNITY_EVENT` - -Назначение: - -- заявки в сообщество; -- выход из сообщества; -- принятие; -- исключение. - -### 6.1.1. Подтипы - -- `subType=10` — `COMMUNITY_JOIN_REQUEST` -- `subType=20` — `COMMUNITY_LEAVE` -- `subType=30` — `COMMUNITY_ACCEPT` -- `subType=40` — `COMMUNITY_REMOVE` - -### 6.1.2. Базовая логика - -`COMMUNITY_JOIN_REQUEST` - -- создаёт пользователь; -- target — `CONTENT_ENTRYPOINT` канала; -- может содержать текст заявки. - -`COMMUNITY_LEAVE` - -- создаёт сам участник; -- target — `CONTENT_ENTRYPOINT` канала; -- подтверждение не требуется; -- может содержать текст. - -`COMMUNITY_ACCEPT` - -- создаёт владелец канала; -- target — конкретный блок `COMMUNITY_JOIN_REQUEST`; -- может содержать текст. - -`COMMUNITY_REMOVE` - -- создаёт владелец канала; -- target — `CONTENT_ENTRYPOINT` канала; -- body дополнительно хранит `subjectLogin`, кого исключили; -- может содержать текст. - -### 6.1.3. Текущее членство - -Пользователь считается текущим участником сообщества, если: - -- у него есть хотя бы одно принятие в это сообщество; -- после этого принятия нет более позднего: - - `COMMUNITY_LEAVE` - - `COMMUNITY_REMOVE` - -Заявка сама по себе членство не создаёт. - -### 6.1.4. Формат body - -Для `JOIN_REQUEST` и `LEAVE`: - -```text -CommunityActionBody_v1 -- toBlockchainNameLen: uint8 -- toBlockchainName UTF-8 -- toBlockGlobalNumber: int32 -- toBlockHash32: [32] -- noteLenBytes: uint16 -- note UTF-8 -``` - -Для `ACCEPT`: - -```text -CommunityAcceptBody_v1 -- toBlockchainNameLen: uint8 -- toBlockchainName UTF-8 -- toBlockGlobalNumber: int32 -- toBlockHash32: [32] -- noteLenBytes: uint16 -- note UTF-8 -``` - -Для `REMOVE`: - -```text -CommunityRemoveBody_v1 -- toBlockchainNameLen: uint8 -- toBlockchainName UTF-8 -- toBlockGlobalNumber: int32 -- toBlockHash32: [32] -- subjectLoginLen: uint8 -- subjectLogin ASCII -- noteLenBytes: uint16 -- note UTF-8 -``` - -## 7. Что остаётся на старых типах - -### 7.0. Обычный канал и лента достижений - -На уровне продукта рекомендуется различать: - -- обычный канал постов пользователя; -- отдельную ленту его действий и достижений. - -В обычном канале пользователь: - -- пишет посты; -- публикует материалы; -- общается и обсуждает. - -В ленте достижений видны события: - -- какие упражнения он делал; -- какие услуги / процедуры проходил; -- какие курсы его заинтересовали; -- какие курсы он начал; -- какие курсы он завершил; -- что он бросил. - -В данном ТЗ эта модель фиксируется как продуктовая логика. -Конкретный способ хранения можно реализовать: - -- либо отдельным специальным каналом; -- либо отдельным режимом чтения по статусным блокам. - -### 7.1. Лайк пользователю - -Лайк пользователю не вводится как `REACTION`. - -Он остаётся в слое социальных связей: - -- через `CONNECTION` -- как будущий отдельный подтип связи - -В этом ТЗ сам новый подтип связи не описывается детально. -Нужно только зафиксировать правило: - -- лайк человека относится к графу связей, а не к реакции на блок. - -### 7.2. Лайк контента - -Лайк на: - -- `CONTENT_PLAIN` -- `CONTENT_EXERCISE` -- `CONTENT_SERVICE` -- `CONTENT_COURSE` -- `CONTENT_ENTRYPOINT` - -может использовать уже существующий: - -- `REACTION_LIKE` -- `REACTION_UNLIKE` - -Отдельный новый формат для лайка контента не нужен. - -### 7.3. Канал целиком - -В текущем ТЗ не вводятся: - -- отзыв на канал целиком; -- лайк канала целиком. - -Это оставляется как будущая возможность. - -### 7.4. Отзывы о людях - -Отзывы о человеке как о человеке в текущем ТЗ допустимы через `TEXT_RATING` на `HEADER`. - -Но продуктовую модель их показа нужно отдельно продумать. - -Направление для будущего: - -- просмотр отзывов о человеке на вкладке связей; -- приоритетный вывод отзывов от близких друзей, родственников, друзей и контактов; -- затем вывод остальных отзывов. - -Эта тема полезна, но требует дополнительной осторожной проработки с точки зрения UX и социальных рисков. - -## 8. Требования к серверу - -Сервер после внедрения должен уметь: - -1. Валидировать новые `type=5..8`. -2. Хранить новые блоки без ломки старого чтения. -3. Определять текущий статус пользователя по объекту: - - `interested` - - `started` - - `completed` - - `abandoned` -4. Считать накопительные события `done_once` для: - - `exercise` - - `service` -5. Считать подтверждения статусов. -6. Определять единственный актуальный `entrypoint` канала. -7. Определять текущее членство в сообществе канала. -8. Поддерживать внутренние ссылки вида: - - `SHiNE//` - - `SHiNE///` - -## 9. Требования к UI - -UI после внедрения должен уметь: - -1. Показывать разные карточки для: - - текста - - упражнения - - услуги - - курса - - entrypoint -2. Показывать стартовую страницу канала, если `entrypoint` существует. -3. Не показывать entrypoint, если он логически удалён. -4. Давать человеку только допустимые действия по типу материала. -5. Показывать: - - текущий статус; - - количество `done_once`; - - подтверждения статуса. -6. Показывать отдельные действия-кнопки на специальных блоках, например: - - `Выполнил упражнение` - - `Прошёл процедуру` - - `Заинтересовало` - - `Начал курс` - - `Закончил курс` -7. При ответе на сообщение давать выбор: - - обычный ответ; - - `мнение / отзыв`. -8. Открывать внутренние ссылки SHiNE. - -## 10. Вывод по совместимости - -Предлагаемая модель реализуема без слома старого блокчейна. - -Причина: - -- старые `type=0..4` не меняются; -- новые сущности вводятся только как новые `type=5..8`; -- существующие `reply`, `like`, `edit`, `HEADER`, `CREATE_CHANNEL` и `CONNECTION` продолжают работать как раньше; -- старые клиенты смогут игнорировать новые типы как неизвестные; -- новые клиенты смогут постепенно включать поддержку нового функционала. - -Итог: - -- это расширение формата блокчейна; -- это не миграция со сломом старых блоков; -- это можно внедрять поэтапно. diff --git a/TODO/Поделить сервер на две части что бы работал с VPS.md b/TODO/Поделить сервер на две части что бы работал с VPS.md new file mode 100644 index 00000000..473a0f4c diff --git a/TODO/Разместить на гитхаб с AGPLv3 лицензией.md b/TODO/Разместить на гитхаб с AGPLv3 лицензией.md new file mode 100644 index 00000000..473a0f4c diff --git a/TODO/межсерверные_звонки.md b/TODO/межсерверные_звонки.md new file mode 100644 index 00000000..0b8a3af3 --- /dev/null +++ b/TODO/межсерверные_звонки.md @@ -0,0 +1,7 @@ +# Межсерверные звонки + +Доделать Звонки что бы работало как сигнал о том что вызов идёт. + +и +Пользователи на разных серверах должны иметь возможность устанавливать звонки так же, как пользователи одного сервера. + diff --git a/VERSION.properties b/VERSION.properties index 628d8941..7042c4e0 100644 --- a/VERSION.properties +++ b/VERSION.properties @@ -1,2 +1,2 @@ -client.version=1.5.35 +client.version=1.5.36 server.version=1.4.11 diff --git a/docs/Figma/README.md b/docs/Figma/README.md deleted file mode 100644 index fc6c0835..00000000 --- a/docs/Figma/README.md +++ /dev/null @@ -1,33 +0,0 @@ -# Figma - -Эта папка хранит рабочие инструкции по переносу экранов SHiNE в Figma и по обратному переносу изменений из Figma в код. - -## Что здесь лежит - -- `README.md` — точка входа и краткий регламент. -- `TRANSFER_UI_SCREENS.md` — подробная инструкция по переносу экранов UI в Figma и обратно. - -## Когда читать - -Читать перед любыми задачами вида: -- перенести экран из `shine-UI` в Figma; -- собрать новый Figma-файл для экранов SHiNE; -- перенести изменения из Figma обратно в код; -- уточнить, каким способом переносить экраны: по одному или пачкой. - -## Ключевое правило - -Для экранов SHiNE безопасный рабочий способ на текущий момент: -- переносить экраны в Figma по одному; -- не пытаться сразу переносить длинный auth-flow пачкой; -- после каждого переноса визуально проверять результат в самой Figma; -- только после удачного одного экрана переходить к следующему. - -## Про Miro - -Отдельной папки `Miro` пока нет. - -Причина: -- практики по Miro в проекте пока мало; -- устойчивого процесса ещё нет; -- как только появится стабильный сценарий работы с Miro, его нужно будет оформить аналогично Figma. diff --git a/docs/Figma/TRANSFER_UI_SCREENS.md b/docs/Figma/TRANSFER_UI_SCREENS.md deleted file mode 100644 index d680d1c4..00000000 --- a/docs/Figma/TRANSFER_UI_SCREENS.md +++ /dev/null @@ -1,222 +0,0 @@ -# Перенос экранов UI в Figma и обратно - -## Зачем нужен этот документ - -Этот документ фиксирует практический опыт, который уже был получен на переносе стартового экрана, экрана регистрации и дальнейших попытках. - -Главная цель: -- чтобы агент не повторял неудачные попытки; -- чтобы переносы делались одинаково; -- чтобы изменения из Figma можно было уверенно переносить назад в `shine-UI`. - -## Где находится основной UI - -- основной клиентский UI: `shine-UI/` -- маршруты и список pre-auth экранов: `shine-UI/js/router.js` -- экраны: `shine-UI/js/pages/` -- общие стили: `shine-UI/styles/main.css`, `shine-UI/styles/layout.css`, `shine-UI/styles/components.css` - -## Что считать успешным переносом в Figma - -Успешный перенос экрана в Figma — это не просто фон и прямоугольники. - -Нужно, чтобы: -- были видны все ключевые текстовые элементы; -- кнопки были перенесены как отдельные элементы; -- поля ввода были явно видны; -- экран был узнаваем визуально; -- пользователь мог вручную подправить макет в Figma; -- после правок можно было понять, что именно переносить обратно в код. - -## Текущий рабочий способ - -На текущем проекте лучший практический способ такой: - -1. Переносить только один экран за раз. -2. Сначала читать конкретный `js/pages/.js`. -3. Затем читать связанные стили из `styles/components.css` и `styles/layout.css`. -4. После этого вручную собирать экран в Figma как отдельный frame с явными элементами. -5. Проверять в Figma, что не получился только фон без текста и контролов. -6. Только после успешной проверки переходить к следующему экрану. - -## Почему нельзя переносить пачкой - -Был получен негативный опыт: -- при переносе сразу многих экранов в Figma часть экранов отображалась как фон без нормальных надписей и элементов; -- длинные экраны с большим количеством текста и форм разваливались; -- автогенерация давала внешний вид, непригодный для ручной доработки. - -Поэтому правило такое: -- auth-flow, регистрация, вход, onboarding — переносить по одному экрану; -- после каждого экрана ждать визуального подтверждения пользователя; -- не объединять 5-10 экранов в один проход без отдельного разрешения и без промежуточной проверки. - -## Рекомендуемый порядок переноса в Figma - -### Вперёд: код -> Figma - -1. Определить точный экран. -2. Найти файл экрана в `shine-UI/js/pages/`. -3. Найти используемые CSS-классы через поиск по файлу экрана. -4. Вытащить: - - тексты; - - состав кнопок; - - поля ввода; - - карточки; - - блоки статуса; - - последовательность секций. -5. Если экран длинный, всё равно переносить его как один frame, но собирать блоками сверху вниз. -6. В Figma создавать отдельный экран рядом с уже существующими экранами, а не смешивать всё в одну кучу. -7. После создания экрана проверить метаданные/скриншот Figma, если инструмент это позволяет. - -### Назад: Figma -> код - -1. Снять актуальный скриншот изменённого Figma-экрана. -2. Получить метаданные узла, если это помогает понять структуру. -3. Сравнить Figma с текущим кодом экрана. -4. Переносить обратно в код только реальные изменения: - - порядок блоков; - - тексты; - - размеры/отступы; - - наличие или отсутствие карточек; - - подписи кнопок; - - видимость блоков. -5. Не придумывать новые UX-решения без отдельного подтверждения пользователя, если их нет в Figma. -6. После правок проверять экран локально или как минимум по коду и зависимостям. - -## Что переносить вручную - -Вручную, а не автогенерацией, нужно переносить: -- экраны регистрации; -- экраны входа; -- длинные формы; -- экраны с несколькими карточками; -- экраны с длинными объясняющими текстами; -- экраны, где важен порядок блоков. - -Причина: -- именно они чаще всего ломаются при слишком автоматическом переносе. - -## Какие ошибки уже были - -### Ошибка 1. Перенос пачкой - -Проблема: -- несколько экранов были добавлены сразу; -- пользователь увидел, что на экранах в Figma «какая-то ерунда». - -Вывод: -- переносить по одному. - -### Ошибка 2. Видно только фон - -Проблема: -- frame создавался, фон и свечения были видны; -- тексты и элементы либо не появлялись, либо получались непригодными. - -Вывод: -- при сложных экранах собирать элементы вручную и явно. - -### Ошибка 3. Слишком вольная реконструкция - -Проблема: -- экран формально был перенесён, но визуально не соответствовал ожиданию пользователя. - -Вывод: -- для SHiNE важнее узнаваемый и редактируемый экран, чем «формально похожий» экран. - -## Обязательные проверки после переноса в Figma - -После каждого нового экрана агент должен проверить: -- виден ли заголовок; -- видны ли кнопки; -- видны ли поля ввода; -- не исчезли ли длинные тексты; -- не сломан ли порядок секций; -- не оказался ли на холсте только фон и пустые прямоугольники. - -Если хотя бы один пункт не выполнен: -- не считать перенос завершённым; -- либо переделать экран сразу; -- либо остановиться и показать пользователю только после исправления. - -## Правила для длинных экранов - -Если экран длинный, например регистрация: -- высота frame может быть больше стандартной мобильной высоты; -- секции должны идти в правильном вертикальном порядке; -- отдельные карточки должны быть вынесены в отдельные блоки; -- тексты лучше упрощённо располагать вручную, чем терять их совсем. - -## Правила для экрана регистрации - -Экран `register-view` особенно чувствительный. - -При переносе нужно отдельно учитывать: -- заголовок и стрелку назад; -- поля логина и пароля; -- строку статуса длины пароля; -- строку статуса проверки логина; -- кнопку проверки логина; -- отдельную карточку первого сервера; -- отдельную карточку FAQ; -- нижние кнопки `Назад` и `Далее`. - -## Правила для экрана входа - -Для экранов входа важно не смешивать: -- экран выбора способа входа; -- вход по логину/паролю; -- вход через другое устройство; -- вход по QR. - -Каждый из них переносить отдельно. - -## Что делать после правок пользователя в Figma - -Если пользователь изменил экран в Figma: - -1. Считать Figma источником визуальной правки. -2. Сначала понять, что именно изменено: - - тексты; - - порядок блоков; - - наличие блоков; - - размеры; - - отступы; - - логика flow. -3. Переносить эти изменения назад в код минимально необходимыми правками. -4. Если из Figma следует уже не только визуальная, но и UX-логическая правка, отдельно проверить, что она согласована пользователем. - -## Когда нужно отдельно согласовать ручную проверку - -Если после изменения по Figma: -- поменялась логика flow; -- поменялась регистрация/вход; -- нужен реальный прогон на test2; -- затронута интеграция с Solana; - -тогда нужно отдельно согласовать ручную проверку с пользователем. - -## Что пока не оформлено для Miro - -По Miro пока нет устойчивого процесса. - -Из того, что уже понятно: -- пока не стоит обещать такой же отлаженный перенос, как для Figma; -- сначала нужно накопить хотя бы 2-3 реальных сценария работы; -- только после этого оформлять отдельную папку и регламент. - -## Краткая памятка для агента - -Если задача звучит как: -- «перенеси экран в Figma»; -- «добавь экран в Figma»; -- «я поправил экран в Figma, перенеси назад»; - -то агент должен: - -1. Прочитать этот документ. -2. Работать по одному экрану. -3. Не переносить auth-flow пачкой. -4. Проверять результат после каждого экрана. -5. При переносе обратно в код не гадать, а опираться на Figma-правки. diff --git a/docs/Personal_Messages/Спецификация_DM_v0.5_устаревшая.md b/docs/Personal_Messages/Спецификация_DM_v0.5_устаревшая.md deleted file mode 100644 index de98104f..00000000 --- a/docs/Personal_Messages/Спецификация_DM_v0.5_устаревшая.md +++ /dev/null @@ -1,230 +0,0 @@ -# Личные сообщения (DM) — v0.5 устаревшая спецификация - -## Статус документа - -Этот документ устарел и сохранён только как историческое описание ранее реализованной схемы DM. - -Aктуальная целевая спецификация: - -- `docs/Personal_Messages/Протокол_DM_v1.md` - -Что в этом документе считать устаревшим: - -- трактовку `encryptedBody` как фактически одинакового содержимого пары; -- отсутствие нормального E2EE-шифрования DM; -- старую модель удаления через пустую ревизию без терминального tombstone; -- старую трактовку обновления только как общей пары без отдельной будущей модели перешифровки; -- все упоминания legacy-формата read-receipt как части целевой архитектуры следующего этапа. - -## Текущее состояние - -Сейчас в проекте реализованы: - -- новый формат контентных личных сообщений `SHiNE_DM`; -- ревизии сообщений через `revisionTimeMs`; -- редактирование сообщения через повторную отправку той же логической пары; -- удаление сообщения через пустую ревизию; -- `upsert` последней версии сообщения на сервере. - -Сейчас в проекте **не реализованы**: - -- вложения в DM; -- upload/download файлов для DM; -- UI-кнопка прикрепления файла; -- серверное хранение файловых связей для DM. - -Черновик будущих вложений вынесен отдельно: - -- `docs/Personal_Messages/Черновик_будущих_DM_вложений.md` - -## Общая схема - -Личное сообщение по-прежнему отправляется парой signed-блоков: - -- `type=1` — входящий блок для получателя; -- `type=2` — исходящая копия для отправителя. - -Read-receipt пока остаются в legacy-формате: - -- `type=3` — входящее подтверждение прочтения; -- `type=4` — исходящая копия подтверждения. - -Ключи сообщения: - -- `baseKey = fromLogin|toLogin|timeMs|nonce` -- `messageKey = baseKey|messageType` - -Логический идентификатор письма задаётся парой: - -- `timeMs` -- `nonce` - -Эти поля не меняются при редактировании или удалении. Меняется только: - -- `revisionTimeMs` -- содержимое `encryptedBody` - -Сервер хранит только последнюю версию записи для каждого `messageKey`. - -## Формат контентного DM: `SHiNE_DM` - -Префикс бинарного блока: - -- `SHiNE_DM` - -Поля идут в big-endian порядке: - -1. `formatVersionMajor` (`u8`) = `1` -2. `formatVersionMinor` (`u8`) = `0` -3. `toLoginLen` (`u8`) + `toLogin` (ASCII, `1..60`) -4. `fromLoginLen` (`u8`) + `fromLogin` (ASCII, `1..60`) -5. `timeMs` (`u64`) -6. `nonce` (`u32`) -7. `messageType` (`u16`) — только `1` или `2` -8. `revisionTimeMs` (`u64`) -9. `attachmentsCount` (`u8`) -10. `encryptedBodyLen` (`u32`) -11. `encryptedBody` (`bytes`) -12. `signature` (`64 bytes`, Ed25519) - -### Ограничения - -- `attachmentsCount` сейчас всегда должен быть `0` -- `encryptedBodyLen` сейчас ограничен сервером до `16384` байт -- `revisionTimeMs` не может быть отрицательным - -Если приходит `attachmentsCount != 0`, сервер отклоняет такой DM как: - -- `ATTACHMENTS_DISABLED` - -## Legacy read-receipt: `SHiNE_dm2` - -Подтверждения прочтения `type=3/4` пока используют старый контейнер `SHiNE_dm2`: - -1. `toLoginLen` (`u8`) + `toLogin` -2. `fromLoginLen` (`u8`) + `fromLogin` -3. `timeMs` (`u64`) -4. `nonce` (`u32`) -5. `messageType` (`u16`) — `3` или `4` -6. `payloadLen` (`u16`) -7. `payloadBytes` -8. `signature` - -## Редактирование - -Редактирование делается новой отправкой той же логической пары сообщения: - -- `timeMs` и `nonce` остаются теми же; -- `messageType` остаётся `1/2`; -- `revisionTimeMs` становится больше; -- `encryptedBody` содержит новую версию текста. - -Если на сервер приходит более старая ревизия, она игнорируется. - -Если приходит та же ревизия и тот же бинарный блок, сервер тоже её не применяет повторно. - -## Удаление - -Удаление личного сообщения делается как новая ревизия того же сообщения: - -- `timeMs` и `nonce` остаются прежними; -- `revisionTimeMs` увеличивается; -- `attachmentsCount = 0`; -- `encryptedBodyLen = 0`; -- `encryptedBody` пустой. - -В UI такое сообщение не показывается. - -На сервере это не отдельный тип сообщения, а просто последняя пустая ревизия того же `messageKey`. - -## Поведение сервера - -Для контентных DM сервер: - -1. принимает пару signed-блоков `type=1/2`; -2. валидирует формат, подпись и совпадение ключевых полей пары; -3. проверяет, что для обеих сторон пары совпадают: - - `fromLogin` - - `toLogin` - - `timeMs` - - `nonce` - - `revisionTimeMs` - - `encryptedBody` -4. делает `upsert` последней версии в `signed_messages_v2`; -5. сбрасывает pending-доставку по сессиям для новой ревизии; -6. рассылает актуальную версию адресатам через `SignedMessageArrived`. - -История старых ревизий сейчас не хранится отдельно: в таблице остаётся только последняя версия по каждому `messageKey`. - -## Хранение в БД - -Основная таблица: - -- `signed_messages_v2` - -Для контентных DM в ней используются: - -- `message_key` -- `base_key` -- `target_login` -- `from_login` -- `to_login` -- `time_ms` -- `nonce` -- `message_type` -- `revision_time_ms` -- `raw_block` -- `created_at_ms` - -Отдельных таблиц файлов для DM сейчас нет. - -## События и доставка - -Запрос на отправку по WebSocket остаётся прежним: - -- `SendMessagePair` -- `ReceiveOutcomingMessage` как алиас - -Клиент отправляет: - -- `incomingBlobB64` -- `outgoingBlobB64` - -Событие в активные сессии: - -- `SignedMessageArrived` - -Если пришла новая ревизия того же сообщения, `messageKey` остаётся прежним, а внутри `blobB64` будет более новый `revisionTimeMs`. - -Подтверждение доставки в сессию: - -- `AckSessionDelivery` - -WebPush и локальные уведомления сейчас работают так: - -- для активной онлайн-сессии приоритет у доставки по WebSocket через `SignedMessageArrived`; -- если целевая сессия не онлайн по WebSocket, сервер может отправить WebPush с `kind=new_message`; -- если вкладка/приложение живы, но страница скрыта (`document.visibilityState !== visible`), UI дополнительно пытается показать системное уведомление через `service worker`; -- для активной видимой страницы UI проигрывает короткий локальный сигнал на каждое новое входящее DM, если браузер ранее разрешил аудио-контекст после пользовательского жеста; -- для скрытой, но живой страницы UI также делает `best effort` сигнал через `vibrate()` и более длинный локальный звук; -- эти локальные сигналы не гарантируются браузером: на мобильных устройствах они зависят от политики Chrome/Android/iOS. - -## Правила UI - -UI сейчас работает так: - -- показывает только текст `encryptedBody`; -- умеет обновлять уже существующее сообщение по тому же `messageKey`; -- не показывает удалённые сообщения; -- позволяет владельцу сообщения вызвать меню `Скопировать как текст / Прочесть / Изменить / Удалить`; -- при редактировании показывает над полем ввода полоску `Редактируем сообщение: ...` с кнопкой отмены; -- после редактирования показывает под временем отдельную строку `изменено: <дата время>`; -- на видимом экране чата/приложения проигрывает короткий локальный звук на новое входящее DM; -- при входящем DM для скрытой, но ещё живой страницы пытается поднять системное уведомление через `service worker`; -- не показывает и не принимает вложения. - -## Что обязательно помнить - -- вложения в DM сейчас отключены на уровне протокола и UI; -- любые старые описания `/f/...`, `/upload` и файловых таблиц для DM больше не актуальны; -- если позже вложения вернутся, их формат и серверная логика могут быть другими. diff --git a/docs/libs/shine-server-bd/DOC.md b/docs/libs/shine-server-bd/DOC.md deleted file mode 100644 index ad2c2483..00000000 --- a/docs/libs/shine-server-bd/DOC.md +++ /dev/null @@ -1,12 +0,0 @@ -shine-server-bd — это библиотека реалезующая всю работу с БД: - -хранит пользователей/сессии/параметры/кэш IP→гео и данные блокчейна (состояние + блоки), предоставляя единый PostgreSQL runtime-контроллер соединений, набор DAO под каждую таблицу (Singleton, методы с Connection для транзакций и без Connection — сами открывают/закрывают), и простые entity-модели как контейнеры данных для маппинга ResultSet↔Java. - -Логика структуры классов (в двух словах): - -shine.db.DbController / shine.db.PostgresDbController — вход в runtime БД: читает `db.url/db.user/db.password`, подключается только к PostgreSQL и выдаёт новые `Connection`. -shine.db.DatabaseInitializer — проверяет наличие `db_schema_version` и при пустой БД автоматически накатывает `postgres/schema_v1.sql`. - - -shine.db.entities.* — POJO-модели строк таблиц (без логики, только поля/геттеры/сеттеры + иногда удобные методы вроде getClientKeyByte()). -shine.db.dao.* — DAO по таблицам: ActiveSessionsDAO, CurrentUsersDAO, UserParamsDAO, IpGeoCacheDAO, BlockchainStateDAO, BlocksDAO, SignedMessagesDAO; плюс сервисные DAO под recovery/resync. diff --git a/docs/libs/shine-server-bd/POSTGRES_RUNTIME_SCHEMA_V1.md b/docs/libs/shine-server-bd/POSTGRES_RUNTIME_SCHEMA_V1.md deleted file mode 100644 index 1f7e787a..00000000 --- a/docs/libs/shine-server-bd/POSTGRES_RUNTIME_SCHEMA_V1.md +++ /dev/null @@ -1,91 +0,0 @@ -# PostgreSQL runtime schema v1 - -Дата фиксации: `2026-07-24` - -## Назначение - -Это целевая серверная runtime-схема PostgreSQL для SHiNE без опоры на SQLite. - -Схема `v1` нужна как стартовая точка большого механического переноса DAO и runtime-запросов -с существующей SQLite-логики на PostgreSQL. - -## Ключевые решения - -- Источник истины по пользователям: `solana_user_pda_current`. -- Legacy-таблицы старого runtime для пользователей и личных сообщений в новой схеме не создаются. -- Основная таблица серверных личных сообщений: `signed_messages`. -- Таблица `blockchain_state` сохраняется как runtime-state таблица сервера: - она не является identity-слоем и не мигрируется как legacy SQLite data. -- Триггеры по `blocks` сохраняются и переписываются под PostgreSQL. - -## Таблицы sync-модуля Solana users - -- `solana_sync_state` -- `solana_sync_tx_history` -- `solana_user_pda_current` -- `solana_user_pda_history` - -## Таблицы server runtime - -- `db_schema_version` -- `active_sessions` -- `esp_pairing_settings` -- `esp_pairing_requests` -- `users_params` -- `ip_geo_cache` -- `test_free_avatar_uploads` -- `sync_servers` -- `blockchain_state` -- `blocks` -- `connections_state` -- `message_stats` -- `reactions_state` -- `channel_names_state` -- `chat200_state` -- `chat200_members_state` -- `user_push_tokens` -- `signed_direct_message_replay` -- `signed_direct_messages_history` -- `signed_messages` -- `signed_message_session_delivery` - -## Триггеры - -Схема `v1` уже включает PostgreSQL-версии триггеров: - -- `trg_blocks_line_integrity_bi` -- `trg_blocks_connection_state_ai` -- `trg_blocks_message_stats_like_ai` -- `trg_blocks_message_stats_reply_ai` -- `trg_blocks_edit_apply_ai` - -## Что не входит в v1 - -- полная зачистка legacy-документации, старых названий и TODO-хвостов; -- переименование Java DAO/классов `*V2` в runtime-коде; -- перенос прямых SQL-запросов из хэндлеров в DAO/service; -- переключение всего runtime-кода на новый `DbProvider`. - -Это отдельные механические шаги поверх уже утверждённой схемы. - -## Совместимость со старыми блоками каналов - -В runtime-сервере сознательно нет жёсткой серверной проверки -`channelName must not contain only digits`. - -Причина: в уже существующей истории блокчейна есть каналы с числовыми именами, -и при холодном восстановлении сервера с пустой БД и без `.bch` такие блоки должны -успешно переигрываться от других sync-серверов. - -Сейчас правило "новый публичный канал не должен состоять только из цифр" остаётся -на уровне UI/продуктовых требований и должно быть позже возвращено на сервере -отдельным совместимым способом, который не ломает replay исторических блоков. - -## Инициализация пустой БД - -Если сервер подключается к PostgreSQL через `db.url=jdbc:postgresql:...` и в выбранной БД ещё нет таблицы `db_schema_version`, -он сам автоматически накатывает `schema_v1.sql` из classpath-ресурса: - -- ресурс: `shine-server-db/src/main/resources/postgres/schema_v1.sql` -- признак пустой схемы: отсутствует `db_schema_version` -- стартовая версия схемы: `1` diff --git a/docs/audit/Solana-audit-2-by-Claude-11июня2026.md b/docs/старый_аудит_смартконтрактов_в_claud_fable/Solana-audit-2-by-Claude-11июня2026.md similarity index 100% rename from docs/audit/Solana-audit-2-by-Claude-11июня2026.md rename to docs/старый_аудит_смартконтрактов_в_claud_fable/Solana-audit-2-by-Claude-11июня2026.md diff --git a/docs/audit/Solana-audit-3-by-Claude-12июня2026.md b/docs/старый_аудит_смартконтрактов_в_claud_fable/Solana-audit-3-by-Claude-12июня2026.md similarity index 100% rename from docs/audit/Solana-audit-3-by-Claude-12июня2026.md rename to docs/старый_аудит_смартконтрактов_в_claud_fable/Solana-audit-3-by-Claude-12июня2026.md diff --git a/docs/audit/Solana-audit-by-Claude-File5-9июня2026.md b/docs/старый_аудит_смартконтрактов_в_claud_fable/Solana-audit-by-Claude-File5-9июня2026.md similarity index 100% rename from docs/audit/Solana-audit-by-Claude-File5-9июня2026.md rename to docs/старый_аудит_смартконтрактов_в_claud_fable/Solana-audit-by-Claude-File5-9июня2026.md diff --git a/shine-UI/js/pages/registration-payment-view.js b/shine-UI/js/pages/registration-payment-view.js index 5740749d..4e54e206 100644 --- a/shine-UI/js/pages/registration-payment-view.js +++ b/shine-UI/js/pages/registration-payment-view.js @@ -257,8 +257,8 @@ export function render({ navigate }) { topupButton.textContent = 'Пополнить кошелёк'; topupButton.addEventListener('click', async () => { try { - const walletAddress = await deriveUserWalletAddress(); - window.open(getTopupSiteUrl(walletAddress), '_blank', 'noopener,noreferrer'); + await deriveUserWalletAddress(); + navigate('topup-view'); } catch (error) { status.className = 'status-line is-unavailable'; status.textContent = `Не удалось подготовить кошелёк: ${error?.message || 'unknown'}`; @@ -301,10 +301,8 @@ export function render({ navigate }) { : `Для регистрации пополните этот кошелёк соланами примерно на ${RECOMMENDED_TOPUP_SOL} SOL. Сейчас на кошельке ${formatSol(currentBalance, 6)} SOL. Минимум для продолжения: ${MIN_REQUIRED_SOL} SOL.`; status.style.display = ''; if (isTestContour) { - const openTopup = window.confirm('Открыть страницу пополнения с вашим кошельком?'); - if (openTopup) { - window.open(getTopupSiteUrl(walletAddress), '_blank', 'noopener,noreferrer'); - } + const openTopup = window.confirm('Перейти на экран пополнения и затем продолжить регистрацию?'); + if (openTopup) navigate('topup-view'); } return; } diff --git a/shine-UI/js/pages/topup-view.js b/shine-UI/js/pages/topup-view.js index 2fb17fd8..09d61665 100644 --- a/shine-UI/js/pages/topup-view.js +++ b/shine-UI/js/pages/topup-view.js @@ -1,14 +1,18 @@ import { renderHeader } from '../components/header.js'; import { state } from '../state.js'; import { + createSolanaWalletFromPrivateBase58, formatSol, getBalanceSol, getTopupSiteUrl, - requestAirdropSol, + transferSol, } from '../services/solana-wallet-service.js'; import { loadSolanaWeb3 } from '../vendor/solana-web3-loader.js'; -export const pageMeta = { id: 'topup-view', title: 'Пополнение счета', showAppChrome: false }; +export const pageMeta = { id: 'topup-view', title: 'Пополнение solana счета', showAppChrome: false }; +const DEVNET_ENDPOINT = 'https://api.devnet.solana.com'; +const SENDER_PRIVATE_32_BASE58 = '6xqAuKYvA8qrCdAkcw7Y8aMgvBnYk8JLxWLma5BzbAvu'; +const REGISTRATION_TOPUP_AMOUNT_SOL = 0.02; // Канонический Solana-адрес пополнения = публичный device-ключ из сгенерированного набора ключей. // Тот же путь, что в registration-payment-view (deriveUserWalletAddress); не выводим адрес @@ -39,6 +43,10 @@ export function render({ navigate }) { const status = document.createElement('p'); status.className = 'meta-muted'; status.textContent = 'Проверяем кошелек...'; + status.style.whiteSpace = 'pre-wrap'; + status.style.overflowWrap = 'anywhere'; + status.style.wordBreak = 'break-word'; + status.style.fontSize = '13px'; const copyButton = document.createElement('button'); copyButton.className = 'ghost-btn'; @@ -63,42 +71,54 @@ export function render({ navigate }) { const card = document.createElement('div'); card.className = 'card stack'; card.innerHTML = ` -

Кнопка «Пополнить» в кошельке будет переводить на отдельный сайт. Пока доступно тестовое пополнение.

-
-

1. Вы можете открыть промо-сайт пополнения с подставленным кошельком.

-

2. Либо нажать «Тестовое пополнение» и получить 1 SOL через DevNet airdrop.

-
- Открыть сайт пополнения +

Можете или пополнить счёт тестовыми соланами и продолжить регистрацию.

Кошелёк для пополнения (client key = Solana wallet)
+
+

Или можете отдельно открыть страницу тестового пополнения.

+ Открыть страницу тестового пополнения +
`; - card.children[3].append(walletRow); + card.children[1].append(walletRow); const testButton = document.createElement('button'); testButton.className = 'ghost-btn'; testButton.type = 'button'; - testButton.textContent = 'Тестовое пополнение (1 SOL)'; + testButton.textContent = 'Тестовое пополнение для регистрации'; testButton.addEventListener('click', async () => { const address = String(walletValue.value || '').trim(); if (!address) { window.alert('Адрес кошелька не найден.'); return; } + if (!senderKeypair) { + status.textContent = 'Ошибка: тестовый кошелёк отправителя ещё не инициализирован.'; + return; + } testButton.disabled = true; try { - const drop = await requestAirdropSol({ - endpoint: state.entrySettings.solanaServer, - address, - amountSol: 1, + status.textContent = 'Отправляем тестовое пополнение для регистрации...'; + const tx = await transferSol({ + endpoint: DEVNET_ENDPOINT, + fromKeypair: senderKeypair, + toAddress: address, + amountSol: REGISTRATION_TOPUP_AMOUNT_SOL, }); const bal = await getBalanceSol({ - endpoint: state.entrySettings.solanaServer, + endpoint: DEVNET_ENDPOINT, address, }); state.registrationPayment.balanceSOL = String(bal.sol); - status.textContent = `Тестовое пополнение выполнено. Новый баланс: ${formatSol(bal.sol, 6)} SOL. Signature: ${drop.signature}`; + status.style.fontSize = '12px'; + status.textContent = [ + 'Тестовое пополнение для регистрации выполнено.', + `Кошелёк пополнен на ${REGISTRATION_TOPUP_AMOUNT_SOL} SOL.`, + `Новый баланс: ${formatSol(bal.sol, 6)} SOL.`, + `Signature: ${tx.signature}`, + ].join('\n'); } catch (error) { + status.style.fontSize = '13px'; status.textContent = `Ошибка тестового пополнения: ${error?.message || 'unknown'}`; } finally { testButton.disabled = false; @@ -108,12 +128,13 @@ export function render({ navigate }) { const backButton = document.createElement('button'); backButton.className = 'primary-btn'; backButton.type = 'button'; - backButton.textContent = 'Назад'; + backButton.textContent = 'Продолжить регистрацию'; backButton.addEventListener('click', () => navigate('registration-payment-view')); const actions = document.createElement('div'); actions.className = 'auth-footer-actions'; actions.append(testButton, backButton); + let senderKeypair = null; (async () => { try { @@ -132,6 +153,8 @@ export function render({ navigate }) { }); state.registrationPayment.balanceSOL = String(balance.sol); status.textContent = `Текущий баланс: ${formatSol(balance.sol, 6)} SOL`; + const sender = await createSolanaWalletFromPrivateBase58(SENDER_PRIVATE_32_BASE58); + senderKeypair = sender.keypair; } catch (error) { status.textContent = `Не удалось получить баланс: ${error?.message || 'unknown'}`; } @@ -139,7 +162,7 @@ export function render({ navigate }) { screen.append( renderHeader({ - title: 'Пополнение счета', + title: 'Пополнение solana счета', leftAction: { label: '←', onClick: () => navigate('registration-payment-view') }, }), card,