diff --git a/SHiNE-server/AGENTS.md b/SHiNE-server/AGENTS.md index 573f3bea..2cf116e6 100644 --- a/SHiNE-server/AGENTS.md +++ b/SHiNE-server/AGENTS.md @@ -9,7 +9,7 @@ SHiNE-server — серверная часть мессенджера SHiNE: Web - `shine-server-net-server/` — точка входа, запуск HTTP/WS сервера - `shine-server-net-protocol/` — обработчики операций (RPC и события WS) -- `shine-server-db/` — DAO, SQL-схема, SQLite +- `shine-server-db/` — DAO, SQL-схема, PostgreSQL runtime - `shine-server-blockchain/` — логика хранения и проверки блоков блокчейна - `shine-server-crypto/` — криптографические утилиты - `shine-server-config/` — конфигурация сервера diff --git a/SHiNE-server/shine-server-db/src/main/java/shine/db/DbController.java b/SHiNE-server/shine-server-db/src/main/java/shine/db/DbController.java index 11cb1409..72dec60c 100644 --- a/SHiNE-server/shine-server-db/src/main/java/shine/db/DbController.java +++ b/SHiNE-server/shine-server-db/src/main/java/shine/db/DbController.java @@ -36,10 +36,6 @@ public final class DbController implements DbProvider { return delegate.getConnection(); } - public boolean isPostgres() { - return true; - } - @Override public void close() { delegate.close(); diff --git a/SHiNE-server/shine-server-db/src/main/java/shine/db/connection/DriverManagerDbProvider.java b/SHiNE-server/shine-server-db/src/main/java/shine/db/connection/DriverManagerDbProvider.java index be5b4362..ec90a154 100644 --- a/SHiNE-server/shine-server-db/src/main/java/shine/db/connection/DriverManagerDbProvider.java +++ b/SHiNE-server/shine-server-db/src/main/java/shine/db/connection/DriverManagerDbProvider.java @@ -7,7 +7,7 @@ import java.sql.SQLException; /** * Базовый JDBC provider поверх DriverManager. * - * Не знает ничего про SQLite/PostgreSQL как про доменные режимы: + * Не знает ничего про конкретный доменный режим БД: * конкретные параметры и post-connect инициализация задаются снаружи. */ public final class DriverManagerDbProvider implements DbProvider { diff --git a/SHiNE-server/shine-server-db/src/main/java/shine/db/dao/BlockchainResyncCleanupDAO.java b/SHiNE-server/shine-server-db/src/main/java/shine/db/dao/BlockchainResyncCleanupDAO.java index f2ad4d8f..423bc74b 100644 --- a/SHiNE-server/shine-server-db/src/main/java/shine/db/dao/BlockchainResyncCleanupDAO.java +++ b/SHiNE-server/shine-server-db/src/main/java/shine/db/dao/BlockchainResyncCleanupDAO.java @@ -24,7 +24,7 @@ import java.sql.SQLException; * - эта схема проще и прозрачнее, чем много обратных триггеров по разным таблицам; * - если любой шаг не удался, делаем rollback и БД остаётся в исходном состоянии; * - файловые действия (.bch / .tmp_bch) сознательно НЕ входят в эту транзакцию: - * SQLite не может атомарно закоммитить и SQL, и файловую систему сразу; + * SQL-транзакция и файловая система не коммитятся атомарно вместе; * поэтому БД-чистка делается здесь, а файловая чистка будет следующим шагом * отдельным recovery/resync-слоем после успешного commit. * diff --git a/SHiNE-server/shine-server-db/src/main/java/shine/db/dao/SolanaUsersDAO.java b/SHiNE-server/shine-server-db/src/main/java/shine/db/dao/SolanaUsersDAO.java index d681287b..6ff8ed30 100644 --- a/SHiNE-server/shine-server-db/src/main/java/shine/db/dao/SolanaUsersDAO.java +++ b/SHiNE-server/shine-server-db/src/main/java/shine/db/dao/SolanaUsersDAO.java @@ -14,7 +14,7 @@ import java.util.List; * Таблица: solana_users * * Колонки: - * - login TEXT PRIMARY KEY (COLLATE NOCASE) + * - login TEXT PRIMARY KEY * - blockchain_name TEXT NOT NULL * - solana_key TEXT NOT NULL * - blockchain_key TEXT NOT NULL diff --git a/SHiNE-server/shine-server-db/src/main/java/shine/db/entities/SolanaUserEntry.java b/SHiNE-server/shine-server-db/src/main/java/shine/db/entities/SolanaUserEntry.java index 7552faf1..ee0e7a20 100644 --- a/SHiNE-server/shine-server-db/src/main/java/shine/db/entities/SolanaUserEntry.java +++ b/SHiNE-server/shine-server-db/src/main/java/shine/db/entities/SolanaUserEntry.java @@ -8,7 +8,7 @@ import java.util.Base64; * Таблица: solana_users * * Поля: - * - login — PRIMARY KEY (TEXT) (case-insensitive на уровне COLLATE NOCASE) + * - login — PRIMARY KEY (TEXT) * - blockchain_name — TEXT NOT NULL * - solana_key — TEXT NOT NULL * - blockchain_key — TEXT NOT NULL @@ -81,4 +81,4 @@ public class SolanaUserEntry { return null; } -} \ No newline at end of file +} diff --git a/SHiNE-server/shine-server-db/src/main/resources/postgres/schema_v1.sql b/SHiNE-server/shine-server-db/src/main/resources/postgres/schema_v1.sql index 1da3fe34..69da9863 100644 --- a/SHiNE-server/shine-server-db/src/main/resources/postgres/schema_v1.sql +++ b/SHiNE-server/shine-server-db/src/main/resources/postgres/schema_v1.sql @@ -4,7 +4,7 @@ -- Назначение: -- - поднять пустую PostgreSQL БД сервера SHiNE с нуля; -- - включить таблицы модуля синхронизации Solana users; --- - включить runtime-таблицы сервера без legacy SQLite таблиц: +-- - включить runtime-таблицы сервера без legacy-таблиц старого runtime: -- * НЕ создаём solana_users -- * НЕ создаём direct_messages -- * основной runtime DM storage = signed_messages @@ -12,7 +12,7 @@ -- Важно: -- - источник истины по пользователям: solana_user_pda_current; -- - runtime table blockchain_state остаётся как локальное серверное состояние chain, --- но не мигрируется из старой SQLite и не считается identity-слоем; +-- но не мигрируется из старого локального runtime и не считается identity-слоем; -- - триггеры переписаны под PostgreSQL и сохраняют текущую серверную логику. BEGIN; diff --git a/SHiNE-server/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/connections/Net_AddCloseFriend_Handler.java b/SHiNE-server/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/connections/Net_AddCloseFriend_Handler.java index 9c0fe3d1..bf55ee5e 100644 --- a/SHiNE-server/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/connections/Net_AddCloseFriend_Handler.java +++ b/SHiNE-server/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/connections/Net_AddCloseFriend_Handler.java @@ -42,8 +42,7 @@ public class Net_AddCloseFriend_Handler implements JsonMessageHandler { } // Idempotent insert for close-friend relation. - // Using INSERT OR IGNORE avoids ON CONFLICT(column list) mismatches - // across DB instances with different UNIQUE schemas. + // Rely on PostgreSQL ON CONFLICT DO NOTHING. insertCloseFriendIgnoreDuplicate(c, from, canonicalTo, targetBch); Net_AddCloseFriend_Response resp = new Net_AddCloseFriend_Response(); diff --git a/THIRD_PARTY_NOTICES.md b/THIRD_PARTY_NOTICES.md index 9393aae8..42e7a809 100644 --- a/THIRD_PARTY_NOTICES.md +++ b/THIRD_PARTY_NOTICES.md @@ -67,7 +67,7 @@ The SHiNE Java server uses third-party dependencies from Maven Central, includin - Jackson (`com.fasterxml.jackson.core:jackson-databind`) - Apache-2.0 - Logback (`ch.qos.logback:logback-classic`) - EPL-1.0 / LGPL-2.1 - SLF4J (`org.slf4j:slf4j-api`) - MIT -- SQLite JDBC (`org.xerial:sqlite-jdbc`) - Apache-2.0 +- PostgreSQL JDBC (`org.postgresql:postgresql`) - BSD-2-Clause - Web Push Java library (`nl.martijndwars:web-push`) - Apache-2.0 - JUnit (`org.junit:*`) - EPL-2.0 diff --git a/TODO/README.md b/TODO/README.md index 6d4c72ff..6a13506f 100644 --- a/TODO/README.md +++ b/TODO/README.md @@ -49,7 +49,7 @@ - `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-07-22_переход_с_sqlite_на_postgresql.md` - подготовить перевод серверной БД с `SQLite` на `PostgreSQL` для более серьёзной конкурентной нагрузки и дальнейшего масштабирования. +- `medium/2026-07-22_переход_с_sqlite_на_postgresql.md` - завершить зачистку хвостов после перевода серверной БД с `SQLite` на `PostgreSQL`. ### dao_запуск diff --git a/TODO/medium/2026-07-22_переход_с_sqlite_на_postgresql.md b/TODO/medium/2026-07-22_переход_с_sqlite_на_postgresql.md index 95b90fc8..72c097a1 100644 --- a/TODO/medium/2026-07-22_переход_с_sqlite_на_postgresql.md +++ b/TODO/medium/2026-07-22_переход_с_sqlite_на_postgresql.md @@ -2,32 +2,30 @@ ## Зачем -Текущая серверная база на `SQLite` удобна для простого односерверного режима, но она хуже подходит для большого числа параллельных записей, роста нагрузки и дальнейшего масштабирования сервера. +Переход runtime-сервера на `PostgreSQL` уже выполнен, но после него остались хвосты в документации, именах, комментариях и части прямых SQL-запросов. -`PostgreSQL` нужен как следующий уровень серверной БД для более надёжной конкурентной записи, более предсказуемой работы под нагрузкой и дальнейшего роста проекта. +Этот TODO теперь нужен не для самого перехода, а для доведения проекта до полностью консистентного состояния после ухода от `SQLite`. ## Что сделать -- Подготовить план переноса серверной БД с `SQLite` на `PostgreSQL`. -- Найти все места, где код завязан на особенности `SQLite`. -- Проверить все DAO и SQL-запросы на совместимость с `PostgreSQL`. -- Продумать схему миграции существующей production/test базы без потери данных. -- Отдельно проверить транзакции, `UPSERT`, индексы, case-insensitive сравнения и миграции схемы. -- После этого подготовить отдельный этап внедрения и переключения сервера. +- Дочистить документацию, где ещё описан `SQLite` как текущий runtime. +- Убрать или переименовать legacy-названия и комментарии, которые уже не соответствуют PostgreSQL runtime. +- Постепенно перенести оставшиеся прямые SQL-запросы из хэндлеров в DAO/service. +- Проверить case-insensitive сравнения, уникальные ограничения и индексы уже в чисто PostgreSQL модели. +- Отдельно пройтись по TODO/служебным документам и убрать ссылки на удалённые SQLite-классы как на актуальный код. ## Что уже есть в коде - Доступ к БД в основном проходит через DAO-слой, а не полностью размазан по проекту. - Основная серверная логика уже разделена по модулям. -- Но SQL и миграции сейчас написаны под `SQLite` и потребуют отдельного прохода. +- Runtime-сервер уже работает только с `PostgreSQL`. +- Пустая БД инициализируется автоматически через `schema_v1`. ## Откуда продолжать -- Начать с инвентаризации всех DAO и схемы БД. -- После этого сделать отдельный документ с оценкой объёма работ по переносу. -- Затем решить, будет ли это: - - полный перевод сервера на `PostgreSQL`; - - или поддержка двух драйверов на переходный период. +- Продолжать с зачистки legacy-документации и комментариев. +- Затем добрать оставшиеся прямые SQL-запросы вне DAO. +- После этого можно отдельно решать вопрос косметического переименования `*V2`, `DbController` и других переходных сущностей. ## Что потом обновить diff --git a/TODO/near/2026-07-07_дм_v11_убрать_временную_очистку_signed_messages.md b/TODO/near/2026-07-07_дм_v11_убрать_временную_очистку_signed_messages.md index e4b1bcb9..2b04642a 100644 --- a/TODO/near/2026-07-07_дм_v11_убрать_временную_очистку_signed_messages.md +++ b/TODO/near/2026-07-07_дм_v11_убрать_временную_очистку_signed_messages.md @@ -11,7 +11,7 @@ ## Что именно потом сделать -- удалить временную миграцию `migrateToV11()` из [SqliteDbController.java](/home/ai/work/SHiNE/SHiNE-server-sha256/SHiNE-server/shine-server-db/src/main/java/shine/db/SqliteDbController.java); +- найти историческое место, где была добавлена временная миграция `migrateToV11()`, и убрать её остатки из runtime-логики/документации; - удалить helper `clearLegacySignedMessagesForDmV11(...)`; - поднять версию схемы дальше обычным образом уже без destructive-cleanup; - при необходимости заменить это на нормальную точечную миграцию старых DM-записей или совсем убрать поддержку старой истории. diff --git a/VERSION.properties b/VERSION.properties index 8e9a67ec..d1394bda 100644 --- a/VERSION.properties +++ b/VERSION.properties @@ -1,2 +1,2 @@ client.version=1.2.354 -server.version=1.2.331 +server.version=1.2.332 diff --git a/deploy/SETUP_SERVER_FROM_ZERO.md b/deploy/SETUP_SERVER_FROM_ZERO.md index de4b6f6d..7e20b2f7 100644 --- a/deploy/SETUP_SERVER_FROM_ZERO.md +++ b/deploy/SETUP_SERVER_FROM_ZERO.md @@ -46,7 +46,9 @@ Production пример: ```properties server.port=7070 server.SHiNE.login=shineupme -db.path=data/shine.sqlite +db.url=jdbc:postgresql://127.0.0.1:5432/shine_server_db +db.user=shine_server +db.password=CHANGE_ME server.ui.indexPath=/home/player/SHiNE/shine-ui/index.html server.info.url=https://shineup.me server.info.origin=production @@ -58,7 +60,9 @@ Test/devnet пример: ```properties server.port=7102 server.SHiNE.login=server_t2 -db.path=data/shine.sqlite +db.url=jdbc:postgresql://127.0.0.1:5432/shine_t2_db +db.user=shine_t2 +db.password=CHANGE_ME server.ui.indexPath=/home/player/t2/UI/index.html server.info.url=https://t2.shineup.me server.info.origin=devnet @@ -66,6 +70,9 @@ solana.cluster=devnet solana.rpcUrl=https://api.devnet.solana.com ``` +Если указан `db.url` и в выбранной БД ещё нет таблицы `db_schema_version`, +сервер сам создаст runtime-схему PostgreSQL при первом старте. + ## 5. Caddy Минимальный site block: diff --git a/deploy/SOLANA_USERS_SYNC_SERVER_SETUP.md b/deploy/SOLANA_USERS_SYNC_SERVER_SETUP.md index 5c80df7f..bb96d8f0 100644 --- a/deploy/SOLANA_USERS_SYNC_SERVER_SETUP.md +++ b/deploy/SOLANA_USERS_SYNC_SERVER_SETUP.md @@ -92,5 +92,5 @@ cp /path/to/SHiNE-product/application.properties ./application.properties ## Что пока остаётся как есть - `sync_servers` сервер по-прежнему загружает из server PDA в Solana; -- старый SQLite runtime код ещё может лежать в репозитории, но новая runtime-схема на него не должна опираться; -- механический перенос DAO и runtime SQL на PostgreSQL делается отдельным шагом после утверждения схемы `v1`. +- runtime-сервер уже работает только с PostgreSQL; +- дальнейшим отдельным шагом остаются зачистка legacy-документации, переименования и перенос оставшихся прямых SQL-запросов в DAO/service. diff --git a/docs/API/14_Test_Free_Avatar_Upload_API.md b/docs/API/14_Test_Free_Avatar_Upload_API.md index 29438ff6..7fb55656 100644 --- a/docs/API/14_Test_Free_Avatar_Upload_API.md +++ b/docs/API/14_Test_Free_Avatar_Upload_API.md @@ -9,7 +9,7 @@ - загрузка идёт через **серверный Arweave-кошелёк**; - лимит на пользователя: по умолчанию `3` загрузки за всё время; -- лимит хранится в SQLite-таблице `test_free_avatar_uploads`; +- лимит хранится в PostgreSQL-таблице `test_free_avatar_uploads`; - если лимит исчерпан, сервер возвращает понятную ошибку; - загружать можно только маленький итоговый файл аватара, по умолчанию до `128 KB`. diff --git a/docs/Solana/SOLANA_USERS_SYNC_MODULE_DESIGN.md b/docs/Solana/SOLANA_USERS_SYNC_MODULE_DESIGN.md index 0aa9ded4..725ede05 100644 --- a/docs/Solana/SOLANA_USERS_SYNC_MODULE_DESIGN.md +++ b/docs/Solana/SOLANA_USERS_SYNC_MODULE_DESIGN.md @@ -550,7 +550,7 @@ SYNC_POLL_INTERVAL_SECONDS=300 3. выделить lifecycle-сервис с `awaitReady()`; 4. реализовать вычисление `users_economy_config_pda`; 5. реализовать polling истории по сигнатурам; -6. добавить новые SQLite-таблицы; +6. добавить runtime-таблицы PostgreSQL; 7. добавить запись в `current` и `history`; 8. добавить periodic guard раз в 5 минут; 9. сохранить отдельный `main` для запуска как процесса. diff --git a/docs/libs/shine-server-bd/DOC.md b/docs/libs/shine-server-bd/DOC.md index aae2dfaa..0c7fcffe 100644 --- a/docs/libs/shine-server-bd/DOC.md +++ b/docs/libs/shine-server-bd/DOC.md @@ -1,17 +1,16 @@ shine-server-bd — это библиотека реалезующая всю работу с БД: -хранит пользователей/сессии/параметры/кэш IP→гео и данные блокчейна (состояние + блоки), предоставляя единый SqliteDbController для соединений, набор DAO под каждую таблицу (Singleton, методы с Connection для транзакций и без Connection — сами открывают/закрывают), и простые entity-модели как контейнеры данных для маппинга ResultSet↔Java. +хранит пользователей/сессии/параметры/кэш IP→гео и данные блокчейна (состояние + блоки), предоставляя единый PostgreSQL runtime-контроллер соединений, набор DAO под каждую таблицу (Singleton, методы с Connection для транзакций и без Connection — сами открывают/закрывают), и простые entity-модели как контейнеры данных для маппинга ResultSet↔Java. Логика структуры классов (в двух словах): -shine.db.SqliteDbController — один вход в БД: читает db.path, при отсутствии файла создаёт БД, выдаёт новые Connection и настраивает PRAGMA. -shine.db.DatabaseInitializer — разовая сборка схемы (таблицы + индексы). +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, SolanaUsersDAO, UserParamsDAO, IpGeoCacheDAO, BlockchainStateDAO, BlocksDAO; плюс “сервисные” DAO: UserCreateDAO — атомарная регистрация пользователя в транзакции (BEGIN IMMEDIATE + rollback/commit). -// Временное решение позволяющее регистрировать новых пользователей -// атомарно и добавляет запись и в solana_users и в BlockchainState - +// Временное runtime-решение, позволяющее регистрировать новых пользователей +// атомарно и добавляющее запись в runtime-таблицы сервера. diff --git a/docs/libs/shine-server-bd/POSTGRES_RUNTIME_SCHEMA_V1.md b/docs/libs/shine-server-bd/POSTGRES_RUNTIME_SCHEMA_V1.md index dd5c441d..b6cb1641 100644 --- a/docs/libs/shine-server-bd/POSTGRES_RUNTIME_SCHEMA_V1.md +++ b/docs/libs/shine-server-bd/POSTGRES_RUNTIME_SCHEMA_V1.md @@ -62,7 +62,7 @@ ## Что не входит в v1 -- удаление legacy SQLite-классов; +- полная зачистка legacy-документации, старых названий и TODO-хвостов; - переименование Java DAO/классов `*V2` в runtime-коде; - перенос прямых SQL-запросов из хэндлеров в DAO/service; - переключение всего runtime-кода на новый `DbProvider`. diff --git a/docs/libs/shine-server-config/doc.md b/docs/libs/shine-server-config/doc.md index e2f49003..929add26 100644 --- a/docs/libs/shine-server-config/doc.md +++ b/docs/libs/shine-server-config/doc.md @@ -4,4 +4,6 @@ shine-server-config Настройки: server.port=7070 — порт запуска сервера -db.path=data/shine.sqlite — путь к SQLite базе данных \ No newline at end of file +db.url=jdbc:postgresql://127.0.0.1:5432/shine_server_db — JDBC URL PostgreSQL +db.user=shine_server — пользователь PostgreSQL +db.password=... — пароль пользователя PostgreSQL