Remove docs/ folder from git tracking (now ignored)
This commit is contained in:
@@ -1,269 +0,0 @@
|
|||||||
<!--
|
|
||||||
Copyright (c) 2024-2025 Тарабанов Александр Викторович
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
This software is proprietary and confidential.
|
|
||||||
Unauthorized copying, modification, or distribution is prohibited.
|
|
||||||
|
|
||||||
For licensing inquiries: info@hb3-accelerator.com
|
|
||||||
Website: https://hb3-accelerator.com
|
|
||||||
GitHub: https://github.com/HB3-ACCELERATOR
|
|
||||||
-->
|
|
||||||
|
|
||||||
# Архитектура проекта DLE
|
|
||||||
|
|
||||||
## 🎯 Общий принцип
|
|
||||||
|
|
||||||
**Backend** - только для чтения данных из блокчейна
|
|
||||||
**Frontend** - для выполнения транзакций через MetaMask
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📋 Что у нас есть:
|
|
||||||
|
|
||||||
### 1. ✅ **Смарт контракт DLE.sol**
|
|
||||||
- Находится в `backend/contracts/DLE.sol`
|
|
||||||
- Содержит все функции для управления DLE
|
|
||||||
- Деплоится в сеть Sepolia (Chain ID: 11155111)
|
|
||||||
|
|
||||||
### 2. ✅ **Backend API (модульная архитектура)**
|
|
||||||
- **Порт:** 8000
|
|
||||||
- **Принцип:** Разделение по функциональности
|
|
||||||
- **Функции только для чтения данных из блокчейна**
|
|
||||||
|
|
||||||
### 3. ✅ **Frontend (выполнение транзакций)**
|
|
||||||
- Файл: `frontend/src/utils/dle-contract.js`
|
|
||||||
- Порт: 5173
|
|
||||||
- **Функции для выполнения транзакций через MetaMask**
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🔄 Как это работает:
|
|
||||||
|
|
||||||
### **Чтение данных:**
|
|
||||||
```
|
|
||||||
Frontend → Backend API → Blockchain
|
|
||||||
```
|
|
||||||
|
|
||||||
### **Выполнение транзакций:**
|
|
||||||
```
|
|
||||||
Frontend → MetaMask → Blockchain
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📚 Backend API (модульная архитектура):
|
|
||||||
|
|
||||||
### 🏗️ Структура модулей:
|
|
||||||
|
|
||||||
```
|
|
||||||
backend/routes/
|
|
||||||
├── dleCore.js # Основные функции DLE
|
|
||||||
├── dleProposals.js # Функции предложений
|
|
||||||
├── dleModules.js # Функции модулей
|
|
||||||
├── dleTokens.js # Функции токенов
|
|
||||||
├── dleAnalytics.js # Аналитика и история
|
|
||||||
├── dleMultichain.js # Мультичейн функции
|
|
||||||
└── blockchain.js # Устаревший монолитный файл
|
|
||||||
```
|
|
||||||
|
|
||||||
### 🔧 Модули и их функции:
|
|
||||||
|
|
||||||
#### **dleCore.js** - Основные функции DLE:
|
|
||||||
- `POST /dle-core/read-dle-info` - информация о DLE
|
|
||||||
- `POST /dle-core/get-governance-params` - параметры управления
|
|
||||||
- `POST /dle-core/is-active` - проверка активности DLE
|
|
||||||
- `POST /dle-core/deactivate-dle` - проверка возможности деактивации
|
|
||||||
|
|
||||||
#### **dleProposals.js** - Функции предложений:
|
|
||||||
- `POST /dle-proposals/get-proposals` - список предложений
|
|
||||||
- `POST /dle-proposals/get-proposal-info` - информация о предложении
|
|
||||||
- `POST /dle-proposals/get-proposal-state` - состояние предложения
|
|
||||||
- `POST /dle-proposals/get-proposal-votes` - голоса по предложению
|
|
||||||
- `POST /dle-proposals/get-proposals-count` - количество предложений
|
|
||||||
- `POST /dle-proposals/list-proposals` - список с пагинацией
|
|
||||||
- `POST /dle-proposals/get-voting-power-at` - голосующая сила
|
|
||||||
- `POST /dle-proposals/get-quorum-at` - требуемый кворум
|
|
||||||
|
|
||||||
#### **dleModules.js** - Функции модулей:
|
|
||||||
- `POST /dle-modules/is-module-active` - активность модуля
|
|
||||||
- `POST /dle-modules/get-module-address` - адрес модуля
|
|
||||||
- `POST /dle-modules/get-all-modules` - все модули
|
|
||||||
- `POST /dle-modules/create-add-module-proposal` - предложение добавления
|
|
||||||
- `POST /dle-modules/create-remove-module-proposal` - предложение удаления
|
|
||||||
|
|
||||||
#### **dleTokens.js** - Функции токенов:
|
|
||||||
- `POST /dle-tokens/get-token-balance` - баланс токенов
|
|
||||||
- `POST /dle-tokens/get-total-supply` - общее предложение
|
|
||||||
- `POST /dle-tokens/get-token-holders` - держатели токенов
|
|
||||||
|
|
||||||
#### **dleAnalytics.js** - Аналитика и история:
|
|
||||||
- `POST /dle-analytics/get-dle-analytics` - аналитика DLE
|
|
||||||
- `POST /dle-analytics/get-dle-history` - история событий
|
|
||||||
|
|
||||||
#### **dleMultichain.js** - Мультичейн функции:
|
|
||||||
- `POST /dle-multichain/get-supported-chains` - поддерживаемые сети
|
|
||||||
- `POST /dle-multichain/is-chain-supported` - проверка поддержки сети
|
|
||||||
- `POST /dle-multichain/get-supported-chain-count` - количество сетей
|
|
||||||
- `POST /dle-multichain/get-supported-chain-id` - ID сети по индексу
|
|
||||||
- `POST /dle-multichain/check-chain-connection` - подключение к сети
|
|
||||||
- `POST /dle-multichain/check-sync-readiness` - готовность синхронизации
|
|
||||||
- `POST /dle-multichain/sync-to-all-chains` - синхронизация
|
|
||||||
- `POST /dle-multichain/execute-proposal-by-signatures` - исполнение по подписям
|
|
||||||
|
|
||||||
### Что НЕ делает backend:
|
|
||||||
- ❌ Не создает предложения
|
|
||||||
- ❌ Не голосует
|
|
||||||
- ❌ Не исполняет предложения
|
|
||||||
- ❌ Не требует приватные ключи
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🔐 Frontend (транзакции через MetaMask):
|
|
||||||
|
|
||||||
### Основные функции в `dle-contract.js`:
|
|
||||||
```javascript
|
|
||||||
// Создание предложения
|
|
||||||
createProposal(dleAddress, proposalData)
|
|
||||||
|
|
||||||
// Голосование
|
|
||||||
voteForProposal(dleAddress, proposalId, support)
|
|
||||||
|
|
||||||
// Исполнение предложения
|
|
||||||
executeProposal(dleAddress, proposalId)
|
|
||||||
|
|
||||||
// Подключение к кошельку
|
|
||||||
checkWalletConnection()
|
|
||||||
```
|
|
||||||
|
|
||||||
### Как использовать:
|
|
||||||
```javascript
|
|
||||||
import { createProposal } from '@/utils/dle-contract.js';
|
|
||||||
|
|
||||||
// Создаем предложение через MetaMask
|
|
||||||
const result = await createProposal(dleAddress, {
|
|
||||||
description: "Новое предложение",
|
|
||||||
duration: 86400,
|
|
||||||
operation: "0x...",
|
|
||||||
governanceChainId: 11155111,
|
|
||||||
targetChains: [11155111, 137]
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🔄 Frontend сервисы (модульная архитектура):
|
|
||||||
|
|
||||||
### 📁 Структура сервисов:
|
|
||||||
```
|
|
||||||
frontend/src/services/
|
|
||||||
├── dleV2Service.js # Основные функции DLE
|
|
||||||
├── proposalsService.js # Функции предложений
|
|
||||||
├── modulesService.js # Функции модулей
|
|
||||||
├── tokensService.js # Функции токенов
|
|
||||||
├── analyticsService.js # Аналитические данные
|
|
||||||
├── multichainService.js # Мультичейн функциональность
|
|
||||||
└── index.js # Индексный файл для импорта
|
|
||||||
```
|
|
||||||
|
|
||||||
### 🔗 Соответствие backend модулям:
|
|
||||||
|
|
||||||
| Backend модуль | Frontend сервис | Описание |
|
|
||||||
|----------------|-----------------|----------|
|
|
||||||
| `dleCore.js` | `dleV2Service.js` | Основные функции DLE |
|
|
||||||
| `dleProposals.js` | `proposalsService.js` | Управление предложениями |
|
|
||||||
| `dleModules.js` | `modulesService.js` | Управление модулями |
|
|
||||||
| `dleTokens.js` | `tokensService.js` | Работа с токенами |
|
|
||||||
| `dleAnalytics.js` | `analyticsService.js` | Аналитика и история |
|
|
||||||
| `dleMultichain.js` | `multichainService.js` | Мультичейн функции |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🚀 Пример полного цикла:
|
|
||||||
|
|
||||||
### 1. Чтение данных DLE:
|
|
||||||
```javascript
|
|
||||||
// Frontend → Backend API (новые модульные endpoints)
|
|
||||||
const response = await fetch('/api/dle-core/read-dle-info', {
|
|
||||||
method: 'POST',
|
|
||||||
body: JSON.stringify({ dleAddress: '0x...' })
|
|
||||||
});
|
|
||||||
const dleInfo = response.data;
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. Создание предложения:
|
|
||||||
```javascript
|
|
||||||
// Frontend → MetaMask → Blockchain
|
|
||||||
import { createProposal } from '@/utils/dle-contract.js';
|
|
||||||
|
|
||||||
const result = await createProposal(dleAddress, proposalData);
|
|
||||||
console.log('Предложение создано:', result.txHash);
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. Голосование:
|
|
||||||
```javascript
|
|
||||||
// Frontend → MetaMask → Blockchain
|
|
||||||
import { voteForProposal } from '@/utils/dle-contract.js';
|
|
||||||
|
|
||||||
const result = await voteForProposal(dleAddress, proposalId, true);
|
|
||||||
console.log('Голосование выполнено:', result.txHash);
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🔧 Порты и URL:
|
|
||||||
|
|
||||||
- **Frontend:** `http://localhost:5173`
|
|
||||||
- **Backend:** `http://localhost:8000`
|
|
||||||
- **API через proxy:** `http://localhost:5173/api`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ✅ Преимущества модульной архитектуры:
|
|
||||||
|
|
||||||
### 🔒 Безопасность:
|
|
||||||
- Нет приватных ключей на сервере
|
|
||||||
- Транзакции подписываются пользователем через MetaMask
|
|
||||||
|
|
||||||
### 🏗️ Модульность:
|
|
||||||
- Четкое разделение ответственности
|
|
||||||
- Легко поддерживать и тестировать
|
|
||||||
- Простое добавление новых функций
|
|
||||||
|
|
||||||
### 📈 Масштабируемость:
|
|
||||||
- Каждый модуль можно развивать независимо
|
|
||||||
- Возможность переиспользования кода
|
|
||||||
- Простое развертывание отдельных компонентов
|
|
||||||
|
|
||||||
### 🎯 Читаемость:
|
|
||||||
- Понятная структура файлов
|
|
||||||
- Логическое группирование функций
|
|
||||||
- Удобная навигация по коду
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🎯 Итог:
|
|
||||||
|
|
||||||
### 📊 Статистика рефакторинга:
|
|
||||||
|
|
||||||
| Модуль | Endpoints | Строк кода | Описание |
|
|
||||||
|--------|-----------|------------|----------|
|
|
||||||
| `dleCore.js` | 4 | ~200 | Основные функции DLE |
|
|
||||||
| `dleProposals.js` | 10 | ~400 | Управление предложениями |
|
|
||||||
| `dleModules.js` | 5 | ~150 | Управление модулями |
|
|
||||||
| `dleTokens.js` | 3 | ~100 | Работа с токенами |
|
|
||||||
| `dleAnalytics.js` | 2 | ~150 | Аналитика и история |
|
|
||||||
| `dleMultichain.js` | 8 | ~300 | Мультичейн функции |
|
|
||||||
|
|
||||||
### ✅ Результат:
|
|
||||||
|
|
||||||
**Backend** = модульная архитектура для чтения данных из блокчейна
|
|
||||||
**Frontend** = модульные сервисы + выполнение транзакций через MetaMask
|
|
||||||
|
|
||||||
**Преимущества новой архитектуры:**
|
|
||||||
- 🏗️ **Модульность** - четкое разделение ответственности
|
|
||||||
- 🔒 **Безопасность** - нет приватных ключей на сервере
|
|
||||||
- 📈 **Масштабируемость** - легко добавлять новые функции
|
|
||||||
- 🎯 **Читаемость** - понятная структура и навигация
|
|
||||||
|
|
||||||
Это современная, безопасная и масштабируемая архитектура! 🚀
|
|
||||||
@@ -1,951 +0,0 @@
|
|||||||
<!--
|
|
||||||
Copyright (c) 2024-2025 Тарабанов Александр Викторович
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
This software is proprietary and confidential.
|
|
||||||
Unauthorized copying, modification, or distribution is prohibited.
|
|
||||||
|
|
||||||
For licensing inquiries: info@hb3-accelerator.com
|
|
||||||
Website: https://hb3-accelerator.com
|
|
||||||
GitHub: https://github.com/HB3-ACCELERATOR
|
|
||||||
-->
|
|
||||||
|
|
||||||
# API Endpoints для обновленного смарт контракта DLE
|
|
||||||
|
|
||||||
## Обзор
|
|
||||||
|
|
||||||
Данный документ содержит полный список всех API endpoints, созданных для работы с обновленным смарт контрактом DLE (Digital Legal Entity). Все endpoints находятся в файле `backend/routes/blockchain.js` и обеспечивают полное покрытие функциональности смарт контракта.
|
|
||||||
|
|
||||||
## Структура ответов
|
|
||||||
|
|
||||||
Все API endpoints возвращают ответы в следующем формате:
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
// Успешный ответ
|
|
||||||
{
|
|
||||||
"success": true,
|
|
||||||
"data": {
|
|
||||||
// Данные ответа
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ошибка
|
|
||||||
{
|
|
||||||
"success": false,
|
|
||||||
"error": "Описание ошибки"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📋 Основные функции DLE
|
|
||||||
|
|
||||||
### 1. Чтение данных DLE из блокчейна
|
|
||||||
```http
|
|
||||||
POST /blockchain/read-dle-info
|
|
||||||
```
|
|
||||||
|
|
||||||
**Описание:** Получение основной информации о DLE из блокчейна.
|
|
||||||
|
|
||||||
**Параметры:**
|
|
||||||
- `dleAddress` (string) - Адрес DLE контракта
|
|
||||||
|
|
||||||
**Ответ:**
|
|
||||||
```javascript
|
|
||||||
{
|
|
||||||
"success": true,
|
|
||||||
"data": {
|
|
||||||
"name": "Название DLE",
|
|
||||||
"symbol": "DLE",
|
|
||||||
"totalSupply": "1000000000000000000000000",
|
|
||||||
"quorumPercentage": 51,
|
|
||||||
"currentChainId": 11155111,
|
|
||||||
"isActive": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. Получение параметров управления
|
|
||||||
```http
|
|
||||||
POST /blockchain/get-governance-params
|
|
||||||
```
|
|
||||||
|
|
||||||
**Описание:** Получение параметров управления DLE.
|
|
||||||
|
|
||||||
**Параметры:**
|
|
||||||
- `dleAddress` (string) - Адрес DLE контракта
|
|
||||||
|
|
||||||
**Ответ:**
|
|
||||||
```javascript
|
|
||||||
{
|
|
||||||
"success": true,
|
|
||||||
"data": {
|
|
||||||
"quorumPercentage": 51,
|
|
||||||
"chainId": 11155111,
|
|
||||||
"supportedCount": 3
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. Проверка активности DLE
|
|
||||||
```http
|
|
||||||
POST /blockchain/is-active
|
|
||||||
```
|
|
||||||
|
|
||||||
**Описание:** Проверка активности DLE контракта.
|
|
||||||
|
|
||||||
**Параметры:**
|
|
||||||
- `dleAddress` (string) - Адрес DLE контракта
|
|
||||||
|
|
||||||
**Ответ:**
|
|
||||||
```javascript
|
|
||||||
{
|
|
||||||
"success": true,
|
|
||||||
"data": {
|
|
||||||
"isActive": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🗳️ Управление предложениями
|
|
||||||
|
|
||||||
### 4. Получение списка предложений
|
|
||||||
```http
|
|
||||||
POST /blockchain/get-proposals
|
|
||||||
```
|
|
||||||
|
|
||||||
**Описание:** Получение списка всех предложений DLE.
|
|
||||||
|
|
||||||
**Параметры:**
|
|
||||||
- `dleAddress` (string) - Адрес DLE контракта
|
|
||||||
|
|
||||||
**Ответ:**
|
|
||||||
```javascript
|
|
||||||
{
|
|
||||||
"success": true,
|
|
||||||
"data": {
|
|
||||||
"proposals": [
|
|
||||||
{
|
|
||||||
"id": 1,
|
|
||||||
"description": "Описание предложения",
|
|
||||||
"state": 1,
|
|
||||||
"forVotes": "1000000000000000000000",
|
|
||||||
"againstVotes": "0",
|
|
||||||
"totalVotes": "1000000000000000000000"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 5. Получение информации о предложении
|
|
||||||
```http
|
|
||||||
POST /blockchain/get-proposal-info
|
|
||||||
```
|
|
||||||
|
|
||||||
**Описание:** Получение детальной информации о конкретном предложении.
|
|
||||||
|
|
||||||
**Параметры:**
|
|
||||||
- `dleAddress` (string) - Адрес DLE контракта
|
|
||||||
- `proposalId` (number) - ID предложения
|
|
||||||
|
|
||||||
**Ответ:**
|
|
||||||
```javascript
|
|
||||||
{
|
|
||||||
"success": true,
|
|
||||||
"data": {
|
|
||||||
"proposalId": 1,
|
|
||||||
"description": "Описание предложения",
|
|
||||||
"duration": 86400,
|
|
||||||
"operation": "0x...",
|
|
||||||
"governanceChainId": 11155111,
|
|
||||||
"targetChains": [11155111, 137],
|
|
||||||
"state": 1,
|
|
||||||
"forVotes": "1000000000000000000000",
|
|
||||||
"againstVotes": "0",
|
|
||||||
"totalVotes": "1000000000000000000000",
|
|
||||||
"quorumRequired": "510000000000000000000"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 6. Получение данных для создания предложения
|
|
||||||
```http
|
|
||||||
POST /blockchain/create-proposal
|
|
||||||
```
|
|
||||||
|
|
||||||
**Описание:** Получение данных для создания нового предложения. Фактическое создание выполняется через frontend с MetaMask.
|
|
||||||
|
|
||||||
**Параметры:**
|
|
||||||
- `dleAddress` (string) - Адрес DLE контракта
|
|
||||||
- `description` (string) - Описание предложения
|
|
||||||
- `duration` (number) - Продолжительность голосования в секундах
|
|
||||||
- `operation` (string) - Операция в формате bytes
|
|
||||||
- `governanceChainId` (number) - ID сети управления
|
|
||||||
- `targetChains` (array) - Массив целевых сетей
|
|
||||||
- `userAddress` (string) - Адрес пользователя
|
|
||||||
|
|
||||||
**Ответ:**
|
|
||||||
```javascript
|
|
||||||
{
|
|
||||||
"success": true,
|
|
||||||
"data": {
|
|
||||||
"proposalData": {
|
|
||||||
"dleAddress": "0x...",
|
|
||||||
"description": "Новое предложение",
|
|
||||||
"duration": 86400,
|
|
||||||
"operation": "0x...",
|
|
||||||
"governanceChainId": 11155111,
|
|
||||||
"targetChains": [11155111, 137],
|
|
||||||
"userAddress": "0x...",
|
|
||||||
"timelockDelay": 0
|
|
||||||
},
|
|
||||||
"message": "Используйте функцию createProposal из dle-contract.js для создания предложения через MetaMask"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 7. Голосование за предложение
|
|
||||||
```http
|
|
||||||
POST /blockchain/vote-proposal
|
|
||||||
```
|
|
||||||
|
|
||||||
**Описание:** Голосование за предложение.
|
|
||||||
|
|
||||||
**Параметры:**
|
|
||||||
- `dleAddress` (string) - Адрес DLE контракта
|
|
||||||
- `proposalId` (number) - ID предложения
|
|
||||||
- `support` (boolean) - Поддержка (true/false)
|
|
||||||
- `userAddress` (string) - Адрес пользователя
|
|
||||||
|
|
||||||
**Ответ:**
|
|
||||||
```javascript
|
|
||||||
{
|
|
||||||
"success": true,
|
|
||||||
"data": {
|
|
||||||
"transactionHash": "0x..."
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 8. Исполнение предложения
|
|
||||||
```http
|
|
||||||
POST /blockchain/execute-proposal
|
|
||||||
```
|
|
||||||
|
|
||||||
**Описание:** Исполнение предложения.
|
|
||||||
|
|
||||||
**Параметры:**
|
|
||||||
- `dleAddress` (string) - Адрес DLE контракта
|
|
||||||
- `proposalId` (number) - ID предложения
|
|
||||||
- `userAddress` (string) - Адрес пользователя
|
|
||||||
|
|
||||||
**Ответ:**
|
|
||||||
```javascript
|
|
||||||
{
|
|
||||||
"success": true,
|
|
||||||
"data": {
|
|
||||||
"transactionHash": "0x..."
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 9. Отмена предложения
|
|
||||||
```http
|
|
||||||
POST /blockchain/cancel-proposal
|
|
||||||
```
|
|
||||||
|
|
||||||
**Описание:** Отмена предложения.
|
|
||||||
|
|
||||||
**Параметры:**
|
|
||||||
- `dleAddress` (string) - Адрес DLE контракта
|
|
||||||
- `proposalId` (number) - ID предложения
|
|
||||||
- `reason` (string) - Причина отмены
|
|
||||||
- `userAddress` (string) - Адрес пользователя
|
|
||||||
|
|
||||||
**Ответ:**
|
|
||||||
```javascript
|
|
||||||
{
|
|
||||||
"success": true,
|
|
||||||
"data": {
|
|
||||||
"transactionHash": "0x..."
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 10. Получение состояния предложения
|
|
||||||
```http
|
|
||||||
POST /blockchain/get-proposal-state
|
|
||||||
```
|
|
||||||
|
|
||||||
**Описание:** Получение текущего состояния предложения.
|
|
||||||
|
|
||||||
**Параметры:**
|
|
||||||
- `dleAddress` (string) - Адрес DLE контракта
|
|
||||||
- `proposalId` (number) - ID предложения
|
|
||||||
|
|
||||||
**Ответ:**
|
|
||||||
```javascript
|
|
||||||
{
|
|
||||||
"success": true,
|
|
||||||
"data": {
|
|
||||||
"proposalId": 1,
|
|
||||||
"state": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 11. Получение голосов по предложению
|
|
||||||
```http
|
|
||||||
POST /blockchain/get-proposal-votes
|
|
||||||
```
|
|
||||||
|
|
||||||
**Описание:** Получение статистики голосования по предложению.
|
|
||||||
|
|
||||||
**Параметры:**
|
|
||||||
- `dleAddress` (string) - Адрес DLE контракта
|
|
||||||
- `proposalId` (number) - ID предложения
|
|
||||||
|
|
||||||
**Ответ:**
|
|
||||||
```javascript
|
|
||||||
{
|
|
||||||
"success": true,
|
|
||||||
"data": {
|
|
||||||
"proposalId": 1,
|
|
||||||
"forVotes": "1000000000000000000000",
|
|
||||||
"againstVotes": "0",
|
|
||||||
"totalVotes": "1000000000000000000000",
|
|
||||||
"quorumRequired": "510000000000000000000"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 12. Проверка результата предложения
|
|
||||||
```http
|
|
||||||
POST /blockchain/check-proposal-result
|
|
||||||
```
|
|
||||||
|
|
||||||
**Описание:** Проверка результата голосования по предложению.
|
|
||||||
|
|
||||||
**Параметры:**
|
|
||||||
- `dleAddress` (string) - Адрес DLE контракта
|
|
||||||
- `proposalId` (number) - ID предложения
|
|
||||||
|
|
||||||
**Ответ:**
|
|
||||||
```javascript
|
|
||||||
{
|
|
||||||
"success": true,
|
|
||||||
"data": {
|
|
||||||
"proposalId": 1,
|
|
||||||
"passed": true,
|
|
||||||
"quorumReached": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 13. Получение количества предложений
|
|
||||||
```http
|
|
||||||
POST /blockchain/get-proposals-count
|
|
||||||
```
|
|
||||||
|
|
||||||
**Описание:** Получение общего количества предложений.
|
|
||||||
|
|
||||||
**Параметры:**
|
|
||||||
- `dleAddress` (string) - Адрес DLE контракта
|
|
||||||
|
|
||||||
**Ответ:**
|
|
||||||
```javascript
|
|
||||||
{
|
|
||||||
"success": true,
|
|
||||||
"data": {
|
|
||||||
"count": 5
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 14. Получение списка предложений с пагинацией
|
|
||||||
```http
|
|
||||||
POST /blockchain/list-proposals
|
|
||||||
```
|
|
||||||
|
|
||||||
**Описание:** Получение списка предложений с поддержкой пагинации.
|
|
||||||
|
|
||||||
**Параметры:**
|
|
||||||
- `dleAddress` (string) - Адрес DLE контракта
|
|
||||||
- `offset` (number) - Смещение
|
|
||||||
- `limit` (number) - Лимит
|
|
||||||
|
|
||||||
**Ответ:**
|
|
||||||
```javascript
|
|
||||||
{
|
|
||||||
"success": true,
|
|
||||||
"data": {
|
|
||||||
"proposals": [1, 2, 3],
|
|
||||||
"offset": 0,
|
|
||||||
"limit": 10
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🔧 Управление модулями
|
|
||||||
|
|
||||||
### 15. Создание предложения добавления модуля
|
|
||||||
```http
|
|
||||||
POST /blockchain/create-add-module-proposal
|
|
||||||
```
|
|
||||||
|
|
||||||
**Описание:** Создание предложения для добавления нового модуля.
|
|
||||||
|
|
||||||
**Параметры:**
|
|
||||||
- `dleAddress` (string) - Адрес DLE контракта
|
|
||||||
- `moduleId` (string) - ID модуля
|
|
||||||
- `moduleAddress` (string) - Адрес модуля
|
|
||||||
- `userAddress` (string) - Адрес пользователя
|
|
||||||
|
|
||||||
**Ответ:**
|
|
||||||
```javascript
|
|
||||||
{
|
|
||||||
"success": true,
|
|
||||||
"data": {
|
|
||||||
"proposalId": 1,
|
|
||||||
"transactionHash": "0x..."
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 16. Создание предложения удаления модуля
|
|
||||||
```http
|
|
||||||
POST /blockchain/create-remove-module-proposal
|
|
||||||
```
|
|
||||||
|
|
||||||
**Описание:** Создание предложения для удаления модуля.
|
|
||||||
|
|
||||||
**Параметры:**
|
|
||||||
- `dleAddress` (string) - Адрес DLE контракта
|
|
||||||
- `moduleId` (string) - ID модуля
|
|
||||||
- `userAddress` (string) - Адрес пользователя
|
|
||||||
|
|
||||||
**Ответ:**
|
|
||||||
```javascript
|
|
||||||
{
|
|
||||||
"success": true,
|
|
||||||
"data": {
|
|
||||||
"proposalId": 1,
|
|
||||||
"transactionHash": "0x..."
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 17. Проверка активности модуля
|
|
||||||
```http
|
|
||||||
POST /blockchain/is-module-active
|
|
||||||
```
|
|
||||||
|
|
||||||
**Описание:** Проверка активности модуля.
|
|
||||||
|
|
||||||
**Параметры:**
|
|
||||||
- `dleAddress` (string) - Адрес DLE контракта
|
|
||||||
- `moduleId` (string) - ID модуля
|
|
||||||
|
|
||||||
**Ответ:**
|
|
||||||
```javascript
|
|
||||||
{
|
|
||||||
"success": true,
|
|
||||||
"data": {
|
|
||||||
"moduleId": "0x...",
|
|
||||||
"isActive": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 18. Получение адреса модуля
|
|
||||||
```http
|
|
||||||
POST /blockchain/get-module-address
|
|
||||||
```
|
|
||||||
|
|
||||||
**Описание:** Получение адреса модуля по его ID.
|
|
||||||
|
|
||||||
**Параметры:**
|
|
||||||
- `dleAddress` (string) - Адрес DLE контракта
|
|
||||||
- `moduleId` (string) - ID модуля
|
|
||||||
|
|
||||||
**Ответ:**
|
|
||||||
```javascript
|
|
||||||
{
|
|
||||||
"success": true,
|
|
||||||
"data": {
|
|
||||||
"moduleId": "0x...",
|
|
||||||
"moduleAddress": "0x..."
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🌐 Мульти-чейн функциональность
|
|
||||||
|
|
||||||
### 19. Получение поддерживаемых сетей
|
|
||||||
```http
|
|
||||||
POST /blockchain/get-supported-chains
|
|
||||||
```
|
|
||||||
|
|
||||||
**Описание:** Получение списка поддерживаемых сетей.
|
|
||||||
|
|
||||||
**Параметры:**
|
|
||||||
- `dleAddress` (string) - Адрес DLE контракта
|
|
||||||
|
|
||||||
**Ответ:**
|
|
||||||
```javascript
|
|
||||||
{
|
|
||||||
"success": true,
|
|
||||||
"data": {
|
|
||||||
"supportedChains": [11155111, 137, 1]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 20. Проверка поддержки сети
|
|
||||||
```http
|
|
||||||
POST /blockchain/is-chain-supported
|
|
||||||
```
|
|
||||||
|
|
||||||
**Описание:** Проверка поддержки конкретной сети.
|
|
||||||
|
|
||||||
**Параметры:**
|
|
||||||
- `dleAddress` (string) - Адрес DLE контракта
|
|
||||||
- `chainId` (number) - ID сети
|
|
||||||
|
|
||||||
**Ответ:**
|
|
||||||
```javascript
|
|
||||||
{
|
|
||||||
"success": true,
|
|
||||||
"data": {
|
|
||||||
"chainId": 11155111,
|
|
||||||
"isSupported": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 21. Получение текущей сети
|
|
||||||
```http
|
|
||||||
POST /blockchain/get-current-chain-id
|
|
||||||
```
|
|
||||||
|
|
||||||
**Описание:** Получение ID текущей сети.
|
|
||||||
|
|
||||||
**Параметры:**
|
|
||||||
- `dleAddress` (string) - Адрес DLE контракта
|
|
||||||
|
|
||||||
**Ответ:**
|
|
||||||
```javascript
|
|
||||||
{
|
|
||||||
"success": true,
|
|
||||||
"data": {
|
|
||||||
"currentChainId": 11155111
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 22. Исполнение предложения по подписям
|
|
||||||
```http
|
|
||||||
POST /blockchain/execute-proposal-by-signatures
|
|
||||||
```
|
|
||||||
|
|
||||||
**Описание:** Исполнение предложения с использованием подписей.
|
|
||||||
|
|
||||||
**Параметры:**
|
|
||||||
- `dleAddress` (string) - Адрес DLE контракта
|
|
||||||
- `proposalId` (number) - ID предложения
|
|
||||||
- `signers` (array) - Массив адресов подписантов
|
|
||||||
- `signatures` (array) - Массив подписей
|
|
||||||
- `userAddress` (string) - Адрес пользователя
|
|
||||||
|
|
||||||
**Ответ:**
|
|
||||||
```javascript
|
|
||||||
{
|
|
||||||
"success": true,
|
|
||||||
"data": {
|
|
||||||
"transactionHash": "0x..."
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 23. Проверка подключения к сети
|
|
||||||
```http
|
|
||||||
POST /blockchain/check-chain-connection
|
|
||||||
```
|
|
||||||
|
|
||||||
**Описание:** Проверка доступности подключения к сети.
|
|
||||||
|
|
||||||
**Параметры:**
|
|
||||||
- `dleAddress` (string) - Адрес DLE контракта
|
|
||||||
- `chainId` (number) - ID сети
|
|
||||||
|
|
||||||
**Ответ:**
|
|
||||||
```javascript
|
|
||||||
{
|
|
||||||
"success": true,
|
|
||||||
"data": {
|
|
||||||
"chainId": 11155111,
|
|
||||||
"isAvailable": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 24. Синхронизация во все сети
|
|
||||||
```http
|
|
||||||
POST /blockchain/sync-to-all-chains
|
|
||||||
```
|
|
||||||
|
|
||||||
**Описание:** Синхронизация предложения во все поддерживаемые сети.
|
|
||||||
|
|
||||||
**Параметры:**
|
|
||||||
- `dleAddress` (string) - Адрес DLE контракта
|
|
||||||
- `proposalId` (number) - ID предложения
|
|
||||||
- `userAddress` (string) - Адрес пользователя
|
|
||||||
|
|
||||||
**Ответ:**
|
|
||||||
```javascript
|
|
||||||
{
|
|
||||||
"success": true,
|
|
||||||
"data": {
|
|
||||||
"transactionHash": "0x..."
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 25. Получение количества поддерживаемых сетей
|
|
||||||
```http
|
|
||||||
POST /blockchain/get-supported-chain-count
|
|
||||||
```
|
|
||||||
|
|
||||||
**Описание:** Получение количества поддерживаемых сетей.
|
|
||||||
|
|
||||||
**Параметры:**
|
|
||||||
- `dleAddress` (string) - Адрес DLE контракта
|
|
||||||
|
|
||||||
**Ответ:**
|
|
||||||
```javascript
|
|
||||||
{
|
|
||||||
"success": true,
|
|
||||||
"data": {
|
|
||||||
"count": 3
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 26. Получение ID поддерживаемой сети по индексу
|
|
||||||
```http
|
|
||||||
POST /blockchain/get-supported-chain-id
|
|
||||||
```
|
|
||||||
|
|
||||||
**Описание:** Получение ID поддерживаемой сети по индексу.
|
|
||||||
|
|
||||||
**Параметры:**
|
|
||||||
- `dleAddress` (string) - Адрес DLE контракта
|
|
||||||
- `index` (number) - Индекс сети
|
|
||||||
|
|
||||||
**Ответ:**
|
|
||||||
```javascript
|
|
||||||
{
|
|
||||||
"success": true,
|
|
||||||
"data": {
|
|
||||||
"index": 0,
|
|
||||||
"chainId": 11155111
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📊 Аналитика и пагинация
|
|
||||||
|
|
||||||
### 27. Получение голосующей силы на момент времени
|
|
||||||
```http
|
|
||||||
POST /blockchain/get-voting-power-at
|
|
||||||
```
|
|
||||||
|
|
||||||
**Описание:** Получение голосующей силы пользователя на определенный момент времени.
|
|
||||||
|
|
||||||
**Параметры:**
|
|
||||||
- `dleAddress` (string) - Адрес DLE контракта
|
|
||||||
- `voter` (string) - Адрес голосующего
|
|
||||||
- `timepoint` (number) - Момент времени
|
|
||||||
|
|
||||||
**Ответ:**
|
|
||||||
```javascript
|
|
||||||
{
|
|
||||||
"success": true,
|
|
||||||
"data": {
|
|
||||||
"voter": "0x...",
|
|
||||||
"timepoint": 1234567890,
|
|
||||||
"votingPower": "1000000000000000000000"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 28. Получение требуемого кворума на момент времени
|
|
||||||
```http
|
|
||||||
POST /blockchain/get-quorum-at
|
|
||||||
```
|
|
||||||
|
|
||||||
**Описание:** Получение требуемого кворума на определенный момент времени.
|
|
||||||
|
|
||||||
**Параметры:**
|
|
||||||
- `dleAddress` (string) - Адрес DLE контракта
|
|
||||||
- `timepoint` (number) - Момент времени
|
|
||||||
|
|
||||||
**Ответ:**
|
|
||||||
```javascript
|
|
||||||
{
|
|
||||||
"success": true,
|
|
||||||
"data": {
|
|
||||||
"timepoint": 1234567890,
|
|
||||||
"quorum": "510000000000000000000"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🪙 Токены и балансы
|
|
||||||
|
|
||||||
### 29. Получение баланса токенов
|
|
||||||
```http
|
|
||||||
POST /blockchain/get-token-balance
|
|
||||||
```
|
|
||||||
|
|
||||||
**Описание:** Получение баланса токенов пользователя.
|
|
||||||
|
|
||||||
**Параметры:**
|
|
||||||
- `dleAddress` (string) - Адрес DLE контракта
|
|
||||||
- `account` (string) - Адрес аккаунта
|
|
||||||
|
|
||||||
**Ответ:**
|
|
||||||
```javascript
|
|
||||||
{
|
|
||||||
"success": true,
|
|
||||||
"data": {
|
|
||||||
"account": "0x...",
|
|
||||||
"balance": "1000.0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 30. Получение общего предложения токенов
|
|
||||||
```http
|
|
||||||
POST /blockchain/get-total-supply
|
|
||||||
```
|
|
||||||
|
|
||||||
**Описание:** Получение общего предложения токенов DLE.
|
|
||||||
|
|
||||||
**Параметры:**
|
|
||||||
- `dleAddress` (string) - Адрес DLE контракта
|
|
||||||
|
|
||||||
**Ответ:**
|
|
||||||
```javascript
|
|
||||||
{
|
|
||||||
"success": true,
|
|
||||||
"data": {
|
|
||||||
"totalSupply": "1000000.0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🔗 Frontend сервисы
|
|
||||||
|
|
||||||
Для работы с API endpoints созданы следующие сервисы в frontend:
|
|
||||||
|
|
||||||
### 1. dleV2Service.js
|
|
||||||
Основной сервис для работы с DLE, содержащий все функции для взаимодействия с API.
|
|
||||||
|
|
||||||
### 2. tokens.js
|
|
||||||
Сервис для работы с токенами и балансами.
|
|
||||||
|
|
||||||
### 3. proposalsService.js
|
|
||||||
Сервис для работы с предложениями и голосованием.
|
|
||||||
|
|
||||||
### 4. modulesService.js
|
|
||||||
Сервис для работы с модулями DLE.
|
|
||||||
|
|
||||||
### 5. analyticsService.js
|
|
||||||
Сервис для работы с аналитикой и статистикой.
|
|
||||||
|
|
||||||
### 6. multichainService.js
|
|
||||||
Сервис для работы с мульти-чейн функциональностью.
|
|
||||||
|
|
||||||
## 🔐 Выполнение транзакций через MetaMask
|
|
||||||
|
|
||||||
Для выполнения транзакций (создание предложений, голосование, исполнение) используется файл `frontend/src/utils/dle-contract.js` с функциями:
|
|
||||||
|
|
||||||
### Основные функции для транзакций:
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
// Создание предложения
|
|
||||||
import { createProposal } from '@/utils/dle-contract.js';
|
|
||||||
const result = await createProposal(dleAddress, proposalData);
|
|
||||||
|
|
||||||
// Голосование за предложение
|
|
||||||
import { voteForProposal } from '@/utils/dle-contract.js';
|
|
||||||
const result = await voteForProposal(dleAddress, proposalId, support);
|
|
||||||
|
|
||||||
// Исполнение предложения
|
|
||||||
import { executeProposal } from '@/utils/dle-contract.js';
|
|
||||||
const result = await executeProposal(dleAddress, proposalId);
|
|
||||||
|
|
||||||
// Проверка подключения к кошельку
|
|
||||||
import { checkWalletConnection } from '@/utils/dle-contract.js';
|
|
||||||
const walletInfo = await checkWalletConnection();
|
|
||||||
```
|
|
||||||
|
|
||||||
### Пример использования:
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
// 1. Получаем данные для создания предложения от backend
|
|
||||||
const response = await fetch('/api/blockchain/create-proposal', {
|
|
||||||
method: 'POST',
|
|
||||||
headers: { 'Content-Type': 'application/json' },
|
|
||||||
body: JSON.stringify({
|
|
||||||
dleAddress: '0x...',
|
|
||||||
description: 'Новое предложение',
|
|
||||||
duration: 86400,
|
|
||||||
operation: '0x...',
|
|
||||||
governanceChainId: 11155111,
|
|
||||||
targetChains: [11155111, 137],
|
|
||||||
userAddress: '0x...'
|
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
const { proposalData } = response.data;
|
|
||||||
|
|
||||||
// 2. Создаем предложение через MetaMask
|
|
||||||
import { createProposal } from '@/utils/dle-contract.js';
|
|
||||||
const result = await createProposal(proposalData.dleAddress, proposalData);
|
|
||||||
console.log('Предложение создано:', result.txHash);
|
|
||||||
```
|
|
||||||
|
|
||||||
**Важно:** Все транзакции выполняются через MetaMask или другой Web3 кошелек для обеспечения безопасности пользователей.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📋 Состояния предложений
|
|
||||||
|
|
||||||
Справочник состояний предложений:
|
|
||||||
|
|
||||||
- `0` - Pending (Ожидает)
|
|
||||||
- `1` - Active (Активно)
|
|
||||||
- `2` - Canceled (Отменено)
|
|
||||||
- `3` - Defeated (Отклонено)
|
|
||||||
- `4` - Succeeded (Успешно)
|
|
||||||
- `5` - Queued (В очереди)
|
|
||||||
- `6` - Expired (Истекло)
|
|
||||||
- `7` - Executed (Исполнено)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🚀 Использование
|
|
||||||
|
|
||||||
Все API endpoints используют:
|
|
||||||
- **Сеть:** Sepolia (Chain ID: 11155111)
|
|
||||||
- **Формат:** JSON
|
|
||||||
- **Метод:** POST
|
|
||||||
- **Базовый URL:** `http://localhost:8000` (backend) или `/api` (через frontend proxy)
|
|
||||||
|
|
||||||
### Пример использования:
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
// Создание предложения (через frontend proxy)
|
|
||||||
const response = await fetch('/api/blockchain/create-proposal', {
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json'
|
|
||||||
},
|
|
||||||
body: JSON.stringify({
|
|
||||||
dleAddress: '0x...',
|
|
||||||
description: 'Новое предложение',
|
|
||||||
duration: 86400,
|
|
||||||
operation: '0x...',
|
|
||||||
governanceChainId: 11155111,
|
|
||||||
targetChains: [11155111, 137],
|
|
||||||
userAddress: '0x...'
|
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
const result = await response.json();
|
|
||||||
|
|
||||||
// Или напрямую к backend
|
|
||||||
const response = await fetch('http://localhost:8000/blockchain/create-proposal', {
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json'
|
|
||||||
},
|
|
||||||
body: JSON.stringify({
|
|
||||||
dleAddress: '0x...',
|
|
||||||
description: 'Новое предложение',
|
|
||||||
duration: 86400,
|
|
||||||
operation: '0x...',
|
|
||||||
governanceChainId: 11155111,
|
|
||||||
targetChains: [11155111, 137],
|
|
||||||
userAddress: '0x...'
|
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
const result = await response.json();
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ✅ Покрытие функций смарт контракта
|
|
||||||
|
|
||||||
Все функции смарт контракта `DLE.sol` имеют соответствующие API endpoints:
|
|
||||||
|
|
||||||
| Функция смарт контракта | API Endpoint | Статус |
|
|
||||||
|-------------------------|--------------|--------|
|
|
||||||
| `getDLEInfo()` | `read-dle-info` | ✅ |
|
|
||||||
| `getGovernanceParams()` | `get-governance-params` | ✅ |
|
|
||||||
| `isActive()` | `is-active` | ✅ |
|
|
||||||
| `createProposal()` | `create-proposal` | ✅ |
|
|
||||||
| `vote()` | `vote-proposal` | ✅ |
|
|
||||||
| `executeProposal()` | `execute-proposal` | ✅ |
|
|
||||||
| `cancelProposal()` | `cancel-proposal` | ✅ |
|
|
||||||
| `getProposalSummary()` | `get-proposal-info` | ✅ |
|
|
||||||
| `getProposalState()` | `get-proposal-state` | ✅ |
|
|
||||||
| `getProposalVotes()` | `get-proposal-votes` | ✅ |
|
|
||||||
| `checkProposalResult()` | `check-proposal-result` | ✅ |
|
|
||||||
| `getProposalsCount()` | `get-proposals-count` | ✅ |
|
|
||||||
| `listProposals()` | `list-proposals` | ✅ |
|
|
||||||
| `getVotingPowerAt()` | `get-voting-power-at` | ✅ |
|
|
||||||
| `getQuorumAt()` | `get-quorum-at` | ✅ |
|
|
||||||
| `createAddModuleProposal()` | `create-add-module-proposal` | ✅ |
|
|
||||||
| `createRemoveModuleProposal()` | `create-remove-module-proposal` | ✅ |
|
|
||||||
| `isModuleActive()` | `is-module-active` | ✅ |
|
|
||||||
| `getModuleAddress()` | `get-module-address` | ✅ |
|
|
||||||
| `listSupportedChains()` | `get-supported-chains` | ✅ |
|
|
||||||
| `isChainSupported()` | `is-chain-supported` | ✅ |
|
|
||||||
| `getCurrentChainId()` | `get-current-chain-id` | ✅ |
|
|
||||||
| `executeProposalBySignatures()` | `execute-proposal-by-signatures` | ✅ |
|
|
||||||
| `checkChainConnection()` | `check-chain-connection` | ✅ |
|
|
||||||
| `syncToAllChains()` | `sync-to-all-chains` | ✅ |
|
|
||||||
| `getSupportedChainCount()` | `get-supported-chain-count` | ✅ |
|
|
||||||
| `getSupportedChainId()` | `get-supported-chain-id` | ✅ |
|
|
||||||
| `balanceOf()` | `get-token-balance` | ✅ |
|
|
||||||
| `totalSupply()` | `get-total-supply` | ✅ |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🎯 Итог
|
|
||||||
|
|
||||||
**Полное покрытие функциональности смарт контракта DLE достигнуто!**
|
|
||||||
|
|
||||||
- ✅ **30 API endpoints** создано
|
|
||||||
- ✅ **6 frontend сервисов** создано
|
|
||||||
- ✅ **100% покрытие** функций смарт контракта
|
|
||||||
- ✅ **Готово к использованию** в интерфейсе управления
|
|
||||||
|
|
||||||
Система полностью готова для работы с обновленным функционалом смарт контракта DLE! 🚀
|
|
||||||
@@ -1,964 +0,0 @@
|
|||||||
<!--
|
|
||||||
Copyright (c) 2024-2025 Тарабанов Александр Викторович
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
This software is proprietary and confidential.
|
|
||||||
Unauthorized copying, modification, or distribution is prohibited.
|
|
||||||
|
|
||||||
For licensing inquiries: info@hb3-accelerator.com
|
|
||||||
Website: https://hb3-accelerator.com
|
|
||||||
GitHub: https://github.com/HB3-ACCELERATOR
|
|
||||||
-->
|
|
||||||
|
|
||||||
# DLE v2 — краткие обновления
|
|
||||||
|
|
||||||
- Single‑Chain Governance: голосование фиксируется в одной сети, исполнение в целевых сетях по EIP‑712 подписям без внешних мостов.
|
|
||||||
- Снапшоты голосующей силы: `ERC20Votes` (`getPastVotes`, `getPastTotalSupply`) исключают перелив голосов.
|
|
||||||
- Делегирование «только на себя»: 1 токен = 1 голос, запрет делегирования третьим лицам.
|
|
||||||
- Модульность: казна, таймлок, деактивация, коммуникации выделены в отдельные модули, операции выполняются через ядро DLE.
|
|
||||||
- «100% или ничего»: много-сетевые операции исполняются только при готовности всех целевых сетей.
|
|
||||||
- Детерминированный деплой: CREATE с выровненным nonce для одинаковых адресов во всех выбранных сетях.
|
|
||||||
- Аналитика: добавлены view‑функции для сводок, пагинации и агрегирования по предложениям.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# DLE - Единый Смарт-Контракт с Модульной Архитектурой
|
|
||||||
|
|
||||||
## 🎯 ПОЛНОЕ ПОНИМАНИЕ ЗАДАЧИ DLE
|
|
||||||
|
|
||||||
### **1. ОСНОВНАЯ КОНЦЕПЦИЯ:**
|
|
||||||
```
|
|
||||||
DLE (Digital Legal Entity) = Универсальная цифровая юридическая организация
|
|
||||||
├── Один смарт-контракт с одинаковым адресом во всех цепочках
|
|
||||||
├── Управление только через токен-холдеров (никаких админских ролей)
|
|
||||||
├── Модульная архитектура (основной контракт + добавляемые модули)
|
|
||||||
└── Мульти-чейн синхронизация (работа в нескольких блокчейнах одновременно)
|
|
||||||
```
|
|
||||||
|
|
||||||
### **2. АРХИТЕКТУРА СИСТЕМЫ:**
|
|
||||||
|
|
||||||
#### **Деплой в множественных цепочках:**
|
|
||||||
```
|
|
||||||
Пользователь выбирает цепочки (например, 4):
|
|
||||||
├── Ethereum (ChainId = 1)
|
|
||||||
├── Polygon (ChainId = 137)
|
|
||||||
├── BSC (ChainId = 56)
|
|
||||||
└── Arbitrum (ChainId = 42161)
|
|
||||||
|
|
||||||
Деплой в каждой цепочке:
|
|
||||||
├── Одинаковый адрес DLE (через CREATE2)
|
|
||||||
├── Одинаковые токены для партнеров
|
|
||||||
└── Синхронизированное состояние
|
|
||||||
```
|
|
||||||
|
|
||||||
#### **Распределение токенов:**
|
|
||||||
```
|
|
||||||
3 партнера получают по 1000 токенов в каждой из 4 цепочек:
|
|
||||||
├── Партнер A: 1000 токенов (в 4 цепочках)
|
|
||||||
├── Партнер B: 1000 токенов (в 4 цепочках)
|
|
||||||
└── Партнер C: 1000 токенов (в 4 цепочках)
|
|
||||||
|
|
||||||
Итого: 3000 токенов в каждой цепочке
|
|
||||||
```
|
|
||||||
|
|
||||||
### **3. СИСТЕМА УПРАВЛЕНИЯ:**
|
|
||||||
|
|
||||||
#### **Голосование токен‑холдеров:**
|
|
||||||
```
|
|
||||||
- Только токен-холдеры участвуют в управлении
|
|
||||||
- Каждый токен = одна голосующая сила
|
|
||||||
- Кворум настраиваемый (например, 60% от общего количества токенов)
|
|
||||||
- Коллективное голосование токен‑холдеров (ERC20Votes снапшоты)
|
|
||||||
```
|
|
||||||
|
|
||||||
#### **Создание предложений:**
|
|
||||||
```
|
|
||||||
1. Токен-холдер создает предложение
|
|
||||||
2. Выбирает ОДНУ цепочку для сбора подписей/голосов
|
|
||||||
3. Сбор происходит только в выбранной цепочке
|
|
||||||
4. При достижении кворума - исполнение
|
|
||||||
5. Синхронизация исполнения во все остальные цепочки
|
|
||||||
```
|
|
||||||
|
|
||||||
### **4. МУЛЬТИ-ЧЕЙН СИНХРОНИЗАЦИЯ:**
|
|
||||||
|
|
||||||
#### **Передача токенов:**
|
|
||||||
```
|
|
||||||
Партнер A передает 500 токенов Партнеру B:
|
|
||||||
├── Ethereum: A → B (500 токенов)
|
|
||||||
├── Polygon: A → B (500 токенов)
|
|
||||||
├── BSC: A → B (500 токенов)
|
|
||||||
└── Arbitrum: A → B (500 токенов)
|
|
||||||
|
|
||||||
Синхронизация происходит во всех цепочках одновременно
|
|
||||||
```
|
|
||||||
|
|
||||||
#### **Создание и исполнение предложений:**
|
|
||||||
```
|
|
||||||
Пример: "Передать 100 токенов от A к C"
|
|
||||||
1. Создание в Ethereum
|
|
||||||
2. Выбор Polygon для кворума
|
|
||||||
3. Сбор подписей в Polygon
|
|
||||||
4. Кворум: 60% от 3000 = 1800 токенов
|
|
||||||
5. При достижении кворума:
|
|
||||||
├── Исполнение в Polygon: A → C (100 токенов)
|
|
||||||
├── Синхронизация в Ethereum: A → C (100 токенов)
|
|
||||||
├── Синхронизация в BSC: A → C (100 токенов)
|
|
||||||
└── Синхронизация в Arbitrum: A → C (100 токенов)
|
|
||||||
```
|
|
||||||
|
|
||||||
### **5. МОДУЛЬНАЯ АРХИТЕКТУРА:**
|
|
||||||
|
|
||||||
#### **Основной контракт DLE.sol:**
|
|
||||||
```
|
|
||||||
- ERC-20 токены
|
|
||||||
- Система голосования
|
|
||||||
- Мультичейн синхронизация
|
|
||||||
- Управление модулями
|
|
||||||
- DLEInfo (юридическая информация)
|
|
||||||
```
|
|
||||||
|
|
||||||
#### **Модули (отдельные контракты):**
|
|
||||||
```
|
|
||||||
- TreasuryModule.sol (казначейство)
|
|
||||||
- HierarchicalVotingModule.sol (иерархическое голосование)
|
|
||||||
- CommunicationModule.sol (коммуникации)
|
|
||||||
- CustomModule.sol (пользовательские модули)
|
|
||||||
```
|
|
||||||
|
|
||||||
### **6. ПРИМЕРЫ ИСПОЛЬЗОВАНИЯ:**
|
|
||||||
|
|
||||||
#### **Передача токенов:**
|
|
||||||
```
|
|
||||||
1. Создание предложения: "A → C (100 токенов)"
|
|
||||||
2. Выбор цепочки для кворума: Polygon
|
|
||||||
3. Сбор подписей в Polygon
|
|
||||||
4. При кворуме: исполнение + синхронизация во все цепочки
|
|
||||||
```
|
|
||||||
|
|
||||||
#### **Удаление таблицы в приложении:**
|
|
||||||
```
|
|
||||||
1. Создание предложения: "Удалить таблицу пользователей"
|
|
||||||
2. Выбор цепочки: Ethereum
|
|
||||||
3. Сбор подписей в Ethereum
|
|
||||||
4. При кворуме: информация добавляется в блокчейн
|
|
||||||
5. Синхронизация во все цепочки
|
|
||||||
6. Результат: таблица удаляется из приложения
|
|
||||||
```
|
|
||||||
|
|
||||||
### **7. КЛЮЧЕВЫЕ ПРИНЦИПЫ:**
|
|
||||||
|
|
||||||
#### **Безопасность:**
|
|
||||||
```
|
|
||||||
- Только токен-холдеры управляют
|
|
||||||
- Проверка баланса при каждой операции
|
|
||||||
- Кворум голосов - все решения через коллективное голосование
|
|
||||||
- Синхронизация между цепочками
|
|
||||||
```
|
|
||||||
|
|
||||||
#### **Масштабируемость:**
|
|
||||||
```
|
|
||||||
- Модульная архитектура
|
|
||||||
- Добавление новых функций через модули
|
|
||||||
- Поддержка новых цепочек
|
|
||||||
- Иерархическое голосование
|
|
||||||
```
|
|
||||||
|
|
||||||
#### **Универсальность:**
|
|
||||||
```
|
|
||||||
- Один адрес во всех цепочках
|
|
||||||
- Любая цепочка для создания предложений
|
|
||||||
- Единый интерфейс управления
|
|
||||||
- Совместимость с существующими стандартами
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🎯 ОСНОВНАЯ КОНЦЕПЦИЯ
|
|
||||||
|
|
||||||
### Один смарт-контракт с модулями
|
|
||||||
```
|
|
||||||
DLE.sol (Основной контракт) + Модули (добавляемые через голосование)
|
|
||||||
```
|
|
||||||
|
|
||||||
### Ключевые принципы:
|
|
||||||
1. **Один основной контракт** - управление токенами, голосованием, мультиподписью
|
|
||||||
2. **Модули** - специализированные функции (казначейство, иерархическое голосование, коммуникации)
|
|
||||||
3. **Только токен-холдеры** - никаких админских ролей
|
|
||||||
4. **Кворум голосов** - все решения через коллективное голосование
|
|
||||||
5. **Проверка баланса** - при каждой операции
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🏗️ АРХИТЕКТУРА СИСТЕМЫ
|
|
||||||
|
|
||||||
### Основной контракт DLE.sol
|
|
||||||
```
|
|
||||||
DLE.sol
|
|
||||||
├── ERC-20 токены (голосующая сила)
|
|
||||||
├── Настраиваемый кворум (% от общего количества токенов)
|
|
||||||
├── Система голосования (проверка баланса токенов)
|
|
||||||
├── Выбор цепочки для кворума (governanceChainId)
|
|
||||||
├── Синхронизация голосов между цепочками
|
|
||||||
├── Поддержка множественных цепочек
|
|
||||||
├── Голосование токен‑холдеров
|
|
||||||
├── Мультичейн синхронизация
|
|
||||||
└── Система модулей (добавление/управление)
|
|
||||||
```
|
|
||||||
|
|
||||||
### Модули (отдельные контракты)
|
|
||||||
```
|
|
||||||
Модули
|
|
||||||
├── TreasuryModule.sol (Казначейство)
|
|
||||||
├── HierarchicalVotingModule.sol (Иерархическое голосование)
|
|
||||||
├── CommunicationModule.sol (Сообщения/звонки)
|
|
||||||
├── ExternalDLEModule.sol (Меж-DLE взаимодействие)
|
|
||||||
└── CustomModule.sol (Пользовательские модули)
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📋 ФУНКЦИОНАЛЬНЫЕ ТРЕБОВАНИЯ
|
|
||||||
|
|
||||||
### 1. Основной контракт DLE.sol ✅
|
|
||||||
- **ERC-20 токены** - голосующая сила = количество токенов
|
|
||||||
- **Настраиваемый кворум** - процент от общего количества токенов
|
|
||||||
- **Система голосования** - только токен-холдеры участвуют
|
|
||||||
- **Выбор цепочки для кворума** - токен-холдер может выбрать любую поддерживаемую цепочку
|
|
||||||
- **Синхронизация голосов** - после голосования результаты синхронизируются между цепочками
|
|
||||||
- **Поддержка множественных цепочек** - Ethereum, Polygon, BSC и др.
|
|
||||||
- **Голосование** - через токен‑холдеров с проверкой баланса
|
|
||||||
- **Мультичейн синхронизация** - одинаковый адрес во всех цепочках
|
|
||||||
- **Управление модулями** - добавление/удаление через голосование
|
|
||||||
|
|
||||||
### 2. TreasuryModule.sol ✅
|
|
||||||
- **Внесение токенов** - в казну через голосование
|
|
||||||
- **Вывод токенов** - из казны через голосование
|
|
||||||
- **Распределение дивидендов** - через голосование
|
|
||||||
- **Бюджетирование** - через предложения
|
|
||||||
|
|
||||||
### 3. HierarchicalVotingModule.sol ✅
|
|
||||||
- **Владение токенами других DLE** - покупка/продажа токенов
|
|
||||||
- **Создание предложений** - для голосования в других DLE
|
|
||||||
- **Внутреннее голосование** - кворум внутри DLE для внешнего голосования
|
|
||||||
- **Внешнее голосование** - участие в голосованиях других DLE
|
|
||||||
|
|
||||||
### 4. CommunicationModule.sol ✅
|
|
||||||
- **Прием сообщений** - от токен-холдеров
|
|
||||||
- **Прием звонков** - аудио/видео коммуникации
|
|
||||||
- **История коммуникаций** - хранение и синхронизация
|
|
||||||
- **Кворум для действий** - голосование за коммуникационные операции
|
|
||||||
|
|
||||||
### 5. ExternalDLEModule.sol ✅
|
|
||||||
- **Меж-DLE взаимодействие** - управление DLE B через приложение DLE A
|
|
||||||
- **Встраивание интерфейсов** - безопасное управление
|
|
||||||
- **Проверка прав** - через голосование токен‑холдеров
|
|
||||||
- **Аудит действий** - отслеживание операций
|
|
||||||
|
|
||||||
### 6. Мульти-чейн архитектура ✅
|
|
||||||
- **CREATE2 деплой** - одинаковый адрес во всех цепочках
|
|
||||||
- **Синхронизация состояния** - токены, предложения, голосования
|
|
||||||
- **Создание предложений** - в любой цепочке
|
|
||||||
- **Голосование** - через токен‑холдеров с проверкой баланса
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🔒 БЕЗОПАСНОСТЬ
|
|
||||||
|
|
||||||
### Основные принципы безопасности:
|
|
||||||
1. **Только токен-холдеры** - никаких админских ролей
|
|
||||||
2. **Проверка баланса** - при каждой операции
|
|
||||||
3. **Кворум голосов** - все решения коллективные
|
|
||||||
4. **Простая логика** - минимум уязвимостей
|
|
||||||
|
|
||||||
### Защита от атак:
|
|
||||||
|
|
||||||
#### **1. Защита от Double-Spending**
|
|
||||||
```solidity
|
|
||||||
function signOperation(bytes32 _operationHash) external {
|
|
||||||
require(!hasSigned[_operationHash][msg.sender], "Already signed");
|
|
||||||
require(balanceOf(msg.sender) > 0, "No tokens to sign");
|
|
||||||
|
|
||||||
hasSigned[_operationHash][msg.sender] = true;
|
|
||||||
signatures[_operationHash] += balanceOf(msg.sender);
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### **2. Защита от Reentrancy**
|
|
||||||
```solidity
|
|
||||||
mapping(address => bool) private _locked;
|
|
||||||
|
|
||||||
modifier nonReentrant() {
|
|
||||||
require(!_locked[msg.sender], "Reentrant call");
|
|
||||||
_locked[msg.sender] = true;
|
|
||||||
_;
|
|
||||||
_locked[msg.sender] = false;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### **3. Защита от Манипуляций**
|
|
||||||
```solidity
|
|
||||||
mapping(uint256 => uint256) public proposalSnapshots;
|
|
||||||
|
|
||||||
function createProposal(string memory _description) external returns (uint256) {
|
|
||||||
require(balanceOf(msg.sender) > 0, "Must hold tokens");
|
|
||||||
|
|
||||||
uint256 proposalId = proposalCount++;
|
|
||||||
proposalSnapshots[proposalId] = block.number;
|
|
||||||
|
|
||||||
return proposalId;
|
|
||||||
}
|
|
||||||
|
|
||||||
function vote(uint256 _proposalId, bool _support) external {
|
|
||||||
uint256 votingPower = balanceOfAt(msg.sender, proposalSnapshots[_proposalId]);
|
|
||||||
require(votingPower > 0, "No voting power");
|
|
||||||
|
|
||||||
// Голосование
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🔧 ТЕХНИЧЕСКАЯ РЕАЛИЗАЦИЯ
|
|
||||||
|
|
||||||
### Основной контракт DLE.sol
|
|
||||||
```solidity
|
|
||||||
contract DLE is ERC20, ReentrancyGuard {
|
|
||||||
// Настройки
|
|
||||||
uint256 public quorumPercentage;
|
|
||||||
mapping(address => bool) public activeModules;
|
|
||||||
|
|
||||||
// Мульти-чейн
|
|
||||||
mapping(uint256 => bool) public supportedChains;
|
|
||||||
mapping(uint256 => uint256) public chainBalances;
|
|
||||||
|
|
||||||
// Предложения и голосования
|
|
||||||
mapping(uint256 => Proposal) public proposals;
|
|
||||||
mapping(uint256 => mapping(address => bool)) public hasVoted;
|
|
||||||
|
|
||||||
// Модули
|
|
||||||
mapping(bytes32 => address) public modules;
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
string memory _name,
|
|
||||||
string memory _symbol,
|
|
||||||
uint256 _initialSupply,
|
|
||||||
uint256 _quorumPercentage
|
|
||||||
) ERC20(_name, _symbol) {
|
|
||||||
quorumPercentage = _quorumPercentage;
|
|
||||||
_mint(msg.sender, _initialSupply);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Создание предложения
|
|
||||||
function createProposal(string memory _description, uint256 _duration) external returns (uint256) {
|
|
||||||
require(balanceOf(msg.sender) > 0, "Must hold tokens");
|
|
||||||
|
|
||||||
uint256 proposalId = proposalCount++;
|
|
||||||
proposals[proposalId] = Proposal({
|
|
||||||
id: proposalId,
|
|
||||||
description: _description,
|
|
||||||
forVotes: 0,
|
|
||||||
againstVotes: 0,
|
|
||||||
executed: false,
|
|
||||||
deadline: block.timestamp + _duration
|
|
||||||
});
|
|
||||||
|
|
||||||
return proposalId;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Голосование
|
|
||||||
function vote(uint256 _proposalId, bool _support) external {
|
|
||||||
Proposal storage proposal = proposals[_proposalId];
|
|
||||||
require(block.timestamp < proposal.deadline, "Voting ended");
|
|
||||||
require(!proposal.executed, "Already executed");
|
|
||||||
require(!hasVoted[_proposalId][msg.sender], "Already voted");
|
|
||||||
|
|
||||||
uint256 votingPower = balanceOf(msg.sender);
|
|
||||||
require(votingPower > 0, "No tokens to vote");
|
|
||||||
|
|
||||||
hasVoted[_proposalId][msg.sender] = true;
|
|
||||||
|
|
||||||
if (_support) {
|
|
||||||
proposal.forVotes += votingPower;
|
|
||||||
} else {
|
|
||||||
proposal.againstVotes += votingPower;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Добавление модуля
|
|
||||||
function addModule(bytes32 _moduleId, address _moduleAddress) external {
|
|
||||||
require(checkProposalResult(getLastProposalId()).passed, "Proposal not passed");
|
|
||||||
|
|
||||||
modules[_moduleId] = _moduleAddress;
|
|
||||||
activeModules[_moduleAddress] = true;
|
|
||||||
|
|
||||||
emit ModuleAdded(_moduleId, _moduleAddress);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Модуль казначейства TreasuryModule.sol
|
|
||||||
```solidity
|
|
||||||
contract TreasuryModule {
|
|
||||||
DLE public dle;
|
|
||||||
uint256 public treasuryBalance;
|
|
||||||
|
|
||||||
constructor(address _dle) {
|
|
||||||
dle = DLE(_dle);
|
|
||||||
}
|
|
||||||
|
|
||||||
function depositToTreasury(uint256 _amount) external {
|
|
||||||
require(dle.balanceOf(msg.sender) >= _amount, "Insufficient balance");
|
|
||||||
require(dle.transferFrom(msg.sender, address(this), _amount), "Transfer failed");
|
|
||||||
|
|
||||||
treasuryBalance += _amount;
|
|
||||||
emit TreasuryDeposit(msg.sender, _amount);
|
|
||||||
}
|
|
||||||
|
|
||||||
function withdrawFromTreasury(address _recipient, uint256 _amount) external {
|
|
||||||
require(dle.checkProposalResult(getTreasuryProposalId()).passed, "Proposal not passed");
|
|
||||||
require(_amount <= treasuryBalance, "Insufficient treasury");
|
|
||||||
|
|
||||||
treasuryBalance -= _amount;
|
|
||||||
require(dle.transfer(_recipient, _amount), "Transfer failed");
|
|
||||||
|
|
||||||
emit TreasuryWithdrawal(_recipient, _amount);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Модуль иерархического голосования HierarchicalVotingModule.sol
|
|
||||||
```solidity
|
|
||||||
contract HierarchicalVotingModule {
|
|
||||||
DLE public dle;
|
|
||||||
mapping(address => uint256) public externalDLEBalances;
|
|
||||||
mapping(uint256 => ExternalVotingProposal) public externalVotingProposals;
|
|
||||||
|
|
||||||
struct ExternalVotingProposal {
|
|
||||||
address targetDLE;
|
|
||||||
uint256 targetProposalId;
|
|
||||||
bool support;
|
|
||||||
string reason;
|
|
||||||
bool executed;
|
|
||||||
uint256 internalProposalId;
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor(address _dle) {
|
|
||||||
dle = DLE(_dle);
|
|
||||||
}
|
|
||||||
|
|
||||||
function buyTokensFromOtherDLE(address _otherDLE, uint256 _amount) external {
|
|
||||||
require(dle.balanceOf(msg.sender) > 0, "Must hold DLE tokens");
|
|
||||||
require(_amount > 0, "Amount must be positive");
|
|
||||||
|
|
||||||
require(dle.transferFrom(msg.sender, address(this), _amount), "Transfer failed");
|
|
||||||
externalDLEBalances[_otherDLE] += _amount;
|
|
||||||
|
|
||||||
emit ExternalDLEInvestment(_otherDLE, _amount);
|
|
||||||
}
|
|
||||||
|
|
||||||
function createExternalVotingProposal(
|
|
||||||
address _targetDLE,
|
|
||||||
uint256 _targetProposalId,
|
|
||||||
bool _support,
|
|
||||||
string memory _reason
|
|
||||||
) external returns (uint256) {
|
|
||||||
require(dle.balanceOf(msg.sender) > 0, "Must hold DLE tokens");
|
|
||||||
require(externalDLEBalances[_targetDLE] > 0, "No tokens in target DLE");
|
|
||||||
|
|
||||||
string memory description = string(abi.encodePacked(
|
|
||||||
"Vote in DLE ", _targetDLE, " on proposal ", _targetProposalId.toString()
|
|
||||||
));
|
|
||||||
|
|
||||||
uint256 internalProposalId = dle.createProposal(description, 7 days);
|
|
||||||
|
|
||||||
uint256 proposalId = externalProposalCount++;
|
|
||||||
externalVotingProposals[proposalId] = ExternalVotingProposal({
|
|
||||||
targetDLE: _targetDLE,
|
|
||||||
targetProposalId: _targetProposalId,
|
|
||||||
support: _support,
|
|
||||||
reason: _reason,
|
|
||||||
executed: false,
|
|
||||||
internalProposalId: internalProposalId
|
|
||||||
});
|
|
||||||
|
|
||||||
return proposalId;
|
|
||||||
}
|
|
||||||
|
|
||||||
function executeExternalVote(uint256 _proposalId) external {
|
|
||||||
ExternalVotingProposal storage proposal = externalVotingProposals[_proposalId];
|
|
||||||
require(!proposal.executed, "Already executed");
|
|
||||||
|
|
||||||
(bool passed, bool quorumReached) = dle.checkProposalResult(proposal.internalProposalId);
|
|
||||||
require(passed && quorumReached, "Internal proposal not passed");
|
|
||||||
|
|
||||||
uint256 votingPower = externalDLEBalances[proposal.targetDLE];
|
|
||||||
|
|
||||||
emit ExternalDLEVote(proposal.targetDLE, proposal.targetProposalId, proposal.support, votingPower);
|
|
||||||
|
|
||||||
proposal.executed = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🌐 МУЛЬТИ-ЧЕЙН АРХИТЕКТУРА
|
|
||||||
|
|
||||||
### Мульти-чейн функциональность
|
|
||||||
```solidity
|
|
||||||
// Создание предложения с выбором цепочки для кворума
|
|
||||||
function createProposal(
|
|
||||||
string memory _description,
|
|
||||||
uint256 _duration,
|
|
||||||
uint256 _governanceChainId
|
|
||||||
) external returns (uint256);
|
|
||||||
|
|
||||||
// Исполнение в целевых сетях по EIP-712 подписям (без мостов)
|
|
||||||
function executeProposalBySignatures(
|
|
||||||
uint256 proposalId,
|
|
||||||
bytes[] calldata signatures
|
|
||||||
) external;
|
|
||||||
|
|
||||||
// Проверка поддерживаемых цепочек
|
|
||||||
function isChainSupported(uint256 _chainId) external view returns (bool);
|
|
||||||
```
|
|
||||||
|
|
||||||
### Синхронизация между цепочками
|
|
||||||
- Результаты голосования фиксируются снапшотами ERC20Votes в governance‑сети.
|
|
||||||
- Целевые сети принимают исполнение при верификации EIP‑712 подписей холдеров и кворума на зафиксированном timepoint.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ⚠️ ПРОБЛЕМЫ ДОСТУПНОСТИ ЦЕПОЧЕК
|
|
||||||
|
|
||||||
### **Сценарий: Из 4 цепочек доступны только 2**
|
|
||||||
|
|
||||||
#### **1. Проблема при деплое:**
|
|
||||||
```
|
|
||||||
Планируемый деплой: Ethereum, Polygon, BSC, Arbitrum
|
|
||||||
Доступные цепочки: Ethereum, Polygon
|
|
||||||
Недоступные: BSC, Arbitrum (ошибка подключения/интернет)
|
|
||||||
```
|
|
||||||
|
|
||||||
#### **2. Проблема при синхронизации:**
|
|
||||||
```
|
|
||||||
Исполнение в Ethereum → Синхронизация в остальные цепочки
|
|
||||||
✅ Polygon: синхронизация успешна
|
|
||||||
❌ BSC: ошибка подключения
|
|
||||||
❌ Arbitrum: нет интернета
|
|
||||||
```
|
|
||||||
|
|
||||||
### **ПРОСТОЕ И БЕЗОПАСНОЕ РЕШЕНИЕ:**
|
|
||||||
|
|
||||||
#### **Принцип: 100% или ничего**
|
|
||||||
```
|
|
||||||
Перед любым действием:
|
|
||||||
1. ✅ Проверить все подключения
|
|
||||||
2. ✅ Убедиться в доступности всех цепочек
|
|
||||||
3. ✅ Выполнить операцию на 100%
|
|
||||||
4. ❌ При любом сбое - отменить всё с указанием причины
|
|
||||||
```
|
|
||||||
|
|
||||||
#### **1. Проверка подключений перед деплоем**
|
|
||||||
```solidity
|
|
||||||
contract DLE is ERC20, ReentrancyGuard {
|
|
||||||
// Статус проверки цепочек
|
|
||||||
mapping(uint256 => bool) public chainConnectionStatus;
|
|
||||||
|
|
||||||
// События
|
|
||||||
event PreDeployCheckStarted(uint256[] chainIds);
|
|
||||||
event PreDeployCheckCompleted(bool allChainsAvailable, string[] unavailableChains);
|
|
||||||
event DeployCancelled(string reason);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @dev Проверить подключения перед деплоем
|
|
||||||
*/
|
|
||||||
function checkAllConnections(uint256[] memory _chainIds) external returns (bool) {
|
|
||||||
require(balanceOf(msg.sender) > 0, "Must hold tokens");
|
|
||||||
|
|
||||||
emit PreDeployCheckStarted(_chainIds);
|
|
||||||
|
|
||||||
bool allAvailable = true;
|
|
||||||
string[] memory unavailableChains = new string[](_chainIds.length);
|
|
||||||
uint256 unavailableCount = 0;
|
|
||||||
|
|
||||||
for (uint256 i = 0; i < _chainIds.length; i++) {
|
|
||||||
bool isAvailable = checkChainConnection(_chainIds[i]);
|
|
||||||
chainConnectionStatus[_chainIds[i]] = isAvailable;
|
|
||||||
|
|
||||||
if (!isAvailable) {
|
|
||||||
allAvailable = false;
|
|
||||||
unavailableChains[unavailableCount] = getChainName(_chainIds[i]);
|
|
||||||
unavailableCount++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
emit PreDeployCheckCompleted(allAvailable, unavailableChains);
|
|
||||||
|
|
||||||
if (!allAvailable) {
|
|
||||||
string memory reason = string(abi.encodePacked(
|
|
||||||
"Deploy cancelled: Chains unavailable - ",
|
|
||||||
joinStrings(unavailableChains, unavailableCount)
|
|
||||||
));
|
|
||||||
emit DeployCancelled(reason);
|
|
||||||
}
|
|
||||||
|
|
||||||
return allAvailable;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @dev Проверить подключение к конкретной цепочке
|
|
||||||
*/
|
|
||||||
function checkChainConnection(uint256 _chainId) internal view returns (bool) {
|
|
||||||
// Здесь должна быть реальная проверка подключения
|
|
||||||
// Для примера используем простую проверку
|
|
||||||
return _chainId > 0 && _chainId <= 999999;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @dev Получить название цепочки
|
|
||||||
*/
|
|
||||||
function getChainName(uint256 _chainId) internal pure returns (string memory) {
|
|
||||||
if (_chainId == 1) return "Ethereum";
|
|
||||||
if (_chainId == 137) return "Polygon";
|
|
||||||
if (_chainId == 56) return "BSC";
|
|
||||||
if (_chainId == 42161) return "Arbitrum";
|
|
||||||
return "Unknown";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### **2. Проверка перед синхронизацией**
|
|
||||||
```solidity
|
|
||||||
contract DLE is ERC20, ReentrancyGuard {
|
|
||||||
/**
|
|
||||||
* @dev Проверить все цепочки перед синхронизацией
|
|
||||||
*/
|
|
||||||
function checkSyncReadiness(uint256 _proposalId) external returns (bool) {
|
|
||||||
require(balanceOf(msg.sender) > 0, "Must hold tokens");
|
|
||||||
|
|
||||||
Proposal storage proposal = proposals[_proposalId];
|
|
||||||
require(proposal.id == _proposalId, "Proposal does not exist");
|
|
||||||
|
|
||||||
// Проверяем все поддерживаемые цепочки
|
|
||||||
bool allChainsReady = true;
|
|
||||||
string[] memory unavailableChains = new string[](supportedChainIds.length);
|
|
||||||
uint256 unavailableCount = 0;
|
|
||||||
|
|
||||||
for (uint256 i = 0; i < supportedChainIds.length; i++) {
|
|
||||||
uint256 chainId = supportedChainIds[i];
|
|
||||||
bool isReady = checkChainConnection(chainId);
|
|
||||||
|
|
||||||
if (!isReady) {
|
|
||||||
allChainsReady = false;
|
|
||||||
unavailableChains[unavailableCount] = getChainName(chainId);
|
|
||||||
unavailableCount++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!allChainsReady) {
|
|
||||||
string memory reason = string(abi.encodePacked(
|
|
||||||
"Sync cancelled: Chains unavailable - ",
|
|
||||||
joinStrings(unavailableChains, unavailableCount)
|
|
||||||
));
|
|
||||||
emit SyncCancelled(_proposalId, reason);
|
|
||||||
}
|
|
||||||
|
|
||||||
return allChainsReady;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @dev Синхронизация только при 100% готовности
|
|
||||||
*/
|
|
||||||
function syncToAllChains(uint256 _proposalId) external {
|
|
||||||
require(checkSyncReadiness(_proposalId), "Not all chains ready");
|
|
||||||
|
|
||||||
// Выполняем синхронизацию во все цепочки
|
|
||||||
for (uint256 i = 0; i < supportedChainIds.length; i++) {
|
|
||||||
uint256 chainId = supportedChainIds[i];
|
|
||||||
syncToChain(_proposalId, chainId);
|
|
||||||
}
|
|
||||||
|
|
||||||
emit SyncCompleted(_proposalId, supportedChainIds);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### **3. Проверка перед голосованием**
|
|
||||||
```solidity
|
|
||||||
contract DLE is ERC20, ReentrancyGuard {
|
|
||||||
/**
|
|
||||||
* @dev Проверить цепочку перед голосованием
|
|
||||||
*/
|
|
||||||
function checkVotingChain(uint256 _chainId) external returns (bool) {
|
|
||||||
require(balanceOf(msg.sender) > 0, "Must hold tokens");
|
|
||||||
|
|
||||||
bool isAvailable = checkChainConnection(_chainId);
|
|
||||||
|
|
||||||
if (!isAvailable) {
|
|
||||||
string memory reason = string(abi.encodePacked(
|
|
||||||
"Voting cancelled: Chain ",
|
|
||||||
getChainName(_chainId),
|
|
||||||
" unavailable"
|
|
||||||
));
|
|
||||||
emit VotingCancelled(reason);
|
|
||||||
}
|
|
||||||
|
|
||||||
return isAvailable;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @dev Создать предложение только при доступности цепочки
|
|
||||||
*/
|
|
||||||
function createProposalWithChainCheck(
|
|
||||||
string memory _description,
|
|
||||||
uint256 _duration,
|
|
||||||
uint256 _votingChainId
|
|
||||||
) external returns (uint256) {
|
|
||||||
require(checkVotingChain(_votingChainId), "Voting chain not available");
|
|
||||||
|
|
||||||
return createProposal(_description, _duration, _votingChainId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### **СТРАТЕГИИ ОБРАБОТКИ:**
|
|
||||||
|
|
||||||
#### **1. При деплое (проверка всех цепочек):**
|
|
||||||
```
|
|
||||||
Планируемый деплой: Ethereum, Polygon, BSC, Arbitrum
|
|
||||||
|
|
||||||
Проверка:
|
|
||||||
✅ Ethereum: доступен
|
|
||||||
✅ Polygon: доступен
|
|
||||||
❌ BSC: недоступен
|
|
||||||
❌ Arbitrum: недоступен
|
|
||||||
|
|
||||||
Результат:
|
|
||||||
❌ Деплой ОТМЕНЕН
|
|
||||||
📋 Причина: "BSC, Arbitrum недоступны"
|
|
||||||
🔔 Уведомление токен-холдеров
|
|
||||||
```
|
|
||||||
|
|
||||||
#### **2. При синхронизации (проверка всех цепочек):**
|
|
||||||
```
|
|
||||||
Исполнение в Ethereum → Синхронизация
|
|
||||||
|
|
||||||
Проверка:
|
|
||||||
✅ Ethereum: доступен
|
|
||||||
✅ Polygon: доступен
|
|
||||||
❌ BSC: недоступен
|
|
||||||
❌ Arbitrum: недоступен
|
|
||||||
|
|
||||||
Результат:
|
|
||||||
❌ Синхронизация ОТМЕНЕНА
|
|
||||||
📋 Причина: "BSC, Arbitrum недоступны"
|
|
||||||
🔔 Уведомление токен-холдеров
|
|
||||||
```
|
|
||||||
|
|
||||||
#### **3. При голосовании (проверка выбранной цепочки):**
|
|
||||||
```
|
|
||||||
Планируемое голосование: Polygon
|
|
||||||
|
|
||||||
Проверка:
|
|
||||||
❌ Polygon: недоступен
|
|
||||||
|
|
||||||
Результат:
|
|
||||||
❌ Голосование ОТМЕНЕНО
|
|
||||||
📋 Причина: "Polygon недоступен"
|
|
||||||
🔔 Уведомление токен-холдеров
|
|
||||||
```
|
|
||||||
|
|
||||||
### **ПРИМЕРЫ СЦЕНАРИЕВ:**
|
|
||||||
|
|
||||||
#### **Сценарий 1: Деплой с проблемами**
|
|
||||||
```
|
|
||||||
Планируемый деплой: 4 цепочки
|
|
||||||
|
|
||||||
Проверка подключений:
|
|
||||||
✅ Ethereum: доступен
|
|
||||||
✅ Polygon: доступен
|
|
||||||
❌ BSC: ошибка подключения
|
|
||||||
❌ Arbitrum: нет интернета
|
|
||||||
|
|
||||||
Действия:
|
|
||||||
1. ❌ Деплой ОТМЕНЕН
|
|
||||||
2. 📋 Причина: "BSC, Arbitrum недоступны"
|
|
||||||
3. 🔔 Уведомление токен-холдеров
|
|
||||||
4. ⏰ Ожидание восстановления подключений
|
|
||||||
5. 🔄 Повторная проверка при восстановлении
|
|
||||||
```
|
|
||||||
|
|
||||||
#### **Сценарий 2: Синхронизация с проблемами**
|
|
||||||
```
|
|
||||||
Исполнение в Ethereum → Синхронизация
|
|
||||||
|
|
||||||
Проверка всех цепочек:
|
|
||||||
✅ Ethereum: доступен
|
|
||||||
✅ Polygon: доступен
|
|
||||||
❌ BSC: ошибка подключения
|
|
||||||
❌ Arbitrum: нет интернета
|
|
||||||
|
|
||||||
Действия:
|
|
||||||
1. ❌ Синхронизация ОТМЕНЕНА
|
|
||||||
2. 📋 Причина: "BSC, Arbitrum недоступны"
|
|
||||||
3. 🔔 Уведомление токен-холдеров
|
|
||||||
4. ⏰ Ожидание восстановления подключений
|
|
||||||
5. 🔄 Повторная проверка при восстановлении
|
|
||||||
```
|
|
||||||
|
|
||||||
#### **Сценарий 3: Голосование с проблемами**
|
|
||||||
```
|
|
||||||
Планируемое голосование: Polygon
|
|
||||||
|
|
||||||
Проверка Polygon:
|
|
||||||
❌ Polygon: недоступен
|
|
||||||
|
|
||||||
Действия:
|
|
||||||
1. ❌ Голосование ОТМЕНЕНО
|
|
||||||
2. 📋 Причина: "Polygon недоступен"
|
|
||||||
3. 🔔 Уведомление токен-холдеров
|
|
||||||
4. ⏰ Ожидание восстановления подключения
|
|
||||||
5. 🔄 Повторная проверка при восстановлении
|
|
||||||
```
|
|
||||||
|
|
||||||
### **ПРЕИМУЩЕСТВА ПРОСТОГО РЕШЕНИЯ:**
|
|
||||||
|
|
||||||
#### **✅ Безопасность:**
|
|
||||||
- Никаких частичных операций
|
|
||||||
- Никаких рассинхронизаций
|
|
||||||
- Четкие причины отмены
|
|
||||||
|
|
||||||
#### **✅ Простота:**
|
|
||||||
- Понятная логика
|
|
||||||
- Минимум кода
|
|
||||||
- Легко отлаживать
|
|
||||||
|
|
||||||
#### **✅ Надежность:**
|
|
||||||
- 100% или ничего
|
|
||||||
- Предсказуемое поведение
|
|
||||||
- Нет скрытых состояний
|
|
||||||
|
|
||||||
#### **✅ Прозрачность:**
|
|
||||||
- Четкие причины отмены
|
|
||||||
- Уведомления токен-холдеров
|
|
||||||
- Понятная логика
|
|
||||||
|
|
||||||
### **КЛЮЧЕВЫЕ ПРИНЦИПЫ:**
|
|
||||||
|
|
||||||
#### **1. Проверка перед действием:**
|
|
||||||
```
|
|
||||||
Любое действие = Проверка всех подключений → Выполнение или Отмена
|
|
||||||
```
|
|
||||||
|
|
||||||
#### **2. 100% или ничего:**
|
|
||||||
```
|
|
||||||
Все цепочки доступны → Выполнить
|
|
||||||
Любая цепочка недоступна → Отменить с причиной
|
|
||||||
```
|
|
||||||
|
|
||||||
#### **3. Четкие причины:**
|
|
||||||
```
|
|
||||||
Отмена = Конкретная причина + Уведомление токен-холдеров
|
|
||||||
```
|
|
||||||
|
|
||||||
#### **4. Простота восстановления:**
|
|
||||||
```
|
|
||||||
Проблема решена → Повторная проверка → Выполнение
|
|
||||||
```
|
|
||||||
|
|
||||||
**Теперь система DLE работает по принципу "100% или ничего" - просто, безопасно и надежно!**
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📊 ПРИМЕРЫ ИСПОЛЬЗОВАНИЯ
|
|
||||||
|
|
||||||
### Пример 1: Деплой в 4 цепочках
|
|
||||||
```
|
|
||||||
1. Пользователь выбирает 4 цепочки: Ethereum, Polygon, BSC, Arbitrum
|
|
||||||
2. Деплой DLE в каждой цепочке с одинаковым адресом
|
|
||||||
3. Партнеры получают по 1000 токенов в каждой цепочке:
|
|
||||||
- Партнер A: 1000 токенов (в 4 цепочках)
|
|
||||||
- Партнер B: 1000 токенов (в 4 цепочках)
|
|
||||||
- Партнер C: 1000 токенов (в 4 цепочках)
|
|
||||||
4. Передача токенов синхронизируется между всеми цепочками
|
|
||||||
```
|
|
||||||
|
|
||||||
### Пример 2: Создание предложения и сбор подписей
|
|
||||||
```
|
|
||||||
1. Партнер A создает предложение "Передать 100 токенов от A к C"
|
|
||||||
2. Выбирает одну цепочку (например, Polygon) для сбора подписей
|
|
||||||
3. Сбор подписей происходит только в выбранной цепочке
|
|
||||||
4. Кворум: 60% от 3000 = 1800 токенов
|
|
||||||
5. При достижении кворума - исполнение в Polygon
|
|
||||||
6. Синхронизация исполнения во все остальные цепочки
|
|
||||||
```
|
|
||||||
|
|
||||||
### Пример 3: Исполнение и синхронизация
|
|
||||||
```
|
|
||||||
1. Кворум достигнут в Polygon (1800+ токенов)
|
|
||||||
2. Исполнение в Polygon: A → C (100 токенов)
|
|
||||||
3. Синхронизация в Ethereum: A → C (100 токенов)
|
|
||||||
4. Синхронизация в BSC: A → C (100 токенов)
|
|
||||||
5. Синхронизация в Arbitrum: A → C (100 токенов)
|
|
||||||
6. Результат: токены переданы во всех 4 цепочках
|
|
||||||
```
|
|
||||||
|
|
||||||
### Пример 4: Удаление таблицы в приложении
|
|
||||||
```
|
|
||||||
1. Партнер A создает предложение "Удалить таблицу пользователей"
|
|
||||||
2. Выбирает Ethereum для сбора подписей
|
|
||||||
3. Кворум достигнут в Ethereum
|
|
||||||
4. Исполнение в Ethereum: информация добавляется в блокчейн
|
|
||||||
5. Синхронизация во все цепочки: информация добавляется везде
|
|
||||||
6. Результат: таблица удаляется из приложения
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🎯 ПРЕИМУЩЕСТВА АРХИТЕКТУРЫ
|
|
||||||
|
|
||||||
### ✅ Простота
|
|
||||||
- Один основной контракт с модулями
|
|
||||||
- Только токен-холдеры участвуют в управлении
|
|
||||||
- Проверка баланса при каждой операции
|
|
||||||
- Настраиваемый кворум для всех решений
|
|
||||||
|
|
||||||
### ✅ Безопасность
|
|
||||||
- Никаких админских ролей
|
|
||||||
- Простая логика коллективного голосования
|
|
||||||
- Защита от основных атак
|
|
||||||
- Прозрачность всех операций
|
|
||||||
|
|
||||||
### ✅ Масштабируемость
|
|
||||||
- Модульная архитектура
|
|
||||||
- Добавление новых функций через модули
|
|
||||||
- Мульти-чейн синхронизация
|
|
||||||
- Иерархическое голосование
|
|
||||||
|
|
||||||
### ✅ Универсальность
|
|
||||||
- Один адрес во всех цепочках
|
|
||||||
- Любая цепочка для создания предложений
|
|
||||||
- Единый интерфейс управления
|
|
||||||
- Совместимость с существующими стандартами
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📈 ЗАКЛЮЧЕНИЕ
|
|
||||||
|
|
||||||
**DLE - это единый смарт-контракт с модульной архитектурой, который:**
|
|
||||||
|
|
||||||
1. **Управляется только токен‑холдерами** через кворум голосов
|
|
||||||
2. **Проверяет баланс токенов** при каждой операции
|
|
||||||
3. **Использует модули** для специализированных функций
|
|
||||||
4. **Синхронизируется между цепочками** с одинаковым адресом
|
|
||||||
5. **Поддерживает иерархическое голосование** через отдельный модуль
|
|
||||||
|
|
||||||
**Ключевые принципы:**
|
|
||||||
- Простота и безопасность
|
|
||||||
- Коллективное управление
|
|
||||||
- Модульная архитектура
|
|
||||||
- Мульти-чейн синхронизация
|
|
||||||
|
|
||||||
**Результат:** Безопасная, масштабируемая и универсальная система DLE! 🚀
|
|
||||||
@@ -1,311 +0,0 @@
|
|||||||
<!--
|
|
||||||
Copyright (c) 2024-2025 Тарабанов Александр Викторович
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
This software is proprietary and confidential.
|
|
||||||
Unauthorized copying, modification, or distribution is prohibited.
|
|
||||||
|
|
||||||
For licensing inquiries: info@hb3-accelerator.com
|
|
||||||
Website: https://hb3-accelerator.com
|
|
||||||
GitHub: https://github.com/HB3-ACCELERATOR
|
|
||||||
-->
|
|
||||||
|
|
||||||
# Руководство по деплою DLE v2
|
|
||||||
|
|
||||||
## Обзор
|
|
||||||
|
|
||||||
DLE v2 (Digital Legal Entity) - это система для создания цифровых юридических лиц с мульти-чейн поддержкой. Основная особенность - использование CREATE с выровненным nonce для обеспечения одинакового адреса смарт-контракта во всех поддерживаемых сетях.
|
|
||||||
|
|
||||||
## Архитектура
|
|
||||||
|
|
||||||
### Компоненты системы
|
|
||||||
|
|
||||||
1. **DLE.sol** - Основной смарт-контракт с ERC-20 токенами управления
|
|
||||||
2. **Детерминированный деплой** - через CREATE с выровненным nonce для одинаковых адресов
|
|
||||||
3. **Модули** - Дополнительная функциональность (Treasury, Timelock, etc.)
|
|
||||||
|
|
||||||
### Мульти-чейн поддержка
|
|
||||||
|
|
||||||
- **CREATE с выровненным nonce** - Одинаковый адрес во всех EVM-совместимых сетях
|
|
||||||
- **Single-Chain Governance** - Голосование происходит в одной сети
|
|
||||||
- **Multi-Chain Execution** - Исполнение в целевых сетях по подписям
|
|
||||||
|
|
||||||
## Процесс деплоя
|
|
||||||
|
|
||||||
### 1. Подготовка
|
|
||||||
|
|
||||||
1. Убедитесь, что у вас есть:
|
|
||||||
- Приватный ключ с достаточным балансом в выбранных сетях
|
|
||||||
- RPC URLs для всех целевых сетей
|
|
||||||
- API ключ Etherscan (опционально, для верификации)
|
|
||||||
|
|
||||||
2. Настройте RPC провайдеры в веб-интерфейсе:
|
|
||||||
- Откройте страницу настроек: `http://localhost:5173/settings/security`
|
|
||||||
- Перейдите в раздел "RPC Провайдеры"
|
|
||||||
- Добавьте RPC URLs для нужных сетей:
|
|
||||||
- **Ethereum Mainnet**: Chain ID 1
|
|
||||||
- **Polygon**: Chain ID 137
|
|
||||||
- **BSC**: Chain ID 56
|
|
||||||
- **Arbitrum**: Chain ID 42161
|
|
||||||
- **Sepolia Testnet**: Chain ID 11155111
|
|
||||||
- И другие нужные сети
|
|
||||||
|
|
||||||
3. Приватные ключи вводятся непосредственно в форме деплоя для безопасности
|
|
||||||
|
|
||||||
### 2. Деплой через веб-интерфейс
|
|
||||||
|
|
||||||
1. Откройте страницу: `http://localhost:5173/settings/dle-v2-deploy`
|
|
||||||
|
|
||||||
2. Заполните форму:
|
|
||||||
- **Основная информация**: Название, символ токена
|
|
||||||
- **Юридическая информация**: Страна, ОКВЭД, адрес
|
|
||||||
- **Партнеры**: Адреса и доли токенов
|
|
||||||
- **Сети**: Выберите целевые блокчейн-сети
|
|
||||||
- **Приватный ключ**: Для деплоя контрактов
|
|
||||||
|
|
||||||
3. Нажмите "Развернуть DLE"
|
|
||||||
|
|
||||||
### 3. Процесс деплоя
|
|
||||||
|
|
||||||
Система автоматически:
|
|
||||||
|
|
||||||
1. **Проверяет балансы** во всех выбранных сетях
|
|
||||||
2. **Компилирует контракты** через Hardhat
|
|
||||||
3. **Проверяет Factory адреса** в базе данных
|
|
||||||
4. **Выравнивает nonce** для детерминированного деплоя
|
|
||||||
5. **Вычисляет адрес DLE** через CREATE с выровненным nonce
|
|
||||||
6. **Деплоит DLE** с одинаковым адресом во всех сетях
|
|
||||||
8. **Деплоит базовые модули** (Treasury, Timelock, Reader) в каждой сети
|
|
||||||
9. **Инициализирует модули** в DLE контракте
|
|
||||||
10. **Верифицирует контракты** в Etherscan (опционально)
|
|
||||||
|
|
||||||
### 4. Результат
|
|
||||||
|
|
||||||
После успешного деплоя вы получите:
|
|
||||||
|
|
||||||
- **Одинаковый адрес DLE** во всех выбранных сетях
|
|
||||||
- **Одинаковый адрес Factory** во всех выбранных сетях
|
|
||||||
- **Базовые модули** (Treasury, Timelock, Reader) в каждой сети
|
|
||||||
- **Инициализированные модули** в DLE контракте
|
|
||||||
- **ERC-20 токены управления** распределенные между партнерами
|
|
||||||
- **Настроенный кворум** для принятия решений
|
|
||||||
- **Поддержку мульти-чейн операций**
|
|
||||||
|
|
||||||
### 5. Управление Factory адресами
|
|
||||||
|
|
||||||
Система автоматически управляет Factory адресами:
|
|
||||||
|
|
||||||
#### API Endpoints:
|
|
||||||
- `GET /api/factory` - Получить все Factory адреса
|
|
||||||
- `GET /api/factory/:chainId` - Получить Factory адрес для сети
|
|
||||||
- `POST /api/factory` - Сохранить Factory адрес
|
|
||||||
- `POST /api/factory/bulk` - Сохранить адреса для нескольких сетей
|
|
||||||
- `DELETE /api/factory/:chainId` - Удалить Factory адрес
|
|
||||||
- `POST /api/factory/check` - Проверить наличие адресов
|
|
||||||
|
|
||||||
#### Автоматическое управление:
|
|
||||||
- **Кэширование** - Factory адреса сохраняются в базе данных
|
|
||||||
- **Переиспользование** - Существующие Factory используются повторно
|
|
||||||
- **Валидация** - Проверка существования Factory в блокчейне
|
|
||||||
- **Автодеплой** - Новые Factory деплоятся при необходимости
|
|
||||||
|
|
||||||
### 6. Проверка одинаковости адресов
|
|
||||||
|
|
||||||
Система автоматически проверяет, что все адреса одинаковые:
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
// Проверка адресов DLE
|
|
||||||
const addresses = results.filter(r => r.success).map(r => r.address);
|
|
||||||
const uniqueAddresses = [...new Set(addresses)];
|
|
||||||
|
|
||||||
if (uniqueAddresses.length === 1) {
|
|
||||||
console.log("✅ Все адреса DLE одинаковые:", uniqueAddresses[0]);
|
|
||||||
} else {
|
|
||||||
throw new Error("CREATE2 не обеспечил одинаковые адреса");
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Если адреса не совпадают, это указывает на проблему с:
|
|
||||||
- Разными Factory адресами в сетях
|
|
||||||
- Разными salt значениями
|
|
||||||
- Разными bytecode контрактов
|
|
||||||
|
|
||||||
## Технические детали
|
|
||||||
|
|
||||||
### База данных Factory адресов
|
|
||||||
|
|
||||||
Система использует таблицу `factory_addresses` для хранения адресов:
|
|
||||||
|
|
||||||
```sql
|
|
||||||
CREATE TABLE factory_addresses (
|
|
||||||
id SERIAL PRIMARY KEY,
|
|
||||||
chain_id INTEGER NOT NULL UNIQUE,
|
|
||||||
factory_address VARCHAR(42) NOT NULL,
|
|
||||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
||||||
);
|
|
||||||
```
|
|
||||||
|
|
||||||
### CREATE Механизм
|
|
||||||
|
|
||||||
Система использует CREATE с выровненным nonce для обеспечения одинаковых адресов:
|
|
||||||
|
|
||||||
#### 1. Выравнивание nonce
|
|
||||||
```javascript
|
|
||||||
// Выравнивание nonce до целевого значения
|
|
||||||
while (currentNonce < targetNonce) {
|
|
||||||
await sendTransaction({
|
|
||||||
to: burnAddress,
|
|
||||||
value: 0,
|
|
||||||
nonce: currentNonce
|
|
||||||
});
|
|
||||||
currentNonce++;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 2. Деплой DLE
|
|
||||||
```javascript
|
|
||||||
// Вычисление адреса DLE через CREATE
|
|
||||||
const predictedAddress = ethers.getCreateAddress({
|
|
||||||
from: wallet.address,
|
|
||||||
nonce: targetNonce
|
|
||||||
});
|
|
||||||
|
|
||||||
// Деплой DLE с предсказанным адресом
|
|
||||||
await wallet.sendTransaction({
|
|
||||||
data: dleInitCode,
|
|
||||||
nonce: targetNonce
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Ключевые принципы:
|
|
||||||
- **Выровненный nonce** обеспечивает одинаковые адреса во всех сетях
|
|
||||||
- **Burn address** используется для выравнивания nonce без потери средств
|
|
||||||
- **Проверка баланса** перед деплоем предотвращает неудачи
|
|
||||||
- **DLE Contract** деплоится через Factory с одинаковым salt
|
|
||||||
- **Результат**: Одинаковый адрес DLE во всех EVM-совместимых сетях
|
|
||||||
|
|
||||||
### Структура DLE
|
|
||||||
|
|
||||||
```solidity
|
|
||||||
contract DLE is ERC20, ERC20Permit, ERC20Votes, ReentrancyGuard {
|
|
||||||
// Основная информация
|
|
||||||
DLEInfo public dleInfo;
|
|
||||||
|
|
||||||
// Настройки управления
|
|
||||||
uint256 public quorumPercentage;
|
|
||||||
|
|
||||||
// Мульти-чейн поддержка
|
|
||||||
uint256[] public supportedChainIds;
|
|
||||||
uint256 public governanceChainId;
|
|
||||||
|
|
||||||
// Система предложений
|
|
||||||
mapping(uint256 => Proposal) public proposals;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Базовые модули (автоматически деплоятся)
|
|
||||||
|
|
||||||
При деплое DLE автоматически развертываются и инициализируются:
|
|
||||||
|
|
||||||
- **TreasuryModule** - Управление финансами, депозиты, выводы, дивиденды
|
|
||||||
- **TimelockModule** - Задержки исполнения критических операций
|
|
||||||
- **DLEReader** - API для чтения данных DLE
|
|
||||||
|
|
||||||
### Дополнительные модули (через голосование)
|
|
||||||
|
|
||||||
DLE поддерживает модульную архитектуру:
|
|
||||||
|
|
||||||
- **CommunicationModule** - Внешние коммуникации
|
|
||||||
- **BurnModule** - Сжигание токенов
|
|
||||||
- **MintModule** - Выпуск новых токенов
|
|
||||||
- **OracleModule** - Внешние данные
|
|
||||||
- **CustomModule** - Пользовательские модули
|
|
||||||
|
|
||||||
## Управление DLE
|
|
||||||
|
|
||||||
### Создание предложений
|
|
||||||
|
|
||||||
```solidity
|
|
||||||
// Создать предложение
|
|
||||||
uint256 proposalId = dle.createProposal(
|
|
||||||
"Описание предложения",
|
|
||||||
governanceChainId,
|
|
||||||
targetChains,
|
|
||||||
timelockHours,
|
|
||||||
operationCalldata
|
|
||||||
);
|
|
||||||
```
|
|
||||||
|
|
||||||
### Голосование
|
|
||||||
|
|
||||||
```solidity
|
|
||||||
// Голосовать за предложение
|
|
||||||
dle.vote(proposalId, true); // За
|
|
||||||
dle.vote(proposalId, false); // Против
|
|
||||||
```
|
|
||||||
|
|
||||||
### Исполнение
|
|
||||||
|
|
||||||
```solidity
|
|
||||||
// Исполнить предложение
|
|
||||||
dle.executeProposalBySignatures(proposalId, signatures);
|
|
||||||
```
|
|
||||||
|
|
||||||
## Безопасность
|
|
||||||
|
|
||||||
### Ключевые принципы
|
|
||||||
|
|
||||||
1. **Только токен-холдеры** участвуют в управлении
|
|
||||||
2. **Прямые переводы токенов заблокированы**
|
|
||||||
3. **Все операции через кворум**
|
|
||||||
4. **CREATE2 обеспечивает детерминистические адреса**
|
|
||||||
5. **EIP-712 подписи для мульти-чейн исполнения**
|
|
||||||
|
|
||||||
### Проверки
|
|
||||||
|
|
||||||
- Валидация приватных ключей
|
|
||||||
- Проверка балансов перед деплоем
|
|
||||||
- Верификация CREATE2 адресов
|
|
||||||
- Контроль кворума при голосовании
|
|
||||||
|
|
||||||
## Устранение неполадок
|
|
||||||
|
|
||||||
### Частые проблемы
|
|
||||||
|
|
||||||
1. **Недостаточно средств**
|
|
||||||
- Проверьте балансы во всех сетях
|
|
||||||
- Убедитесь в правильности RPC URLs в настройках
|
|
||||||
|
|
||||||
2. **Ошибки компиляции**
|
|
||||||
- Проверьте версию Solidity (0.8.20)
|
|
||||||
- Убедитесь в корректности импортов OpenZeppelin
|
|
||||||
|
|
||||||
3. **Разные адреса в сетях**
|
|
||||||
- Проверьте, что Factory контракты имеют одинаковые адреса
|
|
||||||
- Проверьте CREATE2 salt для DLE
|
|
||||||
- Убедитесь в одинаковом bytecode контрактов
|
|
||||||
- Проверьте nonce кошелька деплоера
|
|
||||||
|
|
||||||
4. **Ошибки верификации**
|
|
||||||
- Проверьте API ключ Etherscan в форме деплоя
|
|
||||||
- Убедитесь в корректности constructor arguments
|
|
||||||
|
|
||||||
5. **RPC URL не найден**
|
|
||||||
- Проверьте настройки RPC провайдеров в `/settings/security`
|
|
||||||
- Убедитесь, что Chain ID указан правильно
|
|
||||||
- Протестируйте RPC URL через кнопку "Тест" в настройках
|
|
||||||
|
|
||||||
### Логи
|
|
||||||
|
|
||||||
Логи деплоя доступны в:
|
|
||||||
- Backend: `backend/logs/`
|
|
||||||
- Hardhat: `backend/artifacts/`
|
|
||||||
- Результаты: `backend/contracts-data/dles/`
|
|
||||||
|
|
||||||
## Поддержка
|
|
||||||
|
|
||||||
Для получения поддержки:
|
|
||||||
- Email: info@hb3-accelerator.com
|
|
||||||
- Website: https://hb3-accelerator.com
|
|
||||||
- GitHub: https://github.com/HB3-ACCELERATOR
|
|
||||||
@@ -1,717 +0,0 @@
|
|||||||
<!--
|
|
||||||
Copyright (c) 2024-2025 Тарабанов Александр Викторович
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
This software is proprietary and confidential.
|
|
||||||
Unauthorized copying, modification, or distribution is prohibited.
|
|
||||||
|
|
||||||
For licensing inquiries: info@hb3-accelerator.com
|
|
||||||
Website: https://hb3-accelerator.com
|
|
||||||
GitHub: https://github.com/HB3-ACCELERATOR
|
|
||||||
-->
|
|
||||||
|
|
||||||
# Детальный план задач: Управление Digital Legal Entity (DLE)
|
|
||||||
|
|
||||||
## Общие принципы разработки
|
|
||||||
|
|
||||||
### Архитектурные требования
|
|
||||||
- **Single-Chain Governance**: Голосование происходит только в одной выбранной сети
|
|
||||||
- **Кворум голосов токен‑холдеров**: Все операции требуют достижения кворума голосующей силы по снапшотам
|
|
||||||
- **Настраиваемые таймлоки**: Инициатор устанавливает задержку для каждого предложения
|
|
||||||
- **Cross-chain исполнение**: Решения выполняются во всех целевых сетях
|
|
||||||
- **Без админских ролей**: Только коллективное управление через токен-холдеров
|
|
||||||
|
|
||||||
### Технический стек
|
|
||||||
- **Frontend**: Vue.js 3 + Composition API
|
|
||||||
- **Web3**: ethers.js или web3.js
|
|
||||||
- **Контракты**: Solidity + OpenZeppelin (ERC‑4337 опционально для кошельков/UX)
|
|
||||||
- **Стили**: Scoped CSS с переменными
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Обновления (DLE v2)
|
|
||||||
|
|
||||||
- Деплой:
|
|
||||||
- Мультисетевой деплой одной кнопкой: backend вызывает `deploy-multichain.js`.
|
|
||||||
- Предсказанные адреса DLE отображаются автоматически (endpoint `/api/dle-v2/predict-addresses`).
|
|
||||||
- INIT_CODE_HASH вычисляется автоматически на backend, не вводится вручную.
|
|
||||||
- Предложения (UI):
|
|
||||||
- Порядок секций: Базовая информация → Timelock → Governance‑сеть → Целевые сети → Тип операции и параметры → Предпросмотр.
|
|
||||||
- Поля: `timelockHours`, `targetChains`, `governanceChainId`.
|
|
||||||
- Аналитика:
|
|
||||||
- Использовать новые view‑функции: `getProposalSummary`, `getProposalState`, `getProposalVotes`, `getQuorumAt`, `getVotingPowerAt`, `listSupportedChains`, `getGovernanceParams`.
|
|
||||||
|
|
||||||
## 1. БЛОК "ПРЕДЛОЖЕНИЯ" (`/management/proposals`)
|
|
||||||
|
|
||||||
### Задача 1.1: Создание предложений
|
|
||||||
**Описание**: Пользователь создает предложение для выполнения операции в DLE
|
|
||||||
|
|
||||||
**Что нужно сделать**:
|
|
||||||
- [ ] Добавить форму создания предложения с полями:
|
|
||||||
- Тип операции (управление токенами, казна, модули, настройки)
|
|
||||||
- Описание операции (текстовое поле)
|
|
||||||
- Выбор governance-сети (выпадающий список)
|
|
||||||
- Выбор целевых сетей для исполнения (мультиселект)
|
|
||||||
- Таймлок задержка в часах (числовое поле)
|
|
||||||
- [ ] Подключить к контракту метод `createProposal(operation, targetChains, timelockDelay)`
|
|
||||||
- [ ] Добавить валидацию: только токен-холдеры могут создавать предложения
|
|
||||||
- [ ] Показывать предварительный расчет газа для создания предложения
|
|
||||||
|
|
||||||
**Время**: 8-12 часов
|
|
||||||
|
|
||||||
### Задача 1.2: Подписание предложений
|
|
||||||
**Описание**: Токен-холдеры подписывают предложения для достижения кворума
|
|
||||||
|
|
||||||
**Что нужно сделать**:
|
|
||||||
- [ ] Отображать список активных предложений с прогрессом подписей
|
|
||||||
- [ ] Показывать для каждого предложения:
|
|
||||||
- Текущее количество подписей / требуемый кворум
|
|
||||||
- Список подписавших с их балансами токенов
|
|
||||||
- Время до истечения таймлока
|
|
||||||
- [ ] Добавить кнопку "Подписать" для токен-холдеров
|
|
||||||
- [ ] Подключить к контракту метод `signProposal(proposalId)`
|
|
||||||
- [ ] Проверять баланс токенов при подписании
|
|
||||||
- [ ] Обновлять UI в реальном времени при новых подписях
|
|
||||||
|
|
||||||
**Время**: 10-14 часов
|
|
||||||
|
|
||||||
### Задача 1.3: Исполнение предложений
|
|
||||||
**Описание**: Выполнение предложений после достижения кворума и истечения таймлока
|
|
||||||
|
|
||||||
**Что нужно сделать**:
|
|
||||||
- [ ] Отображать статус предложений: "Ожидание", "Кворум достигнут", "Готово к исполнению", "Исполнено"
|
|
||||||
- [ ] Добавить кнопку "Исполнить" для предложений готовых к исполнению
|
|
||||||
- [ ] Подключить к контракту метод `executeProposal(proposalId)`
|
|
||||||
- [ ] Показывать прогресс исполнения в целевых сетях
|
|
||||||
- [ ] Обрабатывать ошибки исполнения и показывать fallback статусы
|
|
||||||
- [ ] Добавить возможность отмены предложений до истечения таймлока
|
|
||||||
|
|
||||||
**Время**: 8-12 часов
|
|
||||||
|
|
||||||
### Задача 1.4: История и фильтрация
|
|
||||||
**Описание**: Просмотр истории предложений с возможностью фильтрации
|
|
||||||
|
|
||||||
**Что нужно сделать**:
|
|
||||||
- [ ] Добавить фильтры по:
|
|
||||||
- Статусу предложения
|
|
||||||
- Типу операции
|
|
||||||
- Governance-сети
|
|
||||||
- Периоду времени
|
|
||||||
- [ ] Реализовать поиск по описанию предложения
|
|
||||||
- [ ] Добавить пагинацию для больших списков
|
|
||||||
- [ ] Показывать детали каждого предложения в модальном окне
|
|
||||||
- [ ] Добавить ссылки на блокчейн-эксплореры для транзакций
|
|
||||||
|
|
||||||
**Время**: 6-8 часов
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 2. БЛОК "ТОКЕНЫ DLE" (`/management/tokens`)
|
|
||||||
|
|
||||||
### Задача 2.1: Информация о токенах
|
|
||||||
**Описание**: Отображение основной информации о токенах DLE
|
|
||||||
|
|
||||||
**Что нужно сделать**:
|
|
||||||
- [ ] Показывать общий supply токенов
|
|
||||||
- [ ] Отображать баланс текущего пользователя
|
|
||||||
- [ ] Показывать процент кворума для голосования
|
|
||||||
- [ ] Отображать текущую рыночную стоимость токена (если доступна)
|
|
||||||
- [ ] Подключить к контракту методы `totalSupply()`, `balanceOf(address)`
|
|
||||||
- [ ] Обновлять данные в реальном времени при изменениях
|
|
||||||
|
|
||||||
**Время**: 4-6 часов
|
|
||||||
|
|
||||||
### Задача 2.2: Передача токенов
|
|
||||||
**Описание**: Перевод токенов между участниками через кворум
|
|
||||||
|
|
||||||
**Что нужно сделать**:
|
|
||||||
- [ ] Создать форму перевода с полями:
|
|
||||||
- Адрес получателя
|
|
||||||
- Количество токенов
|
|
||||||
- Описание перевода
|
|
||||||
- [ ] Создавать предложение для перевода токенов
|
|
||||||
- [ ] Показывать статус предложения перевода
|
|
||||||
- [ ] Валидировать баланс отправителя
|
|
||||||
- [ ] Подключать к контракту через систему предложений
|
|
||||||
|
|
||||||
**Время**: 6-8 часов
|
|
||||||
|
|
||||||
### Задача 2.3: Распределение токенов
|
|
||||||
**Описание**: Массовое распределение токенов новым участникам
|
|
||||||
|
|
||||||
**Что нужно сделать**:
|
|
||||||
- [ ] Создать форму распределения с возможностью добавления множественных получателей
|
|
||||||
- [ ] Поля для каждого получателя: адрес, количество токенов
|
|
||||||
- [ ] Кнопки "Добавить получателя" и "Удалить получателя"
|
|
||||||
- [ ] Создавать предложение для распределения
|
|
||||||
- [ ] Показывать общую сумму распределения
|
|
||||||
- [ ] Валидировать общий supply и права на минтинг
|
|
||||||
|
|
||||||
**Время**: 8-10 часов
|
|
||||||
|
|
||||||
### Задача 2.4: Список держателей токенов
|
|
||||||
**Описание**: Отображение всех держателей токенов с их балансами
|
|
||||||
|
|
||||||
**Что нужно сделать**:
|
|
||||||
- [ ] Получать список всех держателей токенов
|
|
||||||
- [ ] Отображать для каждого держателя:
|
|
||||||
- Адрес кошелька
|
|
||||||
- Количество токенов
|
|
||||||
- Процент от общего supply
|
|
||||||
- Дата последней активности
|
|
||||||
- [ ] Добавить сортировку по балансу, активности, адресу
|
|
||||||
- [ ] Реализовать поиск по адресу
|
|
||||||
- [ ] Показывать топ-10 держателей отдельно
|
|
||||||
|
|
||||||
**Время**: 6-8 часов
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 3. БЛОК "КВОРУМ" (`/management/quorum`)
|
|
||||||
|
|
||||||
### Задача 3.1: Текущие настройки кворума
|
|
||||||
**Описание**: Отображение текущих параметров кворума
|
|
||||||
|
|
||||||
**Что нужно сделать**:
|
|
||||||
- [ ] Показывать текущий процент кворума для голосования
|
|
||||||
- [ ] Отображать минимальную задержку голосования
|
|
||||||
- [ ] Показывать период голосования
|
|
||||||
- [ ] Отображать порог для создания предложений
|
|
||||||
- [ ] Подключать к контракту для получения актуальных значений
|
|
||||||
- [ ] Показывать когда были изменены последние настройки
|
|
||||||
|
|
||||||
**Время**: 4-6 часов
|
|
||||||
|
|
||||||
### Задача 3.2: Изменение настроек кворума
|
|
||||||
**Описание**: Создание предложения для изменения параметров кворума
|
|
||||||
|
|
||||||
**Что нужно сделать**:
|
|
||||||
- [ ] Создать форму изменения настроек с полями:
|
|
||||||
- Новый процент кворума (1-100%)
|
|
||||||
- Новая задержка голосования (в часах)
|
|
||||||
- Новый период голосования (в днях)
|
|
||||||
- Новый порог для предложений (в токенах)
|
|
||||||
- Причина изменения
|
|
||||||
- [ ] Валидировать значения (кворум не менее 51%, разумные периоды)
|
|
||||||
- [ ] Создавать предложение для изменения настроек
|
|
||||||
- [ ] Показывать предварительный расчет влияния изменений
|
|
||||||
- [ ] Добавить подтверждение критических изменений
|
|
||||||
|
|
||||||
**Время**: 8-10 часов
|
|
||||||
|
|
||||||
### Задача 3.3: История изменений кворума
|
|
||||||
**Описание**: Просмотр истории изменений параметров кворума
|
|
||||||
|
|
||||||
**Что нужно сделать**:
|
|
||||||
- [ ] Отображать список всех изменений кворума
|
|
||||||
- [ ] Показывать для каждого изменения:
|
|
||||||
- Старые и новые значения
|
|
||||||
- Кто инициировал изменение
|
|
||||||
- Когда было предложено и когда принято
|
|
||||||
- Причину изменения
|
|
||||||
- [ ] Добавить фильтрацию по периоду и типу изменений
|
|
||||||
- [ ] Показывать статистику изменений (частота, тренды)
|
|
||||||
|
|
||||||
**Время**: 6-8 часов
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 4. БЛОК "МОДУЛИ DLE" (`/management/modules`)
|
|
||||||
|
|
||||||
### Задача 4.1: Список установленных модулей
|
|
||||||
**Описание**: Отображение всех установленных модулей DLE
|
|
||||||
|
|
||||||
**Что нужно сделать**:
|
|
||||||
- [ ] Получать список всех модулей из контракта
|
|
||||||
- [ ] Отображать для каждого модуля:
|
|
||||||
- Название и описание
|
|
||||||
- Адрес контракта модуля
|
|
||||||
- Версию модуля
|
|
||||||
- Статус (активен/неактивен)
|
|
||||||
- Дата установки
|
|
||||||
- [ ] Показывать общую статистику модулей
|
|
||||||
- [ ] Добавить поиск и фильтрацию по модулям
|
|
||||||
|
|
||||||
**Время**: 6-8 часов
|
|
||||||
|
|
||||||
### Задача 4.2: Установка новых модулей
|
|
||||||
**Описание**: Добавление новых модулей через голосование
|
|
||||||
|
|
||||||
**Что нужно сделать**:
|
|
||||||
- [ ] Создать форму установки модуля с полями:
|
|
||||||
- Название модуля
|
|
||||||
- Адрес контракта модуля
|
|
||||||
- Описание функциональности
|
|
||||||
- Параметры инициализации
|
|
||||||
- Причина установки
|
|
||||||
- [ ] Валидировать адрес контракта и совместимость
|
|
||||||
- [ ] Создавать предложение для установки модуля
|
|
||||||
- [ ] Показывать предварительную проверку модуля
|
|
||||||
- [ ] Добавить возможность тестирования модуля перед установкой
|
|
||||||
|
|
||||||
**Время**: 10-12 часов
|
|
||||||
|
|
||||||
### Задача 4.3: Управление модулями
|
|
||||||
**Описание**: Активация, деактивация и удаление модулей
|
|
||||||
|
|
||||||
**Что нужно сделать**:
|
|
||||||
- [ ] Добавить кнопки управления для каждого модуля:
|
|
||||||
- Активировать/деактивировать
|
|
||||||
- Обновить версию
|
|
||||||
- Удалить модуль
|
|
||||||
- [ ] Создавать предложения для каждого действия
|
|
||||||
- [ ] Показывать зависимости между модулями
|
|
||||||
- [ ] Предупреждать о критических операциях
|
|
||||||
- [ ] Добавить возможность отката изменений
|
|
||||||
|
|
||||||
**Время**: 8-10 часов
|
|
||||||
|
|
||||||
### Задача 4.4: Интерфейсы модулей
|
|
||||||
**Описание**: Встраивание интерфейсов управления модулями
|
|
||||||
|
|
||||||
**Что нужно сделать**:
|
|
||||||
- [ ] Создать систему встраивания интерфейсов модулей
|
|
||||||
- [ ] Каждый модуль может предоставлять свой UI
|
|
||||||
- [ ] Безопасное взаимодействие между основным приложением и модулями
|
|
||||||
- [ ] Единообразный стиль для всех модулей
|
|
||||||
- [ ] Добавить документацию для разработчиков модулей
|
|
||||||
|
|
||||||
**Время**: 12-16 часов
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 5. БЛОК "DLE" (Интеграция с другими DLE) (`/management/dle`)
|
|
||||||
|
|
||||||
### Задача 5.1: Список подключенных DLE
|
|
||||||
**Описание**: Отображение DLE, с которыми установлена интеграция
|
|
||||||
|
|
||||||
**Что нужно сделать**:
|
|
||||||
- [ ] Показывать карточки всех подключенных DLE
|
|
||||||
- [ ] Для каждого DLE отображать:
|
|
||||||
- Название и описание
|
|
||||||
- Адрес контракта
|
|
||||||
- Количество токенов этого DLE в нашем балансе
|
|
||||||
- Процент голосов, который мы можем использовать
|
|
||||||
- Статус подключения
|
|
||||||
- [ ] Добавить возможность удаления DLE из списка
|
|
||||||
- [ ] Показывать общую статистику интеграций
|
|
||||||
|
|
||||||
**Время**: 6-8 часов
|
|
||||||
|
|
||||||
### Задача 5.2: Добавление новых DLE
|
|
||||||
**Описание**: Подключение новых DLE для участия в их голосованиях
|
|
||||||
|
|
||||||
**Что нужно сделать**:
|
|
||||||
- [ ] Создать форму добавления DLE с полями:
|
|
||||||
- Название DLE
|
|
||||||
- Адрес контракта DLE
|
|
||||||
- Описание и назначение
|
|
||||||
- Причина подключения
|
|
||||||
- [ ] Валидировать адрес и проверять существование контракта
|
|
||||||
- [ ] Проверять баланс токенов этого DLE
|
|
||||||
- [ ] Создавать предложение для добавления DLE
|
|
||||||
- [ ] Показывать предварительную информацию о DLE
|
|
||||||
|
|
||||||
**Время**: 8-10 часов
|
|
||||||
|
|
||||||
### Задача 5.3: Участие в голосованиях других DLE
|
|
||||||
**Описание**: Голосование в предложениях других DLE через наш кворум
|
|
||||||
|
|
||||||
**Что нужно сделать**:
|
|
||||||
- [ ] Отображать активные предложения других DLE
|
|
||||||
- [ ] Показывать для каждого предложения:
|
|
||||||
- Описание и тип операции
|
|
||||||
- Наш возможный вес голоса
|
|
||||||
- Текущий статус голосования
|
|
||||||
- Время до истечения
|
|
||||||
- [ ] Создавать внутренние предложения для голосования в других DLE
|
|
||||||
- [ ] Собирать кворум подписей для внешнего голосования
|
|
||||||
- [ ] Отправлять голос в целевое DLE после достижения кворума
|
|
||||||
|
|
||||||
**Время**: 12-16 часов
|
|
||||||
|
|
||||||
### Задача 5.4: Встраивание интерфейсов управления
|
|
||||||
**Описание**: Управление другими DLE через встроенные интерфейсы
|
|
||||||
|
|
||||||
**Что нужно сделать**:
|
|
||||||
- [ ] Создать систему встраивания интерфейсов других DLE
|
|
||||||
- [ ] Безопасное отображение внешних интерфейсов в iframe
|
|
||||||
- [ ] Передача контекста аутентификации
|
|
||||||
- [ ] Обработка событий и обновлений
|
|
||||||
- [ ] Единообразный стиль и навигация
|
|
||||||
- [ ] Добавить возможность открытия в новой вкладке
|
|
||||||
|
|
||||||
**Время**: 16-20 часов
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 6. БЛОК "КАЗНА" (`/management/treasury`)
|
|
||||||
|
|
||||||
### Задача 6.1: Баланс казны
|
|
||||||
**Описание**: Отображение всех активов казны DLE
|
|
||||||
|
|
||||||
**Что нужно сделать**:
|
|
||||||
- [ ] Показывать балансы всех токенов в казне:
|
|
||||||
- Нативные токены (ETH, MATIC, BNB и т.д.)
|
|
||||||
- ERC-20 токены
|
|
||||||
- NFT и другие активы
|
|
||||||
- [ ] Отображать общую стоимость в USD
|
|
||||||
- [ ] Показывать историю изменений баланса
|
|
||||||
- [ ] Добавить графики движения средств
|
|
||||||
- [ ] Подключать к контракту для получения актуальных данных
|
|
||||||
|
|
||||||
**Время**: 8-10 часов
|
|
||||||
|
|
||||||
### Задача 6.2: Операции с казной
|
|
||||||
**Описание**: Выполнение финансовых операций через кворум
|
|
||||||
|
|
||||||
**Что нужно сделать**:
|
|
||||||
- [ ] Создать формы для различных операций:
|
|
||||||
- Отправка средств (нативные токены, ERC-20)
|
|
||||||
- Получение средств
|
|
||||||
- Обмен токенов
|
|
||||||
- Инвестиции в DeFi протоколы
|
|
||||||
- [ ] Создавать предложения для каждой операции
|
|
||||||
- [ ] Валидировать балансы и права доступа
|
|
||||||
- [ ] Показывать предварительный расчет газа и комиссий
|
|
||||||
- [ ] Добавить подтверждение критических операций
|
|
||||||
|
|
||||||
**Время**: 12-16 часов
|
|
||||||
|
|
||||||
### Задача 6.3: Распределение дивидендов
|
|
||||||
**Описание**: Выплата дивидендов токен-холдерам
|
|
||||||
|
|
||||||
**Что нужно сделать**:
|
|
||||||
- [ ] Создать форму распределения дивидендов:
|
|
||||||
- Выбор токена для выплаты
|
|
||||||
- Общая сумма дивидендов
|
|
||||||
- Пропорциональное распределение по балансам
|
|
||||||
- [ ] Показывать предварительный расчет выплат каждому держателю
|
|
||||||
- [ ] Создавать предложение для выплаты дивидендов
|
|
||||||
- [ ] Отслеживать статус выплат
|
|
||||||
- [ ] Показывать историю дивидендных выплат
|
|
||||||
|
|
||||||
**Время**: 10-12 часов
|
|
||||||
|
|
||||||
### Задача 6.4: Бюджетирование и отчеты
|
|
||||||
**Описание**: Планирование и контроль расходов казны
|
|
||||||
|
|
||||||
**Что нужно сделать**:
|
|
||||||
- [ ] Создать систему бюджетирования:
|
|
||||||
- Установка лимитов расходов
|
|
||||||
- Категоризация операций
|
|
||||||
- Планирование расходов
|
|
||||||
- [ ] Генерировать отчеты:
|
|
||||||
- Месячные/квартальные отчеты
|
|
||||||
- Анализ доходов и расходов
|
|
||||||
- Прогнозы движения средств
|
|
||||||
- [ ] Добавить уведомления о превышении лимитов
|
|
||||||
- [ ] Экспорт отчетов в PDF/CSV
|
|
||||||
|
|
||||||
**Время**: 12-16 часов
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 7. БЛОК "АНАЛИТИКА" (`/management/analytics`)
|
|
||||||
|
|
||||||
### Задача 7.1: Ключевые метрики
|
|
||||||
**Описание**: Отображение основных показателей DLE
|
|
||||||
|
|
||||||
**Что нужно сделать**:
|
|
||||||
- [ ] Показывать ключевые метрики:
|
|
||||||
- Общая стоимость активов (TVL)
|
|
||||||
- Количество активных участников
|
|
||||||
- Количество предложений за период
|
|
||||||
- Средняя доходность
|
|
||||||
- [ ] Добавить сравнение с предыдущими периодами
|
|
||||||
- [ ] Показывать тренды и изменения
|
|
||||||
- [ ] Подключать реальные данные из контрактов
|
|
||||||
|
|
||||||
**Время**: 8-10 часов
|
|
||||||
|
|
||||||
### Задача 7.2: Графики и визуализация
|
|
||||||
**Описание**: Создание интерактивных графиков и диаграмм
|
|
||||||
|
|
||||||
**Что нужно сделать**:
|
|
||||||
- [ ] Интегрировать библиотеку для графиков (Chart.js, D3.js)
|
|
||||||
- [ ] Создать графики:
|
|
||||||
- Стоимость токенов во времени
|
|
||||||
- Активность участников по дням/неделям
|
|
||||||
- Распределение токенов между держателями
|
|
||||||
- Движение средств в казне
|
|
||||||
- [ ] Добавить интерактивность (зум, фильтры, детализация)
|
|
||||||
- [ ] Реализовать экспорт графиков
|
|
||||||
|
|
||||||
**Время**: 12-16 часов
|
|
||||||
|
|
||||||
### Задача 7.3: Статистика и отчеты
|
|
||||||
**Описание**: Детальная аналитика и отчетность
|
|
||||||
|
|
||||||
**Что нужно сделать**:
|
|
||||||
- [ ] Создать разделы статистики:
|
|
||||||
- Топ держателей токенов
|
|
||||||
- Самые активные участники
|
|
||||||
- История предложений и голосований
|
|
||||||
- Финансовая статистика
|
|
||||||
- [ ] Добавить фильтры по периодам
|
|
||||||
- [ ] Создать настраиваемые дашборды
|
|
||||||
- [ ] Реализовать автоматическую генерацию отчетов
|
|
||||||
|
|
||||||
**Время**: 10-14 часов
|
|
||||||
|
|
||||||
### Задача 7.4: Прогнозирование и тренды
|
|
||||||
**Описание**: Анализ трендов и прогнозирование
|
|
||||||
|
|
||||||
**Что нужно сделать**:
|
|
||||||
- [ ] Анализировать исторические данные для выявления трендов
|
|
||||||
- [ ] Создавать прогнозы:
|
|
||||||
- Движение стоимости токенов
|
|
||||||
- Активность участников
|
|
||||||
- Финансовые показатели
|
|
||||||
- [ ] Показывать аномалии и важные события
|
|
||||||
- [ ] Добавить уведомления о значимых изменениях
|
|
||||||
|
|
||||||
**Время**: 14-18 часов
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 8. БЛОК "ИСТОРИЯ" (`/management/history`)
|
|
||||||
|
|
||||||
### Задача 8.1: Лог всех операций
|
|
||||||
**Описание**: Отображение полной истории операций DLE
|
|
||||||
|
|
||||||
**Что нужно сделать**:
|
|
||||||
- [ ] Собирать и отображать все типы операций:
|
|
||||||
- Создание и исполнение предложений
|
|
||||||
- Операции с токенами
|
|
||||||
- Казначейские операции
|
|
||||||
- Изменения настроек
|
|
||||||
- Модульные операции
|
|
||||||
- [ ] Для каждой операции показывать:
|
|
||||||
- Тип и описание
|
|
||||||
- Время выполнения
|
|
||||||
- Участники
|
|
||||||
- Статус выполнения
|
|
||||||
- Ссылки на транзакции
|
|
||||||
|
|
||||||
**Время**: 10-12 часов
|
|
||||||
|
|
||||||
### Задача 8.2: Фильтрация и поиск
|
|
||||||
**Описание**: Удобный поиск и фильтрация истории
|
|
||||||
|
|
||||||
**Что нужно сделать**:
|
|
||||||
- [ ] Добавить фильтры по:
|
|
||||||
- Типу операции
|
|
||||||
- Периоду времени
|
|
||||||
- Участникам
|
|
||||||
- Статусу
|
|
||||||
- Сетям
|
|
||||||
- [ ] Реализовать полнотекстовый поиск
|
|
||||||
- [ ] Добавить сохранение фильтров
|
|
||||||
- [ ] Создать быстрые фильтры (сегодня, неделя, месяц)
|
|
||||||
|
|
||||||
**Время**: 8-10 часов
|
|
||||||
|
|
||||||
### Задача 8.3: Детали операций
|
|
||||||
**Описание**: Подробная информация о каждой операции
|
|
||||||
|
|
||||||
**Что нужно сделать**:
|
|
||||||
- [ ] Создать модальные окна с деталями операций
|
|
||||||
- [ ] Показывать полную информацию:
|
|
||||||
- Параметры операции
|
|
||||||
- Участники и их роли
|
|
||||||
- Результат выполнения
|
|
||||||
- Ошибки и предупреждения
|
|
||||||
- [ ] Добавить ссылки на блокчейн-эксплореры
|
|
||||||
- [ ] Показывать связанные операции
|
|
||||||
|
|
||||||
**Время**: 8-10 часов
|
|
||||||
|
|
||||||
### Задача 8.4: Экспорт и отчеты
|
|
||||||
**Описание**: Экспорт истории в различные форматы
|
|
||||||
|
|
||||||
**Что нужно сделать**:
|
|
||||||
- [ ] Реализовать экспорт в форматы:
|
|
||||||
- CSV для анализа в Excel
|
|
||||||
- PDF для отчетов
|
|
||||||
- JSON для интеграции
|
|
||||||
- [ ] Добавить настройки экспорта (период, типы операций)
|
|
||||||
- [ ] Создать шаблоны отчетов
|
|
||||||
- [ ] Добавить автоматическую отправку отчетов
|
|
||||||
|
|
||||||
**Время**: 6-8 часов
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 9. БЛОК "НАСТРОЙКИ" (`/management/settings`)
|
|
||||||
|
|
||||||
### Задача 9.1: Основные настройки DLE
|
|
||||||
**Описание**: Управление основной информацией о DLE
|
|
||||||
|
|
||||||
**Что нужно сделать**:
|
|
||||||
- [ ] Создать форму основных настроек:
|
|
||||||
- Название DLE
|
|
||||||
- Символ токена
|
|
||||||
- Описание и назначение
|
|
||||||
- Местонахождение
|
|
||||||
- Веб-сайт
|
|
||||||
- [ ] Подключать к контракту для сохранения изменений
|
|
||||||
- [ ] Валидировать данные перед сохранением
|
|
||||||
- [ ] Показывать историю изменений
|
|
||||||
|
|
||||||
**Время**: 6-8 часов
|
|
||||||
|
|
||||||
### Задача 9.2: Настройки безопасности
|
|
||||||
**Описание**: Управление параметрами безопасности
|
|
||||||
|
|
||||||
**Что нужно сделать**:
|
|
||||||
- [ ] Создать форму настроек безопасности:
|
|
||||||
- Минимальный кворум для голосования
|
|
||||||
- Максимальная длительность предложений
|
|
||||||
- Порог для экстренных действий
|
|
||||||
- Задержка таймлока по умолчанию
|
|
||||||
- Дополнительные настройки (делегирование, KYC)
|
|
||||||
- [ ] Добавить предупреждения о критических изменениях
|
|
||||||
- [ ] Создавать предложения для изменения настроек
|
|
||||||
- [ ] Показывать влияние изменений на безопасность
|
|
||||||
|
|
||||||
**Время**: 10-12 часов
|
|
||||||
|
|
||||||
### Задача 9.3: Настройки сети
|
|
||||||
**Описание**: Управление сетевыми параметрами
|
|
||||||
|
|
||||||
**Что нужно сделать**:
|
|
||||||
- [ ] Создать форму настроек сети:
|
|
||||||
- Выбор поддерживаемых сетей
|
|
||||||
- Сеть по умолчанию для governance
|
|
||||||
- RPC endpoints для каждой сети
|
|
||||||
- Настройки синхронизации
|
|
||||||
- [ ] Тестировать подключение к сетям
|
|
||||||
- [ ] Показывать статус каждой сети
|
|
||||||
- [ ] Добавить возможность добавления новых сетей
|
|
||||||
|
|
||||||
**Время**: 8-10 часов
|
|
||||||
|
|
||||||
### Задача 9.4: Резервное копирование
|
|
||||||
**Описание**: Экспорт и импорт настроек
|
|
||||||
|
|
||||||
**Что нужно сделать**:
|
|
||||||
- [ ] Реализовать экспорт всех настроек в JSON
|
|
||||||
- [ ] Создать импорт настроек из файла
|
|
||||||
- [ ] Валидировать импортируемые данные
|
|
||||||
- [ ] Добавить предварительный просмотр изменений
|
|
||||||
- [ ] Создать автоматическое резервное копирование
|
|
||||||
|
|
||||||
**Время**: 6-8 часов
|
|
||||||
|
|
||||||
### Задача 9.5: Опасная зона
|
|
||||||
**Описание**: Критические операции с DLE
|
|
||||||
|
|
||||||
**Что нужно сделать**:
|
|
||||||
- [ ] Создать раздел опасных операций:
|
|
||||||
- Сброс настроек к значениям по умолчанию
|
|
||||||
- Полное удаление DLE
|
|
||||||
- Экстренная остановка операций
|
|
||||||
- [ ] Добавить множественные подтверждения
|
|
||||||
- [ ] Показывать последствия каждой операции
|
|
||||||
- [ ] Создать логирование критических действий
|
|
||||||
|
|
||||||
**Время**: 8-10 часов
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ОБЩИЕ ЗАДАЧИ ДЛЯ ВСЕХ БЛОКОВ
|
|
||||||
|
|
||||||
### Задача 0.1: Подготовка инфраструктуры
|
|
||||||
**Описание**: Настройка базовой инфраструктуры для всех блоков
|
|
||||||
|
|
||||||
**Что нужно сделать**:
|
|
||||||
- [ ] Настроить web3-провайдеры для всех поддерживаемых сетей
|
|
||||||
- [ ] Создать абстракции для работы с контрактами
|
|
||||||
- [ ] Настроить обработку ошибок и уведомления
|
|
||||||
- [ ] Создать систему кэширования данных
|
|
||||||
- [ ] Настроить мониторинг состояния сетей
|
|
||||||
|
|
||||||
**Время**: 16-20 часов
|
|
||||||
|
|
||||||
### Задача 0.2: Интеграция с контрактами
|
|
||||||
**Описание**: Подключение всех блоков к смарт-контрактам
|
|
||||||
|
|
||||||
**Что нужно сделать**:
|
|
||||||
- [ ] Создать интерфейсы для всех методов контрактов
|
|
||||||
- [ ] Реализовать обработку событий контрактов
|
|
||||||
- [ ] Настроить подписки на изменения состояния
|
|
||||||
- [ ] Добавить обработку ошибок транзакций
|
|
||||||
- [ ] Реализовать retry механизмы для неудачных транзакций
|
|
||||||
|
|
||||||
**Время**: 20-24 часа
|
|
||||||
|
|
||||||
### Задача 0.3: Тестирование и отладка
|
|
||||||
**Описание**: Комплексное тестирование всех функций
|
|
||||||
|
|
||||||
**Что нужно сделать**:
|
|
||||||
- [ ] Создать unit-тесты для всех компонентов
|
|
||||||
- [ ] Написать e2e тесты для основных сценариев
|
|
||||||
- [ ] Протестировать работу в разных сетях
|
|
||||||
- [ ] Провести нагрузочное тестирование
|
|
||||||
- [ ] Исправить найденные ошибки
|
|
||||||
|
|
||||||
**Время**: 24-32 часа
|
|
||||||
|
|
||||||
### Задача 0.4: Оптимизация и производительность
|
|
||||||
**Описание**: Улучшение производительности и пользовательского опыта
|
|
||||||
|
|
||||||
**Что нужно сделать**:
|
|
||||||
- [ ] Оптимизировать загрузку данных
|
|
||||||
- [ ] Добавить lazy loading для больших списков
|
|
||||||
- [ ] Реализовать кэширование на клиенте
|
|
||||||
- [ ] Оптимизировать размер бандла
|
|
||||||
- [ ] Добавить прогресс-индикаторы для длительных операций
|
|
||||||
|
|
||||||
**Время**: 16-20 часов
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ПРИОРИТЕТЫ РАЗРАБОТКИ
|
|
||||||
|
|
||||||
### Высокий приоритет (MVP)
|
|
||||||
1. Предложения - базовая функциональность
|
|
||||||
2. Токены DLE - основные операции
|
|
||||||
3. Кворум - текущие настройки
|
|
||||||
4. Настройки - основные параметры
|
|
||||||
|
|
||||||
### Средний приоритет
|
|
||||||
1. Казна - базовые операции
|
|
||||||
2. История - лог операций
|
|
||||||
3. Аналитика - ключевые метрики
|
|
||||||
4. Модули - список и управление
|
|
||||||
|
|
||||||
### Низкий приоритет
|
|
||||||
1. DLE - интеграция с другими DLE
|
|
||||||
2. Расширенная аналитика
|
|
||||||
3. Сложные отчеты
|
|
||||||
4. Встраивание интерфейсов
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ОЦЕНКА ВРЕМЕНИ
|
|
||||||
|
|
||||||
### Общее время разработки: 280-380 часов
|
|
||||||
|
|
||||||
**Разбивка по блокам:**
|
|
||||||
- Предложения: 32-46 часов
|
|
||||||
- Токены DLE: 24-32 часа
|
|
||||||
- Кворум: 18-24 часа
|
|
||||||
- Модули DLE: 36-46 часов
|
|
||||||
- DLE (интеграция): 42-54 часа
|
|
||||||
- Казна: 42-54 часа
|
|
||||||
- Аналитика: 44-58 часа
|
|
||||||
- История: 32-40 часов
|
|
||||||
- Настройки: 38-48 часов
|
|
||||||
- Общие задачи: 76-96 часов
|
|
||||||
|
|
||||||
**Рекомендации:**
|
|
||||||
- Начать с MVP (высокий приоритет)
|
|
||||||
- Разрабатывать параллельно несколько блоков
|
|
||||||
- Использовать готовые компоненты где возможно
|
|
||||||
- Регулярно тестировать интеграцию с контрактами
|
|
||||||
@@ -1,252 +0,0 @@
|
|||||||
<!--
|
|
||||||
Copyright (c) 2024-2025 Тарабанов Александр Викторович
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
This software is proprietary and confidential.
|
|
||||||
Unauthorized copying, modification, or distribution is prohibited.
|
|
||||||
|
|
||||||
For licensing inquiries: info@hb3-accelerator.com
|
|
||||||
Website: https://hb3-accelerator.com
|
|
||||||
GitHub: https://github.com/HB3-ACCELERATOR
|
|
||||||
-->
|
|
||||||
|
|
||||||
# 🔐 Полное шифрование всех таблиц в DLE
|
|
||||||
|
|
||||||
## 📋 Обзор
|
|
||||||
|
|
||||||
Этот подход шифрует **ВСЕ текстовые данные** во **ВСЕХ таблицах** базы данных.
|
|
||||||
|
|
||||||
## 🎯 Что шифруется
|
|
||||||
|
|
||||||
### **✅ ВСЕ текстовые колонки во ВСЕХ таблицах:**
|
|
||||||
- `text` - текстовые поля
|
|
||||||
- `varchar` - строки переменной длины
|
|
||||||
- `character varying` - строки переменной длины
|
|
||||||
- `json` - JSON данные
|
|
||||||
- `jsonb` - бинарные JSON данные
|
|
||||||
|
|
||||||
### **❌ НЕ шифруются:**
|
|
||||||
- `id` - идентификаторы
|
|
||||||
- `created_at`, `updated_at` - временные метки
|
|
||||||
- `integer`, `numeric`, `boolean` - числовые и логические типы
|
|
||||||
- Колонки, уже содержащие `_encrypted` в названии
|
|
||||||
|
|
||||||
## 🚀 Пошаговая инструкция
|
|
||||||
|
|
||||||
### **Шаг 1: Запуск полного шифрования**
|
|
||||||
```bash
|
|
||||||
chmod +x encrypt-all-tables.sh
|
|
||||||
./encrypt-all-tables.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
### **Шаг 2: Проверка шифрования**
|
|
||||||
```bash
|
|
||||||
./decrypt-all-tables.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
### **Шаг 3: Обновление кода приложения**
|
|
||||||
|
|
||||||
#### **A. Использование универсального сервиса**
|
|
||||||
```javascript
|
|
||||||
const encryptedDataService = require('./services/encryptedDataService');
|
|
||||||
|
|
||||||
// Получение данных с автоматической расшифровкой
|
|
||||||
const users = await encryptedDataService.getData('users', { role: 'admin' });
|
|
||||||
|
|
||||||
// Сохранение данных с автоматическим шифрованием
|
|
||||||
const newUser = await encryptedDataService.saveData('users', {
|
|
||||||
name: 'Иван Иванов',
|
|
||||||
email: 'ivan@example.com',
|
|
||||||
preferences: { theme: 'dark' }
|
|
||||||
});
|
|
||||||
|
|
||||||
// Обновление данных
|
|
||||||
const updatedUser = await encryptedDataService.saveData('users',
|
|
||||||
{ name: 'Иван Петров' },
|
|
||||||
{ id: 1 }
|
|
||||||
);
|
|
||||||
|
|
||||||
// Удаление данных
|
|
||||||
await encryptedDataService.deleteData('users', { id: 1 });
|
|
||||||
```
|
|
||||||
|
|
||||||
#### **B. Проверка статуса шифрования**
|
|
||||||
```javascript
|
|
||||||
const status = await encryptedDataService.getEncryptionStatus();
|
|
||||||
console.log('Статус шифрования:', status);
|
|
||||||
// {
|
|
||||||
// hasEncryptionKey: true,
|
|
||||||
// encryptedTables: [
|
|
||||||
// { table_name: 'users', encrypted_columns: '3' },
|
|
||||||
// { table_name: 'messages', encrypted_columns: '2' }
|
|
||||||
// ],
|
|
||||||
// totalEncryptedColumns: 15
|
|
||||||
// }
|
|
||||||
```
|
|
||||||
|
|
||||||
### **Шаг 4: Обновление существующих роутов**
|
|
||||||
|
|
||||||
#### **Пример обновления роута пользователей:**
|
|
||||||
```javascript
|
|
||||||
// Было:
|
|
||||||
router.get('/users', async (req, res) => {
|
|
||||||
const { rows } = await db.getQuery()('SELECT * FROM users');
|
|
||||||
res.json(rows);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Стало:
|
|
||||||
router.get('/users', async (req, res) => {
|
|
||||||
try {
|
|
||||||
const users = await encryptedDataService.getData('users');
|
|
||||||
res.json(users);
|
|
||||||
} catch (error) {
|
|
||||||
res.status(500).json({ error: error.message });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
#### **Пример обновления роута сообщений:**
|
|
||||||
```javascript
|
|
||||||
// Было:
|
|
||||||
router.post('/messages', async (req, res) => {
|
|
||||||
const { content, user_id } = req.body;
|
|
||||||
const { rows } = await db.getQuery()(
|
|
||||||
'INSERT INTO messages (content, user_id) VALUES ($1, $2) RETURNING *',
|
|
||||||
[content, user_id]
|
|
||||||
);
|
|
||||||
res.json(rows[0]);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Стало:
|
|
||||||
router.post('/messages', async (req, res) => {
|
|
||||||
try {
|
|
||||||
const { content, user_id } = req.body;
|
|
||||||
const message = await encryptedDataService.saveData('messages', {
|
|
||||||
content,
|
|
||||||
user_id
|
|
||||||
});
|
|
||||||
res.json(message);
|
|
||||||
} catch (error) {
|
|
||||||
res.status(500).json({ error: error.message });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
### **Шаг 5: Тестирование**
|
|
||||||
```bash
|
|
||||||
# Проверить работу зашифрованных данных
|
|
||||||
curl -X GET http://localhost:8000/api/users
|
|
||||||
curl -X POST http://localhost:8000/api/messages -H "Content-Type: application/json" -d '{"content":"Тестовое сообщение","user_id":1}'
|
|
||||||
|
|
||||||
# Проверить расшифровку
|
|
||||||
./decrypt-all-tables.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
### **Шаг 6: Удаление незашифрованных колонок**
|
|
||||||
```bash
|
|
||||||
# ВНИМАНИЕ: Это необратимая операция!
|
|
||||||
./remove-unencrypted-columns.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🔑 Управление ключами
|
|
||||||
|
|
||||||
### **Ключ шифрования**
|
|
||||||
- **Файл**: `./ssl/keys/full_db_encryption.key`
|
|
||||||
- **Размер**: 32 байта (base64)
|
|
||||||
- **Алгоритм**: AES-256-CBC
|
|
||||||
|
|
||||||
### **Безопасность ключа**
|
|
||||||
```bash
|
|
||||||
# Права доступа
|
|
||||||
chmod 600 ./ssl/keys/full_db_encryption.key
|
|
||||||
|
|
||||||
# Резервная копия
|
|
||||||
cp ./ssl/keys/full_db_encryption.key ./ssl/keys/full_db_encryption.key.backup
|
|
||||||
|
|
||||||
# Проверка целостности
|
|
||||||
sha256sum ./ssl/keys/full_db_encryption.key
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🛡️ Дополнительные меры безопасности
|
|
||||||
|
|
||||||
### **1. Шифрование томов Docker**
|
|
||||||
```yaml
|
|
||||||
# docker-compose.yml
|
|
||||||
volumes:
|
|
||||||
postgres_data:
|
|
||||||
driver: local
|
|
||||||
driver_opts:
|
|
||||||
type: none
|
|
||||||
o: bind
|
|
||||||
device: /path/to/encrypted/storage
|
|
||||||
```
|
|
||||||
|
|
||||||
### **2. SSL/TLS для PostgreSQL**
|
|
||||||
```yaml
|
|
||||||
# docker-compose.yml
|
|
||||||
services:
|
|
||||||
postgres:
|
|
||||||
command: >
|
|
||||||
postgres
|
|
||||||
-c ssl=on
|
|
||||||
-c ssl_cert_file=/etc/ssl/certs/server.crt
|
|
||||||
-c ssl_key_file=/etc/ssl/certs/server.key
|
|
||||||
```
|
|
||||||
|
|
||||||
### **3. Шифрование переменных окружения**
|
|
||||||
```bash
|
|
||||||
# Для оставшихся переменных окружения
|
|
||||||
./encrypt-env.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🔍 Мониторинг и аудит
|
|
||||||
|
|
||||||
### **Логирование доступа к зашифрованным данным**
|
|
||||||
```javascript
|
|
||||||
// В сервисе добавить логирование
|
|
||||||
console.log(`🔐 Доступ к зашифрованным данным: ${tableName} в ${new Date().toISOString()}`);
|
|
||||||
```
|
|
||||||
|
|
||||||
### **Проверка целостности**
|
|
||||||
```bash
|
|
||||||
# Скрипт для проверки целостности зашифрованных данных
|
|
||||||
./verify-encryption.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
## ⚠️ Важные замечания
|
|
||||||
|
|
||||||
### **1. Производительность**
|
|
||||||
- Шифрование/расшифровка добавляет задержку
|
|
||||||
- Используйте кэширование для часто используемых данных
|
|
||||||
- Рассмотрите индексы для зашифрованных колонок
|
|
||||||
|
|
||||||
### **2. Резервное копирование**
|
|
||||||
- **Обязательно** делайте бэкап ключа шифрования
|
|
||||||
- **Обязательно** делайте бэкап базы данных
|
|
||||||
- Храните ключ отдельно от данных
|
|
||||||
|
|
||||||
### **3. Восстановление**
|
|
||||||
```bash
|
|
||||||
# Восстановление из бэкапа
|
|
||||||
docker exec dapp-postgres psql -U dapp_user -d dapp_db < backup.sql
|
|
||||||
|
|
||||||
# Восстановление ключа
|
|
||||||
cp ./ssl/keys/full_db_encryption.key.backup ./ssl/keys/full_db_encryption.key
|
|
||||||
```
|
|
||||||
|
|
||||||
### **4. Совместимость**
|
|
||||||
- Приложение работает с зашифрованными и незашифрованными данными
|
|
||||||
- Fallback на незашифрованные данные при отсутствии ключа
|
|
||||||
- Постепенная миграция существующих данных
|
|
||||||
|
|
||||||
## 🎯 Результат
|
|
||||||
|
|
||||||
После применения полного шифрования:
|
|
||||||
- ✅ ВСЕ текстовые данные зашифрованы в БД
|
|
||||||
- ✅ Ключ шифрования хранится отдельно
|
|
||||||
- ✅ Приложение работает с зашифрованными данными
|
|
||||||
- ✅ Fallback на незашифрованные данные при отсутствии ключа
|
|
||||||
- ✅ Универсальный сервис для работы с данными
|
|
||||||
- ✅ Возможность ротации ключей
|
|
||||||
|
|
||||||
**Максимальная безопасность данных достигнута!** 🔒
|
|
||||||
@@ -1,122 +0,0 @@
|
|||||||
<!--
|
|
||||||
Copyright (c) 2024-2025 Тарабанов Александр Викторович
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
This software is proprietary and confidential.
|
|
||||||
Unauthorized copying, modification, or distribution is prohibited.
|
|
||||||
|
|
||||||
For licensing inquiries: info@hb3-accelerator.com
|
|
||||||
Website: https://hb3-accelerator.com
|
|
||||||
GitHub: https://github.com/HB3-ACCELERATOR
|
|
||||||
-->
|
|
||||||
|
|
||||||
# Архитектура фронтенда DLE
|
|
||||||
|
|
||||||
## 📁 Структура сервисов
|
|
||||||
|
|
||||||
### 🎯 Принцип разделения ответственности
|
|
||||||
|
|
||||||
Каждый сервис отвечает за свою область функциональности:
|
|
||||||
|
|
||||||
```
|
|
||||||
services/
|
|
||||||
├── dleV2Service.js - Основные функции DLE (создание, чтение, управление)
|
|
||||||
├── modulesService.js - Управление модулями DLE
|
|
||||||
├── proposalsService.js - Управление предложениями и голосованием
|
|
||||||
├── tokensService.js - Работа с токенами и балансами
|
|
||||||
├── analyticsService.js - Аналитические данные и статистика
|
|
||||||
├── multichainService.js - Мультичейн функциональность
|
|
||||||
└── index.js - Индексный файл для удобного импорта
|
|
||||||
```
|
|
||||||
|
|
||||||
### 🔧 Использование сервисов
|
|
||||||
|
|
||||||
#### Импорт отдельных сервисов:
|
|
||||||
```javascript
|
|
||||||
import { getDLEInfo } from '@/services/dleV2Service.js';
|
|
||||||
import { createAddModuleProposal } from '@/services/modulesService.js';
|
|
||||||
import { createProposal } from '@/services/proposalsService.js';
|
|
||||||
import { getTokenBalance } from '@/services/tokensService.js';
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Импорт через индексный файл:
|
|
||||||
```javascript
|
|
||||||
import {
|
|
||||||
getDLEInfo,
|
|
||||||
createAddModuleProposal,
|
|
||||||
createProposal,
|
|
||||||
getTokenBalance
|
|
||||||
} from '@/services/index.js';
|
|
||||||
```
|
|
||||||
|
|
||||||
## 📄 Страницы управления DLE
|
|
||||||
|
|
||||||
### 🎨 Компоненты страниц:
|
|
||||||
|
|
||||||
| Страница | Файл | Используемые сервисы | Описание |
|
|
||||||
|----------|------|---------------------|----------|
|
|
||||||
| **Модули** | `ModulesView.vue` | `modulesService.js` | Управление модулями DLE |
|
|
||||||
| **Предложения** | `DleProposalsView.vue` | `proposalsService.js` | Управление предложениями |
|
|
||||||
| **Токены** | `TokensView.vue` | `tokensService.js` | Работа с токенами |
|
|
||||||
| **Кворум** | `QuorumView.vue` | `proposalsService.js` | Настройки голосования |
|
|
||||||
| **Аналитика** | `AnalyticsView.vue` | `analyticsService.js` | Аналитические данные |
|
|
||||||
| **История** | `HistoryView.vue` | `dleV2Service.js` | История операций |
|
|
||||||
| **Настройки** | `SettingsView.vue` | `dleV2Service.js` | Настройки DLE |
|
|
||||||
| **Управление DLE** | `DleManagementView.vue` | - | Добавление DLE в список |
|
|
||||||
|
|
||||||
## 🔄 Архитектурные принципы
|
|
||||||
|
|
||||||
### 1. **Разделение ответственности**
|
|
||||||
- Каждый сервис отвечает за свою область
|
|
||||||
- Функции не дублируются между сервисами
|
|
||||||
- Четкие границы между модулями
|
|
||||||
|
|
||||||
### 2. **Единообразие API**
|
|
||||||
- Все сервисы используют одинаковый формат ответов
|
|
||||||
- Единообразная обработка ошибок
|
|
||||||
- Консистентные названия функций
|
|
||||||
|
|
||||||
### 3. **Простота использования**
|
|
||||||
- Интуитивно понятные названия функций
|
|
||||||
- Подробная документация JSDoc
|
|
||||||
- Примеры использования
|
|
||||||
|
|
||||||
### 4. **Масштабируемость**
|
|
||||||
- Легко добавлять новые функции
|
|
||||||
- Простое тестирование отдельных модулей
|
|
||||||
- Возможность переиспользования
|
|
||||||
|
|
||||||
## 🛠️ Утилиты
|
|
||||||
|
|
||||||
### `dle-contract.js`
|
|
||||||
Используется только для транзакций через MetaMask:
|
|
||||||
- Создание предложений
|
|
||||||
- Голосование
|
|
||||||
- Исполнение предложений
|
|
||||||
- Деактивация DLE
|
|
||||||
|
|
||||||
### `utils/websocket.js`
|
|
||||||
Для real-time обновлений:
|
|
||||||
- Уведомления о новых предложениях
|
|
||||||
- Обновления статуса голосования
|
|
||||||
- Синхронизация данных
|
|
||||||
|
|
||||||
## 📊 Статистика кода
|
|
||||||
|
|
||||||
| Сервис | Строк | Функций | Описание |
|
|
||||||
|--------|-------|---------|----------|
|
|
||||||
| `dleV2Service.js` | 220 | 8 | Основные функции DLE |
|
|
||||||
| `modulesService.js` | 298 | 5 | Управление модулями |
|
|
||||||
| `proposalsService.js` | 264 | 12 | Управление предложениями |
|
|
||||||
| `tokensService.js` | 72 | 3 | Работа с токенами |
|
|
||||||
| `analyticsService.js` | 320 | 16 | Аналитические данные |
|
|
||||||
| `multichainService.js` | 353 | 18 | Мультичейн функциональность |
|
|
||||||
|
|
||||||
## 🚀 Преимущества новой архитектуры
|
|
||||||
|
|
||||||
1. **✅ Читаемость** - код легко понять и поддерживать
|
|
||||||
2. **✅ Тестируемость** - каждый сервис можно тестировать отдельно
|
|
||||||
3. **✅ Переиспользование** - функции можно использовать в разных компонентах
|
|
||||||
4. **✅ Масштабируемость** - легко добавлять новые функции
|
|
||||||
5. **✅ Производительность** - загрузка только нужных модулей
|
|
||||||
6. **✅ Поддержка** - простое исправление ошибок и добавление функций
|
|
||||||
@@ -1,135 +0,0 @@
|
|||||||
<!--
|
|
||||||
Copyright (c) 2024-2025 Тарабанов Александр Викторович
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
This software is proprietary and confidential.
|
|
||||||
Unauthorized copying, modification, or distribution is prohibited.
|
|
||||||
|
|
||||||
For licensing inquiries: info@hb3-accelerator.com
|
|
||||||
Website: https://hb3-accelerator.com
|
|
||||||
GitHub: https://github.com/HB3-ACCELERATOR
|
|
||||||
-->
|
|
||||||
|
|
||||||
# Архитектура модулей DLE
|
|
||||||
|
|
||||||
## Обзор
|
|
||||||
|
|
||||||
DLE использует модульную архитектуру, где каждый модуль может иметь свои правила доступа и функциональность.
|
|
||||||
|
|
||||||
## Типы модулей
|
|
||||||
|
|
||||||
### 1. Простые модули (Вариант 1)
|
|
||||||
Модули сами проверяют права доступа токен-холдеров.
|
|
||||||
|
|
||||||
```solidity
|
|
||||||
contract SimpleModule {
|
|
||||||
address public dleContract;
|
|
||||||
|
|
||||||
modifier onlyDLEHolders() {
|
|
||||||
require(IERC20(dleContract).balanceOf(msg.sender) > 0, "Must hold DLE tokens");
|
|
||||||
_;
|
|
||||||
}
|
|
||||||
|
|
||||||
function someFunction() external onlyDLEHolders {
|
|
||||||
// Логика функции
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. Сложные модули (Вариант 3)
|
|
||||||
Модули работают через основной контракт DLE.
|
|
||||||
|
|
||||||
```solidity
|
|
||||||
contract ComplexModule {
|
|
||||||
address public dleContract;
|
|
||||||
|
|
||||||
function executeOperation(address caller, bytes calldata operation) external {
|
|
||||||
require(msg.sender == dleContract, "Only DLE can call");
|
|
||||||
require(IERC20(dleContract).balanceOf(caller) > 0, "Must hold tokens");
|
|
||||||
|
|
||||||
// Выполняем операцию
|
|
||||||
_executeOperation(caller, operation);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Рекомендации по выбору
|
|
||||||
|
|
||||||
### Используйте Вариант 1 для:
|
|
||||||
- ✅ Простых операций (чтение данных)
|
|
||||||
- ✅ Модулей с минимальной логикой
|
|
||||||
- ✅ Быстрых операций
|
|
||||||
|
|
||||||
### Используйте Вариант 3 для:
|
|
||||||
- ✅ Сложных финансовых операций
|
|
||||||
- ✅ Модулей с критической логикой
|
|
||||||
- ✅ Операций, требующих аудита
|
|
||||||
|
|
||||||
## Примеры модулей
|
|
||||||
|
|
||||||
### TreasuryModule (Казна)
|
|
||||||
```solidity
|
|
||||||
contract TreasuryModule {
|
|
||||||
address public dleContract;
|
|
||||||
mapping(address => bool) public supportedTokens;
|
|
||||||
|
|
||||||
modifier onlyDLEHolders() {
|
|
||||||
require(IERC20(dleContract).balanceOf(msg.sender) > 0, "Must hold DLE tokens");
|
|
||||||
_;
|
|
||||||
}
|
|
||||||
|
|
||||||
function depositToken(address token, uint256 amount) external onlyDLEHolders {
|
|
||||||
require(supportedTokens[token], "Token not supported");
|
|
||||||
IERC20(token).transferFrom(msg.sender, address(this), amount);
|
|
||||||
}
|
|
||||||
|
|
||||||
function withdrawToken(address token, uint256 amount) external onlyDLEHolders {
|
|
||||||
require(supportedTokens[token], "Token not supported");
|
|
||||||
IERC20(token).transfer(msg.sender, amount);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### GovernanceModule (Управление)
|
|
||||||
```solidity
|
|
||||||
contract GovernanceModule {
|
|
||||||
address public dleContract;
|
|
||||||
|
|
||||||
function executeOperation(address caller, bytes calldata operation) external {
|
|
||||||
require(msg.sender == dleContract, "Only DLE can call");
|
|
||||||
require(IERC20(dleContract).balanceOf(caller) > 0, "Must hold tokens");
|
|
||||||
|
|
||||||
// Выполняем операцию управления
|
|
||||||
_executeGovernanceOperation(caller, operation);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Безопасность
|
|
||||||
|
|
||||||
### Общие принципы:
|
|
||||||
1. **Всегда проверяйте** баланс токенов DLE
|
|
||||||
2. **Валидируйте входные данные** в модулях
|
|
||||||
3. **Используйте ReentrancyGuard** для финансовых операций
|
|
||||||
4. **Логируйте важные операции** через события
|
|
||||||
|
|
||||||
### Аудит модулей:
|
|
||||||
- Проверяйте права доступа
|
|
||||||
- Тестируйте граничные случаи
|
|
||||||
- Валидируйте входные параметры
|
|
||||||
- Проверяйте обработку ошибок
|
|
||||||
|
|
||||||
# Модульная архитектура (обновление для DLE v2)
|
|
||||||
|
|
||||||
- Модули выносятся в отдельные контракты: `TreasuryModule`, `TimelockModule`, `DeactivationModule`, `CommunicationModule`.
|
|
||||||
- Подключение/отключение модулей — строго через предложения DLE (`ModuleAdded`/`ModuleRemoved`).
|
|
||||||
- Исполнение модульных операций инициируется основным DLE через `_executeOperation` по безопасному `operationCalldata`.
|
|
||||||
- Денежные переводы из ядра исключены: все токено‑операции внутри `TreasuryModule`.
|
|
||||||
- Таймлок применяется на уровне предложения: `timelockHours` хранится в `Proposal` и проверяется при исполнении.
|
|
||||||
- Для оффчейн действий ядро эмитит событие `OffchainAction`, которое подписывает и обрабатывает бекенд/клиент.
|
|
||||||
|
|
||||||
Последовательность для казначейской операции:
|
|
||||||
1) Создание предложения с типом операции и параметрами, указание `governanceChainId`, `targetChains`, `timelockHours`.
|
|
||||||
2) Сбор голосов в выбранной сети (снапшоты ERC20Votes).
|
|
||||||
3) По наступлению timelock — `executeProposalBySignatures` в целевых сетях с проверкой EIP‑712 подписей и «100% или ничего».
|
|
||||||
4) Ядро вызывает `TreasuryModule` по `abi.encodeWithSelector(...)`.
|
|
||||||
@@ -1,630 +0,0 @@
|
|||||||
<!--
|
|
||||||
Copyright (c) 2024-2025 Тарабанов Александр Викторович
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
This software is proprietary and confidential.
|
|
||||||
Unauthorized copying, modification, or distribution is prohibited.
|
|
||||||
|
|
||||||
For licensing inquiries: info@hb3-accelerator.com
|
|
||||||
Website: https://hb3-accelerator.com
|
|
||||||
GitHub: https://github.com/HB3-ACCELERATOR
|
|
||||||
-->
|
|
||||||
|
|
||||||
# Улучшения системы деплоя и управления модулями DLE
|
|
||||||
|
|
||||||
## Описание задачи
|
|
||||||
|
|
||||||
Пользователь хочет улучшить процесс деплоя и управления модулями DLE, чтобы обеспечить автоматическую инициализацию и верификацию модулей во всех выбранных пользователем блокчейн-сетях.
|
|
||||||
|
|
||||||
## Текущая ситуация
|
|
||||||
|
|
||||||
### Что уже работает:
|
|
||||||
- ✅ Деплой основного DLE контракта в 4 сетях с одинаковым адресом (через CREATE2)
|
|
||||||
- ✅ Деплой модулей (Treasury, Timelock, Reader) в каждой сети
|
|
||||||
- ✅ Модули инициализируются только через governance предложения
|
|
||||||
- ✅ Верификация контрактов в каждой сети
|
|
||||||
- ✅ Отображение модулей в виде карточек с адресами во всех сетях
|
|
||||||
|
|
||||||
### Проблемы:
|
|
||||||
- ❌ Если деплой модулей в одной сети падает, инициализация не происходит
|
|
||||||
- ❌ Нет механизма повторной инициализации модулей
|
|
||||||
- ❌ Нет проверки статуса инициализации перед деплоем
|
|
||||||
- ❌ Верификация может падать из-за таймаутов блокчейн-эксплореров
|
|
||||||
- ❌ Нет удобного интерфейса для управления модулями
|
|
||||||
|
|
||||||
## Требования пользователя
|
|
||||||
|
|
||||||
### 1. Workflow деплоя
|
|
||||||
**Цель:** При заполнении формы и нажатии на кнопку "Деплой" пользователь должен получить:
|
|
||||||
- Основной смарт-контракт DLE
|
|
||||||
- 3 модуля (Treasury, Timelock, Reader)
|
|
||||||
- Модули должны быть **сразу инициализированы** во всех выбранных сетях
|
|
||||||
- Модули должны быть **сразу верифицированы** во всех выбранных сетях
|
|
||||||
|
|
||||||
### 2. Отображение модулей
|
|
||||||
**Текущее состояние:** ✅ Уже реализовано
|
|
||||||
- Одна карточка для каждого модуля
|
|
||||||
- В карточке показаны адреса модуля во всех сетях
|
|
||||||
- Статус верификации для каждой сети
|
|
||||||
- Кнопка "Настроить" для перехода к настройкам модуля
|
|
||||||
|
|
||||||
### 3. Управление модулями
|
|
||||||
**Требования:**
|
|
||||||
- Кнопка "Настроить" должна открывать страницу с блоками для настройки модулей
|
|
||||||
- Возможность управления модулями через веб-интерфейс
|
|
||||||
- Отображение статуса инициализации и верификации
|
|
||||||
|
|
||||||
## Реализованные улучшения
|
|
||||||
|
|
||||||
### 1. Backend API Endpoints
|
|
||||||
|
|
||||||
#### `/api/dle-modules/initialize-modules-all-networks`
|
|
||||||
**Назначение:** Автоматическая инициализация всех модулей во всех поддерживаемых сетях
|
|
||||||
|
|
||||||
**Параметры:**
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"dleAddress": "0x...",
|
|
||||||
"privateKey": "0x..."
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**Функциональность:**
|
|
||||||
- Получает список поддерживаемых сетей из DLE контракта
|
|
||||||
- Проверяет статус инициализации в каждой сети
|
|
||||||
- Если модули не инициализированы, создает governance предложения для их добавления
|
|
||||||
- Возвращает детальный отчет по каждой сети
|
|
||||||
|
|
||||||
**Возвращаемые статусы:**
|
|
||||||
- `success` - модули успешно инициализированы
|
|
||||||
- `already_initialized` - модули уже инициализированы
|
|
||||||
- `modules_not_deployed` - не все модули задеплоены
|
|
||||||
- `error` - ошибка инициализации
|
|
||||||
|
|
||||||
#### `/api/dle-modules/verify-modules-all-networks`
|
|
||||||
**Назначение:** Автоматическая верификация всех модулей во всех поддерживаемых сетях
|
|
||||||
|
|
||||||
**Параметры:**
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"dleAddress": "0x...",
|
|
||||||
"privateKey": "0x..."
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**Функциональность:**
|
|
||||||
- Получает адреса всех модулей в каждой сети
|
|
||||||
- Отправляет запросы на верификацию в Etherscan/блокчейн-эксплореры
|
|
||||||
- Использует стандартный JSON input для верификации
|
|
||||||
- Возвращает детальный отчет по каждому модулю в каждой сети
|
|
||||||
|
|
||||||
**Возвращаемые статусы:**
|
|
||||||
- `success` - модуль успешно верифицирован
|
|
||||||
- `failed` - ошибка верификации
|
|
||||||
- `not_deployed` - модуль не задеплоен
|
|
||||||
- `error` - ошибка процесса верификации
|
|
||||||
|
|
||||||
### 2. Frontend Service Functions
|
|
||||||
|
|
||||||
#### `initializeModulesAllNetworks(dleAddress, privateKey)`
|
|
||||||
**Назначение:** Вызов API для инициализации модулей
|
|
||||||
|
|
||||||
#### `verifyModulesAllNetworks(dleAddress, privateKey)`
|
|
||||||
**Назначение:** Вызов API для верификации модулей
|
|
||||||
|
|
||||||
### 3. Улучшенный интерфейс модулей
|
|
||||||
|
|
||||||
#### Обновленная карточка модуля:
|
|
||||||
- **Основные действия:** Кнопка "Настроить" (приоритетная)
|
|
||||||
- **Дополнительные действия:** Удалить/Активировать модуль
|
|
||||||
- **Верификация:** Отдельные кнопки для каждой сети
|
|
||||||
|
|
||||||
#### Новые стили:
|
|
||||||
- Группировка кнопок по функциональности
|
|
||||||
- Улучшенная компоновка элементов
|
|
||||||
- Адаптивный дизайн для разных размеров экрана
|
|
||||||
|
|
||||||
## Предлагаемый Workflow (Поэтапный подход с повторами)
|
|
||||||
|
|
||||||
### Этап 1: Деплой основного DLE контракта
|
|
||||||
```bash
|
|
||||||
# Деплой только DLE контракта во всех выбранных сетях
|
|
||||||
npx hardhat run scripts/deploy/deploy-dle-only.js
|
|
||||||
```
|
|
||||||
|
|
||||||
### Этап 2: Проверка успеха деплоя DLE (с повторами)
|
|
||||||
```javascript
|
|
||||||
POST /api/dle-modules/check-dle-deployment-status
|
|
||||||
{
|
|
||||||
"dleAddress": "0x...",
|
|
||||||
"chainIds": [11155111, 17000, 421614, 84532],
|
|
||||||
"maxRetries": 5,
|
|
||||||
"retryDelay": 30000
|
|
||||||
}
|
|
||||||
```
|
|
||||||
**Логика повторов:**
|
|
||||||
- Если не все сети успешны → ждем 30 сек → повторяем проверку
|
|
||||||
- Максимум 5 попыток
|
|
||||||
- Если после 5 попыток не все сети готовы → ошибка
|
|
||||||
|
|
||||||
### Этап 3: Верификация DLE контракта (с повторами)
|
|
||||||
```javascript
|
|
||||||
POST /api/dle-modules/verify-dle-all-networks
|
|
||||||
{
|
|
||||||
"dleAddress": "0x...",
|
|
||||||
"privateKey": "0x...",
|
|
||||||
"maxRetries": 3,
|
|
||||||
"retryDelay": 60000
|
|
||||||
}
|
|
||||||
```
|
|
||||||
**Логика повторов:**
|
|
||||||
- Если верификация не удалась → ждем 60 сек → повторяем
|
|
||||||
- Максимум 3 попытки
|
|
||||||
- Etherscan может быть перегружен, поэтому больше времени между попытками
|
|
||||||
|
|
||||||
### Этап 4: Деплой модуля 1 (TreasuryModule) (с повторами)
|
|
||||||
```javascript
|
|
||||||
POST /api/dle-modules/deploy-module-all-networks
|
|
||||||
{
|
|
||||||
"dleAddress": "0x...",
|
|
||||||
"moduleType": "treasury",
|
|
||||||
"privateKey": "0x...",
|
|
||||||
"maxRetries": 3,
|
|
||||||
"retryDelay": 45000
|
|
||||||
}
|
|
||||||
```
|
|
||||||
**Логика повторов:**
|
|
||||||
- Если деплой в какой-то сети упал → ждем 45 сек → повторяем только для неудачных сетей
|
|
||||||
- Максимум 3 попытки
|
|
||||||
- Gas price может быть высоким, поэтому больше времени между попытками
|
|
||||||
|
|
||||||
### Этап 5: Проверка успеха деплоя TreasuryModule (с повторами)
|
|
||||||
```javascript
|
|
||||||
POST /api/dle-modules/check-module-deployment-status
|
|
||||||
{
|
|
||||||
"dleAddress": "0x...",
|
|
||||||
"moduleType": "treasury",
|
|
||||||
"chainIds": [11155111, 17000, 421614, 84532],
|
|
||||||
"maxRetries": 5,
|
|
||||||
"retryDelay": 30000
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Этап 6: Верификация TreasuryModule (с повторами)
|
|
||||||
```javascript
|
|
||||||
POST /api/dle-modules/verify-module-all-networks
|
|
||||||
{
|
|
||||||
"dleAddress": "0x...",
|
|
||||||
"moduleType": "treasury",
|
|
||||||
"privateKey": "0x...",
|
|
||||||
"maxRetries": 3,
|
|
||||||
"retryDelay": 60000
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Этап 7: Инициализация TreasuryModule (с повторами)
|
|
||||||
```javascript
|
|
||||||
POST /api/dle-modules/initialize-module-all-networks
|
|
||||||
{
|
|
||||||
"dleAddress": "0x...",
|
|
||||||
"moduleType": "treasury",
|
|
||||||
"privateKey": "0x...",
|
|
||||||
"maxRetries": 3,
|
|
||||||
"retryDelay": 30000
|
|
||||||
}
|
|
||||||
```
|
|
||||||
**Логика повторов:**
|
|
||||||
- Если инициализация упала → ждем 30 сек → повторяем
|
|
||||||
- Максимум 3 попытки
|
|
||||||
- Network congestion может влиять на транзакции
|
|
||||||
|
|
||||||
### Этап 8: Деплой модуля 2 (TimelockModule)
|
|
||||||
```javascript
|
|
||||||
POST /api/dle-modules/deploy-module-all-networks
|
|
||||||
{
|
|
||||||
"dleAddress": "0x...",
|
|
||||||
"moduleType": "timelock",
|
|
||||||
"privateKey": "0x..."
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Этап 9: Проверка успеха деплоя TimelockModule
|
|
||||||
```javascript
|
|
||||||
POST /api/dle-modules/check-module-deployment-status
|
|
||||||
{
|
|
||||||
"dleAddress": "0x...",
|
|
||||||
"moduleType": "timelock",
|
|
||||||
"chainIds": [11155111, 17000, 421614, 84532]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Этап 10: Верификация TimelockModule
|
|
||||||
```javascript
|
|
||||||
POST /api/dle-modules/verify-module-all-networks
|
|
||||||
{
|
|
||||||
"dleAddress": "0x...",
|
|
||||||
"moduleType": "timelock",
|
|
||||||
"privateKey": "0x..."
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Этап 11: Инициализация TimelockModule
|
|
||||||
```javascript
|
|
||||||
POST /api/dle-modules/initialize-module-all-networks
|
|
||||||
{
|
|
||||||
"dleAddress": "0x...",
|
|
||||||
"moduleType": "timelock",
|
|
||||||
"privateKey": "0x..."
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Этап 12: Деплой модуля 3 (DLEReader)
|
|
||||||
```javascript
|
|
||||||
POST /api/dle-modules/deploy-module-all-networks
|
|
||||||
{
|
|
||||||
"dleAddress": "0x...",
|
|
||||||
"moduleType": "reader",
|
|
||||||
"privateKey": "0x..."
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Этап 13: Проверка успеха деплоя DLEReader
|
|
||||||
```javascript
|
|
||||||
POST /api/dle-modules/check-module-deployment-status
|
|
||||||
{
|
|
||||||
"dleAddress": "0x...",
|
|
||||||
"moduleType": "reader",
|
|
||||||
"chainIds": [11155111, 17000, 421614, 84532]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Этап 14: Верификация DLEReader
|
|
||||||
```javascript
|
|
||||||
POST /api/dle-modules/verify-module-all-networks
|
|
||||||
{
|
|
||||||
"dleAddress": "0x...",
|
|
||||||
"moduleType": "reader",
|
|
||||||
"privateKey": "0x..."
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Этап 15: Инициализация DLEReader
|
|
||||||
```javascript
|
|
||||||
POST /api/dle-modules/initialize-module-all-networks
|
|
||||||
{
|
|
||||||
"dleAddress": "0x...",
|
|
||||||
"moduleType": "reader",
|
|
||||||
"privateKey": "0x..."
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Этап 16: Финальная инициализация всех модулей
|
|
||||||
```javascript
|
|
||||||
POST /api/dle-modules/initialize-base-modules-all-networks
|
|
||||||
{
|
|
||||||
"dleAddress": "0x...",
|
|
||||||
"privateKey": "0x..."
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Этап 17: Финальная проверка и отображение
|
|
||||||
```javascript
|
|
||||||
POST /api/dle-modules/final-deployment-check
|
|
||||||
{
|
|
||||||
"dleAddress": "0x...",
|
|
||||||
"chainIds": [11155111, 17000, 421614, 84532]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
**Логика финальной проверки:**
|
|
||||||
- Проверяем, что DLE задеплоен во всех сетях
|
|
||||||
- Проверяем, что все модули задеплоены во всех сетях
|
|
||||||
- Проверяем, что все модули верифицированы во всех сетях
|
|
||||||
- Проверяем, что все модули инициализированы во всех сетях
|
|
||||||
|
|
||||||
**Только если ВСЕ проверки пройдены:**
|
|
||||||
- ✅ Карточки DLE и модулей появляются в интерфейсе
|
|
||||||
- ✅ Пользователь может управлять модулями
|
|
||||||
- ✅ Все функции доступны
|
|
||||||
|
|
||||||
**Если хотя бы одна проверка не пройдена:**
|
|
||||||
- ❌ Карточки НЕ отображаются
|
|
||||||
- ❌ Показывается статус "Деплой в процессе" или "Деплой не завершен"
|
|
||||||
- ❌ Предлагается продолжить деплой или исправить ошибки
|
|
||||||
|
|
||||||
## Логика отображения интерфейса
|
|
||||||
|
|
||||||
### Состояния деплоя:
|
|
||||||
|
|
||||||
#### 1. **Деплой не начат**
|
|
||||||
```javascript
|
|
||||||
// Интерфейс показывает:
|
|
||||||
- Форму деплоя DLE
|
|
||||||
- Кнопку "Начать деплой"
|
|
||||||
- Нет карточек модулей
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 2. **Деплой в процессе**
|
|
||||||
```javascript
|
|
||||||
// Интерфейс показывает:
|
|
||||||
- Прогресс-бар с текущим этапом
|
|
||||||
- Логи выполнения в реальном времени
|
|
||||||
- Кнопку "Остановить деплой" (опционально)
|
|
||||||
- Нет карточек модулей
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 3. **Деплой частично завершен (ошибка)**
|
|
||||||
```javascript
|
|
||||||
// Интерфейс показывает:
|
|
||||||
- Статус "Деплой не завершен"
|
|
||||||
- Список успешных этапов
|
|
||||||
- Список неудачных этапов с ошибками
|
|
||||||
- Кнопки "Продолжить деплой" или "Начать заново"
|
|
||||||
- Нет карточек модулей
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 4. **Деплой полностью завершен**
|
|
||||||
```javascript
|
|
||||||
// Интерфейс показывает:
|
|
||||||
- ✅ Карточки DLE и всех модулей
|
|
||||||
- ✅ Все функции управления доступны
|
|
||||||
- ✅ Кнопки "Настроить" для каждого модуля
|
|
||||||
- ✅ Статус "Деплой успешно завершен"
|
|
||||||
```
|
|
||||||
|
|
||||||
### API для проверки статуса деплоя:
|
|
||||||
```javascript
|
|
||||||
POST /api/dle-modules/get-deployment-status
|
|
||||||
{
|
|
||||||
"dleAddress": "0x..."
|
|
||||||
}
|
|
||||||
|
|
||||||
// Возвращает:
|
|
||||||
{
|
|
||||||
"status": "completed|in_progress|failed|not_started",
|
|
||||||
"currentStage": "deploy_dle|verify_dle|deploy_treasury|...",
|
|
||||||
"completedStages": ["deploy_dle", "verify_dle"],
|
|
||||||
"failedStages": [],
|
|
||||||
"progress": 85, // процент завершения
|
|
||||||
"canShowCards": false, // только true если status === "completed"
|
|
||||||
"errors": [],
|
|
||||||
"nextAction": "continue_deployment|restart_deployment|none"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Логика повторов
|
|
||||||
|
|
||||||
### Общие принципы:
|
|
||||||
1. **Каждый этап повторяется до успеха** или до исчерпания попыток
|
|
||||||
2. **Разные задержки** для разных типов операций:
|
|
||||||
- Проверки: 30 сек (быстрые операции)
|
|
||||||
- Деплой: 45 сек (gas price может измениться)
|
|
||||||
- Верификация: 60 сек (Etherscan может быть перегружен)
|
|
||||||
- Инициализация: 30 сек (network congestion)
|
|
||||||
|
|
||||||
3. **Умные повторы:**
|
|
||||||
- Если операция частично успешна → повторяем только для неудачных сетей
|
|
||||||
- Если операция полностью провалилась → повторяем для всех сетей
|
|
||||||
- Логируем каждую попытку для диагностики
|
|
||||||
|
|
||||||
4. **Критические ошибки:**
|
|
||||||
- Если после всех попыток операция не удалась → останавливаем весь процесс
|
|
||||||
- Показываем детальный отчет о том, что не удалось
|
|
||||||
- Предлагаем варианты решения (повторить, пропустить, откатиться)
|
|
||||||
|
|
||||||
### Пример логики повторов:
|
|
||||||
```javascript
|
|
||||||
async function executeWithRetries(operation, maxRetries, retryDelay) {
|
|
||||||
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
|
||||||
try {
|
|
||||||
const result = await operation();
|
|
||||||
|
|
||||||
// Проверяем, все ли сети успешны
|
|
||||||
const failedNetworks = result.filter(r => r.status !== 'success');
|
|
||||||
|
|
||||||
if (failedNetworks.length === 0) {
|
|
||||||
console.log(`✅ Операция успешна с попытки ${attempt}`);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (attempt < maxRetries) {
|
|
||||||
console.log(`⚠️ Попытка ${attempt} частично успешна. Повторяем через ${retryDelay}мс...`);
|
|
||||||
console.log(`Неудачные сети: ${failedNetworks.map(n => n.networkName).join(', ')}`);
|
|
||||||
await sleep(retryDelay);
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (error) {
|
|
||||||
if (attempt < maxRetries) {
|
|
||||||
console.log(`❌ Попытка ${attempt} провалилась: ${error.message}`);
|
|
||||||
console.log(`Повторяем через ${retryDelay}мс...`);
|
|
||||||
await sleep(retryDelay);
|
|
||||||
} else {
|
|
||||||
throw new Error(`Операция провалилась после ${maxRetries} попыток: ${error.message}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Преимущества поэтапного подхода
|
|
||||||
|
|
||||||
### 1. Максимальная надежность
|
|
||||||
- ✅ **Проверка на каждом этапе** - если что-то пошло не так, процесс останавливается
|
|
||||||
- ✅ **Изоляция ошибок** - проблема с одним модулем не влияет на другие
|
|
||||||
- ✅ **Возможность восстановления** - можно продолжить с места остановки
|
|
||||||
- ✅ **Детальная диагностика** - точно знаем, на каком этапе произошла ошибка
|
|
||||||
- ✅ **Автоматические повторы** - временные проблемы решаются автоматически
|
|
||||||
- ✅ **Устойчивость к сбоям** - network congestion, gas spikes, Etherscan overload
|
|
||||||
|
|
||||||
### 2. Гибкость управления
|
|
||||||
- ✅ **Выборочный деплой** - можно деплоить только нужные модули
|
|
||||||
- ✅ **Повторные попытки** - можно повторить только неудачный этап
|
|
||||||
- ✅ **Параллельная работа** - разные модули можно деплоить независимо
|
|
||||||
- ✅ **Контроль качества** - верификация после каждого деплоя
|
|
||||||
|
|
||||||
### 3. Улучшенная диагностика
|
|
||||||
- ✅ **Пошаговые логи** - детальная информация о каждом этапе
|
|
||||||
- ✅ **Статусы в реальном времени** - видно прогресс выполнения
|
|
||||||
- ✅ **Обработка ошибок** - понятные сообщения об ошибках
|
|
||||||
- ✅ **История операций** - можно отследить все выполненные действия
|
|
||||||
|
|
||||||
### 4. Масштабируемость
|
|
||||||
- ✅ **Легко добавить новые модули** - просто добавить новые этапы
|
|
||||||
- ✅ **Поддержка новых сетей** - автоматически работает для всех сетей
|
|
||||||
- ✅ **Модульная архитектура** - каждый endpoint независим
|
|
||||||
- ✅ **Расширяемость** - легко добавить новые типы операций
|
|
||||||
|
|
||||||
### 5. Безопасность
|
|
||||||
- ✅ **Постепенное развертывание** - минимизация рисков
|
|
||||||
- ✅ **Проверка перед выполнением** - валидация на каждом этапе
|
|
||||||
- ✅ **Откат изменений** - можно отменить неудачные операции
|
|
||||||
- ✅ **Аудит операций** - полная история всех действий
|
|
||||||
|
|
||||||
## Пример использования поэтапного подхода
|
|
||||||
|
|
||||||
### Сценарий: Деплой DLE с модулями в 4 сетях
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
// 1. Деплой DLE контракта
|
|
||||||
const dleResult = await deployDLE({
|
|
||||||
networks: [11155111, 17000, 421614, 84532],
|
|
||||||
privateKey: "0x...",
|
|
||||||
params: { name: "My DLE", symbol: "MDLE" }
|
|
||||||
});
|
|
||||||
|
|
||||||
// 2. Проверка деплоя DLE
|
|
||||||
const dleStatus = await checkDLEStatus(dleResult.address, [11155111, 17000, 421614, 84532]);
|
|
||||||
if (!dleStatus.allDeployed) {
|
|
||||||
throw new Error("DLE не задеплоен во всех сетях");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. Верификация DLE
|
|
||||||
const dleVerification = await verifyDLE(dleResult.address, "0x...");
|
|
||||||
console.log("DLE верификация:", dleVerification);
|
|
||||||
|
|
||||||
// 4. Деплой TreasuryModule
|
|
||||||
const treasuryResult = await deployModule("treasury", dleResult.address, "0x...");
|
|
||||||
|
|
||||||
// 5. Проверка деплоя TreasuryModule
|
|
||||||
const treasuryStatus = await checkModuleStatus("treasury", dleResult.address, [11155111, 17000, 421614, 84532]);
|
|
||||||
if (!treasuryStatus.allDeployed) {
|
|
||||||
throw new Error("TreasuryModule не задеплоен во всех сетях");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 6. Верификация TreasuryModule
|
|
||||||
const treasuryVerification = await verifyModule("treasury", dleResult.address, "0x...");
|
|
||||||
console.log("TreasuryModule верификация:", treasuryVerification);
|
|
||||||
|
|
||||||
// 7. Инициализация TreasuryModule
|
|
||||||
const treasuryInit = await initializeModule("treasury", dleResult.address, "0x...");
|
|
||||||
console.log("TreasuryModule инициализация:", treasuryInit);
|
|
||||||
|
|
||||||
// 8-15. Повторяем для TimelockModule и DLEReader...
|
|
||||||
|
|
||||||
// 16. Создание governance предложений для добавления модулей
|
|
||||||
const addTreasuryProposal = await createAddModuleProposal(dleResult.address, treasuryAddress, "Treasury Module");
|
|
||||||
const addTimelockProposal = await createAddModuleProposal(dleResult.address, timelockAddress, "Timelock Module");
|
|
||||||
const addReaderProposal = await createAddModuleProposal(dleResult.address, readerAddress, "Reader Module");
|
|
||||||
console.log("Governance предложения созданы:", { addTreasuryProposal, addTimelockProposal, addReaderProposal });
|
|
||||||
```
|
|
||||||
|
|
||||||
### Обработка ошибок
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
try {
|
|
||||||
// Деплой модуля
|
|
||||||
const result = await deployModule("treasury", dleAddress, privateKey);
|
|
||||||
|
|
||||||
// Проверка успеха
|
|
||||||
const status = await checkModuleStatus("treasury", dleAddress, chainIds);
|
|
||||||
|
|
||||||
if (status.errors.length > 0) {
|
|
||||||
console.log("Ошибки деплоя:", status.errors);
|
|
||||||
// Можно повторить только для сетей с ошибками
|
|
||||||
const retryResult = await deployModule("treasury", dleAddress, privateKey, status.errorChains);
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (error) {
|
|
||||||
console.error("Критическая ошибка:", error);
|
|
||||||
// Логирование и уведомление пользователя
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Следующие шаги
|
|
||||||
|
|
||||||
### 1. Реализация новых API endpoints
|
|
||||||
- `check-dle-deployment-status` - проверка деплоя DLE
|
|
||||||
- `check-module-deployment-status` - проверка деплоя модуля
|
|
||||||
- `deploy-module-all-networks` - деплой одного модуля
|
|
||||||
- `verify-dle-all-networks` - верификация DLE
|
|
||||||
- `verify-module-all-networks` - верификация модуля
|
|
||||||
- `initialize-module-all-networks` - инициализация модуля
|
|
||||||
- `initialize-base-modules-all-networks` - финальная инициализация
|
|
||||||
|
|
||||||
### 2. Веб-интерфейс для поэтапного деплоя
|
|
||||||
- Мастер деплоя с пошаговым интерфейсом
|
|
||||||
- Прогресс-бар для каждого этапа
|
|
||||||
- Обработка ошибок и повторные попытки
|
|
||||||
- Логи операций в реальном времени
|
|
||||||
|
|
||||||
### 3. Интеграция с существующей формой деплоя
|
|
||||||
- Добавить опцию "Поэтапный деплой"
|
|
||||||
- Автоматическое выполнение всех этапов
|
|
||||||
- Уведомления о статусе каждого этапа
|
|
||||||
|
|
||||||
### 4. Мониторинг и логирование
|
|
||||||
- Детальные логи всех операций
|
|
||||||
- История деплоев и их статусов
|
|
||||||
- Алерты при ошибках
|
|
||||||
- Метрики производительности
|
|
||||||
|
|
||||||
## Технические детали
|
|
||||||
|
|
||||||
### Поддерживаемые сети:
|
|
||||||
- Sepolia (Chain ID: 11155111)
|
|
||||||
- Holesky (Chain ID: 17000)
|
|
||||||
- Arbitrum Sepolia (Chain ID: 421614)
|
|
||||||
- Base Sepolia (Chain ID: 84532)
|
|
||||||
|
|
||||||
### Модули:
|
|
||||||
- **TreasuryModule** - управление финансами
|
|
||||||
- **TimelockModule** - задержки исполнения
|
|
||||||
- **DLEReader** - чтение данных DLE
|
|
||||||
|
|
||||||
### API Endpoints:
|
|
||||||
|
|
||||||
#### Основные endpoints (уже реализованы):
|
|
||||||
- `POST /api/dle-modules/initialize-modules-all-networks` - инициализация всех модулей
|
|
||||||
- `POST /api/dle-modules/verify-modules-all-networks` - верификация всех модулей
|
|
||||||
- `POST /api/dle-modules/get-all-modules` - получение списка модулей
|
|
||||||
- `POST /api/dle-modules/get-networks-info` - информация о сетях
|
|
||||||
|
|
||||||
#### Новые endpoints (требуют реализации):
|
|
||||||
|
|
||||||
**Проверка статуса деплоя:**
|
|
||||||
- `POST /api/dle-modules/check-dle-deployment-status` - проверка деплоя DLE контракта
|
|
||||||
- `POST /api/dle-modules/check-module-deployment-status` - проверка деплоя конкретного модуля
|
|
||||||
|
|
||||||
**Деплой модулей:**
|
|
||||||
- `POST /api/dle-modules/deploy-module-all-networks` - деплой одного модуля во всех сетях
|
|
||||||
|
|
||||||
**Верификация:**
|
|
||||||
- `POST /api/dle-modules/verify-dle-all-networks` - верификация DLE контракта
|
|
||||||
- `POST /api/dle-modules/verify-module-all-networks` - верификация одного модуля
|
|
||||||
|
|
||||||
**Инициализация:**
|
|
||||||
- `POST /api/dle-modules/initialize-module-all-networks` - инициализация одного модуля
|
|
||||||
- `POST /api/dle-modules/initialize-base-modules-all-networks` - финальная инициализация всех модулей
|
|
||||||
|
|
||||||
**Управление отображением:**
|
|
||||||
- `POST /api/dle-modules/final-deployment-check` - финальная проверка готовности
|
|
||||||
- `POST /api/dle-modules/get-deployment-status` - получение статуса деплоя
|
|
||||||
|
|
||||||
## Заключение
|
|
||||||
|
|
||||||
Реализованные улучшения обеспечивают:
|
|
||||||
1. **Полную автоматизацию** процесса деплоя модулей
|
|
||||||
2. **Надежность** через проверки статуса и обработку ошибок
|
|
||||||
3. **Удобство использования** через улучшенный интерфейс
|
|
||||||
4. **Масштабируемость** для добавления новых сетей и модулей
|
|
||||||
|
|
||||||
Пользователь теперь может одним кликом развернуть полностью функциональный DLE с инициализированными и верифицированными модулями во всех выбранных сетях.
|
|
||||||
@@ -1,151 +0,0 @@
|
|||||||
# Интеграция динамических операций модулей в CreateProposalView
|
|
||||||
|
|
||||||
## Обзор
|
|
||||||
|
|
||||||
Реализована система автоматического отображения блоков с предложениями операций модулей в реальном времени на странице создания предложений (`/management/create-proposal`). После деплоя модуля карточки с операциями автоматически появляются без необходимости обновления страницы.
|
|
||||||
|
|
||||||
## Архитектура решения
|
|
||||||
|
|
||||||
### 1. Backend API Endpoints
|
|
||||||
|
|
||||||
Добавлены новые API endpoints в `/backend/routes/dleModules.js`:
|
|
||||||
|
|
||||||
- `POST /dle-modules/get-module-operations` - получение всех доступных операций модулей для DLE
|
|
||||||
- `POST /dle-modules/get-module-specific-operations` - получение операций конкретного модуля
|
|
||||||
- `POST /dle-modules/get-module-interface` - получение ABI и интерфейса модуля
|
|
||||||
- `POST /dle-modules/get-module-available-functions` - получение доступных функций модуля
|
|
||||||
- `POST /dle-modules/get-module-function-parameters` - получение параметров функции модуля
|
|
||||||
- `POST /dle-modules/create-module-operation-proposal` - создание предложения для операции модуля
|
|
||||||
- `POST /dle-modules/validate-module-operation` - валидация операции модуля
|
|
||||||
|
|
||||||
### 2. Frontend Services
|
|
||||||
|
|
||||||
Создан новый сервис `/frontend/src/services/moduleOperationsService.js` с функциями:
|
|
||||||
|
|
||||||
- `getModuleOperations(dleAddress)` - получение операций модулей
|
|
||||||
- `getModuleSpecificOperations(dleAddress, moduleType, moduleAddress, chainId)` - операции конкретного модуля
|
|
||||||
- `createModuleOperationProposal(dleAddress, operationData)` - создание предложения
|
|
||||||
- `getModuleInterface(moduleType, moduleAddress, chainId)` - получение интерфейса
|
|
||||||
- `validateModuleOperation(dleAddress, operationData)` - валидация операции
|
|
||||||
|
|
||||||
### 3. WebSocket Integration
|
|
||||||
|
|
||||||
#### Backend (wsHub.js)
|
|
||||||
- Добавлена функция `broadcastModulesUpdate(dleAddress, updateType, moduleData)` для отправки уведомлений об обновлениях модулей
|
|
||||||
- Уведомления отправляются при обнаружении новых модулей в файлах деплоя
|
|
||||||
|
|
||||||
#### Frontend (CreateProposalView.vue)
|
|
||||||
- Подключение к WebSocket при монтировании компонента
|
|
||||||
- Обработка сообщений: `modules_updated`, `module_verified`, `module_status_changed`
|
|
||||||
- Автоматическое обновление списка операций при получении уведомлений
|
|
||||||
|
|
||||||
### 4. Динамическое отображение
|
|
||||||
|
|
||||||
#### Состояние компонента
|
|
||||||
```javascript
|
|
||||||
const moduleOperations = ref([]);
|
|
||||||
const isLoadingModuleOperations = ref(false);
|
|
||||||
const modulesWebSocket = ref(null);
|
|
||||||
const isModulesWSConnected = ref(false);
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Шаблон
|
|
||||||
- Условное отображение индикатора загрузки
|
|
||||||
- Динамическое создание блоков операций для каждого модуля
|
|
||||||
- Анимация появления новых блоков
|
|
||||||
|
|
||||||
## Поддерживаемые типы модулей и операции
|
|
||||||
|
|
||||||
### 1. Treasury Module (💰)
|
|
||||||
- **Депозит средств** - пополнение казначейства DLE
|
|
||||||
- **Вывод средств** - вывод средств из казначейства
|
|
||||||
- **Распределение дивидендов** - распределение дивидендов между держателями токенов
|
|
||||||
|
|
||||||
### 2. Timelock Module (⏰)
|
|
||||||
- **Установить задержку** - установить время задержки для операций
|
|
||||||
- **Поставить операцию в очередь** - добавить операцию в очередь для выполнения
|
|
||||||
|
|
||||||
### 3. Reader Module (📖)
|
|
||||||
- **Обновить данные** - обновить информацию о DLE
|
|
||||||
|
|
||||||
### 4. Hierarchical Voting Module (🗳️)
|
|
||||||
- **Голосование во внешнем DLE** - использовать токены для голосования в другом DLE
|
|
||||||
|
|
||||||
## Реальный процесс работы
|
|
||||||
|
|
||||||
1. **Деплой модуля** → Backend сохраняет информацию в файлы деплоя
|
|
||||||
2. **Обнаружение модуля** → `getDeployedModulesInfo()` читает файлы и находит новые модули
|
|
||||||
3. **WebSocket уведомление** → `broadcastModulesUpdate()` отправляет уведомление клиентам
|
|
||||||
4. **Обновление UI** → Frontend получает уведомление и автоматически загружает новые операции
|
|
||||||
5. **Отображение блоков** → Новые блоки операций появляются с анимацией
|
|
||||||
|
|
||||||
## Стили и UX
|
|
||||||
|
|
||||||
### Визуальные особенности
|
|
||||||
- Отдельные стили для блоков операций модулей (`.module-operation-block`)
|
|
||||||
- Цветовая схема с зеленым акцентом для модулей
|
|
||||||
- Теги категорий операций
|
|
||||||
- Анимация появления (`fadeInUp`)
|
|
||||||
- Индикатор загрузки с анимацией
|
|
||||||
|
|
||||||
### Адаптивность
|
|
||||||
- Responsive grid для блоков операций
|
|
||||||
- Поддержка мобильных устройств
|
|
||||||
- Адаптивные размеры и отступы
|
|
||||||
|
|
||||||
## Технические детали
|
|
||||||
|
|
||||||
### WebSocket Events
|
|
||||||
```javascript
|
|
||||||
// Подписка на обновления
|
|
||||||
{
|
|
||||||
type: 'subscribe',
|
|
||||||
dleAddress: '0x...'
|
|
||||||
}
|
|
||||||
|
|
||||||
// Уведомления
|
|
||||||
{
|
|
||||||
type: 'modules_updated',
|
|
||||||
dleAddress: '0x...',
|
|
||||||
moduleData: { modulesCount: 3, moduleTypes: ['treasury', 'timelock'] },
|
|
||||||
timestamp: 1234567890
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Структура данных операций
|
|
||||||
```javascript
|
|
||||||
{
|
|
||||||
id: 'deposit',
|
|
||||||
name: 'Депозит средств',
|
|
||||||
description: 'Пополнение казначейства DLE',
|
|
||||||
icon: '💰',
|
|
||||||
functionName: 'deposit',
|
|
||||||
parameters: [
|
|
||||||
{ name: 'amount', type: 'uint256', label: 'Сумма', required: true }
|
|
||||||
],
|
|
||||||
category: 'Финансы'
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Будущие улучшения
|
|
||||||
|
|
||||||
1. **Полные формы создания предложений** - замена alert на полноценные модальные окна
|
|
||||||
2. **Валидация параметров** - клиентская валидация перед отправкой
|
|
||||||
3. **Предпросмотр операций** - отображение calldata перед созданием предложения
|
|
||||||
4. **История операций** - показ выполненных операций модулей
|
|
||||||
5. **Расширенная фильтрация** - фильтры по типам операций и модулей
|
|
||||||
|
|
||||||
## Файлы изменений
|
|
||||||
|
|
||||||
### Новые файлы
|
|
||||||
- `frontend/src/services/moduleOperationsService.js`
|
|
||||||
- `docs/MODULE_OPERATIONS_INTEGRATION.md`
|
|
||||||
|
|
||||||
### Измененные файлы
|
|
||||||
- `frontend/src/views/smartcontracts/CreateProposalView.vue`
|
|
||||||
- `backend/routes/dleModules.js`
|
|
||||||
- `backend/wsHub.js`
|
|
||||||
|
|
||||||
## Заключение
|
|
||||||
|
|
||||||
Реализована полноценная система динамического отображения операций модулей с реальным временем обновлений через WebSocket. После деплоя модуля пользователи сразу видят доступные операции без необходимости обновления страницы, что значительно улучшает пользовательский опыт.
|
|
||||||
@@ -1,462 +0,0 @@
|
|||||||
<!--
|
|
||||||
Copyright (c) 2024-2025 Тарабанов Александр Викторович
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
This software is proprietary and confidential.
|
|
||||||
Unauthorized copying, modification, or distribution is prohibited.
|
|
||||||
|
|
||||||
For licensing inquiries: info@hb3-accelerator.com
|
|
||||||
Website: https://hb3-accelerator.com
|
|
||||||
GitHub: https://github.com/HB3-ACCELERATOR
|
|
||||||
-->
|
|
||||||
|
|
||||||
# Внедрение RAG-ассистента: поэтапный план
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Особенности проекта: разнообразие клиентов, каналов и данных
|
|
||||||
|
|
||||||
- **Клиенты:**
|
|
||||||
- Различные сегменты: B2B, B2C, VIP, оптовые и розничные покупатели, корпоративные клиенты, частные лица и др.
|
|
||||||
- Различные сценарии взаимодействия (покупка, поддержка, консультация, возврат и т.д.).
|
|
||||||
|
|
||||||
- **Каналы коммуникации:**
|
|
||||||
- Веб-чат
|
|
||||||
- Email
|
|
||||||
- Telegram/мессенджеры
|
|
||||||
- Возможна интеграция с другими каналами (WhatsApp, телефон и др.)
|
|
||||||
|
|
||||||
- **Типы данных:**
|
|
||||||
- Текстовые сообщения
|
|
||||||
- Аудио, видео, изображения (мультимодальные данные)
|
|
||||||
- Вложения (документы, сканы, фото товаров и т.д.)
|
|
||||||
|
|
||||||
- **Языки:**
|
|
||||||
- Русский
|
|
||||||
- Английский
|
|
||||||
- Испанский
|
|
||||||
- Китайский
|
|
||||||
- Возможность расширения на другие языки
|
|
||||||
|
|
||||||
- **Товары и услуги:**
|
|
||||||
- Широкий ассортимент товаров (разные категории, бренды, характеристики)
|
|
||||||
- Различные услуги (консультации, сервис, доставка, гарантия, возврат и др.)
|
|
||||||
- Возможность кросс-продаж и рекомендаций
|
|
||||||
|
|
||||||
- **Требования к RAG:**
|
|
||||||
- Гибкая фильтрация знаний по сегменту клиента, языку, категории товара/услуги, каналу обращения
|
|
||||||
- Поддержка мультиязычности и мультимодальности
|
|
||||||
- Масштабируемость для добавления новых ассистентов, сегментов, каналов и языков
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Многоагентная архитектура AI-ассистента
|
|
||||||
|
|
||||||
### 🎯 Главный AI-координатор
|
|
||||||
- **Роль:** Анализирует входящие сообщения и координирует работу специализированных агентов
|
|
||||||
- **Функции:**
|
|
||||||
- Определяет какие агенты нужны для обработки сообщения
|
|
||||||
- Собирает результаты от всех агентов
|
|
||||||
- Генерирует финальный персонализированный ответ
|
|
||||||
- Управляет контекстом беседы
|
|
||||||
|
|
||||||
### 🤖 Специализированные агенты
|
|
||||||
|
|
||||||
#### 1. Агент "Персонализация пользователя"
|
|
||||||
- **Задача:** Извлечение и управление персональными данными
|
|
||||||
- **Функции:**
|
|
||||||
- Извлекает имя из сообщений ("меня зовут Саша")
|
|
||||||
- Анализирует профиль пользователя (компания, должность, предпочтения)
|
|
||||||
- Отслеживает историю взаимодействий
|
|
||||||
- Определяет стадию в воронке продаж
|
|
||||||
- **Результат:** Персонализированный контекст для ответа
|
|
||||||
|
|
||||||
#### 2. Агент "Анализ запроса"
|
|
||||||
- **Задача:** Классификация и понимание сути обращения
|
|
||||||
- **Функции:**
|
|
||||||
- Определяет тип вопроса (техническая проблема, вопрос о цене, жалоба)
|
|
||||||
- Анализирует эмоциональное состояние клиента
|
|
||||||
- Выявляет скрытые потребности
|
|
||||||
- Определяет приоритетность запроса
|
|
||||||
- **Результат:** Структурированный анализ запроса
|
|
||||||
|
|
||||||
#### 3. Агент "RAG поиск"
|
|
||||||
- **Задача:** Поиск релевантной информации в базе знаний
|
|
||||||
- **Функции:**
|
|
||||||
- Векторный поиск по RAG базе
|
|
||||||
- Фильтрация по тегам пользователя
|
|
||||||
- Поиск похожих случаев и решений
|
|
||||||
- Извлечение контекстной информации
|
|
||||||
- **Результат:** Релевантные ответы и шаблоны
|
|
||||||
|
|
||||||
#### 4. Агент "Контекст беседы"
|
|
||||||
- **Задача:** Анализ истории взаимодействий
|
|
||||||
- **Функции:**
|
|
||||||
- Изучает предыдущие сообщения в беседе
|
|
||||||
- Анализирует все предыдущие обращения пользователя
|
|
||||||
- Определяет повторяющиеся темы и проблемы
|
|
||||||
- Отслеживает прогресс в решении задач
|
|
||||||
- **Результат:** Контекстная картина взаимодействия
|
|
||||||
|
|
||||||
#### 5. Агент "Детализация"
|
|
||||||
- **Задача:** Выяснение недостающей информации
|
|
||||||
- **Функции:**
|
|
||||||
- Формулирует уточняющие вопросы
|
|
||||||
- Определяет какие детали нужны для решения
|
|
||||||
- Адаптирует вопросы под контекст беседы
|
|
||||||
- Отслеживает ответы на уточняющие вопросы
|
|
||||||
- **Результат:** Структурированные уточняющие вопросы
|
|
||||||
|
|
||||||
#### 6. Агент "Персонализация ответа"
|
|
||||||
- **Задача:** Адаптация ответа под конкретного пользователя
|
|
||||||
- **Функции:**
|
|
||||||
- Учитывает стиль общения пользователя
|
|
||||||
- Адаптирует тон (формальный/неформальный)
|
|
||||||
- Использует имя и персональные данные
|
|
||||||
- Ссылается на предыдущие взаимодействия
|
|
||||||
- **Результат:** Персонализированный ответ
|
|
||||||
|
|
||||||
#### 7. Агент "Мультиязычность"
|
|
||||||
- **Задача:** Обработка многоязычных запросов
|
|
||||||
- **Функции:**
|
|
||||||
- Определяет язык входящего сообщения
|
|
||||||
- Ищет ответы на соответствующем языке
|
|
||||||
- Генерирует ответы на языке пользователя
|
|
||||||
- Адаптирует культурные особенности
|
|
||||||
- **Результат:** Локализованный ответ
|
|
||||||
|
|
||||||
#### 8. Агент "Мультимодальность"
|
|
||||||
- **Задача:** Обработка различных типов контента
|
|
||||||
- **Функции:**
|
|
||||||
- Анализ изображений, аудио, видео
|
|
||||||
- Извлечение текста из медиафайлов
|
|
||||||
- Поиск похожих медиа в базе знаний
|
|
||||||
- Генерация мультимодальных ответов
|
|
||||||
- **Результат:** Контекст из медиафайлов
|
|
||||||
|
|
||||||
#### 9. Агент "Саммари беседы"
|
|
||||||
- **Задача:** Создание краткого саммари истории беседы
|
|
||||||
- **Функции:**
|
|
||||||
- Анализирует последние 10-20 сообщений из истории
|
|
||||||
- Создает краткое саммари через AI (вместо передачи полной истории)
|
|
||||||
- Кэширует результат для повторного использования
|
|
||||||
- Обновляет саммари при поступлении новых сообщений
|
|
||||||
- Оптимизирует количество токенов в промпте
|
|
||||||
- **Результат:** Оптимизированный контекст беседы для AI
|
|
||||||
|
|
||||||
#### 10. Агент "Анализ контакта"
|
|
||||||
- **Задача:** Извлечение и анализ данных пользователя из профиля
|
|
||||||
- **Функции:**
|
|
||||||
- Получает данные из профиля контакта (имя, теги, язык, роль)
|
|
||||||
- Анализирует предпочтения и историю взаимодействий
|
|
||||||
- Кэширует анализ для быстрого доступа
|
|
||||||
- Обновляет при изменении профиля пользователя
|
|
||||||
- Определяет стиль общения и приоритет
|
|
||||||
- **Результат:** Персонализированный контекст для ответа
|
|
||||||
|
|
||||||
#### 11. Агент "Кэширование бесед"
|
|
||||||
- **Задача:** Управление кэшем бесед и контекста
|
|
||||||
- **Функции:**
|
|
||||||
- Кэширует саммари беседы + анализ контакта
|
|
||||||
- Управляет TTL (Time To Live) для автоматической очистки
|
|
||||||
- Проверяет актуальность кэша при новых сообщениях
|
|
||||||
- Оптимизирует производительность системы
|
|
||||||
- Предотвращает повторные вычисления
|
|
||||||
- **Результат:** Быстрый доступ к контексту без пересчета
|
|
||||||
|
|
||||||
### ⚙️ Логика работы многоагентной системы
|
|
||||||
|
|
||||||
#### Шаг 1: Получение сообщения
|
|
||||||
- Координатор получает входящее сообщение
|
|
||||||
- Анализирует базовый контекст
|
|
||||||
- Определяет необходимых агентов
|
|
||||||
|
|
||||||
#### Шаг 2: Параллельный запуск агентов
|
|
||||||
- Агент "Персонализация" → извлекает данные пользователя
|
|
||||||
- Агент "Анализ запроса" → классифицирует обращение
|
|
||||||
- Агент "RAG поиск" → ищет релевантную информацию
|
|
||||||
- Агент "Контекст" → анализирует историю
|
|
||||||
- Агент "Мультиязычность" → определяет язык
|
|
||||||
- Агент "Мультимодальность" → обрабатывает медиа
|
|
||||||
- Агент "Саммари беседы" → создает краткое саммари истории
|
|
||||||
- Агент "Анализ контакта" → извлекает данные из профиля
|
|
||||||
- Агент "Кэширование бесед" → проверяет и обновляет кэш
|
|
||||||
|
|
||||||
#### Шаг 3: Сбор и анализ результатов
|
|
||||||
- Координатор собирает данные от всех агентов
|
|
||||||
- Анализирует полноту информации
|
|
||||||
- Определяет необходимость дополнительных уточнений
|
|
||||||
|
|
||||||
#### Шаг 4: Генерация ответа
|
|
||||||
- Если информации достаточно → генерирует персонализированный ответ
|
|
||||||
- Если нужно уточнить → запускает агента "Детализация"
|
|
||||||
- Если требуется дополнительный контекст → запрашивает у других агентов
|
|
||||||
|
|
||||||
#### Шаг 5: Сохранение контекста
|
|
||||||
- Обновляет профиль пользователя
|
|
||||||
- Сохраняет контекст беседы
|
|
||||||
- Логирует использованные знания
|
|
||||||
- Обновляет кэш саммари и анализа контакта
|
|
||||||
- Сохраняет оптимизированный контекст для будущих запросов
|
|
||||||
|
|
||||||
### 🎨 Преимущества многоагентной архитектуры
|
|
||||||
|
|
||||||
1. **Модульность:** Каждый агент решает свою специализированную задачу
|
|
||||||
2. **Масштабируемость:** Легко добавлять новых агентов
|
|
||||||
3. **Эффективность:** Параллельная обработка разных аспектов
|
|
||||||
4. **Гибкость:** Разные комбинации агентов для разных ситуаций
|
|
||||||
5. **Персонализация:** Глубокое понимание каждого пользователя
|
|
||||||
6. **Качество:** Специализированная обработка каждого аспекта
|
|
||||||
7. **Оптимизация:** Саммари бесед снижает количество токенов
|
|
||||||
8. **Кэширование:** Быстрый доступ к контексту без пересчета
|
|
||||||
9. **Производительность:** Уменьшение времени ответа и нагрузки на AI
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Персонализация на уровне аккаунта пользователя
|
|
||||||
|
|
||||||
### 👤 Профиль пользователя
|
|
||||||
- **Базовые данные:** Имя, компания, должность, контактная информация
|
|
||||||
- **История взаимодействий:** Все предыдущие обращения и решения
|
|
||||||
- **Предпочтения:** Стиль общения, технический уровень, приоритеты
|
|
||||||
- **Статус:** Стадия в воронке продаж, статус клиента
|
|
||||||
- **Теги:** Категории, сегменты, специализации
|
|
||||||
|
|
||||||
### 📊 Контекстная картина
|
|
||||||
- **Текущая беседа:** Сообщения в рамках одной сессии
|
|
||||||
- **История обращений:** Все предыдущие взаимодействия
|
|
||||||
- **Решенные проблемы:** Успешно закрытые задачи
|
|
||||||
- **Открытые вопросы:** Незавершенные обращения
|
|
||||||
- **Эмоциональное состояние:** Тон и настроение клиента
|
|
||||||
|
|
||||||
### 🎯 Алгоритм персонализации
|
|
||||||
|
|
||||||
#### 1. Анализ входящего сообщения
|
|
||||||
- Определение типа обращения
|
|
||||||
- Извлечение ключевой информации
|
|
||||||
- Анализ эмоционального контекста
|
|
||||||
|
|
||||||
#### 2. Загрузка профиля пользователя
|
|
||||||
- Получение персональных данных
|
|
||||||
- Анализ истории взаимодействий
|
|
||||||
- Определение текущего статуса
|
|
||||||
|
|
||||||
#### 3. Поиск в RAG базе
|
|
||||||
- Фильтрация по тегам пользователя
|
|
||||||
- Поиск релевантных решений
|
|
||||||
- Анализ похожих случаев
|
|
||||||
|
|
||||||
#### 4. Формирование контекста
|
|
||||||
- Объединение данных профиля и истории
|
|
||||||
- Анализ текущей ситуации
|
|
||||||
- Определение оптимального подхода
|
|
||||||
|
|
||||||
#### 5. Генерация персонализированного ответа
|
|
||||||
- Учет персональных данных
|
|
||||||
- Адаптация под стиль общения
|
|
||||||
- Ссылки на предыдущие взаимодействия
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Этап 1. Проектирование и подготовка инфраструктуры
|
|
||||||
1. **Проектирование схемы хранения знаний (RAG):**
|
|
||||||
- Описать структуру таблицы `knowledge_documents` (миграция).
|
|
||||||
- Определить поля: id, content, language, type (текст/медиа), метаданные, дата, автор и т.д.
|
|
||||||
2. **Подготовка backend:**
|
|
||||||
- Создать миграцию и модель для `knowledge_documents`.
|
|
||||||
- Подготовить базовые CRUD-эндпоинты для работы с базой знаний.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Этап 2. Интеграция векторного поиска (RAG)
|
|
||||||
1. **Реализация векторного хранилища:**
|
|
||||||
- Реализовать методы инициализации и поиска (`initVectorStore`, `findSimilarDocuments`) в `ai-assistant.js`.
|
|
||||||
- Настроить хранение эмбеддингов для документов.
|
|
||||||
2. **API для поиска знаний:**
|
|
||||||
- Добавить эндпоинт для поиска релевантных знаний по запросу пользователя.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Этап 3. Разработка многоагентной архитектуры
|
|
||||||
1. **Создание базовой структуры агентов:**
|
|
||||||
- Реализовать главный AI-координатор
|
|
||||||
- Создать базовые классы для специализированных агентов
|
|
||||||
- Настроить систему координации между агентами
|
|
||||||
2. **Разработка специализированных агентов:**
|
|
||||||
- Агент "Персонализация пользователя"
|
|
||||||
- Агент "Анализ запроса"
|
|
||||||
- Агент "RAG поиск"
|
|
||||||
- Агент "Контекст беседы"
|
|
||||||
- Агент "Детализация"
|
|
||||||
- Агент "Персонализация ответа"
|
|
||||||
- Агент "Саммари беседы" (новый)
|
|
||||||
- Агент "Анализ контакта" (новый)
|
|
||||||
- Агент "Кэширование бесед" (новый)
|
|
||||||
3. **Интеграция с существующей системой:**
|
|
||||||
- Подключение агентов к текущему pipeline
|
|
||||||
- Настройка логирования и мониторинга
|
|
||||||
- Тестирование взаимодействия агентов
|
|
||||||
4. **Реализация оптимизаций:**
|
|
||||||
- Создание сервиса саммари бесед
|
|
||||||
- Интеграция анализа контактов для персонализации
|
|
||||||
- Настройка кэширования для повышения производительности
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Этап 4. Интеграция RAG в pipeline ассистента
|
|
||||||
1. **Модификация логики ответа ассистента:**
|
|
||||||
- При получении сообщения пользователя — искать релевантные знания и включать их в prompt LLM.
|
|
||||||
- Обеспечить мультиязычность поиска и генерации ответа.
|
|
||||||
- Интегрировать саммари беседы вместо передачи полной истории.
|
|
||||||
- Использовать анализ контактов для персонализации ответов.
|
|
||||||
2. **Логирование и трассировка:**
|
|
||||||
- Сохранять, какие знания были использованы для ответа.
|
|
||||||
- Логировать использование саммари и кэширования.
|
|
||||||
- Отслеживать производительность оптимизаций.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Этап 5. Интерфейс для админа
|
|
||||||
1. **UI для управления знаниями:**
|
|
||||||
- Добавить на фронте раздел для просмотра, добавления, редактирования и удаления знаний.
|
|
||||||
2. **UI для модерации ответов ассистента:**
|
|
||||||
- Кнопки "Редактировать", "Отправить", "Добавить в RAG" для сообщений и ответов.
|
|
||||||
- Возможность быстро добавить сообщение пользователя или ответ ассистента в базу знаний.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Этап 6. Поддержка мультимодальности и мультиязычности
|
|
||||||
1. **Обработка вложений (аудио, видео, картинки):**
|
|
||||||
- Решить, как хранить и индексировать такие данные (например, хранить ссылки и метаданные, а не сами файлы).
|
|
||||||
2. **Мультиязычный поиск и генерация:**
|
|
||||||
- Проверить корректность работы эмбеддингов и LLM для разных языков.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Этап 7. Тестирование и оптимизация
|
|
||||||
1. **Покрытие тестами ключевых сценариев (unit, интеграционные).**
|
|
||||||
2. **Оптимизация скорости поиска и генерации.**
|
|
||||||
3. **Тестирование производительности саммари и кэширования.**
|
|
||||||
4. **Оптимизация использования токенов и времени ответа.**
|
|
||||||
5. **Документация для команды.**
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Бизнес-логика управления знаниями и тегами для RAG-ассистента
|
|
||||||
|
|
||||||
### 1. Гибкая система тегов и связей с пользователями
|
|
||||||
- Пользователь может создавать собственные таблицы тегов (например, "покупатель", "поставщик", "VIP-клиент" и т.д.).
|
|
||||||
- В таблице тегов должна быть возможность добавлять ссылки (relation) на пользователей из таблицы `users`.
|
|
||||||
- Для одного тега может быть привязано несколько пользователей (мультисвязь).
|
|
||||||
- Для одного пользователя может быть несколько тегов.
|
|
||||||
|
|
||||||
### 2. Управление знаниями (FAQ, инструкции, ответы)
|
|
||||||
- Пользователь может создавать таблицы с вопросами и ответами (например, FAQ для определённой группы клиентов).
|
|
||||||
- Каждая запись (вопрос-ответ) может быть связана с определённым тегом или группой тегов.
|
|
||||||
- Возможна фильтрация и поиск знаний по тегам, языку, типу клиента и другим параметрам.
|
|
||||||
|
|
||||||
### 3. Использование тегов и знаний в RAG-ассистенте
|
|
||||||
- При обработке запроса пользователя RAG-ассистент определяет его теги (по связям в таблице тегов).
|
|
||||||
- Для генерации ответа ассистент использует только те знания (вопросы/ответы), которые соответствуют тегам пользователя.
|
|
||||||
- Администратор может добавлять новые теги, связывать их с пользователями, а также создавать и редактировать знания для каждой группы.
|
|
||||||
- **Оптимизация через саммари:** Вместо передачи полной истории беседы (10 сообщений), система создает краткое саммари через AI.
|
|
||||||
- **Персонализация через контакты:** Ассистент использует данные из профиля контакта (имя, язык, теги) для персонализации ответов.
|
|
||||||
- **Кэширование контекста:** Саммари беседы и анализ контактов кэшируются для быстрого доступа без пересчета.
|
|
||||||
|
|
||||||
### 4. UI/UX требования
|
|
||||||
- В интерфейсе создания/редактирования пользовательских таблиц должен быть доступен тип столбца "relation" (связь с users).
|
|
||||||
- Для ячеек типа "relation" реализовать выпадающий список с поиском по пользователям.
|
|
||||||
- Для таблиц знаний — возможность выбора одного или нескольких тегов для каждой записи.
|
|
||||||
|
|
||||||
**Пример структуры:**
|
|
||||||
- Таблица `user_tags`: id, name, [user_id (relation, мультисвязь)]
|
|
||||||
- Таблица `faq`: id, question, answer, [tag_id (relation, мультисвязь)]
|
|
||||||
|
|
||||||
**Применение:**
|
|
||||||
- RAG-ассистент использует связи между пользователями, тегами и знаниями для персонализации ответов и поиска релевантной информации.
|
|
||||||
|
|
||||||
### 5. Безопасность и контроль
|
|
||||||
- Только администратор может создавать и редактировать системные теги и знания.
|
|
||||||
- Обычные пользователи могут видеть только свои теги и связанные с ними знания.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Требования к CRM-интерфейсу для работы с контактами, тегами и настройками RAG-ассистента
|
|
||||||
|
|
||||||
### 1. Раздел "Контакты" в CRM
|
|
||||||
- **Фильтры:**
|
|
||||||
- Новые пользователи (по дате создания или статусу "новый").
|
|
||||||
- Новые входящие сообщения (по наличию непрочитанных/неотвеченных сообщений).
|
|
||||||
- Теги (мультиселект по тегам пользователя).
|
|
||||||
- **Детали контакта:**
|
|
||||||
- Просмотр истории сообщений.
|
|
||||||
- Список тегов пользователя.
|
|
||||||
- Добавление/удаление тегов через выпадающий список или автокомплит (создание связи в таблице user_tags).
|
|
||||||
|
|
||||||
### 2. Настройки ИИ-ассистента
|
|
||||||
- **Выбор RAG-таблиц:**
|
|
||||||
- В настройках ассистента отображается список всех доступных RAG-таблиц.
|
|
||||||
- Администратор выбирает (чекбоксами или мультиселектом), какие таблицы использовать для поиска ответов.
|
|
||||||
- Для каждой выбранной таблицы отображается список тегов, которые она содержит.
|
|
||||||
- **Связь с тегами:**
|
|
||||||
- При генерации ответа ИИ использует только те RAG-таблицы и записи, которые соответствуют тегам пользователя.
|
|
||||||
|
|
||||||
### 3. Рекомендации по интерфейсу (Vue)
|
|
||||||
- Компоненты:
|
|
||||||
- `ContactList.vue` — фильтры, список пользователей
|
|
||||||
- `ContactDetails.vue` — история сообщений, теги, добавление тегов
|
|
||||||
- `AssistantSettings.vue` — выбор RAG-таблиц
|
|
||||||
- `RagTableSelector.vue` — список таблиц с чекбоксами
|
|
||||||
- `TagList.vue` — просмотр тегов в выбранной таблице
|
|
||||||
|
|
||||||
### 4. Схема действий администратора
|
|
||||||
1. В разделе "Контакты" находит нового пользователя/сообщение через фильтры.
|
|
||||||
2. В деталях контакта добавляет нужные теги пользователю.
|
|
||||||
3. В настройках ассистента выбирает, какие RAG-таблицы использовать для поиска по тегам.
|
|
||||||
4. ИИ-ассистент при ответе использует только релевантные RAG-таблицы и теги.
|
|
||||||
|
|
||||||
### 5. Пример структуры таблиц для RAG и тегов
|
|
||||||
- `users` — пользователи
|
|
||||||
- `messages` — сообщения
|
|
||||||
- `tags` — справочник тегов
|
|
||||||
- `user_tags` — связь пользователей и тегов (user_id, tag_id)
|
|
||||||
- `rag_tables` — таблицы знаний (например, FAQ, инструкции)
|
|
||||||
- `rag_entries` — записи в таблицах знаний (content, rag_table_id, ...)
|
|
||||||
- `rag_entry_tags` — связь записей знаний и тегов (rag_entry_id, tag_id)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## План внедрения RAG-ассистента в CRM
|
|
||||||
|
|
||||||
1. **Создать RAG-таблицы для ИИ-ассистента**
|
|
||||||
- Таблицы для хранения знаний о компании, продуктах, услугах (например, `rag_tables`, `rag_entries`).
|
|
||||||
- Возможность добавлять, редактировать, удалять записи через UI.
|
|
||||||
- Каждая запись может быть связана с тегами (например, категория продукта, язык, сегмент клиента).
|
|
||||||
|
|
||||||
2. **Создать таблицы с тегами для пользователей**
|
|
||||||
- Таблица тегов (`tags`).
|
|
||||||
- Связующая таблица `user_tags` (user_id, tag_id).
|
|
||||||
- UI для управления тегами и их привязкой к пользователям.
|
|
||||||
|
|
||||||
3. **Отредактировать страницу настройки ИИ-ассистента**
|
|
||||||
- Добавить выбор, какие RAG-таблицы использовать для поиска.
|
|
||||||
- Отображать список тегов, связанных с выбранными таблицами.
|
|
||||||
- Возможность быстро подключать/отключать таблицы и теги.
|
|
||||||
|
|
||||||
4. **Добавить в раздел "Контакты" фильтры (отдельные компоненты)**
|
|
||||||
- Фильтр по новым пользователям.
|
|
||||||
- Фильтр по новым входящим сообщениям.
|
|
||||||
- Фильтр по тегам (мультиселект).
|
|
||||||
- Каждый фильтр реализовать отдельным Vue-компонентом для переиспользования.
|
|
||||||
|
|
||||||
5. **В "Детали контакта" добавить инлайн-кнопки**
|
|
||||||
- Кнопки:
|
|
||||||
- Сгенерировать (ответ с помощью ИИ)
|
|
||||||
- Редактировать (отредактировать сгенерированный ответ)
|
|
||||||
- Отправить (отправить ответ пользователю)
|
|
||||||
- Добавить в RAG-таблицу (сделать сообщение или ответ частью базы знаний)
|
|
||||||
- Кнопки должны быть доступны для каждого сообщения в истории.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Этот документ будет дополняться по мере реализации каждого этапа.**
|
|
||||||
@@ -1,105 +0,0 @@
|
|||||||
# Настройка расширенной системы прав доступа
|
|
||||||
|
|
||||||
## Описание изменений
|
|
||||||
|
|
||||||
Добавлена расширенная система прав доступа с настраиваемыми порогами:
|
|
||||||
|
|
||||||
- **Read-Only (1+ токен)** - только просмотр данных
|
|
||||||
- **Editor (2+ токен)** - просмотр + редактирование + удаление
|
|
||||||
- **User (0 токенов)** - базовые права без изменений
|
|
||||||
|
|
||||||
## Новые поля в форме добавления токенов
|
|
||||||
|
|
||||||
На странице `/settings/security` в форме добавления токенов добавлены два новых поля:
|
|
||||||
|
|
||||||
1. **Минимум токенов для Read-Only доступа** (по умолчанию: 1)
|
|
||||||
2. **Минимум токенов для Editor доступа** (по умолчанию: 2)
|
|
||||||
|
|
||||||
## Применение изменений
|
|
||||||
|
|
||||||
### 1. Обновление базы данных
|
|
||||||
|
|
||||||
Выполните SQL скрипт для добавления новых полей:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Подключитесь к базе данных PostgreSQL
|
|
||||||
psql -h localhost -U your_username -d your_database
|
|
||||||
|
|
||||||
# Выполните миграцию
|
|
||||||
\i backend/scripts/add_access_thresholds.sql
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. Перезапуск сервера
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# В папке backend
|
|
||||||
yarn restart
|
|
||||||
# или
|
|
||||||
docker-compose restart backend
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. Перезапуск frontend
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# В папке frontend
|
|
||||||
yarn dev
|
|
||||||
```
|
|
||||||
|
|
||||||
## Как использовать
|
|
||||||
|
|
||||||
### Для администраторов:
|
|
||||||
|
|
||||||
1. Перейдите на страницу `/settings/security`
|
|
||||||
2. В разделе "Токены аутентификации" нажмите "Подробнее"
|
|
||||||
3. При добавлении нового токена заполните:
|
|
||||||
- Название токена
|
|
||||||
- Адрес смарт-контракта
|
|
||||||
- Сеть блокчейна
|
|
||||||
- Минимальный баланс
|
|
||||||
- **Минимум токенов для Read-Only доступа**
|
|
||||||
- **Минимум токенов для Editor доступа**
|
|
||||||
|
|
||||||
### Для пользователей:
|
|
||||||
|
|
||||||
- Система автоматически определяет уровень доступа на основе количества токенов
|
|
||||||
- Отображается текущий уровень доступа с визуальными индикаторами
|
|
||||||
- UI автоматически адаптируется под уровень доступа
|
|
||||||
|
|
||||||
## Примеры настроек
|
|
||||||
|
|
||||||
### Стандартные настройки:
|
|
||||||
- Read-Only: 1 токен
|
|
||||||
- Editor: 2 токена
|
|
||||||
|
|
||||||
### Строгие настройки:
|
|
||||||
- Read-Only: 2 токена
|
|
||||||
- Editor: 5 токенов
|
|
||||||
|
|
||||||
### Либеральные настройки:
|
|
||||||
- Read-Only: 1 токен
|
|
||||||
- Editor: 1 токен (все пользователи с токенами могут редактировать)
|
|
||||||
|
|
||||||
## Технические детали
|
|
||||||
|
|
||||||
### Backend изменения:
|
|
||||||
- `auth-service.js` - добавлена функция `getUserAccessLevel()`
|
|
||||||
- `authTokenService.js` - поддержка новых полей
|
|
||||||
- `tokenBalanceService.js` - возврат порогов доступа
|
|
||||||
- `routes/settings.js` - API endpoint для новых полей
|
|
||||||
- `routes/auth.js` - новый endpoint `/access-level/:address`
|
|
||||||
|
|
||||||
### Frontend изменения:
|
|
||||||
- `useAuth.js` - поддержка уровней доступа
|
|
||||||
- `usePermissions.js` - новый composable для проверки прав
|
|
||||||
- `AuthTokensSettings.vue` - форма с новыми полями
|
|
||||||
- `SecuritySettingsView.vue` - использование новых прав доступа
|
|
||||||
|
|
||||||
### Новые поля в БД:
|
|
||||||
- `auth_tokens.readonly_threshold` - порог для Read-Only
|
|
||||||
- `auth_tokens.editor_threshold` - порог для Editor
|
|
||||||
|
|
||||||
## Обратная совместимость
|
|
||||||
|
|
||||||
- Все существующие токены получают значения по умолчанию (1 и 2)
|
|
||||||
- Старые проверки `isAdmin` продолжают работать
|
|
||||||
- Система автоматически мигрирует существующие данные
|
|
||||||
@@ -1,558 +0,0 @@
|
|||||||
<!--
|
|
||||||
Copyright (c) 2024-2025 Тарабанов Александр Викторович
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
This software is proprietary and confidential.
|
|
||||||
Unauthorized copying, modification, or distribution is prohibited.
|
|
||||||
|
|
||||||
For licensing inquiries: info@hb3-accelerator.com
|
|
||||||
Website: https://hb3-accelerator.com
|
|
||||||
GitHub: https://github.com/HB3-ACCELERATOR
|
|
||||||
-->
|
|
||||||
|
|
||||||
# Смарт Контракты Digital Legal Entity (DLE)
|
|
||||||
|
|
||||||
## Основной смарт контракт DLE
|
|
||||||
|
|
||||||
### DLE v2: ключевые изменения и API (актуально)
|
|
||||||
- Безопасность: удалены уязвимые Merkle‑механизмы cross‑chain; нет внешних мостов/оракулов.
|
|
||||||
- Голосующая сила: OpenZeppelin `ERC20Votes` (снимки `getPastVotes`, `getPastTotalSupply`).
|
|
||||||
- Делегирование: жестко ограничено «только на себя»; третьим лицам делегировать нельзя (1 токен = 1 голос).
|
|
||||||
- Переводы токенов: ЗАБЛОКИРОВАНЫ прямые переводы (transfer, transferFrom, approve); переводы возможны ТОЛЬКО через governance предложения.
|
|
||||||
- Single‑Chain Governance: голосование происходит в одной выбранной сети (`governanceChainId`), время снапшота фиксируется на создании предложения и используется во всех сетях.
|
|
||||||
- Multi‑Chain исполнение: выполнение в целевых сетях по EIP‑712 подписям холдеров, проверяется суммарная голосующая сила на зафиксированном `timepoint` (без доверия к мостам).
|
|
||||||
- «100% или ничего»: операции считаются успешными только при готовности/успешности всех целевых сетей.
|
|
||||||
- Модули вынесены отдельно: `Treasury`, `Timelock`, `Deactivation`, `Communication` и др. Управление только через предложения.
|
|
||||||
- Детерминированные адреса: CREATE с выровненным nonce. Единый адрес DLE и модулей во всех выбранных сетях.
|
|
||||||
- Аналитика: добавлены view‑функции для агрегирования и пагинации.
|
|
||||||
|
|
||||||
Пример основных функций DLE v2 (интерфейс):
|
|
||||||
```solidity
|
|
||||||
// Создание предложения с фиксацией сети голосования, целевых сетей и таймлока
|
|
||||||
function createProposal(
|
|
||||||
string calldata description,
|
|
||||||
uint256 governanceChainId,
|
|
||||||
uint256[] calldata targetChains,
|
|
||||||
uint64 timelockHours,
|
|
||||||
bytes calldata operationCalldata
|
|
||||||
) external returns (uint256 proposalId);
|
|
||||||
|
|
||||||
// Голосование с использованием снапшотов ERC20Votes (учет силы на момент создания)
|
|
||||||
function vote(uint256 proposalId, bool support) external;
|
|
||||||
|
|
||||||
// Отмена инициатором при наличии достаточной голосующей силы (мягкая отмена)
|
|
||||||
function cancelProposal(uint256 proposalId) external;
|
|
||||||
|
|
||||||
// Исполнение в целевой сети по EIP-712 подписям холдеров (без мостов)
|
|
||||||
function executeProposalBySignatures(
|
|
||||||
uint256 proposalId,
|
|
||||||
bytes[] calldata signatures
|
|
||||||
) external;
|
|
||||||
|
|
||||||
// Просмотровые функции (аналитика)
|
|
||||||
function getProposalState(uint256 proposalId) external view returns (uint8);
|
|
||||||
function getProposalVotes(uint256 proposalId) external view returns (uint256 forVotes, uint256 againstVotes);
|
|
||||||
function getQuorumAt(uint256 timepoint) external view returns (uint256);
|
|
||||||
function getVotingPowerAt(address account, uint256 timepoint) external view returns (uint256);
|
|
||||||
function getProposalSummary(uint256 proposalId) external view returns (/* агрегированные поля */);
|
|
||||||
function getGovernanceParams() external view returns (/* кворум, снапшоты, chainIds */);
|
|
||||||
function listSupportedChains() external view returns (uint256[] memory);
|
|
||||||
```
|
|
||||||
|
|
||||||
События (ключевые):
|
|
||||||
- `ProposalCreated`, `ProposalCancelled`, `ProposalExecuted`
|
|
||||||
- `OffchainAction` (триггер оффчейн‑действий через события)
|
|
||||||
- `ModuleAdded`, `ModuleRemoved`
|
|
||||||
|
|
||||||
Замечания по безопасности:
|
|
||||||
- Снапшоты голосующей силы через `ERC20Votes` исключают перелив голосов.
|
|
||||||
- Верификация EIP‑712 подписей исключает зависимость от внешних мостов.
|
|
||||||
- Отсутствуют админ‑роли: все изменения только предложением и кворумом.
|
|
||||||
- Защита от повторов: `nonces` и EIP‑712 схемы подписи используются по стандарту OZ.
|
|
||||||
```
|
|
||||||
|
|
||||||
### Концепция
|
|
||||||
**Один смарт-контракт** с ERC-20 токенами, настраиваемым кворумом и модулями. Адрес контракта одновременно выполняет функции банковского счета и контактных данных.
|
|
||||||
|
|
||||||
### Архитектура
|
|
||||||
```
|
|
||||||
DLE.sol (Один контракт)
|
|
||||||
├── ERC-20 токены (голосующая сила)
|
|
||||||
├── Настраиваемый кворум (% от общего количества токенов)
|
|
||||||
├── Система голосования (проверка баланса токенов)
|
|
||||||
├── Голосование токен‑холдеров
|
|
||||||
├── Модули (добавляемые через голосование)
|
|
||||||
├── Мультичейн синхронизация
|
|
||||||
└── Полное управление данными DLE через кворум
|
|
||||||
```
|
|
||||||
|
|
||||||
### Требования
|
|
||||||
|
|
||||||
#### 1. Токен управления (ERC-20)
|
|
||||||
- **Описание**: Стандартный ERC-20 токен для управления DLE
|
|
||||||
- **Функции**:
|
|
||||||
- Минтинг токенов при создании DLE
|
|
||||||
- Распределение токенов между участниками
|
|
||||||
- **Голосующая сила = количество токенов**
|
|
||||||
- Проверка баланса токенов при каждой операции
|
|
||||||
- **Прямые переводы ЗАБЛОКИРОВАНЫ** - токены служат только для голосования
|
|
||||||
- **Переводы возможны ТОЛЬКО через governance предложения**
|
|
||||||
|
|
||||||
#### 2. Настраиваемый кворум
|
|
||||||
- **Описание**: Процент от общего количества токенов для принятия решений
|
|
||||||
- **Функции**:
|
|
||||||
- Настройка кворума при создании DLE
|
|
||||||
- **Изменение кворума через голосование** ✅
|
|
||||||
- Расчет кворума: `(totalSupply * quorumPercentage) / 100`
|
|
||||||
- Проверка достижения кворума для каждого решения
|
|
||||||
|
|
||||||
#### 3. Система голосования через токен-холдеров
|
|
||||||
- **Описание**: Только владельцы токенов участвуют в управлении
|
|
||||||
- **Функции**:
|
|
||||||
- Создание предложений (любым токен-холдером)
|
|
||||||
- Голосование пропорционально балансу токенов
|
|
||||||
- Проверка баланса токенов при каждой подписи
|
|
||||||
- Выполнение предложений после достижения кворума
|
|
||||||
- **НЕТ админских ролей - только коллективное управление**
|
|
||||||
|
|
||||||
#### 4. Полное управление данными DLE через кворум ✅
|
|
||||||
- **Описание**: Все данные DLE можно изменить через систему голосования
|
|
||||||
- **Функции**:
|
|
||||||
- **Изменение названия DLE** через кворум
|
|
||||||
- **Изменение символа токена** через кворум
|
|
||||||
- **Изменение местонахождения** через кворум
|
|
||||||
- **Изменение координат** через кворум
|
|
||||||
- **Изменение юрисдикции** через кворум
|
|
||||||
- **Изменение ОКТМО** через кворум
|
|
||||||
- **Изменение КПП** через кворум
|
|
||||||
- **Изменение кодов ОКВЭД** через кворум
|
|
||||||
- **Изменение процента кворума** через кворум
|
|
||||||
- **Изменение текущей цепочки** через кворум
|
|
||||||
|
|
||||||
#### 5. Голосование токен‑холдеров
|
|
||||||
- **Описание**: Критические операции подтверждаются голосованием держателей токенов
|
|
||||||
- **Функции**:
|
|
||||||
- Подача голосов за/против с учетом голосующей силы
|
|
||||||
- Подсчет голосов по снапшотам `ERC20Votes`
|
|
||||||
- Исполнение операций после достижения кворума
|
|
||||||
|
|
||||||
#### 6. Казначейские функции
|
|
||||||
- **Описание**: Управление финансами DLE через голосование
|
|
||||||
- **Функции**:
|
|
||||||
- Внесение токенов в казну
|
|
||||||
- Вывод токенов из казны через голосование
|
|
||||||
- Распределение дивидендов
|
|
||||||
- Бюджетирование через предложения
|
|
||||||
|
|
||||||
#### 7. Модульная система
|
|
||||||
- **Описание**: Добавление новых функций через модули
|
|
||||||
- **Функции**:
|
|
||||||
- Добавление модулей через голосование
|
|
||||||
- Управление модулями через голосование
|
|
||||||
- Изоляция модулей от основного контракта
|
|
||||||
- Обновление модулей через голосование
|
|
||||||
|
|
||||||
#### 8. Коммуникационные функции
|
|
||||||
- **Описание**: Прием сообщений и звонков
|
|
||||||
- **Функции**:
|
|
||||||
- Прием текстовых сообщений
|
|
||||||
- Прием аудио/видео звонков
|
|
||||||
- Кворум для коммуникационных действий
|
|
||||||
- Хранение истории коммуникаций
|
|
||||||
|
|
||||||
### Иерархическая система голосования DLE
|
|
||||||
|
|
||||||
#### Концепция
|
|
||||||
DLE может владеть токенами других DLE и участвовать в их голосовании через систему кворума подписей.
|
|
||||||
|
|
||||||
#### Механизм работы
|
|
||||||
1. **DLE A** владеет токенами **DLE B**
|
|
||||||
2. **Голос DLE A** в **DLE B** прямо пропорционален количеству токенов **DLE B** на балансе **DLE A**
|
|
||||||
3. Для участия в голосовании **DLE B** холдеры **DLE A** должны собрать **кворум голосов** внутри **DLE A**
|
|
||||||
4. После достижения кворума подписей **DLE A** может голосовать в **DLE B** как единое целое
|
|
||||||
|
|
||||||
### Новые возможности изменения данных DLE ✅
|
|
||||||
|
|
||||||
#### 1. Обновление основной информации DLE
|
|
||||||
```solidity
|
|
||||||
function _updateDLEInfo(
|
|
||||||
string memory _name,
|
|
||||||
string memory _symbol,
|
|
||||||
string memory _location,
|
|
||||||
string memory _coordinates,
|
|
||||||
uint256 _jurisdiction,
|
|
||||||
uint256 _oktmo,
|
|
||||||
string[] memory _okvedCodes,
|
|
||||||
uint256 _kpp
|
|
||||||
) internal
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 2. Изменение процента кворума
|
|
||||||
```solidity
|
|
||||||
function _updateQuorumPercentage(uint256 _newQuorumPercentage) internal
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
#### 3. События для отслеживания изменений
|
|
||||||
```solidity
|
|
||||||
event DLEInfoUpdated(string name, string symbol, string location, string coordinates, uint256 jurisdiction, uint256 oktmo, string[] okvedCodes, uint256 kpp);
|
|
||||||
event QuorumPercentageUpdated(uint256 oldQuorumPercentage, uint256 newQuorumPercentage);
|
|
||||||
```
|
|
||||||
|
|
||||||
### Процесс изменения данных DLE
|
|
||||||
|
|
||||||
#### 1. Создание предложения
|
|
||||||
- Любой токен-холдер создает предложение об изменении данных
|
|
||||||
- Выбирает цепочку для сбора голосов
|
|
||||||
- Указывает новые значения для изменения
|
|
||||||
|
|
||||||
#### 2. Голосование
|
|
||||||
- Токен-холдеры голосуют за/против изменения
|
|
||||||
- Голосующая сила = количество токенов
|
|
||||||
- Проверка баланса при каждом голосе
|
|
||||||
|
|
||||||
#### 3. Исполнение
|
|
||||||
- При достижении кворума предложение исполняется
|
|
||||||
- Данные DLE обновляются
|
|
||||||
- Событие эмитится для отслеживания
|
|
||||||
|
|
||||||
#### 4. Синхронизация
|
|
||||||
- Изменения синхронизируются во все поддерживаемые цепочки
|
|
||||||
- EIP‑712 подписи холдеров обеспечивают безопасность cross-chain исполнения (без мостов)
|
|
||||||
|
|
||||||
### Примеры использования
|
|
||||||
|
|
||||||
#### Изменение названия DLE
|
|
||||||
```
|
|
||||||
1. Создание предложения: "Изменить название на 'Новое DLE'"
|
|
||||||
2. Голосование в выбранной цепочке
|
|
||||||
3. При кворуме: обновление названия
|
|
||||||
4. Синхронизация во все цепочки
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Изменение кворума
|
|
||||||
```
|
|
||||||
1. Создание предложения: "Изменить кворум с 51% на 60%"
|
|
||||||
2. Голосование в выбранной цепочке
|
|
||||||
3. При кворуме: обновление процента кворума
|
|
||||||
4. Синхронизация во все цепочки
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Изменение текущей цепочки
|
|
||||||
```
|
|
||||||
1. Создание предложения: "Изменить текущую цепочку на Polygon"
|
|
||||||
2. Голосование в выбранной цепочке
|
|
||||||
3. При кворуме: обновление currentChainId
|
|
||||||
4. Синхронизация во все цепочки
|
|
||||||
```
|
|
||||||
|
|
||||||
### Безопасность
|
|
||||||
|
|
||||||
#### Валидация данных
|
|
||||||
- Проверка корректности всех входящих данных
|
|
||||||
- Валидация адресов и числовых значений
|
|
||||||
- Проверка поддержки цепочек перед изменением
|
|
||||||
|
|
||||||
#### Защита от злоупотреблений
|
|
||||||
- Все изменения только через кворум
|
|
||||||
- Проверка баланса токенов при голосовании
|
|
||||||
- EIP‑712 подписи и проверка снапшотов для cross-chain безопасности
|
|
||||||
|
|
||||||
#### Аудит изменений
|
|
||||||
- Все изменения логируются в событиях
|
|
||||||
- Возможность отслеживания истории изменений
|
|
||||||
- Прозрачность всех операций
|
|
||||||
|
|
||||||
### Иерархическая система голосования DLE
|
|
||||||
|
|
||||||
#### Концепция
|
|
||||||
DLE может владеть токенами других DLE и участвовать в их голосовании через систему кворума подписей.
|
|
||||||
|
|
||||||
#### Механизм работы
|
|
||||||
1. **DLE A** владеет токенами **DLE B**
|
|
||||||
2. **Голос DLE A** в **DLE B** прямо пропорционален количеству токенов **DLE B** на балансе **DLE A**
|
|
||||||
3. Для участия в голосовании **DLE B** холдеры **DLE A** должны собрать **кворум голосов** внутри **DLE A**
|
|
||||||
4. После достижения кворума подписей **DLE A** может голосовать в **DLE B** как единое целое
|
|
||||||
|
|
||||||
#### Пример
|
|
||||||
- **DLE A** владеет **10% токенов DLE B**
|
|
||||||
- Кворум в **DLE B** = **51%**
|
|
||||||
- Холдеры **DLE A** голосуют за подпись в **DLE B**
|
|
||||||
- **DLE B** получает от **DLE A** подпись на **10% голосов**
|
|
||||||
|
|
||||||
#### Технические требования
|
|
||||||
- Система сбора голосов внутри DLE для внешнего голосования
|
|
||||||
- Проверка прав через голосование
|
|
||||||
- Прямо пропорциональный подсчет голосов по количеству токенов
|
|
||||||
- Интерфейсы для взаимодействия между DLE
|
|
||||||
|
|
||||||
### Межприложное взаимодействие DLE
|
|
||||||
|
|
||||||
#### Концепция
|
|
||||||
Каждое DLE имеет свое веб3 приложение с интерфейсом управления. DLE могут взаимодействовать через встраивание интерфейсов.
|
|
||||||
|
|
||||||
#### Архитектура взаимодействия
|
|
||||||
- **DLE A** (домен 1) + **Веб3 приложение A** с интерфейсом
|
|
||||||
- **DLE B** (домен 2) + **Веб3 приложение B** с интерфейсом
|
|
||||||
- **Голосование** происходит через блокчейн между доменами
|
|
||||||
|
|
||||||
#### Вариант реализации (рекомендуемый)
|
|
||||||
**Встраивание интерфейса DLE B в приложение DLE A**
|
|
||||||
|
|
||||||
##### Преимущества:
|
|
||||||
- **Безопасность**: Холдеры DLE A не покидают свое приложение
|
|
||||||
- **Защита от фишинга**: Пользователи всегда в знакомой среде
|
|
||||||
- **Контроль**: DLE A контролирует безопасность интерфейса
|
|
||||||
- **Удобство**: Единый интерфейс для управления всеми DLE
|
|
||||||
- **Аудит**: Все действия отслеживаются в одном месте
|
|
||||||
|
|
||||||
##### Техническая реализация:
|
|
||||||
```javascript
|
|
||||||
// В приложении DLE A
|
|
||||||
function DLEBManagementInterface({ dleBAddress }) {
|
|
||||||
return (
|
|
||||||
<div className="dle-b-management">
|
|
||||||
<h3>Управление DLE B</h3>
|
|
||||||
<VotingInterface targetDLE={dleBAddress} />
|
|
||||||
<ProposalInterface targetDLE={dleBAddress} />
|
|
||||||
<TreasuryInterface targetDLE={dleBAddress} />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
##### Пример интерфейса:
|
|
||||||
- URL: `http://localhost:5173/dle-management`
|
|
||||||
- Встраивание компонентов управления DLE B
|
|
||||||
- Безопасное подписание транзакций для DLE B
|
|
||||||
- Проверка прав через голосование
|
|
||||||
|
|
||||||
### Технические требования
|
|
||||||
- Один адрес = универсальная точка входа
|
|
||||||
- Безопасность коллективного голосования токен‑холдеров по снапшотам
|
|
||||||
- Масштабируемость через модули
|
|
||||||
- Поддержка аудио/видео коммуникации
|
|
||||||
- Совместимость с существующими стандартами (ERC-20, ERC-721)
|
|
||||||
- Иерархическая система голосования между DLE
|
|
||||||
- Межприложное взаимодействие через встраивание интерфейсов
|
|
||||||
|
|
||||||
## Мульти-чейн архитектура DLE
|
|
||||||
|
|
||||||
### Концепция
|
|
||||||
DLE должен функционировать в нескольких блокчейн-сетях с одинаковым адресом для обеспечения максимального удобства и универсальности.
|
|
||||||
|
|
||||||
### Требования
|
|
||||||
|
|
||||||
#### 1. CREATE2 детерминистический деплой
|
|
||||||
- Использование CREATE2 opcode для предсказуемых адресов
|
|
||||||
- Одинаковый адрес смарт-контракта во всех EVM-совместимых сетях
|
|
||||||
- Factory контракт с одинаковым адресом во всех целевых сетях
|
|
||||||
- Детерминистический salt на основе пользовательских данных
|
|
||||||
|
|
||||||
#### 2. Синхронные токены управления
|
|
||||||
- Одинаковое количество токенов для каждого партнера во всех сетях
|
|
||||||
- Синхронизация операций с токенами между всеми развернутыми сетями
|
|
||||||
- Все операции с токенами только через кворум голосов
|
|
||||||
- Защита от double-spending и рассинхронизации
|
|
||||||
|
|
||||||
#### 3. Single-Chain Governance система
|
|
||||||
- Инициатор предложения выбирает ОДНУ сеть для голосования
|
|
||||||
- Все токен-холдеры участвуют в голосовании только в выбранной сети
|
|
||||||
- Инициатор устанавливает таймлок для предложения
|
|
||||||
- Проверка балансов токен-холдеров при подписании
|
|
||||||
- Исполнение решения происходит во всех целевых сетях
|
|
||||||
|
|
||||||
#### 4. Упрощенная cross-chain архитектура
|
|
||||||
- Голосование и кворум ТОЛЬКО в одной governance сети
|
|
||||||
- Проверка балансов токен-холдеров при подписании
|
|
||||||
- Настраиваемый таймлок для каждого предложения
|
|
||||||
- Исполнение во всех выбранных целевых сетях
|
|
||||||
|
|
||||||
#### 5. Мульти-сетевой деплой
|
|
||||||
- Выбор множественных сетей для деплоя из интерфейса
|
|
||||||
- Автоматический расчет стоимости деплоя по всем сетям
|
|
||||||
- Поддержка различных EVM-совместимых сетей
|
|
||||||
- Возможность добавления новых сетей после первоначального деплоя
|
|
||||||
|
|
||||||
### Поддерживаемые сети
|
|
||||||
- Динамическое добавление сетей через таблицу RPC провайдеров
|
|
||||||
|
|
||||||
### Архитектура синхронизации
|
|
||||||
|
|
||||||
#### Single-Chain Governance операции
|
|
||||||
```solidity
|
|
||||||
contract DLE_SingleChainGovernance {
|
|
||||||
struct Proposal {
|
|
||||||
bytes operation; // Операция для выполнения
|
|
||||||
uint256[] targetChains; // Целевые сети для исполнения
|
|
||||||
uint256 timelock; // Время исполнения (timestamp)
|
|
||||||
uint256 governanceChain; // Сеть где проходит голосование
|
|
||||||
address initiator; // Инициатор предложения
|
|
||||||
bytes[] signatures; // Подписи токен-холдеров
|
|
||||||
bool executed; // Статус исполнения
|
|
||||||
}
|
|
||||||
|
|
||||||
function createProposal(
|
|
||||||
bytes calldata operation,
|
|
||||||
uint256[] calldata targetChains,
|
|
||||||
uint256 timelockDelay
|
|
||||||
) external onlyTokenHolder returns (uint256 proposalId);
|
|
||||||
|
|
||||||
function signProposal(uint256 proposalId) external onlyTokenHolder;
|
|
||||||
|
|
||||||
function executeProposal(uint256 proposalId) external;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Типы операций
|
|
||||||
- **Управление токенами** - перевод, минтинг, сжигание
|
|
||||||
- **Финансовые операции** - выплата дивидендов, инвестиции
|
|
||||||
- **Emergency действия** - пауза, разморозка, восстановление
|
|
||||||
- **Модульные операции** - добавление/удаление функциональности
|
|
||||||
|
|
||||||
### Безопасность Single-Chain Governance
|
|
||||||
|
|
||||||
#### Требования к безопасности
|
|
||||||
- Участие только верифицированных токен-холдеров
|
|
||||||
- Проверка балансов токенов на момент подписания
|
|
||||||
- Настраиваемый кворум подписей (минимум 51%)
|
|
||||||
- Настраиваемый таймлок для всех операций (кроме emergency)
|
|
||||||
|
|
||||||
#### Механизмы защиты
|
|
||||||
- **Token-holder verification** - только владельцы токенов участвуют
|
|
||||||
- **Balance verification** - проверка баланса при каждой подписи
|
|
||||||
- **Flexible timelock** - инициатор устанавливает задержку
|
|
||||||
- **Governance chain selection** - инициатор устанавливает сеть для голосования
|
|
||||||
- **Atomic execution** - операция выполняется во всех сетях или не выполняется
|
|
||||||
- **Fallback mechanisms** - исполнение в доступных сетях при сбоях
|
|
||||||
|
|
||||||
### Пользовательский интерфейс
|
|
||||||
|
|
||||||
#### Форма мульти-чейн деплоя
|
|
||||||
- Выбор целевых сетей из выпадающего списка
|
|
||||||
- Предварительный расчет стоимости деплоя
|
|
||||||
- Настройки single-chain governance
|
|
||||||
|
|
||||||
#### Создание предложений
|
|
||||||
- Выбор governance сети для голосования
|
|
||||||
- Установка таймлока инициатором
|
|
||||||
- Выбор целевых сетей для исполнения
|
|
||||||
- Описание операции и параметров
|
|
||||||
|
|
||||||
#### Участие в голосовании
|
|
||||||
- Подписание предложений в governance сети
|
|
||||||
- Проверка баланса токенов при подписи
|
|
||||||
- Отображение прогресса сбора подписей
|
|
||||||
- Статус исполнения в целевых сетях
|
|
||||||
|
|
||||||
### Технические требования упрощенной архитектуры
|
|
||||||
- Детерминистический деплой через CREATE2
|
|
||||||
- Single-chain governance для безопасности
|
|
||||||
- Token-holder verification при каждой подписи
|
|
||||||
- Настраиваемые таймлоки для разных типов операций
|
|
||||||
- Атомарное исполнение во всех целевых сетях
|
|
||||||
- Fallback механизмы при недоступности сетей
|
|
||||||
|
|
||||||
## Технические решения
|
|
||||||
|
|
||||||
### ERC-4337 (Account Abstraction) как основа
|
|
||||||
|
|
||||||
#### Концепция
|
|
||||||
ERC-4337 предоставляет стандартную инфраструктуру для смарт-контракт кошельков с универсальностью (один адрес во всех цепочках) и готовыми решениями для оптимизации газа.
|
|
||||||
|
|
||||||
#### Компоненты ERC-4337
|
|
||||||
- **Smart Contract Wallets** — инфраструктура аккаунтов (опционально для UX)
|
|
||||||
- **Bundlers** - оптимизация газа через агрегацию транзакций
|
|
||||||
- **Paymasters** - гибкая оплата транзакций
|
|
||||||
- **Account Abstraction** - универсальность и стандартизация
|
|
||||||
|
|
||||||
#### Преимущества использования ERC-4337
|
|
||||||
- ✅ **Универсальность** - один адрес во всех блокчейнах
|
|
||||||
- ✅ **Готовые решения** - проверенная экосистема
|
|
||||||
- ✅ **Безопасность** - прошедший аудит стандарт
|
|
||||||
- ✅ **Оптимизация** - встроенная экономия газа
|
|
||||||
- ✅ **Совместимость** - стандартные интерфейсы
|
|
||||||
|
|
||||||
### Варианты технической реализации
|
|
||||||
|
|
||||||
#### Вариант 1: Собственный контракт + ERC-4337
|
|
||||||
**Создание собственного DLE контракта с использованием компонентов ERC-4337**
|
|
||||||
|
|
||||||
##### Архитектура:
|
|
||||||
```
|
|
||||||
Собственный DLE контракт
|
|
||||||
├── ERC-4337 компоненты (импорт/наследование)
|
|
||||||
│ ├── Account Abstraction логика
|
|
||||||
│ ├── Bundler совместимость
|
|
||||||
│ └── Paymaster поддержка
|
|
||||||
└── DLE Logic (ваша уникальная логика)
|
|
||||||
├── Governance Token
|
|
||||||
├── Single-Chain Voting System
|
|
||||||
├── Communication
|
|
||||||
├── Treasury
|
|
||||||
└── Multi-Chain Execution
|
|
||||||
```
|
|
||||||
|
|
||||||
### Лицензия ERC-4337
|
|
||||||
ERC-4337 распространяется под лицензией **CC0** (Public Domain), что означает полную свободу использования.
|
|
||||||
|
|
||||||
## Готовые компоненты с аудитом
|
|
||||||
|
|
||||||
### 1. **OpenZeppelin** (аудит: ConsenSys Diligence)
|
|
||||||
- ✅ **ERC-20** - токены управления
|
|
||||||
- ✅ **Governance** - система голосования
|
|
||||||
- ✅ **Access Control** - роли и разрешения
|
|
||||||
(устарело) Multisig — используем голосование токен‑холдеров (ERC20Votes)
|
|
||||||
- ✅ **Timelock** - задержки выполнения
|
|
||||||
|
|
||||||
### 2. **ERC-4337** (аудит: Trail of Bits)
|
|
||||||
- ✅ **Account Abstraction** - универсальность
|
|
||||||
- ✅ **Smart Contract Wallets** - кошельки
|
|
||||||
- ✅ **Bundlers** - оптимизация газа
|
|
||||||
|
|
||||||
### 3. **Проверенные паттерны**
|
|
||||||
- ✅ **Diamond Pattern** (EIP-2535) - модульность
|
|
||||||
- ✅ **Proxy Pattern** - обновляемость
|
|
||||||
- ✅ **Factory Pattern** - создание контрактов
|
|
||||||
|
|
||||||
## Архитектура безопасного контракта DLE
|
|
||||||
|
|
||||||
### **Сборка в один безопасный контракт:**
|
|
||||||
```solidity
|
|
||||||
contract DLE is ERC20, Governor, TimelockController {
|
|
||||||
// Single-chain governance логика
|
|
||||||
// + готовые компоненты с аудитом
|
|
||||||
// + проверенные паттерны
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### **Компоненты для интеграции:**
|
|
||||||
- **ERC-20** - токен управления DLE
|
|
||||||
- **Governor** - система голосования
|
|
||||||
- **TimelockController** - настраиваемые таймлоки
|
|
||||||
- **Account Abstraction** - универсальность адреса
|
|
||||||
|
|
||||||
## Преимущества упрощенного подхода:
|
|
||||||
|
|
||||||
### ✅ **Безопасность**
|
|
||||||
- Все компоненты протестированы и проаудированы
|
|
||||||
- Устранены риски cross-chain мостов
|
|
||||||
- Single-chain governance снижает сложность
|
|
||||||
|
|
||||||
### ✅ **Эффективность**
|
|
||||||
- Использование готовых решений OpenZeppelin
|
|
||||||
- Быстрая разработка с проверенными компонентами
|
|
||||||
- Меньше ошибок благодаря упрощенной архитектуре
|
|
||||||
|
|
||||||
### ✅ **Надежность**
|
|
||||||
- Временем проверенные решения
|
|
||||||
- Простая логика коллективного голосования токен‑холдеров
|
|
||||||
- Понятные механизмы таймлоков
|
|
||||||
|
|
||||||
### ✅ **Совместимость**
|
|
||||||
- Стандартные интерфейсы Ethereum
|
|
||||||
- Совместимость с существующими кошельками
|
|
||||||
- Легкая интеграция с DeFi протоколами
|
|
||||||
|
|
||||||
### Примечание про ERC-4337 (опционально)
|
|
||||||
- Может использоваться в кошельках/окружении для UX (userOps), но не является частью ядра DLE v2.
|
|
||||||
@@ -1,192 +0,0 @@
|
|||||||
# Деплой на VDS - Руководство
|
|
||||||
|
|
||||||
## 📋 Обзор
|
|
||||||
|
|
||||||
Этот документ описывает процесс безопасного деплоя изменений из приватной ветки `private/development` на VDS сервер с сохранением данных пользователей.
|
|
||||||
|
|
||||||
## 🔄 Workflow разработки
|
|
||||||
|
|
||||||
### Структура веток:
|
|
||||||
```
|
|
||||||
🌍 main (публичная) ← Базовый софт для скачивания
|
|
||||||
🔒 private/development (приватная) ← Разработка и тестирование
|
|
||||||
```
|
|
||||||
|
|
||||||
### VDS конфигурация:
|
|
||||||
- **Адрес:** 185.221.214.140
|
|
||||||
- **Пользователь:** root
|
|
||||||
- **Пароль:** [НЕ ХРАНИТЬ В ДОКУМЕНТАЦИИ - использовать переменные окружения]
|
|
||||||
- **Путь:** /home/docker/dapp
|
|
||||||
- **Compose файл:** docker-compose.prod.yml
|
|
||||||
|
|
||||||
## 🛡️ Безопасность данных
|
|
||||||
|
|
||||||
### Docker Volumes (сохраняются при обновлениях):
|
|
||||||
- `postgres_data` - база данных пользователей
|
|
||||||
- `ollama_data` - AI модели
|
|
||||||
- `vector_search_data` - векторные индексы
|
|
||||||
|
|
||||||
### Важно:
|
|
||||||
- Данные пользователей НЕ удаляются при обновлении кода
|
|
||||||
- Volumes остаются неизменными при пересборке контейнеров
|
|
||||||
- Возможен откат к предыдущей версии
|
|
||||||
|
|
||||||
## 🔐 Настройка безопасности
|
|
||||||
|
|
||||||
### Переменные окружения:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Установить пароль VDS (временно)
|
|
||||||
export VDS_PASSWORD="your_vds_password"
|
|
||||||
|
|
||||||
# Или добавить в ~/.bashrc для постоянного использования
|
|
||||||
echo 'export VDS_PASSWORD="your_vds_password"' >> ~/.bashrc
|
|
||||||
source ~/.bashrc
|
|
||||||
```
|
|
||||||
|
|
||||||
### SSH ключи (рекомендуется):
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Создать SSH ключ
|
|
||||||
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
|
|
||||||
|
|
||||||
# Скопировать публичный ключ на VDS
|
|
||||||
ssh-copy-id root@185.221.214.140
|
|
||||||
|
|
||||||
# После этого можно использовать ssh без пароля
|
|
||||||
ssh root@185.221.214.140 "cd /home/docker/dapp && docker compose -f docker-compose.prod.yml ps"
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🚀 Процесс деплоя
|
|
||||||
|
|
||||||
### 1. Подготовка изменений (локально):
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Убедитесь, что находитесь в приватной ветке
|
|
||||||
git checkout private/development
|
|
||||||
|
|
||||||
# Внесите изменения в код
|
|
||||||
# Протестируйте локально
|
|
||||||
./setup.sh
|
|
||||||
|
|
||||||
# Зафиксируйте изменения
|
|
||||||
git add .
|
|
||||||
git commit -m "feat: описание изменений"
|
|
||||||
git push origin private/development
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. Деплой на VDS:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Полный деплой одной командой (используйте переменную окружения для пароля)
|
|
||||||
sshpass -p "$VDS_PASSWORD" ssh -o StrictHostKeyChecking=no root@185.221.214.140 \
|
|
||||||
"cd /home/docker/dapp && git pull origin private/development && docker compose -f docker-compose.prod.yml up -d --build && docker exec dapp-backend yarn migrate"
|
|
||||||
|
|
||||||
# Или используйте SSH ключи (рекомендуется):
|
|
||||||
ssh -o StrictHostKeyChecking=no root@185.221.214.140 \
|
|
||||||
"cd /home/docker/dapp && git pull origin private/development && docker compose -f docker-compose.prod.yml up -d --build && docker exec dapp-backend yarn migrate"
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. Проверка деплоя:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Проверить статус контейнеров
|
|
||||||
sshpass -p "$VDS_PASSWORD" ssh -o StrictHostKeyChecking=no root@185.221.214.140 \
|
|
||||||
"cd /home/docker/dapp && docker compose -f docker-compose.prod.yml ps"
|
|
||||||
|
|
||||||
# Проверить логи
|
|
||||||
sshpass -p "$VDS_PASSWORD" ssh -o StrictHostKeyChecking=no root@185.221.214.140 \
|
|
||||||
"cd /home/docker/dapp && docker compose -f docker-compose.prod.yml logs backend"
|
|
||||||
```
|
|
||||||
|
|
||||||
## 📊 Мониторинг
|
|
||||||
|
|
||||||
### Просмотр логов в реальном времени:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Backend логи
|
|
||||||
sshpass -p "$VDS_PASSWORD" ssh -o StrictHostKeyChecking=no root@185.221.214.140 \
|
|
||||||
"cd /home/docker/dapp && docker compose -f docker-compose.prod.yml logs -f backend"
|
|
||||||
|
|
||||||
# Все логи
|
|
||||||
sshpass -p "$VDS_PASSWORD" ssh -o StrictHostKeyChecking=no root@185.221.214.140 \
|
|
||||||
"cd /home/docker/dapp && docker compose -f docker-compose.prod.yml logs -f"
|
|
||||||
```
|
|
||||||
|
|
||||||
### Проверка использования ресурсов:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
sshpass -p "$VDS_PASSWORD" ssh -o StrictHostKeyChecking=no root@185.221.214.140 \
|
|
||||||
"cd /home/docker/dapp && docker stats --no-stream"
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🔧 Устранение неполадок
|
|
||||||
|
|
||||||
### Если деплой не удался:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Проверить статус
|
|
||||||
sshpass -p "$VDS_PASSWORD" ssh -o StrictHostKeyChecking=no root@185.221.214.140 \
|
|
||||||
"cd /home/docker/dapp && docker compose -f docker-compose.prod.yml ps"
|
|
||||||
|
|
||||||
# Перезапустить сервисы
|
|
||||||
sshpass -p "$VDS_PASSWORD" ssh -o StrictHostKeyChecking=no root@185.221.214.140 \
|
|
||||||
"cd /home/docker/dapp && docker compose -f docker-compose.prod.yml restart"
|
|
||||||
```
|
|
||||||
|
|
||||||
### Откат к предыдущей версии:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Вернуться к предыдущему коммиту
|
|
||||||
sshpass -p "$VDS_PASSWORD" ssh -o StrictHostKeyChecking=no root@185.221.214.140 \
|
|
||||||
"cd /home/docker/dapp && git reset --hard HEAD~1 && docker compose -f docker-compose.prod.yml up -d --build"
|
|
||||||
```
|
|
||||||
|
|
||||||
## 📋 Чек-лист деплоя
|
|
||||||
|
|
||||||
### Перед деплоем:
|
|
||||||
- [ ] Код протестирован локально
|
|
||||||
- [ ] Изменения зафиксированы в `private/development`
|
|
||||||
- [ ] Изменения отправлены в GitHub
|
|
||||||
- [ ] Проверена совместимость схемы БД
|
|
||||||
|
|
||||||
### После деплоя:
|
|
||||||
- [ ] Все контейнеры запущены
|
|
||||||
- [ ] Логи не содержат ошибок
|
|
||||||
- [ ] Приложение доступно по домену
|
|
||||||
- [ ] Данные пользователей сохранены
|
|
||||||
|
|
||||||
## 🔄 Резервное копирование
|
|
||||||
|
|
||||||
### Создание бэкапа перед деплоем:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Создать бэкап базы данных
|
|
||||||
sshpass -p "$VDS_PASSWORD" ssh -o StrictHostKeyChecking=no root@185.221.214.140 \
|
|
||||||
"cd /home/docker/dapp && docker exec dapp-postgres pg_dump -U dapp_user dapp_db > backup_$(date +%Y%m%d_%H%M%S).sql"
|
|
||||||
```
|
|
||||||
|
|
||||||
### Восстановление из бэкапа:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Восстановить базу данных
|
|
||||||
sshpass -p "$VDS_PASSWORD" ssh -o StrictHostKeyChecking=no root@185.221.214.140 \
|
|
||||||
"cd /home/docker/dapp && docker exec -i dapp-postgres psql -U dapp_user dapp_db < backup_YYYYMMDD_HHMMSS.sql"
|
|
||||||
```
|
|
||||||
|
|
||||||
## 📞 Поддержка
|
|
||||||
|
|
||||||
При возникновении проблем:
|
|
||||||
1. Проверьте логи контейнеров
|
|
||||||
2. Убедитесь, что все сервисы запущены
|
|
||||||
3. Проверьте доступность VDS сервера
|
|
||||||
4. При необходимости создайте issue в GitHub
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Автор:** Тарабанов Александр Викторович
|
|
||||||
**Организация:** HB3 Accelerator
|
|
||||||
**Email:** info@hb3-accelerator.com
|
|
||||||
**Сайт:** [hb3-accelerator.com](https://hb3-accelerator.com)
|
|
||||||
|
|
||||||
**© 2024-2025 Тарабанов Александр Викторович. Все права защищены.**
|
|
||||||
@@ -1,123 +0,0 @@
|
|||||||
<!--
|
|
||||||
Copyright (c) 2024-2025 Тарабанов Александр Викторович
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
This software is proprietary and confidential.
|
|
||||||
Unauthorized copying, modification, or distribution is prohibited.
|
|
||||||
|
|
||||||
For licensing inquiries: info@hb3-accelerator.com
|
|
||||||
Website: https://hb3-accelerator.com
|
|
||||||
GitHub: https://github.com/HB3-ACCELERATOR
|
|
||||||
-->
|
|
||||||
|
|
||||||
# Автоматизация публикации локального приложения через SSH-туннель и NGINX
|
|
||||||
|
|
||||||
## Описание задачи
|
|
||||||
|
|
||||||
Необходимо реализовать функционал, позволяющий пользователю локального веб-приложения в один клик опубликовать своё приложение в интернете по собственному домену. Для этого используется внешний сервер (VPS) с белым IP и доменом, на котором автоматически настраиваются:
|
|
||||||
- Установка и настройка NGINX для проксирования домена на SSH-туннель
|
|
||||||
- Выпуск и установка SSL-сертификата (Let's Encrypt)
|
|
||||||
- SSH reverse-туннель с сервера на локальное приложение пользователя
|
|
||||||
- (Опционально) Автоматическая установка NGINX и certbot на сервере по SSH силами локального агента
|
|
||||||
|
|
||||||
Пользователь заполняет форму с необходимыми данными, после чего система автоматически выполняет все шаги по настройке инфраструктуры.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Архитектура решения
|
|
||||||
|
|
||||||
1. **Локальное приложение** работает в Docker-контейнере на ПК пользователя (порт 5173 проброшен наружу).
|
|
||||||
2. **Локальный агент** (Node.js-приложение) устанавливается на ПК пользователя и позволяет фронтенду запускать команды (например, поднять SSH-туннель, а также настраивать NGINX/SSL на сервере по SSH) в один клик.
|
|
||||||
3. **Агент по SSH подключается к серверу (VPS)** и:
|
|
||||||
- Устанавливает NGINX и certbot (если не установлены)
|
|
||||||
- Создаёт или обновляет конфиг NGINX для указанного домена (проксирует на порт 9000)
|
|
||||||
- Перезапускает NGINX
|
|
||||||
- Выпускает SSL-сертификат через certbot
|
|
||||||
- Проверяет доступность домена по HTTPS
|
|
||||||
- Запускает SSH reverse-туннель (9000:localhost:5173)
|
|
||||||
4. **NGINX** на сервере проксирует домен на порт туннеля (9000).
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Необходимые данные для формы
|
|
||||||
|
|
||||||
- Домен (например, myapp.example.com)
|
|
||||||
- Host/IP сервера
|
|
||||||
- Пользователь SSH
|
|
||||||
- SSH-ключ (или пароль)
|
|
||||||
- E-mail для SSL (Let's Encrypt)
|
|
||||||
|
|
||||||
**Поля "Локальный порт приложения", "Порт на сервере для туннеля" и "Порт SSH" скрыты и всегда используются значения по умолчанию:**
|
|
||||||
- Локальный порт: 5173
|
|
||||||
- Порт на сервере: 9000
|
|
||||||
- Порт SSH: 22
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## UX-поток с локальным агентом (финальный порядок)
|
|
||||||
|
|
||||||
1. Пользователь заходит в локальное веб-приложение и заполняет форму публикации (домен, SSH и т.д.).
|
|
||||||
2. Нажимает кнопку "Опубликовать".
|
|
||||||
3. Агент автоматически скачивается, устанавливается и запускается (без дополнительных действий пользователя).
|
|
||||||
4. После запуска агента фронтенд отправляет параметры публикации на локальный агент (порты и порт SSH подставляются автоматически).
|
|
||||||
5. Агент по SSH подключается к серверу и:
|
|
||||||
- Устанавливает NGINX и certbot (если не установлены)
|
|
||||||
- Создаёт или обновляет конфиг NGINX для домена
|
|
||||||
- Перезапускает NGINX
|
|
||||||
- Выпускает SSL-сертификат через certbot
|
|
||||||
- Запускает SSH reverse-туннель (9000:localhost:5173, порт SSH всегда 22)
|
|
||||||
6. После успешного запуска туннеля приложение становится доступно по домену из интернета.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## План выполнения
|
|
||||||
|
|
||||||
### 1. Фронтенд
|
|
||||||
- [ ] Добавить на страницу настроек интерфейса блок "WEB SSH" с кнопкой "Подробнее"
|
|
||||||
- [ ] Создать отдельную страницу
|
|
||||||
- [ ] Реализовать отправку формы на локальный агент (поля с портами и портом SSH скрыты, используются значения по умолчанию)
|
|
||||||
- [ ] После успешной настройки — отобразить пользователю статус публикации с ссылкой на домен
|
|
||||||
|
|
||||||
### 2. Локальный агент
|
|
||||||
- [ ] Реализовать Node.js-приложение (Web SSH Agent), слушающее локальный порт
|
|
||||||
- [ ] API: запуск/остановка SSH-туннеля, статус, логирование
|
|
||||||
- [ ] Автоматическая установка и настройка NGINX, выпуск SSL-сертификата на сервере по SSH
|
|
||||||
- [ ] Безопасность: принимать команды только с localhost, авторизация по токену
|
|
||||||
- [ ] Инструкция по установке для пользователя (Windows, Mac, Linux)
|
|
||||||
- [ ] (Опционально) Автообновление агента
|
|
||||||
|
|
||||||
### 3. Бэкенд (опционально)
|
|
||||||
- [ ] Реализовать API для логирования, аудита, хранения истории публикаций (если требуется)
|
|
||||||
- [ ] Возвращать статус выполнения и сообщения об ошибках (если используется)
|
|
||||||
|
|
||||||
### 4. Инфраструктура/DevOps
|
|
||||||
- [ ] Проверить, что на сервере открыт порт 9000 для туннеля
|
|
||||||
- [ ] Проверить, что домен указывает на сервер
|
|
||||||
- [ ] Проверить, что на сервере установлен NGINX и certbot
|
|
||||||
- [ ] (Опционально) Добавить systemd unit для автозапуска туннеля
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Важные замечания
|
|
||||||
- Для полной автоматизации публикации в один клик требуется локальный агент, который запускает команды на ПК пользователя и может настраивать сервер по SSH.
|
|
||||||
- В браузере без агента можно только сгенерировать команду для ручного запуска SSH-туннеля.
|
|
||||||
- Все действия на сервере должны выполняться только для авторизованных пользователей (лучше — только для админов)
|
|
||||||
- Необходимо реализовать валидацию всех полей формы
|
|
||||||
- **Используется именно проброшенный наружу порт из Docker (5173)**
|
|
||||||
- **Порт SSH всегда 1024 (по умолчанию), пользователь не видит это поле**
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
приложение остаётся локально — туннель обязателен
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Пример команды для SSH-туннеля
|
|
||||||
|
|
||||||
```bash
|
|
||||||
ssh -i /path/to/key -p 22 -R 9000:localhost:5173 user@ваш-сервер
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## С локальным агентом публикация действительно становится "в один клик"!
|
|
||||||
@@ -1,261 +0,0 @@
|
|||||||
<!--
|
|
||||||
Copyright (c) 2024-2025 Тарабанов Александр Викторович
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
This software is proprietary and confidential.
|
|
||||||
Unauthorized copying, modification, or distribution is prohibited.
|
|
||||||
|
|
||||||
For licensing inquiries: info@hb3-accelerator.com
|
|
||||||
Website: https://hb3-accelerator.com
|
|
||||||
GitHub: https://github.com/HB3-ACCELERATOR
|
|
||||||
-->
|
|
||||||
|
|
||||||
# Система очереди AI запросов
|
|
||||||
|
|
||||||
## Обзор
|
|
||||||
|
|
||||||
Система очереди AI запросов предназначена для управления нагрузкой на Ollama и обеспечения стабильной работы AI ассистента. Она предотвращает перегрузку модели, обеспечивает приоритизацию запросов и предоставляет мониторинг производительности.
|
|
||||||
|
|
||||||
## Архитектура
|
|
||||||
|
|
||||||
### Компоненты
|
|
||||||
|
|
||||||
1. **AIQueueService** (`backend/services/ai-queue.js`) - основной сервис очереди
|
|
||||||
2. **AI Queue Routes** (`backend/routes/ai-queue.js`) - API маршруты для управления очередью
|
|
||||||
3. **AIQueueMonitor** (`frontend/src/components/AIQueueMonitor.vue`) - компонент мониторинга
|
|
||||||
4. **Обновленный Chat Route** - поддержка очереди в чате
|
|
||||||
|
|
||||||
### Технологии
|
|
||||||
|
|
||||||
- **better-queue** - библиотека для управления очередью
|
|
||||||
- **Node.js** - серверная часть
|
|
||||||
- **Vue.js** - клиентская часть
|
|
||||||
- **Chart.js** - визуализация статистики
|
|
||||||
|
|
||||||
## Конфигурация очереди
|
|
||||||
|
|
||||||
### Основные параметры
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
{
|
|
||||||
concurrent: 2, // Количество одновременных запросов
|
|
||||||
maxTimeout: 180000, // Максимальное время выполнения (3 мин)
|
|
||||||
afterProcessDelay: 1000, // Задержка между задачами (1 сек)
|
|
||||||
maxRetries: 2, // Максимальное количество повторных попыток
|
|
||||||
retryDelay: 5000 // Задержка между повторными попытками (5 сек)
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Приоритизация
|
|
||||||
|
|
||||||
Система автоматически определяет приоритет задач:
|
|
||||||
|
|
||||||
- **Администраторы**: +10 к приоритету
|
|
||||||
- **Срочные запросы**: +20 к приоритету
|
|
||||||
- **Чат**: +5 к приоритету
|
|
||||||
- **Анализ**: +3 к приоритету
|
|
||||||
- **Генерация**: +1 к приоритету
|
|
||||||
- **Короткие запросы** (<100 символов): +2 к приоритету
|
|
||||||
- **Долгое ожидание** (>30 сек): +5 к приоритету
|
|
||||||
|
|
||||||
## API Endpoints
|
|
||||||
|
|
||||||
### Получение статистики
|
|
||||||
```http
|
|
||||||
GET /api/ai-queue/stats
|
|
||||||
```
|
|
||||||
|
|
||||||
### Добавление задачи в очередь
|
|
||||||
```http
|
|
||||||
POST /api/ai-queue/task
|
|
||||||
Content-Type: application/json
|
|
||||||
|
|
||||||
{
|
|
||||||
"message": "Текст сообщения",
|
|
||||||
"language": "ru",
|
|
||||||
"history": [...],
|
|
||||||
"systemPrompt": "...",
|
|
||||||
"rules": {...},
|
|
||||||
"type": "chat"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Получение статуса задачи
|
|
||||||
```http
|
|
||||||
GET /api/ai-queue/task/:taskId
|
|
||||||
```
|
|
||||||
|
|
||||||
### Управление очередью (только для админов)
|
|
||||||
```http
|
|
||||||
POST /api/ai-queue/control
|
|
||||||
Content-Type: application/json
|
|
||||||
|
|
||||||
{
|
|
||||||
"action": "pause|resume|clear"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Информация о производительности
|
|
||||||
```http
|
|
||||||
GET /api/ai-queue/performance
|
|
||||||
```
|
|
||||||
|
|
||||||
## Использование в чате
|
|
||||||
|
|
||||||
### Обычный режим (без очереди)
|
|
||||||
```http
|
|
||||||
POST /api/chat/message
|
|
||||||
```
|
|
||||||
|
|
||||||
### Режим с очередью
|
|
||||||
```http
|
|
||||||
POST /api/chat/message-queued
|
|
||||||
```
|
|
||||||
|
|
||||||
## Мониторинг
|
|
||||||
|
|
||||||
### Компонент AIQueueMonitor
|
|
||||||
|
|
||||||
Компонент предоставляет:
|
|
||||||
|
|
||||||
- **Статус очереди**: активна, ожидает, пуста, ошибка
|
|
||||||
- **Количество задач**: в очереди и выполняющихся
|
|
||||||
- **Производительность**: успешность, среднее время обработки
|
|
||||||
- **Детальная статистика**: общее количество, ошибки, время
|
|
||||||
- **Управление**: пауза, возобновление, очистка (для админов)
|
|
||||||
- **График производительности**: реальное время
|
|
||||||
|
|
||||||
### Интеграция в интерфейс
|
|
||||||
|
|
||||||
```vue
|
|
||||||
<template>
|
|
||||||
<AIQueueMonitor :isAdmin="userIsAdmin" />
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import AIQueueMonitor from '@/components/AIQueueMonitor.vue'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
components: {
|
|
||||||
AIQueueMonitor
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
```
|
|
||||||
|
|
||||||
## Ограничения и защита
|
|
||||||
|
|
||||||
### Rate Limiting
|
|
||||||
|
|
||||||
- **Ограничение по пользователю**: 10 запросов в минуту
|
|
||||||
- **Размер сообщения**: максимум 10,000 символов
|
|
||||||
- **Валидация**: проверка обязательных полей
|
|
||||||
|
|
||||||
### Фильтрация
|
|
||||||
|
|
||||||
- Проверка формата сообщения
|
|
||||||
- Валидация ID запроса
|
|
||||||
- Проверка размера сообщения
|
|
||||||
- Контроль частоты запросов
|
|
||||||
|
|
||||||
### Слияние задач
|
|
||||||
|
|
||||||
- Объединение одинаковых запросов от одного пользователя
|
|
||||||
- Обновление метаданных при повторных запросах
|
|
||||||
|
|
||||||
## Производительность
|
|
||||||
|
|
||||||
### Оптимизации
|
|
||||||
|
|
||||||
1. **Кэширование**: ответы кэшируются на 5 минут
|
|
||||||
2. **Проверка здоровья**: мониторинг состояния модели
|
|
||||||
3. **Ограничение ресурсов**: Docker контейнер с лимитами
|
|
||||||
4. **Таймауты**: защита от зависших запросов
|
|
||||||
|
|
||||||
### Мониторинг
|
|
||||||
|
|
||||||
- Время обработки запросов
|
|
||||||
- Успешность выполнения
|
|
||||||
- Размер очереди
|
|
||||||
- Количество ошибок
|
|
||||||
- Статистика по пользователям
|
|
||||||
|
|
||||||
## Устранение неполадок
|
|
||||||
|
|
||||||
### Частые проблемы
|
|
||||||
|
|
||||||
1. **Медленные ответы**
|
|
||||||
- Проверить размер очереди
|
|
||||||
- Увеличить количество concurrent задач
|
|
||||||
- Проверить ресурсы Ollama
|
|
||||||
|
|
||||||
2. **Ошибки таймаута**
|
|
||||||
- Увеличить maxTimeout
|
|
||||||
- Проверить состояние модели
|
|
||||||
- Очистить очередь
|
|
||||||
|
|
||||||
3. **Высокая нагрузка**
|
|
||||||
- Уменьшить concurrent задачи
|
|
||||||
- Включить rate limiting
|
|
||||||
- Добавить задержки между задачами
|
|
||||||
|
|
||||||
### Логи
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Просмотр логов очереди
|
|
||||||
docker logs dapp-backend | grep AIQueue
|
|
||||||
|
|
||||||
# Статистика очереди
|
|
||||||
curl http://localhost:8000/api/ai-queue/stats
|
|
||||||
|
|
||||||
# Проверка здоровья
|
|
||||||
curl http://localhost:8000/api/health
|
|
||||||
```
|
|
||||||
|
|
||||||
## Настройка для продакшена
|
|
||||||
|
|
||||||
### Рекомендуемые параметры
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
{
|
|
||||||
concurrent: 1, // Один запрос за раз для стабильности
|
|
||||||
maxTimeout: 300000, // 5 минут таймаут
|
|
||||||
afterProcessDelay: 2000, // 2 секунды между запросами
|
|
||||||
maxRetries: 1, // Одна повторная попытка
|
|
||||||
retryDelay: 10000 // 10 секунд между попытками
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Мониторинг
|
|
||||||
|
|
||||||
- Настройка алертов при высокой нагрузке
|
|
||||||
- Логирование всех операций
|
|
||||||
- Метрики производительности
|
|
||||||
- Автоматическое масштабирование
|
|
||||||
|
|
||||||
### Безопасность
|
|
||||||
|
|
||||||
- Аутентификация для всех endpoints
|
|
||||||
- Авторизация для управления очередью
|
|
||||||
- Валидация всех входных данных
|
|
||||||
- Защита от DDoS атак
|
|
||||||
|
|
||||||
## Разработка
|
|
||||||
|
|
||||||
### Добавление новых типов задач
|
|
||||||
|
|
||||||
1. Обновить функцию `getTaskPriority`
|
|
||||||
2. Добавить обработку в `processTask`
|
|
||||||
3. Обновить документацию
|
|
||||||
|
|
||||||
### Расширение мониторинга
|
|
||||||
|
|
||||||
1. Добавить новые метрики в `getStats`
|
|
||||||
2. Обновить компонент `AIQueueMonitor`
|
|
||||||
3. Добавить новые API endpoints
|
|
||||||
|
|
||||||
### Интеграция с другими сервисами
|
|
||||||
|
|
||||||
1. Подключение к Redis для персистентности
|
|
||||||
2. Интеграция с системами мониторинга
|
|
||||||
3. Подключение к лог-агрегаторам
|
|
||||||
@@ -1,98 +0,0 @@
|
|||||||
# Настройка DNS записей для VDS
|
|
||||||
|
|
||||||
## 🎯 **Цель:**
|
|
||||||
Настроить DNS записи так, чтобы домен указывал на IP адрес VDS сервера.
|
|
||||||
|
|
||||||
## 📋 **Требуемые DNS записи:**
|
|
||||||
|
|
||||||
### **1. A запись (обязательная):**
|
|
||||||
```
|
|
||||||
Тип: A
|
|
||||||
Имя: @ (или пустое)
|
|
||||||
Значение: IP_VDS_СЕРВЕРА
|
|
||||||
TTL: 3600 (или по умолчанию)
|
|
||||||
```
|
|
||||||
|
|
||||||
### **2. CNAME запись (опциональная):**
|
|
||||||
```
|
|
||||||
Тип: CNAME
|
|
||||||
Имя: www
|
|
||||||
Значение: example.com
|
|
||||||
TTL: 3600 (или по умолчанию)
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🔧 **Настройка у разных провайдеров:**
|
|
||||||
|
|
||||||
### **Cloudflare:**
|
|
||||||
1. Заходим в панель Cloudflare
|
|
||||||
2. Выбираем домен
|
|
||||||
3. Переходим в "DNS" → "Records"
|
|
||||||
4. Добавляем A запись:
|
|
||||||
- **Type:** A
|
|
||||||
- **Name:** @
|
|
||||||
- **IPv4 address:** IP_VDS_СЕРВЕРА
|
|
||||||
- **Proxy status:** DNS only (серый облачок)
|
|
||||||
|
|
||||||
### **Reg.ru:**
|
|
||||||
1. Заходим в панель управления
|
|
||||||
2. Выбираем домен
|
|
||||||
3. Переходим в "DNS-записи"
|
|
||||||
4. Добавляем A запись:
|
|
||||||
- **Тип:** A
|
|
||||||
- **Поддомен:** @
|
|
||||||
- **IP-адрес:** IP_VDS_СЕРВЕРА
|
|
||||||
|
|
||||||
### **Namecheap:**
|
|
||||||
1. Заходим в панель управления
|
|
||||||
2. Выбираем домен
|
|
||||||
3. Переходим в "Advanced DNS"
|
|
||||||
4. Добавляем A запись:
|
|
||||||
- **Type:** A Record
|
|
||||||
- **Host:** @
|
|
||||||
- **Value:** IP_VDS_СЕРВЕРА
|
|
||||||
|
|
||||||
## ⏱️ **Время распространения DNS:**
|
|
||||||
|
|
||||||
- **Обычно:** 15-60 минут
|
|
||||||
- **Максимум:** 24-48 часов
|
|
||||||
- **Проверка:** `nslookup example.com` или `dig example.com`
|
|
||||||
|
|
||||||
## 🔍 **Проверка DNS записей:**
|
|
||||||
|
|
||||||
### **Через браузер:**
|
|
||||||
- Откройте `https://dns.google/resolve?name=example.com&type=A`
|
|
||||||
- Проверьте, что в ответе указан IP VDS сервера
|
|
||||||
|
|
||||||
### **Через командную строку:**
|
|
||||||
```bash
|
|
||||||
# Linux/Mac
|
|
||||||
nslookup example.com
|
|
||||||
dig example.com
|
|
||||||
|
|
||||||
# Windows
|
|
||||||
nslookup example.com
|
|
||||||
```
|
|
||||||
|
|
||||||
## ⚠️ **Важные моменты:**
|
|
||||||
|
|
||||||
1. **Убедитесь, что домен активен** и не заблокирован
|
|
||||||
2. **Проверьте, что IP VDS сервера правильный**
|
|
||||||
3. **Дождитесь распространения DNS** перед настройкой VDS
|
|
||||||
4. **Используйте только IP адрес** (не домен) для VDS
|
|
||||||
|
|
||||||
## 🚨 **Частые проблемы:**
|
|
||||||
|
|
||||||
### **DNS не обновляется:**
|
|
||||||
- Проверьте TTL записи (должен быть 300-3600)
|
|
||||||
- Очистите DNS кэш: `ipconfig /flushdns` (Windows)
|
|
||||||
- Подождите до 48 часов
|
|
||||||
|
|
||||||
### **Домен не указывает на VDS:**
|
|
||||||
- Проверьте правильность IP адреса
|
|
||||||
- Убедитесь, что A запись создана для корневого домена (@)
|
|
||||||
- Проверьте, что нет других A записей
|
|
||||||
|
|
||||||
### **Сайт не открывается:**
|
|
||||||
- Убедитесь, что VDS сервер запущен
|
|
||||||
- Проверьте, что порт 80/443 открыт
|
|
||||||
- Проверьте firewall на VDS сервере
|
|
||||||
@@ -1,127 +0,0 @@
|
|||||||
# Миграция Docker образов на VDS
|
|
||||||
|
|
||||||
## 📋 Процесс миграции Docker образов
|
|
||||||
|
|
||||||
### **🎯 Как работает импорт Docker образов:**
|
|
||||||
|
|
||||||
#### **Автоматическая миграция (единственный способ)**
|
|
||||||
1. **Запуск настройки VDS** через форму
|
|
||||||
2. **Автоматический экспорт** образов агентом из локального Docker
|
|
||||||
3. **Автоматическая передача** образов агентом через SCP
|
|
||||||
4. **Автоматический импорт** образов на VDS
|
|
||||||
|
|
||||||
### **🔧 Детальный процесс автоматической миграции:**
|
|
||||||
|
|
||||||
#### **1. Автоматический экспорт ВСЕХ образов приложения (агентом):**
|
|
||||||
```bash
|
|
||||||
# Агент экспортирует ВСЕ образы приложения из локального Docker
|
|
||||||
docker save dapp-postgres:latest -o /tmp/dapp-postgres.tar # PostgreSQL с данными БД
|
|
||||||
docker save dapp-ollama:latest -o /tmp/dapp-ollama.tar # Ollama AI сервис
|
|
||||||
docker save dapp-vector-search:latest -o /tmp/dapp-vector-search.tar # Vector Search
|
|
||||||
docker save dapp-backend:latest -o /tmp/dapp-backend.tar # Backend API
|
|
||||||
docker save dapp-frontend-nginx:latest -o /tmp/dapp-frontend-nginx.tar # Frontend + Nginx
|
|
||||||
docker save dapp-webssh-agent:latest -o /tmp/dapp-webssh-agent.tar # WebSSH Agent
|
|
||||||
|
|
||||||
# Создание архива с ВСЕМИ образами
|
|
||||||
tar -czf /tmp/docker-images.tar.gz dapp-postgres.tar dapp-ollama.tar dapp-vector-search.tar dapp-backend.tar dapp-frontend-nginx.tar dapp-webssh-agent.tar
|
|
||||||
```
|
|
||||||
|
|
||||||
#### **2. Автоматическая передача (агент):**
|
|
||||||
```bash
|
|
||||||
# Передача архива на VDS через SCP
|
|
||||||
scp /tmp/docker-images.tar.gz ubuntu@vds:/home/docker/dapp/docker-images.tar.gz
|
|
||||||
|
|
||||||
# Создание скрипта импорта на VDS
|
|
||||||
# Импорт образов
|
|
||||||
cd /home/docker/dapp && ./import-images.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
#### **3. Импорт образов (на VDS):**
|
|
||||||
```bash
|
|
||||||
#!/bin/bash
|
|
||||||
# Скрипт import-images.sh создается агентом
|
|
||||||
|
|
||||||
# Распаковка архива
|
|
||||||
tar -xzf ./docker-images.tar.gz -C ./temp-images
|
|
||||||
|
|
||||||
# Импорт ВСЕХ образов приложения
|
|
||||||
docker load -i ./temp-images/dapp-postgres.tar # PostgreSQL с данными БД
|
|
||||||
docker load -i ./temp-images/dapp-ollama.tar # Ollama AI сервис
|
|
||||||
docker load -i ./temp-images/dapp-vector-search.tar # Vector Search
|
|
||||||
docker load -i ./temp-images/dapp-backend.tar # Backend API
|
|
||||||
docker load -i ./temp-images/dapp-frontend-nginx.tar # Frontend + Nginx
|
|
||||||
docker load -i ./temp-images/dapp-webssh-agent.tar # WebSSH Agent
|
|
||||||
|
|
||||||
# Очистка временных файлов
|
|
||||||
rm -rf ./temp-images
|
|
||||||
```
|
|
||||||
|
|
||||||
### **📦 Содержимое архива образов:**
|
|
||||||
|
|
||||||
| Образ | Назначение | Размер (примерно) |
|
|
||||||
|-------|------------|-------------------|
|
|
||||||
| `dapp-postgres:latest` | PostgreSQL с данными БД | ~400MB |
|
|
||||||
| `dapp-ollama:latest` | AI модели | ~4GB |
|
|
||||||
| `dapp-vector-search:latest` | Векторный поиск | ~500MB |
|
|
||||||
| `dapp-backend:latest` | Backend API | ~300MB |
|
|
||||||
| `dapp-frontend-nginx:latest` | Frontend + Nginx | ~200MB |
|
|
||||||
| `dapp-webssh-agent:latest` | SSH агент | ~150MB |
|
|
||||||
|
|
||||||
### **⚡ Преимущества автоматической миграции:**
|
|
||||||
|
|
||||||
#### **✅ Скорость:**
|
|
||||||
- **С образами:** ~5-10 минут (включая PostgreSQL с данными)
|
|
||||||
- **Без образов:** ~30-60 минут (сборка на VDS + настройка БД)
|
|
||||||
|
|
||||||
#### **✅ Надежность:**
|
|
||||||
- **PostgreSQL с данными** - все переменные в зашифрованных таблицах
|
|
||||||
- Проверенные образы с локальной машины
|
|
||||||
- Нет риска ошибок сборки на VDS
|
|
||||||
- Быстрое восстановление при сбоях
|
|
||||||
|
|
||||||
#### **✅ Консистентность:**
|
|
||||||
- Одинаковые образы на локальной машине и VDS
|
|
||||||
- **База данных с настройками** - готова к работе
|
|
||||||
- Нет различий в версиях зависимостей
|
|
||||||
|
|
||||||
### **🚨 Важные моменты:**
|
|
||||||
|
|
||||||
#### **Предварительные требования:**
|
|
||||||
1. **Образы должны быть собраны** на локальной машине
|
|
||||||
2. **PostgreSQL образ содержит данные БД** - готовая база с настройками
|
|
||||||
3. **Агент НЕ создает БД** - использует готовую из образа
|
|
||||||
|
|
||||||
#### **Что НЕ нужно делать:**
|
|
||||||
- ❌ Создавать базу данных на VDS
|
|
||||||
- ❌ Восстанавливать данные из бэкапа
|
|
||||||
- ❌ Настраивать таблицы БД
|
|
||||||
- ❌ Импортировать данные вручную
|
|
||||||
3. **VDS должен иметь достаточно места** (минимум 10GB свободного места)
|
|
||||||
|
|
||||||
#### **Если архива нет:**
|
|
||||||
- Агент покажет предупреждение
|
|
||||||
- Образы будут собираться на VDS
|
|
||||||
- Процесс займет больше времени
|
|
||||||
|
|
||||||
### **📝 Логи процесса:**
|
|
||||||
|
|
||||||
#### **Успешная миграция:**
|
|
||||||
```
|
|
||||||
✅ Docker образы переданы на VDS
|
|
||||||
🚀 Импорт Docker образов на VDS...
|
|
||||||
📦 Импорт образа ollama...
|
|
||||||
📦 Импорт образа vector-search...
|
|
||||||
📦 Импорт образа backend...
|
|
||||||
📦 Импорт образа frontend-nginx...
|
|
||||||
📦 Импорт образа webssh-agent...
|
|
||||||
✅ Образы успешно импортированы!
|
|
||||||
```
|
|
||||||
|
|
||||||
#### **Если архива нет:**
|
|
||||||
```
|
|
||||||
⚠️ Локальный архив образов не найден. Образы будут собираться на VDS.
|
|
||||||
ℹ️ Для ускорения процесса выполните: ./scripts/export-images.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
## ✅ **Итог:**
|
|
||||||
**Импорт Docker образов настроен правильно и работает автоматически при наличии архива образов!**
|
|
||||||
@@ -1,211 +0,0 @@
|
|||||||
<!--
|
|
||||||
Copyright (c) 2024-2025 Тарабанов Александр Викторович
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
This software is proprietary and confidential.
|
|
||||||
Unauthorized copying, modification, or distribution is prohibited.
|
|
||||||
|
|
||||||
For licensing inquiries: info@hb3-accelerator.com
|
|
||||||
Website: https://hb3-accelerator.com
|
|
||||||
GitHub: https://github.com/HB3-ACCELERATOR
|
|
||||||
-->
|
|
||||||
|
|
||||||
# Интерактивный обмен веб-страницами с ИИ-ассистентом в корпоративном чате
|
|
||||||
|
|
||||||
## Описание задачи
|
|
||||||
|
|
||||||
Реализовать функционал, позволяющий пользователям создавать веб-страницы с данными о компании, продуктах или статьями (блог), делиться ими в корпоративном чате в виде интерактивных сообщений с кнопками, а также обеспечивать автоматическое добавление этих страниц в базу знаний (RAG) для поиска и генерации ответов ИИ-ассистентом. Страницы должны быть доступны для поиска в интернете по ключевым словам.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Основные требования
|
|
||||||
|
|
||||||
1. **Создание веб-страниц**
|
|
||||||
- Форма на странице `/content` для ввода информации (название, описание, текст, теги, изображения и т.д.).
|
|
||||||
- Возможность предпросмотра и редактирования страницы до публикации.
|
|
||||||
- Кнопка "Поделиться", после нажатия которой страница сохраняется и становится доступной для дальнейших действий.
|
|
||||||
|
|
||||||
2. **Публикация и доступность**
|
|
||||||
- После публикации страница доступна по уникальному URL (например, `/content/page/123` или `/content/page/название`).
|
|
||||||
- Страница оптимизирована для SEO (мета-теги, ЧПУ-адреса, sitemap.xml).
|
|
||||||
- При необходимости — настройка индексации для поисковых систем (robots.txt).
|
|
||||||
- **Оптимизация для ИИ-поиска**: страницы должны быть структурированы и открыты для индексации поисковыми ИИ (Perplexity, GPT, Gemini и др.). Рекомендуется:
|
|
||||||
- Использовать семантическую разметку (schema.org, JSON-LD)
|
|
||||||
- Добавлять структурированные данные (FAQ, Article, Product)
|
|
||||||
- Открывать страницы для crawler-ботов ИИ (не блокировать их в robots.txt)
|
|
||||||
- Обеспечивать чистый, легко читаемый HTML-код
|
|
||||||
- Добавлять релевантные ключевые слова и теги
|
|
||||||
|
|
||||||
3. **Интеграция с корпоративным чатом**
|
|
||||||
- После публикации пользователь может отправить страницу в чат с помощью кнопки "Поделиться в чат".
|
|
||||||
- В чате появляется интерактивное сообщение (карточка) с краткой информацией о странице и кнопкой (например, "Показать содержимое").
|
|
||||||
- При нажатии на кнопку ассистент отправляет содержимое страницы (или его резюме) в чат.
|
|
||||||
- Возможность задать вопрос по содержимому страницы через чат (ассистент ищет ответ только в этой странице).
|
|
||||||
- При публикации страницы в чатах пользователей (веб, Telegram, email) вместе с ответами на сообщения должно автоматически добавляться интерактивное сообщение с заголовком страницы и кнопкой "Подробнее". При нажатии на кнопку ИИ-ассистент отправляет содержимое веб-страницы в чат.
|
|
||||||
|
|
||||||
4. **Интеграция с RAG (Retrieval-Augmented Generation)**
|
|
||||||
- После публикации страница автоматически разбивается на смысловые блоки (например, по абзацам).
|
|
||||||
- Каждый блок векторизуется (создается embedding) и сохраняется в векторное хранилище (Qdrant, Pinecone и т.д.) с метаданными (id страницы, теги, автор, дата).
|
|
||||||
- Ассистент использует эти данные для поиска и генерации ответов на вопросы пользователей.
|
|
||||||
- В форме создания страницы добавить выпадающий список "Интегрировать с RAG" (Да/Нет). При выборе "Да" ИИ-ассистент анализирует содержимое страницы, автоматически предлагает список возможных вопросов и ответов (Q&A) по теме страницы. Пользователь может отредактировать эти вопросы и ответы, отметить чекбоксами нужные и нажать "Добавить" — выбранные Q&A будут сохранены в базу знаний для последующего поиска и генерации ответов.
|
|
||||||
|
|
||||||
5. **Поиск в интернете**
|
|
||||||
- Страницы доступны для индексации поисковыми системами.
|
|
||||||
- Поиск по ключевым словам приводит к отображению соответствующих страниц.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Пользовательские сценарии
|
|
||||||
|
|
||||||
1. **Создание и публикация страницы**
|
|
||||||
- Пользователь заполняет форму на `/content`, нажимает "Поделиться".
|
|
||||||
- Страница сохраняется, появляется уникальный URL.
|
|
||||||
|
|
||||||
2. **Обмен в чате**
|
|
||||||
- Пользователь нажимает "Поделиться в чат".
|
|
||||||
- В чате появляется карточка с кнопкой "Показать содержимое".
|
|
||||||
- Другой пользователь нажимает кнопку — ассистент отправляет содержимое страницы в чат.
|
|
||||||
|
|
||||||
3. **Поиск и ответы ассистента**
|
|
||||||
- Пользователь задаёт вопрос по теме страницы.
|
|
||||||
- Ассистент ищет ответ в RAG по содержимому страницы и формирует релевантный ответ.
|
|
||||||
|
|
||||||
4. **Поиск через интернет**
|
|
||||||
- Внешний пользователь находит страницу через поисковик по ключевым словам.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Техническая реализация
|
|
||||||
|
|
||||||
### Frontend
|
|
||||||
- Vue.js, локальные scoped-стили
|
|
||||||
- Форма создания/редактирования страницы
|
|
||||||
- Компонент карточки для чата с интерактивной кнопкой
|
|
||||||
|
|
||||||
### Backend
|
|
||||||
- Node.js/NestJS/Fastify/Express
|
|
||||||
- REST API для создания, публикации, получения страниц
|
|
||||||
- Векторизация и интеграция с векторным хранилищем (Qdrant, Pinecone)
|
|
||||||
- Генерация и отправка сообщений в чат
|
|
||||||
|
|
||||||
### Векторное хранилище (RAG)
|
|
||||||
- Сохранение embedding-блоков с метаданными
|
|
||||||
- Поиск по embedding для генерации ответов ассистентом
|
|
||||||
|
|
||||||
### SEO и индексация
|
|
||||||
- Генерация мета-тегов, sitemap.xml
|
|
||||||
- ЧПУ-адреса страниц
|
|
||||||
- Настройка robots.txt
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Диаграмма взаимодействия
|
|
||||||
|
|
||||||
```mermaid
|
|
||||||
sequenceDiagram
|
|
||||||
participant User
|
|
||||||
participant Frontend
|
|
||||||
participant Backend
|
|
||||||
participant VectorDB
|
|
||||||
participant Chat
|
|
||||||
participant SearchEngine
|
|
||||||
|
|
||||||
User->>Frontend: Заполняет форму на /content
|
|
||||||
Frontend->>Backend: POST /api/content (данные)
|
|
||||||
Backend->>Backend: Создает страницу, сохраняет в БД
|
|
||||||
Backend->>VectorDB: Векторизация, добавление в RAG
|
|
||||||
Backend->>Frontend: Возвращает ссылку на страницу
|
|
||||||
Frontend->>Chat: Отправляет карточку в чат
|
|
||||||
Chat->>User: Показывает карточку + ответ ассистента
|
|
||||||
SearchEngine->>Backend: Индексирует страницу (если разрешено)
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Примечания
|
|
||||||
- Все компоненты должны быть реализованы с учетом безопасности и приватности данных.
|
|
||||||
- Необходимо предусмотреть возможность удаления и редактирования страниц.
|
|
||||||
- Для интеграции с ИИ-ассистентом использовать современные RAG-фреймворки (LlamaIndex, LangChain и т.д.).
|
|
||||||
- Для векторизации использовать актуальные модели (OpenAI, Sentence Transformers и др.).
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Автоматический выбор и добавление интерактивных сообщений ИИ-ассистентом
|
|
||||||
|
|
||||||
ИИ-ассистент может самостоятельно анализировать контекст диалога и принимать решение о добавлении интерактивных сообщений (карточек) в чат, чтобы повысить релевантность и удобство взаимодействия.
|
|
||||||
|
|
||||||
### Принцип работы
|
|
||||||
|
|
||||||
1. **Анализ контекста диалога**
|
|
||||||
- Ассистент анализирует сообщения пользователя, определяет тему, намерение и ключевые слова.
|
|
||||||
- Выполняет поиск по базе знаний (RAG) для нахождения релевантных страниц или блоков.
|
|
||||||
|
|
||||||
2. **Принятие решения о вставке интерактивного сообщения**
|
|
||||||
- Если найден релевантный контент, ассистент решает, нужно ли добавить карточку с кнопкой (например, "Подробнее").
|
|
||||||
- Решение зависит от:
|
|
||||||
- Тематики и повторяемости вопросов
|
|
||||||
- Новизны или важности контента
|
|
||||||
- Явных триггеров в сообщениях пользователя (например, "покажи инструкцию", "расскажи подробнее" и т.д.)
|
|
||||||
|
|
||||||
3. **Формирование интерактивного сообщения**
|
|
||||||
- Ассистент формирует карточку с заголовком, кратким описанием и кнопкой (например, "Подробнее").
|
|
||||||
- При нажатии на кнопку пользователем ассистент отправляет содержимое страницы или выбранного блока в чат.
|
|
||||||
|
|
||||||
### Пример сценария
|
|
||||||
|
|
||||||
- Пользователь: "Как подключить наш продукт X?"
|
|
||||||
- Ассистент:
|
|
||||||
1. Находит в RAG инструкцию по подключению продукта X.
|
|
||||||
2. Отвечает кратко и автоматически добавляет интерактивную карточку с кнопкой "Показать инструкцию".
|
|
||||||
3. При нажатии на кнопку отправляет подробную инструкцию в чат.
|
|
||||||
|
|
||||||
### Преимущества
|
|
||||||
- Пользователь получает релевантную информацию в нужный момент, не перегружая чат лишними карточками.
|
|
||||||
- Ассистент становится более "умным" и проактивным.
|
|
||||||
- Повышается вовлечённость и удовлетворённость пользователей.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Публикация страниц в социальных сетях и блогах через API
|
|
||||||
|
|
||||||
Система может поддерживать публикацию созданных страниц на страницах компании в социальных сетях и блогах (Medium, LinkedIn, Instagram, Paragraph, Telegraph, Telegram и др.) с помощью соответствующих API.
|
|
||||||
|
|
||||||
### Возможности
|
|
||||||
- Публикация статей и постов на платформах: Medium, LinkedIn (страницы компаний), Instagram (бизнес-аккаунты), Paragraph, Telegraph, Telegram (боты/каналы) и др.
|
|
||||||
- Выбор платформ для публикации пользователем (чекбоксы или список).
|
|
||||||
- Формирование контента с учётом особенностей каждой платформы (текст, изображения, разметка).
|
|
||||||
|
|
||||||
### Принцип работы
|
|
||||||
1. Пользователь выбирает опцию "Опубликовать в соцсетях" после создания страницы.
|
|
||||||
2. Открывается окно выбора платформ и авторизации (OAuth2, если требуется).
|
|
||||||
3. Для каждой платформы формируется подходящий формат контента.
|
|
||||||
4. Система отправляет запросы к API выбранных платформ для публикации.
|
|
||||||
5. Пользователь получает уведомление об успешной публикации или ошибке.
|
|
||||||
|
|
||||||
### Ограничения и нюансы
|
|
||||||
- Для некоторых платформ требуется бизнес-аккаунт и прохождение модерации приложения (LinkedIn, Instagram).
|
|
||||||
- Формат и объём контента может отличаться (например, Instagram — только изображение+текст).
|
|
||||||
- Возможны лимиты на частоту публикаций и размер постов.
|
|
||||||
- Некоторые платформы могут задерживать публикацию для модерации.
|
|
||||||
|
|
||||||
### Пример архитектуры
|
|
||||||
|
|
||||||
```mermaid
|
|
||||||
sequenceDiagram
|
|
||||||
participant User
|
|
||||||
participant Frontend
|
|
||||||
participant Backend
|
|
||||||
participant SocialAPI
|
|
||||||
|
|
||||||
User->>Frontend: Нажимает “Опубликовать в соцсетях”
|
|
||||||
Frontend->>Backend: POST /api/publish-to-social (данные, токены)
|
|
||||||
Backend->>SocialAPI: Публикует на выбранных платформах
|
|
||||||
SocialAPI-->>Backend: Ответ (успех/ошибка)
|
|
||||||
Backend-->>Frontend: Сообщение о результате
|
|
||||||
Frontend-->>User: Уведомление
|
|
||||||
```
|
|
||||||
|
|
||||||
### Рекомендации
|
|
||||||
- Для каждой платформы реализовать отдельный модуль интеграции или использовать сторонние сервисы (Zapier, Make).
|
|
||||||
- Предусмотреть очередь публикаций и логи для отслеживания статуса.
|
|
||||||
- Обеспечить безопасное хранение и обновление токенов авторизации.
|
|
||||||
@@ -1,162 +0,0 @@
|
|||||||
<!--
|
|
||||||
Copyright (c) 2024-2025 Тарабанов Александр Викторович
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
This software is proprietary and confidential.
|
|
||||||
Unauthorized copying, modification, or distribution is prohibited.
|
|
||||||
|
|
||||||
For licensing inquiries: info@hb3-accelerator.com
|
|
||||||
Website: https://hb3-accelerator.com
|
|
||||||
GitHub: https://github.com/HB3-ACCELERATOR
|
|
||||||
-->
|
|
||||||
|
|
||||||
# Техническое задание: Пользовательские таблицы с настраиваемыми связями
|
|
||||||
|
|
||||||
## Цель
|
|
||||||
Реализовать систему пользовательских таблиц, в которых при создании столбца можно настраивать нужные связи (relation/reference/lookup) с другими таблицами.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Основные требования
|
|
||||||
|
|
||||||
1. **Пользователь может создавать любые таблицы** (например, "Клиенты", "Теги", "Продукты", "RAG-таблица" и т.д.).
|
|
||||||
2. **Для каждой таблицы можно добавлять столбцы разных типов:**
|
|
||||||
- text, number, date, select, multiselect
|
|
||||||
- relation/reference (связь с другой таблицей)
|
|
||||||
- lookup (вывод связанных данных из другой таблицы)
|
|
||||||
3. **Для столбцов типа relation/reference:**
|
|
||||||
- Можно выбрать, с какой таблицей и каким полем устанавливается связь
|
|
||||||
- Можно выбрать тип связи: один-к-одному, один-ко-многим, многие-ко-многим
|
|
||||||
- В ячейке такого столбца пользователь может выбрать одну или несколько строк из связанной таблицы
|
|
||||||
4. **Связи хранятся в отдельной таблице связей или в value ячейки (массив id)**
|
|
||||||
5. **В интерфейсе:**
|
|
||||||
- При создании/редактировании столбца типа relation пользователь выбирает таблицу и поле для связи
|
|
||||||
- В таблице, в ячейке relation-столбца, отображается выпадающий список/мультивыбор с данными из связанной таблицы
|
|
||||||
6. **Фильтрация и поиск:**
|
|
||||||
- Можно фильтровать строки по связанным значениям (например, все вопросы, относящиеся к определённому тегу или продукту)
|
|
||||||
7. **Масштабируемость:**
|
|
||||||
- Архитектура должна поддерживать создание большого количества таблиц, столбцов и связей без потери производительности
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Примеры сценариев
|
|
||||||
|
|
||||||
### 1. Связь "Клиент — Теги"
|
|
||||||
- Пользователь создаёт таблицу "Клиенты" и таблицу "Теги"
|
|
||||||
- В таблице "Клиенты" добавляет столбец типа relation, связывающий клиента с одним или несколькими тегами
|
|
||||||
- В каждой строке можно выбрать теги из справочника
|
|
||||||
|
|
||||||
### 2. Связь "Вопрос — Продукты"
|
|
||||||
- В RAG-таблице добавляется столбец типа relation к таблице "Продукты"
|
|
||||||
- Для каждого вопроса можно выбрать, к каким продуктам он относится
|
|
||||||
|
|
||||||
### 3. Lookup-столбец
|
|
||||||
- В таблице "Клиенты" можно добавить lookup-столбец, который автоматически подтягивает связанные значения из другой таблицы (например, список продуктов, которыми пользуется клиент)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Требования к backend
|
|
||||||
- Расширить модели user_tables, user_columns, user_rows, user_cell_values
|
|
||||||
- Добавить таблицу связей (например, table_relations: id, from_row_id, column_id, to_table, to_row_id)
|
|
||||||
- API для создания/редактирования столбцов с типом relation
|
|
||||||
- API для получения и сохранения связей
|
|
||||||
|
|
||||||
## Требования к frontend
|
|
||||||
- UI для выбора типа столбца (relation/reference/lookup)
|
|
||||||
- UI для выбора связанной таблицы и поля
|
|
||||||
- UI для выбора значений в ячейке relation-столбца (выпадающий список, мультивыбор)
|
|
||||||
- Фильтрация и отображение связанных данных
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Преимущества
|
|
||||||
- Максимальная гибкость и масштабируемость
|
|
||||||
- Возможность строить сложные взаимосвязанные базы знаний, CRM, RAG-ассистентов
|
|
||||||
- Удобство для ИИ и аналитики
|
|
||||||
|
|
||||||
## Типы столбцов для пользовательских таблиц
|
|
||||||
|
|
||||||
1. **text** — однострочный текст
|
|
||||||
2. **textarea** — многострочный текст (заметки, описания)
|
|
||||||
3. **number** — число (целое или дробное)
|
|
||||||
4. **date** — дата
|
|
||||||
5. **datetime** — дата и время
|
|
||||||
6. **time** — только время
|
|
||||||
7. **boolean/checkbox** — булево значение (чекбокс)
|
|
||||||
8. **select** — выпадающий список (одиночный выбор)
|
|
||||||
9. **multiselect** — выпадающий список (множественный выбор)
|
|
||||||
10. **file/image** — файл или изображение (загрузка и хранение)
|
|
||||||
11. **relation/reference** — связь с другой таблицей (выбор одной или нескольких строк из другой таблицы)
|
|
||||||
12. **lookup** — автоматический вывод связанных данных из другой таблицы по relation
|
|
||||||
13. **email** — email-адрес с валидацией
|
|
||||||
14. **phone** — телефон с валидацией
|
|
||||||
15. **url** — ссылка/URL с валидацией
|
|
||||||
16. **currency** — число с символом валюты
|
|
||||||
17. **percent** — число с отображением в процентах
|
|
||||||
18. **color** — выбор цвета (colorpicker)
|
|
||||||
19. **user/assignee** — ссылка на пользователя системы (ответственный)
|
|
||||||
20. **status** — список статусов (например, “В работе”, “Готово”)
|
|
||||||
21. **formula** — вычисляемое поле на основе других столбцов
|
|
||||||
22. **progress/rating** — визуальное отображение прогресса, рейтинга (шкала, звёзды)
|
|
||||||
23. **json/object** — хранение структурированных данных (JSON)
|
|
||||||
|
|
||||||
## Плейсхолдеры для интеграции с ИИ-ассистентом
|
|
||||||
|
|
||||||
- Для каждого столбца при создании автоматически генерируется плейсхолдер (placeholder), который можно использовать в промтах и шаблонах для ИИ-ассистента.
|
|
||||||
- Плейсхолдер формируется на основе названия столбца (транслитерация, нижний регистр, замена пробелов на подчёркивания, например: "Партнеры венчурного фонда" → {partners_venchurnogo_fonda}).
|
|
||||||
- Плейсхолдер уникален в рамках таблицы. При совпадении имён добавляется суффикс или используется id столбца.
|
|
||||||
- В таблице user_columns рекомендуется добавить поле placeholder (string, unique).
|
|
||||||
- В интерфейсе при создании/редактировании столбца отображать сгенерированный плейсхолдер (и, при необходимости, давать возможность его редактировать).
|
|
||||||
- В системных промтах и шаблонах для LLM/ассистента значения автоматически подставляются по плейсхолдерам.
|
|
||||||
|
|
||||||
**Пример использования в промте:**
|
|
||||||
```
|
|
||||||
Вопрос: {question}
|
|
||||||
Ответ: {answer}
|
|
||||||
Партнеры: {partners}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Использование плейсхолдеров в системном промте ассистента
|
|
||||||
|
|
||||||
- На странице настроек ассистента (`/settings/ai/assistant`) под полем для системного промта автоматически отображается список всех плейсхолдеров, созданных пользователем в пользовательских таблицах.
|
|
||||||
- Для каждого плейсхолдера показывается:
|
|
||||||
- Сам плейсхолдер (например, `{partners}`)
|
|
||||||
- Название столбца и таблицы, к которому он относится (например, “Партнеры венчурного фонда” — RAG-таблица)
|
|
||||||
- Список плейсхолдеров обновляется автоматически при добавлении/удалении столбцов.
|
|
||||||
|
|
||||||
**Инструкция для пользователя:**
|
|
||||||
> Используйте плейсхолдеры из списка ниже для подстановки значений из пользовательских таблиц в системный промт. Например:
|
|
||||||
> ```
|
|
||||||
> Вопрос: {question}
|
|
||||||
> Ответ: {answer}
|
|
||||||
> Партнеры: {partners}
|
|
||||||
> ```
|
|
||||||
> Плейсхолдеры автоматически заменяются на соответствующие значения при генерации ответа ассистента.
|
|
||||||
|
|
||||||
## Сценарий: добавление тегов пользователю через пользовательские таблицы
|
|
||||||
|
|
||||||
1. **Добавление тега на странице контакта**
|
|
||||||
- На странице контакта (`/contacts/1`) при нажатии на кнопку "Добавить тег" система автоматически создаёт пользовательскую таблицу "Теги клиентов" (если она ещё не создана).
|
|
||||||
- Пользователь может добавить новый тег (например, "VIP", "B2B", "Startup") — он появляется в этой таблице.
|
|
||||||
|
|
||||||
2. **Выпадающий список тегов**
|
|
||||||
- После добавления хотя бы одного тега появляется выпадающий список (или мультивыбор), в котором отображаются все теги из таблицы "Теги клиентов".
|
|
||||||
- Пользователь может выбрать один или несколько тегов для текущего контакта.
|
|
||||||
|
|
||||||
3. **Связь пользователя с тегом**
|
|
||||||
- При выборе тега для пользователя создаётся связь между пользователем и тегом.
|
|
||||||
- Эта связь хранится в отдельной пользовательской таблице (например, `user_tag_links` или универсальной таблице связей), где фиксируется, какой пользователь связан с каким тегом.
|
|
||||||
- Пример структуры таблицы связей:
|
|
||||||
| id | user_id | tag_id |
|
|
||||||
|----|---------|--------|
|
|
||||||
| 1 | 1 | 2 |
|
|
||||||
| 2 | 1 | 3 |
|
|
||||||
|
|
||||||
4. **Обратная связь (теги → пользователи)**
|
|
||||||
- В таблице "Теги клиентов" можно реализовать обратную связь: для каждого тега показывать список пользователей, у которых он установлен (например, через relation/lookup-столбец).
|
|
||||||
|
|
||||||
5. **Итог:**
|
|
||||||
- Пользователь может создавать и редактировать теги.
|
|
||||||
- Для каждого контакта можно выбрать теги из выпадающего списка.
|
|
||||||
- Все связи между пользователями и тегами хранятся в отдельной таблице.
|
|
||||||
- Можно быстро получить список всех пользователей с определённым тегом и наоборот.
|
|
||||||
@@ -1,247 +0,0 @@
|
|||||||
# Процесс настройки VDS агентом
|
|
||||||
|
|
||||||
## 📋 Полная последовательность настройки VDS
|
|
||||||
|
|
||||||
### **🎯 Что делает агент при настройке VDS:**
|
|
||||||
|
|
||||||
#### **1. Создание SSH ключей агентом на хосте (Этап 1-2)**
|
|
||||||
```bash
|
|
||||||
# Агент создает SSH ключи на хосте (не в контейнере!)
|
|
||||||
ssh-keygen -t rsa -b 4096 -C "email@example.com" -f ~/.ssh/id_rsa -N ""
|
|
||||||
|
|
||||||
# Автоматическое исправление прав доступа к SSH конфигу
|
|
||||||
chmod 600 /root/.ssh/config 2>/dev/null || true
|
|
||||||
|
|
||||||
# Установка правильных прав доступа к созданным ключам
|
|
||||||
chmod 600 /root/.ssh/id_rsa
|
|
||||||
chmod 644 /root/.ssh/id_rsa.pub
|
|
||||||
|
|
||||||
# Ключи автоматически доступны в контейнерах через монтирование:
|
|
||||||
# ~/.ssh:/root/.ssh:rw (в docker-compose.yml)
|
|
||||||
|
|
||||||
# Создание директории .ssh для root на VDS
|
|
||||||
sudo mkdir -p /root/.ssh
|
|
||||||
sudo chmod 700 /root/.ssh
|
|
||||||
|
|
||||||
# Добавление публичного ключа в authorized_keys на VDS
|
|
||||||
echo "ssh-rsa AAAAB3NzaC1yc2E..." | sudo tee -a /root/.ssh/authorized_keys
|
|
||||||
sudo chmod 600 /root/.ssh/authorized_keys
|
|
||||||
sudo chown root:root /root/.ssh/authorized_keys
|
|
||||||
```
|
|
||||||
|
|
||||||
**⚠️ Важно:** SSH ключи создаются на хосте и автоматически доступны в контейнерах через монтирование `~/.ssh:/root/.ssh:rw` в docker-compose.yml. Это позволяет SSH Key Server находить ключи для health check.
|
|
||||||
|
|
||||||
#### **2. Создание пользователей БЕЗ паролей (Этап 3-4)**
|
|
||||||
```bash
|
|
||||||
# Создание пользователя Ubuntu БЕЗ пароля
|
|
||||||
sudo useradd -m -s /bin/bash ubuntu
|
|
||||||
sudo usermod -aG sudo ubuntu
|
|
||||||
|
|
||||||
# Создание пользователя Docker БЕЗ пароля
|
|
||||||
sudo useradd -m -s /bin/bash docker
|
|
||||||
sudo usermod -aG sudo docker
|
|
||||||
sudo usermod -aG docker docker
|
|
||||||
|
|
||||||
# Создание директории для приложения
|
|
||||||
sudo mkdir -p /home/docker/dapp
|
|
||||||
sudo chown docker:docker /home/docker/dapp
|
|
||||||
```
|
|
||||||
|
|
||||||
#### **3. Установка Docker и Docker Compose (Этап 5-6)**
|
|
||||||
```bash
|
|
||||||
# Установка Docker
|
|
||||||
curl -fsSL https://get.docker.com -o get-docker.sh
|
|
||||||
sudo sh get-docker.sh
|
|
||||||
sudo usermod -aG docker docker
|
|
||||||
|
|
||||||
# Установка Docker Compose
|
|
||||||
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
|
|
||||||
sudo chmod +x /usr/local/bin/docker-compose
|
|
||||||
```
|
|
||||||
|
|
||||||
#### **4. Настройка firewall (Этап 7)**
|
|
||||||
```bash
|
|
||||||
# Настройка UFW
|
|
||||||
sudo ufw --force enable
|
|
||||||
sudo ufw allow ssh
|
|
||||||
sudo ufw allow 80
|
|
||||||
sudo ufw allow 443
|
|
||||||
```
|
|
||||||
|
|
||||||
#### **5. Сохранение ключа шифрования (Этап 8)**
|
|
||||||
```bash
|
|
||||||
# Создание директории для ключей
|
|
||||||
sudo mkdir -p /home/docker/dapp/ssl/keys
|
|
||||||
|
|
||||||
# Сохранение ключа шифрования
|
|
||||||
echo 'encryption-key-content' | sudo tee /home/docker/dapp/ssl/keys/full_db_encryption.key
|
|
||||||
sudo chmod 600 /home/docker/dapp/ssl/keys/full_db_encryption.key
|
|
||||||
sudo chown docker:docker /home/docker/dapp/ssl/keys/full_db_encryption.key
|
|
||||||
```
|
|
||||||
|
|
||||||
#### **6. Установка Nginx и SSL сертификатов (Этап 9)**
|
|
||||||
```bash
|
|
||||||
# Установка Nginx
|
|
||||||
sudo apt-get install -y nginx
|
|
||||||
sudo systemctl enable nginx
|
|
||||||
|
|
||||||
# Установка Certbot
|
|
||||||
sudo apt-get install -y certbot python3-certbot-nginx
|
|
||||||
|
|
||||||
# Получение SSL сертификата
|
|
||||||
sudo certbot --nginx -d example.com --email admin@example.com --agree-tos --non-interactive
|
|
||||||
```
|
|
||||||
|
|
||||||
#### **7. Создание конфигурации приложения (Этап 9.4-9.5)**
|
|
||||||
```bash
|
|
||||||
# Создание docker-compose.yml
|
|
||||||
cat > /home/docker/dapp/docker-compose.yml << 'EOF'
|
|
||||||
version: '3.8'
|
|
||||||
services:
|
|
||||||
postgres:
|
|
||||||
image: postgres:16-alpine
|
|
||||||
container_name: dapp-postgres
|
|
||||||
restart: unless-stopped
|
|
||||||
environment:
|
|
||||||
- POSTGRES_DB=dapp_db
|
|
||||||
- POSTGRES_USER=dapp_user
|
|
||||||
- POSTGRES_PASSWORD=dapp_password
|
|
||||||
volumes:
|
|
||||||
- postgres_data:/var/lib/postgresql/data
|
|
||||||
|
|
||||||
ollama:
|
|
||||||
image: dapp-ollama:latest
|
|
||||||
container_name: dapp-ollama
|
|
||||||
restart: unless-stopped
|
|
||||||
volumes:
|
|
||||||
- ollama_data:/root/.ollama
|
|
||||||
ports:
|
|
||||||
- "11434:11434"
|
|
||||||
|
|
||||||
vector-search:
|
|
||||||
image: dapp-vector-search:latest
|
|
||||||
container_name: dapp-vector-search
|
|
||||||
restart: unless-stopped
|
|
||||||
ports:
|
|
||||||
- "8080:8080"
|
|
||||||
|
|
||||||
backend:
|
|
||||||
image: dapp-backend:latest
|
|
||||||
container_name: dapp-backend
|
|
||||||
restart: unless-stopped
|
|
||||||
environment:
|
|
||||||
- NODE_ENV=production
|
|
||||||
- PORT=8000
|
|
||||||
- FRONTEND_URL=https://${DOMAIN}
|
|
||||||
depends_on:
|
|
||||||
- postgres
|
|
||||||
- ollama
|
|
||||||
- vector-search
|
|
||||||
|
|
||||||
frontend-nginx:
|
|
||||||
image: dapp-frontend-nginx:latest
|
|
||||||
container_name: dapp-frontend-nginx
|
|
||||||
restart: unless-stopped
|
|
||||||
ports:
|
|
||||||
- "80:80"
|
|
||||||
- "443:443"
|
|
||||||
environment:
|
|
||||||
- DOMAIN=${DOMAIN}
|
|
||||||
- BACKEND_CONTAINER=dapp-backend
|
|
||||||
volumes:
|
|
||||||
- ./ssl:/etc/ssl/certs:ro
|
|
||||||
depends_on:
|
|
||||||
- backend
|
|
||||||
|
|
||||||
volumes:
|
|
||||||
postgres_data:
|
|
||||||
ollama_data:
|
|
||||||
EOF
|
|
||||||
|
|
||||||
# Создание .env файла
|
|
||||||
cat > /home/docker/dapp/.env << EOF
|
|
||||||
DOMAIN=example.com
|
|
||||||
BACKEND_CONTAINER=dapp-backend
|
|
||||||
EOF
|
|
||||||
```
|
|
||||||
|
|
||||||
#### **8. Импорт Docker образов (Этап 10)**
|
|
||||||
```bash
|
|
||||||
# Проверка наличия Docker образов
|
|
||||||
if [ -f /home/docker/dapp/docker-images.tar.gz ]; then
|
|
||||||
echo "Импорт Docker образов..."
|
|
||||||
cd /home/docker/dapp
|
|
||||||
sudo chmod +x import-images.sh
|
|
||||||
./import-images.sh
|
|
||||||
else
|
|
||||||
echo "Docker образы не найдены. Образы будут собираться на VDS."
|
|
||||||
fi
|
|
||||||
```
|
|
||||||
|
|
||||||
#### **9. Запуск приложения (Этап 11-12)**
|
|
||||||
```bash
|
|
||||||
# Запуск приложения
|
|
||||||
cd /home/docker/dapp
|
|
||||||
sudo docker compose up -d
|
|
||||||
|
|
||||||
# Проверка статуса контейнеров
|
|
||||||
sudo docker ps --format "table {{.Names}}\t{{.Status}}"
|
|
||||||
```
|
|
||||||
|
|
||||||
## ✅ **Результат настройки:**
|
|
||||||
|
|
||||||
### **Что получается после настройки:**
|
|
||||||
1. **✅ SSH ключи** созданы агентом автоматически
|
|
||||||
2. **✅ Пользователи Ubuntu и Docker** созданы БЕЗ паролей (только SSH ключи)
|
|
||||||
3. **✅ Docker и Docker Compose** установлены
|
|
||||||
4. **✅ Firewall** настроен (SSH, HTTP, HTTPS)
|
|
||||||
5. **✅ Ключ шифрования** передан с локальной машины
|
|
||||||
6. **✅ Nginx** установлен и настроен
|
|
||||||
7. **✅ SSL сертификат** получен от Let's Encrypt
|
|
||||||
8. **✅ Docker образы** экспортированы и переданы с локальной машины
|
|
||||||
9. **✅ Docker контейнеры** запущены и работают
|
|
||||||
10. **✅ Приложение** доступно по HTTPS
|
|
||||||
|
|
||||||
### **URL приложения:**
|
|
||||||
- **HTTP:** `http://example.com`
|
|
||||||
- **HTTPS:** `https://example.com` ✅ (основной)
|
|
||||||
|
|
||||||
## 🚨 **Важные моменты:**
|
|
||||||
|
|
||||||
### **Предварительные требования:**
|
|
||||||
1. **Домен** должен указывать на IP VDS сервера (A запись)
|
|
||||||
2. **VDS сервер** должен быть доступен по SSH
|
|
||||||
3. **Пользователь** должен иметь права sudo на VDS
|
|
||||||
4. **Порты 80 и 443** должны быть открыты
|
|
||||||
|
|
||||||
### **Что НЕ настраивается агентом:**
|
|
||||||
1. **База данных** - создается при первом запуске контейнеров
|
|
||||||
2. **Данные приложения** - нужно будет восстановить отдельно
|
|
||||||
3. **Резервное копирование** - настраивается отдельно
|
|
||||||
|
|
||||||
## 📝 **Логи настройки:**
|
|
||||||
Агент выводит подробные логи каждого этапа настройки, что позволяет отслеживать прогресс и выявлять проблемы.
|
|
||||||
|
|
||||||
## 🔧 **Исправления SSH проблем (v1.1):**
|
|
||||||
|
|
||||||
### **Проблема:**
|
|
||||||
SSH команды падали с ошибкой `Bad owner or permissions on /root/.ssh/config`, что препятствовало подключению к VDS серверам.
|
|
||||||
|
|
||||||
### **Решение:**
|
|
||||||
1. **Dockerfile:** Добавлено создание SSH конфига с правильными правами доступа (600)
|
|
||||||
2. **SSH утилиты:** Добавлена функция `fixSshPermissions()` для автоматического исправления прав
|
|
||||||
3. **Создание ключей:** Улучшена функция создания SSH ключей с установкой правильных прав доступа
|
|
||||||
4. **Предварительная проверка:** Каждая SSH/SCP команда теперь автоматически исправляет права доступа
|
|
||||||
|
|
||||||
### **Результат:**
|
|
||||||
- ✅ Устранена ошибка "Bad owner or permissions on /root/.ssh/config"
|
|
||||||
- ✅ Повышена надежность SSH подключений
|
|
||||||
- ✅ Автоматическое исправление прав доступа
|
|
||||||
- ✅ Сохранена вся существующая функциональность
|
|
||||||
|
|
||||||
### **Для применения исправлений:**
|
|
||||||
```bash
|
|
||||||
# Пересборка контейнера с исправлениями
|
|
||||||
docker compose build dapp-webssh-agent
|
|
||||||
docker compose restart dapp-webssh-agent
|
|
||||||
```
|
|
||||||
@@ -1,341 +0,0 @@
|
|||||||
# Отчет об ошибках развертывания VDS - Новая сессия
|
|
||||||
|
|
||||||
**Дата:** 3 октября 2025
|
|
||||||
**Время:** 15:11 UTC
|
|
||||||
**VDS IP:** 185.221.214.140
|
|
||||||
**Домен:** hb3-accelerator.com
|
|
||||||
|
|
||||||
## 🎯 Статус развертывания
|
|
||||||
|
|
||||||
### ✅ Успешно выполнено:
|
|
||||||
1. **SSH подключение** - установлено и работает стабильно
|
|
||||||
2. **Системные требования** - проверены и соответствуют
|
|
||||||
3. **Пользователи созданы** - ubuntu, docker с SSH ключами
|
|
||||||
4. **Docker установлен** - версия 28.5.0
|
|
||||||
5. **Docker Compose установлен** - последняя версия
|
|
||||||
6. **fail2ban настроен** - с увеличенными лимитами (maxretry=50, findtime=3600)
|
|
||||||
7. **SSH безопасность** - парольная аутентификация отключена
|
|
||||||
8. **Конфигурационные файлы** - docker-compose.prod.yml и .env переданы
|
|
||||||
9. **Docker образы экспортированы** - все 7 образов (общий размер ~3GB)
|
|
||||||
10. **Docker volumes экспортированы** - postgres_data, ollama_data, vector_search_data
|
|
||||||
11. **Передача данных** - архив 8.5GB успешно передан на VDS
|
|
||||||
12. **Импорт образов** - все Docker образы успешно импортированы
|
|
||||||
13. **Импорт volumes** - все volumes созданы и данные импортированы
|
|
||||||
14. **SSL сертификаты** - скрипт обновления создан
|
|
||||||
15. **PostgreSQL запущен** - база данных принимает подключения
|
|
||||||
|
|
||||||
### ❌ Обнаруженные ошибки:
|
|
||||||
|
|
||||||
## **Ошибка 1: Конфликт имен Docker volumes**
|
|
||||||
|
|
||||||
**Описание:** PostgreSQL использует неправильный volume для данных
|
|
||||||
|
|
||||||
**Симптомы:**
|
|
||||||
- База данных подключена, но пустая
|
|
||||||
- Команда `\dt` возвращает "Did not find any relations"
|
|
||||||
- Обнаружены два volume: `dapp_postgres_data` и `postgres_data`
|
|
||||||
|
|
||||||
**Причина:**
|
|
||||||
- Старый volume `dapp_postgres_data` (с префиксом проекта) содержит данные
|
|
||||||
- Новый volume `postgres_data` (созданный скриптом импорта) пустой
|
|
||||||
- Контейнер PostgreSQL монтирует пустой volume
|
|
||||||
|
|
||||||
**Логи:**
|
|
||||||
```bash
|
|
||||||
# Проверка volumes
|
|
||||||
docker volume ls | grep postgres
|
|
||||||
# Результат:
|
|
||||||
local dapp_postgres_data # ← содержит данные
|
|
||||||
local postgres_data # ← пустой, используется контейнером
|
|
||||||
|
|
||||||
# Проверка базы данных
|
|
||||||
psql -U dapp_user -d dapp_db -c "\dt"
|
|
||||||
# Результат: Did not find any relations
|
|
||||||
```
|
|
||||||
|
|
||||||
**Решение:**
|
|
||||||
1. **Исправить `docker-compose.prod.yml`** - изменить `source: postgres_data` на `source: dapp_postgres_data`
|
|
||||||
2. **Перезапустить PostgreSQL контейнер** - чтобы он использовал правильный volume
|
|
||||||
|
|
||||||
**Команды для исправления:**
|
|
||||||
```bash
|
|
||||||
# Исправить конфигурацию docker-compose
|
|
||||||
cd /home/docker/dapp
|
|
||||||
sed -i 's/source: postgres_data/source: dapp_postgres_data/g' docker-compose.prod.yml
|
|
||||||
|
|
||||||
# Перезапустить контейнер
|
|
||||||
sudo docker compose -f docker-compose.prod.yml restart postgres
|
|
||||||
|
|
||||||
# Проверить базу данных
|
|
||||||
sudo docker compose -f docker-compose.prod.yml exec -T postgres psql -U dapp_user -d dapp_db -c "\dt"
|
|
||||||
```
|
|
||||||
|
|
||||||
**Альтернативное решение (если первое не работает):**
|
|
||||||
```bash
|
|
||||||
# Остановить контейнер
|
|
||||||
sudo docker compose -f docker-compose.prod.yml stop postgres
|
|
||||||
|
|
||||||
# Удалить пустой volume
|
|
||||||
sudo docker volume rm postgres_data
|
|
||||||
|
|
||||||
# Переименовать volume с данными
|
|
||||||
sudo docker volume create postgres_data
|
|
||||||
sudo docker run --rm -v dapp_postgres_data:/source -v postgres_data:/target alpine sh -c "cp -r /source/* /target/"
|
|
||||||
|
|
||||||
# Удалить старый volume
|
|
||||||
sudo docker volume rm dapp_postgres_data
|
|
||||||
|
|
||||||
# Запустить контейнер
|
|
||||||
sudo docker compose -f docker-compose.prod.yml start postgres
|
|
||||||
```
|
|
||||||
|
|
||||||
**Статус исправления:**
|
|
||||||
- ✅ Скрипт импорта исправлен в коде агента
|
|
||||||
- ⚠️ Требуется ручное исправление `docker-compose.prod.yml` на текущей VDS
|
|
||||||
- ⚠️ Требуется перезапуск postgres контейнера после исправления
|
|
||||||
|
|
||||||
## **Ошибка 2: Неправильный импорт данных PostgreSQL**
|
|
||||||
|
|
||||||
**Описание:** Данные PostgreSQL не были правильно импортированы из архива
|
|
||||||
|
|
||||||
**Симптомы:**
|
|
||||||
- База данных подключена, но пустая
|
|
||||||
- Команда `\dt` возвращает "Did not find any relations"
|
|
||||||
- Volume содержит только системные файлы PostgreSQL без пользовательских таблиц
|
|
||||||
|
|
||||||
**Причина:**
|
|
||||||
- Скрипт импорта создал volumes с правильными именами
|
|
||||||
- Но данные не были корректно извлечены из архива `postgres_data.tar.gz`
|
|
||||||
- Volume содержит пустую базу данных PostgreSQL без пользовательских данных
|
|
||||||
|
|
||||||
**Логи:**
|
|
||||||
```bash
|
|
||||||
# Проверка содержимого volume
|
|
||||||
sudo docker run --rm -v postgres_data:/data alpine ls -la /data
|
|
||||||
# Результат: только системные файлы PostgreSQL (PG_VERSION, base/, global/, etc.)
|
|
||||||
# Отсутствуют пользовательские таблицы и данные
|
|
||||||
|
|
||||||
# Проверка базы данных
|
|
||||||
psql -U dapp_user -d dapp_db -c "\dt"
|
|
||||||
# Результат: Did not find any relations
|
|
||||||
```
|
|
||||||
|
|
||||||
**Анализ:**
|
|
||||||
1. **Структура volume корректна** - содержит стандартные файлы PostgreSQL
|
|
||||||
2. **Данные отсутствуют** - нет пользовательских таблиц (email_settings, db_settings, session)
|
|
||||||
3. **Проблема в импорте** - архив `postgres_data.tar.gz` не содержал пользовательские данные или был поврежден
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## **Ошибка 3: Отсутствие crontab на VDS**
|
|
||||||
|
|
||||||
**Описание:** Команда crontab не найдена на VDS сервере
|
|
||||||
|
|
||||||
**Симптомы:**
|
|
||||||
```
|
|
||||||
sudo: crontab: command not found
|
|
||||||
```
|
|
||||||
|
|
||||||
**Причина:** Пакет cron не установлен на минимальном Ubuntu сервере
|
|
||||||
|
|
||||||
**Решение:** Установить cron пакет
|
|
||||||
```bash
|
|
||||||
sudo apt-get update
|
|
||||||
sudo apt-get install -y cron
|
|
||||||
```
|
|
||||||
|
|
||||||
## **Ошибка 4: Отсутствие SSL сертификатов для frontend-nginx**
|
|
||||||
|
|
||||||
**Описание:** Агент не создал SSL сертификаты для домена hb3-accelerator.com
|
|
||||||
|
|
||||||
**Симптомы:**
|
|
||||||
- Контейнер frontend-nginx не может запуститься
|
|
||||||
- Ошибка монтирования: `error mounting "/home/docker/dapp/ssl" to rootfs at "/etc/ssl/certs/fallback": create mountpoint for /etc/ssl/certs/fallback mount: mkdirat`
|
|
||||||
- Сайт hb3-accelerator.com недоступен (ERR_CONNECTION_CLOSED)
|
|
||||||
|
|
||||||
**Причина:**
|
|
||||||
- Агент не выполнил этап создания SSL сертификатов через Certbot
|
|
||||||
- Агент не создал необходимые директории: `/etc/letsencrypt/live/hb3-accelerator.com/` и `/var/www/certbot`
|
|
||||||
- Контейнер frontend-nginx требует SSL сертификаты для запуска
|
|
||||||
|
|
||||||
**Логи:**
|
|
||||||
```
|
|
||||||
Error response from daemon: failed to create task for container: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: error during container init: error mounting "/home/docker/dapp/ssl" to rootfs at "/etc/ssl/certs/fallback": create mountpoint for /etc/ssl/certs/fallback mount: mkdirat /var/lib/docker/overlay2/.../merged/etc/ssl/certs/fallback: read-only file system: unknown
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## **Ошибка 5: Ошибка монтирования SSL сертификатов в frontend-nginx**
|
|
||||||
|
|
||||||
**Описание:** Контейнер frontend-nginx не может запуститься из-за ошибки монтирования SSL сертификатов
|
|
||||||
|
|
||||||
**Симптомы:**
|
|
||||||
- Контейнер frontend-nginx не запускается
|
|
||||||
- Ошибка: `error mounting "/home/docker/dapp/ssl" to rootfs at "/etc/ssl/certs/fallback": create mountpoint for /etc/ssl/certs/fallback mount: mkdirat ... read-only file system: unknown`
|
|
||||||
- Сайт недоступен через домен hb3-accelerator.com
|
|
||||||
|
|
||||||
**Причина:**
|
|
||||||
- Docker не может создать mountpoint `/etc/ssl/certs/fallback` внутри контейнера
|
|
||||||
- Файловая система контейнера read-only в точке монтирования
|
|
||||||
- Конфигурация Docker Compose требует монтирование в недоступную директорию
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## **Ошибка 6: Отсутствие ключа шифрования в backend контейнере**
|
|
||||||
|
|
||||||
**Описание:** Backend контейнер не может выполнять операции шифрования из-за отсутствия ключа шифрования
|
|
||||||
|
|
||||||
**Симптомы:**
|
|
||||||
- Ошибка 401 (Unauthorized) при аутентификации пользователей
|
|
||||||
- Ошибка `pg_base64_decode` в PostgreSQL функции `encrypt_text`
|
|
||||||
- Nonce не сохраняется в базе данных
|
|
||||||
- Функция `encrypt_text` падает на строке 6
|
|
||||||
|
|
||||||
**Причина:**
|
|
||||||
- Ключ шифрования `encryption.key` отсутствует в директории `/app/ssl/keys/` внутри backend контейнера
|
|
||||||
- Директория `/home/docker/dapp/ssl/keys/` на VDS пустая
|
|
||||||
- **Агент ищет ключ в неправильном месте**: `/app/ssl/keys/full_db_encryption.key` (путь внутри Docker контейнера)
|
|
||||||
- **Ключ существует локально**: `/home/alex/Digital_Legal_Entity(DLE)/ssl/keys/full_db_encryption.key`
|
|
||||||
- **Эндпоинт `/vds/transfer-encryption-key` не вызывается**, потому что агент не может найти ключ локально
|
|
||||||
|
|
||||||
**Логи:**
|
|
||||||
```bash
|
|
||||||
# Backend ошибки
|
|
||||||
dapp-backend | error: [verify] Nonce not found for address: 0x15a4ed4759e5762174b300a4cf51cc17ad967f4d
|
|
||||||
dapp-backend | warn: Nonce f303278b09e09c5e2ccbbe4a85f10f8f generated for address 0x15A4ed4759e5762174b300a4Cf51cc17ad967f4d but not saved to DB due to error
|
|
||||||
|
|
||||||
# Проверка ключа на VDS
|
|
||||||
ls -la /home/docker/dapp/ssl/keys/
|
|
||||||
# Результат: директория пустая, нет encryption.key
|
|
||||||
|
|
||||||
# Проверка ключа в контейнере
|
|
||||||
docker compose exec backend ls -la /app/ssl/keys/
|
|
||||||
# Результат: директория пустая, нет encryption.key
|
|
||||||
```
|
|
||||||
|
|
||||||
**Анализ:**
|
|
||||||
1. **Критическая ошибка** - блокирует аутентификацию пользователей
|
|
||||||
2. **Проблема передачи** - агент не передал ключ шифрования на VDS
|
|
||||||
3. **Влияние на функциональность** - без ключа невозможно шифрование данных
|
|
||||||
|
|
||||||
**Решение:**
|
|
||||||
1. **Исправить путь к ключу в агенте** - изменить `/app/ssl/keys/full_db_encryption.key` на `/home/alex/Digital_Legal_Entity(DLE)/ssl/keys/full_db_encryption.key`
|
|
||||||
2. **Перезапустить агент** с исправленным кодом
|
|
||||||
3. **Повторить развертывание** или вызвать эндпоинт `/vds/transfer-encryption-key` вручную
|
|
||||||
4. **Проверить права доступа** к файлу ключа
|
|
||||||
5. **Перезапустить backend контейнер** после передачи ключа
|
|
||||||
|
|
||||||
**Статус исправления:**
|
|
||||||
- ✅ Путь к ключу исправлен в коде агента
|
|
||||||
- ✅ Ключ шифрования передан на VDS через эндпоинт `/vds/transfer-encryption-key`
|
|
||||||
- ✅ Ключ доступен в backend контейнере (`/app/ssl/keys/full_db_encryption.key`)
|
|
||||||
- ✅ Backend перезапущен и загрузил ключ (логи показывают "🔍 Ключ шифрования: установлен")
|
|
||||||
- ✅ **ПРОБЛЕМА РЕШЕНА** - аутентификация должна работать
|
|
||||||
|
|
||||||
## **Ошибка 7: Проблема с сохранением аутентификации в сессию**
|
|
||||||
|
|
||||||
**Описание:** После успешной верификации подписи пользователи не остаются аутентифицированными
|
|
||||||
|
|
||||||
**Симптомы:**
|
|
||||||
- API `/auth/verify` возвращает статус 200 (успех)
|
|
||||||
- Но `/auth/check` показывает `authenticated: false`
|
|
||||||
- Пользователь остается неаутентифицированным
|
|
||||||
- Сессии создаются, но содержат только cookie данные без информации о пользователе
|
|
||||||
|
|
||||||
**Причина:**
|
|
||||||
- После успешной верификации подписи в `/auth/verify` данные пользователя не сохраняются в сессию
|
|
||||||
- Сессия содержит только cookie информацию: `{"cookie":{"originalMaxAge":2592000000,"expires":"2025-11-02T15:14:50.136Z","secure":true,"httpOnly":true,"path":"/","sameSite":"lax"}}`
|
|
||||||
- Отсутствуют данные: `userId`, `address`, `authType`, `telegramId` и т.д.
|
|
||||||
- **Проблема НЕ в CORS** - заголовки добавлены, но данные все равно не сохраняются
|
|
||||||
- **Проблема в коде backend** - логика сохранения данных пользователя в сессию не работает
|
|
||||||
|
|
||||||
**Логи:**
|
|
||||||
```bash
|
|
||||||
# Frontend логи
|
|
||||||
GET /auth/nonce - status 200 ✅
|
|
||||||
POST /auth/verify - status 200 ✅
|
|
||||||
GET /auth/check - status 200, но authenticated: false ❌
|
|
||||||
|
|
||||||
# База данных
|
|
||||||
SELECT sess FROM session WHERE sid = 'w-haDJd23ON18WPF5NaDUP2wB00rqQW4';
|
|
||||||
# Результат: только cookie данные, нет данных пользователя
|
|
||||||
|
|
||||||
# Проверка пользователей
|
|
||||||
SELECT COUNT(*) FROM user_identities; -- 27 записей (пользователи существуют)
|
|
||||||
```
|
|
||||||
|
|
||||||
**Анализ:**
|
|
||||||
1. **Ключ шифрования работает** - верификация подписи успешна
|
|
||||||
2. **База данных содержит пользователей** - 27 записей в user_identities
|
|
||||||
3. **CORS настроен** - заголовки добавлены, но проблема остается
|
|
||||||
4. **Проблема в коде backend** - логика сохранения данных пользователя в сессию не работает
|
|
||||||
5. **Критическая ошибка** - блокирует использование приложения
|
|
||||||
|
|
||||||
**Решение:**
|
|
||||||
1. **✅ CORS настроен в агенте** - добавлена автоматическая настройка CORS заголовков в nginx для будущих развертываний
|
|
||||||
2. **⚠️ Требуется исправление кода backend** - после успешной верификации подписи данные пользователя должны сохраняться в сессию:
|
|
||||||
- `req.session.userId = user.id`
|
|
||||||
- `req.session.address = address`
|
|
||||||
- `req.session.authType = 'wallet'`
|
|
||||||
|
|
||||||
**Статус исправления:**
|
|
||||||
- ✅ CORS заголовки добавлены в nginx на VDS
|
|
||||||
- ✅ CORS настройка добавлена в агент для будущих развертываний
|
|
||||||
- ✅ **ПРОБЛЕМА РЕШЕНА** - исправлены настройки сессии:
|
|
||||||
- `resave: true` (вместо `false`)
|
|
||||||
- `saveUninitialized: false` (вместо `true`)
|
|
||||||
- `secure: false` (вместо `process.env.NODE_ENV === 'production'`)
|
|
||||||
- ✅ **АУТЕНТИФИКАЦИЯ РАБОТАЕТ** - пользователи остаются аутентифицированными
|
|
||||||
|
|
||||||
## **Ошибка 8: Отсутствие UFW на VDS**
|
|
||||||
|
|
||||||
**Описание:** Firewall UFW не установлен на VDS сервере
|
|
||||||
|
|
||||||
**Симптомы:**
|
|
||||||
```
|
|
||||||
sudo: ufw: command not found
|
|
||||||
```
|
|
||||||
|
|
||||||
**Причина:** UFW не включен в минимальную установку Ubuntu
|
|
||||||
|
|
||||||
**Решение:** Установить UFW или использовать iptables
|
|
||||||
```bash
|
|
||||||
sudo apt-get install -y ufw
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🔧 Рекомендации по исправлению
|
|
||||||
|
|
||||||
### Приоритет 1 (Критично):
|
|
||||||
1. **Передать ключ шифрования** - отсутствие ключа блокирует аутентификацию
|
|
||||||
2. **Исправить импорт данных PostgreSQL** - данные не были правильно импортированы из архива
|
|
||||||
3. **Проверить целостность архива** - убедиться, что архив содержит пользовательские данные
|
|
||||||
|
|
||||||
### Приоритет 2 (Важно):
|
|
||||||
4. **Установить cron** - для автоматического обновления SSL
|
|
||||||
5. **Установить UFW** - для настройки firewall
|
|
||||||
|
|
||||||
### Приоритет 3 (Желательно):
|
|
||||||
6. **Оптимизировать скрипт импорта** - исправить логику создания volumes
|
|
||||||
7. **Добавить проверку целостности** - после импорта данных
|
|
||||||
|
|
||||||
## 📊 Общая статистика
|
|
||||||
|
|
||||||
- **Всего этапов:** 20
|
|
||||||
- **Успешно выполнено:** 15 (75%)
|
|
||||||
- **Ошибки:** 7 (35%)
|
|
||||||
- **Критические ошибки:** 5 (25%)
|
|
||||||
- **Время выполнения:** ~45 минут
|
|
||||||
- **Размер переданных данных:** 8.5GB
|
|
||||||
|
|
||||||
## 🎯 Заключение
|
|
||||||
|
|
||||||
Развертывание VDS прошло **успешно на 75%**. Основные компоненты работают:
|
|
||||||
- ✅ Docker и контейнеры запущены
|
|
||||||
- ✅ Сеть настроена
|
|
||||||
- ✅ Безопасность настроена
|
|
||||||
- ✅ SSL сертификаты настроены
|
|
||||||
- ❌ **База данных требует исправления volume**
|
|
||||||
|
|
||||||
**Главная проблема:** Данные PostgreSQL не были правильно импортированы из архива. Volume содержит только системные файлы PostgreSQL без пользовательских таблиц.
|
|
||||||
|
|
||||||
**Корневая причина:** Архив `postgres_data.tar.gz` не содержал пользовательские данные или был поврежден при экспорте/импорте.
|
|
||||||
@@ -1,500 +0,0 @@
|
|||||||
# Отчет по ошибкам развертывания на VDS
|
|
||||||
|
|
||||||
## 📋 Обзор
|
|
||||||
|
|
||||||
Документ содержит полный список ошибок, обнаруженных при развертывании приложения Digital Legal Entity на VDS сервере `185.221.214.140`.
|
|
||||||
|
|
||||||
## 🚨 Обнаруженные ошибки
|
|
||||||
|
|
||||||
### 1. HTTP ERROR 503 - Service Unavailable
|
|
||||||
|
|
||||||
**Описание:** При обращении к `http://185.221.214.140` возвращается ошибка 503.
|
|
||||||
|
|
||||||
**Детали:**
|
|
||||||
- Системный nginx уже запущен на портах 80/443
|
|
||||||
- Наш `dapp-frontend-nginx` пытается занять те же порты
|
|
||||||
- Контейнеры запускаются, но недоступны извне
|
|
||||||
|
|
||||||
**Логи ошибок:**
|
|
||||||
```
|
|
||||||
Error response from daemon: failed to set up container networking:
|
|
||||||
driver failed programming external connectivity on endpoint dapp-frontend-nginx:
|
|
||||||
failed to bind host port for 0.0.0.0:80:172.18.0.7:80/tcp: address already in use
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. Конфликт портов nginx
|
|
||||||
|
|
||||||
**Проблема:** Два nginx сервера пытаются использовать одни порты.
|
|
||||||
|
|
||||||
**Системный nginx:**
|
|
||||||
- Установлен в системе Linux
|
|
||||||
- Занимает порты 80 (HTTP) и 443 (HTTPS)
|
|
||||||
- Статус: `nginx: master process`
|
|
||||||
|
|
||||||
**Наш frontend-nginx:**
|
|
||||||
- Docker контейнер `dapp-frontend-nginx`
|
|
||||||
- Пытается занять порты 80/443
|
|
||||||
- Статус: не может запуститься
|
|
||||||
|
|
||||||
### 3. Проблемы с health checks
|
|
||||||
|
|
||||||
**Vector Search контейнер:**
|
|
||||||
- Статус: `unhealthy`
|
|
||||||
- Причина: health check endpoint недоступен
|
|
||||||
- Влияние: блокирует запуск зависимых сервисов
|
|
||||||
|
|
||||||
**Backend контейнер:**
|
|
||||||
- Статус: `health: starting`
|
|
||||||
- Зависит от vector-search
|
|
||||||
- Не запускается из-за failed dependencies
|
|
||||||
|
|
||||||
### 4. Ошибки конфигурации nginx в контейнере
|
|
||||||
|
|
||||||
**Frontend-nginx контейнер:**
|
|
||||||
- Статус: `Restarting (1)`
|
|
||||||
- Ошибка: `invalid number of arguments in "server_name" directive in /etc/nginx/nginx.conf:37`
|
|
||||||
- Причина: неправильная конфигурация nginx внутри контейнера
|
|
||||||
|
|
||||||
**Логи ошибок:**
|
|
||||||
```
|
|
||||||
2025/10/03 06:02:15 [emerg] 1#1: invalid number of arguments in "server_name" directive in /etc/nginx/nginx.conf:37
|
|
||||||
nginx: [emerg] invalid number of arguments in "server_name" directive in /etc/nginx/nginx.conf:37
|
|
||||||
```
|
|
||||||
|
|
||||||
### 5. Проблемы с системным nginx
|
|
||||||
|
|
||||||
**Ошибка запуска:**
|
|
||||||
- Команда: `systemctl restart nginx`
|
|
||||||
- Результат: `Job for nginx.service failed because the control process exited with error code`
|
|
||||||
|
|
||||||
**Логи ошибок:**
|
|
||||||
```
|
|
||||||
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
|
|
||||||
nginx: [emerg] bind() to 0.0.0.0:443 failed (98: Address already in use)
|
|
||||||
nginx: [emerg] still could not bind()
|
|
||||||
```
|
|
||||||
|
|
||||||
### 6. Ошибки подключения к базе данных
|
|
||||||
|
|
||||||
**Backend контейнер:**
|
|
||||||
- Ошибка: `SASL: SCRAM-SERVER-FIRST-MESSAGE: client password must be a string`
|
|
||||||
- Причина: неправильная передача пароля для PostgreSQL
|
|
||||||
- Влияние: backend не может подключиться к базе данных
|
|
||||||
|
|
||||||
**Логи ошибок:**
|
|
||||||
```
|
|
||||||
Ошибка подключения к базе данных: Error: SASL: SCRAM-SERVER-FIRST-MESSAGE: client password must be a string
|
|
||||||
at /app/node_modules/pg-pool/index.js:45:11
|
|
||||||
```
|
|
||||||
|
|
||||||
### 7. Ошибки YAML синтаксиса в docker-compose.yml
|
|
||||||
|
|
||||||
**Проблема:** Неправильный формат переменных окружения в docker-compose.yml
|
|
||||||
|
|
||||||
**Ошибки:**
|
|
||||||
```
|
|
||||||
yaml: line 20: did not find expected '-' indicator
|
|
||||||
yaml: line 20: did not find expected key
|
|
||||||
```
|
|
||||||
|
|
||||||
**Причина:** Смешанный формат переменных окружения:
|
|
||||||
- В секции postgres: `- KEY=value` (неправильно)
|
|
||||||
- В секции backend: `- KEY=value` (правильно для backend)
|
|
||||||
|
|
||||||
### 8. Отсутствующие таблицы в базе данных
|
|
||||||
|
|
||||||
**Backend контейнер:**
|
|
||||||
- Ошибка: `relation "email_settings" does not exist`
|
|
||||||
- Ошибка: `relation "db_settings" does not exist`
|
|
||||||
- Ошибка: `relation "session" does not exist`
|
|
||||||
|
|
||||||
**Логи ошибок:**
|
|
||||||
```
|
|
||||||
error: Unhandled Rejection: relation "email_settings" does not exist {"code":"42P01"}
|
|
||||||
error: [DatabaseConnectionManager] Ошибка инициализации: relation "db_settings" does not exist {"code":"42P01"}
|
|
||||||
error: Unhandled Rejection: relation "session" does not exist {"code":"42P01"}
|
|
||||||
```
|
|
||||||
|
|
||||||
**Диагностика базы данных:**
|
|
||||||
```
|
|
||||||
docker exec dapp-postgres psql -U dapp_user -d dapp_db -c '\dt'
|
|
||||||
Did not find any relations.
|
|
||||||
```
|
|
||||||
|
|
||||||
**Причина:** База данных полностью пустая - отсутствует схема и все таблицы
|
|
||||||
|
|
||||||
**Влияние:** Backend не может полностью инициализироваться, API недоступен
|
|
||||||
|
|
||||||
### 9. Проблемы с пробросом портов
|
|
||||||
|
|
||||||
**Frontend контейнер:**
|
|
||||||
- Порт 5173 не проброшен наружу
|
|
||||||
- Контейнер запущен, но недоступен извне
|
|
||||||
- Статус: `Up (health: starting)`
|
|
||||||
|
|
||||||
**Frontend-nginx контейнер:**
|
|
||||||
- Порт 9000 не проброшен наружу
|
|
||||||
- Контейнер не запускается из-за конфликтов
|
|
||||||
|
|
||||||
### 10. Проблемы с переменными окружения
|
|
||||||
|
|
||||||
**Отсутствующие переменные в .env:**
|
|
||||||
- `DB_NAME`, `DB_USER`, `DB_PASSWORD`
|
|
||||||
- `NODE_ENV`, `PORT`
|
|
||||||
- `OLLAMA_MODEL`, `OLLAMA_EMBEDDINGS_MODEL`
|
|
||||||
|
|
||||||
**Неправильная передача в docker-compose.yml:**
|
|
||||||
- Переменные не передаются в контейнеры
|
|
||||||
- Backend использует "дефолтные настройки подключения к БД"
|
|
||||||
|
|
||||||
### 11. Отсутствие миграций базы данных
|
|
||||||
|
|
||||||
**Проблема:** Схема базы данных не создается автоматически
|
|
||||||
|
|
||||||
**Найденные файлы:**
|
|
||||||
- `./backend/scripts/run-migrations.js` - скрипт для запуска миграций
|
|
||||||
- Скрипт ищет SQL файлы в `./backend/db/migrations/`
|
|
||||||
|
|
||||||
**Диагностика:**
|
|
||||||
```
|
|
||||||
find ./backend -name "*.sql" -o -name "*schema*" -o -name "*migration*"
|
|
||||||
# Результат: только node_modules файлы, нет SQL миграций
|
|
||||||
```
|
|
||||||
|
|
||||||
**Причина:** Отсутствуют файлы миграций для создания схемы базы данных
|
|
||||||
|
|
||||||
**Влияние:** База данных остается пустой, backend не может инициализироваться
|
|
||||||
|
|
||||||
### 12. Проверка ключа шифрования
|
|
||||||
|
|
||||||
**Статус ключа шифрования:**
|
|
||||||
- **Локальный ключ:** `MsPbvDsNXra/kqw4XgnaustFDcuuSvZY1TwhYrpxMnE=`
|
|
||||||
- **Ключ на VDS:** `MsPbvDsNXra/kqw4XgnaustFDcuuSvZY1TwhYrpxMnE=`
|
|
||||||
- **Статус:** Ключи идентичны, передача корректна
|
|
||||||
|
|
||||||
**Монтирование в контейнер:**
|
|
||||||
- Ключ доступен в `/app/ssl/full_db_encryption.key`
|
|
||||||
- Права доступа: `-rw------- 1 root root 45`
|
|
||||||
|
|
||||||
**Вывод:** Проблема не в ключе шифрования
|
|
||||||
|
|
||||||
## 📊 Статистика ошибок
|
|
||||||
|
|
||||||
### По типам:
|
|
||||||
- **База данных:** 4 ошибки (отсутствие схемы, миграций, таблиц)
|
|
||||||
- **Конфигурация nginx:** 3 ошибки
|
|
||||||
- **Проблемы с портами:** 2 ошибки
|
|
||||||
- **Docker Compose:** 2 ошибки
|
|
||||||
- **Health checks:** 1 ошибка
|
|
||||||
|
|
||||||
### По критичности:
|
|
||||||
- **Критические:** 5 ошибок (блокируют работу приложения)
|
|
||||||
- **Серьезные:** 5 ошибок (влияют на функциональность)
|
|
||||||
- **Предупреждения:** 2 ошибки (не блокируют, но требуют внимания)
|
|
||||||
|
|
||||||
## 🔍 Диагностические данные
|
|
||||||
|
|
||||||
### Статус контейнеров:
|
|
||||||
```
|
|
||||||
NAMES STATUS PORTS
|
|
||||||
dapp-frontend-nginx Restarting (1) 11 seconds ago
|
|
||||||
dapp-frontend Up 25 seconds (health: starting) 5173/tcp
|
|
||||||
dapp-backend Up 12 minutes (unhealthy) 0.0.0.0:8000->8000/tcp
|
|
||||||
dapp-vector-search Up 12 minutes (unhealthy) 8001/tcp
|
|
||||||
dapp-postgres Up 12 minutes (healthy) 5432/tcp
|
|
||||||
dapp-ollama Up 12 minutes (healthy) 11434/tcp
|
|
||||||
```
|
|
||||||
|
|
||||||
### Занятые порты:
|
|
||||||
```
|
|
||||||
tcp 0 0 0.0.0.0:443 0.0.0.0:* LISTEN 12785/nginx: master
|
|
||||||
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 12785/nginx: master
|
|
||||||
tcp 0 0 0.0.0.0:8000 0.0.0.0:* LISTEN 40287/docker-proxy
|
|
||||||
```
|
|
||||||
|
|
||||||
### Процессы nginx:
|
|
||||||
```
|
|
||||||
root 12785 0.0 0.1 35468 9160 ? Ss Oct02 0:00 nginx: master process nginx -c /etc/nginx/nginx.conf
|
|
||||||
www-data 32875 0.0 0.1 36820 11032 ? S 05:11 0:00 nginx: worker process
|
|
||||||
www-data 32876 0.0 0.1 36820 10904 ? S 05:11 0:00 nginx: worker process
|
|
||||||
www-data 32877 0.0 0.1 36820 10776 ? S 05:11 0:00 nginx: worker process
|
|
||||||
www-data 32878 0.0 0.1 36820 10648 ? S 05:11 0:00 nginx: worker process
|
|
||||||
```
|
|
||||||
|
|
||||||
## 📝 Заключение
|
|
||||||
|
|
||||||
Обнаружено **20 различных типов ошибок** при развертывании приложения на VDS сервере. Основные проблемы связаны с:
|
|
||||||
|
|
||||||
1. **Отсутствием схемы базы данных** - база полностью пустая, нет таблиц и миграций
|
|
||||||
2. **Конфликтами портов** между системным и контейнерным nginx
|
|
||||||
3. **Неправильной конфигурацией** docker-compose.yml и переменных окружения
|
|
||||||
4. **Проблемами с health checks** и зависимостями между сервисами
|
|
||||||
|
|
||||||
**Ключевая проблема:** Данные PostgreSQL импортированы в volume с неправильным именем. Контейнер читает из пустой базы данных, хотя данные есть в другом volume.
|
|
||||||
|
|
||||||
**РЕШЕНО:**
|
|
||||||
- База данных восстановлена, содержит 37 таблиц
|
|
||||||
- Backend подключается к базе данных
|
|
||||||
- AI сервис (Ollama) работает корректно
|
|
||||||
- Все основные сервисы функционируют
|
|
||||||
|
|
||||||
**Ключ шифрования:** Передан корректно, проблема не в нем.
|
|
||||||
|
|
||||||
## Error 13: Проверка целостности архива данных
|
|
||||||
|
|
||||||
**Описание:** Проверка целостности архива `docker-images-and-data.tar.gz` на VDS.
|
|
||||||
|
|
||||||
**Детали:**
|
|
||||||
- Размер архива: 8.4GB
|
|
||||||
- Команда `tar -tf` не возвращала содержимое
|
|
||||||
- Подозрение на повреждение архива
|
|
||||||
- Проверка: `tar -xzf docker-images-and-data.tar.gz -C test-extract/`
|
|
||||||
- Результат: Архив успешно распакован
|
|
||||||
|
|
||||||
**Содержимое архива:**
|
|
||||||
- Docker образы: 7 файлов (dapp-backend.tar, dapp-frontend.tar, dapp-frontend-nginx.tar, dapp-ollama.tar, dapp-postgres.tar, dapp-vector-search.tar, dapp-webssh-agent.tar)
|
|
||||||
- Данные volumes: 3 файла (ollama_data.tar.gz, postgres_data.tar.gz, vector_search_data.tar.gz)
|
|
||||||
|
|
||||||
**Влияние:** Критическое - без корректного архива невозможно восстановить данные приложения.
|
|
||||||
|
|
||||||
**Статус:** ✅ РЕШЕНО - архив целый и содержит все необходимые данные.
|
|
||||||
|
|
||||||
## Error 14: Несоответствие имен Docker volumes
|
|
||||||
|
|
||||||
**Описание:** Данные PostgreSQL импортированы в volume с неправильным именем.
|
|
||||||
|
|
||||||
**Детали:**
|
|
||||||
- Скрипт импорта создает volume: `digital_legal_entitydle_postgres_data`
|
|
||||||
- Контейнер PostgreSQL использует volume: `dapp_postgres_data`
|
|
||||||
- Данные находятся в правильном volume, но контейнер читает из пустого
|
|
||||||
- Проверка: `docker inspect dapp-postgres | grep Mounts`
|
|
||||||
- Результат: Контейнер монтирует `dapp_postgres_data`, а данные в `digital_legal_entitydle_postgres_data`
|
|
||||||
|
|
||||||
**Содержимое volumes:**
|
|
||||||
- `dapp_postgres_data`: пустая база данных (только системные файлы)
|
|
||||||
- `digital_legal_entitydle_postgres_data`: содержит базы данных (директории 1, 4, 5, 16384)
|
|
||||||
|
|
||||||
**Влияние:** Критическое - backend не может найти таблицы, так как читает из пустой базы данных.
|
|
||||||
|
|
||||||
**Статус:** ✅ РЕШЕНО - данные скопированы в правильный volume, база данных восстановлена.
|
|
||||||
|
|
||||||
**Решение:**
|
|
||||||
1. Остановлен и удален контейнер PostgreSQL
|
|
||||||
2. Удален пустой volume `dapp_postgres_data`
|
|
||||||
3. Скопированы данные из `digital_legal_entitydle_postgres_data` в `dapp_postgres_data`
|
|
||||||
4. Запущен новый контейнер PostgreSQL с правильным volume
|
|
||||||
5. Проверено: база данных `dapp_db` содержит 37 таблиц, включая `email_settings`, `db_settings`, `session`
|
|
||||||
|
|
||||||
## Error 15: Контейнеры в разных Docker сетях
|
|
||||||
|
|
||||||
**Описание:** Backend не может подключиться к PostgreSQL из-за разных Docker сетей.
|
|
||||||
|
|
||||||
**Детали:**
|
|
||||||
- `dapp-backend` находится в сети `dapp_default`
|
|
||||||
- `dapp-postgres` находится в сети `bridge`
|
|
||||||
- Backend пытается подключиться к хосту `postgres`, но не может его найти
|
|
||||||
- Ошибка: `getaddrinfo EAI_AGAIN postgres`
|
|
||||||
|
|
||||||
**Влияние:** Критическое - backend не может подключиться к базе данных.
|
|
||||||
|
|
||||||
**Статус:** 🔄 В ПРОЦЕССЕ - требуется подключение контейнеров к одной сети.
|
|
||||||
|
|
||||||
## Error 16: Неправильное имя хоста в переменных окружения
|
|
||||||
|
|
||||||
**Описание:** Backend ищет хост `postgres`, но контейнер называется `dapp-postgres`.
|
|
||||||
|
|
||||||
**Детали:**
|
|
||||||
- Переменная окружения: `DB_HOST=postgres`
|
|
||||||
- Реальное имя контейнера: `dapp-postgres`
|
|
||||||
- Контейнеры подключены к одной сети `dapp_default`
|
|
||||||
- Сетевое соединение работает (ping успешен)
|
|
||||||
- Проблема в DNS разрешении имени `postgres`
|
|
||||||
|
|
||||||
**Влияние:** Критическое - backend не может найти PostgreSQL по имени хоста.
|
|
||||||
|
|
||||||
**Статус:** ✅ РЕШЕНО - backend перезапущен с правильной переменной окружения `DB_HOST=dapp-postgres`.
|
|
||||||
|
|
||||||
**Решение:**
|
|
||||||
1. Остановлен и удален старый контейнер backend
|
|
||||||
2. Запущен новый контейнер с правильными переменными окружения
|
|
||||||
3. Проверено: API отвечает, база данных подключена
|
|
||||||
|
|
||||||
## Error 17: Проблема с расшифровкой данных
|
|
||||||
|
|
||||||
**Описание:** Ошибка расшифровки base64 данных в базе данных.
|
|
||||||
|
|
||||||
**Детали:**
|
|
||||||
- Ошибка: `invalid symbol "-" found while decoding base64 sequence`
|
|
||||||
- Проблема в функции `decrypt_text` PostgreSQL
|
|
||||||
- Данные в базе зашифрованы, но ключ шифрования не подходит
|
|
||||||
- Влияет на EmailBotService и DbSettingsService
|
|
||||||
|
|
||||||
**Влияние:** Среднее - некоторые функции могут не работать из-за проблем с расшифровкой.
|
|
||||||
|
|
||||||
**Статус:** 🔄 В ПРОЦЕССЕ - требуется проверка ключа шифрования.
|
|
||||||
|
|
||||||
## Error 18: AI сервис недоступен
|
|
||||||
|
|
||||||
**Описание:** Ollama сервис не отвечает на запросы.
|
|
||||||
|
|
||||||
**Детали:**
|
|
||||||
- Health check: AI сервис возвращает ошибку
|
|
||||||
- URL: `http://localhost:11434`
|
|
||||||
- Ошибка: `fetch failed`
|
|
||||||
- Vector Search работает корректно
|
|
||||||
|
|
||||||
**Влияние:** Среднее - AI функции недоступны.
|
|
||||||
|
|
||||||
**Статус:** ✅ РЕШЕНО - добавлена переменная окружения `OLLAMA_BASE_URL=http://ollama:11434`.
|
|
||||||
|
|
||||||
**Решение:**
|
|
||||||
1. Обнаружена проблема в коде: `ai-assistant.js` использовал `localhost:11434` по умолчанию
|
|
||||||
2. Добавлена переменная окружения `OLLAMA_BASE_URL=http://ollama:11434`
|
|
||||||
3. Backend перезапущен с правильными настройками
|
|
||||||
4. Проверено: AI сервис работает, 1 модель доступна
|
|
||||||
|
|
||||||
## Error 19: Проблема с расшифровкой данных
|
|
||||||
|
|
||||||
**Описание:** Ошибка расшифровки base64 данных в базе данных.
|
|
||||||
|
|
||||||
**Детали:**
|
|
||||||
- Ошибка: `invalid symbol "-" found while decoding base64 sequence`
|
|
||||||
- Проблема в функции `decrypt_text` PostgreSQL
|
|
||||||
- Данные в базе зашифрованы, но ключ шифрования не подходит
|
|
||||||
- Влияет на EmailBotService и DbSettingsService
|
|
||||||
|
|
||||||
**Влияние:** Среднее - некоторые функции могут не работать из-за проблем с расшифровкой.
|
|
||||||
|
|
||||||
**Статус:** ✅ РЕШЕНО - ключ шифрования смонтирован в контейнер.
|
|
||||||
|
|
||||||
**Решение:**
|
|
||||||
1. Обнаружено, что ключ шифрования не был смонтирован в контейнер backend
|
|
||||||
2. Ключ находился на хосте VDS в `/home/docker/dapp/ssl/keys/full_db_encryption.key`
|
|
||||||
3. Backend перезапущен с монтированием `-v /home/docker/dapp/ssl:/app/ssl`
|
|
||||||
4. Проверено: ключ доступен в контейнере, логи показывают "🔍 Ключ шифрования: установлен"
|
|
||||||
|
|
||||||
## Error 20: Frontend недоступен (502 Bad Gateway)
|
|
||||||
|
|
||||||
**Описание:** Домен hb3-accelerator.com возвращает ошибку 502 Bad Gateway.
|
|
||||||
|
|
||||||
**Детали:**
|
|
||||||
- Frontend-nginx контейнер постоянно перезапускается
|
|
||||||
- Ошибка nginx: `invalid number of arguments in "server_name" directive in /etc/nginx/nginx.conf:37`
|
|
||||||
- Frontend контейнер нездоров (unhealthy)
|
|
||||||
- Данные frontend-nginx volumes не импортированы
|
|
||||||
|
|
||||||
**Влияние:** Критическое - приложение недоступно через веб-интерфейс.
|
|
||||||
|
|
||||||
**Статус:** ✅ РЕШЕНО - frontend-nginx контейнер запущен с правильными переменными окружения.
|
|
||||||
|
|
||||||
**Решение:**
|
|
||||||
1. Обнаружена проблема: переменные окружения `DOMAIN` и `BACKEND_CONTAINER` не были установлены в контейнере
|
|
||||||
2. Контейнер перезапущен с переменными: `DOMAIN=hb3-accelerator.com` и `BACKEND_CONTAINER=dapp-backend`
|
|
||||||
3. Nginx конфигурация успешно обработана, контейнер запущен без ошибок
|
|
||||||
4. Frontend доступен через порт 9000: `http://185.221.214.140:9000`
|
|
||||||
|
|
||||||
**ТЕКУЩИЙ СТАТУС:** Все основные сервисы работают:
|
|
||||||
- ✅ Database: OK
|
|
||||||
- ✅ AI: OK (1 модель доступна)
|
|
||||||
- ✅ Vector Search: OK
|
|
||||||
- ✅ Шифрование: OK
|
|
||||||
- ✅ Frontend: OK (доступен через порт 9000)
|
|
||||||
- ⚠️ WebSocket: Частично работает (подключение есть, но nginx не проксирует `/ws`)
|
|
||||||
|
|
||||||
## Error 21: WebSocket не проксируется через nginx
|
|
||||||
|
|
||||||
**Описание:** Frontend подключается к WebSocket, но nginx не проксирует соединения на `/ws` к backend.
|
|
||||||
|
|
||||||
**Детали:**
|
|
||||||
- WebSocket подключение устанавливается: `[WebSocket] Подключение установлено`
|
|
||||||
- API запросы работают корректно: все `/api/*` запросы успешны
|
|
||||||
- Проблема: nginx конфигурация не содержит секцию для `/ws` endpoint
|
|
||||||
- Результат: frontend не получает real-time обновления после подключения кошелька
|
|
||||||
|
|
||||||
**Логи frontend:**
|
|
||||||
```
|
|
||||||
[WebSocket] Подключаемся к: wss://hb3-accelerator.com/ws
|
|
||||||
[WebSocket] Подключение установлено
|
|
||||||
🌐 [AXIOS] Отправляем запрос: /api/auth/verify
|
|
||||||
🌐 [AXIOS] Получен ответ: status 200
|
|
||||||
Auth check response: {authenticated: false, ...}
|
|
||||||
```
|
|
||||||
|
|
||||||
**Влияние:** Среднее - приложение работает, но отсутствуют real-time обновления аутентификации.
|
|
||||||
|
|
||||||
**Статус:** 🔄 В ПРОЦЕССЕ - требуется добавление поддержки WebSocket в nginx конфигурацию.
|
|
||||||
|
|
||||||
**Необходимое решение:**
|
|
||||||
Добавить в nginx конфигурацию секцию:
|
|
||||||
```nginx
|
|
||||||
location /ws {
|
|
||||||
proxy_pass http://dapp-backend:8000/ws;
|
|
||||||
proxy_http_version 1.1;
|
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
|
||||||
proxy_set_header Connection "upgrade";
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## 📊 ДИАГНОСТИКА VDS СЕРВЕРА `185.221.214.140`
|
|
||||||
|
|
||||||
### 🖥️ **СИСТЕМА:**
|
|
||||||
- **ОС:** Ubuntu 24.04.2 LTS (Noble Numbat)
|
|
||||||
- **Ядро:** Linux 6.8.0-63-generic
|
|
||||||
- **Архитектура:** x86_64
|
|
||||||
- **Память:** 7.8GB (используется 1.6GB, доступно 6.1GB)
|
|
||||||
- **Диск:** 59GB (используется 35GB, доступно 22GB - 63%)
|
|
||||||
- **IP:** 185.221.214.140/24
|
|
||||||
|
|
||||||
### 🔧 **УСТАНОВЛЕННЫЕ ПРОГРАММЫ:**
|
|
||||||
- **Docker:** 28.5.0 ✅
|
|
||||||
- **Docker Compose:** v2.39.4 ✅
|
|
||||||
- **Nginx:** 1.24.0 (Ubuntu) ✅
|
|
||||||
- **Node.js:** Не установлен (используется в контейнерах)
|
|
||||||
- **SSH:** Активен ✅
|
|
||||||
|
|
||||||
### 🐳 **DOCKER КОНТЕЙНЕРЫ (6 из 6 работают):**
|
|
||||||
- **dapp-frontend-nginx:** Up 4 minutes (порт 9000) ✅
|
|
||||||
- **dapp-frontend:** Up 26 minutes ✅
|
|
||||||
- **dapp-backend:** Up 37 minutes (порт 8000) ✅
|
|
||||||
- **dapp-postgres:** Up About an hour (порт 5432) ✅
|
|
||||||
- **dapp-vector-search:** Up 2 hours (unhealthy) ⚠️
|
|
||||||
- **dapp-ollama:** Up 2 hours (healthy) ✅
|
|
||||||
|
|
||||||
### 🌐 **СЕТЬ И ПОРТЫ:**
|
|
||||||
- **Открытые порты:**
|
|
||||||
- 80, 443 (системный nginx)
|
|
||||||
- 8000 (backend API)
|
|
||||||
- 9000 (frontend nginx)
|
|
||||||
- 5432 (PostgreSQL)
|
|
||||||
- **Docker сети:** dapp_default, bridge, host, none
|
|
||||||
- **Docker volumes:** 10 volumes (данные приложения)
|
|
||||||
|
|
||||||
### 🔒 **SSL И БЕЗОПАСНОСТЬ:**
|
|
||||||
- **SSL сертификат:** hb3-accelerator.com ✅
|
|
||||||
- **Nginx конфигурации:** 2 активных сайта
|
|
||||||
- **SSH атаки:** Обнаружены попытки взлома с IP 185.91.127.114 ⚠️
|
|
||||||
|
|
||||||
### 📈 **СТАТУС ПРИЛОЖЕНИЯ:**
|
|
||||||
- **Frontend:** ✅ Доступен (https://hb3-accelerator.com)
|
|
||||||
- **Backend API:** ✅ Работает (порт 8000)
|
|
||||||
- **Database:** ✅ 37 таблиц, все данные восстановлены
|
|
||||||
- **AI сервис:** ✅ 1 модель доступна
|
|
||||||
- **WebSocket:** ⚠️ Подключение есть, но nginx не проксирует `/ws`
|
|
||||||
|
|
||||||
### 🚨 **ПРОБЛЕМЫ:**
|
|
||||||
1. **Vector Search:** unhealthy (не критично)
|
|
||||||
2. **WebSocket:** Нужна настройка проксирования в nginx
|
|
||||||
3. **SSH атаки:** Рекомендуется усилить защиту
|
|
||||||
|
|
||||||
### ✅ **ВЫВОД:**
|
|
||||||
VDS сервер настроен корректно, все основные сервисы работают. Приложение Digital Legal Entity полностью функционально и доступно через веб-интерфейс. Остается только настроить WebSocket проксирование для полной функциональности.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Дата создания:** 2025-10-03
|
|
||||||
**Версия:** 1.2
|
|
||||||
**Статус:** Ошибки зафиксированы, диагностика VDS завершена
|
|
||||||
524
docs/vds.md
524
docs/vds.md
@@ -1,524 +0,0 @@
|
|||||||
# Задача: Простая настройка VDS с автоматической установкой Ubuntu
|
|
||||||
|
|
||||||
## 🎯 **Описание задачи:**
|
|
||||||
|
|
||||||
### **Цель:**
|
|
||||||
Создать простую форму для автоматической настройки VDS сервера с установкой Ubuntu и деплоем DLE приложения.
|
|
||||||
|
|
||||||
### **Проблема:**
|
|
||||||
Нужно вручную настраивать VDS сервер, устанавливать Ubuntu и необходимые компоненты для работы DLE приложения.
|
|
||||||
|
|
||||||
### **Решение:**
|
|
||||||
Автоматическая очистка VDS, установка Ubuntu, создание пользователя и деплой DLE приложения через локальную форму.
|
|
||||||
|
|
||||||
## 📋 **Требования:**
|
|
||||||
|
|
||||||
### **1. Входные данные (8 полей):**
|
|
||||||
- **Домен** - например `example.com` (IP адрес определяется автоматически из DNS)
|
|
||||||
- **Email** - для SSL сертификата
|
|
||||||
- **Логин Ubuntu** - пользователь для VDS (по умолчанию `ubuntu`, создается БЕЗ пароля)
|
|
||||||
- **Логин Docker** - пользователь для Docker (по умолчанию `docker`, создается БЕЗ пароля)
|
|
||||||
- **SSH хост** - SSH хост сервера (может отличаться от домена)
|
|
||||||
- **SSH порт** - SSH порт сервера (обычно 22)
|
|
||||||
- **SSH пользователь** - пользователь для SSH подключения (обычно `root`)
|
|
||||||
- **SSH пароль** - пароль для SSH подключения к VDS
|
|
||||||
|
|
||||||
### **1.1. Требования к домену:**
|
|
||||||
- **A запись** `example.com` → IP VDS сервера
|
|
||||||
- **CNAME запись** `www.example.com` → `example.com` (опционально)
|
|
||||||
- **Домен должен быть активен** и доступен
|
|
||||||
- **DNS записи должны распространиться** (проверка перед настройкой)
|
|
||||||
|
|
||||||
### **2. Что должно происходить:**
|
|
||||||
1. **Проверка DNS** - валидация A записи домена
|
|
||||||
2. **Подключение** к VDS по SSH (root + пароль)
|
|
||||||
3. **Создание SSH ключей на хосте** агентом автоматически (доступны в контейнерах через монтирование)
|
|
||||||
4. **Очистка** всего содержимого на VDS
|
|
||||||
5. **Создание пользователя Ubuntu** БЕЗ пароля (только SSH ключи)
|
|
||||||
6. **Создание пользователя Docker** БЕЗ пароля (только SSH ключи)
|
|
||||||
7. **Установка** Docker, Docker Compose, nginx
|
|
||||||
8. **Настройка безопасности** (UFW, отключение парольной аутентификации)
|
|
||||||
9. **Настройка** nginx для продакшн приложения
|
|
||||||
10. **Получение** SSL сертификата
|
|
||||||
11. **Экспорт и передача** Docker образов с локальной машины
|
|
||||||
12. **Передача ключа шифрования** на VDS
|
|
||||||
13. **Запуск** DLE приложения в Docker
|
|
||||||
|
|
||||||
### **3. Результат:**
|
|
||||||
- **VDS полностью очищена** и настроена
|
|
||||||
- **Пользователи Ubuntu и Docker** созданы БЕЗ паролей (только SSH ключи)
|
|
||||||
- **Базовый софт установлен** (Docker, nginx, SSL)
|
|
||||||
- **Безопасность настроена** (UFW, отключение парольной аутентификации)
|
|
||||||
- **Docker образы** экспортированы и переданы с локальной машины
|
|
||||||
- **Ключ шифрования** передан с локальной машины на VDS
|
|
||||||
- **SSH ключи** настроены для безопасного доступа
|
|
||||||
- **DLE приложение** работает в Docker на VDS
|
|
||||||
- **Домен работает** с SSL
|
|
||||||
- **Приложение работает** автономно на VDS
|
|
||||||
|
|
||||||
## 🏗️ **Архитектура:**
|
|
||||||
|
|
||||||
```
|
|
||||||
Продакшн режим:
|
|
||||||
Интернет → VDS nginx (домен) → VDS Docker приложение (автономно)
|
|
||||||
|
|
||||||
Настройка:
|
|
||||||
Локальная машина → WebSSH Agent (Docker) → SSH → VDS сервер → Очистка + Ubuntu + Docker миграция
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🤖 **WebSSH Agent - Автоматизация развертывания:**
|
|
||||||
|
|
||||||
### 🚀 **Возможности агента:**
|
|
||||||
|
|
||||||
WebSSH Agent - это мощный инструмент для автоматического развертывания приложения на VDS серверах.
|
|
||||||
|
|
||||||
**Архитектура:**
|
|
||||||
- Агент работает в Docker контейнере `dapp-webssh-agent`
|
|
||||||
- Порт 3000 проброшен с контейнера на хост (`0.0.0.0:3000->3000/tcp`)
|
|
||||||
- Доступен локально через `http://localhost:3000`
|
|
||||||
- Имеет расширенные права для автоматизации развертывания
|
|
||||||
|
|
||||||
#### 🔐 **Права доступа:**
|
|
||||||
- **SSH ключи:** Полный доступ к локальным SSH ключам (`~/.ssh/`)
|
|
||||||
- **Docker API:** Полный доступ к Docker socket для управления контейнерами
|
|
||||||
- **Файловая система:** Доступ к временным файлам и SSL сертификатам
|
|
||||||
- **Сетевые операции:** Выполнение SSH/SCP команд на удаленных серверах
|
|
||||||
|
|
||||||
#### 🛠️ **Функциональность:**
|
|
||||||
- **Автоматическая настройка VDS:** Установка Docker, Nginx, SSL сертификатов
|
|
||||||
- **Передача Docker образов:** Экспорт локальных образов и импорт на VDS
|
|
||||||
- **Управление пользователями:** Создание системных пользователей с SSH доступом
|
|
||||||
- **Безопасность:** Настройка firewall, отключение парольной аутентификации
|
|
||||||
- **Мониторинг:** Проверка системных требований и состояния серверов
|
|
||||||
|
|
||||||
#### 🔒 **Безопасность:**
|
|
||||||
- Агент работает в Docker контейнере, порт 3000 проброшен на хост
|
|
||||||
- SSH ключи монтируются в режиме только чтения
|
|
||||||
- Docker socket доступен только для управления контейнерами
|
|
||||||
- Все операции логируются для аудита
|
|
||||||
- Доступен локально через `http://localhost:3000`
|
|
||||||
|
|
||||||
#### 📡 **API Endpoints:**
|
|
||||||
- `GET /health` - Проверка состояния агента
|
|
||||||
- `POST /vds/check-requirements` - Проверка системных требований VDS
|
|
||||||
- `POST /vds/setup` - Полная настройка VDS сервера
|
|
||||||
- `POST /vds/transfer-encryption-key` - Передача ключей шифрования
|
|
||||||
|
|
||||||
### 🚨 **Важно:**
|
|
||||||
Агент имеет расширенные права для автоматизации развертывания. Используйте только на доверенных серверах и в защищенных сетях.
|
|
||||||
|
|
||||||
### 🔍 **Проверка работы агента:**
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Проверка состояния агента
|
|
||||||
curl http://localhost:3000/health
|
|
||||||
|
|
||||||
# Просмотр логов агента
|
|
||||||
docker logs dapp-webssh-agent
|
|
||||||
|
|
||||||
# Проверка статуса контейнера
|
|
||||||
docker ps | grep webssh-agent
|
|
||||||
```
|
|
||||||
|
|
||||||
**Ожидаемый ответ от /health:**
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"status": "ok",
|
|
||||||
"timestamp": "2025-10-02T16:33:16.477Z",
|
|
||||||
"version": "1.0.0",
|
|
||||||
"vdsConfigured": false,
|
|
||||||
"vdsDomain": null
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🔑 **Логика SSH ключей:**
|
|
||||||
|
|
||||||
### **Автоматическое создание SSH ключей агентом:**
|
|
||||||
|
|
||||||
#### **📍 На локальной машине (в агенте):**
|
|
||||||
- ✅ **id_rsa** (приватный ключ) - создается агентом автоматически
|
|
||||||
- ✅ **id_rsa.pub** (публичный ключ) - создается агентом автоматически
|
|
||||||
|
|
||||||
#### **📍 На VDS сервере:**
|
|
||||||
- ✅ **id_rsa.pub** (публичный ключ) - добавляется в `/root/.ssh/authorized_keys`
|
|
||||||
- ✅ **id_rsa.pub** (публичный ключ) - добавляется в `/home/ubuntu/.ssh/authorized_keys`
|
|
||||||
- ✅ **id_rsa.pub** (публичный ключ) - добавляется в `/home/docker/.ssh/authorized_keys`
|
|
||||||
- ❌ **id_rsa** (приватный ключ) - НЕ передается на VDS
|
|
||||||
|
|
||||||
### **Процесс аутентификации:**
|
|
||||||
```
|
|
||||||
1. Агент создает SSH ключи на хосте: ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa
|
|
||||||
2. Агент добавляет публичный ключ в authorized_keys на VDS
|
|
||||||
3. Агент подключается: ssh -i ~/.ssh/id_rsa root@VDS_IP
|
|
||||||
4. VDS проверяет подпись с помощью публичного ключа
|
|
||||||
5. Доступ разрешен для всех пользователей (root, ubuntu, docker)
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🔧 **Важные особенности архитектуры:**
|
|
||||||
|
|
||||||
#### **На локальной машине (разработка):**
|
|
||||||
- ✅ Git репозиторий с историей изменений
|
|
||||||
- ✅ Возможность отката к предыдущим версиям
|
|
||||||
- ✅ Разработка и тестирование
|
|
||||||
- ✅ Создание архивов для продакшн
|
|
||||||
|
|
||||||
#### **На VDS сервере (продакшн):**
|
|
||||||
- ❌ Git НЕ устанавливается и НЕ нужен
|
|
||||||
- ❌ История изменений НЕ хранится
|
|
||||||
- ❌ Откат происходит через архивы с локальной машины
|
|
||||||
- ✅ Только работающая версия приложения
|
|
||||||
- ✅ Полная автономность без внешних зависимостей
|
|
||||||
|
|
||||||
### **Компоненты:**
|
|
||||||
1. **Веб-форма** - настройка VDS (8 полей, без лишних настроек портов)
|
|
||||||
2. **WebSSH сервис** - SSH команды к VDS с автоматическим определением IP
|
|
||||||
3. **SSH агент** - подключение к VDS
|
|
||||||
4. **VDS сервер** - Ubuntu + Docker + nginx + SSL + Node.js
|
|
||||||
5. **Docker образы** - мигрированы с локальной машины
|
|
||||||
6. **База данных** - с зашифрованными настройками в таблицах
|
|
||||||
|
|
||||||
## 🚀 **Процесс работы:**
|
|
||||||
|
|
||||||
### **1. Первоначальная настройка:**
|
|
||||||
- Заходит на `http://localhost:5173/settings/interface/webssh`
|
|
||||||
- Заполняет форму с данными VDS (8 полей: домен, email, логины, SSH хост/порт/пользователь/пароль)
|
|
||||||
- Нажимает "Опубликовать" (настроить VDS)
|
|
||||||
|
|
||||||
### **2. Система настраивает VDS:**
|
|
||||||
- **Получает IP адрес** из DNS записей домена автоматически
|
|
||||||
- **Проверяет доступность** домена и IP
|
|
||||||
- **Предупреждает** если домен не готов
|
|
||||||
- Подключается к VDS по SSH (root + пароль)
|
|
||||||
- **Создает SSH ключи** агентом автоматически
|
|
||||||
- **Очищает** все содержимое на VDS
|
|
||||||
- **Создает пользователя Ubuntu** БЕЗ пароля (только SSH ключи)
|
|
||||||
- **Создает пользователя Docker** БЕЗ пароля (только SSH ключи)
|
|
||||||
- **Устанавливает** Docker, Docker Compose, nginx
|
|
||||||
- **Настраивает безопасность** (UFW, отключение парольной аутентификации)
|
|
||||||
- Настраивает nginx для продакшн
|
|
||||||
- Получает SSL сертификат
|
|
||||||
- **Экспортирует и передает** Docker образы с локальной машины
|
|
||||||
- **Передает ключ шифрования** на VDS
|
|
||||||
- **Запускает** DLE приложение в Docker
|
|
||||||
|
|
||||||
### **3. Результат:**
|
|
||||||
- **VDS полностью готова** для работы
|
|
||||||
- **Пользователи Ubuntu и Docker** созданы БЕЗ паролей (только SSH ключи)
|
|
||||||
- **Базовый софт установлен** (Docker, nginx, SSL)
|
|
||||||
- **Безопасность настроена** (UFW, отключение парольной аутентификации)
|
|
||||||
- **Docker образы** экспортированы и переданы с локальной машины
|
|
||||||
- **Ключ шифрования** передан с локальной машины на VDS
|
|
||||||
- **SSH ключи** настроены для безопасного доступа
|
|
||||||
- **DLE приложение** работает автономно в Docker
|
|
||||||
- **Домен доступен** с SSL
|
|
||||||
- **Полная автономность** - никаких внешних зависимостей
|
|
||||||
|
|
||||||
## 🔧 **Детальная логика установки софта на VDS:**
|
|
||||||
|
|
||||||
### **Этап 1: Проверка и подготовка**
|
|
||||||
```bash
|
|
||||||
# 1. Получение IP адреса из DNS записей домена
|
|
||||||
VDS_IP=$(dig +short $DOMAIN | head -1)
|
|
||||||
echo "IP адрес VDS сервера: $VDS_IP"
|
|
||||||
|
|
||||||
# 2. Проверка подключения к VDS
|
|
||||||
ssh -o ConnectTimeout=10 -o BatchMode=yes $SSH_USER@$VDS_IP "echo 'Connection OK'"
|
|
||||||
```
|
|
||||||
|
|
||||||
### **Этап 2: Очистка VDS**
|
|
||||||
```bash
|
|
||||||
# 1. Подключение к VDS
|
|
||||||
ssh $SSH_USER@$VDS_IP
|
|
||||||
|
|
||||||
# 2. Остановка всех сервисов
|
|
||||||
systemctl stop nginx || true
|
|
||||||
systemctl stop docker || true
|
|
||||||
systemctl stop postgresql || true
|
|
||||||
|
|
||||||
# 3. Очистка системы
|
|
||||||
apt-get autoremove -y
|
|
||||||
apt-get autoclean
|
|
||||||
rm -rf /var/log/*.log
|
|
||||||
rm -rf /tmp/*
|
|
||||||
rm -rf /var/tmp/*
|
|
||||||
```
|
|
||||||
|
|
||||||
### **Этап 3: Установка Ubuntu и базовых пакетов**
|
|
||||||
```bash
|
|
||||||
# 1. Обновление системы
|
|
||||||
apt-get update && apt-get upgrade -y
|
|
||||||
|
|
||||||
# 2. Установка базовых пакетов
|
|
||||||
# ВАЖНО: Git НЕ устанавливается - все обновления идут с локальной машины через архивы
|
|
||||||
apt-get install -y \
|
|
||||||
curl wget nginx certbot python3-certbot-nginx \
|
|
||||||
ufw fail2ban nano htop unzip tar gzip \
|
|
||||||
openssh-server ca-certificates gnupg lsb-release \
|
|
||||||
software-properties-common apt-transport-https
|
|
||||||
|
|
||||||
# 3. Установка Docker
|
|
||||||
curl -fsSL https://get.docker.com -o get-docker.sh
|
|
||||||
sh get-docker.sh
|
|
||||||
rm get-docker.sh
|
|
||||||
|
|
||||||
# 4. Установка Docker Compose
|
|
||||||
curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
|
|
||||||
chmod +x /usr/local/bin/docker-compose
|
|
||||||
|
|
||||||
# 5. Установка Node.js
|
|
||||||
curl -fsSL https://deb.nodesource.com/setup_20.x | bash -
|
|
||||||
apt-get install -y nodejs
|
|
||||||
```
|
|
||||||
|
|
||||||
### **Этап 4: Создание пользователей**
|
|
||||||
```bash
|
|
||||||
# 1. Создание пользователя Ubuntu
|
|
||||||
useradd -m -s /bin/bash $UBUNTU_USER
|
|
||||||
echo "$UBUNTU_USER:$UBUNTU_PASSWORD" | chpasswd
|
|
||||||
usermod -aG sudo $UBUNTU_USER
|
|
||||||
|
|
||||||
# 2. Создание пользователя Docker
|
|
||||||
useradd -m -s /bin/bash $DOCKER_USER
|
|
||||||
echo "$DOCKER_USER:$DOCKER_PASSWORD" | chpasswd
|
|
||||||
usermod -aG docker $DOCKER_USER
|
|
||||||
usermod -aG sudo $DOCKER_USER
|
|
||||||
```
|
|
||||||
|
|
||||||
### **Этап 5: Настройка безопасности**
|
|
||||||
```bash
|
|
||||||
# 1. Настройка UFW Firewall
|
|
||||||
ufw --force enable
|
|
||||||
ufw allow ssh
|
|
||||||
ufw allow 80
|
|
||||||
ufw allow 443
|
|
||||||
ufw allow 8000
|
|
||||||
ufw allow 5173
|
|
||||||
|
|
||||||
# 2. Настройка Fail2ban
|
|
||||||
systemctl enable fail2ban
|
|
||||||
systemctl start fail2ban
|
|
||||||
|
|
||||||
# 3. Настройка SSH
|
|
||||||
sed -i 's/#PasswordAuthentication yes/PasswordAuthentication yes/' /etc/ssh/sshd_config
|
|
||||||
sed -i 's/#PubkeyAuthentication yes/PubkeyAuthentication yes/' /etc/ssh/sshd_config
|
|
||||||
systemctl restart sshd
|
|
||||||
```
|
|
||||||
|
|
||||||
### **Этап 6: Настройка Nginx**
|
|
||||||
```bash
|
|
||||||
# 1. Создание конфигурации для домена
|
|
||||||
cat > /etc/nginx/sites-available/$DOMAIN << EOF
|
|
||||||
server {
|
|
||||||
listen 80;
|
|
||||||
server_name $DOMAIN;
|
|
||||||
|
|
||||||
# Основной location для фронтенда
|
|
||||||
location / {
|
|
||||||
proxy_pass http://localhost:5173;
|
|
||||||
proxy_set_header Host \$host;
|
|
||||||
proxy_set_header X-Real-IP \$remote_addr;
|
|
||||||
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
|
||||||
proxy_set_header X-Forwarded-Proto \$scheme;
|
|
||||||
}
|
|
||||||
|
|
||||||
# API проксирование к backend
|
|
||||||
location /api/ {
|
|
||||||
proxy_pass http://localhost:8000/api/;
|
|
||||||
proxy_set_header Host \$host;
|
|
||||||
proxy_set_header X-Real-IP \$remote_addr;
|
|
||||||
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
|
||||||
proxy_set_header X-Forwarded-Proto \$scheme;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
|
|
||||||
# 2. Активация конфигурации
|
|
||||||
ln -sf /etc/nginx/sites-available/$DOMAIN /etc/nginx/sites-enabled/
|
|
||||||
rm -f /etc/nginx/sites-enabled/default
|
|
||||||
nginx -t && systemctl reload nginx
|
|
||||||
```
|
|
||||||
|
|
||||||
### **Этап 7: Получение SSL сертификата**
|
|
||||||
```bash
|
|
||||||
# 1. Получение SSL сертификата
|
|
||||||
certbot --nginx -d $DOMAIN --non-interactive --agree-tos --email $EMAIL
|
|
||||||
|
|
||||||
# 2. Настройка автообновления
|
|
||||||
echo "0 12 * * * /usr/bin/certbot renew --quiet" | crontab -
|
|
||||||
```
|
|
||||||
|
|
||||||
### **Этап 8: Миграция Docker образов**
|
|
||||||
```bash
|
|
||||||
# 1. Создание директории для приложения
|
|
||||||
mkdir -p /home/$DOCKER_USER/dapp
|
|
||||||
cd /home/$DOCKER_USER/dapp
|
|
||||||
|
|
||||||
# 2. Создание бэкапа на локальной машине
|
|
||||||
docker compose down
|
|
||||||
docker compose up -d postgres
|
|
||||||
sleep 10
|
|
||||||
docker compose exec -T postgres pg_dump -U dapp_user dapp_db > postgres-backup.sql
|
|
||||||
docker compose exec -T ollama ollama list > ollama-models.txt
|
|
||||||
|
|
||||||
# 3. Создание архива приложения
|
|
||||||
tar -czf app-migration-$(date +%Y%m%d-%H%M%S).tar.gz \
|
|
||||||
. \
|
|
||||||
postgres-backup.sql \
|
|
||||||
ollama-models.txt \
|
|
||||||
--exclude='node_modules' \
|
|
||||||
--exclude='.git' \
|
|
||||||
--exclude='*.log' \
|
|
||||||
--exclude='temp' \
|
|
||||||
--exclude='sessions'
|
|
||||||
|
|
||||||
# 4. Копирование архива на VDS
|
|
||||||
scp app-migration-*.tar.gz $DOCKER_USER@$VDS_IP:/home/$DOCKER_USER/dapp/
|
|
||||||
|
|
||||||
# 5. Распаковка на VDS
|
|
||||||
ssh $DOCKER_USER@$VDS_IP "cd /home/$DOCKER_USER/dapp && tar -xzf app-migration-*.tar.gz"
|
|
||||||
```
|
|
||||||
|
|
||||||
### **Этап 9: Передача ключей**
|
|
||||||
```bash
|
|
||||||
# 1. Создание директории для ключей на VDS
|
|
||||||
ssh root@$VDS_IP "mkdir -p /home/$DOCKER_USER/dapp/ssl/keys"
|
|
||||||
|
|
||||||
# 2. Копирование ключа шифрования БД
|
|
||||||
scp ./ssl/keys/full_db_encryption.key root@$VDS_IP:/home/$DOCKER_USER/dapp/ssl/keys/
|
|
||||||
|
|
||||||
# 3. Настройка SSH ключей (выполняется автоматически агентом)
|
|
||||||
# Публичный ключ (id_rsa.pub) добавляется в /root/.ssh/authorized_keys
|
|
||||||
# Приватный ключ (id_rsa) остается на локальной машине
|
|
||||||
```
|
|
||||||
|
|
||||||
### **Этап 10: Восстановление базы данных с настройками**
|
|
||||||
```bash
|
|
||||||
# 1. Запуск PostgreSQL на VDS
|
|
||||||
ssh $DOCKER_USER@$VDS_IP "cd /home/$DOCKER_USER/dapp && docker compose up -d postgres"
|
|
||||||
sleep 10
|
|
||||||
|
|
||||||
# 2. Восстановление базы данных (включая все таблицы настроек)
|
|
||||||
ssh $DOCKER_USER@$VDS_IP "cd /home/$DOCKER_USER/dapp && docker compose exec -T postgres psql -U dapp_user -d dapp_db < postgres-backup.sql"
|
|
||||||
```
|
|
||||||
|
|
||||||
### **Этап 11: Запуск приложения**
|
|
||||||
```bash
|
|
||||||
# 1. Запуск всех сервисов
|
|
||||||
ssh $DOCKER_USER@$VDS_IP "cd /home/$DOCKER_USER/dapp && docker compose up -d"
|
|
||||||
|
|
||||||
# 2. Проверка статуса
|
|
||||||
ssh $DOCKER_USER@$VDS_IP "cd /home/$DOCKER_USER/dapp && docker compose ps"
|
|
||||||
|
|
||||||
# 3. Проверка логов
|
|
||||||
ssh $DOCKER_USER@$VDS_IP "cd /home/$DOCKER_USER/dapp && docker compose logs --tail=20"
|
|
||||||
```
|
|
||||||
|
|
||||||
### **Этап 12: Проверка работоспособности**
|
|
||||||
```bash
|
|
||||||
# 1. Проверка доступности домена
|
|
||||||
curl -I https://$DOMAIN
|
|
||||||
|
|
||||||
# 2. Проверка API
|
|
||||||
curl -I https://$DOMAIN/api/health
|
|
||||||
|
|
||||||
# 3. Проверка SSL сертификата
|
|
||||||
openssl s_client -connect $DOMAIN:443 -servername $DOMAIN
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🔄 **Процесс обновлений приложения:**
|
|
||||||
|
|
||||||
### **Обновление с локальной машины:**
|
|
||||||
```bash
|
|
||||||
# 1. На локальной машине - разработка
|
|
||||||
git add .
|
|
||||||
git commit -m "Новая функция"
|
|
||||||
git tag v1.2.0
|
|
||||||
|
|
||||||
# 2. Создание архива для продакшн
|
|
||||||
tar -czf app-update-v1.2.0-$(date +%Y%m%d-%H%M%S).tar.gz \
|
|
||||||
. \
|
|
||||||
postgres-backup.sql \
|
|
||||||
ollama-models.txt \
|
|
||||||
--exclude='node_modules' \
|
|
||||||
--exclude='.git' \
|
|
||||||
--exclude='*.log' \
|
|
||||||
--exclude='temp' \
|
|
||||||
--exclude='sessions'
|
|
||||||
|
|
||||||
# 3. Деплой на VDS
|
|
||||||
scp app-update-v1.2.0-*.tar.gz $DOCKER_USER@$VDS_IP:/home/$DOCKER_USER/dapp/
|
|
||||||
ssh $DOCKER_USER@$VDS_IP "cd /home/$DOCKER_USER/dapp && tar -xzf app-update-v1.2.0-*.tar.gz && docker compose restart"
|
|
||||||
```
|
|
||||||
|
|
||||||
### **Откат к предыдущей версии:**
|
|
||||||
```bash
|
|
||||||
# 1. На локальной машине - переход к предыдущей версии
|
|
||||||
git checkout v1.1.0
|
|
||||||
|
|
||||||
# 2. Создание архива предыдущей версии
|
|
||||||
tar -czf app-rollback-v1.1.0-$(date +%Y%m%d-%H%M%S).tar.gz \
|
|
||||||
. \
|
|
||||||
postgres-backup.sql \
|
|
||||||
ollama-models.txt \
|
|
||||||
--exclude='node_modules' \
|
|
||||||
--exclude='.git' \
|
|
||||||
--exclude='*.log' \
|
|
||||||
--exclude='temp' \
|
|
||||||
--exclude='sessions'
|
|
||||||
|
|
||||||
# 3. Деплой предыдущей версии на VDS
|
|
||||||
scp app-rollback-v1.1.0-*.tar.gz $DOCKER_USER@$VDS_IP:/home/$DOCKER_USER/dapp/
|
|
||||||
ssh $DOCKER_USER@$VDS_IP "cd /home/$DOCKER_USER/dapp && tar -xzf app-rollback-v1.1.0-*.tar.gz && docker compose restart"
|
|
||||||
```
|
|
||||||
|
|
||||||
### **Ключевые принципы:**
|
|
||||||
- **Все обновления** идут с локальной машины через архивы
|
|
||||||
- **Все откаты** происходят с локальной машины через архивы
|
|
||||||
- **VDS** никогда не работает с Git - только с архивами
|
|
||||||
- **Полная автономность** - VDS работает без внешних зависимостей
|
|
||||||
|
|
||||||
## 📁 **Файлы проекта:**
|
|
||||||
|
|
||||||
### **Frontend:**
|
|
||||||
- `frontend/src/components/WebSshForm.vue` - форма управления
|
|
||||||
- `frontend/src/services/webSshService.js` - SSH команды к VDS
|
|
||||||
|
|
||||||
### **Backend:**
|
|
||||||
- `backend/routes/vds-management.js` - API для управления VDS
|
|
||||||
- `backend/services/sshManager.js` - SSH команды
|
|
||||||
- `backend/services/encryptionManager.js` - управление шифрованием
|
|
||||||
|
|
||||||
### **Scripts:**
|
|
||||||
- `scripts/setup-vds.sh` - очистка VDS и установка Ubuntu
|
|
||||||
- `scripts/migrate-docker.sh` - миграция Docker образов на VDS
|
|
||||||
- `scripts/configure-vds.sh` - настройка nginx и SSL
|
|
||||||
- `scripts/transfer-keys.sh` - передача ключей на VDS
|
|
||||||
- `scripts/restore-database.sh` - восстановление БД с настройками
|
|
||||||
- `scripts/install-ubuntu.sh` - автоматическая установка Ubuntu
|
|
||||||
|
|
||||||
## ✅ **Статус:**
|
|
||||||
|
|
||||||
### **Готово:**
|
|
||||||
- ✅ Форма WebSSH упрощена
|
|
||||||
- ✅ WebSSH сервис обновлен
|
|
||||||
- ✅ DNS проверка добавлена
|
|
||||||
- ✅ Инструкции по настройке DNS созданы
|
|
||||||
- ✅ Поле VDS IP добавлено в форму
|
|
||||||
|
|
||||||
### **Нужно доработать:**
|
|
||||||
- 🔄 SSH агент для очистки и установки Ubuntu
|
|
||||||
- 🔄 API для управления VDS
|
|
||||||
- 🔄 Миграция Docker образов на VDS
|
|
||||||
- 🔄 Передача ключей (шифрования и RSA) на VDS
|
|
||||||
- 🔄 Восстановление БД с зашифрованными настройками
|
|
||||||
- 🔄 Автоматическая загрузка ключа шифрования в форму
|
|
||||||
|
|
||||||
## 🎯 **Следующие шаги:**
|
|
||||||
|
|
||||||
1. **Создать SSH агент** для очистки и установки Ubuntu
|
|
||||||
2. **Добавить API** для управления VDS
|
|
||||||
3. **Реализовать миграцию** Docker образов на VDS
|
|
||||||
4. **Создать скрипты** для передачи ключей на VDS
|
|
||||||
5. **Реализовать восстановление** БД с зашифрованными настройками
|
|
||||||
6. **Добавить автоматическую загрузку** ключа шифрования в форму
|
|
||||||
7. **Протестировать** на реальной VDS
|
|
||||||
@@ -1,120 +0,0 @@
|
|||||||
<!--
|
|
||||||
Copyright (c) 2024-2025 Тарабанов Александр Викторович
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
This software is proprietary and confidential.
|
|
||||||
Unauthorized copying, modification, or distribution is prohibited.
|
|
||||||
|
|
||||||
For licensing inquiries: info@hb3-accelerator.com
|
|
||||||
Website: https://hb3-accelerator.com
|
|
||||||
GitHub: https://github.com/HB3-ACCELERATOR
|
|
||||||
-->
|
|
||||||
|
|
||||||
# Техническое задание: Векторный сервис поиска по таблице
|
|
||||||
|
|
||||||
## Цель
|
|
||||||
Реализовать отдельный микросервис для векторного поиска по данным из таблицы в базе данных. Сервис должен предоставлять REST API для добавления, поиска и обновления векторных представлений (эмбеддингов) строк таблицы.
|
|
||||||
|
|
||||||
## Язык и стек
|
|
||||||
- Язык: Python 3.10+
|
|
||||||
- Векторный движок: FAISS
|
|
||||||
- API: FastAPI
|
|
||||||
- Хранение индекса: на диске (persistency)
|
|
||||||
- Docker-образ для деплоя
|
|
||||||
|
|
||||||
## API сервиса
|
|
||||||
|
|
||||||
### 1. Добавление/обновление записей
|
|
||||||
- **POST /upsert**
|
|
||||||
- Тело запроса:
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"table_id": "string", // идентификатор таблицы
|
|
||||||
"rows": [
|
|
||||||
{
|
|
||||||
"row_id": "string", // идентификатор строки
|
|
||||||
"text": "string", // текст для эмбеддинга
|
|
||||||
"metadata": { ... } // любые дополнительные поля
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
- Ответ: `{ "success": true }`
|
|
||||||
|
|
||||||
### 2. Поиск похожих записей
|
|
||||||
- **POST /search**
|
|
||||||
- Тело запроса:
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"table_id": "string",
|
|
||||||
"query": "string", // текст запроса
|
|
||||||
"top_k": 3 // количество результатов
|
|
||||||
}
|
|
||||||
```
|
|
||||||
- Ответ:
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"results": [
|
|
||||||
{
|
|
||||||
"row_id": "string",
|
|
||||||
"score": float,
|
|
||||||
"metadata": { ... }
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. Удаление записей
|
|
||||||
- **POST /delete**
|
|
||||||
- Тело запроса:
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"table_id": "string",
|
|
||||||
"row_ids": ["string", ...]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
- Ответ: `{ "success": true }`
|
|
||||||
|
|
||||||
### 4. Пересоздание индекса (опционально)
|
|
||||||
- **POST /rebuild**
|
|
||||||
- Тело запроса:
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"table_id": "string"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
- Ответ: `{ "success": true }`
|
|
||||||
|
|
||||||
## Требования к эмбеддингам
|
|
||||||
- Для генерации эмбеддингов сервис использует Ollama (через HTTP API, модель mxbai-embed-large или аналогичную).
|
|
||||||
- Эмбеддинги кэшируются локально для ускорения поиска.
|
|
||||||
|
|
||||||
## Требования к интеграции
|
|
||||||
- Сервис не хранит бизнес-логику, только индексы и метаданные.
|
|
||||||
- Node.js backend обращается к сервису по HTTP (localhost или через docker-compose).
|
|
||||||
- Все операции атомарны, сервис устойчив к сбоям.
|
|
||||||
|
|
||||||
## Безопасность
|
|
||||||
- Сервис доступен только во внутренней сети (docker-compose).
|
|
||||||
- Нет публичного доступа извне.
|
|
||||||
|
|
||||||
## Мониторинг и логирование
|
|
||||||
- Логирование всех запросов и ошибок.
|
|
||||||
- Healthcheck endpoint: **GET /health** (ответ: `{ "status": "ok" }`)
|
|
||||||
|
|
||||||
## Docker
|
|
||||||
- Сервис должен запускаться как отдельный контейнер.
|
|
||||||
- Все зависимости описаны в requirements.txt.
|
|
||||||
|
|
||||||
## Пример docker-compose.yml (фрагмент)
|
|
||||||
```yaml
|
|
||||||
services:
|
|
||||||
vector-search:
|
|
||||||
build: ./vector-search
|
|
||||||
ports:
|
|
||||||
- "8001:8001"
|
|
||||||
environment:
|
|
||||||
- OLLAMA_BASE_URL=http://ollama:11434
|
|
||||||
depends_on:
|
|
||||||
- ollama
|
|
||||||
```
|
|
||||||
@@ -1,315 +0,0 @@
|
|||||||
# 🤖 WebSSH Agent - Детальный анализ функциональности (ОБНОВЛЕНО)
|
|
||||||
|
|
||||||
## 🆕 **ОСНОВНЫЕ ИЗМЕНЕНИЯ В ВЕРСИИ 2.0:**
|
|
||||||
- ✅ **Умная проверка nginx** - агент автоматически определяет наличие системного nginx и удаляет его
|
|
||||||
- ✅ **Docker nginx с автоматическим SSL** - полная автоматизация получения и обновления SSL сертификатов
|
|
||||||
- ✅ **Certbot контейнер** - автоматическое получение SSL через webroot режим
|
|
||||||
- ✅ **Автообновление SSL** - cron задача для ежедневного обновления сертификатов
|
|
||||||
- ✅ **Исправлены все 12 ошибок** из отчета о развертывании
|
|
||||||
- ✅ **Универсальность** - работает на любом VDS (с nginx или без)
|
|
||||||
|
|
||||||
## 📋 **API Endpoints и их функции:**
|
|
||||||
|
|
||||||
### 1. **GET /health** - Проверка состояния
|
|
||||||
- **Что делает:** Возвращает статус агента и информацию о настроенных VDS
|
|
||||||
- **Данные:** Текущее время, версия, состояние VDS
|
|
||||||
- **Передает:** JSON с статусом агента
|
|
||||||
|
|
||||||
### 2. **POST /vds/check-requirements** - Проверка системных требований
|
|
||||||
- **Входные данные:**
|
|
||||||
- `vdsIp` - IP адрес VDS сервера
|
|
||||||
- `ubuntuUser` - имя пользователя Ubuntu
|
|
||||||
- `sshHost` - SSH хост (опционально)
|
|
||||||
- `sshPort` - SSH порт (по умолчанию 22)
|
|
||||||
- `sshConnectUser` - пользователь для SSH подключения
|
|
||||||
- `sshConnectPassword` - пароль для SSH подключения
|
|
||||||
|
|
||||||
- **Что делает:**
|
|
||||||
- Подключается к VDS по SSH
|
|
||||||
- Проверяет системные требования (ОС, память, диск, CPU)
|
|
||||||
- Анализирует совместимость с приложением
|
|
||||||
|
|
||||||
- **Передает:** JSON с результатами проверки, системной информацией, предупреждениями и ошибками
|
|
||||||
|
|
||||||
### 3. **POST /vds/transfer-encryption-key** - Передача ключа шифрования
|
|
||||||
- **Входные данные:**
|
|
||||||
- `vdsIp` - IP адрес VDS сервера
|
|
||||||
- `dockerUser` - пользователь Docker
|
|
||||||
- `sshConnectUser` - пользователь для SSH подключения
|
|
||||||
- `sshConnectPassword` - пароль для SSH подключения
|
|
||||||
|
|
||||||
- **Что делает:**
|
|
||||||
- Читает ключ шифрования с локальной машины (`/app/ssl/keys/full_db_encryption.key`)
|
|
||||||
- Передает ключ на VDS через SCP в `/home/dockerUser/dapp/ssl/keys/full_db_encryption.key`
|
|
||||||
- Устанавливает правильные права доступа (600, владелец dockerUser)
|
|
||||||
- **Важно:** Путь соответствует монтированию `./ssl:/app/ssl:ro` в docker-compose.prod.yml
|
|
||||||
|
|
||||||
- **Передает:** Ключ шифрования базы данных
|
|
||||||
- **НЕ передает:** Пароли или другие секретные данные
|
|
||||||
|
|
||||||
### 4. **POST /vds/setup** - Полная настройка VDS (ОСНОВНАЯ ФУНКЦИЯ)
|
|
||||||
- **Входные данные:**
|
|
||||||
- `vdsIp` - IP адрес VDS сервера
|
|
||||||
- `domain` - доменное имя
|
|
||||||
- `email` - email для SSL сертификата
|
|
||||||
- `ubuntuUser` - пользователь Ubuntu
|
|
||||||
- `dockerUser` - пользователь Docker
|
|
||||||
- `sshConnectUser` - пользователь для SSH подключения
|
|
||||||
- `sshConnectPassword` - пароль для SSH подключения
|
|
||||||
|
|
||||||
## 🔄 **Детальный порядок выполнения /vds/setup:**
|
|
||||||
|
|
||||||
### **Этап 0: Проверка системных требований**
|
|
||||||
- Подключается к VDS по SSH
|
|
||||||
- Проверяет ОС, память, диск, CPU
|
|
||||||
- Анализирует совместимость архитектуры
|
|
||||||
- **Поддерживаемые архитектуры:** x86_64, amd64, aarch64, arm64, armv7l, armv8l, i386, i686, ppc64le, s390x
|
|
||||||
- **Минимальные требования:** 6GB RAM, 30GB диск, 2 CPU ядра
|
|
||||||
- **Рекомендуемые требования:** 8GB RAM, 50GB диск
|
|
||||||
|
|
||||||
### **Этап 1: Создание SSH ключей локально**
|
|
||||||
- Создает SSH ключи на хосте (`~/.ssh/id_rsa`, `~/.ssh/id_rsa.pub`)
|
|
||||||
- Использует email для генерации ключей
|
|
||||||
- **Приватный ключ остается на хосте** для будущего использования
|
|
||||||
- **Публичный ключ передается в контейнер** через монтирование
|
|
||||||
|
|
||||||
### **Этап 2: Настройка SSH ключей для root**
|
|
||||||
- Добавляет публичный ключ в `/root/.ssh/authorized_keys` на VDS
|
|
||||||
- Настраивает права доступа
|
|
||||||
|
|
||||||
### **Этап 3: Очистка VDS сервера**
|
|
||||||
- Останавливает и удаляет все Docker контейнеры
|
|
||||||
- Очищает Docker систему (образы, volumes, networks)
|
|
||||||
- **🆕 Умная проверка nginx:** автоматически определяет наличие системного nginx
|
|
||||||
- **🆕 Полное удаление nginx:** если найден системный nginx - полностью удаляет его
|
|
||||||
- Очищает временные файлы
|
|
||||||
|
|
||||||
### **Этап 4: Создание пользователей**
|
|
||||||
- Создает пользователя `ubuntuUser` с sudo правами
|
|
||||||
- Создает пользователя `dockerUser` с sudo и docker правами
|
|
||||||
- Настраивает SSH ключи для обоих пользователей
|
|
||||||
- Создает директорию `/home/dockerUser/dapp`
|
|
||||||
|
|
||||||
### **Этап 5: Установка Docker**
|
|
||||||
- Скачивает и устанавливает Docker
|
|
||||||
- Добавляет `dockerUser` в группу docker
|
|
||||||
|
|
||||||
### **Этап 6: Установка Docker Compose**
|
|
||||||
- Скачивает и устанавливает Docker Compose
|
|
||||||
- Настраивает права выполнения
|
|
||||||
|
|
||||||
### **Этап 7: Отключение парольной аутентификации**
|
|
||||||
- Настраивает SSH для работы только с ключами
|
|
||||||
- Отключает парольную аутентификацию
|
|
||||||
|
|
||||||
### **Этап 8: Настройка firewall**
|
|
||||||
- Включает UFW
|
|
||||||
- Разрешает SSH (22), HTTP (80), HTTPS (443)
|
|
||||||
|
|
||||||
### **Этап 9: Создание директории для ключей шифрования**
|
|
||||||
- Создает `/home/dockerUser/dapp/ssl/keys`
|
|
||||||
- Настраивает права доступа (700)
|
|
||||||
|
|
||||||
### **Этап 10: 🆕 Умная проверка и удаление системного nginx**
|
|
||||||
- **🔍 Проверяет наличие системного nginx** в системе
|
|
||||||
- **⚠️ Если найден:** полностью удаляет системный nginx (stop, disable, mask, purge)
|
|
||||||
- **ℹ️ Если не найден:** продолжает без изменений
|
|
||||||
- **✅ Результат:** порты 80/443 полностью освобождены для Docker nginx
|
|
||||||
|
|
||||||
### **Этап 11: 🆕 Автоматический SSL через Docker**
|
|
||||||
- **🔒 SSL сертификаты получаются автоматически** через Docker certbot контейнер
|
|
||||||
- **📋 Certbot настроен** для автоматического получения и обновления SSL сертификатов
|
|
||||||
- **🚫 НЕ устанавливает системный certbot** - все через Docker
|
|
||||||
|
|
||||||
### **Этап 12: 🆕 Настройка Docker nginx**
|
|
||||||
- **🐳 Nginx конфигурация встроена** в Docker образ frontend-nginx
|
|
||||||
- **🔧 Конфигурация применяется автоматически** при запуске контейнера
|
|
||||||
- **🌐 Поддержка HTTPS** с автоматическими SSL сертификатами
|
|
||||||
|
|
||||||
### **Этап 13: Передача docker-compose.prod.yml**
|
|
||||||
- Читает файл с локальной машины (`/app/docker-compose.prod.yml`)
|
|
||||||
- Передает на VDS как `/home/dockerUser/dapp/docker-compose.yml`
|
|
||||||
|
|
||||||
### **Этап 14: 🆕 Создание полного .env файла**
|
|
||||||
- Создает файл с полными переменными окружения:
|
|
||||||
```
|
|
||||||
# Основные настройки
|
|
||||||
DOMAIN=example.com
|
|
||||||
BACKEND_CONTAINER=dapp-backend
|
|
||||||
EMAIL=admin@example.com
|
|
||||||
|
|
||||||
# Настройки базы данных
|
|
||||||
DB_NAME=dapp_db
|
|
||||||
DB_USER=dapp_user
|
|
||||||
DB_PASSWORD=dapp_password
|
|
||||||
|
|
||||||
# Настройки Node.js
|
|
||||||
NODE_ENV=production
|
|
||||||
PORT=8000
|
|
||||||
|
|
||||||
# Настройки Ollama
|
|
||||||
OLLAMA_MODEL=qwen2.5:7b
|
|
||||||
OLLAMA_EMBEDDINGS_MODEL=qwen2.5:7b
|
|
||||||
|
|
||||||
# Настройки безопасности
|
|
||||||
SSL_CERT_PATH=/etc/ssl/certs
|
|
||||||
SSL_KEY_PATH=/etc/ssl/private
|
|
||||||
```
|
|
||||||
|
|
||||||
### **Этап 15: Экспорт и передача Docker образов и данных**
|
|
||||||
- **Экспортирует с локальной машины (образы + данные):**
|
|
||||||
- `postgres:16-alpine` - образ PostgreSQL + данные БД
|
|
||||||
- `digital_legal_entitydle-ollama:latest` - образ Ollama + модели
|
|
||||||
- `digital_legal_entitydle-vector-search:latest` - образ Vector Search + индексы
|
|
||||||
- `digital_legal_entitydle-backend:latest` - образ Backend
|
|
||||||
- `digital_legal_entitydle-frontend:latest` - образ Frontend
|
|
||||||
- `digital_legal_entitydle-frontend-nginx:latest` - образ Nginx
|
|
||||||
- `digital_legal_entitydle-webssh-agent:latest` - образ WebSSH Agent
|
|
||||||
|
|
||||||
- **Экспортирует данные из volumes:**
|
|
||||||
- `postgres_data` - данные базы данных PostgreSQL
|
|
||||||
- `ollama_data` - модели Ollama
|
|
||||||
- `vector_search_data` - индексы векторного поиска
|
|
||||||
|
|
||||||
- **Создает архив:** `docker-images-and-data.tar.gz` со всеми образами и данными
|
|
||||||
- **Передает на VDS:** Через SCP в `/home/dockerUser/dapp/`
|
|
||||||
- **Импортирует на VDS:** Распаковывает и загружает образы + создает volumes с данными
|
|
||||||
- **Очищает локальные файлы:** Удаляет временные tar файлы
|
|
||||||
- **✅ Важно:** Передаются образы И данные для полного развертывания
|
|
||||||
|
|
||||||
### **Этап 16: 🆕 Запуск приложения с автоматическим SSL**
|
|
||||||
- Запускает `docker compose up -d` на VDS
|
|
||||||
- Запускает все контейнеры приложения, включая certbot контейнер
|
|
||||||
- **🔒 Автоматическое получение SSL:** certbot получает сертификаты через webroot режим
|
|
||||||
|
|
||||||
### **Этап 16.0: 🆕 Настройка автообновления SSL**
|
|
||||||
- **📅 Создает cron задачу** для ежедневного обновления SSL сертификатов
|
|
||||||
- **🔄 Скрипт обновления:** `renew-ssl.sh` - обновляет сертификаты и перезапускает nginx
|
|
||||||
- **⏰ Расписание:** ежедневно в 12:00
|
|
||||||
|
|
||||||
### **Этап 17: 🆕 Проверка готовности и целостности БД**
|
|
||||||
- **⏳ Ожидание готовности базы данных:** проверяет доступность PostgreSQL с повторными попытками
|
|
||||||
- **🗃️ Проверка целостности переданной БД:** проверяет наличие таблиц (email_settings, db_settings, session)
|
|
||||||
- **📊 Подсчет таблиц:** показывает количество таблиц в переданной базе данных
|
|
||||||
- **🔑 Проверка ключа шифрования:** проверяет наличие ключа в backend контейнере
|
|
||||||
- **📈 Проверка статуса контейнеров:** логирует результаты всех проверок
|
|
||||||
|
|
||||||
## 📊 **Что передается и что НЕ передается:**
|
|
||||||
|
|
||||||
### ✅ **ПЕРЕДАЕТСЯ:**
|
|
||||||
- **Docker образы:** Все 7 образов приложения (полный стек)
|
|
||||||
- **Docker данные:** Данные из volumes (PostgreSQL, Ollama модели, Vector Search индексы)
|
|
||||||
- **Конфигурационные файлы:** docker-compose.prod.yml, .env
|
|
||||||
- **SSH ключи:** Публичные ключи для доступа (создаются на хосте, передаются в контейнер)
|
|
||||||
- **Ключ шифрования:** Ключ для шифрования базы данных
|
|
||||||
- **SSL сертификаты:** Получаются автоматически через Let's Encrypt
|
|
||||||
|
|
||||||
### ❌ **НЕ ПЕРЕДАЕТСЯ:**
|
|
||||||
- **Пароли:** Только SSH ключи, пароли не передаются
|
|
||||||
- **Приватные SSH ключи:** Остаются на хосте для безопасности
|
|
||||||
- **Секретные данные:** Только ключ шифрования БД
|
|
||||||
- **Пользовательские данные:** Только системная настройка
|
|
||||||
- **Исходный код:** Только скомпилированные Docker образы
|
|
||||||
|
|
||||||
## 🎯 **Результат работы агента:**
|
|
||||||
- **Полностью настроенный VDS сервер** с Ubuntu
|
|
||||||
- **Работающее приложение** на домене с SSL
|
|
||||||
- **Безопасный доступ** только по SSH ключам
|
|
||||||
- **Автономная работа** без зависимости от локальной машины
|
|
||||||
|
|
||||||
## 🔧 **Технические детали:**
|
|
||||||
|
|
||||||
### **Архитектура:**
|
|
||||||
- Агент работает в Docker контейнере `dapp-webssh-agent`
|
|
||||||
- Порт 3000 проброшен с контейнера на хост (`0.0.0.0:3000->3000/tcp`)
|
|
||||||
- Доступен локально через `http://localhost:3000`
|
|
||||||
|
|
||||||
### **Процесс создания SSH ключей:**
|
|
||||||
1. **Создание на хосте:** `ssh-keygen -t rsa -b 4096 -C "email" -f ~/.ssh/id_rsa -N ""`
|
|
||||||
2. **Исправление прав доступа:** Автоматическое исправление прав доступа к SSH конфигу (`chmod 600 /root/.ssh/config`)
|
|
||||||
3. **Приватный ключ:** Остается на хосте (`~/.ssh/id_rsa`) для безопасности с правами 600
|
|
||||||
4. **Публичный ключ:** Передается в контейнер через монтирование (`~/.ssh/id_rsa.pub` → `/root/.ssh/id_rsa.pub`) с правами 644
|
|
||||||
5. **Передача на VDS:** Публичный ключ передается через SSH команду
|
|
||||||
6. **Очистка:** Временные файлы удаляются, SSH ключи сохраняются на хосте
|
|
||||||
|
|
||||||
### **Права доступа:**
|
|
||||||
- **SSH ключи:** Полный доступ к локальным SSH ключам (`~/.ssh/`) с автоматическим исправлением прав доступа
|
|
||||||
- **SSH конфигурация:** Автоматическое исправление прав доступа к `/root/.ssh/config` (600) перед каждой операцией
|
|
||||||
- **Docker API:** Полный доступ к Docker socket для управления контейнерами
|
|
||||||
- **Файловая система:** Доступ к временным файлам и SSL сертификатам
|
|
||||||
- **Сетевые операции:** Выполнение SSH/SCP команд на удаленных серверах с предварительной проверкой прав доступа
|
|
||||||
|
|
||||||
## 🛠️ **ИСПРАВЛЕННЫЕ ОШИБКИ ИЗ ОТЧЕТА:**
|
|
||||||
|
|
||||||
### ✅ **ВСЕ 12 ОШИБОК ПОЛНОСТЬЮ ИСПРАВЛЕНЫ:**
|
|
||||||
|
|
||||||
| № | Ошибка | Статус | Решение |
|
|
||||||
|---|--------|--------|---------|
|
|
||||||
| 1 | HTTP ERROR 503 - конфликт портов nginx | ✅ ИСПРАВЛЕНО | Умная проверка и удаление системного nginx |
|
|
||||||
| 2 | Конфликт портов nginx | ✅ ИСПРАВЛЕНО | Системный nginx полностью удаляется |
|
|
||||||
| 3 | Проблемы с health checks | ✅ ИСПРАВЛЕНО | Улучшены health checks, изменены зависимости |
|
|
||||||
| 4 | Ошибки конфигурации nginx | ✅ ИСПРАВЛЕНО | Исправлены переменные, добавлена валидация |
|
|
||||||
| 5 | Проблемы с системным nginx | ✅ ИСПРАВЛЕНО | Системный nginx удаляется автоматически |
|
|
||||||
| 6 | Ошибки подключения к БД | ✅ ИСПРАВЛЕНО | Добавлен SCRAM-SHA-256, исправлены переменные |
|
|
||||||
| 7 | YAML синтаксис | ✅ ИСПРАВЛЕНО | Корректный формат переменных окружения |
|
|
||||||
| 8 | Отсутствующие таблицы БД | ✅ ИСПРАВЛЕНО | Проверка целостности переданной БД с таблицами |
|
|
||||||
| 9 | Проблемы с пробросом портов | ✅ ИСПРАВЛЕНО | Правильные порты в docker-compose |
|
|
||||||
| 10 | Проблемы с переменными окружения | ✅ ИСПРАВЛЕНО | Полный .env файл со всеми переменными |
|
|
||||||
| 11 | Отсутствие миграций БД | ✅ ИСПРАВЛЕНО | Проверка целостности переданной БД вместо миграций |
|
|
||||||
| 12 | Проверка ключа шифрования | ✅ ИСПРАВЛЕНО | Агент проверяет наличие ключа |
|
|
||||||
|
|
||||||
### 🚀 **ДОПОЛНИТЕЛЬНЫЕ УЛУЧШЕНИЯ:**
|
|
||||||
|
|
||||||
- ✅ **Автоматический SSL** - certbot контейнер для получения сертификатов
|
|
||||||
- ✅ **HTTPS редирект** - принудительный переход на HTTPS
|
|
||||||
- ✅ **Автообновление SSL** - cron задача для ежедневного обновления
|
|
||||||
- ✅ **Универсальность** - работает на любом VDS (с nginx или без)
|
|
||||||
- ✅ **Безопасность** - современные SSL настройки + полная защита
|
|
||||||
- ✅ **Health checks** - проверка состояния всех контейнеров
|
|
||||||
- ✅ **Fail2ban** - защита от SSH и HTTP атак
|
|
||||||
|
|
||||||
### 🎯 **ИТОГОВАЯ АРХИТЕКТУРА:**
|
|
||||||
|
|
||||||
```
|
|
||||||
Интернет → Docker nginx (порты 80/443) → Docker контейнеры
|
|
||||||
├── HTTP → HTTPS редирект
|
|
||||||
├── Frontend (порт 5173)
|
|
||||||
├── Backend API (порт 8000)
|
|
||||||
├── WebSocket (порт 8000/ws)
|
|
||||||
└── Certbot (автообновление SSL)
|
|
||||||
```
|
|
||||||
|
|
||||||
**Система полностью готова к продакшну!** 🚀
|
|
||||||
|
|
||||||
### **Безопасность:**
|
|
||||||
- Агент работает в Docker контейнере, порт 3000 проброшен на хост
|
|
||||||
- SSH ключи монтируются в режиме только чтения
|
|
||||||
- Docker socket доступен только для управления контейнерами
|
|
||||||
- Все операции логируются для аудита
|
|
||||||
- Доступен локально через `http://localhost:3000`
|
|
||||||
|
|
||||||
## 🔧 **Исправления SSH проблем (v1.1):**
|
|
||||||
|
|
||||||
### **Проблема:**
|
|
||||||
SSH команды падали с ошибкой `Bad owner or permissions on /root/.ssh/config`, что препятствовало подключению к VDS серверам.
|
|
||||||
|
|
||||||
### **Решение:**
|
|
||||||
1. **Dockerfile:** Добавлено создание SSH конфига с правильными правами доступа (600)
|
|
||||||
2. **SSH утилиты:** Добавлена функция `fixSshPermissions()` для автоматического исправления прав
|
|
||||||
3. **Создание ключей:** Улучшена функция создания SSH ключей с установкой правильных прав доступа
|
|
||||||
4. **Предварительная проверка:** Каждая SSH/SCP команда теперь автоматически исправляет права доступа
|
|
||||||
|
|
||||||
### **Результат:**
|
|
||||||
- ✅ Устранена ошибка "Bad owner or permissions on /root/.ssh/config"
|
|
||||||
- ✅ Повышена надежность SSH подключений
|
|
||||||
- ✅ Автоматическое исправление прав доступа
|
|
||||||
- ✅ Сохранена вся существующая функциональность
|
|
||||||
|
|
||||||
## 🚨 **Важно:**
|
|
||||||
Агент имеет расширенные права для автоматизации развертывания. Используйте только на доверенных серверах и в защищенных сетях.
|
|
||||||
|
|
||||||
**Агент выполняет полную автоматизацию развертывания от чистого VDS до работающего приложения!** 🚀
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**© 2024-2025 Тарабанов Александр Викторович. Все права защищены.**
|
|
||||||
Reference in New Issue
Block a user