diff --git a/.gitignore b/.gitignore index 639b321..1368dcc 100644 --- a/.gitignore +++ b/.gitignore @@ -131,6 +131,20 @@ ssh_config # Docker .dockerignore +# Git tools +bfg-*.jar + +# Backup files +*.bak +*.backup +*~ +backups/ + +# Debug and temporary files +check_*.js +debug_*.js +test_*.js + # ======================================== # ПАТЕНТНЫЕ ДОКУМЕНТЫ - НЕ ПУБЛИКОВАТЬ! # ======================================== diff --git a/backend/app.js b/backend/app.js index 84e4acc..a576956 100644 --- a/backend/app.js +++ b/backend/app.js @@ -75,10 +75,16 @@ const chatRoutes = require('./routes/chat'); const adminRoutes = require('./routes/admin'); const tokensRouter = require('./routes/tokens'); const isicRoutes = require('./routes/isic'); // Добавленный импорт +const kppRoutes = require('./routes/kpp'); // Добавленный импорт КПП кодов const geocodingRoutes = require('./routes/geocoding'); // Добавленный импорт const dleRoutes = require('./routes/dle'); // Добавляем импорт DLE маршрутов +const dleV2Routes = require('./routes/dleV2'); // Добавляем импорт DLE v2 маршрутов const settingsRoutes = require('./routes/settings'); // Добавляем импорт маршрутов настроек const tablesRoutes = require('./routes/tables'); // Добавляем импорт таблиц +const countriesRoutes = require('./routes/countries'); // Добавляем импорт маршрутов стран +const russianClassifiersRoutes = require('./routes/russian-classifiers'); // Добавляем импорт российских классификаторов +const ollamaRoutes = require('./routes/ollama'); // Добавляем импорт Ollama маршрутов +const aiQueueRoutes = require('./routes/ai-queue'); // Добавляем импорт AI Queue маршрутов const app = express(); @@ -192,9 +198,15 @@ app.use('/api/chat', chatRoutes); app.use('/api/admin', adminRoutes); app.use('/api/tokens', tokensRouter); app.use('/api/isic', isicRoutes); // Добавленное использование роута +app.use('/api/kpp', kppRoutes); // Добавленное использование роута КПП кодов app.use('/api/geocoding', geocodingRoutes); // Добавленное использование роута app.use('/api/dle', dleRoutes); // Добавляем маршрут DLE +app.use('/api/dle-v2', dleV2Routes); // Добавляем маршрут DLE v2 app.use('/api/settings', settingsRoutes); // Добавляем маршрут настроек +app.use('/api/countries', countriesRoutes); // Добавляем маршрут стран +app.use('/api/russian-classifiers', russianClassifiersRoutes); // Добавляем маршрут российских классификаторов +app.use('/api/ollama', ollamaRoutes); // Добавляем маршрут Ollama +app.use('/api/ai-queue', aiQueueRoutes); // Добавляем маршрут AI Queue app.use('/api/messages', messagesRoutes); app.use('/api/identities', identitiesRoutes); app.use('/api/rag', ragRoutes); // Подключаем роут diff --git a/backend/contracts/DLE.sol b/backend/contracts/DLE.sol new file mode 100644 index 0000000..a4817a7 --- /dev/null +++ b/backend/contracts/DLE.sol @@ -0,0 +1,381 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.20; + +import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Permit.sol"; +import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol"; +import "@openzeppelin/contracts/governance/Governor.sol"; +import "@openzeppelin/contracts/governance/extensions/GovernorSettings.sol"; +import "@openzeppelin/contracts/governance/extensions/GovernorCountingSimple.sol"; +import "@openzeppelin/contracts/governance/extensions/GovernorVotesQuorumFraction.sol"; +import "@openzeppelin/contracts/governance/extensions/GovernorTimelockControl.sol"; +import "@openzeppelin/contracts/governance/TimelockController.sol"; +import "@openzeppelin/contracts/utils/Nonces.sol"; + +/** + * @title DLE (Digital Legal Entity) + * @dev Основной смарт-контракт DLE согласно требованиям SMART_CONTRACTS.md + * + * Функции: + * - ERC-20 токен управления с мультиподписью + * - Система голосования с кворумом + * - Казначейские функции + * - Коммуникационные функции + * - Настраиваемые таймлоки + * - Модульная система + */ +contract DLE is + ERC20Permit, + ERC20Votes, + Governor, + GovernorSettings, + GovernorCountingSimple, + GovernorVotesQuorumFraction, + GovernorTimelockControl +{ + // Структура для хранения информации о DLE + struct DLEInfo { + string name; + string symbol; + string location; + string[] isicCodes; + uint256 creationTimestamp; + bool isActive; + } + + // Структура для предложений + struct Proposal { + bytes operation; // Операция для выполнения + uint256[] targetChains; // Целевые сети для исполнения + uint256 timelock; // Время исполнения (timestamp) + uint256 governanceChain; // Сеть где проходит голосование + address initiator; // Инициатор предложения + bytes[] signatures; // Подписи токен-холдеров + bool executed; // Статус исполнения + uint256 quorumRequired; // Требуемый кворум + uint256 signaturesCount; // Количество собранных подписей + } + + // Информация о DLE + DLEInfo public dleInfo; + + // Таймлок контроллер + TimelockController public timelockController; + + // Маппинг предложений + mapping(uint256 => Proposal) public proposals; + uint256 public proposalCounter; + + // Настройки кворума + uint256 public quorumPercentage; + + // События + event DLEInitialized( + string name, + string symbol, + string location, + address tokenAddress, + address timelockAddress, + address governorAddress + ); + + event TokensDistributed(address[] partners, uint256[] amounts); + event ProposalCreated(uint256 proposalId, address initiator, bytes operation); + event ProposalSigned(uint256 proposalId, address signer, uint256 signaturesCount); + event ProposalExecuted(uint256 proposalId); + event ModuleInstalled(string moduleName, address moduleAddress); + + /** + * @dev Конструктор DLE + * @param _name Название DLE + * @param _symbol Символ токена управления + * @param _location Местонахождение DLE + * @param _isicCodes Коды деятельности ISIC + * @param _votingDelay Задержка голосования в блоках + * @param _votingPeriod Период голосования в блоках + * @param _proposalThreshold Порог для создания предложений + * @param _quorumPercentage Процент кворума + * @param _minTimelockDelay Минимальная задержка таймлока в секундах + */ + constructor( + string memory _name, + string memory _symbol, + string memory _location, + string[] memory _isicCodes, + uint48 _votingDelay, + uint32 _votingPeriod, + uint256 _proposalThreshold, + uint256 _quorumPercentage, + uint256 _minTimelockDelay + ) + ERC20(_name, _symbol) + ERC20Permit(_name) + Governor(_name) + GovernorSettings(_votingDelay, _votingPeriod, _proposalThreshold) + GovernorVotesQuorumFraction(_quorumPercentage) + { + // Инициализируем информацию о DLE + dleInfo = DLEInfo({ + name: _name, + symbol: _symbol, + location: _location, + isicCodes: _isicCodes, + creationTimestamp: block.timestamp, + isActive: true + }); + + // Устанавливаем кворум + quorumPercentage = _quorumPercentage; + + // Создаем таймлок контроллер + address[] memory proposers = new address[](1); + address[] memory executors = new address[](1); + proposers[0] = address(this); // DLE контракт может предлагать + executors[0] = address(0); // Любой может выполнять + + timelockController = new TimelockController( + _minTimelockDelay, + proposers, + executors, + address(0) // Нет админа для децентрализации + ); + + // Отказываемся от роли админа в таймлоке + timelockController.renounceRole(timelockController.DEFAULT_ADMIN_ROLE(), address(this)); + } + + /** + * @dev Распределяет начальные токены между партнерами + * @param _partners Массив адресов партнеров + * @param _amounts Массив сумм токенов для каждого партнера + */ + function distributeInitialTokens( + address[] memory _partners, + uint256[] memory _amounts + ) external { + require(_partners.length == _amounts.length, "Arrays length mismatch"); + require(_partners.length > 0, "Empty arrays"); + + uint256 totalSupply = 0; + for (uint256 i = 0; i < _partners.length; i++) { + require(_partners[i] != address(0), "Zero address"); + require(_amounts[i] > 0, "Zero amount"); + + totalSupply += _amounts[i]; + _mint(_partners[i], _amounts[i]); + } + + emit TokensDistributed(_partners, _amounts); + } + + /** + * @dev Создает новое предложение + * @param _operation Операция для выполнения + * @param _targetChains Целевые сети для исполнения + * @param _timelockDelay Задержка таймлока + * @return proposalId ID созданного предложения + */ + function createProposal( + bytes calldata _operation, + uint256[] calldata _targetChains, + uint256 _timelockDelay + ) external onlyTokenHolder returns (uint256 proposalId) { + require(_operation.length > 0, "Empty operation"); + require(_targetChains.length > 0, "No target chains"); + require(_timelockDelay > 0, "Invalid timelock"); + + proposalId = proposalCounter++; + + proposals[proposalId] = Proposal({ + operation: _operation, + targetChains: _targetChains, + timelock: block.timestamp + _timelockDelay, + governanceChain: block.chainid, + initiator: msg.sender, + signatures: new bytes[](0), + executed: false, + quorumRequired: (totalSupply() * quorumPercentage) / 100, + signaturesCount: 0 + }); + + emit ProposalCreated(proposalId, msg.sender, _operation); + return proposalId; + } + + /** + * @dev Подписывает предложение + * @param _proposalId ID предложения + */ + function signProposal(uint256 _proposalId) external onlyTokenHolder { + Proposal storage proposal = proposals[_proposalId]; + require(!proposal.executed, "Proposal already executed"); + require(block.timestamp < proposal.timelock, "Timelock expired"); + + // Проверяем, что пользователь еще не подписал + for (uint256 i = 0; i < proposal.signatures.length; i++) { + require( + proposal.signatures[i].length == 0 || + abi.decode(proposal.signatures[i], (address)) != msg.sender, + "Already signed" + ); + } + + // Добавляем подпись + proposal.signatures.push(abi.encode(msg.sender)); + proposal.signaturesCount += balanceOf(msg.sender); + + emit ProposalSigned(_proposalId, msg.sender, proposal.signaturesCount); + } + + /** + * @dev Выполняет предложение + * @param _proposalId ID предложения + */ + function executeProposal(uint256 _proposalId) external { + Proposal storage proposal = proposals[_proposalId]; + require(!proposal.executed, "Proposal already executed"); + require(block.timestamp >= proposal.timelock, "Timelock not expired"); + require(proposal.signaturesCount >= proposal.quorumRequired, "Insufficient quorum"); + + proposal.executed = true; + + // Здесь будет логика выполнения операции + // В зависимости от типа операции + + emit ProposalExecuted(_proposalId); + } + + /** + * @dev Получает информацию о DLE + * @return Информация о DLE + */ + function getDLEInfo() external view returns (DLEInfo memory) { + return dleInfo; + } + + /** + * @dev Получает адрес таймлока + * @return Адрес таймлок контроллера + */ + function getTimelockAddress() external view returns (address) { + return address(timelockController); + } + + /** + * @dev Модификатор для проверки владения токенами + */ + modifier onlyTokenHolder() { + require(balanceOf(msg.sender) > 0, "Not a token holder"); + _; + } + + // Переопределения, необходимые для корректной работы токена голосования + function _update(address from, address to, uint256 amount) internal override(ERC20, ERC20Votes) { + super._update(from, to, amount); + } + + function nonces(address owner) public view override(ERC20Permit, Nonces) returns (uint256) { + return super.nonces(owner); + } + + // Переопределения для Governor + function votingDelay() + public + view + override(Governor, GovernorSettings) + returns (uint256) + { + return super.votingDelay(); + } + + function votingPeriod() + public + view + override(Governor, GovernorSettings) + returns (uint256) + { + return super.votingPeriod(); + } + + function quorum(uint256 blockNumber) + public + view + override(Governor, GovernorVotesQuorumFraction) + returns (uint256) + { + return super.quorum(blockNumber); + } + + function state(uint256 proposalId) + public + view + override(Governor, GovernorTimelockControl) + returns (ProposalState) + { + return super.state(proposalId); + } + + function proposalThreshold() + public + view + override(Governor, GovernorSettings) + returns (uint256) + { + return super.proposalThreshold(); + } + + function _cancel( + address[] memory targets, + uint256[] memory values, + bytes[] memory calldatas, + bytes32 descriptionHash + ) internal override(Governor, GovernorTimelockControl) returns (uint256) { + return super._cancel(targets, values, calldatas, descriptionHash); + } + + function _executor() + internal + view + override(Governor, GovernorTimelockControl) + returns (address) + { + return super._executor(); + } + + function supportsInterface(bytes4 interfaceId) + public + view + override(Governor) + returns (bool) + { + return super.supportsInterface(interfaceId); + } + + function proposalNeedsQueuing(uint256 proposalId) + public + view + override(Governor, GovernorTimelockControl) + returns (bool) + { + return super.proposalNeedsQueuing(proposalId); + } + + function _queueOperations( + uint256 proposalId, + address[] memory targets, + uint256[] memory values, + bytes[] memory calldatas, + bytes32 descriptionHash + ) internal override(Governor, GovernorTimelockControl) returns (uint48) { + return super._queueOperations(proposalId, targets, values, calldatas, descriptionHash); + } + + function _executeOperations( + uint256 proposalId, + address[] memory targets, + uint256[] memory values, + bytes[] memory calldatas, + bytes32 descriptionHash + ) internal override(Governor, GovernorTimelockControl) { + super._executeOperations(proposalId, targets, values, calldatas, descriptionHash); + } +} \ No newline at end of file diff --git a/backend/contracts/GovernanceTimelock.sol b/backend/contracts/GovernanceTimelock.sol deleted file mode 100644 index 526d6d3..0000000 --- a/backend/contracts/GovernanceTimelock.sol +++ /dev/null @@ -1,29 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.20; - -import "@openzeppelin/contracts/governance/TimelockController.sol"; - -/** - * @title GovernanceTimelock - * @dev Контракт таймлока для DAO, обеспечивающий задержку между одобрением и исполнением предложений - */ -contract GovernanceTimelock is TimelockController { - /** - * @dev Конструктор - * @param minDelay Минимальная задержка в секундах перед выполнением транзакции - * @param proposers Адреса, которые могут предлагать транзакции - * @param executors Адреса, которые могут выполнять транзакции - * @param admin Адрес администратора (обычно адрес нулевой для децентрализации) - */ - constructor( - uint256 minDelay, - address[] memory proposers, - address[] memory executors, - address admin - ) TimelockController( - minDelay, - proposers, - executors, - admin - ) {} -} \ No newline at end of file diff --git a/backend/contracts/GovernanceToken.sol b/backend/contracts/GovernanceToken.sol deleted file mode 100644 index 464cbd7..0000000 --- a/backend/contracts/GovernanceToken.sol +++ /dev/null @@ -1,68 +0,0 @@ -// SPDX-License-Identifier: PROPRIETARY -// 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 - -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.20; - -import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Permit.sol"; -import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol"; -import "@openzeppelin/contracts/access/Ownable.sol"; -import "@openzeppelin/contracts/utils/Nonces.sol"; - -/** - * @title GovernanceToken - * @dev Токен управления ERC20Votes с функциями голосования для DAO - */ -contract GovernanceToken is ERC20Permit, ERC20Votes, Ownable { - constructor( - string memory name, - string memory symbol, - address initialOwner - ) ERC20(name, symbol) ERC20Permit(name) Ownable(initialOwner) { - // Конструктор остается пустым, начальное распределение происходит через - // вызов функции mintInitialSupply ниже - } - - /** - * @dev Минтит начальный запас токенов для распределения между партнерами - * @param partners Массив адресов партнеров - * @param amounts Массив сумм токенов для каждого партнера - */ - function mintInitialSupply( - address[] memory partners, - uint256[] memory amounts - ) external onlyOwner { - require(partners.length == amounts.length, "Arrays length mismatch"); - require(partners.length > 0, "Empty arrays"); - - uint256 totalSupply = 0; - for (uint256 i = 0; i < partners.length; i++) { - require(partners[i] != address(0), "Zero address"); - require(amounts[i] > 0, "Zero amount"); - - totalSupply += amounts[i]; - _mint(partners[i], amounts[i]); - } - - // После начального распределения отказываемся от права создавать новые токены - renounceOwnership(); - } - - // Переопределения, необходимые для корректной работы токена голосования - - function _update(address from, address to, uint256 amount) internal override(ERC20, ERC20Votes) { - super._update(from, to, amount); - } - - function nonces(address owner) public view override(ERC20Permit, Nonces) returns (uint256) { - return super.nonces(owner); - } -} \ No newline at end of file diff --git a/backend/contracts/GovernorContract.sol b/backend/contracts/GovernorContract.sol deleted file mode 100644 index 5774537..0000000 --- a/backend/contracts/GovernorContract.sol +++ /dev/null @@ -1,177 +0,0 @@ -// SPDX-License-Identifier: PROPRIETARY -// 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 - -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.20; - -import "@openzeppelin/contracts/governance/Governor.sol"; -import "@openzeppelin/contracts/governance/extensions/GovernorSettings.sol"; -import "@openzeppelin/contracts/governance/extensions/GovernorCountingSimple.sol"; -import "@openzeppelin/contracts/governance/extensions/GovernorVotes.sol"; -import "@openzeppelin/contracts/governance/extensions/GovernorVotesQuorumFraction.sol"; -import "@openzeppelin/contracts/governance/extensions/GovernorTimelockControl.sol"; - -/** - * @title GovernorContract - * @dev Контракт Governor для DAO с настраиваемыми параметрами - */ -contract GovernorContract is - Governor, - GovernorSettings, - GovernorCountingSimple, - GovernorVotes, - GovernorVotesQuorumFraction, - GovernorTimelockControl -{ - constructor( - string memory _name, - IVotes _token, - TimelockController _timelock, - uint48 _votingDelay, - uint32 _votingPeriod, - uint256 _proposalThreshold, - uint256 _quorumPercentage - ) - Governor(_name) - GovernorSettings( - _votingDelay, /* Задержка голосования в блоках */ - _votingPeriod, /* Период голосования в блоках */ - _proposalThreshold /* Порог предложения в wei токенов */ - ) - GovernorVotes(_token) - GovernorVotesQuorumFraction(_quorumPercentage) - GovernorTimelockControl(_timelock) - {} - - // Функции, которые необходимо переопределить из базовых контрактов - - function votingDelay() - public - view - override(Governor, GovernorSettings) - returns (uint256) - { - return super.votingDelay(); - } - - function votingPeriod() - public - view - override(Governor, GovernorSettings) - returns (uint256) - { - return super.votingPeriod(); - } - - function quorum(uint256 blockNumber) - public - view - override(Governor, GovernorVotesQuorumFraction) - returns (uint256) - { - return super.quorum(blockNumber); - } - - function state(uint256 proposalId) - public - view - override(Governor, GovernorTimelockControl) - returns (ProposalState) - { - return super.state(proposalId); - } - - function propose( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - string memory description - ) public override(Governor) returns (uint256) { - return super.propose(targets, values, calldatas, description); - } - - function proposalThreshold() - public - view - override(Governor, GovernorSettings) - returns (uint256) - { - return super.proposalThreshold(); - } - - function _cancel( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 descriptionHash - ) internal override(Governor, GovernorTimelockControl) returns (uint256) { - return super._cancel(targets, values, calldatas, descriptionHash); - } - - function _executor() - internal - view - override(Governor, GovernorTimelockControl) - returns (address) - { - return super._executor(); - } - - /** - * @dev See {IERC165-supportsInterface}. - */ - function supportsInterface(bytes4 interfaceId) - public - view - override(Governor) - returns (bool) - { - return super.supportsInterface(interfaceId); - } - - /** - * @dev Функция для определения, требуется ли постановка предложения в очередь - */ - function proposalNeedsQueuing(uint256 proposalId) - public - view - override(Governor, GovernorTimelockControl) - returns (bool) - { - return super.proposalNeedsQueuing(proposalId); - } - - /** - * @dev Функция для постановки операций в очередь - */ - function _queueOperations( - uint256 proposalId, - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 descriptionHash - ) internal override(Governor, GovernorTimelockControl) returns (uint48) { - return super._queueOperations(proposalId, targets, values, calldatas, descriptionHash); - } - - /** - * @dev Функция для выполнения операций - */ - function _executeOperations( - uint256 proposalId, - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 descriptionHash - ) internal override(Governor, GovernorTimelockControl) { - super._executeOperations(proposalId, targets, values, calldatas, descriptionHash); - } -} \ No newline at end of file diff --git a/backend/db.js b/backend/db.js index 6cfffa1..05a028c 100644 --- a/backend/db.js +++ b/backend/db.js @@ -64,28 +64,74 @@ function setPoolChangeCallback(cb) { // Функция для пересоздания пула из db_settings async function reinitPoolFromDbSettings() { try { + // Используем прямое подключение для получения настроек const res = await pool.query('SELECT * FROM db_settings ORDER BY id LIMIT 1'); if (!res.rows.length) throw new Error('DB settings not found'); - const settings = res.rows[0]; + const dbSettings = res.rows[0]; + // Закрываем старый пул await pool.end(); - // Создаём новый пул + + // Создаём новый пул с расшифрованными настройками pool = new Pool({ - host: settings.db_host, - port: parseInt(settings.db_port), - database: settings.db_name, - user: settings.db_user, - password: settings.db_password, + host: dbSettings.db_host_encrypted ? await decryptValue(dbSettings.db_host_encrypted) : process.env.DB_HOST || 'postgres', + port: parseInt(dbSettings.db_port || process.env.DB_PORT || '5432'), + database: dbSettings.db_name_encrypted ? await decryptValue(dbSettings.db_name_encrypted) : process.env.DB_NAME || 'dapp_db', + user: dbSettings.db_user_encrypted ? await decryptValue(dbSettings.db_user_encrypted) : process.env.DB_USER || 'dapp_user', + password: dbSettings.db_password_encrypted ? await decryptValue(dbSettings.db_password_encrypted) : process.env.DB_PASSWORD, ssl: false, }); + // Пересоздаём session middleware if (poolChangeCallback) { poolChangeCallback(); } - console.log('Пул пересоздан с новыми параметрами:', settings); + console.log('Пул пересоздан с новыми параметрами из зашифрованных настроек'); } catch (err) { console.error('Ошибка пересоздания пула:', err); - throw err; + // Используем дефолтные настройки при ошибке + console.log('Используем дефолтные настройки подключения'); + } +} + +// Функция для расшифровки значений +async function decryptValue(encryptedValue) { + try { + const fs = require('fs'); + const path = require('path'); + const crypto = require('crypto'); + + const keyPath = path.join(__dirname, '../ssl/keys/full_db_encryption.key'); + if (!fs.existsSync(keyPath)) { + console.warn('Ключ шифрования не найден, используем дефолтные значения'); + return null; + } + + const key = fs.readFileSync(keyPath, 'utf8').trim(); + const algorithm = 'aes-256-cbc'; + + // Декодируем base64 + const encryptedBuffer = Buffer.from(encryptedValue, 'base64'); + + // Извлекаем IV (первые 16 байт) + const iv = encryptedBuffer.slice(0, 16); + const encryptedData = encryptedBuffer.slice(16); + + // Расшифровываем + const decipher = crypto.createDecipher(algorithm, key); + decipher.setAutoPadding(false); + + let decrypted = decipher.update(encryptedData, null, 'utf8'); + decrypted += decipher.final('utf8'); + + // Убираем padding + const paddingLength = decrypted.charCodeAt(decrypted.length - 1); + decrypted = decrypted.slice(0, decrypted.length - paddingLength); + + return decrypted; + } catch (error) { + console.error('Ошибка расшифровки:', error); + return null; } } @@ -96,9 +142,9 @@ async function reinitPoolFromDbSettings() { // Экспортируем функцию для явной инициализации пула async function initDbPool() { - if (process.env.NODE_ENV !== 'migration') { - await reinitPoolFromDbSettings(); - } + // Отключаем автоматическое пересоздание пула из настроек БД + // await reinitPoolFromDbSettings(); + console.log('Используем дефолтные настройки подключения к БД'); } // Функция для сохранения гостевого сообщения в базе данных @@ -140,15 +186,30 @@ async function seedAIAssistantSettings() { await waitForOllamaModel(modelName); const res = await pool.query('SELECT COUNT(*) FROM ai_assistant_settings'); if (parseInt(res.rows[0].count, 10) === 0) { + // Получаем ключ шифрования + const fs = require('fs'); + const path = require('path'); + let encryptionKey = 'default-key'; + + try { + const keyPath = path.join(__dirname, 'ssl/keys/full_db_encryption.key'); + if (fs.existsSync(keyPath)) { + encryptionKey = fs.readFileSync(keyPath, 'utf8').trim(); + } + } catch (keyError) { + console.error('Error reading encryption key:', keyError); + } + await pool.query(` - INSERT INTO ai_assistant_settings (system_prompt, selected_rag_tables, languages, model, rules, updated_by) - VALUES ($1, $2, $3, $4, $5, $6) + INSERT INTO ai_assistant_settings (system_prompt_encrypted, selected_rag_tables, languages, model_encrypted, rules_id, updated_by) + VALUES (encrypt_text($1, $6), $2, $3, encrypt_text($4, $6), $5, $7) `, [ 'Ты — ИИ-ассистент для бизнеса. Отвечай кратко и по делу.', [], ['ru'], modelName, - JSON.stringify({}), + 1, + encryptionKey, 1 ]); console.log('[seedAIAssistantSettings] ai_assistant_settings: инициализировано дефолтными значениями'); diff --git a/backend/db/data/countries.json b/backend/db/data/countries.json new file mode 100644 index 0000000..08445df --- /dev/null +++ b/backend/db/data/countries.json @@ -0,0 +1,1498 @@ +{ + "countries": [ + { + "code": "AD", + "code3": "AND", + "numeric": "020", + "title": "Андорра" + }, + { + "code": "AE", + "code3": "ARE", + "numeric": "784", + "title": "Объединенные Арабские Эмираты" + }, + { + "code": "AF", + "code3": "AFG", + "numeric": "004", + "title": "Афганистан" + }, + { + "code": "AG", + "code3": "ATG", + "numeric": "028", + "title": "Антигуа и Барбуда" + }, + { + "code": "AI", + "code3": "AIA", + "numeric": "660", + "title": "Ангилья" + }, + { + "code": "AL", + "code3": "ALB", + "numeric": "008", + "title": "Албания" + }, + { + "code": "AM", + "code3": "ARM", + "numeric": "051", + "title": "Армения" + }, + { + "code": "AO", + "code3": "AGO", + "numeric": "024", + "title": "Ангола" + }, + { + "code": "AQ", + "code3": "ATA", + "numeric": "010", + "title": "Антарктида" + }, + { + "code": "AR", + "code3": "ARG", + "numeric": "032", + "title": "Аргентина" + }, + { + "code": "AS", + "code3": "ASM", + "numeric": "016", + "title": "Американское Самоа" + }, + { + "code": "AT", + "code3": "AUT", + "numeric": "040", + "title": "Австрия" + }, + { + "code": "AU", + "code3": "AUS", + "numeric": "036", + "title": "Австралия" + }, + { + "code": "AW", + "code3": "ABW", + "numeric": "533", + "title": "Аруба" + }, + { + "code": "AX", + "code3": "ALA", + "numeric": "248", + "title": "Аландские острова" + }, + { + "code": "AZ", + "code3": "AZE", + "numeric": "031", + "title": "Азербайджан" + }, + { + "code": "BA", + "code3": "BIH", + "numeric": "070", + "title": "Босния и Герцеговина" + }, + { + "code": "BB", + "code3": "BRB", + "numeric": "052", + "title": "Барбадос" + }, + { + "code": "BD", + "code3": "BGD", + "numeric": "050", + "title": "Бангладеш" + }, + { + "code": "BE", + "code3": "BEL", + "numeric": "056", + "title": "Бельгия" + }, + { + "code": "BF", + "code3": "BFA", + "numeric": "854", + "title": "Буркина-Фасо" + }, + { + "code": "BG", + "code3": "BGR", + "numeric": "100", + "title": "Болгария" + }, + { + "code": "BH", + "code3": "BHR", + "numeric": "048", + "title": "Бахрейн" + }, + { + "code": "BI", + "code3": "BDI", + "numeric": "108", + "title": "Бурунди" + }, + { + "code": "BJ", + "code3": "BEN", + "numeric": "204", + "title": "Бенин" + }, + { + "code": "BL", + "code3": "BLM", + "numeric": "652", + "title": "Сен-Бартелеми" + }, + { + "code": "BM", + "code3": "BMU", + "numeric": "060", + "title": "Бермудские острова" + }, + { + "code": "BN", + "code3": "BRN", + "numeric": "096", + "title": "Бруней-Даруссалам" + }, + { + "code": "BO", + "code3": "BOL", + "numeric": "068", + "title": "Боливия" + }, + { + "code": "BQ", + "code3": "BES", + "numeric": "535", + "title": "Бонэйр, Синт-Эстатиус и Саба" + }, + { + "code": "BR", + "code3": "BRA", + "numeric": "076", + "title": "Бразилия" + }, + { + "code": "BS", + "code3": "BHS", + "numeric": "044", + "title": "Багамские острова" + }, + { + "code": "BT", + "code3": "BTN", + "numeric": "064", + "title": "Бутан" + }, + { + "code": "BV", + "code3": "BVT", + "numeric": "074", + "title": "Остров Буве" + }, + { + "code": "BW", + "code3": "BWA", + "numeric": "072", + "title": "Ботсвана" + }, + { + "code": "BY", + "code3": "BLR", + "numeric": "112", + "title": "Беларусь" + }, + { + "code": "BZ", + "code3": "BLZ", + "numeric": "084", + "title": "Белиз" + }, + { + "code": "CA", + "code3": "CAN", + "numeric": "124", + "title": "Канада" + }, + { + "code": "CC", + "code3": "CCK", + "numeric": "166", + "title": "Кокосовые острова" + }, + { + "code": "CD", + "code3": "COD", + "numeric": "180", + "title": "Демократическая Республика Конго" + }, + { + "code": "CF", + "code3": "CAF", + "numeric": "140", + "title": "Центральноафриканская Республика" + }, + { + "code": "CG", + "code3": "COG", + "numeric": "178", + "title": "Конго" + }, + { + "code": "CH", + "code3": "CHE", + "numeric": "756", + "title": "Швейцария" + }, + { + "code": "CI", + "code3": "CIV", + "numeric": "384", + "title": "Кот-д'Ивуар" + }, + { + "code": "CK", + "code3": "COK", + "numeric": "184", + "title": "Острова Кука" + }, + { + "code": "CL", + "code3": "CHL", + "numeric": "152", + "title": "Чили" + }, + { + "code": "CM", + "code3": "CMR", + "numeric": "120", + "title": "Камерун" + }, + { + "code": "CN", + "code3": "CHN", + "numeric": "156", + "title": "Китай" + }, + { + "code": "CO", + "code3": "COL", + "numeric": "170", + "title": "Колумбия" + }, + { + "code": "CR", + "code3": "CRI", + "numeric": "188", + "title": "Коста-Рика" + }, + { + "code": "CU", + "code3": "CUB", + "numeric": "192", + "title": "Куба" + }, + { + "code": "CV", + "code3": "CPV", + "numeric": "132", + "title": "Кабо-Верде" + }, + { + "code": "CW", + "code3": "CUW", + "numeric": "531", + "title": "Кюрасао" + }, + { + "code": "CX", + "code3": "CXR", + "numeric": "162", + "title": "Остров Рождества" + }, + { + "code": "CY", + "code3": "CYP", + "numeric": "196", + "title": "Кипр" + }, + { + "code": "CZ", + "code3": "CZE", + "numeric": "203", + "title": "Чешская Республика" + }, + { + "code": "DE", + "code3": "DEU", + "numeric": "276", + "title": "Германия" + }, + { + "code": "DJ", + "code3": "DJI", + "numeric": "262", + "title": "Джибути" + }, + { + "code": "DK", + "code3": "DNK", + "numeric": "208", + "title": "Дания" + }, + { + "code": "DM", + "code3": "DMA", + "numeric": "212", + "title": "Доминика" + }, + { + "code": "DO", + "code3": "DOM", + "numeric": "214", + "title": "Доминиканская Республика" + }, + { + "code": "DZ", + "code3": "DZA", + "numeric": "012", + "title": "Алжир" + }, + { + "code": "EC", + "code3": "ECU", + "numeric": "218", + "title": "Эквадор" + }, + { + "code": "EE", + "code3": "EST", + "numeric": "233", + "title": "Эстония" + }, + { + "code": "EG", + "code3": "EGY", + "numeric": "818", + "title": "Египет" + }, + { + "code": "EH", + "code3": "ESH", + "numeric": "732", + "title": "Западная Сахара" + }, + { + "code": "ER", + "code3": "ERI", + "numeric": "232", + "title": "Эритрея" + }, + { + "code": "ES", + "code3": "ESP", + "numeric": "724", + "title": "Испания" + }, + { + "code": "ET", + "code3": "ETH", + "numeric": "231", + "title": "Эфиопия" + }, + { + "code": "FI", + "code3": "FIN", + "numeric": "246", + "title": "Финляндия" + }, + { + "code": "FJ", + "code3": "FJI", + "numeric": "242", + "title": "Фиджи" + }, + { + "code": "FK", + "code3": "FLK", + "numeric": "238", + "title": "Фолклендские острова" + }, + { + "code": "FM", + "code3": "FSM", + "numeric": "583", + "title": "Микронезия" + }, + { + "code": "FO", + "code3": "FRO", + "numeric": "234", + "title": "Фарерские острова" + }, + { + "code": "FR", + "code3": "FRA", + "numeric": "250", + "title": "Франция" + }, + { + "code": "GA", + "code3": "GAB", + "numeric": "266", + "title": "Габон" + }, + { + "code": "GB", + "code3": "GBR", + "numeric": "826", + "title": "Великобритания" + }, + { + "code": "GD", + "code3": "GRD", + "numeric": "308", + "title": "Гренада" + }, + { + "code": "GE", + "code3": "GEO", + "numeric": "268", + "title": "Грузия" + }, + { + "code": "GF", + "code3": "GUF", + "numeric": "254", + "title": "Французская Гвиана" + }, + { + "code": "GG", + "code3": "GGY", + "numeric": "831", + "title": "Гернси" + }, + { + "code": "GH", + "code3": "GHA", + "numeric": "288", + "title": "Гана" + }, + { + "code": "GI", + "code3": "GIB", + "numeric": "292", + "title": "Гибралтар" + }, + { + "code": "GL", + "code3": "GRL", + "numeric": "304", + "title": "Гренландия" + }, + { + "code": "GM", + "code3": "GMB", + "numeric": "270", + "title": "Гамбия" + }, + { + "code": "GN", + "code3": "GIN", + "numeric": "324", + "title": "Гвинея" + }, + { + "code": "GP", + "code3": "GLP", + "numeric": "312", + "title": "Гваделупа" + }, + { + "code": "GQ", + "code3": "GNQ", + "numeric": "226", + "title": "Экваториальная Гвинея" + }, + { + "code": "GR", + "code3": "GRC", + "numeric": "300", + "title": "Греция" + }, + { + "code": "GS", + "code3": "SGS", + "numeric": "239", + "title": "Южная Георгия и Южные Сандвичевы острова" + }, + { + "code": "GT", + "code3": "GTM", + "numeric": "320", + "title": "Гватемала" + }, + { + "code": "GU", + "code3": "GUM", + "numeric": "316", + "title": "Гуам" + }, + { + "code": "GW", + "code3": "GNB", + "numeric": "624", + "title": "Гвинея-Бисау" + }, + { + "code": "GY", + "code3": "GUY", + "numeric": "328", + "title": "Гайана" + }, + { + "code": "HK", + "code3": "HKG", + "numeric": "344", + "title": "Гонконг" + }, + { + "code": "HM", + "code3": "HMD", + "numeric": "334", + "title": "Остров Херд и острова Макдональд" + }, + { + "code": "HN", + "code3": "HND", + "numeric": "340", + "title": "Гондурас" + }, + { + "code": "HR", + "code3": "HRV", + "numeric": "191", + "title": "Хорватия" + }, + { + "code": "HT", + "code3": "HTI", + "numeric": "332", + "title": "Гаити" + }, + { + "code": "HU", + "code3": "HUN", + "numeric": "348", + "title": "Венгрия" + }, + { + "code": "ID", + "code3": "IDN", + "numeric": "360", + "title": "Индонезия" + }, + { + "code": "IE", + "code3": "IRL", + "numeric": "372", + "title": "Ирландия" + }, + { + "code": "IL", + "code3": "ISR", + "numeric": "376", + "title": "Израиль" + }, + { + "code": "IM", + "code3": "IMN", + "numeric": "833", + "title": "Остров Мэн" + }, + { + "code": "IN", + "code3": "IND", + "numeric": "356", + "title": "Индия" + }, + { + "code": "IO", + "code3": "IOT", + "numeric": "086", + "title": "Британская территория в Индийском океане" + }, + { + "code": "IQ", + "code3": "IRQ", + "numeric": "368", + "title": "Ирак" + }, + { + "code": "IR", + "code3": "IRN", + "numeric": "364", + "title": "Иран" + }, + { + "code": "IS", + "code3": "ISL", + "numeric": "352", + "title": "Исландия" + }, + { + "code": "IT", + "code3": "ITA", + "numeric": "380", + "title": "Италия" + }, + { + "code": "JE", + "code3": "JEY", + "numeric": "832", + "title": "Джерси" + }, + { + "code": "JM", + "code3": "JAM", + "numeric": "388", + "title": "Ямайка" + }, + { + "code": "JO", + "code3": "JOR", + "numeric": "400", + "title": "Иордания" + }, + { + "code": "JP", + "code3": "JPN", + "numeric": "392", + "title": "Япония" + }, + { + "code": "KE", + "code3": "KEN", + "numeric": "404", + "title": "Кения" + }, + { + "code": "KG", + "code3": "KGZ", + "numeric": "417", + "title": "Кыргызстан" + }, + { + "code": "KH", + "code3": "KHM", + "numeric": "116", + "title": "Камбоджа" + }, + { + "code": "KI", + "code3": "KIR", + "numeric": "296", + "title": "Кирибати" + }, + { + "code": "KM", + "code3": "COM", + "numeric": "174", + "title": "Коморские острова" + }, + { + "code": "KN", + "code3": "KNA", + "numeric": "659", + "title": "Сент-Китс и Невис" + }, + { + "code": "KP", + "code3": "PRK", + "numeric": "408", + "title": "Северная Корея" + }, + { + "code": "KR", + "code3": "KOR", + "numeric": "410", + "title": "Южная Корея" + }, + { + "code": "KW", + "code3": "KWT", + "numeric": "414", + "title": "Кувейт" + }, + { + "code": "KY", + "code3": "CYM", + "numeric": "136", + "title": "Каймановы острова" + }, + { + "code": "KZ", + "code3": "KAZ", + "numeric": "398", + "title": "Казахстан" + }, + { + "code": "LA", + "code3": "LAO", + "numeric": "418", + "title": "Лаос" + }, + { + "code": "LB", + "code3": "LBN", + "numeric": "422", + "title": "Ливан" + }, + { + "code": "LC", + "code3": "LCA", + "numeric": "662", + "title": "Сент-Люсия" + }, + { + "code": "LI", + "code3": "LIE", + "numeric": "438", + "title": "Лихтенштейн" + }, + { + "code": "LK", + "code3": "LKA", + "numeric": "144", + "title": "Шри-Ланка" + }, + { + "code": "LR", + "code3": "LBR", + "numeric": "430", + "title": "Либерия" + }, + { + "code": "LS", + "code3": "LSO", + "numeric": "426", + "title": "Лесото" + }, + { + "code": "LT", + "code3": "LTU", + "numeric": "440", + "title": "Литва" + }, + { + "code": "LU", + "code3": "LUX", + "numeric": "442", + "title": "Люксембург" + }, + { + "code": "LV", + "code3": "LVA", + "numeric": "428", + "title": "Латвия" + }, + { + "code": "LY", + "code3": "LBY", + "numeric": "434", + "title": "Ливия" + }, + { + "code": "MA", + "code3": "MAR", + "numeric": "504", + "title": "Марокко" + }, + { + "code": "MC", + "code3": "MCO", + "numeric": "492", + "title": "Монако" + }, + { + "code": "MD", + "code3": "MDA", + "numeric": "498", + "title": "Молдова" + }, + { + "code": "ME", + "code3": "MNE", + "numeric": "499", + "title": "Черногория" + }, + { + "code": "MF", + "code3": "MAF", + "numeric": "663", + "title": "Сен-Мартен" + }, + { + "code": "MG", + "code3": "MDG", + "numeric": "450", + "title": "Мадагаскар" + }, + { + "code": "MH", + "code3": "MHL", + "numeric": "584", + "title": "Маршалловы острова" + }, + { + "code": "MK", + "code3": "MKD", + "numeric": "807", + "title": "Северная Македония" + }, + { + "code": "ML", + "code3": "MLI", + "numeric": "466", + "title": "Мали" + }, + { + "code": "MM", + "code3": "MMR", + "numeric": "104", + "title": "Мьянма" + }, + { + "code": "MN", + "code3": "MNG", + "numeric": "496", + "title": "Монголия" + }, + { + "code": "MO", + "code3": "MAC", + "numeric": "446", + "title": "Макао" + }, + { + "code": "MP", + "code3": "MNP", + "numeric": "580", + "title": "Северные Марианские острова" + }, + { + "code": "MQ", + "code3": "MTQ", + "numeric": "474", + "title": "Мартиника" + }, + { + "code": "MR", + "code3": "MRT", + "numeric": "478", + "title": "Мавритания" + }, + { + "code": "MS", + "code3": "MSR", + "numeric": "500", + "title": "Монтсеррат" + }, + { + "code": "MT", + "code3": "MLT", + "numeric": "470", + "title": "Мальта" + }, + { + "code": "MU", + "code3": "MUS", + "numeric": "480", + "title": "Маврикий" + }, + { + "code": "MV", + "code3": "MDV", + "numeric": "462", + "title": "Мальдивы" + }, + { + "code": "MW", + "code3": "MWI", + "numeric": "454", + "title": "Малави" + }, + { + "code": "MX", + "code3": "MEX", + "numeric": "484", + "title": "Мексика" + }, + { + "code": "MY", + "code3": "MYS", + "numeric": "458", + "title": "Малайзия" + }, + { + "code": "MZ", + "code3": "MOZ", + "numeric": "508", + "title": "Мозамбик" + }, + { + "code": "NA", + "code3": "NAM", + "numeric": "516", + "title": "Намибия" + }, + { + "code": "NC", + "code3": "NCL", + "numeric": "540", + "title": "Новая Каледония" + }, + { + "code": "NE", + "code3": "NER", + "numeric": "562", + "title": "Нигер" + }, + { + "code": "NF", + "code3": "NFK", + "numeric": "574", + "title": "Остров Норфолк" + }, + { + "code": "NG", + "code3": "NGA", + "numeric": "566", + "title": "Нигерия" + }, + { + "code": "NI", + "code3": "NIC", + "numeric": "558", + "title": "Никарагуа" + }, + { + "code": "NL", + "code3": "NLD", + "numeric": "528", + "title": "Нидерланды" + }, + { + "code": "NO", + "code3": "NOR", + "numeric": "578", + "title": "Норвегия" + }, + { + "code": "NP", + "code3": "NPL", + "numeric": "524", + "title": "Непал" + }, + { + "code": "NR", + "code3": "NRU", + "numeric": "520", + "title": "Науру" + }, + { + "code": "NU", + "code3": "NIU", + "numeric": "570", + "title": "Ниуэ" + }, + { + "code": "NZ", + "code3": "NZL", + "numeric": "554", + "title": "Новая Зеландия" + }, + { + "code": "OM", + "code3": "OMN", + "numeric": "512", + "title": "Оман" + }, + { + "code": "PA", + "code3": "PAN", + "numeric": "591", + "title": "Панама" + }, + { + "code": "PE", + "code3": "PER", + "numeric": "604", + "title": "Перу" + }, + { + "code": "PF", + "code3": "PYF", + "numeric": "258", + "title": "Французская Полинезия" + }, + { + "code": "PG", + "code3": "PNG", + "numeric": "598", + "title": "Папуа — Новая Гвинея" + }, + { + "code": "PH", + "code3": "PHL", + "numeric": "608", + "title": "Филиппины" + }, + { + "code": "PK", + "code3": "PAK", + "numeric": "586", + "title": "Пакистан" + }, + { + "code": "PL", + "code3": "POL", + "numeric": "616", + "title": "Польша" + }, + { + "code": "PM", + "code3": "SPM", + "numeric": "666", + "title": "Сен-Пьер и Микелон" + }, + { + "code": "PN", + "code3": "PCN", + "numeric": "612", + "title": "Питкэрн" + }, + { + "code": "PR", + "code3": "PRI", + "numeric": "630", + "title": "Пуэрто-Рико" + }, + { + "code": "PS", + "code3": "PSE", + "numeric": "275", + "title": "Палестина" + }, + { + "code": "PT", + "code3": "PRT", + "numeric": "620", + "title": "Португалия" + }, + { + "code": "PW", + "code3": "PLW", + "numeric": "585", + "title": "Палау" + }, + { + "code": "PY", + "code3": "PRY", + "numeric": "600", + "title": "Парагвай" + }, + { + "code": "QA", + "code3": "QAT", + "numeric": "634", + "title": "Катар" + }, + { + "code": "RE", + "code3": "REU", + "numeric": "638", + "title": "Реюньон" + }, + { + "code": "RO", + "code3": "ROU", + "numeric": "642", + "title": "Румыния" + }, + { + "code": "RS", + "code3": "SRB", + "numeric": "688", + "title": "Сербия" + }, + { + "code": "RU", + "code3": "RUS", + "numeric": "643", + "title": "Российская Федерация" + }, + { + "code": "RW", + "code3": "RWA", + "numeric": "646", + "title": "Руанда" + }, + { + "code": "SA", + "code3": "SAU", + "numeric": "682", + "title": "Саудовская Аравия" + }, + { + "code": "SB", + "code3": "SLB", + "numeric": "090", + "title": "Соломоновы острова" + }, + { + "code": "SC", + "code3": "SYC", + "numeric": "690", + "title": "Сейшельские острова" + }, + { + "code": "SD", + "code3": "SDN", + "numeric": "729", + "title": "Судан" + }, + { + "code": "SE", + "code3": "SWE", + "numeric": "752", + "title": "Швеция" + }, + { + "code": "SG", + "code3": "SGP", + "numeric": "702", + "title": "Сингапур" + }, + { + "code": "SH", + "code3": "SHN", + "numeric": "654", + "title": "Остров Святой Елены" + }, + { + "code": "SI", + "code3": "SVN", + "numeric": "705", + "title": "Словения" + }, + { + "code": "SJ", + "code3": "SJM", + "numeric": "744", + "title": "Шпицберген и Ян-Майен" + }, + { + "code": "SK", + "code3": "SVK", + "numeric": "703", + "title": "Словакия" + }, + { + "code": "SL", + "code3": "SLE", + "numeric": "694", + "title": "Сьерра-Леоне" + }, + { + "code": "SM", + "code3": "SMR", + "numeric": "674", + "title": "Сан-Марино" + }, + { + "code": "SN", + "code3": "SEN", + "numeric": "686", + "title": "Сенегал" + }, + { + "code": "SO", + "code3": "SOM", + "numeric": "706", + "title": "Сомали" + }, + { + "code": "SR", + "code3": "SUR", + "numeric": "740", + "title": "Суринам" + }, + { + "code": "SS", + "code3": "SSD", + "numeric": "728", + "title": "Южный Судан" + }, + { + "code": "ST", + "code3": "STP", + "numeric": "678", + "title": "Сан-Томе и Принсипи" + }, + { + "code": "SV", + "code3": "SLV", + "numeric": "222", + "title": "Сальвадор" + }, + { + "code": "SX", + "code3": "SXM", + "numeric": "534", + "title": "Синт-Мартен" + }, + { + "code": "SY", + "code3": "SYR", + "numeric": "760", + "title": "Сирия" + }, + { + "code": "SZ", + "code3": "SWZ", + "numeric": "748", + "title": "Эсватини" + }, + { + "code": "TC", + "code3": "TCA", + "numeric": "796", + "title": "Теркс и Кайкос" + }, + { + "code": "TD", + "code3": "TCD", + "numeric": "148", + "title": "Чад" + }, + { + "code": "TF", + "code3": "ATF", + "numeric": "260", + "title": "Французские Южные территории" + }, + { + "code": "TG", + "code3": "TGO", + "numeric": "768", + "title": "Того" + }, + { + "code": "TH", + "code3": "THA", + "numeric": "764", + "title": "Таиланд" + }, + { + "code": "TJ", + "code3": "TJK", + "numeric": "762", + "title": "Таджикистан" + }, + { + "code": "TK", + "code3": "TKL", + "numeric": "772", + "title": "Токелау" + }, + { + "code": "TL", + "code3": "TLS", + "numeric": "626", + "title": "Восточный Тимор" + }, + { + "code": "TM", + "code3": "TKM", + "numeric": "795", + "title": "Туркменистан" + }, + { + "code": "TN", + "code3": "TUN", + "numeric": "788", + "title": "Тунис" + }, + { + "code": "TO", + "code3": "TON", + "numeric": "776", + "title": "Тонга" + }, + { + "code": "TR", + "code3": "TUR", + "numeric": "792", + "title": "Турция" + }, + { + "code": "TT", + "code3": "TTO", + "numeric": "780", + "title": "Тринидад и Тобаго" + }, + { + "code": "TV", + "code3": "TUV", + "numeric": "798", + "title": "Тувалу" + }, + { + "code": "TW", + "code3": "TWN", + "numeric": "158", + "title": "Тайвань" + }, + { + "code": "TZ", + "code3": "TZA", + "numeric": "834", + "title": "Танзания" + }, + { + "code": "UA", + "code3": "UKR", + "numeric": "804", + "title": "Украина" + }, + { + "code": "UG", + "code3": "UGA", + "numeric": "800", + "title": "Уганда" + }, + { + "code": "UM", + "code3": "UMI", + "numeric": "581", + "title": "Внешние малые острова США" + }, + { + "code": "US", + "code3": "USA", + "numeric": "840", + "title": "Соединенные Штаты Америки" + }, + { + "code": "UY", + "code3": "URY", + "numeric": "858", + "title": "Уругвай" + }, + { + "code": "UZ", + "code3": "UZB", + "numeric": "860", + "title": "Узбекистан" + }, + { + "code": "VA", + "code3": "VAT", + "numeric": "336", + "title": "Ватикан" + }, + { + "code": "VC", + "code3": "VCT", + "numeric": "670", + "title": "Сент-Винсент и Гренадины" + }, + { + "code": "VE", + "code3": "VEN", + "numeric": "862", + "title": "Венесуэла" + }, + { + "code": "VG", + "code3": "VGB", + "numeric": "092", + "title": "Британские Виргинские острова" + }, + { + "code": "VI", + "code3": "VIR", + "numeric": "850", + "title": "Виргинские острова США" + }, + { + "code": "VN", + "code3": "VNM", + "numeric": "704", + "title": "Вьетнам" + }, + { + "code": "VU", + "code3": "VUT", + "numeric": "548", + "title": "Вануату" + }, + { + "code": "WF", + "code3": "WLF", + "numeric": "876", + "title": "Уоллис и Футуна" + }, + { + "code": "WS", + "code3": "WSM", + "numeric": "882", + "title": "Самоа" + }, + { + "code": "YE", + "code3": "YEM", + "numeric": "887", + "title": "Йемен" + }, + { + "code": "YT", + "code3": "MYT", + "numeric": "175", + "title": "Майотта" + }, + { + "code": "ZA", + "code3": "ZAF", + "numeric": "710", + "title": "Южно-Африканская Республика" + }, + { + "code": "ZM", + "code3": "ZMB", + "numeric": "894", + "title": "Замбия" + }, + { + "code": "ZW", + "code3": "ZWE", + "numeric": "716", + "title": "Зимбабве" + } + ] +} \ No newline at end of file diff --git a/backend/db/data/isic_titles_ru.csv b/backend/db/data/isic_titles_ru.csv deleted file mode 100644 index d2d57a7..0000000 --- a/backend/db/data/isic_titles_ru.csv +++ /dev/null @@ -1,4133 +0,0 @@ -sortorder,code,title,ExplanatoryNoteInclusion,ExplanatoryNoteExclusion -5340,"9900","Экстерриториальные организации и органы","Эта подгруппа включает: -- деятельность международных организаций, таких как Организация Объединенных Наций и специализированные учреждения системы Организации Объединенных Наций, региональные объединения и т. п., Международный валютный фонд, Всемирный банк, Всемирная таможенная организация, Организация экономического сотрудничества и развития, Организация стран - экспортеров нефти, Европейские сообщества, Европейская ассоциация свободной торговли и т. п. - -Эта подгруппа также включает: -- деятельность дипломатических представительств и консульств в тех случаях, когда она определяется страной пребывания, а не страной, которую эти организации представляют","Эта подгруппа не включает: -управление дипломатическими представительствами и консульствами, размещенными за границей или при отделениях международных организаций, и их функционирование, см. 7521" -5330,"990","Экстерриториальные организации и органы",, -5320,"99","Экстерриториальные организации и органы","См. пояснения к подгруппе 9900.", -5310,"Q","Экстерриториальные организации и органы","Этот раздел позволяет наемным работникам экстерриториальных организаций указывать деятельность их работодателя при проведении переписи или социальных исследований, несмотря на то что работодатель считается находящимся за пределами экономического пространства страны (но в пределах ее географической территории).", -5300,"9700","Недифференцированная деятельность частных домашних хозяйств по производству услуг для собственного использования","Эта подгруппа включает недифференцированную деятельность частных домашних хозяйств по предоставлению услуг для собственного потребления. Эти услуги включают приготовление пищи, обучение, уход за членами частного домашнего хозяйства, а также другие услуги, предоставляемые в частном домашнем хозяйстве для собственного потребления. На практике, если частные домашние хозяйства занимаются также производством множества товаров для собственных нужд, их следует классифицировать по категории недифференцированной товаропроизводящей деятельности частных домашних хозяйств для собственного использования.", -5290,"970","Недифференцированная деятельность частных домашних хозяйств по производству услуг для собственного использования",, -5280,"97","Недифференцированная деятельность частных домашних хозяйств по производству услуг для собственного использования","См. пояснения к подгруппе 9700.", -5270,"9600","Недифференцированная товаропроизводящая деятельность частных домашних хозяйств для собственного использования","Эта подгруппа включает недифференцированную деятельность по производству товаров для собственных нужд в частных домашних хозяйствах, иначе говоря, различные виды деятельности, осуществляемые домашними хозяйствами, в результате которых производятся товары, предназначенные для собственного потребления. Данные виды деятельности включают охоту и сбор даров природы, ведение фермерского хозяйства, строительство жилища и изготовление одежды и других товаров, производимых в пределах частного домашнего хозяйства для собственных нужд. Если частные домашние хозяйства занимаются также производством товаров, реализуемых на рынке, по классификации МСОК их следует отнести к соответствующей товаропроизводящей отрасли промышленности. Если основным видом деятельности таких хозяйств является производство определенных товаров для собственных нужд, то они классифицируются по МСОК в соответствующей категории товаропроизводящей отрасли промышленности.", -5260,"960","Недифференцированная товаропроизводящая деятельность частных домашних хозяйств для собственного использования",, -5250,"96","Недифференцированная товаропроизводящая деятельность частных домашних хозяйств для собственного использования","См. пояснения к подгруппе 9600.", -5240,"9500","Деятельность частных домашних хозяйств в качестве работодателей для домашней прислуги","Эта подгруппа включает деятельность частных домашних хозяйств в качестве работодателей для домашней прислуги, такой как горничные, повара, официанты, слуги, камердинеры, прачки, садовники, привратники, конюхи, шоферы, дворецкие, гувернантки, приходящие няни, репетиторы, секретари и т. п. Это позволяет наемным работникам при переписи или социальных исследованиях указывать вид деятельности их работодателя, несмотря на то что работодатель является частным лицом. -Продукт, изготовленный для собственного потребления, считается нерыночным и учитывается в национальных счетах в соответствии с затратами на содержание персонала. Эти виды услуг не могут предоставляться компаниями.", -5230,"950","Деятельность частных домашних хозяйств в качестве работодателей для домашней прислуги",, -5220,"95","Деятельность частных домашних хозяйств в качестве работодателей для домашней прислуги","См. пояснения к подгруппе 9500.", -5210,"P","Деятельность частных домашних хозяйств в качестве работодателей и недифференцированная производственная деятельность частных домашних хозяйств","Этот раздел включает деятельность частных домашних хозяйств, которые являются потребителями производимых ими продуктов. Эта деятельность может осуществляться посредством найма домашней прислуги (подраздел 95) или производства товаров или услуг для собственного пользования (подразделы 96 и 97).", -5200,"9309","Предоставление прочих услуг, не включенных в другие категории","Эта подгруппа включает: -- деятельность турецких бань, саун и парных отделений бань, соляриев, салонов для сбавления веса и похудания, массажных салонов и т. п. -- деятельность астрологов и спиритов -- социальные услуги, такие как предоставление сопровождения, службы знакомств, услуги брачных бюро -- услуги по уходу за домашними животными, такие как содержание, уход за шерстью, присмотр в отсутствие хозяина, выучка животных -- услуги организаций, занимающихся исследованием родословных -- услуги чистильщиков обуви, носильщиков, персонала по парковке автомобилей и т. п. -- автоматы самообслуживания, действующие при опускании монеты (фотокабины, весы, устройства для измерения артериального давления, автоматические камеры хранения и т. п.)","Эта подгруппа не включает: -- услуги по предоставлению телефонной связи через уличные телефоны-автоматы, см. 6420 -- ветеринарные услуги, см. 8520 -- деятельность оздоровительных клубов, см. 9241" -5190,"9303","Организация похорон и связанные с этим услуги","Эта подгруппа включает: -- деятельность, связанную с захоронением и кремацией трупов людей или животных, и связанные с этим услуги: -* подготовку покойников к захоронению или кремации, предоставление услуг по бальзамированию и услуг гробовщиков -* предоставление услуг, связанных с захоронением или кремацией -* аренду оборудованного помещения в салонах для прощания с покойными -- аренду или продажу могил -- содержание могил и мавзолеев и уход за ними","Эта подгруппа не включает: -- деятельность, связанную с религиозными погребальными обрядами, см. 9191" -5180,"9302","Услуги парикмахерских и прочие услуги косметических салонов","Эта подгруппа включает: -- мытье волос, подравнивание и стрижку, укладку, окраску, подцвечивание, завивку, распрямление и аналогичные работы, выполняемые для мужчин и женщин -- бритье и подравнивание бороды -- массаж лица, маникюр и педикюр, макияж и т. п.","Эта подгруппа не включает: -- изготовление париков, см. 3699" -5170,"9301","Стирка и (сухая) чистка текстильных изделий и изделий из меха","Эта подгруппа включает: -- стирку, сухую чистку, глажение и т. п. всех видов одежды (включая меховую) и текстильных изделий, производимые механическим оборудованием, вручную или путем самообслуживания с помощью действующих при опускании монеты машин для широкой публики или для такой клиентуры, как промышленные или торговые предприятия -- сбор белья для стирки и доставку -- мокрую чистку и мытье ковров и ковриков, а также чистку занавесей и портьер, в помещениях у клиентов или нет -- деятельность прачечных по обеспечению клиентов бельем, рабочей форменной одеждой и сопутствующими изделиями -- услуги по снабжению пеленками - -Эта подгруппа также включает: -- ремонт и мелкие переделки одежды или других текстильных изделий, если они производятся в связи с чисткой","Эта подгруппа не включает: -- ремонт и мелкие переделки одежды и т. п. как самостоятельный вид деятельности, см. 5260 -- прокат одежды, кроме рабочей форменной одежды, даже в том случае, когда чистка этих изделий является неотъемлемой частью такой деятельности, см. 7130" -5160,"930","Предоставление прочих видов услуг",, -5150,"93","Предоставление прочих видов услуг","Этот подраздел охватывает все виды услуг, не включенные в другие категории.", -5140,"9249","Прочая деятельность по организации отдыха и развлечений","Эта подгруппа включает деятельность, относящуюся к организации отдыха и развлечений, не включенную в другие подгруппы данного подраздела: -- деятельность парков отдыха и пляжей, в том числе прокат оборудования, такого как раздевальни на пляже, запирающиеся шкафчики, кресла и т. п. -- эксплуатацию мест для стоянки прогулочного транспорта, например пристаней для яхт -- деятельность, связанную с подбором актерского состава для съемки кинофильмов, телевизионных передач или театральных постановок -- деятельность, связанную с азартными играми и ставками на пари: -* продажу лотерейных билетов -* работу (эксплуатацию) действующих при опускании монеты денежных автоматов с возможностью случайного выигрыша -* работу (эксплуатацию) действующих при опускании монеты развлекательных игровых автоматов -* организацию круизов плавучих казино -* управление веб-сайтами с виртуальными азартными играми -- организацию ярмарок и шоу развлекательного характера - -Эта подгруппа также включает: -- прокат оборудования для отдыха и развлечений в качестве неотъемлемой части организации отдыха","Эта подгруппа не включает: -- деятельность самостоятельных агентов или агентств по подбору артистов и творческих работников для театров, см. 7499 -- прочие виды деятельности в области организации развлечений, например постановку цирковых номеров или организацию работы танцевальных залов, см. 9219" -5130,"9241","Спортивная деятельность","Эта подгруппа включает: -- функционирование сооружений для организации и проведения спортивных мероприятий на открытом воздухе или в помещении (открытых, закрытых или под козырьком, с сидениями для зрителей или без сидений): -* стадионов для футбола, хоккея на траве, игры в крикет и бейсбол -* стадионов для занятий легкой атлетикой -* плавательных бассейнов и водных стадионов -* площадок для хоккея на льду -* боксерских рингов -* полей для игры в гольф -* площадок и стадионов для соревнований по зимним видам спорта -- организацию и проведение на открытом воздухе или в помещении спортивных мероприятий для профессионалов или любителей обществами и организациями, имеющими или не имеющими собственных помещений для проведения мероприятий подобного рода: -* футбольными клубами, клубами любителей игры в боулинг, плавательными клубами, гольф-клубами, клубами любителей бокса, борьбы, оздоровительными клубами, клубами культуристов, зимних видов спорта, шахматными, шашечными клубами, клубами любителей игры в домино или в карты, легкоатлетическими, стрелковыми клубами и т. п. -- деятельность по содействию проведению и организации спортивных мероприятий -- деятельность самостоятельно занятых спортсменов и атлетов, судей, секундантов, инструкторов, педагогов, тренеров и т. п. -- деятельность спортивных школ и школ спортивных игр -- деятельность по разведению скаковых лошадей, содержание псарен и гаражей -- деятельность конноспортивных школ -- функционирование заповедников для спортивного рыболовства -- вспомогательная деятельность по организации спортивной охоты и спортивного рыболовства -- предоставление соответствующих услуг","Эта подгруппа не включает: -- прокат спортивного снаряжения, см. 7130 -- деятельность парков и пляжей, см. 9249" -5120,"924","Спортивная деятельность и прочая деятельность по организации развлечений и отдыха",, -5110,"9233","Деятельность ботанических садов, зоопарков и заповедников","Эта подгруппа включает: -- функционирование ботанических садов и зоопарков, включая зоопарки для детей -- функционирование природных заповедников, включая деятельность по охране дикой природы и т. п.", -5100,"9232","Деятельность музеев и охрана исторических мест и зданий","Эта подгруппа включает: -- деятельность самых разнообразных музеев: -* художественных музеев, музеев ювелирных изделий, мебели, костюмов, керамики, изделий из серебра -* музеев естественной истории, науки и техники, исторических музеев, включая венные музеи и исторические дома-музеи -* других специализированных музеев -* музеев на открытом воздухе -- функционирование и охрану исторических мест и зданий", -5090,"9231","Деятельность библиотек и архивов","Эта подгруппа включает: -- услуги, связанные с документацией и информацией, предоставляемые библиотеками всех видов, деятельность читальных залов, кабинетов прослушивания записей и демонстрационных залов, государственных архивов, предоставляющих услуги широкой публике или особому контингенту пользователей, таким как студенты, ученые, сотрудники и члены организаций: -* составление коллекций, специализированных или неспециализированных -* составление каталогов коллекций -* предоставление во временное пользование и хранение книг, карт, периодических изданий, кинопленок, грампластинок, видеокассет, произведений искусства и т. п. -* подбор информации в соответствии с информационными запросами и т. п.","Эта подгруппа не включает: -- прокат видеофильмов, см. 7130 -- деятельность по созданию банков данных, см. 7240" -5080,"923","Деятельность библиотек, архивов, музеев и прочая деятельность в области культуры",, -5070,"9220","Деятельность агентств печати","Эта подгруппа включает: -- деятельность синдикатов новостей и агентств новостей, охватывающую представление новостей, иллюстративных материалов и статей для распространения в средствах массовой информации -- деятельность независимых журналистов", -5060,"922","Деятельность агентств печати",, -5050,"9219","Прочая развлекательная деятельность, не включенная в другие категории","Эта подгруппа включает: -- организацию других видов развлечений, не включенных в другие категории: -* деятельность танцевальных залов и дискотек -* деятельность школ танцев и преподавателей танца -* цирковые представления -* деятельность парков отдыха и ярмарок аттракционов -* представления кукольных театров, родео, деятельность тиров, фейерверки, модели железных дорог и т. п.","Эта подгруппа не включает: -- прочую деятельность по организации развлечений, см. 9249" -5040,"9214","Деятельность в областях драматического искусства, музыки и прочих видов искусства","Эта подгруппа включает: -- производство театральных представлений, концертов, оперных и танцевальных постановок и других сценических представлений: -* деятельность групп или компаний, оркестров или джазовых групп -* деятельность отдельных артистов, таких как драматические актеры, дирижеры, музыканты, авторы, лекторы или докладчики, скульпторы, художники, мультипликаторы, гравировщики, офортисты, художники-оформители, строители и т. п. -- эксплуатацию концертных и театральных залов и других помещений для демонстрации художественных произведений и исполнительского искусства -- работу агентств по продаже билетов -- реставрацию произведений искусства, таких как произведения живописи и т. п.","Эта подгруппа не включает: -- реставрацию мебели, см. 3610 -- реставрацию органов и других старинных музыкальных инструментов, см. 3692 -- реставрацию зданий, см. подраздел 45 -- деятельность самостоятельных театральных или художественных агентов и агентств, см. 7499 -- эксплуатацию кинотеатров, см. 9212 -- деятельность по подбору артистов, см. 9249" -5030,"9213","Деятельность в областях радио и телевидения","Эта подгруппа включает: -- производство радио- и телевизионных программ прямого эфира или записанных на магнитной ленте в сочетании с вещанием или без вещания -- вещание радио- и телевизионных программ - -Подготавливаемые и транслируемые программы могут предназначаться для развлечения, продвижения товаров и идей, целей общего образования или обучения или для распространения новостной информации, такой как спортивные новости, прогнозы погоды и т. п. Результатом подготовки программ обычно является получение оригинала, который может быть продан, предоставлен напрокат или направлен на хранение для использования в целях трансляции или повторной трансляции.","Эта подгруппа не включает: -- радио- и телевизионные передачи по кабельным сетям, см. 6420 -- радио- и телевизионные передачи по релейным линиям или через спутниковые линии связи, см. 6420 -- агентства печати, см. 9220" -5020,"9212","Демонстрация кинофильмов","Эта подгруппа включает: -- демонстрацию кинофильмов или видеофильмов в кинотеатрах, на открытом воздухе или в других сооружениях, предназначенных для показа фильмов - -Эта подгруппа также включает: -- деятельность киноклубов", -5010,"9211","Производство и распространение кино- и видеофильмов","Эта подгруппа включает: -- производство игровых и неигровых кинофильмов, отснятых на кинопленку, на видеоленту или диск для прямой демонстрации в кинотеатрах или для показа по телевидению: -* производство на киностудиях или в специальных лабораториях по созданию анимационных или мультипликационных фильмов полнометражных, документальных, короткометражных фильмов и т. п., предназначенных для развлечения публики, рекламы, образовательных целей, обучения или информирования о новостях -* обработку пленки с кинофильмами -* выпуск пленки с кинофильмами -- вспомогательные виды деятельности, такие как монтаж, редактура, дубляж фильмов и т. п. -- деятельность звукозаписывающих студий -- распространение кинофильмов и видеофильмов среди других отраслей, но не для широкой публики; включаются продажа или предоставление напрокат кинофильмов или видеокассет другим отраслям, а также деятельность, имеющая отношение к распространению кинофильмов и видеокассет, такая как заключение контрактов на прокат фильмов, доставка, хранение и т. п. -- продажа и приобретение прав на распространение кино- и видеофильмов","Эта подгруппа не включает: -- тиражирование фильмов (кроме тиражирования художественных кинофильмов для демонстрации в кинотеатрах), а также тиражирование аудио- и видеозаписей, компакт-дисков и цифровых видеодисков (DVD) с мастер-дисков, см. 2230 -- розничную торговлю кассетами, см. группы 521, 523, 525 -- оптовую торговлю чистыми видеокассетами, см. 5152 -- оптовую торговлю видеокассетами с записью, см. 5139 -- предоставление напрокат видеокассет населению, см. 7130 -- обработку пленок, кроме обработки кинопленок для кинематографии, см. 7494 -- деятельность самостоятельных театральных или художественных агентов или агентств, см. 7499 -- деятельность самостоятельных актеров, мультипликаторов, режиссеров, художников-декораторов и технических специалистов, см. 9214" -5000,"921","Деятельность в областях кино, радио и телевидения и прочих видов отдыха и развлечений",, -4990,"92","Деятельность в области организации отдыха и развлечений, культуры и спорта","Этот подраздел включает функционирование сооружений и предоставление услуг потребителям в области культуры, развлечений, отдыха и спорта. Включены организация живых представлений, мероприятий или выставок, предназначенных для осмотра публикой, их реклама и обеспечение участия в них, предоставление артистического, художественного или технического персонала для создания художественных произведений и организации живых представлений, сохранение и предоставление для осмотра и посещения объектов и мест, имеющих историческую, культурную или образовательную ценность, а также обеспечение функционирования структур и предоставление услуг, позволяющих потребителям участвовать в спортивной и развлекательной деятельности, или заниматься любимыми увлечениями, развивать интересы и с пользой проводить свободное время.", -4980,"9199","Деятельность прочих членских организаций, не включенных в другие категории","Эта подгруппа включает: -- деятельность организаций, непосредственно не связанных с какой-либо политической партией, участвующих в борьбе за общее дело такими средствами, как просвещение широкой общественности, политические акции, сбор средств и т. п.: -* гражданские инициативы или движения протеста -* движения в защиту окружающей среды и экологии -* организации, выступающие в поддержку развития общин и расширения возможностей образования, не включенные в другие категории -* организации, занимающиеся защитой и улучшением положения особых групп населения, то есть этнических групп и групп меньшинств -* патриотические ассоциации, включая ассоциации ветеранов войны -- организации по интересам, такие как туристические клубы, ассоциации автомобилистов и потребительские объединения -- объединения, способствующие установлению социальных контактов, такие как клубы деловых людей, ложи и т. п. -- молодежные ассоциации, ассоциации молодых людей, ассоциации студентов, клубы и общины и т. п. -- ассоциации, занимающиеся организацией культурных мероприятий и досуга, или ассоциации по интересам (кроме спорта или игр), например поэтические, литературные клубы, клубы книголюбов, ассоциации любителей истории, садоводства, клубы кино- и фотолюбителей, любителей музыки и искусств, любителей ремесленных искусств и клубы коллекционеров, общественные клубы, карнавальные клубы и т. п. -- создание ассоциаций защиты животных","Эта подгруппа не включает: -- деятельность профессиональных ассоциаций, см. 9112" -4970,"9192","Деятельность политических организаций","Эта подгруппа включает: -- деятельность политических организаций и вспомогательных организаций, таких как организации молодежи, ассоциированные с политической партией. Эти организации главным образом оказывают влияние на принятие решений государственными органами путем размещения членов партии и сочувствующих партии лиц на руководящих постах; круг их деятельности может включать распространение информации, связи с общественностью, сбор средств и т. п.", -4960,"9191","Деятельность религиозных организаций","Эта подгруппа включает: -- деятельность религиозных организаций или отдельных лиц, которые предоставляют услуги непосредственно прихожанам церквей, мечетей, храмов, синагог и других мест -- деятельность по оказанию услуг мужским и женским монастырям -- религиозную деятельность, связанную с отшельничеством - -Эта подгруппа также включает: -- деятельность, связанную с религиозными погребальными обрядами","Эта подгруппа не включает: -- образование, предоставляемое этими организациями, см. подраздел 80 -- деятельность в области здравоохранения, осуществляемую этими организациями, см. группу 851 -- социальную деятельность этих организаций, см. группу 853" -4950,"919","Деятельность прочих членских организаций",, -4940,"9120","Деятельность профсоюзов","Эта подгруппа включает: -- деятельность ассоциаций, членами которых в основном являются лица наемного труда, заинтересованные главным образом в том, чтобы были представлены их позиции по вопросам заработной платы и положения в области труда, а также в согласованных действиях через организацию -- деятельность союзов одного предприятия или союзов, в состав которых входят филиалы, и трудовых организаций, состоящих из филиалов союзов, объединенных по отраслевому, региональному, организационному принципу или на основе других критериев","Эта подгруппа не включает: -- образование, предоставляемое этими организациями, см. подраздел 80" -4930,"912","Деятельность профсоюзов",, -4920,"9112","Деятельность профессиональных организаций","Эта подгруппа включает: -- деятельность организаций, интересы членов которых в основном сосредоточиваются на конкретной отрасли знаний или отрасли профессиональной практической деятельности или в технической области -- ассоциации специалистов, осуществляющих деятельность в области прикладных и теоретических наук или в области культуры, такие как ассоциации писателей, художников, актеров различных амплуа, журналистов и т. п. -- распространение информации, разработку норм практической деятельности и контроль за их соблюдением, представительство в отношениях с государственными учреждениями, связи с общественностью - -Эта подгруппа также включает: -- деятельность научных обществ","Эта подгруппа не включает: -- образование, предоставляемое этими организациями, см. подраздел 80" -4910,"9111","Деятельность коммерческих и предпринимательских организаций","Эта подгруппа включает: -- деятельность организаций, интересы членов которых сосредоточиваются на развитии и процветании конкретного направления коммерческой или торговой деятельности, в том числе в области сельского хозяйства, экономического роста и создания условий для развития конкретного географического района или административной единицы, независимо от направления коммерческой деятельности. -- деятельность федераций подобных ассоциаций -- деятельность торговых палат, гильдий и аналогичных организаций -- распространение информации, представительство в отношениях с государственными учреждениями, связи с общественностью и переговоры по вопросам труда","Эта подгруппа не включает: -- деятельность профессиональных союзов, см. 9120" -4900,"911","Деятельность коммерческих, предпринимательских и профессиональных организаций",, -4890,"91","Деятельность членских организаций, не включенных в другие категории","Этот подраздел включает деятельность организаций, представляющих интересы групп или занимающихся пропагандой идей среди широкой публики. Эти организации обычно имеют избранный круг членов, но их деятельность может также затрагивать и нечленов и осуществляться в их интересах. Первичная разбивка данного подраздела определяется задачами, которые ставят перед собой эти организации, а именно: защита интересов предпринимателей, самостоятельно занятых лиц и научных ассоциаций (группа 911), интересов служащих (группа 912) или продвижение религиозных, политических, культурных, образовательных или развлекательных видов деятельности и идей (группа 919).", -4880,"9000","Канализация и удаление отходов, санитарная обработка и другие услуги","Эта подгруппа включает: -- сбор и транспортировку от одного или нескольких пользователей через систему канализации, коллекторы, резервуары или другими способами транспортирования (ассенизационными автомобилями и т. п.) отходов жизнедеятельности человека, а также дождевой воды, их обработку и удаление -- обработку сточных вод физическими, химическими и биологическими способами, например растворением, процеживанием, фильтрацией, седиментацией и т. п. -- обработку сточных вод, поступающих из плавательных бассейнов и промышленных предприятий -- техническое обслуживание и очистку канализационных и дренажных систем -- опорожнение и очистку выгребных ям и канализационных отстойников, сточных труб и колодцев сточных вод, обслуживание биотуалетов -- сбор мусора бытового и промышленного происхождения с помощью мусорных баков, мусоровозов, контейнеров и т. п. -- сбор мусора в урны в местах общего пользования -- сбор опасных отходов, использованных батарей, использованных пищевых масел и жиров и т. п. -- сбор использованных технических масел из транспортных средств и гаражей -- сбор строительного мусора, в том числе мусора, образующегося при сносе зданий -- функционирование центров по сбору отходов -- удаление отходов сжиганием или другими способами: -* сваливание отходов на земле или в воде, захоронение или запахивание отходов -* обработку и удаление транзитных радиоактивных отходов, то есть радиоактивных отходов, подвергающихся распаду во время транспортировки, из больниц и т. п. -- соответствующую обработку и удаление токсичных живых и мертвых животных, а также прочих загрязненных отходов -- удаление бывших в употреблении товаров, таких как холодильники, с целью удаления вредных отходов -- дезактивацию загрязненного грунта и загрязненных грунтовых вод, выполняемую непосредственно на месте загрязнения или за его пределами, например с использованием механических, химических или биологических методов -- дезактивацию и очистку поверхностных вод после случайного загрязнения, например, посредством сбора загрязняющих веществ или с помощью обработки химикатами -- очистку мест нефтяных разливов на земле, в поверхностных водах, в морях и океанах, включая прибрежные воды -- подметание и поливку улиц, площадей, дорог, рынков, парков, скверов и т. п. -- очистку автострад, взлетно-посадочных полос аэропортов от снега и льда, включая посыпание солью или песком и т. п. -- прочую специализированную деятельность по борьбе с загрязнением окружающей среды","Эта подгруппа не включает: -- очистку канав и борьбу с вредителями в сельском хозяйстве, см. 0140 -- переработку остаточных пищевых продуктов для производства продуктов питания, см. подраздел 15 -- переработку отходов скотобоен с целью получения кормов для животных, см. 1533 -- переработку использованного ядерного топлива и обращение с радиоактивными ядерными отходами, см. 2330 -- приготовление компоста из отходов органического происхождения, см. 2412 -- переработку отходов производства пищевых продуктов, напитков и табачных изделий во вторичные сырьевые материалы, см. 3720 -- очистку воды для целей водоснабжения, см. 4100 -- снятие загрязненного грунта как часть строительной деятельности, см. 4510 -- разминирование строительных площадок и подобных участков (включая взрывные работы), см. 4510 -- строительство и ремонт канализационных систем, см. 4520 -- обработку отходов и мусора без видоизменения механическим или химическим способом для продажи третьим лицам, например разборку легковых автомобилей, машин или компьютеров, сортировку или прессовку бумажных отходов, отходов текстильных изделий, пластмасс, древесины и т. п., см. подразделы 50-52 -- сбор отходов как часть оптовой торговли отходами, см. 5149 -- транспортировку загрязненного грунта, удаленного третьими лицами, см. 6023 -- проведение технических испытаний и анализов, см. 7422 -- услуги по дезинфекции и санитарной обработке зданий, см. 7493" -4870,"900","Канализация и удаление отходов, санитарная обработка и другие услуги",, -4860,"90","Канализация и удаление отходов, санитарная обработка и другие услуги","Этот подраздел включает: -- сбор и обработку бытового мусора и промышленных отходов, не предназначенных для дальнейшего использования в каком-либо производственном процессе, с целью их удаления и получения в результате продукта, имеющего низкую стоимость или не имеющего стоимости. - -Этот подраздел также включает: -- другие виды деятельности, такие как уборку улиц, очистку от снега и т. п.","Этот подраздел не включает: -- переработку отходов, мусора и прочих предметов во вторичное сырье, предназначенное для непосредственного использования в процессе промышленного производства, см. 3710 и 3720 -- оптовую торговлю (покупку и продажу) отходами и мусором, включая сбор, сортировку, упаковывание, доставку и т. п., без реального видоизменения, см. 5149" -4850,"O","Прочие коммунальные, социальные и персональные услуги","Этот раздел включает услуги, предоставляемые коммерческими и государственными учреждениями частным лицам, другим коммерческим организациям или всему населению, не вошедшие в предыдущие части данной классификации.", -4840,"8532","Социальные услуги без обеспечения проживания","Эта подгруппа включает: -- услуги социального характера, консультации, попечительство, помощь беженцам, удовлетворение просьб о помощи и аналогичные услуги, предоставляемые отдельным лицам и семьям на дому или в других местах. Эти услуги могут предоставляться государственными учреждениями или частными организациями, организациями по оказанию помощи в случае стихийных бедствий, национальными или местными организациями самопомощи, а также специалистами, предоставляющими консультативные услуги, и включать: -* благотворительную и воспитательную деятельность с детьми и подростками -* услуги по усыновлению (удочерению), деятельность по предотвращению жестокого обращения с детьми и другими лицами -* посещение престарелых и больных людей -* консультации по бюджету домашнего хозяйства, по вопросам брака и семьи -* деятельность в общине и близлежащих районах -* деятельность по оказанию помощи жертвам стихийных бедствий, беженцам, иммигрантам и т. п., в том числе предоставление им временного крова или жилья на более длительный срок -* профессиональную реабилитацию или подготовку к определенному виду деятельности лиц, страдающих физическими или умственными недостатками, или безработных при условии ограниченности образовательного компонента -- определение прав на получение благотворительной помощи, доплаты за аренду жилья или продовольственных талонов -- деятельность по дневному уходу за детьми, в том числе деятельность по дневному уходу за детьми, страдающими физическими или умственными недостатками -- деятельность по дневному уходу за лицами с физическими или умственными недостатками -- дневной стационар для бездомных и людей, принадлежащих другим социально незащищенным группам -- благотворительная деятельность, например сбор средств, и прочие виды вспомогательной деятельности в области оказания социальных услуг","Эта подгруппа не включает: -- финансирование программ обязательного социального страхования и управление ими, см. 7530 -- виды деятельности, аналогичные описанным в данной подгруппе, но обеспечивающие проживание, см. 8531" -4830,"8531","Социальные услуги с обеспечением проживания","Эта подгруппа включает: -- деятельность, направленную на предоставление круглосуточной социальной помощи детям, престарелым и специальным категориям лиц с ограниченными возможностями ухода за собой, в которой, однако, лечение или образование не являются важными составляющими в: -* приютах для сирот -* интернатах и общежитиях для детей -* круглосуточных яслях -* домах престарелых -* домах для лиц с физическими или умственными недостатками, в том числе для слепых, глухих и немых -* реабилитационных заведениях (без лечения) для наркоманов и алкоголиков -* приютах для бездомных -* заведениях, обеспечивающих уход за матерями-одиночками и их детьми - -Эта деятельность может осуществляться правительственными учреждениями или частными организациями.","Эта подгруппа не включает: -- финансирование программ обязательного социального страхования и управление ими, см. 7530 -- услуги по усыновлению (удочерению), см. 8532 -- услуги по предоставлению временного жилья для жертв стихийных бедствий, см. 8532" -4820,"853","Деятельность в области социальных услуг",, -4810,"8520","Ветеринарная деятельность","Эта подгруппа включает: -- деятельность по контролю и охране здоровья сельскохозяйственных животных -- деятельность по контролю и охране здоровья домашних животных - -Эти услуги предоставляются квалифицированными ветеринарами в ветеринарных лечебницах, а также во время посещений сельскохозяйственных ферм, питомников или домов, в частных ветеринарных кабинетах и операционных или в других местах. - -Эта подгруппа также включает: -- деятельность ассистентов ветеринаров и другого вспомогательного ветеринарного персонала -- деятельность в области клинической патологии и прочую деятельность в области диагностики в отношении животных -- услуги машин скорой помощи для животных","Эта подгруппа не включает: -- услуги по временному содержанию сельскохозяйственных животных без ветеринарного обслуживания, см. 0140 -- услуги по временному содержанию домашних животных без ветеринарного обслуживания, см. 9309" -4800,"852","Ветеринарная деятельность",, -4790,"8519","Прочая деятельность по охране здоровья человека","Эта подгруппа включает: -- деятельность по охране здоровья человека, осуществляемую не больницами и не лечащими врачами или стоматологами: -- деятельность санитарок, акушерок, физиотерапевтов и другого парамедицинского персонала в областях оптометрии, гидротерапии, лечебного массажа, трудотерапии, лечении дефектов речи, ухода за ногами, гомеопатии, мануальной терапии, иглоукалывания и т. п. - -Эти услуги могут предоставляться в оздоровительных центрах, например, действующих при фирмах, школах, домах престарелых, организациях трудящихся и обществах, в стационарных лечебных заведениях, но не в больницах, а также в собственных помещениях по месту предоставления услуг, на дому у пациентов или в других местах. - -Эта подгруппа также включает: -- деятельность вспомогательного зубоврачебного персонала, такого как зубные терапевты, медицинские сестры по зубоврачебной практике, работающие при школах, и стоматологи-гигиенисты, которые могут работать отдельно от врача-стоматолога, но под периодически осуществляемым контролем с его стороны -- деятельность медицинских лабораторий -- деятельность банков крови, банков спермы, банков органов для трансплантации и т. п. -- срочная транспортировка больных любыми видами санитарного транспорта, включая воздушный -- стационарные лечебные заведения, кроме гостиниц","Эта подгруппа не включает: -- изготовление искусственных зубов, съемных зубных протезов и ортопедических приспособлений зуботехническими лабораториями, см. 3311 -- деятельность по проверке в области гигиены питания, см. 7422 -- услуги, предоставляемые в больницах, см. 8511 -- деятельность в области медицинской и зубоврачебной практики, см. 8512" -4780,"8512","Врачебная и зубоврачебная практика","Эта подгруппа включает: -- консультативные услуги и лечение в области общей и специальной медицины, предоставляемые врачами общего профиля и врачами-специалистами, а также хирургами -- стоматологические услуги общего и специального характера -- ортодонтические услуги - -Эти услуги могут предоставляться в порядке частной практики, в центрах, где медицинские услуги оказываются группами врачей, в амбулаториях при больницах, в клиниках, действующих при фирмах, школах, домах престарелых, организациях трудящихся и обществах, а также в виде помощи на дому. - -Эта подгруппа также включает: -- стоматологические услуги, предоставляемые в операционных -- услуги частных консультантов, оказываемые стационарным больным","Эта подгруппа не включает: -- изготовление искусственных зубов, мостов и съемных зубных протезов в зуботехнических лабораториях, см. 3311 -- деятельность больниц, см. 8511 -- деятельность парамедицинского персонала, такого как акушерки, санитарки и физиотерапевты, см. 8519" -4770,"8511","Деятельность больниц","Эта подгруппа включает: -- деятельность больниц общего и специализированного профиля при кратковременном или длительном пребывании пациентов, санаториев, профилакториев, домов престарелых с медицинским обслуживанием, интернатов для инвалидов, психиатрических больниц и клиник, реабилитационных центров, лепрозориев и прочих учреждений здравоохранения, имеющих стационары, включая госпитали при военных базах и тюремные больницы: -* медицинские услуги и хирургическую техническую помощь, например проведение диагностики, лечения, операций, анализов и исследований, оказание неотложной медицинской помощи и т. п. - -Эта деятельность направлена преимущественно на лечение стационарных больных, осуществляется под непосредственным наблюдением лечащих врачей и состоит из: -- услуг медицинского и парамедицинского персонала -- услуг лабораторий и технических служб, в том числе радиологической и анестезиологической служб -- кабинетов неотложной помощи -- служб питания и прочих больничных служб","Эта подгруппа не включает: -- медицинские услуги, предоставляемые личному составу вооруженных сил в полевых условиях, см. 7522 -- услуги частных консультантов, предоставляемые стационарным больным, см. 8512 -- стоматологические услуги без госпитализации, см. 8512 -- услуги скорой помощи, см. 8519 -- ветеринарную деятельность, см. 8520" -4760,"851","Деятельность по охране здоровья человека",, -4750,"85","Здравоохранение и социальные услуги","Этот раздел включает предоставление услуг здравоохранения посредством установления диагноза и лечения и обеспечение ухода в домах-интернатах по причинам медицинского и социального характера, а также предоставление социальной помощи, такой как консультирование, социальное обеспечение, защита детства, предоставление муниципального жилья и продовольственной помощи, профессиональная реабилитация и уход за детьми для тех, кто нуждается в помощи такого рода. Кроме того, включено предоставление ветеринарных услуг.", -4740,"N","Здравоохранение и социальные услуги","См. пояснения к подразделу 85.", -4730,"8090","Прочее образование","В эту подгруппу входят специальные виды обучения, в основном для взрослых, отличные от системы общего образования, включенной в группы 801-803. -Эта подгруппа включает: -- образование для взрослых, то есть образование для людей, которые не обучаются в системе регулярного школьного образования или в системе высшего образования. Обучение может проводиться в дневное время или на вечерних занятиях в школах или в специальных заведениях, предусмотренных для взрослых: школы автовождения, летные школы, художественные школы, кулинарные школы и т. п. -- программы обучения могут включать как общеобразовательные, так и специальные предметы -- образование, не подразделенное по ступеням -Обучение может проводиться в классных комнатах или по радио или телевидению, через Интернет или заочно.","Эта подгруппа не включает: -- высшее образование, см. 8030 -- деятельность школ танца, см. 9219 -- программы обучения спортивным дисциплинам и играм, см. 9241" -4720,"809","Прочее образование",, -4710,"8030","Высшее образование","Эта подгруппа включает: -- первый, второй и третий этапы высшего образования: -* образование выше среднего, не ведущее к получению университетской степени или ее эквивалента -* образование выше среднего, ведущее к получению университетской степени или ее эквивалента -На этой ступени предлагаются самые разнообразные тематические программы, часть которых делает больший акцент на теоретических, часть - на практических аспектах обучения. -Обучение может проводиться в классных комнатах или по радио или телевидению, через Интернет или заочно. - -Эта подгруппа также включает: -- специальное образование данной ступени для учащихся, страдающих физическими или умственными недостатками", -4700,"803","Высшее образование",, -4690,"8022","Техническое и профессиональное среднее образование","Эта подгруппа включает: -- техническое и профессиональное образование более низкой ступени, чем высшее образование, как это определено в 8030 -Как правило, в программах уделяется основное внимание предметной специализации и преподаванию как теоретических основ, так и практических навыков, обычно связанных с нынешним или будущим родом занятий. Цель программы может варьироваться от подготовки к работе общего профиля до подготовки к высокоспециализированным видам работы. -Обучение может проводиться в классных комнатах или по радио или телевидению, через Интернет или заочно. - -Эта подгруппа также включает: -- специальное образование данной ступени для учащихся, страдающих физическими или умственными недостатками","Эта подгруппа не включает: -- техническое и профессиональное образование выше второй ступени или на уровне высшего учебного заведения, см. 8030" -4680,"8021","Общее среднее образование","Эта подгруппа включает: -- общее школьное образование на первом этапе среднего образования, в той или иной мере соответствующее периоду обязательного школьного обучения -- общее школьное образование на втором этапе среднего образования, в принципе открывающее доступ к высшему образованию -Обучение может проводиться в классных комнатах или по радио или телевидению, через Интернет или заочно. -Предметная специализация на этой ступени нередко начинает влиять на приобретаемый в процессе обучения опыт даже тех учащихся, кто следует общей программе. Такие программы рассчитаны на то, чтобы подготовить учащихся либо к получению технического и профессионального образования, либо к поступлению в высшее учебное заведение, не обусловливая это какой-либо специальной подготовкой по какому-либо предмету. - -Эта подгруппа также включает: -- специальное образование данной ступени для учащихся, страдающих физическими или умственными недостатками","Эта подгруппа не включает: -- образование для взрослых, как определено в 8090" -4670,"802","Среднее образование",, -4660,"8010","Начальное образование","Эта подгруппа включает: -- дошкольное образование (образование, предшествующее первой ступени) -- начальное образование (образование первой ступени) -Обучение может проводиться в классных комнатах или по радио или телевидению, через Интернет или заочно. - -Эта подгруппа также включает: -- специальное образование данной ступени для учащихся, страдающих физическими или умственными недостатками -- предоставление программ обучения грамоте для взрослых","Эта подгруппа не включает: -- деятельность по дневному уходу за детьми, см. 8532" -4650,"801","Начальное образование",, -4640,"80","Образование","Этот подраздел включает государственное, а также частное образование любой ступени и обучение любой профессии, устным или письменным способом, а также по радио и телевидению или с использованием других средств связи. Включено образование, предоставляемое различными учреждениями, входящими в систему регулярного школьного образования различного уровня, а также получение образования взрослыми людьми, программы обучения грамоте и т. п. Также включены военные школы и академии, тюремные школы и т. п. соответствующего уровня. -На каждой ступени начального образования соответствующие подгруппы включают специальное образование для людей с физическими или умственными недостатками. -Разбивка на категории в данном подразделе основывается на ступенях образования, предложенных в МСКО 1997.","Этот подраздел не включает: -- обучение, направленное главным образом на организацию отдыха, например обучение игре в бридж или гольф, см. подраздел 92" -4630,"M","Образование","См. пояснения к подразделу 80.", -4620,"7530","Деятельность в области обязательного социального страхования","Эта подгруппа включает: -- финансирование предоставляемых правительством программ социального страхования и руководство ими: -* страхование от болезни, несчастного случая и безработицы -* пенсии по случаю выхода в отставку -* программы по компенсации потери дохода из-за рождения ребенка, временной нетрудоспособности, вдовства и т. п.","Эта подгруппа не включает: -- необязательное социальное страхование, см. 6602 -- предоставление услуг по социальному обеспечению и прочих социальных услуг, см. 8531, 8532" -4610,"753","Деятельность в области обязательного социального страхования",, -4600,"7523","Деятельность в области охраны общественного порядка и безопасности","Эта подгруппа включает: -- руководство деятельностью и функционирование регулярных и вспомогательных полицейских сил, финансируемых органами государственной власти, и портовых, пограничных полицейских сил, сил береговой охраны и других специальных полицейских сил, включая деятельность по регулированию дорожного движения, регистрации иностранных граждан, функционирование полицейских лабораторий и ведение досье арестов -- тушение пожаров и предупреждение пожаров: -* руководство деятельностью и функционирование регулярных и вспомогательных пожарных бригад, финансируемых органами государственной власти, в области предупреждения и тушения пожаров, спасения людей и животных, оказания помощи при стихийных бедствиях, наводнениях, дорожно-транспортных происшествиях и т. п. -- руководство деятельностью и функционирование административных гражданских и уголовных судов, военных трибуналов и судебно-правовой системы, в том числе юридическое представительство и консультации от имени правительства или от имени других лиц, если они обеспечиваются правительственными денежными средствами или услугами -- вынесение судебных решений и толкование закона -- арбитражное разбирательство гражданских дел -- управление тюрьмами и предоставление услуг в области исправительных мер, включая услуги по реабилитации -- обеспечение запасов для внутреннего использования в чрезвычайных обстоятельствах в случае стихийных бедствий в мирное время","Эта подгруппа не включает: -- услуги по защите лесов от пожаров, см. 0200 -- частные услуги по тушению пожаров и предупреждению пожаров на производственных предприятиях, см. раздел D -- услуги по тушению пожаров и предупреждению пожаров в аэропортах, см. 6303 -- консультации и представительство в гражданских, уголовных и других делах, см. 7411 -- руководство и регулирование в области вооруженных сил, см. 7522 -- деятельность тюремных школ, см. подраздел 80 -- деятельность тюремных больниц, см. 8511" -4590,"7522","Оборонная деятельность","Эта подгруппа включает: -- руководство, контроль и регулирование, осуществляемые в области военной обороны и вооруженных сил: сухопутных, морских, воздушных и космических, таких как: -* боевые силы армии, военно-морского флота и авиации -* инженерные войска, транспортные войска, связь, разведка, материально-техническое обеспечение, личный состав штабов и другие небоевые силы и соединения -* резервные и вспомогательные силы обороны -* обеспечение материальной части, инженерно-технической части, снабжения и т. п. -* деятельность в области медицинского обслуживания личного состава вооруженных сил в полевых условиях -- руководство, контроль и регулирование вопросов, связанных с гражданскими силами обороны -- помощь в разработке планов действий при различных вариантах обстановки и проведение учений, в которых принимают участие гражданские учреждения и население -- руководство исследованиями и разработками оборонного характера и связанными с ними фондами","Эта подгруппа не включает: -- деятельность по проведению исследований и экспериментальных разработок, см. подраздел 73 -- предоставление военной помощи иностранным государствам, см. 7521 -- деятельность военных трибуналов, см. 7523 -- обеспечение запасов для внутреннего использования в чрезвычайных обстоятельствах в случае стихийных бедствий в мирное время, см. 7523 -- деятельность в области образования военных школ, училищ и академий, см. подраздел 80 -- деятельность военных госпиталей, см. 8511" -4580,"7521","Международные отношения","Эта подгруппа включает: -- руководство деятельностью и функционирование министерства иностранных дел, а также дипломатических и консульских миссий, размещенных за границей или при отделениях международных организаций -- руководство деятельностью, регулирование и поддержку услуг в областях информации и культуры, предназначенных для распространения за пределами национальных границ -- помощь иностранным государствам, направляемую или не направляемую через международные организации -- предоставление военной помощи иностранным государствам -- руководство в области внешней торговли, международных финансов и иностранной технической помощи -- международную помощь, например программы помощи беженцам или голодающим", -4570,"752","Предоставление услуг обществу в целом",, -4560,"7514","Вспомогательные услуги правительству в целом","Эта подгруппа включает: -- деятельность, связанную с услугами персонала общей категории и другое общее обслуживание: -* руководство и регулирование в вопросах обслуживания персоналом общей категории, связанного или не связанного с выполнением конкретных функций -* разработку и осуществление общей кадровой политики и процедур, охватывающих отбор и продвижение по службе, методы оценки работы, описание вида работы, оценку и классификацию работы, контроль за соблюдением правил гражданской службы и т. п. -- руководство, регулирование и поддержку всех аспектов общего обслуживания: -* услуги по централизованным поставкам и закупкам -* содержание и хранение правительственных отчетов и архивов -* эксплуатацию приобретенных или занимаемых правительством зданий -* эксплуатацию центральных учреждений, а также другие услуги общего характера, не связанные с выполнением конкретных функций", -4550,"7513","Регулирование и содействие развитию более эффективной коммерческой деятельности","Эта подгруппа включает: -- государственное управление и регулирование, включая выделение субсидий, в различных секторах экономики: -* сельском хозяйстве -* землепользовании -* эксплуатации энергетических и ископаемых ресурсов -* инфраструктуре -* транспорте -* связи -* гостиничном бизнесе и туризме -* оптовой и розничной торговле -- руководство политикой в области исследований и разработок и связанных с ними фондами, предназначенными для повышения экономической эффективности -- руководство общими вопросами, касающимися трудовых отношений -- осуществление политики по региональному развитию, например мер по сокращению безработицы","Эта подгруппа не включает: -- деятельность по проведению исследований и экспериментальных разработок, см. подраздел 73" -4540,"7512","Регулирование деятельности учреждений, обеспечивающих медицинское обслуживание, образование, культурное обслуживание и другие социальные услуги, кроме социального страхования","Эта подгруппа включает: -- руководство программами, предназначенными для повышения личного благосостояния людей, в следующих областях: -* здравоохранение -* образование -* культура -* спорт -* отдых -* окружающая среда -* жилищное строительство -* сфера социальных услуг -- руководство политикой в области исследований и разработок и связанными с ними фондами - -Эта подгруппа также включает: -- спонсорское участие в организации отдыха и культурных мероприятий -- распределение пособий среди творческих работников -- руководство программами обеспечения питьевой водой -- руководство деятельностью по сбору и удалению отходов -- руководство программами по защите окружающей среды -- руководство программами жилищного строительства","Эта подгруппа не включает: -- деятельность по обязательному социальному страхованию, см. 7530 -- деятельность в области образования, см. подраздел 80 -- деятельность, связанную с охраной здоровья человека, см. группу 851 -- канализацию, удаление отходов и санитарную обработку, см. 9000 -- деятельность библиотек, государственных архивов, музеев и других культурных учреждений, см. 923 -- спортивную деятельность и прочую деятельность по организации развлечений и отдыха, см. 924" -4530,"7511","Все аспекты деятельности в области управления на государственном уровне","Эта подгруппа включает: -- исполнительные и законодательные функции управления центральных, региональных и местных органов -- управление и контроль в области налогово-бюджетной политики: -* осуществление налогообложения -* взимание пошлин и налогов на товары и рассмотрение фактов нарушений в налоговой сфере -* управление в области таможенной политики -- исполнение бюджета и управление государственными фондами и государственными долгами: -* извлечение и получение денег и контроль за их расходованием -- руководство политикой в области общих (гражданских) исследований и разработок и связанными с ними фондами -- руководство со стороны государственных органов разного уровня всеми аспектами экономического и социального планирования, деятельностью статистических служб","Эта подгруппа не включает: -- руководство политикой в области исследований и разработок, предназначенных для повышения личного благосостояния людей, и связанными с ними фондами, см. 7512 -- руководство политикой в области исследований и разработок, предназначенных для повышения экономической эффективности и конкурентоспособности, см. 7513 -- руководство исследованиями и разработками в области обороны и связанными с ними фондами, см. 7522" -4520,"751","Управление государством и социально-экономическая политика общества",, -4510,"75","Государственное управление и оборона; обязательное социальное страхование","Этот подраздел включает деятельность, обычно выполняемую государственными органами управления. Однако юридический или институциональный статус сам по себе не является определяющим фактором. Этот подраздел включает организации и учреждения, которые являются частью местных или центральных государственных структур, обеспечивающих надлежащее функционирование органов управления в обществе. - -Этот подраздел включает: -- общее государственное управление (например, органы исполнительной, законодательной, финансовой власти всех уровней) и надзор в области социальной и экономической политики (группа 751) -- оборону, правосудие, полицию, международные отношения и т. п. (группа 752) -- управление в области обязательного социального страхования (группа 753) - -Виды деятельности, классифицируемые в других разделах МСОК, не включаются в подраздел 75, даже если они осуществляются государственными органами управления. Например, управление системой школьного образования (то есть разработка нормативных положений, учебных планов, проведение проверок) классифицируется в подразделе 75, а преподавание как таковое относится к другому подразделу (см. подраздел 80); тюремная больница или военный госпиталь классифицируются как организации здравоохранения (см. подраздел 85). Подобным образом некоторые виды деятельности, отнесенные к подразделу 75, могут выполняться негосударственными учреждениями.", -4500,"L","Государственное управление и оборона; обязательное социальное страхование","См. пояснения к подразделу 75.", -4490,"7499","Прочая коммерческая деятельность, не включенная в другие категории","Эта подгруппа включает самые разнообразные услуги, обычно предоставляемые коммерческим клиентам. -Эта подгруппа включает: -- стенографические и почтовые услуги: -* распечатку на пишущей машинке -* прочую секретарскую деятельность, такую как расшифровка текста, записанного на магнитной ленте или диске -* перепечатку, изготовление ""синек"" на светокопировальных аппаратах, размножение текста и аналогичную деятельность -* надписывание адресов на конвертах, раскладывание по конвертам, запечатывание и отправку почты, составление перечня адресатов почтовых отправлений и т. п., в том числе для рекламных материалов -- письменный и устный перевод -- инкассирование векселей, оценку кредитоспособности в связи с платежеспособностью или коммерческой практикой отдельных лиц или фирм -- брокерские комиссионные операции, то есть организацию покупки или продажи мелких или средних коммерческих предприятий, в том числе профессиональной практики -- брокерские операции с патентами (выполняемые с целью продажи или покупки патентов) -- услуги по оценке, кроме оценки, производимой в связи с операциями с недвижимым имуществом или страхованием -- моделирование, связанное с текстильными изделиями, одеждой, обувью, ювелирными изделиями, мебелью, и прочее оформление интерьера, а также моделирование, связанное с другими модными товарами, а также с прочими бытовыми товарами и предметами личного пользования -- услуги по графическому оформлению -- услуги художников-декораторов по оформлению помещений -- услуги по организации ярмарок, выставок и конгрессов -- услуги по оформлению стендов -- деятельность самостоятельно занятых лиц по организации аукционов -- консультационные услуги, кроме консультаций по техническим вопросам и гражданскому строительству -- работу предприятий за счет кредитования другими организациями -- проставление фирменных штампов - -Эта подгруппа также включает: -- услуги корректоров -- ответы на телефонные звонки -- деятельность центров по опросу населения -- деятельность, осуществляемую агентами и агентствами от имени отдельных лиц, обычно связанную с получением ангажементов на участие в кинофильмах, театральных постановках или других развлекательных или спортивных мероприятиях, а также с размещением книг, пьес, предметов изобразительного искусства, фотографий и т. п. у издателей, продюсеров и т. п. -- услуги по снятию показаний приборов по расходу газа, воды и электроэнергии","Эта подгруппа не включает: -- оптовую продажу через аукционы автомобилей, бывших в употреблении, см. 5010 -- услуги аукционных домов (розница), см. 5240 -- деятельность онлайновых аукционов (розница), см. 5259 -- деятельность, связанную с кредитными карточками, см. подраздел 65 -- услуги баз данных, см. 7240 -- бухгалтерские услуги, см. 7412 -- проектирование машин и промышленный дизайн, см. 7421 -- размещение рекламы и прочие дизайнерские работы, связанные с рекламой, см. 7430" -4480,"7495","Деятельность в области упаковывания","Эта подгруппа включает: -- деятельность в области упаковывания, осуществляемую за вознаграждение или на договорной основе, включающую или не включающую автоматизированные процессы: -* заполнение аэрозольных упаковок -* разлив жидкостей, включая напитки и пищевые продукты, в бутылочную тару -* упаковывание твердых продуктов (укладка в блистерные упаковки, обертывание в фольгу и т. п.) -* безопасное упаковывание фармацевтических препаратов -* этикетирование, штамповку и маркировку -* упаковывание в пакеты и подарочную упаковку","Эта подгруппа не включает: -- деятельность в области упаковывания, связанную с перевозкой, см. 6309" -4470,"7494","Деятельность в области фотографии","Эта подгруппа включает: -- коммерческое и потребительское фотопроизводство: -* портретную фотографию для паспортов, изготовление школьных и свадебных фотографий и т. п. -* фотографию для рекламной, издательской продукции, журналов мод, операций с недвижимостью и целей туризма -* аэрофотосъемку -* видеосъемку событий, свадеб, встреч и т. п. -- обработку пленки: -* проявление, печатание и увеличение с негативов или кинопленок, отснятых клиентами -* вставление слайдов в рамки -* пересъемку, восстановление или ретуширование фотографий - -Эта подгруппа также включает: -- микрофильмирование документов","Эта подгруппа не включает: -- картографическую и другую деятельность, связанную с пространственной информацией, см. 7421 -- обработку кинопленок, связанных с кинематографией и телевидением, см. 9211" -4460,"7493","Деятельность по уборке зданий и промышленного оборудования","Эта подгруппа включает: -- уборку внутренних помещений зданий всех типов, в том числе контор, фабрик, магазинов, учреждений, а также других коммерческих и профессиональных помещений и многоквартирных жилых домов -- мытье окон -- чистку печных труб и каминов, нагревателей, печей, мусоросжигателей, бойлеров, вентиляционных шахт и вытяжных вентиляторов и т. п. -- очистку промышленного механического оборудования -- стерилизацию объектов и помещений -- мытье бутылочной тары - -Эта подгруппа также включает: -- дезинфекцию и дезинсекцию зданий, судов, поездов и т. п. -- мытье поездов, автобусов, самолетов и т. п. -- очистку автоцистерн и трюмов морских танкеров","Эта подгруппа не включает: -- борьбу с вредителями сельского хозяйства, см. 0140 -- паровую чистку, чистку пескоструйными аппаратами и т. п. внешней стороны зданий, см. 4540 -- уборку новых зданий после строительства, см. 4540 -- мытье ковров и ковриков, чистку занавесей и штор, см. 9301" -4450,"7492","Деятельность по расследованию и обеспечению безопасности","Эта подгруппа включает: -- деятельность по расследованию и надзору, предоставлению других видов защиты: -* перевозку ценностей -* услуги телохранителей -* патрулирование улиц, деятельность по охране и наблюдению за жилыми зданиями, конторскими учреждениями, производственными строениями, строительными площадками, гостиницами, театрами, танцевальными залами, стадионами, торговыми центрами и т. п. -* деятельность служб безопасности на пассажирском транспорте, например досмотр пассажиров и багажа в аэропортах, а также патрулирование поездов на железных дорогах и метрополитене -* услуги детективов в магазинах -* дистанционное наблюдение/контроль за работой технического оборудования, наблюдение за зданиями и т. п. -* услуги по предварительной оценке сигналов тревоги (принятие решения о том, является ли полученный сигнал ложным или нет) и, при необходимости, вызову полиции, пожарной команды и скорой помощи -- консультативные услуги в области обеспечения безопасности на промышленных предприятиях, в быту и в государственных учреждениях, включая проверки на благонадежность -- деятельность частных детективов - -Эта подгруппа также включает: -- обучение служебных собак для целей служб безопасности","Эта подгруппа не включает: -- установку систем сигнализации, см. 4530 -- расследование в связи со страхованием, см. 6720" -4440,"7491","Найм рабочей силы и обеспечение персоналом","Эта подгруппа включает: -- поиск персонала, услуги по отбору кандидатов и распределению по месту работы, предоставляемые потенциальному работодателю или потенциальному работнику, включающие: -* описание вида работы -* отбор и проверку лиц, претендующих на получение работы -* проверку характеристик и резюме и т. п. -- деятельность по поиску и размещению работников управленческого аппарата -- деятельность по найму рабочей силы: -* обеспечение клиентов, преимущественно на временной основе, персоналом, нанятым и оплачиваемым агентством","Эта подгруппа не включает: -- деятельность подрядчиков, осуществляющих найм сельскохозяйственной рабочей силы, см. 0140 -- деятельность агентов или агентств по подбору артистов для театральных групп и других творческих работников, см. 7499 -- деятельность по подбору актеров для кино, телевидения и других театральных постановок, см. 9249" -4430,"749","Коммерческая деятельность, не включенная в другие категории",, -4420,"7430","Реклама","Эта подгруппа включает: -- организацию и проведение рекламных кампаний: -* создание и размещение рекламы клиентов в газетах, периодических изданиях, на радио, телевидении, в сети Интернет и других средствах массовой информации -* создание и размещение уличной рекламы, например на афишных тумбах, рекламных щитах, на досках объявлений, в обрамлении; оформление витрин, проектирование выставочных залов, распространение рекламных карточек в машинах и автобусах и т. п. -* представительство в средствах массовой информации, то есть покупку времени и места для рекламы, осуществляемой с помощью средств массовой информации -* воздушную рекламу -* распространение и доставку рекламного материала или образцов продукции -* аренду места на щитах для размещения рекламных объявлений и т. п.","Эта подгруппа не включает: -- полиграфическое исполнение рекламного материала, см. 2221 -- исследование конъюнктуры рынка, см. 7413 -- деятельность по связям с общественностью, см. 7414 -- рекламную фотографию, см. 7494 -- деятельность по непосредственной рассылке по почте (печатание адресов, предварительная сортировка и т. п.), см. 7499 -- подготовку коммерческих сообщений для радио, телевидения и кино, см. 9211, 9213" -4410,"743","Реклама",, -4400,"7422","Технические испытания и анализы","Эта подгруппа включает: -- испытания и проверку всех видов материалов и продуктов: -* испытание состава и чистоты минералов и т. п. -* проведение проверок в области гигиены питания, включая ветеринарный контроль и соответствующий контроль за производством пищевых продуктов -* испытание физических характеристик и эксплуатационных качеств материалов, например испытание прочности, толщины, долговечности, радиоактивности и т. п. -* испытания на соответствие техническим условиям и оценку надежности -* испытания эксплуатационных характеристик смонтированного оборудования машиностроения: двигателей, автомобилей, электронного оборудования и т. п. -* радиографический контроль сварных швов и стыков -* анализ разрушений -* исследование и измерение параметров окружающей среды: степени загрязнения воздуха и воды и т. п. -- сертификацию продуктов, включая потребительские товары, автомобили, самолеты, контейнеры под давлением, атомные станции и т. п. -- периодические испытания автомобилей на безопасность эксплуатации на дорогах -- испытания с использованием моделей или макетов (например, самолетов, судов, плотин и т. п.)","Эта подгруппа не включает: -- исследования и анализы медицинских и стоматологических образцов и проб, см. 8519 -- исследования образцов и проб, взятых у животных, см. 8520" -4390,"7421","Деятельность в областях архитектуры и гражданского строительства и связанные с этим технические консультации","Эта подгруппа включает: -- консультативные услуги в области архитектуры: -* проектно-конструкторские работы и составление чертежей -* наблюдение за строительством -* планировку мелких и крупных городов и их озеленение -- проектирование в области машиностроения и промышленного строительства -- руководство проектами строительства и техническую деятельность: -* в области проектирования, включающего гражданское строительство, гидротехнические сооружения, транспортное строительство -* в области разработки и выполнения проектов по электронике и электротехнике, горной инженерии, химической технологии, машиностроению, организации производства, системотехнике, технике безопасности -- разработку проектов по системам кондиционирования воздуха, охлаждению, контролю за санитарно-гигиеническими условиями, борьбе с загрязнением окружающей среды, акустике и т. п. -- деятельность по проведению геологической разведки и изысканиям: -* изыскательские работы по поиску месторождений нефти и газа, выполнение геофизических, геологических и сейсмических исследований -* изыскательские работы по поиску залежей минералов и подземных вод -- деятельность в области прогнозирования погоды -- геодезические изыскательские работы: -* деятельность в области замеров земли и установлению границ участков -* гидрологические изыскания -* исследование подповерхностных слоев -* картографическую деятельность и сбор соответствующей информации, включая аэрофотосъемку - -Эта подгруппа также включает: -- услуги технических консультантов, кроме консультаций в области гражданского строительства","Эта подгруппа не включает: -- разведочное бурение, связанное с добычей нефти или газа, см. 1120 -- разведочное бурение и бурение пробных скважин, не связанное с добычей нефти или газа, см. 4510 -- услуги консультантов в области компьютерных технологий, см. 7210, 7229 -- деятельность в области научных исследований и разработок, см. 7310, 7320 -- технические испытания, см. 7422 -- аэрофотосъемку, см. 7494 -- оформление интерьеров, см. 7499" -4380,"742","Архитектура, гражданское строительство и другая техническая деятельность",, -4370,"7414","Консультации по вопросам коммерческой деятельности и управления","Эта подгруппа включает: -- предоставление консультаций, рекомендаций и практической помощи коммерческим предприятиям и государственным организациям, в том числе: -* поддержание общественных связей -* проектирование методик и процедур расчета, программ учета затрат, процедур контроля выполнения сметы -* консультации и помощь коммерческим предприятиям и государственным организациям в области планирования, организационных мер, обеспечения эффективности и контроля, информации по вопросам управления и т. п. -* консультации по вопросам управления, например предоставление консультации агрономов и специалистов по экономике сельского хозяйства фермерским хозяйствам и т. п. - -Эта подгруппа также включает: -- деятельность по управлению холдинговыми компаниями","Эта подгруппа не включает: -- разработку компьютерных программ для систем учета, см. 7229 -- юридические консультации и представительство, см. 7411 -- деятельность по составлению счетов, бухгалтерскому учету и аудиторскую деятельность, а также консультации по вопросам налогообложения, см. 7412 -- исследование конъюнктуры рынка и выявление общественного мнения, см. 7413 -- консультативные услуги в области архитектуры, инженерии и по другим техническим вопросам, см. 7421 -- деятельность, связанную с рекламой, см. 7430" -4360,"7413","Исследование конъюнктуры рынка и выявление общественного мнения","Эта подгруппа включает: -- изучение потенциальных возможностей рынка, приемлемости продуктов, осведомленности о них и покупательских привычек потребителей в целях содействия сбыту и разработки новых видов продуктов, включая статистический анализ полученных результатов -- изучение общественного мнения по политическим, экономическим и социальным вопросам, а также статистический анализ полученных результатов", -4350,"7412","Деятельность в области составления счетов, бухгалтерского учета и ревизии; консультации по вопросам налогообложения","Эта подгруппа включает: -- деятельность, связанную с регистрацией коммерческих операций для коммерческих и прочих предприятий -- деятельность, связанную с подготовкой финансовых счетов, анализом этих счетов и подтверждением их точности -- деятельность, связанную с подготовкой для частных лиц или предприятий ведомостей о подоходном налоге -- консультативные услуги и представительство (кроме юридического представительства) от имени клиентов перед налоговыми управлениями","Эта подгруппа не включает: -- услуги по обработке и табулированию данных, см. 7230 -- консультации по вопросам управления, например относительно разработки систем отчетности, программ учета затрат, процедур контроля исполнения сметы, см. 7414 -- инкассирование векселей, см. 7499" -4340,"7411","Деятельность в области права","Эта подгруппа включает: -- представление интересов одной стороны, выступающей против другой стороны, в судах или других судебных органах или же в иных случаях лицами, которые являются членами коллегии адвокатов, или же под их наблюдением: -* консультации и представительство при рассмотрении гражданских дел -* консультации и представительство при рассмотрении уголовных дел -* консультации и представительство при рассмотрении трудовых споров -- предоставление консультаций и советов общего характера, подготовка юридических документов: -* относящихся к статьям, на которые производится ссылка, соглашений о партнерстве и аналогичных документов, связанных с созданием компании -* относящихся к патентам и авторским правам -* составление документов за печатью, завещаний, доверенностей и т. п. -- прочие услуги государственных нотариусов, гражданских нотариусов, судебных исполнителей, арбитров, лиц, назначенных судом для снятия свидетельских показаний, и третейских судей","Эта подгруппа не включает: -- деятельность судов общего права, см. 7523" -4330,"741","Деятельность в областях права, составления счетов, бухгалтерского учета и ревизии; консультации по вопросам налогообложения; исследование конъюнктуры рынка и выявление общественного мнения; консультации по вопросам коммерческой деятельности и управления",, -4320,"74","Прочая коммерческая деятельность","Этот подраздел включает все виды коммерческой деятельности, кроме деятельности, связанной с компьютерной техникой и научными исследованиями, которая относится к подразделам 72 и 73 этого раздела. Некоторые виды деятельности, указанные здесь, часто осуществляются вспомогательными организациями крупных компаний, в то время как другие виды деятельности в основном осуществляются самостоятельными предприятиями. Привлечение внештатных работников является основным фактором, определяющим способы учета данных видов деятельности. Основная часть такой деятельности осуществляется для коммерческих клиентов, кроме деятельности в области права (7411), частично найма рабочей силы и обеспечения персоналом (7491) и деятельности в области фотографии (7494); эти виды деятельности осуществляются также и для частных лиц.", -4310,"7320","Исследования и экспериментальные разработки в области общественных и гуманитарных наук","Эта подгруппа включает: -- систематическое изучение и творческие усилия в трех видах деятельности: в области исследований и разработок, определенных выше, в области общественных и гуманитарных наук (экономики, психологии, социологии, археологии, юридических наук, лингвистики и языкознания, искусств и т. п.). Они предназначаются для увеличения объема знаний и повышения эффективности применения такого рода знаний.","Эта подгруппа не включает: -- исследование конъюнктуры рынка, см. 7413" -4300,"732","Исследования и экспериментальные разработки в области общественных и гуманитарных наук",, -4290,"7310","Исследования и экспериментальные разработки в области естественных и инженерных наук","Эта подгруппа включает: -- систематическое изучение и творческие усилия в трех видах деятельности в области исследований и разработок, определение которых содержится выше, в области естественных наук (математики, физики, астрономии, химии, естествознания, медицинских наук, наук о земле, сельскохозяйственных наук, инженерных наук и технологии и т. п.). Они предназначаются для увеличения объема знаний и повышения эффективности применения такого рода знаний. - -Эта подгруппа также включает: -- многодисциплинарные исследования и разработки", -4280,"731","Исследования и экспериментальные разработки в области естественных и инженерных наук",, -4270,"73","Исследования и разработки","Этот подраздел включает три вида деятельности в области научных исследований и опытно-конструкторских разработок (НИОКР): -- фундаментальные исследования: -* экспериментальная или теоретическая работа, предпринимаемая прежде всего с целью приобретения новых знаний в области фундаментальных законов, лежащих в основе явлений и поддающихся наблюдению фактов, без постановки конкретной задачи в области применения или использования -- прикладные исследования: -* углубленное изучение, предпринимаемое с целью приобретения новых знаний и направленное прежде всего на достижение конкретной практической цели или выполнение задачи -- экспериментальные разработки: -* систематическая работа, основывающаяся на существующих знаниях, полученных в результате исследований и/или практического опыта, и направленная на создание новых материалов, продуктов или устройств, внедрение новых процессов, систем и услуг, а также на существенное совершенствование тех, которые уже созданы или внедрены","Этот подраздел не включает: -- государственное управление НИОКР и связанными с ними фондами в различных областях естественных и общественных наук, см. подраздел 75 -- организация и поддержка прикладных исследований и экспериментальных разработок, связанных с обороной, см. 7522 -- образование в сочетании с проведением НИОКР, см. подраздел 80 -- сбор средств на НИОКР в области медицины, другие социально ориентированные исследования благотворительными организациями и управление этими средствами, см. 8532" -4260,"7290","Прочая деятельность, связанная с компьютерной техникой","Эта подгруппа включает: -- аварийное восстановление после отказа компьютерного оборудования -- услуги по установке программного обеспечения -- прочие услуги, связанные с компьютерной техникой, не включенные в другие категории", -4250,"729","Прочая деятельность, связанная с компьютерной техникой",, -4240,"7250","Техническое обслуживание и ремонт канцелярских, бухгалтерских и электронно-вычислительных машин","Эта подгруппа включает: -- техническое обслуживание и ремонт: -* компьютеров и компьютерного периферийного оборудования -* пишущих машинок, механических или электрических -* устройств для копирования фотографическим или термическим способом -* электронные вычислительные машины, переносные или настольные -* кассовые аппараты", -4230,"725","Техническое обслуживание и ремонт канцелярских, бухгалтерских и электронно-вычислительных машин",, -4220,"7240","Деятельность по созданию баз данных и онлайновое распределение электронного содержания","Онлайновое распределение, включенное в эту подгруппу, относится к организациям, деятельность которых исключительно направлена на онлайновое распределение содержания, но не к организациям, где онлайновая публикация данных выполняется в дополнение к традиционным формам издательской деятельности. В этом смысле это исключение из общего правила в отношении классификации организаций в соответствии с долей добавленной стоимости. - -Эта подгруппа включает: -- компоновку данных из одного или нескольких источников -- обеспечение онлайнового доступа к оригинальным базам данных -- онлайновая публикация базы данных -- онлайновая публикация указателя и списка рассылки -- прочая онлайновая публикация, включая книги в электронном виде -- порталы для поиска веб-страниц -- поисковые страницы в Интернете, страницы с играми в Интернете, развлекательные страницы в Интернете","Эта подгруппа не включает: -- онлайновую публикацию в сочетании с традиционными формами издательской деятельности, см. 221 -- услуги по розничной торговле через Интернет, см. 5251 -- издание программного обеспечения баз данных, см. 7221 -- создание программного обеспечения или систем баз данных, см. 7229 -- использование веб-страниц сети Интернет, посвященных азартным играм, см. 9249" -4210,"724","Деятельность по созданию баз данных и онлайновое распределение электронного содержания",, -4200,"7230","Обработка данных","Эта подгруппа включает: -- обработку данных с использованием пользовательской или оригинальной программы: -* полную обработку данных, представленных пользователем -* услуги по введению данных -* сканирование документов -- управление и эксплуатацию на постоянной основе устройств по обработке данных, принадлежащих другим пользователям -- услуги компьютера, работающего в режиме разделения по времени -- веб-хостинг (пользование сетью)","Эта подгруппа не включает: -- аренду и лизинг компьютеров, а также периферийного компьютерного оборудования, см. 7123" -4190,"723","Обработка данных",, -4182,"7229","Прочие консультационные услуги и поставка программного обеспечения","Эта подгруппа включает: -- анализ, проектирование и программирование программного обеспечения потребительского назначения, в том числе: -* анализ требований и задач, стоящих перед пользователем, консультационные услуги по выбору оптимального решения -* производство программного обеспечения потребительского назначения, позволяющего решить поставленную задачу -- разработку, производство, поставку и подготовку документации по заказному программному обеспечению, отвечающему требованиям конкретных пользователей -- написание программ любого вида в соответствии с указаниями, полученными от пользователя -- техническое обслуживание программного обеспечения -- разработка веб-страницы","Эта подгруппа не включает: -- воспроизводство программного обеспечения, см. 2230 -- оказание консультационных услуг по программному обеспечению совместно с оказанием консультационных услуг по техническому обеспечению, см. 7210 -- издание программного обеспечения, см. 7221" -4180,"7221","Издание программного обеспечения","Эта подгруппа включает: -- производство, поставку программного обеспечения общего применения (не заказного) и составление к нему сопроводительной документации: -* операционные системы -* деловые и прочие прикладные программы -* компьютерные игры для всех платформ","Эта подгруппа не включает: -- копирование программного обеспечения, см. 2230 -- розничную продажу программного обеспечения общего применения, см. 5239 -- производство заказного программного обеспечения, см. 7229" -4170,"722","Издание и поставка программного обеспечения и консультационные услуги по этому вопросу",, -4160,"7210","Консультации по техническому обеспечению","Эта подгруппа включает: -- консультационные услуги относительно типа и конфигурации технического обеспечения с использованием связанного с этим программного обеспечения или без него посредством анализа потребностей и задач пользователей и представления оптимального решения","Эта подгруппа не включает: -- аналогичные консультационные услуги, предоставляемые предприятиями по производству или продаже компьютеров, см. 3000, 5151, 5239" -4150,"721","Консультации по техническому обеспечению",, -4140,"72","Компьютеры и связанная с этим деятельность","В этот подраздел включены виды деятельности, относящейся к разработке конфигурации, установке, эксплуатации и техническому обслуживанию компьютерных систем и сетей, а также к разработке пользовательского программного обеспечения и изданию программ. Включаются различные услуги по обработке данных, хранение и онлайновое распределение электронного содержания. Кроме того, включены услуги по техническому обслуживанию и ремонту прочего офисного, вычислительного и компьютерного оборудования.", -4130,"7130","Прокат бытовых товаров и предметов личного пользования, не включенных в другие категории","Эта подгруппа включает: -- предоставление на прокат всех видов бытовых товаров или предметов личного пользования домашним хозяйствам или отраслям промышленности: -* текстильных изделий, одежды и обуви -* мебели, гончарных изделий и изделий из стекла, кухонной утвари и столовой посуды, электроприборов и предметов домашнего обихода -* прогулочных судов -* велосипедов -* спортивного оборудования -* ювелирных изделий, музыкальных инструментов, театральных декораций и костюмов -* книг, газет и журналов -* видеокассет, грампластинок, компакт-дисков, цифровых видеодисков (DVD) и т. п. -* машин и оборудования ""сделай сам"", ручного инструмента -* цветов и растений","Эта подгруппа не включает: -- аренду без водителя легковых автомобилей, микроавтобусов, мотоциклов, передвижных ""дач"" и прицепов, см. 7111 -- аренду оборудования для отдыха и досуга как неотъемлемую часть деятельности фирм по организации отдыха, см. 9249 -- предоставление прачечными белья, рабочей униформы и сопутствующих изделий, см. 9301" -4120,"713","Прокат бытовых товаров и предметов личного пользования, не включенных в другие категории",, -4110,"7129","Аренда прочих машин и оборудования, не включенных в другие категории","Эта подгруппа включает: -- аренду или операционный лизинг без оператора прочих машин и оборудования, которые обычно используются в качестве средств производства: -* двигателей и турбин -* станков -* оборудования для горных разработок и нефтедобычи -* профессионального радио-, телевизионного и связного оборудования -* оборудования для производства кинофильмов -* измерительного и контрольного оборудования -* прочего научного оборудования и других машин коммерческого и промышленного назначения - -Эта подгруппа также включает: -- аренду жилых или офисных модулей (контейнеров)","Эта подгруппа не включает: -- финансовый лизинг, см. 6591 -- аренда сельскохозяйственных машин и оборудования, см. 7121 -- аренда машин и оборудования для строительства и гражданского строительства, см. 7122 -- аренда канцелярских машин и оборудования, включая компьютеры, см. 7123" -4100,"7123","Аренда канцелярских машин и оборудования (включая компьютеры)","Эта подгруппа включает: -- аренду и операционный лизинг канцелярских машин и оборудования без оператора: -* компьютеров и периферийного компьютерного оборудования -* копировальных машин, пишущих машинок и машин для обработки текстов -* счетных машин и счетного оборудования: кассовых аппаратов, электронных калькуляторов и т. п.","Эта подгруппа не включает: -- финансовый лизинг, см. 6591" -4090,"7122","Аренда машин и оборудования для строительства и гражданского строительства","Эта подгруппа включает: -- аренду и операционный лизинг машин и оборудования для строительства и гражданского строительства без оператора: -* грузовых подъемных кранов на автомобильном шасси -* строительных лесов и рабочих платформ, без установки и демонтажа","Эта подгруппа не включает: -- аренда этого вида машин и оборудования с оператором, см. 4550 -- финансовый лизинг, см. 6591" -4080,"7121","Аренда сельскохозяйственных машин и оборудования","Эта подгруппа включает: -- аренду и операционный лизинг сельскохозяйственных и лесозаготовительных машин и оборудования, без оператора: -* аренду изделий, включенных в подгруппу 2921, таких как сельскохозяйственные тракторы и т. п.","Эта подгруппа не включает: -- аренда этого вида машин и оборудования с оператором, см. 0140 -- финансовый лизинг, см. 6591" -4070,"712","Аренда прочих машин и оборудования",, -4060,"7113","Аренда оборудования для воздушного транспорта","Эта подгруппа включает: -- аренду и операционный лизинг оборудования для воздушного транспорта без оператора: -* самолетов -* воздушных шаров, наполняемых горячим воздухом","Эта подгруппа не включает: -- аренду оборудования для воздушного транспорта с оператором, см. 6220 -- финансовый лизинг, см. 6591" -4050,"7112","Аренда оборудования для водного транспорта","Эта подгруппа включает: -- аренду и операционный лизинг оборудования для водного транспорта, без оператора: -* коммерческих лодок и судов","Эта подгруппа не включает: -- аренда и операционный лизинг оборудования для водного транспорта, с оператором, см. 6110, 6120 -- финансовый лизинг, см. 6591 -- прокат прогулочных судов, см. 7130" -4040,"7111","Аренда оборудования для сухопутного транспорта","Эта подгруппа включает: -- аренду и операционный лизинг оборудования для сухопутного транспорта без водителя: -* автомобилей -* грузовиков, тягачей, прицепов и полуприцепов -* мотоциклов, домов-автоприцепов и автофургонов и т. п. -* железнодорожных транспортных средств - -Эта подгруппа также включает: -- сдачу в аренду грузовых контейнеров -- сдачу в аренду грузовых поддонов","Эта подгруппа не включает: -- прокат или аренда транспортных средств или грузовиков с водителем, см. 6022, 6023 -- финансовый лизинг, см. 6591 -- прокат жилых или офисных модулей (контейнеров), см. 7129 -- прокат велосипедов, см. 7130" -4030,"711","Аренда транспортного оборудования",, -4020,"71","Аренда машин и оборудования без оператора и прокат бытовых товаров и предметов личного пользования","Этот подраздел включает аренду и операционный лизинг. Сдача в аренду может быть кратко- и долговременной. Машины и оборудование могут предоставляться с техническим обслуживанием и без него.","Этот подраздел не включает: -- финансовый лизинг, который обычно является специальной формой предоставления кредита, см. 6591" -4010,"7020","Операции с недвижимым имуществом за вознаграждение или на договорной основе","Эта подгруппа включает: -- деятельность агентов и брокеров, занимающихся недвижимым имуществом -- посреднические услуги по покупке, продаже и сдаче внаем недвижимого имущества за вознаграждение или на договорной основе -- эксплуатацию недвижимого имущества за вознаграждение или на договорной основе -- услуги по оценке стоимости недвижимого имущества -- услуги агентов по договорам с недвижимостью с отлагательным условием", -4000,"702","Операции с недвижимым имуществом за вознаграждение или на договорной основе",, -3990,"7010","Операции с недвижимым имуществом, собственным или арендуемым","Эта подгруппа включает: -- покупку, продажу, сдачу внаем или эксплуатацию собственного или арендуемого недвижимого имущества: -* многоквартирных домов и жилищ -* зданий нежилого типа, включая выставочные залы -* земли - -Эта подгруппа также включает: -- разбивку имущества на партии -- благоустройство и продажу земельных участков -- эксплуатацию участков для проживания в передвижных домах","Эта подгруппа не включает: -- благоустройство за собственный счет, включая строительство, см. 4520 -- эксплуатацию гостиниц, домов для приезжих, кемпингов, стоянок для прицепов типа ""дач"" и других мест для временного или краткосрочного проживания, см. 5510" -3980,"701","Операции с недвижимым имуществом, собственным или арендуемым",, -3970,"70","Операции с недвижимым имуществом",, -3960,"K","Операции с недвижимым имуществом, аренда и коммерческая деятельность","Этот раздел включает деятельность, которая в основном относится к деловому направлению с очевидным исключением операций с недвижимым имуществом. Однако в большей или меньшей мере все виды деятельности, классифицированные в этом разделе, могут также быть отнесены к частному домашнему хозяйству, например прокат бытовых товаров и предметов личного пользования, использование баз данных, юридическая деятельность, расследования и услуги в области обеспечения безопасности, оформление интерьеров и фотографические услуги.", -3950,"6720","Деятельность, являющаяся вспомогательной по отношению к страхованию и пенсионному обеспечению","Эта подгруппа включает: -- деятельность, относящуюся к управлению страхованием и пенсионным обеспечением или тесно связанную с ними, кроме финансового посредничества: -* деятельность страховых агентов -* деятельность диспашеров и специалистов по оценке убытков -* деятельность специалистов по оценке страховых рисков и ущерба -* расследования, связанные со страховой деятельностью -* деятельность актуариев -* деятельность распорядителей спасательными работами","Эта подгруппа не включает: -- спасательные работы на море, см. 6303" -3940,"672","Деятельность, являющаяся вспомогательной по отношению к страхованию и пенсионному обеспечению",, -3930,"6719","Деятельность, являющаяся вспомогательной по отношению к финансовому посредничеству, не включенная в другие категории","Эта подгруппа включает: -- деятельность, являющуюся вспомогательной по отношению к финансовому посредничеству, не включенную в другие категории: -* услуги консультантов по финансовым вопросам -* услуги консультантов по ипотечным операциям и брокеров -* услуги меняльных контор и т. п.","Эта подгруппа не включает: -- деятельность страховых агентов, см. 6720 -- деятельность, тесно связанная со страхованием и пенсионным обеспечением, см. 6720" -3920,"6712","Биржевые операции с фондовыми ценностями","Эта подгруппа включает: -- осуществление операций на финансовых рынках по поручению других (например, брокерских операций на фондовой бирже) и связанную с этим деятельность","Эта подгруппа не включает: -- операции на рынках, осуществляемые за собственный счет, см. 6599" -3910,"6711","Управление финансовыми рынками","Эта подгруппа включает: -- функционирование финансовых рынков и контроль за их деятельностью, кроме осуществляемого государственными органами: -* деятельность фондовых бирж, товарных бирж и т. п.", -3900,"671","Деятельность, являющаяся вспомогательной по отношению к финансовому посредничеству, кроме страхования и пенсионного обеспечения",, -3890,"67","Деятельность, являющаяся вспомогательной по отношению к финансовому посредничеству","Этот подраздел включает предоставление услуг, относящихся к финансовому посредничеству или тесно связанных с ним, кроме самих услуг по финансовому посредничеству. Первичная разбивка этого подраздела проведена в соответствии с типом финансовых операций или видом финансового обеспечения.", -3880,"6603","Страхование, кроме страхования жизни","Эта подгруппа включает: -- страхование и перестрахование, не относящиеся к страхованию жизни: -* от несчастного случая и от пожара -* от болезней -* страхование имущества -* автомобильное, морское, авиационное, транспортное страхование -* страхование на случай денежных убытков и страхование гражданской ответственности", -3870,"6602","Пенсионное обеспечение","Эта подгруппа включает: -- обеспечение доходов в связи с выходом на пенсию","Эта подгруппа не включает: -- программы обязательного социального страхования, см. 7530" -3860,"6601","Страхование жизни","Эта подгруппа включает: -- страхование и перестрахование жизни с существенным элементом сбережения или без него", -3850,"660","Страхование и пенсионное обеспечение, кроме обязательного социального страхования",, -3840,"66","Страхование и пенсионное обеспечение, кроме обязательного социального страхования","Этот подраздел включает организации, занимающиеся учреждением и управлением страховых фондов для всех видов страхования (страхование жизни и страхование, кроме страхования жизни), и организации, занимающиеся обеспечением пенсионных денежных поступлений. В любом случае включается деятельность, связанная с накоплением и инвестированием денежных средств. Эта деятельность включает долговременное и кратковременное распределение рисков с элементом или без элемента сбережения. -Этот подраздел различает пенсионное обеспечение и страхование жизни и страхование, кроме страхования жизни, в качестве первичной разбивки.","Этот подраздел не включает: -- обязательное социальное страхование, см. 7530 -- вспомогательную деятельность по страхованию и пенсионному обеспечению, см. 6720" -3830,"6599","Прочее финансовое посредничество, не включенное в другие категории","Эта подгруппа включает: -- прочие виды финансового посредничества, прежде всего связанные с распределением финансовых средств, кроме предоставления займов: -* капиталовложения в ценные бумаги, например акции, облигации, векселя, ценные бумаги для инвестирования на доверительной основе и т. п. -* операции за собственный счет, осуществляемые дилерами по операциям с ценными бумагами -* капиталовложения в собственность, осуществляемые прежде всего для других финансовых посредников (например, общих инвестиционных траст-фондов) -* заключение свопов, опционов и прочих срочных сделок -- деятельность финансовых холдинговых компаний","Эта подгруппа не включает: -- финансовый лизинг, см. 6591 -- операции с ценными бумагами от имени других, см. 6712 -- торговлю собственностью, лизинг и аренду собственности, см. подраздел 70 -- операционный лизинг, см. подраздел 71" -3820,"6592","Прочее предоставление кредита","Эта подгруппа включает: -- финансовое посредничество, прежде всего связанное с предоставлением займов учреждениям, не занимающимся денежным посредничеством: -* предоставление потребительского кредита -* предоставление долгосрочных финансовых займов промышленности -* предоставление денежных ссуд вне банковской системы -* предоставление кредита на покупку домов специальными учреждениями, которые не депонируют вклады -* деятельность ломбардов и ростовщиков","Эта подгруппа не включает: -- предоставление кредита на покупку домов специальными учреждениями, которые также депонируют вклады, см. 6519 -- операционный лизинг, см. подраздел 71, в соответствии с видом товаров, предоставляемых в лизинг" -3810,"6591","Финансовый лизинг","Эта подгруппа включает: -- лизинг, если этот термин приблизительно охватывает предполагаемый срок службы активов и если арендатор получает в основном все выгоды от их использования и принимает на себя все риски, связанные с владением ими. Активы могут или не могут впоследствии переуступаться.","Эта подгруппа не включает: -- операционный лизинг, см. подраздел 71, в соответствии с видом товаров, предоставляемых в лизинг" -3800,"659","Прочее финансовое посредничество","Эта группа включает: -- финансовое посредничество, кроме осуществляемого денежно-кредитными учреждениями","Эта группа не включает: -- страхование и пенсионное обеспечение, см. подраздел 66" -3790,"6519","Прочее денежное посредничество","Эта подгруппа включает: -- денежное посредничество финансовых учреждений, кроме центральных банков, таких как: -* банки -* сберегательные банки -* вексельные конторы -* кредитные союзы - -Эта подгруппа также включает: -- услуги почтовых систем жиросчетов и сберегательных банков -- деятельность специализированных учреждений, предоставляющих кредит на покупку домов, а также депонирующих вклады","Эта подгруппа не включает: -- учреждения, предоставляющие кредит на покупку домов и не депонирующие вклады, см. 6592" -3780,"6511","Деятельность центральных банков","Эта подгруппа включает: -- прием депозитов, используемых для расчетов между финансовыми учреждениями -- контроль за банковскими операциями -- хранение валютных резервов страны -- выпуск денег в обращение и регулирование денежно-кредитной политики страны -* регулирование и контроль над денежной массой в обращении -- выступление в роли банкира для правительства - -Виды деятельности центральных банков могут варьироваться в зависимости от институциональных причин.", -3770,"651","Денежное посредничество","Эта группа включает: -- получение финансовых средств в форме переводных депозитов, например средства в виде фиксированных денежных сумм, которые поступают на нерегулярной основе и из нефинансовых источников, кроме деятельности центральных банков.", -3760,"65","Финансовое посредничество, кроме страхования и пенсионного обеспечения","Этот подраздел включает: -- деятельность, связанную с получением и перераспределением финансовых средств, кроме средств, предназначающихся для целей страхования, пенсионного обеспечения или обязательного социального страхования - -Примечание. Классификации предприятий и учреждений в рамках этого подраздела, скорее всего, будет зависеть от особенностей национальных институциональных структур. -Виды деятельности, связанной с использованием кредитных карт, классифицируются в соответствии с типом оператора.", -3750,"J","Финансовое посредничество","Этот раздел включает учреждения, основной вид деятельности которых связан с финансовыми операциями, например с операциями по созданию, ликвидации или смене владельцев финансовых средств. Кроме того, включены страховая деятельность и пенсионное обеспечение (подраздел 66), а также деятельность, способствующая эффективности финансовых операций (подраздел 67). Сюда же включены учреждения, осуществляющие денежно-кредитное регулирование, органы валютного контроля. - -Этот раздел не включает деятельность в области обязательного социального страхования (см. 7530).", -3740,"6420","Связь","Эта подгруппа включает: -- передачу звука, изображений, данных или другой информации через системы кабельной, радиотрансляционной, релейной или спутниковой связи: -* телефонную, телеграфную и телексную связь -* передачу (транспортирование) радио- и телепрограмм -- техническое обслуживание сети -- предоставление доступа к сети Интернет -- услуги по предоставлению телефонной связи с помощью платных телефонов-автоматов","Эта подгруппа не включает: -- распространение информации через веб-сайты (размещенные в сети Интернет), см. 7240 -- производство радио- и телевизионных программ в сочетании с трансляцией или без трансляции, см. 9213" -3730,"642","Связь",, -3720,"6412","Курьерская деятельность, кроме деятельности национальных почт","Эта подгруппа включает: -- вывоз, перевозку и доставку писем и бандеролей и пакетов фирмами, не относящимися к государственной почтовой службе. Перевозка может осуществляться одним или несколькими видами транспорта, причем может использоваться как собственный (личный), так и общественный транспорт - -Эта подгруппа также включает: -- услуги по доставке почтовой корреспонденции на дом","Эта подгруппа не включает: -- аналогичные виды деятельности, осуществляемые национальным почтовым управлением, см. 6411" -3710,"6411","Деятельность национальных почт","Эта подгруппа включает: -- вывоз, перевозку и доставку (внутреннюю или международную) почтовой корреспонденции и бандеролей -- сбор почтовой корреспонденции и бандеролей из общественных почтовых ящиков или из почтовых отделений -- распределение и доставку почтовой корреспонденции и бандеролей -- аренду почтовых ящиков, услуги по обработке корреспонденции ""до востребования"" и т. п. -- сортировку почтовых отправлений -- продажу почтовых марок","Эта подгруппа не включает: -- услуги почтовых систем жиросчетов и сберегательных касс, а также другие финансовые услуги, предоставляемые в сочетании с почтовой деятельностью, см. 6519" -3700,"641","Почтовая и курьерская деятельность",, -3690,"64","Почта и связь",, -3680,"6309","Деятельность прочих транспортных агентств","Эта подгруппа включает: -- экспедицию грузов -- организацию или меры по организации перевозок автомобильным, морским или воздушным транспортом -- организацию отправки сборных или индивидуальных грузов (включая вывоз и доставку груза и подготовку сборных грузов) -- подготовку транспортной документации и грузовых накладных -- проверку счетов-фактур и предоставление информации о фрахтовых ставках -- деятельность таможенных агентов -- деятельность экспедиторов по грузовым морским перевозкам и агентов по воздушным грузовым перевозкам -- посреднические операции по фрахту грузового места на судне или в самолете -- операции по обработке грузов, например временная укладка в решетчатую тару с целью защиты грузов во время транспортировки, распаковывание, отбор проб товаров, взвешивание грузов","Эта подгруппа не включает: -- деятельность курьерских служб, см. 6412 -- деятельность, связанную со страхованием грузов, см. 6720" -3670,"6304","Деятельность бюро путешествий, туристских агентов и экскурсоводов; деятельность по оказанию помощи туристам, не включенная в другие категории","Эта подгруппа включает: -- деятельность бюро путешествий: -* предоставление информации о маршрутах поездок и консультаций, планирование маршрутов -* организацию поездок по заказу, обеспечение путешественников и туристов жильем и транспортными средствами -* продажу туров со всеми услугами и т. п. -* обеспечение билетами -- деятельность местных информационных туристских бюро и услуги бюро по размещению туристов -- деятельность экскурсоводов", -3660,"6303","Прочая вспомогательная транспортная деятельность","Эта подгруппа включает: -- деятельность, относящуюся к перевозкам пассажиров, животных или грузов наземными видами транспорта: -* обслуживание терминалов, таких как железнодорожные станции, автобусные станции, перегрузочные товарные станции -* эксплуатацию инфраструктуры железных дорог -* эксплуатацию автомобильных дорог, мостов, туннелей, стоянок и гаражей для автомобилей, мест парковки для велосипедов -- деятельность, относящуюся к перевозкам пассажиров, животных или грузов водным транспортом: -* обслуживание терминалов, таких как гавани и пирсы -* обслуживание шлюзов на каналах и т. п. -* навигационные и лоцманские услуги, обслуживание при швартовке к причалу -* лихтерные перевозки, спасательные работы -* обслуживание маяков -- деятельность, относящуюся к перевозкам пассажиров, животных или грузов воздушным транспортом: -* обслуживание терминалов, таких как аэровокзалы и т. п. -* услуги, предоставляемые аэропортом и диспетчерскими службами -* наземное обслуживание на летном поле и т. п. - -Эта подгруппа также включает: -- службы пожаротушения и противопожарные службы в аэропортах -- техническое обслуживание и небольшой ремонт подвижного состава","Эта подгруппа не включает: -- обработку грузов, см. 6301 -- функционирование летных школ, см. 8090 -- эксплуатацию причальных средств, имеющих отношение к прогулочным судам (морские и речные пристани), см. 9249" -3650,"6302","Хранение и складирование","Эта подгруппа включает: -- хранение и складские услуги для всех видов товаров: -* услуги зернохранилищ, товарных складов общего назначения, складов-холодильников, резервуаров-хранилищ и т. п. - -Эта подгруппа также включает: -- хранение грузов во внешнеторговых зонах","Эта подгруппа не включает: -- услуги стоянок для автомобилей, см. 6303" -3640,"6301","Транспортная обработка грузов","Эта подгруппа включает: -- погрузку и разгрузку грузов и багажа пассажиров, независимо от вида транспорта, используемого для перевозки -- стивидорные работы","Эта подгруппа не включает: -- услуги терминалов, см. 6303" -3630,"630","Вспомогательная и дополнительная транспортная деятельность, деятельность бюро путешествий",, -3620,"63","Вспомогательная и дополнительная транспортная деятельность; деятельность бюро путешествий","Этот подраздел включает погрузку и разгрузку грузов непосредственно перед или сразу после транспортировки или между транспортными сегментами. Включены эксплуатация и техническое обслуживание любых транспортных средств. Этот подраздел также включает деятельность по оказанию помощи пассажирам, которую, например, предоставляют бюро путешествий.", -3610,"6220","Воздушный транспорт, не подчиняющийся расписанию","Эта подгруппа включает: -- пассажирские и грузовые перевозки по воздуху, не подчиняющиеся расписанию -- полеты для осмотра живописных мест и достопримечательностей -- запуск спутников и космических транспортных средств -- перевозку товаров и пассажиров в космическом пространстве - -Эта подгруппа также включает: -- регулярные чартерные рейсы -- аренду средств воздушного транспорта с оператором", -3600,"622","Воздушный транспорт, не подчиняющийся расписанию",, -3590,"6210","Воздушный транспорт, подчиняющийся расписанию","Эта подгруппа включает: -- пассажирские и грузовые перевозки по воздуху, осуществляемые по установленным маршрутам и подчиняющиеся расписанию регулярных рейсов","Эта подгруппа не включает: -- регулярные чартерные рейсы, см. 6220" -3580,"621","Воздушный транспорт, подчиняющийся расписанию",, -3570,"62","Воздушный транспорт","Эта подгруппа включает: -- пассажирские и грузовые перевозки по воздуху или в космическом пространстве ","Эта подгруппа не включает: -- опрыскивание посевов с воздуха, см. 0140 -- капитальный ремонт летательных аппаратов и двигателей летательных аппаратов, см. 3530 -- рекламу с летательных аппаратов, см. 7430 -- аэрофотосъемку, см. 7494" -3560,"6120","Внутренний водный транспорт","Эта подгруппа включает: -- пассажирские и грузовые перевозки по рекам, каналам, озерам и прочим внутренним водным путям, включая перевозки в пределах гаваней и портов - -Эта подгруппа также включает: -- аренду развлекательных судов с экипажем для использования в качестве средств внутреннего водного транспорта", -3550,"612","Внутренний водный транспорт",, -3540,"6110","Морской и каботажный водный транспорт","Эта подгруппа включает: -- пассажирские и грузовые перевозки по морю или в прибрежных водах, подчиняющиеся или не подчиняющиеся расписанию: -* услуги экскурсионных, круизных и прогулочных судов -* услуги паромов, водных такси и т. п. -* транспортировку на буксире или при толкании буксирами барж, морских буровых вышек и т. п. -- аренду кораблей и судов с экипажем для выполнения морских и каботажных перевозок - -Эта подгруппа также включает: -- пассажирские и грузовые перевозки по крупным озерам, с использованием судов аналогичного типа -- аренду прогулочных судов с экипажем для выполнения морских и каботажных перевозок","Эта подгруппа не включает: -- услуги ресторанов и баров на борту судов, кроме тех случаев, когда они предоставляются в качестве неотъемлемой части транспортных услуг, см. 5520 -- транспортную обработку грузов, хранение грузов, портовые операции и прочую вспомогательную деятельность, такую как постановка судна в док, услуги лоцманов, погрузка/выгрузка грузов лихтером, спасательные работы, см. подраздел 63 -- деятельность плавучих казино, см. 9249" -3530,"611","Морской и каботажный водный транспорт",, -3520,"61","Водный транспорт","Этот подраздел включает пассажирские или грузовые перевозки по водным путям, подчиняющиеся или не подчиняющиеся расписанию. Включены также услуги буксиров, буксиров-толкачей, экскурсионных, круизных и прогулочных судов, паромов, водных такси и т. п. -Этот подраздел не включает услуги ресторанов и баров на борту судов (см. подгруппу 5520), кроме тех случаев, когда они предоставляются в качестве неотъемлемой части транспортных услуг.", -3510,"6030","Транспортировка по трубопроводам","Эта подгруппа включает: -- транспортировку газов, жидкостей, воды, жидких растворов и других материалов по трубопроводам - -Эта подгруппа также включает: -- техническое обслуживание трубопроводов -- операции насосных станций","Эта подгруппа не включает: -- распределение природного или генерированного газа, воды или пара, см. 4020, 4030, 4100" -3500,"603","Транспортировка по трубопроводам",, -3490,"6023","Фрахтовые перевозки автодорожным транспортом","Эта подгруппа включает: -- все виды деятельности, связанной с фрахтовыми перевозками автодорожным транспортом: -* перевозку лесоматериалов -* перевозку крупногабаритных грузов -* рефрижераторные перевозки -* перевозку тяжелых грузов -* перевозку насыпных грузов, включая перевозку в автомобильных цистернах и сбор молока на фермах -* перевозку автомобилей -* перевозку мусора и различных отходов, без сбора или утилизации - -Эта подгруппа также включает: -- перевозку мебели -- аренду грузовых автомобилей с водителем -- грузовые перевозки транспортными средствами, передвигаемыми человеком, или на животной тяге","Эта подгруппа не включает: -- перевозку лесоматериалов по лесу, являющуюся частью работ по лесозаготовке, см. 0200 -- услуги терминалов по транспортной обработке грузов, см. 6303 -- укладку и упаковывание для целей транспортировки, см. 6309 -- деятельность почтовых и курьерских служб, см. 641 -- транспортировку отходов как неотъемлемую часть деятельности по сбору отходов, выполняемую специализированными предприятиями, см. 9000" -3480,"6022","Прочий пассажирский сухопутный транспорт, не подчиняющийся расписанию","Эта подгруппа включает: -- деятельность всех видов сухопутного пассажирского транспорта, не подчиняющегося расписанию: -* при выполнении чартерных рейсов, экскурсий и предоставление других услуг по автобусным перевозкам на нерегулярной основе -* работу такси - -Эта подгруппа также включает: -- прочую аренду личных машин с водителем -- пассажирские перевозки транспортными средствами, передвигаемыми человеком, или на животной тяге и т. п.","Эта подгруппа не включает: -- перевозку машинами скорой помощи, см. 8519" -3470,"6021","Прочий пассажирский сухопутный транспорт, подчиняющийся расписанию","Эта подгруппа включает: -- деятельность, обеспечивающую регулярные внутригородские, пригородные и междугородные перевозки пассажиров по установленным маршрутам, как правило, подчиняющиеся установленному расписанию, с посадкой и высадкой пассажиров на остановках, расположенных в установленных местах. Такие перевозки могут осуществляться автобусами, трамваями, троллейбусами, метро и надземным железнодорожным транспортом и т. п. - -Эта подгруппа также включает: -- перевозки школьными автобусами, перевозки по маршрутам город-аэропорт или город-вокзал, перевозки фуникулерами, воздушными канатными дорогами и т. п.","Эта подгруппа не включает: -- пассажирские перевозки, осуществляемые междугородным железнодорожным транспортом, см. 6010" -3460,"602","Прочий сухопутный транспорт",, -3450,"6010","Железнодорожный транспорт","Эта подгруппа включает: -- пассажирские перевозки по междугородним железным дорогам -- грузовые перевозки по междугородним, пригородным и городским железным дорогам - -Эта подгруппа также включает: -- смежные виды деятельности, такие как диспетчерская работа и маневровые операции -- услуги спальных вагонов и вагонов-ресторанов как неотъемлемую часть деятельности железнодорожных компаний","Эта подгруппа не включает: -- услуги спальных вагонов и вагонов-ресторанов, если они предоставляются отдельными фирмами, см. 5510, 5520 -- пассажирский транспорт городской и пригородной систем перевозок, см. 6021 -- деятельность пассажирских и грузовых терминалов, транспортную обработку грузов, хранение и прочую вспомогательную деятельность, см. подраздел 63 -- техническое обслуживание и мелкий ремонт подвижного состава, см. 6303 -- эксплуатацию инфраструктуры железной дороги, см. 6303" -3440,"601","Железнодорожный транспорт",, -3430,"60","Сухопутный транспорт; транспортировка по трубопроводам","Этот подраздел включает перевозку пассажиров и грузов по автомобильным и железным дорогам, а также транспортировку грузов по трубопроводам.", -3410,"5520","Рестораны, бары и столовые","Эта подгруппа включает: -- продажу готовой пищи для потребления непосредственно на месте, а также продажу напитков к пище, возможно, в сопровождении развлекательной программы: -* в обычных ресторанах -* в ресторанах самообслуживания, таких как кафетерии -* на предприятиях быстрого питания, таких как закусочные по продаже гамбургеров -* в ресторанах, торгующих на вынос -* в палатках-закусочных, продающих рыбные закуски, чипсы и т. п. -* в небольших кафе-мороженых -- продажу напитков для потребления непосредственно на месте, возможно, в сопровождении развлекательной программы: -* в пабах, барах, ночных клубах, пивных залах и т. п. -- продажу пищевых блюд и напитков, обычно по сниженной цене, строго определенным группам лиц, которые в основном связаны между собой профессиональной деятельностью: -* в буфетах спортивных организаций, промышленных предприятий или офисов -* в буфетах и на кухнях школ -* в обеденных залах университетов -* в столовых и буфетах, предназначенных для питания военнослужащих и т. п. - -Эта подгруппа также включает: -- поставку продуктов питания, например деятельность контрактных фирм, поставляющих готовую пищу, приготовленную на центральном предприятии и предназначенную для потребления в другом месте, например поставка готовых блюд для: -* питания пассажиров самолетов -* разъездной торговли пищевыми продуктами -* обслуживания банкетов, корпоративных встреч -* обслуживания свадеб, торжественных встреч, других мероприятий или торжеств -- деятельность передвижных закусочных на автомобилях, выполняемая специализированными фирмами -- ресторанные и буфетные услуги на борту судов, предоставляемые специализированными фирмами","Эта подгруппа не включает: -- продажу через торговые автоматы, см. 5259 -- продажу напитков не для немедленного употребления, см. подраздел 52 -- услуги вагонов-ресторанов, являющиеся неотъемлемой частью деятельности железнодорожных компаний или других предприятий пассажирского транспорта, см. 6010" -3400,"552","Рестораны, бары и столовые",, -3390,"5510","Гостиницы; площадки для кемпинга и другие места для краткосрочного проживания","Эта подгруппа включает: -- предоставление места для краткосрочного проживания: -* в отелях, мотелях и гостиницах -* в отелях с возможностью проведения конференций -* на курортах -* в шале, коттеджах и квартирах выходного дня -* в студенческих общежитиях, школах-интернатах -* в гостиницах для временных рабочих -* на территории и в помещениях кемпинга, в лагерях-стоянках для домов-прицепов -* в прочих местах кратковременного проживания, таких как дома для приезжих, жилые дома на фермах, молодежные общежития, хижины в горах (приюты) и т. п. - -Эта подгруппа также включает: -- услуги спальных вагонов, предоставляемые отдельными фирмами","Эта подгруппа не включает: -- аренду жилых помещений для длительного проживания, см. 7010 -- услуги спальных вагонов, являющиеся неотъемлемой частью деятельности железнодорожных компаний или других предприятий пассажирского транспорта, см. 6010" -3380,"551","Гостиницы; площадки для кемпинга и другие места для краткосрочного проживания",, -3370,"55","Гостиницы и рестораны","Этот раздел охватывает предприятия, предоставляющие клиентам места для кратковременного проживания и/или занимающиеся приготовлением готовых блюд, легких закусок и напитков для немедленного потребления. Этот раздел включает услуги по размещению и питанию людей, так как эти два вида деятельности часто сочетаются в одном предприятии. -В разделе Н может обнаружиться некоторое наложение видов деятельности. Ресторанная деятельность является видом специализированной деятельности, но она может также включать и предоставление места для проживания. -Гостиничные учреждения предоставляют места для проживания или кратковременного пребывания пассажиров, отпускников и пр. Существует широкий спектр учреждений подобного рода. Некоторые учреждения предоставляют только места для проживания, в то время как другие предоставляют питание и оборудование для активного отдыха одновременно с местами для проживания. Тип предоставляемых дополнительных услуг может значительно варьироваться для разных учреждений и предприятий. -Учреждения, принадлежащие к группе ресторанов, предоставляют полное питание для непосредственного потребления. Такими учреждениями могут быть обычные рестораны, рестораны самообслуживания и предприятия питания, продающие готовые блюда на вынос, а также временные или стационарные киоски по продаже рыбных закусок и картофельных чипсов, имеющие сидячие места или без них. Решающим является сам факт предложения готовых к употреблению пищевых товаров, а не вид предприятия, предлагающего такие товары. Исключением является производство блюд, не готовых к немедленному потреблению, блюд, не предназначенных для немедленного потребления, и готовых продуктов питания, которые не считаются блюдом (см. подраздел 15). Кроме того, исключение составляет торговля пищевыми продуктами, которые не приготовлены на данном предприятии и которые не считаются блюдом, или блюдами, не предназначенными для немедленного потребления (см. раздел G).", -3360,"H","Гостиницы и рестораны",, -3350,"5260","Ремонт бытовых товаров и предметов личного пользования","Эта подгруппа включает: -- ремонт бытовых электротоваров -- ремонт потребительских электронных товаров: -* телевизоров, радиоприемников, кассетных видеомагнитофонов (ВМ), проигрывателей компакт-дисков (СD-плейеров) и т. п. -* телефонных аппаратов, включая мобильные телефоны -- ремонт обуви, чемоданов и сумок и аналогичных изделий -- ремонт велосипедов -- ремонт и переделку одежды -- ремонт и переделку ювелирных изделий -- ремонт часов -- настройку пианино -- услуги в присутствии заказчика", -3340,"526","Ремонт бытовых товаров и предметов личного пользования","Эта группа включает: -- ремонт предметов личного пользования и бытовых товаров, если он производится не в сочетании с изготовлением, оптовой или розничной продажей этих товаров. Если ремонт производится в сочетании с изготовлением, оптовой или розничной продажей этих товаров, то ремонт включается в оптовую или розничную торговлю, а также в производственную деятельность","Эта подгруппа не включает: -- ремонт автомобилей и мотоциклов, см. подраздел 50" -3330,"5259","Прочая розничная торговля не в магазинах","Эта подгруппа включает: -- розничную торговлю любым видом товаров, осуществляемую любыми способами, не включенными в предыдущие подгруппы: -* путем прямых продаж или через торговых агентов, которые обходят квартиры с целью продать свой товар (коммивояжеров) -* через торговые автоматы и т. п. -- розничную торговлю за вознаграждение или на договорной основе -- деятельность Интернет-аукционов и прочих аукционов (розница), проводимых не в магазине","Эта подгруппа не включает: -- доставку на дом новых товаров, осуществляемую магазинами, см. группы 521-523" -3320,"5252","Розничная торговля через палатки и рынки","Эта подгруппа включает: -- розничную торговлю любым видом товаров обычно в передвижных палатках, располагающихся или вдоль шоссейных дорог, или в определенном месте, отведенном для рынка", -3310,"5251","Розничная торговля через фирмы, выполняющие заказы по почте","Эта подгруппа включает: -- розничную торговлю любым видом товаров, осуществляемую путем заказов по почте. Товары высылаются покупателям, которые выбирают их по рекламе, каталогам, моделям или другим видам предлагаемых образцов - -Эта подгруппа также включает: -- прямую продажу товаров с помощью телевидения и радио, по телефону и Интернету", -3300,"525","Розничная торговля не в магазинах",, -3290,"5240","Розничная торговля подержанными товарами в магазинах","Эта подгруппа включает: -- розничную торговлю букинистическими книгами -- розничную торговлю прочими подержанными товарами -- розничную торговлю антиквариатом -- деятельность аукционных домов (розница)","Эта подгруппа не включает: -- розничную торговлю подержанными автомобилями, см. 5010 -- деятельность Интернет-аукционов и прочих аукционов (розница), проводимых не в магазине, см. 5259 -- деятельность ломбардов, см. 6592" -3280,"524","Розничная торговля подержанными товарами в магазинах",, -3270,"5239","Прочая розничная торговля в специализированных магазинах","Эта подгруппа включает магазины, специализирующиеся на: -- розничной торговле офисным оборудованием, компьютерами и программным обеспечением общего назначения -- розничной торговле конторскими вспомогательными материалами, такими как ручки, карандаши, бумага и т. п. -- розничной торговле книгами, газетами и канцелярскими принадлежностями -- розничной торговле фото- и оптическим оборудованием и точными приборами -- розничной торговле телекоммуникационным оборудованием -- деятельности салонов оптики -- розничной торговле обоями и покрытиями для полов -- розничной торговле коврами и ковриками -- розничной торговле наручными и прочими часами и ювелирными изделиями -- розничной торговле спортивными товарами, рыболовными принадлежностями, товарами для туризма, лодками и велосипедами -- розничной торговле играми и игрушками -- розничной торговле цветами, растениями, семенами, удобрениями, домашними животными и кормами для домашних животных -- розничной торговле сувенирами, кустарной продукцией и изделиями религиозного назначения -- розничной торговле котельным топливом, газом в баллонах, углем и древесным топливом -- розничной торговле чистящими материалами -- розничной торговле оружием и амуницией -- розничной торговле почтовыми марками и монетами -- розничной торговле не относящимися к пищевым продуктам товарами, не включенными в другие категории","Эта подгруппа не включает: -- розничную торговлю букинистическими и антикварными книгами, см. 5240" -3260,"5234","Розничная торговля скобяными изделиями, красками и стеклом","Эта подгруппа включает магазины, специализирующиеся на: -- розничной торговле скобяными изделиями -- розничной торговле красками, лаками и эмалями -- розничной торговле листовым стеклом -- розничной торговле прочими строительными материалами, такими как кирпич, древесина, санитарно-техническое оборудование -- розничной торговле материалами и оборудованием для ""умелых рук"" - -Эта подгруппа также включает: -- розничную торговлю газонокосилками с любым приводом -- розничную торговлю саунами", -3250,"5233","Розничная торговля бытовыми приборами, изделиями и оборудованием","Эта подгруппа включает магазины, специализирующиеся на: -- розничной торговле мебелью для жилых помещений -- розничной торговле осветительными приборами -- розничной торговле домашней утварью и ножевыми изделиями, фаянсовой посудой, изделиями из стекла, фарфора и керамики -- розничной торговле портьерами и гардинами из тюля -- розничной торговле бытовыми предметами из текстильных материалов -- розничной торговле изделиями из дерева, пробки и плетеных материалов -- розничной торговле бытовыми предметами и оборудованием, не включенными в другие категории -- розничной торговле бытовыми электроприборами -- розничной торговле радио- и телевизионным оборудованием и другим бытовым аудиовизуальным оборудованием -- розничной торговле грампластинками, аудио- и видеокассетами, компакт-дисками и кассетами -- розничной торговле музыкальными инструментами и партитурами","Эта подгруппа не включает: -- розничную торговлю плиточными материалами из пробки для полов, см. 5239 -- розничную торговлю антиквариатом, см. 5240 -- прокат кассет и пластинок, см. 7130" -3240,"5232","Розничная торговля текстильными изделиями, одеждой, обувью и изделиями из кожи","Эта подгруппа включает магазины, специализирующиеся на: -- розничной торговле тканями -- розничной торговле трикотажной пряжей -- розничной торговле исходными материалами для производства ковровых изделий, гобеленов или вышитых изделий -- розничной торговле текстильными изделиями -- розничной торговле галантерейными товарами: иголками, швейными нитками и т. п. -- розничной торговле одеждой -- розничной торговле мехом -- розничной торговле аксессуарами одежды, такими как перчатки, галстуки, подтяжки и т. п. -- розничной торговле обувью -- розничной торговле изделиями из кожи -- розничной торговле дорожными принадлежностями из кожи и кожзаменителей", -3230,"5231","Розничная торговля фармацевтическими и медицинскими товарами, косметическими товарами и туалетными принадлежностями","Эта подгруппа включает магазины, специализирующиеся на: -- розничной торговле фармацевтическими товарами -- розничной торговле медицинскими и ортопедическими товарами -- розничной торговле парфюмерией и косметическими товарами", -3220,"523","Прочая розничная торговля новыми товарами в специализированных магазинах","Эта группа включает магазины, специализирующиеся на розничной торговле товарами особых категорий.", -3210,"5220","Розничная торговля пищевыми продуктами, напитками и табачными изделиями в специализированных магазинах","Эта подгруппа включает магазины, занимающиеся розничной торговлей и специализирующиеся на продаже товарами следующих категорий: -- свежих или консервированных фруктов и овощей -- молочных продуктов и яиц -- мяса (включая мясо птицы) и мясных продуктов -- рыбы и рыбных продуктов, а также других морепродуктов -- хлебобулочных изделий -- кондитерских изделий из сахара -- напитков (не предназначенных для потребления на месте продажи) -- табачных изделий -- прочих пищевых продуктов", -3200,"522","Розничная торговля пищевыми продуктами, напитками и табачными изделиями в специализированных магазинах",, -3190,"5219","Прочая розничная торговля в неспециализированных магазинах","Эта подгруппа включает торговые предприятия, занимающиеся: -- розничной торговлей товарами широкого ассортимента, в котором, однако, пищевые продукты, напитки и табачные изделия не должны преобладать -- деятельностью, свойственной универсальным магазинам, торгующим товарами общего ассортимента, включая одежду, мебель, приборы, скобяные изделия, косметику, ювелирные изделия, игрушки, спортивные товары и т. п.", -3180,"5211","Розничная торговля в неспециализированных магазинах преимущественно пищевыми продуктами, напитками и табачными изделиями","Эта подгруппа включает торговые предприятия, занимающиеся: -- розничной торговлей товарами широкого ассортимента, в котором, однако, пищевые продукты, напитки и табачные изделия должны преобладать: -* универсальные магазины, в которых, наряду с основной продажей пищевых продуктов, напитков и табачных изделий, продается еще несколько категорий товаров, таких как одежда, мебель, приборы, скобяные изделия, косметика и т. п.", -3170,"521","Неспециализированная розничная торговля",, -3160,"52","Розничная торговля, кроме торговли автомобилями и мотоциклами; ремонт бытовых товаров и предметов личного пользования","Этот подраздел включает перепродажу (продажу без видоизменения) новых и бывших в употреблении товаров преимущественно широкой публике для личного потребления или домашнего использования магазинами, универмагами, палатками, фирмами, выполняющими заказы по почте, уличными торговцами или торговцами вразнос, потребительскими кооперативами и т. п. -Розничная торговля в первую очередь классифицируется по типу предприятия сбыта (розничная торговля, осуществляемая через магазины: группы 521-524; розничная торговля с помощью других средств: группа 525). Розничная торговля, осуществляемая через магазины, подразделяется далее на розничную торговлю новыми товарами (группы 521-523) и розничную торговлю подержанными товарами (группа 524). Розничная торговля новыми товарами, осуществляемая через магазины, подразделяется на специализированную розничную торговлю (группы 522 и 523) и неспециализированную розничную торговлю (группа 521). Указанные группы далее подразделяются по назначению продаваемых товаров. Продажа не через магазины включает перечень форм торговли (например, выполнение заказов по почте, торговля на рынках, доставка товаров на дом, продажа через автоматы и т. п.). -Номенклатура товаров, поступающих в классифицированную в данном подразделе торговлю, по очевидным причинам ограничивается так называемыми потребительскими товарами и не включает товары, обычно не поступающие в розничную торговлю, например зерно, руды, машины и оборудование промышленного назначения и т. п. -Данный подраздел также включает деятельность предприятий, занимающихся продажей широкой публике товаров из числа выставленных на обозрение, таких как пишущие машинки, канцелярские принадлежности, краски или лесоматериалы, хотя продаваемые товары, возможно, предназначаются не только для личного потребления или домашнего использования. -В отдельных случаях может производиться некоторая обработка товаров, но это всего лишь частное явление в торговле. -В данный подраздел также включена розничная торговля, выполняемая комиссионными агентами, деятельность розничных аукционных домов, ремонт и установка бытовых товаров и предметов личного пользования, выполняемые совместно с розничной торговлей или отдельно.","Эта подгруппа не включает: -- продажу сельскохозяйственной продукции фермерами, см. подраздел 01 -- производство и продажу товаров (например, пищевых продуктов), которые, как правило, классифицируются как производство в подразделах 15-37 -- продажу автомобилей, мотоциклов и их деталей, а также горючего для этих изделий, см. подраздел 50 -- продажу зерна, руд, сырой нефти, химикатов промышленного назначения, чугуна и стали, а также механизмов и оборудования промышленного назначения, см. подраздел 51 -- продажу пищевых продуктов и напитков для потребления на месте продажи и продажа готовых пищевых блюд, отпускаемых на дом, см. 5520 -- предоставление напрокат бытовых товаров и предметов личного пользования широкой публике, см. 7130" -3150,"5190","Прочая оптовая торговля","Эта подгруппа включает: -- специализированную оптовую торговлю, не охваченную ни в одной из предыдущих категорий -- оптовую торговлю широким ассортиментом товаров без какой-либо конкретной специализации", -3140,"519","Прочая оптовая торговля",, -3134,"5159","Оптовая торговля прочими машинами, оборудованием и вспомогательными материалами","Эта подгруппа включает: -- оптовую торговлю машинами и оборудованием офисного назначения, кроме компьютеров и компьютерного периферийного оборудования -- оптовую торговлю офисной мебелью -- оптовую торговлю транспортным оборудованием, кроме автомобилей, мотоциклов и велосипедов -- оптовую торговлю роботизированными автоматическими линиями -- оптовую торговлю проводом и коммутаторами, прочим установочным оборудованием промышленного использования -- оптовую торговлю прочими электротехническими изделиями, такими как электрические двигатели, трансформаторы -- оптовую торговлю прочими машинами, не включенными в другие категории, для использования в промышленности, торговле, навигации и других отраслях - -Эта подгруппа также включает: -- оптовую торговлю станками с компьютерным управлением -- оптовую торговлю машинами с компьютерным управлением для текстильной промышленности и швейными и вязальными машинами с компьютерным управлением -- оптовую торговлю измерительным инструментом и оборудованием -- оптовую торговлю газонокосилками с любым приводом","Эта подгруппа не включает: -- оптовую торговлю автомобилями, прицепами и домами-автоприцепами, см. 5010 -- оптовую торговлю деталями автомобилей, см. 5030 -- оптовую торговлю мотоциклами, см. 5040 -- оптовую торговлю велосипедами, см. 5139 -- оптовую торговлю компьютерами и периферийным оборудованием, см. 5151 -- оптовую торговлю деталями и оборудованием электронного и телекоммуникационного назначения, см. 5152" -3132,"5152","Оптовая торговля электронным и телекоммуникационным оборудованием и комплектующими","Эта подгруппа включает: -- оптовую торговлю электронными лампами и приборами -- оптовую торговлю полупроводниковыми приборами -- оптовую торговлю микрочипами и интегральными схемами -- оптовую торговлю печатными схемами -- оптовую торговлю ""чистыми"" (незаписанными) магнитными лентами для аудио- и видеозаписи и дискетами, магнитными и оптическими дисками -- оптовую торговлю телефонным и коммуникационным оборудованием","Эта подгруппа не включает: -- оптовую торговлю компьютерами и компьютерным периферийным оборудованием, см. 5151" -3130,"5151","Оптовая торговля компьютерами, компьютерным периферийным оборудованием и программным обеспечением","Эта подгруппа включает: -- оптовую торговлю компьютерами и компьютерным периферийным оборудованием -- оптовую торговлю программным обеспечением","Эта подгруппа не включает: -- оптовую торговлю электронными деталями, см. 5152 -- оптовую торговлю копировальными машинами и другим офисным оборудованием, см. 5159 -- оптовую торговлю оборудованием с компьютерным управлением, см. 5159" -3120,"515","Оптовая торговля машинами, оборудованием и вспомогательными материалами",, -3110,"5149","Оптовая торговля прочими промежуточными продуктами, отходами и ломом","Эта подгруппа включает: -- оптовую торговлю химическими веществами производственного назначения: -* анилином, типографской краской, эфирными маслами, промышленными газами, химическими клеями, красителями, синтетическими смолами, метанолом, парафином, отдушками и ароматическими веществами, содой, технической солью, кислотами и серой, крахмалистыми веществами и т. п. -- оптовую торговлю удобрениями и товарами агрохимического назначения -- оптовую торговлю пластическими материалами в первичной форме -- оптовую торговлю резиной -- оптовую торговлю текстильным волокном и т. п. -- оптовую торговлю бумагой в больших партиях -- оптовую торговлю драгоценными камнями -- оптовую торговлю металлическими и неметаллическими отходами и ломом, материалами для вторичной переработки, включая сбор, сортировку, разделение, разборку бывших в употреблении товаров, таких как легковые автомобили, с тем чтобы получить детали, пригодные для повторного использования, упаковывание и переупаковывание, хранение и доставка, но без осуществления процесса реального видоизменения. Кроме того, приобретенные и проданные отходы имеют остаточную стоимость -- демонтаж транспортных средств, достигших конца срока службы (разборка легковых автомобилей; оптовая торговля автомобилями в аварийном состоянии; продажа деталей, снятых с автомобилей в аварийном состоянии, частным лицам и профессиональным пользователям)","Эта подгруппа не включает: -- переработку отходов, лома и других изделий во вторичный сырьевой материал, когда необходимо осуществить процесс реального видоизменения. Полученный вторичный сырьевой материал не является конечным продуктом и направляется для прямого использования в процессе промышленного производства, см. 3710 и 3720 -- утилизацию старых судов, см. 3710 -- резку легковых автомобилей механическим способом, см. 3710 -- розничную торговлю товарами, бывшими в употреблении, см. 5240 -- обработку отходов не для дальнейшего использования в процессе промышленного производства, а с целью удаления, см. 9000 -- сбор и обработку бытовых и промышленных отходов, см. 9000" -3100,"5143","Оптовая торговля строительными материалами, скобяными изделиями, водопроводным и отопительным оборудованием и вспомогательными материалами","Эта подгруппа включает: -- оптовую торговлю древесиной в необработанном виде -- оптовую торговлю продукцией первичной обработки лесоматериалов -- оптовую торговлю красками и лаками -- оптовую торговлю строительными материалами: -* песком, гравием -- оптовую торговлю листовым стеклом -- оптовую торговлю скобяными и замочными изделиями -- оптовую торговлю фитингами и арматурой -- оптовую торговлю нагревателями для воды -- оптовую торговлю сантехническим оборудованием: -* ваннами, раковинами для умывания, унитазами и другими изделиями из фарфора санитарно-технического назначения -- оптовую торговлю монтажно-установочным оборудованием санитарно-технического назначения: -* трубами, патрубками, фитингами, кранами, тройниками, соединителями, резиновыми трубками и т. п. -- оптовую торговлю инструментами, такими как молотки, пилы, отвертки и прочий ручной инструмент", -3090,"5142","Оптовая торговля металлами и металлическими рудами","Эта подгруппа включает: -- оптовую торговлю железной рудой и рудами цветных металлов -- оптовую торговлю черными и цветными металлами в первичных формах -- оптовую торговлю полуфабрикатами изделий из черных и цветных металлов, не включенными в другие категории -- оптовую торговлю золотом и другими драгоценными металлами","Эта подгруппа не включает: -- оптовую торговлю отходами и ломом, см. 5149" -3080,"5141","Оптовая торговля твердым, жидким и газообразным топливом и смежной продукцией","Эта подгруппа также включает: -- оптовую торговлю топливом для транспортных средств с двигателем внутреннего сгорания, маслами, жидкими и твердыми смазочными материалами и т. п.", -3070,"514","Оптовая торговля несельскохозяйственными промежуточными продуктами, отходами и ломом",, -3060,"5139","Оптовая торговля прочими бытовыми товарами","Эта подгруппа включает: -- оптовую торговлю мебелью для жилых помещений -- оптовую торговлю бытовыми приборами -- оптовую торговлю осветительным оборудованием -- оптовую торговлю ножевыми изделиями -- оптовую торговлю изделиями из стекла и дерева -- оптовую торговлю обоями и покрытиями для полов -- оптовую торговлю фармацевтическими и медицинскими товарами -- оптовую торговлю парфюмерией, косметикой и мылом -- оптовую торговлю велосипедами, деталями и принадлежностями для них -- оптовую торговлю писчебумажными изделиями, книгами, журналами и газетами, фото- и оптическими товарами, изделиями из кожи и дорожными принадлежностями, наручными и прочими часами, ювелирными изделиями, музыкальными инструментами, играми и игрушками, спортивными товарами, изделиями из дерева, плетеными изделиями и изделиями из пробки и т. п.","Эта подгруппа не включает: -- оптовую торговлю офисной мебелью, см. 5159" -3050,"5131","Оптовая торговля текстильными изделиями, одеждой и обувью","Эта подгруппа включает: -- оптовую торговлю пряжей -- оптовую торговлю тканями -- оптовую торговлю столовым и постельным бельем -- оптовую торговлю галантерейными товарами: иголками, швейными нитками и т. п. -- оптовую торговлю одеждой, включая спортивную одежду -- оптовую торговлю аксессуарами одежды, такими как перчатки, галстуки и корсеты -- оптовую торговлю обувью -- оптовую торговлю меховыми изделиями -- оптовую торговлю зонтами","Эта подгруппа не включает: -- оптовую торговлю ювелирными и кожаными изделиями, см. 5139 -- оптовую торговлю текстильным волокном, см. 5149" -3040,"513","Оптовая торговля бытовыми товарами",, -3030,"5122","Оптовая торговля пищевыми продуктами, напитками и табачными изделиями","Эта подгруппа включает: -- оптовую торговлю фруктами и овощами -- оптовую торговлю молочными продуктами -- оптовую торговлю яйцами и продуктами, получаемыми из яиц -- оптовую торговлю пищевыми маслами и жирами животного или растительного происхождения -- оптовую торговлю мясом и мясными продуктами -- оптовую торговлю рыбными продуктами -- оптовую торговлю сахаром, шоколадом и кондитерскими изделиями из сахара -- оптовую торговлю хлебобулочными изделиями -- оптовую торговлю напитками -- оптовую торговлю кофе, чаем, какао и пряностями -- оптовую торговлю табачными изделиями - -Эта подгруппа также включает: -- покупку вина наливом и разлив в бутылки без видоизменения -- оптовую торговлю кормами для домашних животных","Эта подгруппа не включает: -- смешивание вин или дистиллированных спиртов, см. 1551" -3020,"5121","Оптовая торговля сельскохозяйственным сырьем и живыми животными","Эта подгруппа включает: -- оптовую торговлю зерном и семенами -- оптовую торговлю масличными плодами -- оптовую торговлю цветами и растениями -- оптовую торговлю необработанным табаком -- оптовую торговлю живыми животными -- оптовую торговлю шкурами и кожами -- оптовую торговлю кожей -- оптовую торговлю сельскохозяйственным материалом, отходами, остатками и побочными продуктами, используемыми в качестве кормов для животных","Эта подгруппа не включает: --оптовая торговля текстильным волокном, см. 5149" -3010,"512","Оптовая торговля сельскохозяйственным сырьем, живыми животными, пищевыми продуктами, напитками и табачными изделиями",, -3000,"5110","Оптовая торговля за вознаграждение или на договорной основе","Эта подгруппа включает: -- деятельность комиссионных агентов, маклеров по купле-продаже сырья и всех прочих оптовых торговцев, осуществляющих сделки от имени или за счет других лиц или фирм -- деятельность лиц, сводящих продавцов с покупателями или осуществляющих коммерческие сделки от имени владельца, включая использование для этой цели сети Интернет - -Эта подгруппа также включает: -- деятельность аукционных домов по оптовой торговле","Эта подгруппа не включает: -- оптовую торговлю от собственного имени, см. 512-519 -- розничную торговлю, выполняемую агентами, см. подраздел 52 -- деятельность страховых агентов, см. 6720 -- деятельность агентов по продаже недвижимости, см. 7020" -2990,"511","Оптовая торговля за вознаграждение или на договорной основе",, -2980,"51","Оптовая и комиссионная торговля, кроме торговли автомобилями и мотоциклами","Этот подраздел включает: -- перепродажу (продажу без видоизменения) новых или бывших в употреблении товаров розничным торговцам, промышленным, коммерческим, учрежденческим или профессиональным пользователям или же другим оптовым торговцам, а также лицам, исполняющим обязанности агентов при покупке товаров от имени таких лиц или компаний или продаже им товаров: -* деятельность оптовых торговцев, маклеров, предприятий оптовой торговли, специализирующихся на обслуживании промышленности, экспортеров, импортеров, объединений по закупкам на кооперативных началах, маклеров, осуществляющих операции с готовой продукцией и сырьем, торговцев, покупающих товары для продажи на комиссионных началах, а также агентов и оптовиков-скупщиков, заготовителей и кооперативных объединений, занимающихся сбытом сельскохозяйственной продукции - -Этот подраздел также включает: -- обычные виды деятельности, включенные в оптовую торговлю, например скупку, сортировку и распределение по сортам крупных партий товаров, их разбивку на мелкие партии, переупаковывание и разлив в бутылочную тару, перераспределение в мелкие расфасовки, например фармацевтической продукции; хранение, охлаждение, доставку и установку товаров за свой счет -- упаковывание твердых товаров и бутылирование жидких или газообразных товаров, включая смешивание и фильтрование за свой счет","Этого подраздел не включает: -- оптовую торговлю автомобилями, домами-автоприцепами и мотоциклами, см. 5010, 5040 -- оптовую торговлю принадлежностями к моторам, см. 5030, 5040 -- сдачу в аренду и лизинг товаров, см. подраздел 71 -- упаковывание твердых товаров и бутылирование жидких или газообразных товаров, включая смешивание и фильтрование для третьих лиц, см. 7495" -2970,"5050","Розничная продажа горючего для транспортных средств с двигателями внутреннего сгорания","Эта подгруппа включает: -- розничную продажу горючего для автомобилей, мотоциклов и т. п.: -* моторного бензина -* газолина -* бензина -* жидкого нефтяного газа - -Эта подгруппа также включает: -- розничную продажу аналогичного топлива, используемого на судах -- розничную продажу смазочных масел и охладителей, используемых для автомобилей","Эта подгруппа не включает: -- оптовую продажу топлива, см. 5141 -- розничную продажу жидкого нефтяного газа для приготовления пищи или обогрева, см. 5239" -2960,"505","Розничная продажа горючего для транспортных средств с двигателями внутреннего сгорания",, -2950,"5040","Продажа, техническое обслуживание и ремонт мотоциклов и продажа соответствующих деталей и принадлежностей","Эта подгруппа включает: -- оптовую и розничную продажу мотоциклов, включая мопеды -- оптовую и розничную продажу, включая заказ по почте, частей и принадлежностей для мотоциклов -- деятельность комиссионных агентов -- техническое обслуживание и ремонт мотоциклов","Эта подгруппа не включает: -- продажу, техническое обслуживание и ремонт велосипедов и соответствующих деталей и принадлежностей, см. 5110, 5139, 5239, 5260" -2940,"504","Продажа, техническое обслуживание и ремонт мотоциклов и продажа соответствующих деталей и принадлежностей",, -2930,"5030","Продажа деталей и принадлежностей для автомобилей","Эта подгруппа включает: -- оптовую и розничную продажу всех видов деталей, компонентов, расходных материалов, инструментов и принадлежностей для автомобилей (если она не объединена с продажей автомобилей)", -2920,"503","Продажа деталей и принадлежностей для автомобилей",, -2910,"5020","Техническое обслуживание и ремонт автомобилей","Эта подгруппа включает: -- техническое обслуживание и ремонт автомобилей: -* механический ремонт -* электрический ремонт -* ремонт систем электронного впрыска топлива -* текущее обслуживание -* ремонт кузова -* ремонт деталей автомобиля -* мойку, полировку и т. п. -* напыление и окраску -* ремонт решеток и окон -* ремонт сидений -- ремонт шин и камер, их установку или замену -- антикоррозионную обработку -- установку деталей и принадлежностей, не являющуюся частью производственного процесса -- буксировку -- оказание помощи на дороге","Эта подгруппа не включает: -- восстановление протектора и капитальный ремонт шин, см. 2511" -2900,"502","Техническое обслуживание и ремонт автомобилей",, -2890,"5010","Продажа автомобилей","Эта подгруппа включает: -- оптовую и розничную продажу новых и подержанных транспортных средств: -* легковых автомобилей, в том числе специализированных пассажирских автомобилей, таких как машины скорой помощи, микроавтобусы и т. п. -* грузовиков, прицепов и полуприцепов -* машин типа ""дача"", таких как дома-автоприцепы и дома на колесах - -Эта подгруппа также включает: -- оптовую и розничную продажу автомобилей, способных преодолевать труднопроходимые участки (джипы и т. п.) -- оптовую и розничную продажу комиссионными агентами -- продажу автомобилей с аукциона","Эта подгруппа не включает: -- оптовую и розничную продажу деталей и принадлежностей для автомобилей, см. 5030" -2880,"501","Продажа автомобилей",, -2870,"50","Продажа, техническое обслуживание и ремонт автомобилей и мотоциклов; розничная продажа горючего для транспортных средств с двигателями внутреннего сгорания","Этот подраздел включает: -- все виды деятельности (кроме производства и сдачи в аренду) в отношении автомобилей и мотоциклов, включая грузовики и автомобильные тягачи: -* оптовую и розничную продажу новых и подержанных транспортных средств -* техническое обслуживание и ремонт -* оптовую и розничную продажу деталей и принадлежностей -* деятельность комиссионных агентов, связанную с оптовой и розничной продажей транспортных средств -* мойку, полировку и буксировку транспортных средств и т. п. - -Этот подраздел также включает: -- розничную продажу горючего для транспортных средств с двигателями внутреннего сгорания, смазочных масел и охладителей","Этот подраздел не включает: -- аренду автомобилей и мотоциклов без водителя, см. 7111 -- аренду личных машин с водителями, см. 6022 -- аренду грузовиков с водителем, см. 6023" -2860,"G","Оптовая и розничная торговля; ремонт автомобилей, мотоциклов, бытовых товаров и предметов личного пользования","Этот раздел включает оптовую и розничную торговлю (продажу без видоизменения) любых товаров и предоставление услуг, свойственных продаже товаров. Оптовая и розничная торговля являются конечными этапами распределения товаров. В этот раздел также включены ремонт автомобилей, установка и ремонт бытовых товаров и предметов личного пользования. -Считается, что продажа без видоизменения включает обычные операции (или манипуляции), связанные с торговлей, например сортировку, классификацию и сборку товаров, смешивание (компаундирование) товаров (например, вина или песка), разлив в бутылочную тару (с предварительной мойкой бутылок или без нее), упаковывание, разбивку крупных партий товаров и переупаковывание для сбыта партиями меньшего размера, хранение (в замороженном и охлажденном виде или без замораживания и охлаждения), очистку и сушку сельскохозяйственных продуктов, резку древесно-волокнистых плит или металлических листовых материалов за собственный счет. -Оптовая торговля - это перепродажа (продажа без видоизменения) новых или бывших в употреблении товаров розничным торговцам, промышленным, коммерческим, учрежденческим или профессиональным пользователям или же другим оптовым торговцам, а также лицам, исполняющим обязанности агентов или маклеров при покупке товаров от имени таких лиц или компаний или продаже им товаров. Включаются такие основные виды коммерческих предприятий, как оптовые торговые предприятия, то есть оптовики, приобретающие право собственности на товары, которые они продают, как, например, оптовые торговцы или профессиональные биржевики, предприятия оптовой торговли, специализирующиеся на обслуживании промышленности, экспортеры, импортеры, объединения по закупкам на кооперативных началах, отделения по продаже и бюро по продаже (но не магазины розничной торговли), которые содержатся обрабатывающими или горнодобывающими предприятиями, в дополнение к заводам или шахтам и рудникам, для сбыта своей продукции, функции которых не ограничиваются приемом заказов, выполняемых путем прямых отгрузок с заводов или рудников и шахт. Включаются также маклеры, осуществляющие операции с готовой продукцией и сырьем, торговцы, покупающие товары для продажи на комиссионных началах, а также агенты и оптовики-скупщики, заготовители и кооперативные объединения, занимающиеся сбытом сельскохозяйственной продукции. Оптовые торговцы нередко своими силами осуществляют скупку, сортировку и распределение по сортам крупных партий нерассортированных товаров и их разбивку на мелкие партии, переупаковывание, перераспределение в мелкие расфасовки, например фармацевтической продукции; хранение, охлаждение, доставку и установку товаров, занимаются рекламой своих товаров среди клиентов и разработкой этикеток. -Розничная торговля - это перепродажа (продажа без видоизменения) новых и бывших в употреблении товаров широкой публике для личного потребления или домашнего использования, осуществляемая магазинами, универмагами, палатками, фирмами, выполняющими заказы по почте, уличными торговцами или торговцами вразнос, потребительскими кооперативами, фирмами, организующими продажи с аукциона, и т. п. Большинство розничных торговцев приобретают право собственности на товары, которыми они торгуют, однако некоторые из них выступают в качестве агентов от имени владельца и осуществляют продажи или на условиях консигнации, или на комиссионных началах.", -2850,"4550","Аренда оборудования с оператором для строительства или сноса","Эта подгруппа включает: -- аренду кранов, с оператором -- аренду бульдозеров, устройств для распределения (подачи) строительного раствора, машин для отделки поверхностей бетоном и т. п., с оператором","Эта подгруппа не включает: -- аренда машин и оборудования для строительства и сноса, без операторов, см. 7122" -2830,"4540","Завершение строительства","Эта подгруппа включает: -- отделку внутренних стен и фасада зданий и прочих сооружений штукатуркой, включая сопутствующие сеточные материалы -- установку дверей, окон, дверных косяков и оконных рам, готовых кухонь, сооружение лестниц, арматуры и т. п. не собственного производства из дерева или других материалов -- внутреннюю отделку, например потолков, установку деревянных стенных покрытий, раздвижных перегородок и т. п. -- укладку, покрытие, облицовку или поклейку в зданиях и прочих сооружениях: -* керамической, цементной или каменной стенной или напольной плитки, керамической каминной плитки -* паркета и других деревянных напольных покрытий -* напольных ковровых покрытий и линолеума, в том числе из резины и пластических материалов -* напольных или стенных покрытий из тераццио, мрамора, гранита или шиферной плитки -* обоев -- покраску зданий изнутри и снаружи -- покраску объектов гражданского строительства -- установку стекла, зеркал и т. п. -- сооружение частных плавательных бассейнов -- паровую очистку, пескоструйную очистку и аналогичные виды наружной очистки зданий -- очистку новых зданий после строительных работ -- прочие работы по завершению и отделке зданий, не включенные в другие категории","Эта подгруппа не включает: -- установку плотнических или столярных элементов собственного производства, которая классифицирована в соответствующей подгруппе производства готовых изделий в зависимости от использованного материала (например, если из дерева, см. 2022) -- уборку внутренних помещений зданий и прочих сооружений, см. 7493 -- деятельность дизайнеров по декоративному обустройству внутренних помещений, см. 7499" -2820,"454","Завершение строительства",, -2810,"4530","Оборудование зданий","Эта подгруппа включает: -- оборудование зданий и прочих сооружений: -* электропроводкой и арматурой -* проводкой для телесвязи -* электрическими системами отопления, в том числе электрическими коллекторами солнечной энергии, антеннами и антенными мачтами -* системами противопожарной безопасности -* системами охранной сигнализации -* лифтами и эскалаторами -* молниеотводами и т. п. -- установку в зданиях и прочих сооружениях: -* тепло-, звуко- и виброизоляции -* водопроводно-канализационного и сантехнического оборудования -* оборудования для газоснабжения -* обогревательных и вентиляционных устройств, холодильников или кондиционеров воздуха -* неэлектрических коллекторов солнечной энергии -* дождевальных противопожарных систем -- установку систем освещения и сигнализации для шоссейных дорог, железных дорог, аэропортов и гаваней -- установку в зданиях и прочих сооружениях арматуры и креплений, не включенных в другие категории -- общий технический ремонт и эксплуатацию оснащения зданий","Эта подгруппа не включает: -- установку телекоммуникационных систем, см. 3220" -2800,"453","Оборудование зданий",, -2790,"4520","Строительство завершенных сооружений или их частей; гражданское строительство","Эта подгруппа включает: -- строительство любых видов зданий -- возведение объектов гражданского строительства: -* мостов, в том числе дорожных эстакад, виадуков, туннелей и подземных путей -* трубопроводов большой протяженности, линий связи и линий электропередач -* городских трубопроводов, городских линий связи и линий электропередач; вспомогательные городские работы -- строительство: -* водотоков, гаваней и речных сооружений, пристаней для яхт (марин), шлюзов и т. п. -* дамб и плотин -* канализационных систем, включая ремонтные работы -- строительство автомобильных дорог, улиц, дорог, прочих сооружений для движения транспорта и пешеходов -- строительство железных дорог -- строительство взлетных полос аэродромов -- строительство (кроме возводимых на крышах зданий) стадионов, плавательных бассейнов, гимнастических залов, теннисных кортов, полей для гольфа и прочих спортивных сооружений -- сборку и возведение готовых сборных конструкций на участке -- возведение крыш -- кровельные работы -- нанесение дорожного покрытия на автодорожных эстакадах, мостах и в туннелях -- установку заградительных барьеров, дорожных знаков и т. п. -- землечерпательные работы -- подземные работы -- строительные работы, специализирующиеся на одном аспекте, общем для различных строительных объектов, но требующем специальных навыков или оборудования: -* закладка фундамента, в том числе забивка свай -* бурение и сооружение водяных колодцев, проходческие работы -* возведение стальных конструкций несобственного производства -* отгиб арматурных стержней -* кирпичная кладка и каменная кладка -* возведение и демонтаж лесов и строительных платформ, включая аренду строительных лесов и строительных платформ -* строительство дымоходов и промышленных печей -* работы, требующие специального разрешения, навыков высотных работ и использования соответствующего оборудования, например высотные работы на высоких зданиях - -Эта подгруппа также включает: -- землеустроительные работы на строительных участках, где работа ведется за собственный счет","Эта подгруппа не включает: -- строительные работы, связанные с добычей нефти и природного газа, см. 1120 -- сооружение завершенных зданий из готовых блочных конструкций или деталей собственного производства, кроме тех случаев, когда основным материалом является бетон, см. подразделы 20, 26 и 28 -- предварительную выемку земли, см. 4510 -- оборудование зданий, см. 4530 -- завершение строительства зданий, см. 4540 -- деятельность в областях архитектуры и гражданского строительства, см. 7421 -- руководство строительными проектами, см. 7421 -- аренду строительных лесов без возведения и демонтажа, см. 7122" -2780,"452","Строительство завершенных сооружений или их частей; гражданское строительство",, -2770,"4510","Подготовка строительного участка","Эта подгруппа включает: -- разборку или слом зданий и других сооружений -- очистку строительных участков -- земляные работы: экскавацию грунта, засыпку землей, выравнивание и нивелирование строительных участков, рытье траншей, удаление камней, взрывные работы и т. п. -- удаление слоев зараженной почвы как часть строительной деятельности -- подготовку участка к освоению: -* выемку лишнего грунта и прочие работы по освоению и подготовке участков и месторождений, кроме месторождений нефти и газа -- разведочное бурение, разведочное бурение со взятием образцов керна для строительных, геофизических, геологических или иных аналогичных целей - -Эта подгруппа также включает: -- дренаж строительного участка -- дренаж сельскохозяйственных или лесных земель -- разминирование и т. п. (включая подрыв мин) строительных участков","Эта подгруппа не включает: -- бурение нефтяных и газовых скважин, см. 1110 (если такие работы осуществляются за свой счет) или 1120 (если они осуществляются за вознаграждение или на договорной основе) -- бурение водяных скважин, см. 4520 -- проходку шахт, см. 4520 -- исследование и геофизическое, геологическое и сейсмическое обследование месторождений нефти и природного газа, см. 7421 -- обеззараживание почвы, см. 9000" -2760,"451","Подготовка строительного участка",, -2750,"45","Строительство","Этот подраздел охватывает общие и специальные работы по строительству зданий и гражданских объектов, монтажные работы и завершение строительства. Он включает новое строительство, ремонтные работы, дополнения и изменения, возведение зданий из готовых блочных конструкций на строительном участке, а также строений временного характера. -Общие строительные работы включают строительство завершенных жилых домов, учрежденческих зданий, магазинов и других коммунально-бытовых зданий, сельскохозяйственных построек и т. п. и строительство тяжелых конструкций, таких как автострады, улицы, мосты, туннели, железные дороги, аэродромы, гавани и другие водные объекты, оросительные системы, системы канализации, промышленные сооружения, трубопроводы и линии электропередач, спортивные сооружения и т. п. Такие работы осуществляются за собственный счет или за вознаграждение либо на договорной основе. Доля этой работы, а иногда и весь объем практических работ могут передаваться субподрядчикам этой отрасли. -Специальные строительные работы включают строительство частей зданий и гражданских объектов или их подготовку. Обычно они специализируются на одном аспекте, общем для различных строительных объектов, но требующем специальных навыков или оборудования. Сюда относится такая деятельность, как забивка свай, закладка фундамента, бурение водяных скважин, каркасные работы, бетонные работы, кирпичная кладка, каменная кладка, возведение лесов, кровельные работы и т. п. Возведение стальных конструкций включается в том случае, если их детали не производятся на том же предприятии. Специальные строительные работы выполняются преимущественно по субподряду, однако в некоторых случаях, особенно при строительных работах, связанных с ремонтом, они выполняются непосредственно для владельца собственности. -Монтажные работы включают установку всех видов коммунального оборудования, благодаря которому сооружение функционирует как таковое. Эти работы обычно осуществляются на строительном участке, хотя некоторые их виды могут выполняться в специальных мастерских. Сюда включается такая деятельность, как слесарно-водопроводные работы, установка систем отопления и кондиционирования воздуха, антенн, систем охранной сигнализации и прочие виды электромонтажных работ, установка дождевальных противопожарных систем, лифтов, эскалаторов и т. п. Включены также работы по водо-, тепло- и звукоизоляции, обшивка листовым металлом, установка коммерческих рефрижераторных систем, проводка систем освещения и сигнализации для шоссейных дорог, железных дорог, аэропортов, гаваней и т. п. Кроме того, включены ремонтные работы того же типа, что и описанные выше монтажные работы. -Завершение строительства охватывает деятельность, способствующую завершению строительства или отделке строения, такую как остекление, штукатурные работы, малярно-декоративные работы, облицовка стен кафелем и покрытие полов плиткой или другими материалами, такими как паркет, ковры, обои и т. п., циклевка полов, настил ковровых покрытий, звукоизоляционные работы, очистка наружных стен здания и т. п. Помимо этого включены ремонтные работы того же типа, что и описанные выше виды деятельности.","Этот подраздел не включает: -- производство строительных материалов, см. разделы С и D -- возведение или монтаж промышленного оборудования, см. раздел D (например, монтаж промышленных печей, турбин и т. п.) -- возведение полносборных зданий и сооружений из частей, изготовленных своими силами, которое классифицируется в соответствующей категории производства готовой продукции в зависимости от основного используемого материала, за исключением случаев, когда основным материалом является бетон; в таком случае эта деятельность классифицируется в данном подразделе -- возведение металлических структур из сборных частей, изготовленных своими силами, см. 2811 -- укладку ковровых покрытий и установку плотнических или столярных изделий собственного производства, которая классифицируется в соответствующей категории производства готовой продукции в зависимости от используемого материала (например, если из дерева, см. 2022) -- деятельность в областях архитектуры и гражданского строительства, см. 7421 -- руководство строительными проектами, см. 7421 -- пейзажное планирование и дизайн, разбивка газонов и садов, а также уход за ними и подрезка деревьев, см. 0140 -- строительные работы, непосредственно связанные с добычей нефти и природного газа, см. 1120 (Однако строительство зданий, дорог и т. п. на местах добычи классифицируется в настоящей подгруппе.) -- мытье окон снаружи и внутри зданий, чистка дымоходов, котлов, интерьера и т. п., см. 7493" -2740,"F","Строительство",, -2730,"4100","Сбор, очистка и распределение воды","Эта подгруппа включает также: -- очистку воды для целей водоснабжения -- опреснение морской воды для получения пресной воды в качестве основного целевого продукта","Эта подгруппа не включает: -- эксплуатацию систем орошения для сельскохозяйственных целей, см. 0140 -- транспортировку воды (на большие расстояния) по трубопроводам, см. 6030 -- обработку сточных вод в целях предотвращения загрязнения, см. 9000" -2720,"410","Сбор, очистка и распределение воды",, -2710,"41","Сбор, очистка и распределение воды",, -2700,"4030","Снабжение паром и горячей водой","Эта подгруппа включает: -- производство, сбор и распределение пара и горячей воды для отопления, производства энергии и для других целей - -Эта подгруппа также включает: -- производство и распределение охлажденной воды или льда для целей охлаждения", -2690,"403","Снабжение паром и горячей водой",, -2680,"4020","Производство газа; распределение газообразного топлива по трубопроводам","Эта подгруппа включает: -- производство газа для целей газоснабжения путем коксования угля, из побочных продуктов сельского хозяйства или отходов -- производство газообразного топлива с указанными тепловыми показателями путем очистки, смешивания и других процессов из газов различных видов, в том числе природного газа -- транспортировку, распределение и поставку любых видов газообразного топлива через систему магистральных газопроводов -- продажу газа потребителям через систему магистральных газопроводов -- деятельность энергетических посредников или агентов, которые организуют реализацию электроэнергии через распределительные системы, находящиеся под управлением других лиц","Эта подгруппа не включает: -- эксплуатацию коксовых печей, см. 2310 -- производство продуктов нефтеперегонки, см. 2320 -- производство промышленных газов, см. 2411 -- продажу газообразного топлива крупными партиями или в баллонах (см. 5110, 5141 и 5239, а также группу 525) -- транспортировку газообразного топлива по трубопроводам (кроме магистральных трубопроводов), см. 6030" -2670,"402","Производство газа; распределение газообразного топлива по трубопроводам",, -2660,"4010","Производство, передача и распределение электроэнергии","Эта подгруппа включает: -- управление энергетическими предприятиями, которые производят электроэнергию, в том числе тепловыми, ядерными, гидроэлектрическими, газотурбинными, дизельными и использующими возобновляемые источники энергии -- управление системами передачи, которые доставляют электроэнергию с энергетического предприятия в распределительную систему -- управление распределительными системами (состоящими из линий, столбов, счетчиков, проводки), которые доставляют электроэнергию, полученную от электростанций или от линий электропередач, конечным потребителям -- продажу электроэнергии потребителю -- деятельность энергетических посредников или агентов, которые организуют реализацию электроэнергии через распределительные системы, находящиеся под управлением других лиц", -2650,"401","Производство, передача и распределение электроэнергии",, -2640,"40","Снабжение электроэнергией, газом, паром и горячей водой",, -2630,"E","Электроэнергия, газ и водоснабжение","Этот раздел охватывает деятельность по снабжению электроэнергией, природным газом, паром и водой, осуществляемую с помощью постоянной инфраструктуры (сетей), состоящей из линий, магистралей и трубопроводов. Параметры такой сети не играют решающей роли; данный раздел также охватывает энерго-, газо-, паро- и водоснабжение промышленных предприятий и жилых массивов. -Производство, управление инфраструктурой и поставку продукции конечному потребителю может осуществлять одно и то же предприятие или разные предприятия. Предприятия, занимающиеся поставками электроэнергии и/или природного газа и/или пара и горячей и/или холодной воды, должны классифицироваться по их главному виду деятельности.", -2620,"3720","Вторичная переработка неметаллических отходов и лома","Эта подгруппа включает: -- переработку неметаллических отходов и лома и неметаллических изделий во вторичный сырьевой материал. Примерами механических или химических процессов переработки являются: -* утилизация резины, такой как использованные автомобильные покрышки, для получения вторичного сырьевого материала -* сортировка и гранулирование изделий из пластмассы, пригодных для получения вторичного сырьевого материала для производства труб, цветочных горшков, плит и т. п. -* переработка (очистка, плавка, дробление) пластмассовых или резиновых отходов в гранулы -* извлечение химикатов из химических отходов -* дробление, очистка и сортировка стекла -* дробление, очистка и сортировка прочих отходов, таких как ликвидационные отходы, для получения вторичного сырьевого материала -* механическое измельчение и дробление отходов от строительства и разрушения зданий (в том числе деревянных), асфальта -* переработка использованных пищевых масел и жиров во вторичный сырьевой материал для производства корма для домашних или сельскохозяйственных животных -* переработка прочих отходов пищевых продуктов, напитков и табачных изделий и остаточных веществ во вторичный сырьевой материал -* извлечение металлов из отходов фотографии, например закрепителя или фотопленок и фотобумаги","Эта подгруппа не включает: -- производство новых конечных продуктов, выработанных из (произведенного своими силами или не своими силами) вторичного сырьевого материала, например прядение пряжи из разработанного лоскута, или получение бумажной массы из макулатуры, или восстановление автомобильных покрышек. Такая деятельность должна классифицироваться в соответствующих подгруппах, касающихся производства готовых изделий, см. подразделы 14-36 -- переработку пищевых отходов для производства пищевых продуктов, см. подраздел 15 -- переработку отходов мясокомбинатов для производства кормов для животных, см. 1533 -- переработку ядерного топлива и обработку ядерных отходов, см. 2330 -- изготовление компоста из органических отходов, см. 2412 -- оптовую торговлю неметаллическими отходами и ломом, включая сбор, сортировку, упаковку, распределение и т. п. без промышленной переработки, см. 5149 -- оптовую и розничную торговлю товарами, бывшими в употреблении, см. подразделы 50 и 51, а также подгруппу 5240 -- сжигание, сброс, захоронение и т. п. отходов, см. 9000 -- переработку и удаление вывозимых радиоактивных отходов из больниц и других учреждений, см. 9000 -- переработку и удаление токсичных, зараженных отходов, см. 9000 -- удаление отходов пищевых продуктов, напитков и табачных изделий, см. 9000" -2610,"372","Вторичная переработка неметаллических отходов и лома",, -2600,"3710","Вторичная переработка металлических отходов и лома","Эта подгруппа включает: -- переработку металлических отходов и лома и металлических изделий во вторичный сырьевой материал. Примерами механических или химических процессов переработки являются: -* механическое дробление металлических отходов, таких как старые автомобили, стиральные машины, велосипеды и т. п. с последующей сортировкой и отделением -* механическое уменьшение размера крупногабаритных изделий из железа, таких как железнодорожные вагоны -* измельчение металлических отходов, старых автомобилей и т. п. -* прочие методы механической переработки, в том числе резание, прессование для уменьшения объема и т. п. -- разборка судов на металл","Эта подгруппа не включает: -- производство новых готовых металлов или новых готовых металлоизделий из (произведенного своими силами или не своими силами) вторичного сырьевого материала, см. подразделы 27 и 28 -- разборку автомобилей, демонтаж механизмов и компьютеров для снятия деталей, пригодных к повторному использованию, включая торговлю подержанными запасными частями, см. подразделы 50, 51 и 52 -- переработку бывших в употреблении товаров, таких как холодильники, в целях ликвидации вредных отходов, см. 9000" -2590,"371","Вторичная переработка металлических отходов и лома",, -2580,"37","Вторичная переработка","Этот подраздел включает: -- переработку металлических отходов и лома и металлических изделий, использованных или не использованных, в новый сырьевой материал. Требуется или механический или химический процесс переработки. Как правило, если речь идет о сырье, то и вводимое сырье и получаемое состоит из отходов и лома, причем вводимое сырье сортируется или не сортируется, но всегда бывает непригодным для дальнейшего непосредственного использования в промышленных процессах, тогда как получаемое сырье становится пригодным для непосредственного использования в процессе промышленного производства. Таким образом, получаемый вторичный сырьевой материал следует считать промежуточным продуктом, имеющим стоимость, но не конечным новым продуктом.","Этот подраздел не включает: -- производство новых конечных продуктов, выработанных из (произведенного своими силами или не своими силами) вторичного сырья, см. подразделы 14-36 -- оптовую продажу отходов и лома, включая сбор, сортировку, распределение или демонтаж изделий, бывших в употреблении (таких, как автомобили), для снятия деталей, пригодных к повторному использованию, а также (пере-)упаковку, хранение и доставку, но без реальной промышленной переработки, см. подразделы 50, 51 и 52 -- оптовую и розничную торговлю товарами, бывшими в употреблении, см. подразделы 50, 51, а также подгруппу 5240 -- переработку отходов не для их дальнейшего использования в процессе промышленного производства, а в целях их удаления, см. 9000" -2570,"3699","Производство прочих готовых изделий, не включенных в другие категории","Эта подгруппа включает: -- производство метел и щеток (в том числе щеток, составляющих элементы машин), ручных механических щеток для пола, швабр и метелок из перьев, малярных кистей, малярных валиков и накаток, резиновых и прочих щеток, метел, швабр и т. п. -- производство щеток для обуви и одежды -- производство всевозможных карандашей и ручек, механических и немеханических -- производство карандашных грифелей -- производство штемпелей для датирования, запечатывания или нумерации, ручных устройств для печатания или рельефного тиснения этикеток, наборочных верстаков для работы вручную, готовых лент для пишущих машинок и штемпельных подушек -- производство детских колясок -- производство дождевых и солнцезащитных зонтов, тростей, тростей-стульев, хлыстов, кнутов для верховой езды, пуговиц, различных кнопок для одежды, запонок, застежек-молний -- производство зажигалок и спичек -- производство предметов личного пользования: курительных трубок, расчесок, заколок для волос и аналогичных изделий, духов в аэрозольной упаковке, термосов и прочих вакуумных сосудов для личного и домашнего обихода, париков, накладных бород, бровей -- производство каруселей, качелей, тиров и других ярмарочных аттракционов -- производство линолеума и прочих твердых непластмассовых покрытий для полов -- производство имитации ювелирных украшений -- производство прочих изделий: свечей, фитилей и т. п., искусственных цветов, плодов и листвы, игрушек-шуток и игрушек-сюрпризов, ручных сит и решет, портновских манекенов, гробов и т. п. -- набивку чучел","Эта подгруппа не включает: -- производство фитилей для светильников, см. 1729" -2560,"3694","Производство игр и игрушек","Эта подгруппа включает производство игр и игрушек из любого материала: -- производство кукол, а также одежды и аксессуаров для кукол -- производство игрушечных животных -- производство игрушек на колесах, предназначенных для езды, включая трехколесные велосипеды -- производство игрушечных музыкальных инструментов -- производство изделий для карнавала, настольных или салонных игр -- производство игральных карт -- производство вращающихся столов, монетных игровых автоматов, бильярдов, специальных столов для азартных игр и автоматического оборудования для кегельбанов -- производство электронных игр: видеоигр, шахмат и т. п. -- производство уменьшенных (""масштабных"") моделей и аналогичных игровых моделей, электрических железных дорог, конструкторов и т. п. -- производство головоломок и т. п.","Эта подгруппа не включает: -- производство детских двухколесных велосипедов, см. 3592 -- производство изделий для праздников, карнавалов и прочих развлекательных мероприятий, см. 3699 -- составление и издание программного обеспечения для видеоигр, см. 7221, 7229" -2550,"3693","Производство спортивных товаров","Эта подгруппа включает: -- производство изделий и инвентаря из любых материалов для занятий спортом, спортивных игр на воздухе и в помещении: -* жестких, мягких и надувных мячей -* ракет, бит и клюшек -* виндсерферов -* лыж, креплений и палок -* инвентаря для спортивного рыболовства, в том числе рыболовных сачков -* инвентаря для охоты, альпинизма и других видов спорта -* кожаных спортивных перчаток и спортивных шлемов -* коньков, роликовых коньков и т. п. -* луков и арбалетов -* оборудование для гимнастических залов, фитнесс-центров или атлетических клубов","Эта подгруппа не включает: -- производство лодочных парусов, см. 1721 -- производство спортивной одежды, см. 1810 -- производство шорно-седельных изделий, см. 1912 -- производство спортивной обуви, см. 1920 -- производство спортивного оружия и снаряжения, см. 2927 -- производство спортивных транспортных средств, кроме саней и т. п., см. подразделы 34 и 35 -- производство лодок, см. 3512 -- производство бильярдных столов и оборудования для игры в кегли, см. 3694 -- производство хлыстов и кнутов для верховой езды, см. 3699" -2540,"3692","Производство музыкальных инструментов","Эта подгруппа включает: -- производство струнных музыкальных инструментов -- производство клавишных струнных музыкальных инструментов, в том числе автоматических фортепьяно -- производство клавишных органов, в том числе фисгармоний и аналогичных клавишных музыкальных инструментов со свободными металлическими язычками -- производство аккордеонов и аналогичных музыкальных инструментов, в том числе губных гармоник -- производство духовых музыкальных инструментов -- производство ударных музыкальных инструментов -- производство музыкальных инструментов с электронным звучанием -- производство музыкальных шкатулок, ярмарочных шарманок, каллиоп и т. п. -- производство деталей и принадлежностей инструментов: -* метрономов, камертонов, камертонов-дудок, ступ, дисков и валиков для автоматических механических инструментов и т. п. - -Эта подгруппа также включает: -- производство свистков, боцманских дудок и прочих свистковых сигнальных инструментов -- реставрацию органов и прочих исторических музыкальных инструментов","Эта подгруппа не включает: -- издание и воспроизведение записанных аудио- и видеокассет и дисков, см. группы 221 и 223, а также подгруппу 9211 -- производство микрофонов, усилителей, громкоговорителей, наушников и аналогичных компонентов, см. 3230 -- производство проигрывателей, магнитофонов и т. п., см. 3230 -- производство игрушечных инструментов, см. 3694 -- настройку роялей, см. 5260" -2530,"3691","Производство ювелирных изделий и смежных товаров","Эта подгруппа включает: -- производство монет, в том числе монет, используемых в качестве законного платежного средства, из благородных или неблагородных металлов -- производство обработанного жемчуга -- производство драгоценных и полудрагоценных камней в обработанном состоянии. Включается обработка камней промышленного назначения и синтетических или восстановленных драгоценных и полудрагоценных камней -- огранку алмазов -- производство ювелирных изделий из благородных металлов или из неблагородных металлов с покрытием из благородных металлов, драгоценных или полудрагоценных камней или из сочетания благородного металла с драгоценными или полудрагоценными камнями или с другими материалами -- производство ювелирных изделий из благородных металлов или из неблагородных металлов с покрытием из благородных металлов: -* столовых приборов, мелкой и глубокой посуды, туалетных принадлежностей, канцелярских или настольных предметов, изделий религиозно-культурного назначения и т. п. -- производство технических или лабораторных изделий из благородных металлов (кроме инструментов или деталей инструментов): тиглей, шпателей, электрогальванических анодов и т. п.","Эта подгруппа не включает: -- производство изделий из неблагородных металлов, плакированных драгоценным металлом, см. подраздел 28 -- производство корпусов и браслетов для наручных часов, см. 3330 -- производство имитации ювелирных украшений, см. 3699" -2520,"369","Производство готовых изделий, не включенных в другие категории",, -2510,"3610","Производство мебели","Эта подгруппа включает производство мебели всех видов из любого материала (кроме камня, бетона и керамики) для любых мест и для различных целей. - -Эта подгруппа включает: -- производство стульев и кресел для служебных помещений, рабочих кабинетов, гостиниц, ресторанов, общественных мест и жилых помещений -- производство стульев и кресел для театров, кинотеатров и т. п. -- производство стульев и кресел для средств транспорта -- производство кроватей, диван-кроватей и мягких кресел -- производство садовых стульев и кресел -- производство специальной мебели для магазинов: прилавков, витрин, полок и т. п. -- производство канцелярской мебели -- производство мебели для церквей, школ, ресторанов -- производство кухонной мебели -- производство мебели для спален, гостиных, садовых участков и т. п. -- производство подставок для швейных машин, телевизоров и т. п. - -Эта подгруппа также включает: -- реставрацию мебели -- отделочные работы, такие как обивка диванов, стульев и кресел -- отделку мебели, например пульверизацию, покраску, покрытие лаком и обивку -- производство каркасов для матрацев -- производство матрацев: -* пружинных или набивных матрацев, а также матрацев с внутренней опорой из вспомогательного материала -* безобтяжных матрацев из пористой резины или пластмасс","Эта подгруппа не включает: -- производство подушек, валиков, диванных подушек, стеганых одеял и стеганых пуховых одеял, см. 1721 -- производство надувных резиновых матрацев, см. 2519 -- производство мебели из керамики, бетона и камня, см. 2691, 2695 и 2696 -- производство осветительной арматуры или ламп, см. 3150 -- производство медицинской, хирургической, стоматологической или ветеринарной мебели, см. 3311" -2500,"361","Производство мебели",, -2490,"36","Производство мебели; производство готовых изделий, не включенных в другие категории","Следует отметить, что в подраздел 36 по остаточному принципу были включены виды деятельности, не отнесенные к другим подразделам. Обычные критерии для сведения подгрупп в категории в данном случае не использовались. -Ремонт изделий, включенный в подраздел 36, в целом относится к группе 526 (Ремонт бытовых товаров и предметов личного пользования), кроме ремонта канцелярской мебели, музыкальных инструментов, профессионального спортивного оборудования, оборудования автоматических кегельбанов и т. п.", -2480,"3599","Производство прочего транспортного оборудования, не включенного в другие категории","Эта подгруппа включает: -- производство тачек, вагонеток, ручных тележек, салазок и т. п. -- производство транспортных средств на животной тяге", -2470,"3592","Производство велосипедов и инвалидных колясок","Эта подгруппа включает: -- производство безмоторных велосипедов и прочих велосипедов, в том числе трехколесных грузовых велосипедов, тандемных велосипедов и детских велосипедов -- производство деталей и принадлежностей велосипедов -- производство инвалидных колясок, моторизованных или безмоторных -- производство деталей и принадлежностей инвалидных колясок","Эта подгруппа не включает: -- производство двухколесных велосипедов с вспомогательным мотором, см. 3591 -- производство детских велосипедов (кроме двухколесных велосипедов), см. 3694" -2460,"3591","Производство мотоциклов","Эта подгруппа включает: -- производство мотоциклов, мопедов и велосипедов, оборудованных вспомогательным мотором -- производство двигателей для мотоциклов -- производство колясок -- производство деталей и принадлежностей мотоциклов","Эта подгруппа не включает: -- производство велосипедов, см. 3592 -- производство моторизованных инвалидных колясок, см. 3592" -2450,"359","Производство транспортного оборудования, не включенного в другие категории",, -2440,"3530","Производство летательных аппаратов и космических летательных аппаратов","Эта подгруппа включает: -- производство самолетов для перевозки грузов и пассажиров, для использования силами обороны, для спортивных и других целей -- производство вертолетов -- производство планеров, буксируемых планеров -- производство дирижаблей и аэростатов -- производство космических летательных аппаратов и ракет-носителей для космических летательных аппаратов, спутников, космических зондов, орбитальных станций, космических кораблей многоразового использования -- производство деталей и принадлежностей для летательных аппаратов этой подгруппы: -* основных узлов, таких как фюзеляжи, крылья, двери, рулевые плоскости, посадочные шасси, топливные баки, гондолы и т. п. -* пропеллеров, вертолетных несущих винтов и пропеллерных лопастей несущих винтов -* моторов и двигателей, обычно устанавливаемых на летательных аппаратах -* деталей турбореактивных и турбовинтовых двигателей для летательных аппаратов -- производство пусковых механизмов для летательных аппаратов, аэрофинимеров и т. п. -- производство наземных тренажеров - -Эта подгруппа также включает: -- обслуживание, ремонт и модификацию летательных аппаратов или их двигателей","Эта подгруппа не включает: -- производство парашютов, см. 1721 -- производство военных баллистических ракет, см. 2927 -- производство деталей зажигания и прочих электрических деталей двигателей внутреннего сгорания, см. 3190 -- производство навигационных и других приборов, используемых на летательных аппаратах, см. 3312 -- производство аэронавигационных систем, см. 3312" -2430,"353","Производство летательных аппаратов и космических летательных аппаратов",, -2420,"3520","Производство железнодорожных и трамвайных локомотивов и подвижного состава","Эта подгруппа включает: -- производство электролокомотивов, дизельных локомотивов, локомотивов с паровым двигателем и прочих рельсовых локомотивов -- производство самоходных железнодорожных или трамвайных пассажирских вагонов, товарных вагонов и грузовых платформ, ремонтно-эксплуатационных транспортных средств -- производство несамоходного железнодорожного или трамвайного подвижного состава: -* пассажирских вагонов, товарных вагонов, железнодорожных цистерн, саморазгружающихся товарных вагонов и платформ, вагонов-мастерских, вагонов-кранов, тендеров и т. п. -- производство специальных деталей железнодорожных и трамвайных локомотивов и подвижного состава: -* вагонеток, осей и колес; тормозов и деталей тормозов; крюков и зажимных устройств, буферов и деталей буферов; амортизаторов; вагонных и локомотивных рам; корпусов; тамбурных связок и т. п. - -Эта подгруппа также включает: -- производство механического и электромеханического сигнального оборудования, оборудования для обеспечения безопасности движения или управления движением на железных дорогах, трамвайных путях, шоссейных дорогах, внутренних водных путях, автомобильных стоянках, в портовых сооружениях или на аэродромах","Эта подгруппа не включает: -- производство несобранных путей, см. 2710 -- производство двигателей и турбин, см. 2911 -- производство электромоторов, см. 3110 -- производство электрического сигнального оборудования, оборудования для обеспечения движения или управления движением, см. 3190" -2410,"352","Производство железнодорожных и трамвайных локомотивов и подвижного состава",, -2400,"3512","Строительство и ремонт прогулочных и спортивных лодок","Эта подгруппа включает: -- производство надувных лодок и плотов -- строительство парусных судов с подвесным мотором или без него -- строительство моторных лодок -- строительство прогулочных судов на воздушной подушке -- строительство прочих прогулочных и спортивных лодок: -* каноэ, байдарок, весельных лодок, яликов -- техническое обслуживание, ремонт или модификацию прогулочных лодок","Эта подгруппа не включает: -- производство деталей прогулочных и спортивных лодок: -* производство парусов, см. 1721 -* производство чугунных и стальных якорей, см. 2899 -* производство судовых двигателей, см. 2911 -- производство виндсёрферов, см. 3693" -2390,"3511","Строительство и ремонт судов","Эта подгруппа включает строительство и ремонт судов, кроме спортивных или прогулочных, и строительство и ремонт плавучих сооружений. - -Эта подгруппа включает: -- строительство судов гражданского назначения: пассажирских судов, паромов, грузовых судов, танкеров, буксиров и т. п. -- строительство военных кораблей -- строительство рыболовных траулеров и рыбоперерабатывающих плавбаз - -Эта подгруппа также включает: -- строительство судов на воздушной подушке (кроме прогулочных судов на воздушной подушке) -- строительство плавучих или погружаемых буровых платформ -- строительство плавучих конструкций: -* плавучих доков, понтонов, коффердамов, плавучих пристаней, буев, плавучих цистерн, барж, маяков, плавучих кранов, непрогулочных надувных плотов и т. п. -- строительство секций судов и плавучих сооружений","Эта подгруппа не включает: -- производство деталей судов, кроме основных корпусных конструкций: -* производство парусов, см. 1721 -* производство винтов для судов, см. 2899 -* производство чугунных или стальных якорей, см. 2899 -* производство двигателей для морских судов, см. 2911 -- производство навигационных приборов, см. 3312 -- производство автомобилей-амфибий, см. 3410 -- производство прогулочных надувных лодок и плотов, см. 3512 -- разборку судов, см. 3710" -2380,"351","Строительство и ремонт судов и лодок",, -2370,"35","Производство прочего транспортного оборудования",, -2360,"3430","Производство деталей и принадлежностей для автомобилей и их двигателей","Эта подгруппа включает: -- производство различных деталей и принадлежностей для автомобилей: -* тормозов, коробок передач, осей, ходовых колес, амортизаторов подвески, радиаторов, глушителей, выхлопных труб, катализаторов, сцеплений, рулевых колес, рулевых колонок и рулевых коробок -- производство деталей и принадлежностей для корпусов автомобилей: -* ремней безопасности, воздушных подушек, дверей, бамперов - -Эта подгруппа также включает: -- производство впускных и выпускных клапанов двигателей внутреннего сгорания","Эта подгруппа не включает: -- производство насосов для автомобилей и автомобильных двигателей, см. 2912 -- производство аккумуляторов для автомобилей, см. 3140 -- производство электрооборудования для автомобилей, см. 3190 -- техническое обслуживание, ремонт и модификацию автомобилей, см. 5020" -2350,"343","Производство деталей и принадлежностей для автомобилей и их двигателей",, -2340,"3420","Производство корпусов (кузовные работы) для автомобилей; производство прицепов и полуприцепов","Эта подгруппа включает: -- производство корпусов, в том числе кабин для водителя -- производство различных деталей для корпусов автомобилей, прицепов и полуприцепов -- производство прицепов и полуприцепов: -* для перевозки грузов: автоцистерн, лесовозов и т. п. -* для перевозки пассажиров: домов-автоприцепов и т. п. -- производство контейнеров для перевозки одним или несколькими видами транспорта","Эта подгруппа не включает: -- производство прицепов и полуприцепов, специально сконструированных для использования в сельском хозяйстве, см. 2921 -- производство деталей и принадлежностей для корпусов автомобилей, см. 3430 -- производство транспортных средств на животной тяге, см. 3599" -2330,"342","Производство корпусов (кузовные работы) для автомобилей; производство прицепов и полуприцепов",, -2320,"3410","Производство автомобилей","Эта подгруппа включает: -- производство пассажирских автомобилей -- производство автомобилей для перевозки грузов: -* автофургонов, грузовиков, дорожных тягачей для полуприцепов и т. п. -- производство автобусов, троллейбусов, междугородных автобусов -- производство автомобильных двигателей -- производство оснащенных двигателями шасси для автомобилей -- производство прочих автомобилей: -* снегоходов, гольфкартов, амфибий -* пожарных машин, подметальных машин, передвижных библиотек, бронированных машин и т. п. -* грузовиков-бетономешалок","Эта подгруппа не включает: -- производство тракторов для использования в сельском хозяйстве, см. 2921 -- производство тракторов для использования в строительстве или горнодобывающей промышленности, см. 2924 -- производство электрических компонентов для автомобилей, см. 3190 -- производство кузовов для автомобилей, см. 3420 -- производство деталей и принадлежностей для автомобилей, см. 3430 -- техническое обслуживание, ремонт и модификацию автомобилей, см. 5020" -2310,"341","Производство автомобилей",, -2300,"34","Производство автомобилей, прицепов и полуприцепов","Этот подраздел охватывает производство автомобилей для перевозки людей или грузов. Кроме того, в этот подраздел включено производство различных деталей и принадлежностей, а также производство прицепов и полуприцепов. - -Техническое обслуживание и ремонт автомобилей, относящихся к данному подразделу, классифицируются в подгруппе 5020.", -2290,"3330","Производство наручных и прочих часов","Эта подгруппа включает: -- производство наручных и прочих часов всех видов, в том числе часов, устанавливаемых на панелях приборов; корпусов для наручных и прочих часов, в том числе корпусов из благородных металлов -- производство приборов для регистрации времени суток и приборов для отсчета, регистрации или иного указания промежутков времени с часовым механизмом или синхронизатором, например парковочных счетчиков, таймеров различных процессов -- производство выключателей или других размыкающих устройств с часовым механизмом или синхронным движителем -- производство деталей наручных и прочих часов: -* различных механизмов наручных и прочих часов -* пружин, камней, циферблатов, стрелок, плат, мостов и других деталей -- производство металлических браслетов для наручных часов, в том числе из благородных металлов","Эта подгруппа не включает: -- производство неметаллических ремешков для наручных часов, см. 1912" -2280,"333","Производство наручных и прочих часов",, -2270,"3320","Производство оптических инструментов и фотооборудования","Эта подгруппа включает: -- производство смонтированных или несмонтированных оптических элементов: -* призм, линз, оптических зеркал, цветофильтров, поляризующих элементов и т. п. из стекла или другого материала -* оптического волокна и кабелей из оптического волокна для прямой передачи изображений: эндоскопия, освещение, передача ""живых"" изображений -* очковых линз и контактных линз -* оправ для очков и оправ для очков с линзами, прошедшими или не прошедшими оптическую обработку: солнцезащитных очков, защитных очков, корректирующих очков и т. п. -* не прошедших обработку оптических элементов из материала, отличного от стекла -- производство оптических приборов: -* оптических микроскопов, оборудования для микрофотосъемки и микропроецирования, увеличительных стекол, луп, счетчиков нитей и т. п. -* биноклей, оптических телескопов, телескопических прицелов, телескопов для наблюдений, астрономических приборов и т. п. -* лазеров, кроме лазерных диодов, и т. п. -* смонтированных, прошедших оптическую обработку стеклянных зеркал, дверных глазков и т. п. -- производство фотооборудования и киноаппаратуры: -* камер всех видов -* диапроекторов, увеличителей и уменьшителей -* кинопроекторов, в том числе кинопроекторов, снабженных звуковоспроизводящими устройствами -* фотовспышек -* приборов и оборудования для фотолабораторий и кинолабораторий, приборов для проецирования контуров схем на светочувствительные полупроводниковые материалы, проекционных экранов","Эта подгруппа не включает: -- производство фотохимических продуктов, см. 2429 -- производство необработанных стеклянных оптических элементов, см. 2610 -- производство фотокопировальных приборов, см. 3000 -- производство кабелей из оптического волокна для передачи кодированных данных, см. 3130 -- производство ламп-вспышек, используемых в фотографии, см. 3150 -- производство телевизионных камер, см. 3220 -- производство видеокамер, см. 3230 -- производство медицинских и хирургических инструментов, содержащих оптические элементы (например, эндоскопов), см. 3311 -- производство микроскопов, кроме оптических, см. 3312 -- производство инструментов для измерения и проверки, содержащих оптические элементы, см. 3312" -2260,"332","Производство оптических инструментов и фотооборудования",, -2250,"3313","Производство контрольного оборудования для промышленных процессов","Эта подгруппа включает: -- производство инструментов и приборов, используемых для непрерывного автоматического измерения и контроля таких переменных, как температура, давление, вязкость и т. п., материалов или изделий в процессе их производства или какой-либо иной обработки.", -2240,"3312","Производство инструментов и приборов для измерения, проверки, испытания, навигации и других целей, кроме контрольного оборудования для промышленных процессов","Эта подгруппа включает: -- производство высокоточных весов лабораторного типа -- производство чертежных, разметочных или математических счетных инструментов: -* измерительных стержней и лент, микрометров, кронциркулей, манометров и т. п. -- производство микроскопов, кроме оптических микроскопов и дифракционных аппаратов -- производство приборов для измерения или проверки электрических параметров: -* осциллоскопов, спектроанализаторов, измерителей перекрестных помех, инструментов для проверки силы тока, напряжения, сопротивления и т. п. -- производство приборов для измерения или проверки неэлектрических параметров: -* индикаторов и счетчиков уровня радиации, приборов для проверки и регулирования автомобильных двигателей и т. п. -- производство навигационных, метеорологических, геофизических и связанных с ними инструментов и приборов: -* геодезических инструментов, океанографических или гидрологических инструментов, сейсмографов, дальномеров, автопилотов, секстантов, приборов для ультразвукового зондирования и т. п. -* аэронавигационных приборов и систем, радарных установок и радионавигационных приборов -- производство счетчиков потребляемой электроэнергии, счетчиков потребляемой воды, газа, бензина и т. п. -- производство машин и приборов для испытания механических свойств материалов -- производство инструментов и аппаратуры для проведения физического или химического анализа: -* поляриметров, фотометров, рефрактометров, колориметров, спектрометров, измерителей концентрации водородных ионов, вискозиметров, измерителей поверхностного натяжения и т. п. -- производство инструментов и приборов для измерения или проверки расхода, уровня, давления и других переменных параметров жидкостей или газов: -* расходомеров, уровнемеров, манометров, измерителей степени нагрева и т. п. -- производство других инструментов, приборов или машин для измерения, проверки или испытания: -* ареометров, термометров, барометров, счетчиков числа оборотов, таксометров, шагомеров, тахометров, балансировочных машин, испытательных стендов, компараторов и т. п. -- производство инструментов и приборов для автоматического регулирования или контроля (кроме контрольного оборудования для промышленных процессов): -* термостатов, датчиков давления, регуляторов влажности -* регуляторов электрических параметров","Эта подгруппа не включает: -- производство насосов со встроенными измерительными устройствами, см. 2912 -- производство медицинских и хирургических инструментов, см. 3311 -- производство контрольного оборудования для промышленных процессов, см. 3313 -- производство биноклей, монокуляров и аналогичных оптических устройств, см. 3320 -- производство оптических микроскопов, см. 3320" -2230,"3311","Производство медицинского и хирургического оборудования и ортопедических приспособлений","Эта подгруппа включает: -- производство инструментов и приборов, используемых в медицине, хирургии, стоматологии или ветеринарии: -* электродиагностической аппаратуры, такой как электрокардиографы, ультразвуковое диагностическое оборудование, сцинтилляционные сканнеры, приборы на основе ядерного магнитного резонанса, стоматологические буры, стерилизаторы, офтальмологические приборы -- производство шприцев, игл для медицинских нужд -- производство зеркал и рефлекторов, эндоскопов и т. п. -- производство аппаратуры, основывающейся на применении рентгеновских лучей или альфа-, бета- или гамма-излучателей, предназначенной или не предназначенной для использования в медицине или ветеринарии: -* рентгеновских трубок, генераторов высокого напряжения, панелей управления, пультов, экранов и т. п. -- производство медицинской, хирургической, стоматологической или ветеринарной мебели: -* операционных столов, больничных коек с механическими приспособлениями, зубоврачебных и парикмахерских кресел -- производство механико-терапевтических приспособлений, массажных аппаратов, аппаратуры для психологического тестирования, аппаратуры для озонотерапии, кислородной терапии, искусственного дыхания, газовых масок - -Эта подгруппа также включает: -- производство ортопедических приспособлений: -* костылей, хирургических и грыжевых бандажей, шин, искусственных зубов, искусственных конечностей и других протезных устройств, слуховых аппаратов, кардиостимуляторов, ортопедической обуви и т. п.","Эта подгруппа не включает: -- производство хирургических перевязочных материалов, прокладок, пропитанных лекарственными средствами, повязок, используемых при переломах, и т. п., см. 2423 -- производство цементов, используемых в стоматологии, см. 2423 -- производство термометров, см. 3312 -- производство корректирующих линз и оправ для очков или оптических микроскопов, см. 3320 -- деятельность стоматологов по подгонке зубных протезов или оптиков по подбору очков, см. 8512 и 8519" -2220,"331","Производство медицинских приборов и инструментов, приборов для измерения, проверки, испытания, навигации и других целей, кроме оптических инструментов",, -2210,"33","Производство медицинских приборов, точных и оптических инструментов, наручных и прочих часов","Этот подраздел охватывает производство не только научных и технических приборов (например, электродиагностической аппаратуры, авиационного электронного оборудования и т. п.), но и фотооборудования и киноаппаратуры, контрольного оборудования для промышленных процессов и предметов личного пользования (например, часов, очков и т. п.). -Данный подраздел также охватывает установку и ремонт такого промышленного оборудования, однако ремонт предметов личного пользования относится к группе 526.", -2200,"3230","Производство теле- и радиоприемников, звуко- или видеозаписывающей или воспроизводящей аппаратуры и сопутствующих потребительских товаров","Эта подгруппа включает: -- производство телевизионных приемников, в том числе видеомониторов и видеопроекторов -- производство видеозаписывающей или видеовоспроизводящей аппаратуры, в том числе видеокамер -- производство цифровых камер -- производство вещательных радиоприемников -- производство магнитофонов и другой звукозаписывающей аппаратуры, в том числе телефонных автоответчиков, кассетных магнитофонов и т. п. -- производство электропроигрывателей (граммофонных дек), проигрывателей для пластинок, кассетных проигрывателей -- производство проигрывателей компакт-дисков (CD-плейеров), проигрывателей цифровых видеодисков (DVD-плейеров) и т. п. -- производство микрофонов, громкоговорителей, шлемофонов, наушников, усилителей и звукоусилительных комплексов -- производство специальных деталей для оборудования, относящегося к данной категории: -* звукоснимателей, тонармов, звуковоспроизводящих магнитных головок, подставок под электропроигрыватели, всевозможных антенн, антенных рефлекторов и антенных роторов, кабельных преобразователей, телевизионных декодеров - -Эта подгруппа также включает: -- производство звукового электроакустического оборудования, систем конференц-связи, портативных звуковых систем","Эта подгруппа не включает: -- издание и тиражирование записанных аудио- и видеодисков и пленок, см. группы 221 и 223, а также подгруппу 9211 -- производство готовых неиспользованных носителей для записи, см. 2429" -2190,"323","Производство теле- и радиоприемников, звуко- или видеозаписывающей или воспроизводящей аппаратуры и сопутствующих потребительских товаров",, -2180,"3220","Производство теле- и радиопередатчиков и аппаратуры для кабельной телефонной и кабельной телеграфной связи","Эта подгруппа включает: -- производство аппаратуры для передачи телевизионных сигналов, в том числе производство ретрансляционных и телевизионных передатчиков для промышленного использования -- производство телевизионных камер -- производство передающей аппаратуры для радиовещания -- производство передающей аппаратуры для радиотелефонии: -* стационарных передатчиков и приемопередатчиков, радиотелефонной аппаратуры для транспортного оборудования, радиотелефонов, других приемоответчиков и т. п. -- производство аппаратуры для кабельной телефонии: -* телефонных аппаратов, факсимильных аппаратов, автоматических и неавтоматических коммутационных щитов и коммутаторов, телексного оборудования и телетайпов -- производство мобильных телефонов -- производство аппаратуры передачи данных: -* маршрутизаторов, шлюзов, концентраторов, перемычек - -Эта подгруппа также включает: -- монтаж телекоммуникационного оборудования","Эта подгруппа не включает: -- производство электронных компонентов, см. 3210 -- прокладку электрического или телекоммуникационного кабеля в зданиях, см. 4530 -- ремонт мобильных телефонов, см. 5260" -2170,"322","Производство теле- и радиопередатчиков и аппаратуры для кабельной телефонной и кабельной телеграфной связи",, -2160,"3210","Производство электронных ламп и трубок и прочих электронных компонентов","Эта подгруппа включает: -- производство термоэлектронных, холоднокатодных или фотокатодных ламп и трубок -* телевизионных кинескопов, передающих телевизионных трубок, электронно-оптических преобразователей и усилителей, микроволновых трубок, принимающих или усилительных ламп и трубок и т. п. -- производство диодов, транзисторов и аналогичных полупроводниковых устройств -- производство фоточувствительных полупроводниковых устройств, в том числе фотоэлектрических элементов и отдельных солнечных элементов -- производство смонтированных пьезоэлектрических кристаллов -- производство электронных интегральных схем и микроблоков: -* монолитных интегральных схем, гибридных интегральных схем и электронных микроблоков с отформованным модулем, микромодулем или модулями аналогичных типов -- производство печатных плат, пустых плат -- производство электрических конденсаторов, в том числе силовых конденсаторов -- производство сопротивлений, в том числе реостатов и потенциометров -- производство электронных компонентов для использования в печатных схемах, кроме трансформаторов -- производство жидкокристаллических дисплеев","Эта подгруппа не включает: -- производство блоков, состоящих из нескольких печатных схем (классифицируемое в той же подгруппе, что и производство всей машины) -- производство трансформаторов, см. 3110 -- производство переключателей, см. 3120" -2150,"321","Производство электронных ламп и трубок и прочих электронных компонентов",, -2140,"32","Производство оборудования и аппаратуры для радио, телевидения и связи","Этот подраздел охватывает производство электронного оборудования для радио- и телевещания, аппаратуры передачи данных, приемников, записывающих устройств и воспроизводящей аппаратуры. Данный подраздел охватывает все промежуточные товары, начиная от профессионального оборудования и заканчивая аппаратурой, используемой широкими слоями населения. -Следует отметить, что в этот подраздел также включены установка и ремонт профессионального оборудования. С другой стороны, ремонт бытовых приборов включен в подгруппу 5260, а установка проводки, антенн или систем сигнализации отнесена к строительным работам (4530).", -2130,"3190","Производство прочего электрооборудования, не включенного в другие категории","Эта подгруппа включает: -- производство электрооборудования для зажигания или пуска двигателей внутреннего сгорания: магнето-зажигания, магнето-динамо, катушек зажигания, свечей зажигания, запальных свечей, стартеров, генераторов (динамо-генераторов и генераторов переменного тока), регуляторов напряжения и т. п. -- производство электрических монтажных схем и систем монтажных проводов -- производство стеклоочистителей и электрических стеклообогревателей и приспособлений против запотевания стекол автомобилей и мотоциклов -- производство антиобледенителей и антизапотевателей с электрореостатами для летательных аппаратов, судов, поездов и других транспортных средств -- производство динамо-генераторов для мотоциклов -- производство электрического осветительного оборудования и оборудования звуковой или визуальной сигнализации для использования на мотоциклах и автомобилях: фар, рожков, сирен и т. п. -- производство электросигнального оборудования, оборудования, обеспечивающего безопасность движения и управление движением на автострадах, шоссейных дорогах и улицах, железных дорогах и трамвайных путях, на внутреннем водном транспорте, в портах и гаванях, а также в аэропортах -- производство прочих электрических устройств звуковой или визуальной сигнализации: -* звонков, сирен, световых табло, сигнальных устройств на случай взлома или пожара и т. п. -- производство электромагнитов, в том числе электромагнитных или постоянных магнитных патронов, сцеплений, тормозов, муфт, зажимов или поднимающих головок -- производство электроизоляторов и изоляционной арматуры, кроме стеклянных или керамических -- производство изоляционной арматуры для электрических машин или оборудования, кроме изготовленной из керамики или пластмасс -- производство угольных или графитовых электродов -- производство трубок для электрических проводов и соединений для таких трубок из неблагородных металлов с подкладкой из изоляционного материала -- производство прочих электрических механизмов и приборов: -* ускорителей частиц, генераторов сигналов, миноискателей и других механизмов","Эта подгруппа не включает: -- производство стеклянных колб для ламп, см. 2610 -- производство ручных электрораспылителей, см. 2919 -- производство электрических газонокосилок, см. 2921 -- производство бытовых электроприборов, см. 2930 -- производство электронных ламп и трубок (в том числе электронных ламп с холодным катодом), см. 3210 -- производство электрических ручных медицинских или стоматологических инструментов, см. 3311" -2120,"319","Производство прочего электрооборудования, не включенного в другие категории",, -2110,"3150","Производство электроламп и осветительного оборудования","Эта подгруппа включает: -- производство электрических ламп накаливания или газоразрядных ламп: -* ультрафиолетовых или инфракрасных ламп -* дуговых ламп -* ламп-вспышек, ламп-вспышек типа ""кубик"" и т. п. -- производство электрических ламп и осветительной арматуры: -* светильников, настольных ламп, ночников или торшеров, даже неэлектрических -* портативных электрических ламп -* освещенных дорожных знаков, освещенных табличек с названиями и т. п., в том числе неоновых знаков -* наружного и дорожного освещения -* осветительных комплектов типа тех, которыми украшают новогоднюю елку - -Эта подгруппа также включает: -- производство неэлектрического осветительного оборудования: -* газовых ламп -* карбидных ламп шахтеров -- производство осветительного оборудования для транспортных средств, кроме автомобилей и мотоциклов.","Эта подгруппа не включает: -- производство осветительного оборудования для автомобилей и мотоциклов, см. 3190 -- производство электронных газоразрядных ламп и фотовспышек, см. 3320" -2100,"315","Производство электроламп и осветительного оборудования",, -2090,"3140","Производство аккумуляторов, первичных элементов и батарей первичных элементов","Эта подгруппа включает: -- производство первичных элементов и батарей первичных элементов: -* элементов, содержащих двуокись марганца, окись ртути, окись серебра или другой материал -- производство электроаккумуляторов, в том числе деталей аккумуляторов: -* прокладок, корпусов, крышек -* свинцово-кислотных, кадмиево-никелевых и железо-никелевых или других аккумуляторов", -2080,"314","Производство аккумуляторов, первичных элементов и батарей первичных элементов",, -2070,"3130","Производство изолированного провода и кабеля","Эта подгруппа включает: -- производство изолированных провода, кабеля, пластин и других изолированных проводников, снабженных или не снабженных соединительными устройствами -- производство кабелей из оптического волокна для передачи кодированных данных в разных областях: телекоммуникации, передача видеоизображений, управление, передача данных и т. п.","Эта подгруппа не включает: -- производство неизолированного провода из цветных металлов, см. 2720 -- производство неизолированного металлического кабеля или изолированного кабеля, который не может использоваться в качестве проводника электричества, см. 2899 -- производство электрических монтажных схем, см. 3190 -- производство оптического волокна и кабеля из оптического волокна для прямой передачи изображений: эндоскопия, освещение, передача ""живых"" изображений, см. 3320" -2060,"313","Производство изолированного провода и кабеля",, -2050,"3120","Производство электрораспределительной и контрольной аппаратуры","Эта подгруппа включает: -- производство электроаппаратуры для коммутирования или защиты электрических цепей, для соединения с электрическими цепями или подключения к электрическим цепям: -* выключателей, плавких предохранителей, молниеотводов, ограничителей напряжения, устройств для сброса перенапряжения, штепселей, соединительных коробок, реле, розеток, патронов для ламп -- производство электронных контрольно-распределительных щитов, панелей, стендов, пультов, распределительных шкафов и других пультов - -Эта подгруппа также включает: -- производство щитов и панелей, оборудованных устройствами, классифицированными в подгруппе 3312","Эта подгруппа не включает: -- производство деталей таких приборов из литой пластмассы, стекла или керамического материала, см. 2520, 2610 и 2691 -- производство плавкой проволоки и плавких пластин, см. 2720 -- производство угольных или графитовых электродов, см. 3190 -- производство коммутационных щитов, панелей, стендов и т. п. для использования на телефонных или телеграфных линиях, см. 3220" -2040,"312","Производство электрораспределительной и контрольной аппаратуры",, -2030,"3110","Производство электромоторов, генераторов и трансформаторов","Эта подгруппа включает: -- производство моторов или генераторов переменного тока -- производство моторов или генераторов постоянного тока -- производство универсальных моторов переменного/постоянного тока -- производство генераторных установок переменного или постоянного тока -- производство электрических вращающихся или статических преобразователей -- производство электрических трансформаторов","Эта подгруппа не включает: -- производство автомобильных генераторов и пусковых двигателей, см. 3190 -- производство диодов, см. 3210" -2020,"311","Производство электромоторов, генераторов и трансформаторов",, -2010,"31","Производство электрических машин и аппаратуры, не включенных в другие категории","Этот подраздел включает производство изделий, которые производят, распределяют и накапливают электроэнергию. В этот подраздел также включено производство электроосветительного и сигнального оборудования. - -Данный подраздел не включает производство электронной продукции (подраздел 32) и бытовых электроприборов (подраздел 29).", -2000,"3000","Производство канцелярских, бухгалтерских и электронно-вычислительных машин","Эта подгруппа включает: -- производство механических и электрических пишущих машинок -- производство устройств для обработки текстов -- производство гектографов или копировально-множительных машин восковочного типа, машин для печатания адресов и канцелярских офсетных печатающих машин с полистной заправкой -- производство калькуляторов, кассовых аппаратов, почтовых франкировальных машин, специальных терминалов по продаже и резервированию билетов и т. п. -- производство фотокопировальной аппаратуры -- производство аппаратуры для автоматической обработки данных, включая микрокомпьютеры: -* цифровой аппаратуры -* аналоговой аппаратуры -* гибридной (цифро-аналоговой) аппаратуры -- производство периферийных блоков: -* терминалов, принтеров, графопостроителей и т. п. -* устройств для ввода данных: клавиатуры, мыши, джойстиков, ручек, графических планшетов и т. п. -* магнитных или оптических считающих и записывающих устройств -* запоминающих устройств компьютера -- производство прочих канцелярских машин или оборудования: -* машин, сортирующих, завертывающих или считающих монеты; машин для автоматической выдачи банкнот; машин, раскладывающих отправления по конвертам, сортирующих почту; точилок для карандашей; дыроколов и машин, сшивающих скобками, и т. п.","Эта подгруппа не включает: -- производство электронных деталей вычислительных машин, см. 3210 -- производство электронных игр, см. 3694 -- техническое обслуживание и ремонт компьютерных систем, см. 7250" -1990,"300","Производство канцелярских, бухгалтерских и электронно-вычислительных машин",, -1980,"30","Производство канцелярских, бухгалтерских и электронно-вычислительных машин","Считается, что производство канцелярского оборудования (например, фотокопировальных машин, кассовых аппаратов и т. п.) и компьютерного оборудования (например, компьютеров, текстовых процессоров и периферийных устройств) включает его установку, но не включает его техническое обслуживание (725), разработку программного обеспечения (722) или производство электронных компонентов (321).", -1970,"2930","Производство бытовых приборов, не включенных в другие категории","Эта подгруппа включает: -- производство бытовых электроприборов: -* холодильников и морозильных камер, посудомоечных машин, стиральных машин и сушилок, пылесосов, полотеров, бытовых измельчителей мусора, кофемолок, миксеров, соковыжималок, консервных ножей, электробритв, электрических зубных щеток, ножеточек, вытяжных или циркуляционных шкафов -- производство бытовых электронагревательных приборов: -* электроводонагревателей, электроодеял, электросушилок, расчесок, щеток, бигуди; электроутюгов, электрообогревателей помещений и вентиляторов бытового назначения; электрических духовок, микроволновых печей, электрических плит, подогревателей для тарелок, тостеров, кофеварок и чайников, сковородок, ростеров, грилей, вытяжных шкафов, реостатов электрообогрева и т. п. -- производство неэлектрического бытового оборудования для приготовления пищи и обогревателей: -* неэлектрических обогревателей помещений, кухонных плит, колосниковых решеток, печей, водонагревателей, кухонных приборов, подогревателей для тарелок.","Эта подгруппа не включает: -- производство промышленного или коммерческого оборудования, см. 291 и 292 -- производство промышленного холодильного и морозильного оборудования, см. 2919 -- производство оборудования для приготовления пищи в учреждениях общественного питания, см. 2925 -- производство стиральных и сушильных машин для прачечных, см. 2926 -- производство швейных машин, см. 2926" -1960,"293","Производство бытовых приборов, не включенных в другие категории",, -1950,"2929","Производство прочих машин специального назначения","Эта подгруппа охватывает производство машин специального назначения, не включенных в другие категории. - -Эта подгруппа включает: -- производство машин для изготовления целлюлозы -- производство бумагоделательных машин и машин для изготовления картона -- производство сушилок для древесины, целлюлозы, бумаги или картона -- производство машин для изготовления изделий из бумаги или картона -- производство машин для обработки мягкой резины или пластмасс или для изготовления изделий из этих материалов: -* шприцмашин, формовочных машин, машин для изготовления пневматических шин или возобновления протекторов, а также других машин для изготовления особых изделий из резины или пластмасс -- производство печатных и переплетных машин, а также машин для вспомогательных печатных операций, включая машины для печати на тканях и других материалах -- производство литьевых форм для любого материала; поддонов для опок; литейных моделей; опок для металлов (кроме изложниц) -- производство машин для изготовления черепицы, кирпича, штампованных керамических паст, труб, графитовых электродов, школьного мела, литейных изложниц и т. п. -- производство машин по изготовлению полупроводников -- производство многофункциональных промышленных роботов -- производство прочих специальных машин и оборудования: -* машин для сборки электрических или электронных ламп, трубок или ламп накаливания -* машин для производства или горячей обработки стекла или стеклянных изделий, стекловолокна или пряжи -* машин или аппаратуры для выделения изотопов -* производство промышленных сушилок для одежды","Эта подгруппа не включает: -- производство машин и оборудования для обработки отвержденной резины, твердых пластмасс или холодного стекла, см. 2922 -- производство изложниц, см. 2923 -- производство бытовых приборов, см. 2930 -- фотокопировальных машин и т. п., см. 3000" -1940,"2927","Производство оружия и военного снаряжения","Эта подгруппа включает: -- производство танков и других боевых машин -- производство тяжелого оружия (артиллерийских орудий, самоходных пушек, пусковых установок, торпедных труб, тяжелых пулеметов) -- производство стрелкового оружия (револьверов, винтовок, легких пулеметов) -- производство пневматических или газовых винтовок и пистолетов -- производство боеприпасов -- производство военных баллистических и управляемых ракет - -Эта подгруппа также включает: -- производство охотничьего, спортивного или используемого в целях защиты стрелкового оружия и боеприпасов -- производство взрывных устройств, таких как бомбы, мины и торпеды","Эта подгруппа не включает: -- производство ударных капсюлей, детонаторов или сигнальных ракет, см. 2429 -- производство сабель, шпаг, штыков и т. п., см. 2893 -- производство бронированных автомобилей для перевозки казначейских билетов и ценностей, см. 3410" -1930,"2926","Производство машин для текстильной, швейной и кожевенной промышленности","Эта подгруппа включает: -- производство машин для текстильной промышленности: -* машин для подготовки, изготовления, формования, вытягивания, текстурирования или резки искусственных текстильных волокон, материалов или пряжи -* машин для первичной обработки текстильного волокна: хлопкоочистительных машин, трепальных машин, машин для разработки крутых концов, хлопочесальных машин, шерстовальных машин, карбонизаторов шерсти, гребнечесальных машин, кардочесальных машин, ровничных рам и т. п. -* прядильных машин -* машин для подготовки пряжи к использованию: мотальных машин, сновальных машин и аналогичных машин -* ткацких машин (станков), в том числе ручных станков -* вязальных машин -* машин для изготовления ажурного полотна, тюля, кружев, басонных изделий и т. п. -- производство вспомогательных машин и оборудования для текстильных машин: -* ремизоподъемных кареток, жаккардовых машин; механизмов автоматической смены шпуль; механизмов для замены челноков; веретен и банкоброшей и т. п. -- производство машин для обработки тканей: -* машин для мытья, отбелки, крашения, аппретирования, отделки, покрытия или пропитки текстильных тканей -* машин для размотки пряжи в мотки и для размотки коконов, для укладки, резки или фестонной обработки текстильных тканей -- производство прачечного оборудования: -* гладильных машин, в том числе гладильных прессов -* производство стиральных и сушильных машин для прачечных -* производство машин для сухой химической чистки -- производство швейных машин, головок швейных машин и игл для швейных машин (бытового или небытового назначения) -- производство машин для изготовления или отделки фетра или нетканых материалов -- производство машин для изготовления изделий из кожи: -* машин для первичной обработки, дубления или выделки крупных и мелких шкур или кожи -* машин для изготовления или ремонта обуви и других изделий из крупных и мелких шкур, кожи или меха","Эта подгруппа не включает: -- производство бумажных или картонных карт, используемых на жаккардовых машинах, см. 2109 -- производство гладильных машин каландрового типа, см. 2919 -- производство швейных машин, используемых в переплетном деле, см. 2929 -- производство машин для печати на тканях, см. 2929 -- производство бытовых стиральных и сушильных машин, см. 2930" -1920,"2925","Производство машин для обработки пищевых продуктов, напитков и табачных изделий","Эта подгруппа включает: -- производство сушилок, используемых в сельском хозяйстве -- производство машин для молочной промышленности: -* молочных сепараторов -* машин для обработки молока (гомогенизаторов и иррадиаторов) -* машин для преобразования молока (маслобоек, масломешалок и формовочных машин) -* сыроваренных машин (гомогенизаторов, формовочных машин, прессов) и т. п. -- производство машин для мукомольной промышленности: -* машин для очистки, сортировки и калибровки семян, зерна и сухих бобовых (веялок, высевающих ремней, сепараторов, щеточных зерноочистительных машин и т. п.) -* машин, используемых для производства муки тонкого и грубого помола и т. п. (мельниц, загрузочных механизмов, сит, механизмов для очистки от высевок, смесителей, шелушильных поставов для риса, горохолущильных машин) -- производство прессов, давилок и аналогичного оборудования, используемого для изготовления вина, сидра, фруктовых соков и т. п. -- производство машин для использования в хлебопекарном производстве или для изготовления макарон, спагетти или аналогичных изделий: -* хлебопекарных печей, тестомешалок, тесторазделителей, формовочных столов, ломтерезок, оборудования для выпечки пирожных и т. д. -- производство машин и оборудования для обработки различных пищевых продуктов: -* машин для производства кондитерских изделий, какао или шоколада; для производства сахара; для пивоваренных заводов; для обработки мяса или птицы; для первичной обработки фруктов, орехов и овощей; для первичной обработки рыбы, моллюсков и других морепродуктов -* машин для фильтрования и очистки -* других машин для промышленной обработки или производства пищевых продуктов и напитков -- производство машин для извлечения и приготовления нелетучих животных или растительных жиров и масел -- производство машин для предварительной обработки табака и изготовления сигарет или сигар или же для изготовления трубочного, жевательного или нюхательного табака -- производство машин для приготовления пищи в гостиницах и ресторанах","Эта подгруппа не включает: -- производство упаковочных и оберточных машин, весоизмерительного оборудования, см. 2919 -- производство машин для очистки, сортировки и калибровки яиц, фруктов или других сельскохозяйственных культур (кроме семян, зерна и сухих бобовых), см. 2921" -1910,"2924","Производство машин для горнодобывающей промышленности, разработки карьеров и строительства","Эта подгруппа включает: -- производство подъемных устройств непрерывного действия и конвейеров для использования под землей -- производство бурильных, выемочных и проходческих машин, а также машин для прокладки туннелей (предназначенных или не предназначенных для использования под землей) -- производство машин для обработки минералов путем просеивания, сортировки, отделения, промывки, дробления и т. п. -- производство бетономешалок или мешалок для строительного раствора -- производство землеотвальных машин: -* бульдозеров и универсальных бульдозеров, грейдеров, выравнивателей, скреперов, механических лопат, ковшовых погрузчиков и т. п. -- производство машин для забивки и извлечения свай, растворораспределителей, распределителей битума, машин для отделки поверхностного слоя бетона и т. д. -- производство гусеничных тракторов и тракторов, используемых в строительстве или в горнодобывающей промышленности -- производство отвальных ножей для бульдозеров и универсальных бульдозеров","Эта подгруппа не включает: -- производство подъемного и такелажного оборудования, см. 2915 -- производство других тракторов, см. 2921 и 3410 -- производство станков для обработки камня, в том числе машин для раскалывания или расщепления камня, см. 2922 -- производство грузовиков-бетономешалок, см. 3410" -1900,"2923","Производство машин для металлургии","Эта подгруппа включает: -- производство машин и оборудования для обработки жидких металлов: -* конвертеров, изложниц, ковшей и разливочных машин -- производство прокатных станов и валов для таких станов","Эта подгруппа не включает: -- производство волочильных станков, см. 2922 -- производство опок и литейных форм (за исключением изложниц), см. 2929 -- производство машин для изготовления литейных опок, см. 2929" -1890,"2922","Производство станков","Эта подгруппа включает: -- производство станков для обработки металлов и других материалов (таких, как дерево, кость, камень, отвержденная резина, твердые пластмассы, холодное стекло и т. д.), в том числе с помощью лазерного луча, ультразвуковых волн, плазменной дуги, магнитного импульса и т. п. -- производство токарных, сверлильных, фрезерных, поперечно-строгальных, строгальных, расточных, шлифовальных и т. п. -- производство штамповочных станков или прессов -- производство листоштамповочных прессов, гидравлических прессов, гидравлических отбойников, падающих молотов, ковочных машин и т. д. -- производство волочильных станков, резьбонакатных роликов или станков для обработки проволоки -- производство станков для крепления гвоздями, скобами, склеивания или иной сборки деталей из дерева, пробки, кости, отвержденной резины или твердых пластмасс и т. п. -- производство станков для газовой или электрической сварки, для пайки твердым или мягким припоем -- производство ручного инструмента с автономным электрическим или неэлектрическим двигателем или с пневматическим приводом -- производство дрелей или дрелей с пробойником, цепных пил, опиловочных станков, клепальных машин и резаков листового металла и т. п. -- производство прессов для производства древесно-стружечных плит и аналогичных материалов - -Эта подгруппа также включает: -- производство деталей и принадлежностей для станков, классифицированных в данной категории: рабочих держателей, разграничителей и других специальных приспособлений для станков","Эта подгруппа не включает: -- производство взаимозаменяемых насадок для ручных инструментов или станков (сверл, пробойников, кернеров, метчиков, фрез, токарных инструментов, полотен для пил, резаков и т. п.), см. 2893 -- производство машин, используемых на металлургических заводах или в литейных цехах, см. 2923 -- производство машин для горнодобывающей промышленности и разработки карьеров, см. 2924" -1880,"2921","Производство машин для сельского хозяйства и лесоводства","Эта подгруппа включает: -- производство тракторов, используемых в сельском хозяйстве и лесоводстве -- производство тракторов с выносным управлением -- производство косилок, в том числе газонокосилок -- производство сельскохозяйственных самозагружающихся и саморазгружающихся прицепов и полуприцепов -- производство сельскохозяйственных машин для подготовки почвы, посадки культур и внесения удобрений -* борон, навозоразбрасывателей, сеялок, прополочных культиваторов и т. д. -- производство уборочных машин и молотилок: -* уборочных машин, молотильных комбайнов, сортировочных машин и т. п. -- производство доильных аппаратов -- производство разбрызгивающих устройств для сельскохозяйственного использования -- производство прочих машин, используемых в сельском хозяйстве: -* машин для птицеводства, машин для пчеловодства, оборудования для приготовления кормов и т. д. -* машин для очистки, сортировки и калибровки яиц, фруктов и т. п.","Эта подгруппа не включает: -- производство ручного инвентаря, используемого в сельском хозяйстве, без силового привода, см. 2893 -- производство транспортеров для использования на фермах, см. 2915 -- производство ручного инвентаря с силовым приводом, см. 2922 -- производство молочных сепараторов, см. 2925 -- машин для очистки, сортировки или калибровки семян, зерна или сухих бобовых, см. 2925 -- производство дорожных тягачей для полуприцепов, см. 3410 -- производство дорожных прицепов или полуприцепов, см. 3420" -1870,"292","Производство машин специального назначения",, -1860,"2919","Производство других машин общего назначения","Эта подгруппа включает: -- производство холодильного или морозильного оборудования, в том числе узлов из основных компонентов -- производство кондиционеров воздуха, в том числе для автомобилей -- производство промышленных вентиляторов -- производство весоизмерительного оборудования (кроме высокоточных лабораторных весов): -* бытовых и магазинных весов, напольных весов, весов для непрерывного взвешивания, мостовых весов, гирь и т. п. -- производство фильтрующих или очищающих машин и аппаратов для жидкостей -- производство оборудования для распыления, рассеивания или разбрызгивания жидкостей или порошков: -* распылителей, огнетушителей, пескоструйных машин, пароочистительных машин и аналогичных струйно-распылительных машин -- производство упаковочных и оберточных машин: -* машин, выполняющих такие операции, как наполнение, закрывание, запечатывание, закрывание колпачками или этикетирование емкостей -- производство машин для мытья и сушки бутылок и других емкостей или для газирования напитков -- производство перегонных или ректификационных установок для нефтеперерабатывающих заводов, химических предприятий, заводов по производству напитков и т. п. -- производство теплообменников -- производство машин для сжижения воздуха или газа -- производство газогенераторов -- производство каландров или других вальцовых машин и цилиндров к ним (кроме предназначенных для прокатки металлов или стекла) -- производство центрифуг (кроме молочных сепараторов и сушилок для белья) -- производство сальников и аналогичных сочленений, изготовленных из нескольких материалов или из слоев одного и того же материала -- производство автоматов по продаже товаров -- производство деталей для машин и оборудования общего назначения","Эта подгруппа не включает: -- производство разбрызгивающих установок, специально предназначенных для использования в сельском хозяйстве, см. 2921 -- производство машин для прокатки металла или стекла и цилиндров к ним, см. 2923, 2929 -- производство сушильного оборудования сельскохозяйственного назначения, машин для фильтрования или очистки пищевых продуктов, см. 2925 -- производство молочных сепараторов, см. 2925 -- производство промышленных сушилок для белья, см. 2929 -- производство бытового холодильного или морозильного оборудования, см. 2930 -- производство бытовых вентиляторов, см. 2930 -- производство высокоточных весов, см. 3312" -1850,"2915","Производство подъемного и такелажного оборудования","Эта подгруппа включает: -- производство оборудования с ручным управлением или с механическим приводом для подъемных, такелажных, погрузочных или разгрузочных работ: -* сложных блоков и полиспастов, лебедок, кабестанов и домкратов -* деррик-кранов, кранов, передвижных подъемных установок, портальных транспортеров и т. п. -* автопогрузчиков, снабженных или не снабженных подъемным краном или другим подъемным или такелажным оборудованием, самоходных или несамоходных, которые используются на заводах -* механических манипуляторов и промышленных роботов, специально предназначенных для подъемных, такелажных, погрузочных или разгрузочных работ -- производство конвейеров, телефериков -- производство лифтов, эскалаторов, движущихся тротуаров -- производство деталей, специально предназначенных для подъемного и такелажного оборудования - -Эта подгруппа также включает: -- техническое обслуживание лифтов и эскалаторов","Эта подгруппа не включает: -- производство подъемников и конвейеров непрерывного действия для использования под землей, см. 2924 -- производство механических лопат, экскаваторов и погрузчиков экскаваторов, см. 2924 -- производство многофункциональных промышленных роботов, см. 2929 -- производство плавучих кранов, рельсовых кранов, кранов-грузовиков, см. 3511, 3520 -- установку лифтов и оборудования, см. 4530" -1840,"2914","Производство обжиговых печей, вагранок и печных горелок","Эта подгруппа включает: -- производство электрических и прочих промышленных и лабораторных вагранок и печей, в том числе установок для сжигания отходов -- производство горелок - -Эта подгруппа также включает: -- производство механических стокеров, колосников, золоудалителей и т. п.","Эта подгруппа не включает: -- производство сельскохозяйственных сушилок, см. 2925 -- производство хлебопекарных печей, см. 2925 -- производство сушилок для древесины, целлюлозы, бумаги или картона, см. 2929 -- производство бытовых печей, см. 2930 -- производство медицинских, хирургических и лабораторных стерилизаторов, см. 3311" -1830,"2913","Производство подшипников, шестеренок, элементов зубчатых передач и приводов","Эта подгруппа включает: -- производство шариковых и роликовых подшипников и их деталей -- производство механического трансмиссионного оборудования: -* трансмиссионных валов и кривошипов: распределительных валов, коленчатых валов, кривошипов и т. п. -* корпусов подшипников и простых валов -- производство шестеренок и зубчатых передач, коробок передач и других элементов коробок переключения скоростей -- производство муфт сцепления и воздушных муфт -- производство маховиков и блоков -- производство шарнирной цепи -- производство приводных цепей -- производство гидравлического трансмиссионного оборудования","Эта подгруппа не включает: -- производство прочих цепей, см. 2899 -- производство электромагнитных муфт, см. 3190 -- производство сборочных узлов оборудования силовой передачи, распознаваемых как детали автомобилей или летательных аппаратов, см. подразделы 34 и 35" -1820,"2912","Производство насосов, компрессоров, пробок и клапанов","Эта подгруппа включает: -- производство воздушных или вакуумных насосов, воздушных или других газовых компрессоров -- производство жидкостных насосов, снабженных или не снабженных измерительными приборами -- насосов, предназначенных для использования с двигателями внутреннего сгорания: масляных, водяных и топливных насосов для автомобилей и т. п. - -Эта подгруппа также включает: -- производство гидравлического силового оборудования и пневматических двигателей и моторов -- производство пробок и клапанов для использования в промышленности, включая регулирующие клапаны и сливные пробки -- производство пробок и клапанов для сантехнических устройств -- производство пробок и клапанов для систем отопления -- производство ручных насосов","Эта подгруппа не включает: -- производство клапанов, изготовляемых из неотвержденной вулканизированной резины, стекла или керамических материалов, см. 2519, 2610 и 2691 -- производство гидравлического трансмиссионного оборудования, см. 2913 -- производство бытовых вентиляторов, см. 2930 -- производство впускных и выпускных клапанов двигателей внутреннего сгорания, см. 3430 и 3530" -1810,"2911","Производство двигателей и турбин, кроме авиационных, автомобильных и мотоциклетных двигателей","Эта подгруппа включает: -- производство двигателей внутреннего сгорания и деталей двигателей, кроме двигателей, предназначенных для приведения в движение автомобилей или летательных аппаратов: -* судовых двигателей -* двигателей рельсового транспорта -- производство турбин и частей турбин: -* паровых турбин различного вида -* гидравлических турбин, водяных колес и регулирующих их механизмов -* ветряков -* газовых турбин, кроме турбореактивных и турбовинтовых двигателей, предназначенных для приведения в движение летательных аппаратов -- котельно-турбинных установок","Эта подгруппа не включает: -- производство электрогенераторов, см. 3110 -- производство электрического оборудования или комплектующих двигателей внутреннего сгорания, см. 3190 -- производство автомобильных, мотоциклетных двигателей и двигателей для летательных аппаратов, см. 3410, 3530, 3591 -- производство турбореактивных и турбовинтовых двигателей, см. 3530" -1800,"291","Производство машин общего назначения",, -1790,"29","Производство машин и оборудования, не включенных в другие категории","Этот подраздел охватывает производство машин и оборудования, которые автономно воздействуют на материалы либо механически, либо термически или выполняют те или иные операции с материалами (такие, как обработка, опрыскивание, взвешивание или упаковка), включая производство их механических компонентов, которые создают силу или оказывают силовое воздействие, а также любые специально изготовленные основные узлы. Данная категория включает неподвижно закрепленные, передвижные или ручные устройства независимо от того, предназначены ли они для использования в промышленности, в строительстве, в частности в гражданском строительстве, сельском хозяйстве, в сфере обороны или в быту. К этому подразделу также относится производство оружия и специального оборудования для пассажирского и грузового транспорта в пределах ограниченной территории. -Данный подраздел не включает производство металлических изделий общего назначения (подраздел 28), соответствующих устройств управления, компьютерного оборудования, измерительного и испытательного оборудования, электрораспределительной аппаратуры и аппаратуры управления (подразделы 30-33) и автотранспортных средств общего назначения (подразделы 34 и 35). -В подразделе 29 проводится различие между производством машин и компонентов общего назначения и машин и компонентов специального назначения; подраздел включает производство: -- моторов и двигателей (кроме электромоторов), турбин, насосов, компрессоров, клапанов и трансмиссий -- печей, горелок, грузоподъемного и грузообрабатывающего оборудования, охлаждающего и вентиляционного оборудования, прочих машин общего назначения (например, упаковочного оборудования, весов и водоочистного оборудования) -- сельскохозяйственных машин, станков, машин и оборудования для конкретных промышленных процессов (например, для производства металлов, строительства, в частности гражданского строительства, горного дела или производства продовольственных товаров, текстильных изделий, бумаги, печатных материалов, изделий из пластмассы и резины) -- оружия и боеприпасов -- бытовых приборов (с электроприводом и без электропривода)", -1780,"2899","Производство прочих готовых металлических изделий, не включенных в другие категории","Эта подгруппа включает: -- производство кадок, банок, бочек, ведер, ящиков -- производство консервных банок и жестяных коробок для продуктов питания, складных тюбиков и мешков -- производство металлических крышек -- металлического кабеля, плетеных окантовок и аналогичных изделий -- производство неизолированного металлического кабеля или изолированного кабеля, который нельзя использовать в качестве проводника электрического тока -- производство изделий из проволоки: колючей проволоки, проволочных ограждений, решеток, сеток, тканей и т. д. -- производство гвоздей и булавок -- производство заклепок, шайб и других безрезьбовых изделий -- производство винторезных изделий -- производство болтов, винтов гаек и других резьбовых изделий -- производство пружин (кроме часовых пружин): -* листовых рессор, спиральных пружин, пружин торсионных валов -* листов для рессор -- производство цепей, кроме цепей для силовых передач -- производство металлической кухонной утвари: -* столовой посуды: тарелки, блюдца и т. п. -* глубокой кухонной посуды: котелки, чайники и т. п. -* мелкой кухонной посуды: миски, блюда и т. п. -* кастрюль, сковород и другой кухонной утвари без электропривода, используемых за столом или в кухне -* небольших ручных кухонных приспособлений и приборов -* металлических подушечек для шабровки -- производство ванн, унитазов, раковин и других сантехнических изделий -- производство металлических изделий для конторских нужд, кроме мебели -- производство сейфов, портативных сейфов, бронированных дверей -- производство прочих металлических изделий: -* судовых винтов и их лопастей -* якорей -* колоколов -* смонтированных креплений для железнодорожных путей -* металлических защитных шлемов -* застежек, пряжек, крючков -* вывесок","Эта подгруппа не включает: -- производство цистерн и резервуаров, см. 2812 -- производство сабель, штыков, см. 2893 -- производство цепей для силовых передач, см. 2913 -- производство провода и кабеля для передачи электроэнергии, см. 3130 -- производство часов или часовых пружин, см. 3330 -- производство металлической мебели, см. 3610 -- производство спортивных товаров, см. 3693 -- производство игр и игрушек, см. 3694" -1770,"2893","Производство ножевых изделий, ручных инструментов и обычных скобяных изделий","Эта подгруппа включает: -- производство изделий, используемых в домашнем обиходе, таких как ножи, вилки, ложки и т. п. -- производство прочих ножевых изделий: -* ножей для резки и рубки мяса -* бритв и бритвенных лезвий -* ножниц и парикмахерских ножниц -- производство ножей и ножевых лезвий для машин или механических приборов -- производство ручных инструментов, таких как плоскогубцы, отвертки и т. п. -- производство ручных инструментов без электропривода, используемых в сельском хозяйстве -- производство пил и полотен для пил, в том числе полотен для циркулярных и цепных пил -- производство взаимозаменяемых насадок для ручных инструментов, с электроприводом или без него, или для станков: сверл, пробойников, кернеров, фрез -- производство кузнечного оборудования: горнов, наковален и т. п. -- производство тисков, зажимов -- производство затворов, замков, ключей, петель и других скобяных изделий для оборудования зданий, мебели, транспортных средств и т. п. -- производство сабель, шпаг, штыков и т. п.","Эта подгруппа не включает: -- производство глубокой (котелки, чайники и т. п.) и мелкой (миски, блюда и т. п.) кухонной и столовой (тарелки, блюдца) посуды, см. 2899 -- производство ручных инструментов с электроприводом, см. 2922 -- производство кухонной утвари из благородных металлов, см. 3691" -1760,"2892","Обработка и покрытие металлов; деятельность в области общего машиностроения за вознаграждение или на договорной основе","Эта подгруппа включает: -- металлизацию, анодирование и т. д. металла -- горячую обработку металла -- удаление заусенцев, пескоструйную очистку, барабанную обработку и очистку металлов -- покраску, гравировку, печатание металла -- нанесение неметаллического покрытия на металлы -- закаливание, полировку металла -* покрытие пластмассой, эмалью, лаком и т. п. -- расточку, токарную обработку, фрезировку, травление, строгальные операции, притирку, развертку, рихтовку, распил, дробление, заточку, полировку, сварку, наращивание и т. д. металлических частей -- резку и гравировку металлов с помощью лазера","Эта подгруппа не включает: -- вальцовку благородных металлов на основные металлы или прочие металлы, см. 2720 -- гравировальные услуги ""в присутствии заказчика"", см. 5260" -1750,"2891","Ковка, прессование, штамповка и прокатка металла; порошковая металлургия","Эта подгруппа включает: -- ковку, прессование, штамповку и прокатку металла -- порошковую металлургию: производство металлических изделий непосредственно из металлических порошков с помощью тепловой обработки (спекания) или под давлением","Эта подгруппа не включает: -- производство металлического порошка, см. 2710, 2720" -1740,"289","Производство прочих готовых металлических изделий; услуги по металлообработке",, -1730,"2813","Производство парогенераторов, кроме бойлеров для центрального отопления","Эта подгруппа включает: -- производство паровых котлов и других парогенераторов -- производство вспомогательных установок, используемых с парогенераторами: -* конденсаторов, экономайзеров, пароперегревателей, коллекторов и паронакопителей -- производство ядерных реакторов всех видов, кроме сепараторов изотопов -- производство котлов для морских судов и электростанций","Эта подгруппа не включает: -- производство бойлеров и радиаторов центрального отопления, см. 2812 -- производство котло-турбинных установок, см. 2911 -- производство сепараторов изотопов, см. 2929" -1720,"2812","Производство цистерн, резервуаров и металлических емкостей","Эта подгруппа включает: -- производство резервуаров, цистерн и аналогичных емкостей, обычно устанавливаемых стационарно для хранения или производственного использования -- производство металлических емкостей для сжатого или сжиженного газа -- производство бойлеров и радиаторов центрального отопления","Эта подгруппа не включает: -- производство бочонков, бочек, банок, ведер, ящиков и т. д., обычно используемых для перевозки или упаковки товаров (независимо от размера), см. 2899 -- производство транспортных контейнеров, см. 3420" -1710,"2811","Производство строительных металлических изделий","Эта подгруппа включает: -- производство металлоконструкций или строительных каркасов и их частей (опор, мачт, форм, мостов и т. п.) -- производство промышленных металлоконструкций (каркасы для доменных печей, грузоподъемного и грузообрабатывающего оборудования) -- производство зданий из сборных, преимущественно металлических конструкций: -* строительных бытовок, элементов выставочных модулей и т. п. -- производство металлических дверей, окон с оконными рамами, ставен и ворот","Эта подгруппа не включает: -- производство деталей для судовых или силовых котлов, см. 2813 -- производство смонтированных креплений для железнодорожных путей, см. 2899 -- производство секций для судов, см. 3511" -1700,"281","Производство строительных металлических изделий, цистерн, резервуаров и парогенераторов",, -1690,"28","Металлообрабатывающая промышленность, кроме производства машин и оборудования","В то время как подраздел 28 касается производства ""чистых"" металлических изделий (таких, как детали, контейнеры и несущие конструкции), как правило, являющихся статичными и недвижимыми, в подразделы 29-36 включены соединения или агрегаты металлических изделий (иногда в сочетании с другими материалами), которые входят в состав более сложных изделий, имеющих (если только эти изделия не являются чисто электрическими, электронными или оптическими) движущиеся части.", -1680,"2732","Цветное литье","Эта подгруппа включает: -- отливку полуфабрикатов из алюминия, магния, титана, цинка и т. п. -- производство литья легких металлов -- производство литья тяжелых металлов -- производство литья из благородных металлов -- производство пресс-литья из цветных металлов","Эта подгруппа не включает: -- отливку, осуществляемую в связи с производством металлических изделий, см. подразделы 27-36" -1670,"2731","Стальное и чугунное литье","Эта подгруппа охватывает деятельность чугуноплавильных и сталелитейных заводов. - -Данная подгруппа включает: -- отливку полуфабрикатов из чугуна -- производство литья из серого чугуна -- производство чугунного литья со сфероидальным графитом -- производство изделий из ковкого чугуна -- отливку полуфабрикатов из стали -- производство стального литья","Эта подгруппа не включает: -- отливку, осуществляемую в связи с производством металлических изделий, см. подразделы 27-36" -1660,"273","Металлическое литье","Эта группа включает: -- производство полуфабрикатов и различного литья, изготовленного для третьих сторон согласно представленным ими указаниям","Эта группа не включает: -- производство готового литья, такого как трубы и связанные с ними изделия, см. 2710; котлы и радиаторы, см. 2812; предметы домашней утвари из литья, см. 2899 и другие подгруппы" -1650,"2720","Производство основных благородных и цветных металлов","Эта подгруппа включает: -- производство благородных металлов: -* производство и обработка недеформируемых и деформируемых благородных металлов: золота, серебра и платины и т. п. из руды и металлолома -- производство сплавов благородных металлов -- производство полуфабрикатов благородных металлов -- производство серебра, навальцованного на основные металлы -- производство золота, навальцованного на основные металлы или серебро -- производство платины или металла платиновой группы, навальцованного на золото, серебро или основные металлы -- производство алюминия из глинозема -- производство алюминия путем электролитического рафинирования алюминиевых отходов и металлолома -- производство алюминиевых сплавов -- изготовление полуфабрикатов из алюминия -- производство свинца, цинка и олова из руды -- производство свинца, цинка и олова путем электролитического рафинирования отходов и металлолома свинца, цинка и олова -- производство сплавов свинца, цинка и олова -- изготовление полуфабрикатов из свинца, цинка и олова -- производство меди из руды -- производство меди путем электролитического рафинирования отходов и металлолома меди -- производство медных сплавов -- изготовление проволоки для плавких предохранителей или полос -- изготовление полуфабрикатов из меди -- производство хрома, марганца, никеля и т. п. из руд или окисей -- производство хрома, марганца, никеля и т. п. путем электролитического и алюминотермического рафинирования отходов и металлолома хрома, марганца, никеля и т. п. -- производство сплавов хрома, марганца, никеля и т. п. -- изготовление полуфабрикатов из хрома, марганца, никеля и т. п. -- производство никелевого штейна - -Эта подгруппа также включает: -- производство проволоки из этих металлов путем волочения -- производство окиси алюминия (глинозема) -- производство алюминиевой фольги","Эта подгруппа не включает: -- производства корпусов для часов из благородных металлов, см. 3330 -- производство ювелирных изделий из благородных металлов, см. 3691 -- операции по кузнечно-прессовой обработке, осуществляемые в связи с производством металлических изделий, см. подразделы 28-36" -1640,"272","Производство основных благородных и цветных металлов",, -1630,"2710","Производство чугуна и стали","Эта подгруппа включает: -- эксплуатацию доменных печей, конвертеров, черных и чистовых прокатных станов -- производство чугунных болванок и шпигелей в форме чушек, блоков или в других первичных формах -- производство ферросплавов -- производство полуфабрикатов из чугуна или нелегированной стали -- производство чушек, других первичных форм и полуфабрикатов из нержавеющей стали или других видов легированной стали -- производство углового проката, фасонной и профильной нержавеющей стали или других видов легированной стали -- производство прутков и катанки из нержавеющей стали или других видов легированной стали -- производство проката из чугуна или нелегированной стали -- производство углового проката, фасонного и профильного чугуна или нелегированной стали -- производство прутков и катанки из чугуна или нелегированной стали -- производство металлических листов -- производство железнодорожных дорожно-строительных материалов (несмонтированные рельсы) -- производство труб из литейного чугуна и центробежно-литых труб из литейного чугуна или стали -- производство арматуры из литейного чугуна: арматуры из ковкого и нековкого литейного чугуна и арматуры из литейной стали, обеспечивающей соединение путем завинчивания крепежных изделий с резьбой, стыкового соединения с помощью переходных муфт или скрепления болтами фланцев арматуры -- производство бесшовных труб путем горячей прокатки, горячего выдавливания и горячего волочения или путем холодного волочения или холодной прокатки -- производство сварных труб путем холодной или горячей отливки и сварки, путем отливки и холодного волочения или путем горячей отливки и протягивания -- производство арматуры стальных труб: -* плоских фланцев и фланцев с коваными стальными частями -* стыковой стальной сварной арматуры -* арматуры с винтовой нарезкой и прочей стальной арматуры -- производство стальных прутков или секций путем холодного волочения, шлифования или очистки -- производство открытого профиля путем последовательной формовки в прокатном цехе или прессования изделий из листовой стали -- производство стальной проволоки методом холодного волочения или протяжки -- производство чугуна в виде гранул или порошка; производство чугуна исключительной чистоты путем электролиза или с помощью других химических процессов","Эта подгруппа не включает: -- операции по кузнечно-прессовой обработке, осуществляемые в связи с производством металлических изделий, см. подразделы 28-36" -1620,"271","Производство чугуна и стали",, -1610,"27","Металлургическая промышленность","Этот подраздел охватывает деятельность, связанную с плавкой и/или переработкой черных и цветных металлов из руды, чушек или металлолома с использованием электрометаллургических процессов и прочих металлургических технологий. В этом подразделе также классифицируется производство металлических сплавов и суперсплавов путем добавления других химических веществ в чистые металлы. Продукция плавки и переработки, обычно в форме чушек, используется в операциях прокатки, волочения и выдавливания для получения продукции в виде листов, полос, брусков, прутов или проволоки или в расплавленном виде для получения литья и прочей основной продукции металлургической промышленности.", -1600,"2699","Производство прочих неметаллических минеральных продуктов, не включенных в другие категории","Эта подгруппа включает: -- производство жерновов, точильных или полировальных камней и природных или искусственных абразивных изделий, включая абразивные изделия на мягкой основе (например, наждачной бумаги) -- производство неметаллической минеральной пряжи и ткани, одежды, головных уборов, обуви, корда, веревки, бумаги, войлока и т. п. (например из асбеста) -- производство фрикционного материала и несмонтированных изделий на основе минеральных веществ или целлюлозы -- производство минеральных изоляционных материалов: -* шлаковой ваты, минеральной силикатной шерсти или аналогичных видов минеральной ваты; расслоенного вермикулита, вспученных глин и аналогичных теплоизолирующих, звукоизолирующих или звукопоглощающих материалов -- производство изделий из различных минеральных веществ: -* обработанной слюды и изделий из слюды, торфа, графита (кроме электротоваров) и т. п. -- производство изделий из асфальта или аналогичного материала, например клеящих веществ на асфальтовой основе, каменноугольного пека и т. п.","Эта подгруппа не включает: -- производство стекловаты и нетканых изделий из стекловаты, см. 2610" -1590,"2696","Резка, фасонирование и отделка камня","Эта подгруппа включает: -- резку, фасонирование и отделку камня для использования в строительстве, кладбищенском хозяйстве, дорожных работах, в качестве кровельного материала и т. п. -- производство предметов мебели из камня","Эта подгруппа не включает: -- деятельность, осуществляемую операторами карьеров, например добычу необработанного крупнорезанного камня, см. 1410 -- производство жерновов, абразивного камня и аналогичных изделий, см. 2699" -1580,"2695","Производство изделий из бетона, цемента и гипса","Эта подгруппа включает: -- производство готовых изделий из бетона, цемента или искусственного камня для использования в строительстве: -* черепицы, плитняка, кирпича, щитов, листов, панелей, труб, столбов и т. п. -- производство готовых конструкций из цемента, бетона или искусственного камня для строительства или гражданского строительства -- производство изделий из гипса для использования в строительстве: -* щитов, листов, панелей и т. п. -- производство строительных материалов из растительного сырья (древесной шерсти, соломы, камыша, тростника), смешанных с цементом, гипсом или другим минеральным связующим -- производство изделий из асбоцемента, целлюлозноволокнистого цемента или подобных материалов: -* гофрированных листов, прочих листов, панелей, черепицы, труб, трубок, резервуаров, желобов, чаш, отстойников, сосудов, мебели, оконных рам и т. п. -- производство прочих изделий из гипса, цемента или искусственного камня: -* скульптур, мебели, барельефов и горельефов, ваз, цветочных горшков и т. п. -- производство порошкообразных строительных растворов -- производство готовых и сухих строительных растворов и бетона","Эта подгруппа не включает: -* производство огнеупорных цементов и строительных растворов, см. 2692" -1570,"2694","Производство цемента, извести и штукатурки","Эта подгруппа включает: -- производство клинкеров и гидравлического цемента, в том числе портландцемента, глиноземного, шлакового и суперфосфатного цемента -- производство негашеной, гашеной и гидравлической извести -- производство штукатурки из кальцинированного гипса или сульфата кальция -- производство кальцинированного доломита","Эта подгруппа не включает: -- производство цементов, используемых в стоматологии, см. 2423 -- производство огнеупорных строительных растворов, цементов и т. п., см. 2692 -- производство изделий из бетона, см. 2695 -- производство изделий из гипса, см. 2695 -- производство готовых и сухих строительных растворов и бетона, см. 2695" -1560,"2693","Производство строительных неогнеупорных глиняных и керамических изделий","Эта подгруппа включает: -- производство неогнеупорного кафеля для пола и стен, мозаичной брусчатки и т. п. -- производство керамического плитняка и дорожного покрытия -- производство строительных неогнеупорных керамических материалов: -* производство керамического кирпича, кровельной черепицы, дефлекторов, труб, трубок, трубопроводов и т. п. -- производство керамических напольных плит","Эта подгруппа не включает: -- производство нестроительных неогнеупорных керамических изделий, см. 2691 -- производство огнеупорных керамических изделий, см. 2692" -1550,"2692","Производство огнеупорных керамических изделий","Эта подгруппа включает: -- производство огнеупорных строительных растворов, цементов и т. п. -- производство огнеупорных керамических изделий: -* теплоизоляционных керамических изделий, изготавливаемых из ископаемого кремнеземного сырья -* огнеупорного кирпича, блоков и плитки -* реторт, тигелей, муфелей, форсунок, труб, трубок и т. д. - -Эта подгруппа также включает: -- производство огнеупорных изделий, содержащих магнезит, доломит или хромит","Эта подгруппа не включает: -- производство неогнеупорных керамических изделий, см. 2691, 2693" -1540,"2691","Производство нестроительных неогнеупорных керамических изделий","Эта подгруппа включает: -- производство столовой посуды и других бытовых изделий или туалетных принадлежностей -- производство статуэток и прочих декоративных керамических изделий -- производство электроизоляторов и керамической изоляционной арматуры -- производство керамических лабораторных, химических и промышленных товаров -- производство керамических горшков, кувшинов и прочих подобных предметов, используемых для транспортировки или хранения товаров -- производство керамической мебели -- производство керамических изделий, не включенных в другие категории","Эта подгруппа не включает: -- производство огнеупорных керамических изделий, см. 2692 -- производство строительных керамических материалов, см. 2693 -- производство искусственных зубов, см. 3311 -- производство керамических игрушек, см. 3694 -- производство бижутерии, см. 3699" -1100,"2101","Производство целлюлозы, бумаги и картона","Эта подгруппа включает: -- производство беленой, полубеленой или небеленой целлюлозы механическими, химическими (растворимыми или нерастворимыми) или полухимическими методами -- производство целлюлозы из хлопкового пуха -- удаление типографской краски и производство целлюлозы из макулатуры -- производство бумаги и картона, предназначенных для дальнейшей промышленной обработки - -Эта подгруппа также включает: -- дальнейшую обработку бумаги и картона: -* поверхностную обработку, нанесение покрытия или пропитку бумаги и картона -* производство крепированной или мятой бумаги -- ручное изготовление бумаги -- производство газетной бумаги или бумаги для прочей типографской печати или письма -- производство целлюлозной ваты и полотен из целлюлозных волокон","Эта подгруппа не включает: -- производство гофрированных бумаги и картона, см. 2102 -- производство других изделий из бумаги, картона или целлюлозы, см. 2109 -- производство наждачной бумаги, см. 2699 -- производство бумаги с покрытием или пропиткой, когда покрытие или пропитка являются главным составным компонентом, см. подгруппу, в которой классифицируется производство покрытия или пропитки" -1090,"210","Производство бумаги и изделий из бумаги",, -1080,"21","Производство бумаги и изделий из бумаги","В этот подраздел включены производство технической целлюлозы, бумаги и изделий из обработанной бумаги. Изготовление этих изделий сгруппировано в один подраздел, поскольку они составляют последовательность вертикально связанных между собой процессов. Как правило, на одном производстве выполняется более одного вида деятельности. Существуют три основных вида деятельности. Производство целлюлозы включает отделение целлюлозных волокон от других веществ, присутствующих в древесной пульпе или использованной бумаге. Производство бумаги включает выкладку волокон целлюлозы в виде листов. Бумажные изделия изготавливаются из бумаги и других материалов с помощью различных способов резки и придания формы, включая нанесение покрытий и ламинирование. На бумажные изделия может быть нанесена декоративная печать (например, при изготовлении обоев, оберточной бумаги для подарков и т. п.), главной целью при этом не является печатание информации. -Производство целлюлозы, бумаги и картона большими партиями включено в подгруппу 2101, в другие подгруппы включено производство обработанной бумаги и изделий из бумаги.", -1070,"2029","Производство прочих деревянных изделий; производство изделий из пробки, соломки и плетенки","Эта подгруппа включает: -- производство различных деревянных изделий: -* деревянных ручек и корпусов для инструмента, метел и щеток -* деревянных обувных колодок и растяжек, одежных плечиков -* предметов домашнего обихода и кухонной утвари из дерева -* деревянных статуэток и декоративных изделий, деревянной инкрустации и мозаики -* деревянных шкатулок для ювелирных украшений и ножевых изделий и аналогичных изделий из точеной древесины -* деревянных шпулек, крышек, бобин, катушек для швейных ниток и аналогичных изделий из точеной древесины -* прочих деревянных изделий -- обработку натуральной пробки, производство прессованной пробковой крошки -- производство изделий из натуральной пробки или прессованной пробковой крошки -- производство плетенки и изделий из материалов для плетения: матов, циновок, ширм, коробок и т. п. -- производство корзин и плетеных изделий","Эта подгруппа не включает: -- производство матов и циновок из текстильных материалов, см. 1722 -- производство чемоданов, см. 1912 -- производство деревянной обуви, см. 1920 -- производство деревянных катушек и бобин, являющихся деталями текстильных машин, см. 2926 -- производство часовых корпусов, см. 3330 -- производство мебели, см. 3610 -- производство деревянных игрушек, см. 3694 -- производство метел и щеток, см. 3699 -- производство тростей и деревянных ручек для зонтов, см. 3699 -- производство спичек, см. 3699 -- производство шкатулок, см. 3699" -1060,"2023","Производство деревянной тары","Эта подгруппа включает: -- производство упаковочных ящиков, коробок, клетей, бочек и аналогичной деревянной тары -- производство грузовых поддонов, ящичных поддонов и прочих деревянных грузовых платформ -- производство чанов, кадок, бадей и прочих бондарных изделий из дерева -- производство деревянных барабанов для намотки кабеля","Эта подгруппа не включает: -- производство деревянных чемоданов, см. 1912 -- производство коробок из плетенки, см. 2029" -1050,"2022","Производство деревянных строительных конструкций и деталей","Эта подгруппа включает: -- производство деревянных изделий, предназначенных для использования преимущественно в строительной промышленности: -* балок, стропил, поперечин для крыши -* клеевых ламинированных и предварительно изготовленных деревянных ферм -* дверей, оконных конструкций, ставней и рам для них, содержащих или не содержащих металлическую арматуру, такую как петли, запоры и т. п. -* лестниц, перил -* деревянных калевок и багета, кровельной дранки и гонта -* паркетных блоков для покрытия полов, досок и т. п., набранных в виде панелей -- производство сборных домов, преимущественно из дерева, или их элементов","Эта подгруппа не включает: -- производство сборных деревянных покрытий для полов, см. 2010 -- производство кухонной встроенной мебели, книжных шкафов, гардеробов и т. п., см. 3610" -1040,"2021","Производство лущеного шпона; производство (клееной) фанеры, ламинированной плиты, древесно-стружечной плиты и прочих панелей и плит","Эта подгруппа включает: -- производство лущеного шпона, достаточно тонкого для использования в фанеровании и в производстве многослойной фанеры, а также для других целей: -* с выровненной поверхностью, окрашенного, с пропиткой, с упрочнением (бумажной или тканевой основой) -* изготовленного в форме узоров -- производство клееной фанеры, фанерованных панелей и аналогичной ламинированной древесины в виде досок и листов -- производство древесно-стружечных и древесно-волокнистых плит -- производство уплотненной древесины", -1030,"202","Производство изделий из дерева, пробки, соломки и плетенки",, -1020,"2010","Лесопильное и строгальное производство","Эта подгруппа включает: -- распиловку, строгание и механическую обработку древесины -- продольную или поперечную распиловку бревен, окорку и переработку в щепу -- производство деревянных железнодорожных шпал -- производство сборных покрытий для пола -- производство древесной массы, древесной муки, стружек, опилок - -Эта подгруппа также включает: -- сушку лесоматериалов -- пропитку или химическую обработку древесины консервантами или другими веществами","Эта подгруппа не включает: -- заготовку леса, производство сырой древесины, см. 0200 -- производство лущеного шпона, достаточно тонкого для использования в производстве фанеры, досок и панелей, см. 2021 -- производство кровельной дранки и гонта, калевок и багета, см. 2022" -1010,"201","Лесопильное и строгальное производство",, -1000,"20","Производство древесины и деревянных и пробковых изделий, кроме мебели; производство изделий из соломки и плетенки","Этот подраздел включает производство деревянных изделий, таких как пиломатериалы, фанера, шпон, деревянная тара, деревянные покрытия для пола, деревянные фермы и сборные деревянные строения из предварительно изготовленных компонентов. Производственные процессы включают распиловку, строгание, фасонирование, ламинирование и сборку деревянных изделий, начиная от необработанного лесоматериала, который разрезается на короткие бревна, или пиломатериалов, которые могут подвергаться последующей распиловке или им может придаваться определенная форма обточкой на токарных станках или обработкой другими инструментами. Пиломатериал или обработанный лесоматериал другого вида может подвергаться также последующему строганию или шлифованию и собираться в готовые изделия, такие как деревянная тара. -За исключением пилорам и предприятий по хранению лесоматериалов, предприятия группируются по отраслям, в основном исходя из того, какие конкретно изделия они производят. -Данный подраздел не включает производство мебели (3610), установку деревянных крепежных изделий, изготовленных не на том же предприятии, и аналогичные виды деятельности (4540).", -990,"1920","Производство обуви","Эта подгруппа включает: -- производство обуви для всех целей, из любого материала, с помощью любого процесса, включая формование -- производство гетр, краг и аналогичных изделий -- производство деталей обуви: изготовление верха обуви и деталей верха, подошвы, стельки, каблуков и т. п.","Эта подгруппа не включает: -- производство обуви из текстильного материала без наложенной подошвы, см. 1810 -- производство обуви из асбеста, см. 2699 -- производство ортопедической обуви, см. 3311" -980,"192","Производство обуви",, -970,"1912","Производство чемоданов, сумок и аналогичных изделий, шорно-седельных изделий","Эта подгруппа включает: -- производство чемоданов, сумок и аналогичных изделий из кожи, составной кожи или другого материала, такого как листовая пластмасса, текстильные материалы, вулканизированное волокно или картон, когда при изготовлении этих изделий используется такая же технология, как при изготовлении изделий из кожи -- производство шорно-седельных изделий -- производство ремешков для наручных часов из неметаллических материалов -- производство разнообразных изделий из кожи или составной кожи: движущиеся ленты, упаковки и т. п.","Эта подгруппа не включает: -- производство кожаной одежды, см. 1810 -- производство кожаных перчаток и головных уборов, см. 1810 -- производство обуви, см. 1920 -- производство металлических браслетов для наручных часов, см. 3330 -- производство велосипедных седел, см. 3592" -960,"1911","Дубление и выделка кожи","Эта подгруппа включает: -- производство дубленой кожи -- производство кожи замшевой выделки, пергаментной выделки или лакированной и металлизированной кожи -- производство составной кожи","Эта подгруппа не включает: -- производство сырых шкур и кож на фермах, см. 0122 -- производство сырых шкур и кож в ходе деятельности скотобоен, см. 1511 -- производство кожаной одежды, см. 1810 -- дубление и выделку меховых шкурок или шкур с волосяным покровом, см. 1820 -- производство искусственной кожи не на основе натуральной кожи, см. 1711, 2519, 2520" -950,"191","Дубление и выделка кожи; производство чемоданов, сумок, шорно-седельных изделий",, -940,"19","Дубление и выделка кожи; производство чемоданов, сумок, шорно-седельных изделий и обуви","Эта подгруппа включает переработку шкур в кожу посредством дубления или просаливания и производство из кожи изделий для конечного потребления. Эта подгруппа также включает производство аналогичных изделий из других материалов (искусственной кожи или кожзаменителей), таких как резиновая обувь, чемоданы из текстильных материалов и т. п. Сюда же включены изделия из кожзаменителей, поскольку они изготовлены теми же способами, которые используются для изготовления изделий из натуральной кожи (например, чемоданов) и часто производятся на том же предприятии.", -930,"1820","Выделка и крашение меха; производство меховых изделий","Эта подгруппа включает: -- выделку и окраску меховых шкурок и кожи с волосяным покровом на ней: мездрение, жирование, дубление, отбеливание, стрижка и щипка с последующей окраской пушных шкурок -- производство меховых изделий: -* меховой одежды и дополнительных предметов одежды -* составные меховые шкуры, такие как ""опущенные"" меховые шкуры, пластины, коврики, полоски и т. п. -* разнообразные изделия из меховых шкур: ковры, пуфики, промышленные полировальные материалы - -Эта подгруппа также включает: -- производство искусственного меха и изделий из него","Эта подгруппа не включает: -- производство меховых шкурок, см. 0122, 0150 -- производство сырых шкур и кож, см. 1511 -- производство искусственного меха (ткань с длинным ворсом из тканых или трикотажных материалов), см. 1711, 1712, 1730 -- производство меховых головных уборов, см. 1810 -- производство одежды, отделанной мехом, см. 1810 -- производство ботинок или туфель с деталями из меха, см. 1920" -920,"182","Выделка и крашение меха; производство меховых изделий",, -910,"1810","Производство одежды, кроме меховой одежды","Эта подгруппа включает производство одежды из материала не собственного производства. Используемый материал может быть любого рода и может быть с покрытием, с пропиткой или прорезиненный. -Эта подгруппа включает: -- производство одежды из кожи или кожзаменителя -- производство рабочей одежды -- производство другой верхней одежды из шерстяной, трикотажной или вязаной ткани, нетканых материалов и т. п. для мужчин, женщин и детей: -* пальто, костюмов, комплектов одежды, пиджаков и жакетов, брюк, рубашек и т. п. -- производство нижнего и спального белья из шерстяной, трикотажной или вязаной ткани, кружевной и другой ткани для мужчин, женщин и детей: -* рубашек, футболок, кальсон, трусов, пижам, ночных рубашек, домашних халатов, блузок, комбинаций, бюстгальтеров, корсетов и т. п. -- производство детской одежды, спортивных костюмов, лыжных костюмов, одежды для плавания и т. п. -- производство шляп и шапок -- производство других дополнительных предметов одежды: перчаток, поясов, платков, галстуков, шарфов, сеток для волос и т. п. - -Эта подгруппа также включает: -- пошив одежды на заказ -- производство головных уборов из меха -- производство обуви из текстильного материала без наложенной подошвы -- производство частей перечисленных изделий","Эта подгруппа не включает: -- производство одежды из трикотажных тканей, изготовленных на том же предприятии, см. 1730 -- производство одежды из меховых шкур (кроме головных уборов), см. 1820 -- производство обуви, см. 1920 -- производство одежды из резины или пластмассы путем не сшивания, а простого склеивания, см. 2519, 2520 -- производство защитных головных уборов (за исключением спортивных шлемов), см. 2520, 2899 -- производство одежды из асбеста, включая шлемы, см. 2699 -- производство кожаных спортивных перчаток и спортивных головных уборов, см. 3693 -- ремонт одежды, см. 5260" -900,"181","Производство одежды, кроме меховой одежды",, -890,"18","Производство одежды; выделка и крашение меха","Швейная промышленность охватывает все направления пошива верхнего платья (готовые к ношению или сшитые по мерке) из любого материала (например, кожи, ткани тканой, трикотажной или вязаной и т. п.), любых предметов одежды (например, верхней одежды, нижнего белья для мужчин, женщин и детей и т. п.; спецодежды, выходной или повседневной одежды и т. п.) и дополнительных предметов одежды из материалов, не изготавливаемых на том же предприятии. Различие между одеждой для взрослых и одеждой для детей или между современной и традиционной одеждой не проводится. Подраздел 18 также включает меховую отрасль (пушные шкурки и меховая одежда).", -880,"1730","Производство трикотажных и вязаных тканей и изделий","Эта подгруппа включает: -- производство и обработку трикотажных или вязаных тканей, изготовленных на том же предприятии: -* ворсового и плюшевого трикотажного полотна -* сетчатых тканей и тканей для оконных занавесей, связанных на рашель-машинах или аналогичных станках -* других трикотажных или вязаных тканей -- производство чулочных изделий, включая носки, колготки и рейтузы -- производство трикотажной и вязаной одежды и других готовых изделий, которым форма придается непосредственно в процессе изготовления: пуловеров, кардиганов, теннисок, жилетов и других аналогичных изделий - -Эта подгруппа также включает: -- производство искусственного меха вязанием","Эта подгруппа не включает: -- производство кружевных сетчатых тканей и тканей для оконных занавесей, связанных на рашель-машинах или аналогичных станках, см. 1729 -- производство трикотажной одежды из трикотажных тканей, изготовленных не на том же предприятии, см. 1810" -870,"173","Производство трикотажных и вязаных тканей и изделий",, -860,"1729","Производство прочих текстильных изделий, не включенных в другие категории","Эта подгруппа включает все виды деятельности, связанные с производством текстильных изделий или продуктов, не включенных в другие категории подразделов 17 или 18 или каких-либо других подразделов данной классификации, в том числе большое число различных процессов и самых разнообразных производимых товаров. - -Эта подгруппа включает: -- производство узких тканых тканей, в том числе состоящих из основы без уточного переплетения и соединяемых клеящим веществом -- производство этикеток, опознавательных значков и нашивок и т. п. -- производство декоративных отделочных изделий: тесьмы, кистей, помпонов и аналогичных изделий -- производство войлока -- производство тюля и других сетчатых тканей, кружевных изделий, кружевных полос и отдельных узоров, вышивки, украшений на одежде -- производство тканей с пропиткой, покрытием, поверхностным слоем или с прослойкой из пластмассы -- производство ваты из текстильных материалов и изделий из ваты: гигиенических салфеток, тампонов и т. п. -- производство металлизированной пряжи и позументной нити, резиновой нити или корда с покрытием из текстильного материала, текстильной пряжи или полос с покрытием, пропиткой или обмоткой оболочкой из резины или пластмассы -- производство готовых текстильных изделий из тканей собственного производства данной подгруппы -- производство шинного корда из высокопрочной искусственной пряжи -- производство других тканей с обработкой или покрытием: полотняной кальки, грунтованного холста для нужд художников, лощенок и аналогичных уплотненных текстильных тканей, тканей со смолистым или крахмалистым покрытием -- производство разнообразных текстильных изделий: текстильных фитилей, газокалильных сеток и круглого трикотажного полотна для калильных сеток, шлангов, лент и ремней для конвейеров и транспортеров (армированных или не армированных металлом или другими материалами), тканей для сит, фильтровальной ткани","Эта подгруппа не включает: -- производство вязанных крючком войлочных покрытий для полов, см. 1722 -- производство лент и ремней для конвейеров и транспортеров из текстильной ткани или из текстильной пряжи или корда с пропиткой, покрытием, верхним слоем или прослойкой из резины, когда основным компонентом является резина, см. 2519 -- производство пластин или листов из пористой резины или пластмассы в сочетании с текстилем, используемым только для укрепления, см. 2519, 2520 -- производство тканей из металлической проволоки, см. 2899" -850,"1723","Производство каната, веревки, шпагата и сетного полотна","Эта подгруппа включает: -- производство шпагата, каната, веревки и тросов из текстильного волокна, лент и аналогичных материалов, водоотталкивающих или намокающих, с покрытием или без покрытия, защищенных или не защищенных оболочкой из резины или пластмассы -- производство сетного полотна из шпагата, каната или веревки -- производство изделий из веревки или сетного полотна: рыболовных сетей, предохранительных сетей на судах, амортизаторов, используемых при разгрузке, такелажных петель для подвески груза, веревок или тросов с металлическими кольцами и т. п.","Эта подгруппа не включает: -- производство сеток для волос, см. 1810" -840,"1722","Производство ковров и ковровых изделий","Эта подгруппа включает: -- производство текстильных покрытий для полов: -* ковров, ковриков и циновок, ковровой плитки - -Эта подгруппа также включает: -- производство вязанных крючком войлочных ковровых покрытий","Эта подгруппа не включает: -- производство циновок и кошм из материалов для плетения, см. 2029 -- производство покрытий для полов из пробки, резины или пластмасс, даже при наличии текстильной основы, см. 2029, 2519, 2520 -- производство линолеума и других твердых покрытий с непластмассовой поверхностью для полов, см. 3699" -830,"1721","Производство готовых текстильных изделий, кроме одежды","Эта подгруппа включает: -- производство из тканей несобственного производства готовых изделий из любого текстильного материала, включая трикотажные или вязаные ткани: -* одеяла, включая дорожные пледы -* постельное белье, скатерти, банные и кухонные полотенца из льняного полотна -* ватные стеганые одеяла, стеганые пуховые одеяла, диванные подушки, пуфы, подушки, спальные мешки и т. п. -- производство готовых предметов меблировки: -* портьер, гардин, штор, постельных покрывал, чехлов для мебели или технических изделий и т. п. -* брезентовых покрышек, палаток, товаров для кемпинга, парусов, солнцезащитных жалюзи, чехлов-накидок для автомобилей, машин или мебели и т. п. -* флагов, знамен, вымпелов и т. п. -* тряпок для уборки пыли, посудных полотенец и аналогичных изделий, спасательных жилетов, парашютов и т. п. - -Эта подгруппа также включает: -- производство текстильных частей электроодеял -- производство ковровых изделий ручной выработки","Эта подгруппа не включает: -- производство текстильных изделий на том же предприятии, которое производит текстильные материалы, см. 1711, 1729 и 1730 -- производство текстильных изделий для технических нужд, см. 1729" -820,"172","Производство прочих текстильных изделий",, -810,"1712","Отделка тканей","Эта подгруппа включает: -- отбелку, крашение и набивку (включая термопечать) изготовленных другими производителями текстильного волокна, пряжи, тканей и текстильных изделий, включая предметы одежды -- аппретирование, сушку, обработку паром, декатировку, штопку, безусадочную отделку, мерсеризацию изготовленных другими производителями ткани и текстильных изделий, включая предметы одежды - -Эта подгруппа также включает: -- отбелку джинсовой ткани -- плиссировку и аналогичные работы на тканях","Эта подгруппа не включает: -- производство тканей, пропитанных, грунтованных, покрытых или ламинированных резиной, в которой основным компонентом является каучук, см. 2519 -- набивку текстильных изделий в присутствии заказчика, см. 5260" -800,"1711","Подготовка и прядение текстильного волокна; изготовление текстильных изделий","Эта подгруппа включает: -- операции по подготовке текстильного волокна: -* перемотку и промывку шелка -* обезжиривание и карбонизацию шерсти, окраску руна -* кардочесание и гребнечесание всех видов волокна растительного или животного происхождения, а также искусственного волокна -- прядение и изготовление пряжи и ниток для производства тканей или шитья, для торговли или дальнейшей переработки -* текстурирование, кручение, дублирование, вязание ""косичкой"" и пропитку пряжи из синтетического или искусственного волокна -- производство широких тканей их хлопковых, шерстяных, камвольных или шелковых тканей, включая ткани из смешанного волокна, искусственной или синтетической пряжи -- производство других широких тканей с использованием волокон льна, рами, конопли, джута, лубяного волокна и пряжи специального назначения -- производство готовых текстильных изделий из тканей собственного производства - -Эта подгруппа также включает: -- производство бумажной пряжи -- производство ворсовой или шинельной ткани, махрового полотна, марли и т. п. -- производство тканых стекловолокнистых материалов -- производство тканого искусственного меха","Эта подгруппа не включает: -- операции по подготовке, осуществляемые в сочетании с сельскохозяйственными или фермерскими работами, см. 01, 02 -- мочку растений, содержащих растительное текстильное волокно (джут, лен, кокосовое волокно и т. п.), см. 0111 -- очистку хлопка от семян, см. 0140 -- производство текстильных изделий для полов, см. 1722 -- производство нетканого полотна и войлока, см. 1729 -- производство узких тканей, см. 1729 -- производство трикотажных и вязаных изделий, см. 1730 -- производство синтетического или искусственного волокна и очесов из них, производство одинарной пряжи (включая высокопрочную пряжу и пряжу для ковров) из синтетического или искусственного волокна, см. 2430 -- производство стекловолокна, см. 2610 -- изготовление асбестовой пряжи, см. 2699" -790,"171","Прядильное, ткацкое и отделочное производство",, -780,"17","Производство текстильных изделий","Этот подраздел включает подготовку и прядение текстильных волокон, а также изготовление текстиля, отделку текстиля и одежды, производство готовых текстильных изделий, кроме одежды (например, столового белья, одеял, ковров и т. п.), и производство вязаных трикотажных тканей и изделий из них (например, носков и свитеров). Выращивание растений для получения натуральных волокон относится к подразделу 01, а производство синтетических волокон является химическим процессом, который должен классифицироваться в подгруппе 2430. Производство одежды относится к подразделу 18.", -770,"1600","Производство табачных изделий","Эта подгруппа включает: -- производство табачных изделий и изделий, являющихся заменителями табака: сигарет, сигаретного табака, сигар, трубочного табака, жевательного табака, нюхательного табака -- производство ""гомогенизированного"" или ""восстановленного"" табака","Эта подгруппа не включает: -- выращивание или предварительную обработку табачного листа, см. 0111" -760,"160","Производство табачных изделий",, -750,"16","Производство табачных изделий","Этот подраздел включает обработку сельскохозяйственного продукта - табака - в форму, пригодную для конечного потребления.", -740,"1554","Производство безалкогольных напитков; разлив минеральной воды по бутылкам","Эта подгруппа включает: -- производство безалкогольных напитков, кроме безалкогольных пива и вина -- производство, то есть разлив в бутылки у источника, минеральной воды -- производство безалкогольных напитков: -* безалкогольных ароматизированных и/или подслащенных напитков на основе воды: лимонада, оранжада, колы, фруктовых напитков, тонизирующих напитков и т. п.","Эта подгруппа не включает: -- производство фруктового и овощного сока, см. 1513 -- производство безалкогольного вина, см. 1552 -- производство безалкогольного пива, см. 1553 -- простой разлив и этикетирование, см. 5122 (если является частью оптовой торговли) и 7495 (если выполняется за вознаграждение или на договорной основе)" -730,"1553","Производство напитков из солода и производство солода","Эта подгруппа включает: -- производство напитков из солода, таких как пиво, эль, портер и крепкий портер -- производство солода - -Эта подгруппа также включает: -- производство безалкогольного пива и пива с низким содержанием алкоголя", -720,"1552","Производство вин","Эта подгруппа включает: -- производство вин из винограда, который не был выращен данным хозяйством -- производство игристых вин -- производство вина из концентрированного виноградного муста -- производство сброженных, но не дистиллированных алкогольных напитков: сакэ, сидра, перри, медового напитка, других фруктовых вин и составных напитков, содержащих алкоголь -- производство вермута и других ароматизированных вин - -Эта подгруппа также включает: -- купажирование вина -- производство безалкогольного вина и вина с низким содержанием алкоголя","Эта подгруппа не включает: -- производство вина в той же местности, в которой выращивается виноград, см. 0113 -- простой разлив и этикетирование, см. 5122 (если является частью оптовой торговли) и 7495 (если выполняется за вознаграждение или на договорной основе)" -710,"1551","Дистилляция, ректификация и смешивание спиртных напитков; производство этилового спирта из сброженных материалов","Эта подгруппа включает: -- производство дистиллированных алкогольных напитков: виски, бренди, джина, ликеров, коктейлей и т. п. -- производство составных спиртных напитков -- производство этилового спирта из сброженных материалов -- производство нейтральных спиртов","Эта подгруппа не включает: -- производство недистиллированных алкогольных напитков, см. 1552, 1553 -- производство денатурированного этилового спирта, см. 2411 -- простой разлив и этикетирование, см. 5122 (если является частью оптовой торговли) и 7495 (если выполняется за вознаграждение или на договорной основе)" -700,"155","Производство напитков",, -690,"1549","Производство прочих пищевых продуктов, не включенных в другие категории","Эта подгруппа включает: -- извлечение кофеина из кофе и обжаривание кофейных зерен -- производство кофейных продуктов: -* молотого кофе -* растворимого кофе -* экстрактов и концентратов кофе -- производство заменителей кофе -- приготовление чайных смесей и матэ -- упаковывание чая, включая упаковывание чая в пакетики -- производство супов и бульонов -- производство пряностей, соусов и приправ: -* майонеза -* горчичного порошка и горчичной муки -* готовой горчицы и т. п. -- производство уксуса -- производство пищевых продуктов особого назначения: -* смесей для питания младенцев -* полуфабрикатов молочных и других продуктов питания для прикорма -* детского питания -* других пищевых продуктов, содержащих гомогенизированные ингредиенты (включая мясо, рыбу, фрукты и т. п.) -- производство искусственного меда и карамели -- производство свежей или замороженной пиццы -- производство замороженных блюд из мяса и домашней птицы -- производство блюд из тушеного мяса в консервных банках и блюд, приготовленных в вакууме - -Эта подгруппа также включает: -- производство добавок из трав (мяты, вербены, ромашки и т. п.) -- производство дрожжей -- производство экстрактов и соков из мяса, рыбы, ракообразных и моллюсков -- производство искусственных заменителей молока и сыра","Эта подгруппа не включает: -- выращивание культур, используемых в качестве приправ, см. 0113 -- производство столовой соли, см. 1422 -- производство замороженных рыбных блюд, включая рыбу целиком и нарезанные кусочки, см. 1512 -- производство инулина, см. 1532 -- производство добавок из трав, если они считаются товарами медицинского назначения, см. 2423" -1530,"269","Производство неметаллических минеральных продуктов, не включенных в другие категории",, -1520,"2610","Производство стекла и изделий из стекла","Эта подгруппа включает все методы производства стекла во всех его формах и изделий из стекла. - -Эта подгруппа включает: -- производство плоского стекла, в том числе армированного, цветного или подцвеченного плоского стекла -- производство небьющегося или слоистого стекла -- производство стекла в виде дротов или труб -- производство стеклянной брусчатки -- производство стеклянных зеркал -- производство изоляционных стеклянных изделий с несколькими стенками -- производство бутылей и других стеклянных или хрустальных сосудов -- производство питьевых стаканов и прочих бытовых стеклянных или хрустальных изделий -- производство стекловолокна, в том числе стекловаты и нетканых изделий из стеклянной пряжи -- производство лабораторного, гигиенического или фармацевтического стеклянного оборудования -- производство стекол для наручных и прочих часов, оптического стекла и оптических стеклянных элементов, не прошедших оптической обработки -- производство стеклянных деталей, используемых при изготовлении бижутерии -- производство изоляционных стеклянных изделий и стеклянной изоляционной арматуры -- производство стеклянных колб для ламп","Эта подгруппа не включает: -- производство тканых тканей из стеклянной пряжи, см. 1711 -- производство оптоволоконных кабелей для передачи кодированных данных, см. 3130 -- производство шприцев и прочего медицинского лабораторного оборудования, см. 3311 -- производство оптических элементов, прошедших оптическую обработку, см. 3320 -- производство оптических волокон и оптоволоконных кабелей для прямой передачи изображений, см. 3320 -- производство игрушек из стекла, см. 3694" -1510,"261","Производство стекла и изделий из стекла",, -1500,"26","Производство прочих неметаллических минеральных продуктов","В этом подразделе объединены различные виды производства, которые имеют отношение к тому или иному веществу минерального происхождения. Данный подраздел охватывает производство стекла и изделий из стекла (например, плоского стекла, пустотелого стекла, стекловолокна, технического стекла и т. п.), а также производство керамических изделий, кафеля и огнеупорных глиняных изделий, цемента и штукатурки, начиная с производства сырья и заканчивая готовыми изделиями. Этот подраздел включает также фасонирование и отделку камней и производство прочих минеральных продуктов.", -1490,"2520","Производство пластмассовых изделий","Эта подгруппа включает: -- производство полуфабрикатов из пластмассы: -* пластмассовых плит, листов, блоков, пленки, фольги, полос и т. п. (самоклеющихся или нет) -- производство готовых пластмассовых изделий: -* пластмассовых труб, трубок и шлангов; фитингов для труб и шлангов -- производство пластмассовых изделий для упаковки товаров: -* пластиковых сумок, мешков, контейнеров, коробок, ящиков, оплетенных бутылок, бутылей и т. д. -- производство строительного пластмассового оборудования: -* пластиковых дверей, окон, рам, ставней, жалюзи, плинтусов -* канистр, емкостей -* пластмассовых покрытий для полов, стен и потолков в рулонах или в виде плиток и т. п. -* пластмассового санитарного оборудования: -* пластмассовых ванн, душевых кабин, раковин, унитазов, водосливных бачков и т. п. -- производство пластмассовой посуды, кухонной утвари и туалетных принадлежностей -- производство разнообразных пластмассовых изделий: -* пластмассовых головных уборов, изоляционных прокладок, частей осветительной арматуры, канцелярских и школьных принадлежностей, предметов одежды (стыкованной, а не прошитой по швам), арматуры для мебели, статуэток, приводных ремней и транспортерных лент и т. п.","Эта подгруппа не включает: -- производство пластиковых чемоданов, см. 1912 -- производство пластиковой обуви, см. 1920 -- производство пластмасс в первичных формах, см. 2413 -- производство предметов из синтетического и натурального каучука, см. 251 -- производство пластиковых медицинских и зубоврачебных приспособлений, см. 3311 -- производство пластмассовых оптических элементов, см. 3320 -- производство пластиковой мебели, см. 3610 -- производство безобтяжных матрацев из пористой пластмассы, см. 3610 -- производство пластмассового спортивного инвентаря, см. 3693 -- производство пластмассовых игр и игрушек, см. 3694 -- производство линолеума и твердых непластиковых покрытий для полов, см. 3699" -1480,"252","Производство пластмассовых изделий",, -1470,"2519","Производство прочих резиновых изделий","Эта подгруппа включает: -- производство прочих изделий из натурального или синтетического каучука и изделий из невулканизированной, вулканизированной или упрочненной резины: -* резиновых плит, листов, полос, брусов и профилей -* труб, трубок и шлангов -* резиновых приводных ремней и транспортерных лент -* резиновых санитарно-гигиенических или фармацевтических изделий: презервативов, сосок, грелок и т. п. -* предметов одежды из резины (если они склеены, а не прошиты по швам) -* резиновых покрытий для полов -* резиновых нитей и веревки -* прорезиненной пряжи и ткани -* резиновых колец, прокладок и уплотнителей -* резиновых роликовых покрытий -* надувных резиновых матрацев -* надувных шаров - -Эта подгруппа также включает: -- производство резиновых материалов для ремонта -- производство текстильных изделий, пропитанных, обработанных, покрытых или ламинированных резиной, в которых резина является главным компонентом","Эта подгруппа не включает: -- производство волокон для кордовых покрышек, см. 1729 -- производство одежды из эластичного волокна, см. 1810 -- производство резиновой обуви, см. 1920 -- производство клея и клеящих веществ на резиновой основе, см. 2429 -- производство выпуклых заготовок для протекторов, см. 2511 -- производство надувных плотов и лодок, см. 3511, 3512 -- производство безобтяжных матрацев из пористой резины, см. 3610 -- производство спортивного инвентаря из резины, кроме одежды, см. 3693 -- производство игр и игрушек из резины, см. 3694 -- регенерацию резины, см. 3720" -1460,"2511","Производство резиновых покрышек и камер; возобновление и восстановление резиновых покрышек","Эта подгруппа включает: -- производство резиновых автомобильных покрышек, используемых на оборудовании, передвижных машинах, самолетах, игрушках, мебели или для других целей: -* пневматических шин -* цельных или бескамерных шин -- производство камер для покрышек -- производство взаимозаменяемых протекторов, флепов, выпуклых заготовок для возобновления протекторов покрышек и т. п. -- восстановление и возобновление покрышек","Эта подгруппа не включает: -- производство материалов для ремонта камер, см. 2519 -- ремонт, вулканизацию или замену покрышек и камер, см. 5020" -1450,"251","Производство резиновых изделий",, -1440,"25","Производство резиновых и пластмассовых изделий","Предприятия по производству резиновых и пластмассовых изделий отличаются потребляемым в процессе производства видом сырья. Однако это не означает, что производство всех изделий из этого сырья будет обязательно относиться к данному виду деятельности. В частности, производство одежды и обуви классифицируется в подразделах 18 и 19 даже в тех случаях, когда основным материалом является резина или пластмасса.", -1430,"2430","Производство искусственных волокон","Эта подгруппа включает: -- производство искусственного или синтетического элементарного волокна -- производство искусственного или синтетического штапельного волокна, не прошедшего процессы кардочесания, гребнечесания или иной обработки для прядения -- производство синтетической или искусственной волокнистой пряжи, включая высокопрочную пряжу -- производство синтетических или искусственных одноволокнистых нитей или полос","Эта подгруппа не включает: -- прядение синтетических или искусственных волокон, см. 1711 -- производство искусственной штапельной пряжи, см. 1711 -- производство пряжи из волокон, очесов, штапеля или из пряжи несобственного производства, см. 1711" -1420,"243","Производство искусственных волокон",, -1410,"2429","Производство прочих химических продуктов, не включенных в другие категории","Эта подгруппа включает: -- производство порошкообразных взрывателей -- производство взрывчатых веществ и пиротехнических средств, включая ударные капсюли, детонаторы, сигнальные ракеты и т. д. -- производство желатина и производных желатина, клея и готовых клеящих веществ, в том числе клеев и клеящих веществ на резиновой основе -- производство экстрактов из природных ароматических продуктов -- производство душистых экстрактов -- производство ароматизированной дистиллированной воды -- производство смесей ароматических веществ для производства парфюмерных изделий или пищевых продуктов -- производство фотографических пластинок, пленок, светочувствительной бумаги и прочих светочувствительных неэкспонированных материалов -- производство химических препаратов для использования в фотографии -- производство носителей для аудио- и видеозаписи -- производство компьютерных дисков и лент без записей -- производство различных химических продуктов: -* пептонов, производных пептонов, прочих белковых соединений и их производных, не включенных в другие категории -* эфирных масел -* химически модифицированных масел и жиров -* материалов, используемых в отделке текстиля и кожи -* порошков и паст, используемых для традиционной и твердой пайки и сварки -* веществ, используемых для травления металла -* готовых добавок для цемента -* активированного угля, добавок для смазочных масел, готовых ускорителей процесса вулканизации, катализаторов и прочих химических продуктов промышленного назначения -* антидетонаторов, антифризов -* сложных диагностических или лабораторных реагентов - -Эта подгруппа также включает: -- производство чернил и туши -- производство химически переработанной соли","Эта подгруппа не включает: -- массовое производство продуктов с определенным химическим составом, см. 2411 -- производство синтетических ароматизированных продуктов, см. 2411 -- производство типографской краски, см. 2422 -- производство парфюмерной продукции и косметических средств, см. 2424 -- производство клеящих веществ на асфальтовой основе, см. 2699" -1400,"2424","Производство мыла и моющих средств, чистящих и полирующих препаратов, парфюмерной продукции и косметических средств","Эта подгруппа включает: -- производство мыла в виде брусков, кусков, формованных, нарезных, в жидком, пастообразном или другом виде -- производство органических поверхностно-активных веществ -- производство мыла -- производство бумаги, ваты, войлока и других материалов, обработанных или покрытых мылом или моющим средством -- производство неочищенного глицерина -- производство поверхностно-активных препаратов: -* стиральных порошков в твердой или жидкой форме и моющих средств -* средств для мытья посуды -* смягчителей ткани -- производство чистящих и полирующих средств: -* препаратов для освежения воздуха и устранения запахов в помещениях -* искусственных восков и готовых восков -* лаков и кремов для изделий из кожи -* лаков и кремов для изделий из дерева -* полирующих средств для кузовных работ, стекла и металла -* чистящих паст и порошков, в том числе в виде бумаги, войлока и т. п., пропитанных или покрытых этими средствами -- производство парфюмерной продукции и косметических средств: -* духов и туалетной воды -* косметических и гримировальных препаратов -* средств для загара и против загара -* препаратов для маникюра и педикюра -* шампуней, лаков для волос, составов для завивки или распрямления волос -* препаратов для гигиенического ухода за полостью рта и зубами, в том числе составов для фиксации зубных протезов -* препаратов для бритья, в том числе применяемых до и после бритья -* дезодорантов и солей для ванны -* депиляторов","Эта подгруппа не включает: -- производство отдельных соединений с определенным химическим составом, см. 2411 -- производство глицерина, синтезированного из нефтепродуктов, см. 2411 -- экстрагирование и очистку натуральных эфирных масел, см. 2429" -1390,"2423","Производство фармацевтических препаратов, медицинских химических веществ и лекарственных растительных продуктов","Эта подгруппа включает: -- производство активных медицинских веществ, используемых в силу их фармацевтических свойств при производстве медикаментов: антибиотиков, основных витаминов, салициловой или О-ацетилсалициловой кислоты и т. п. -- обработку крови -- производство медикаментов: -* антисывороток и других фракций крови -* вакцин -* различных медикаментов, включая гомеопатические препараты -- производство химических противозачаточных средств для наружного использования и гормональных противозачаточных средств -- производство пломбировочного материала и цемента для восстановления костной ткани -- производство медицинских диагностических препаратов, включая препараты для тестов на беременность - -Эта подгруппа также включает: -- производство химически чистого сахара -- обработку желез и производство экстрактов желез -- производство лекарственных повязок, марли, бандажей, перевязочного материала, хирургических ниток и т. п. -- изготовление растительных продуктов (измельченных, рассортированных, размолотых) для использования в фармацевтических целях","Эта подгруппа не включает: -- расфасовку фармацевтических товаров за собственный счет, см. 5139, 5231 -- расфасовку за вознаграждение или на договорной основе, см. 7495" -1380,"2422","Производство красок, олифы и аналогичных покрытий, типографской краски и мастик","Эта подгруппа включает: -- производство красок, олифы, эмалей и лаков -- производство готовых пигментов и красителей, замутнителей и красок -- производство стекловидных эмалей и глазурей, жидких глянцев и аналогичных составов -- производство мастик -- производство замазок и аналогичных неогнеупорных шпатлевок или грунтовок -- производство органических сложных растворителей и разбавителей -- производство готовых растворителей красок и лаков -- производство типографской краски","Эта подгруппа не включает: -- производство красок или красителей, пигментов и скипидара, см. 2411 -- производство чернил и туши, см. 2429" -1370,"2421","Производство пестицидов и прочих агрохимических продуктов","Эта подгруппа включает: -- производство инсектицидов, родентицидов, фунгицидов, гербицидов -- производство веществ, предотвращающих прорастание овощей, и регуляторов роста растений -- производство дезинфицирующих веществ (для сельскохозяйственного и других видов использования) -- производство прочих агрохимических продуктов, не включенных в другие категории","Эта подгруппа не включает: -- производство удобрений и азотных соединений, см. 2412" -1360,"242","Производство прочих химических продуктов",, -1350,"2413","Производство пластмасс в первичных формах и синтетического каучука","Эта подгруппа включает: -- производство пластмасс в первичных формах: -* полимеров, в том числе этилена, полипропилена, стирола, хлорвинила, ацетатвинила и акриловых полимеров -* полиамидов -* феноловых и эпоксидных смол и полиуретанов -* алкидных и полиэфирных смол и полиэфиров -* кремнийсодержащих соединений -* ионитов, основанных на полимерах -- производство синтетического каучука в первичных формах -* синтетического каучука -* пластификаторов -- производство смесей синтетического и натурального каучука и каучукообразных смол (например, балаты) - -Эта подгруппа также включает: -- производство целлюлозы и ее химических производных","Эта подгруппа не включает: -- производство искусственных и синтетических волокон, нитей и пряжи, см. 2430 -- вторичную переработку пластмасс, см. 3720" -1340,"2412","Производство удобрений и азотных соединений","Эта подгруппа включает: -- производство удобрений: -* чистых или сложных азотных, фосфорных или калийных удобрений -* мочевины, неочищенных природных фосфатов или неочищенных природных калийных солей -* компоста -- производство смежной азотсодержащей продукции: -* азотной и азотно-серной кислоты, аммиака, хлористого аммония, углекислого аммония, нитритов и нитратов калия","Эта подгруппа не включает: -- добычу гуано, см. 1421 -- производство агрохимических продуктов, таких как пестициды, см. 2421" -1330,"2411","Производство основных химических веществ, кроме удобрений и азотных соединений","Эта подгруппа включает: -- производство сжиженных или сжатых неорганических промышленных или медицинских газов: -* элементарных газов -* сжиженного или сжатого воздуха -* хладагентов -* смешанных промышленных газов -* инертных газов, таких как двуокись углерода -* изоляционных газов -- производство красителей и пигментов из любого источника в базовой форме или в виде концентрата -- производство химических элементов, кроме металлов и радиоактивных элементов, получаемых на предприятиях по производству ядерного топлива -- производство неорганических кислот, кроме азотной кислоты -- производство щелочей, щелока и других неорганических базовых соединений, кроме аммиака -- производство других неорганических соединений -- производство основных органических химических веществ: -* насыщенных и ненасыщенных нециклических углеводородов -* насыщенных и ненасыщенных циклических углеводородов -* нециклического и циклического спирта, включая синтетический этиловый спирт -* моно- и поликарбоксильных кислот, в том числе уксусной кислоты -* других кислородных соединений, включая альдегиды, кетоны, хиноны и двух- или поливалентные кислородные соединения -* синтетического глицерина -* азотных органических соединений, включая амины -* других органических соединений, включая продукты переработки древесины (например, древесный уголь) и т. п. -- производство пека и пекового кокса -- производство синтетических ароматических продуктов -- перегонку каменноугольной смолы -- обжиг железного колидана - -Эта подгруппа также включает: -- производство продуктов, используемых в качестве флюоресцирующих осветляющих веществ или люминофорных веществ","Эта подгруппа не включает: -- добычу метана, этана, бутана или пропана, см. 1110 -- производство этилового спирта из ферментных материалов, см. 1551 -- производство топливных газов, таких как этан, бутан или пропан на нефтеперерабатывающих заводах, см. 2320 -- производство азотных удобрений и азотных соединений, см. 2412 -- производство аммиака, см. 2412 -- производство хлористого аммония, см. 2412 -- производство нитритов и нитратов калия, см. 2412 -- производство углекислого аммония, см. 2412 -- производство пластмасс в первичных формах, см. 2413 -- производство синтетического каучука в первичных формах, см. 2413 -- производство готовых красителей и пигментов, см. 2422 -- производство салициловой и О-ацетилсалициловой кислоты, см. 2423 -- производство неочищенного глицерина, см. 2424 -- производство натуральных эфирных масел, см. 2429" -1320,"241","Производство основных химических веществ",, -1310,"24","Производство химических веществ и химических продуктов","Основу этого подраздела составляет процесс трансформации органического и неорганического сырья с помощью химической переработки и создания продуктов. В подразделе проводится различие между производством основных химических веществ, образующих первую отраслевую группу, и производством промежуточной и конечной продукции, получаемой путем дальнейшей обработки основных химических веществ, которое классифицируется в остальных промышленных подгруппах.", -1300,"2330","Переработка ядерного топлива","Эта подгруппа включает: -- добычу урана из уранита или других ураносодержащих руд -- производство природного и обогащенного урана, плутония; его соединений, сплавов, дисперсий и смесей -- производство топливных элементов для использования в ядерных реакторах -- переработку ядерного топлива -- производство радиоактивных элементов для использования в промышленных или медицинских целях -- обращение с радиоактивными ядерными отходами","Эта подгруппа не включает: -- добычу и обогащение урановых и ториев руд, см. 1200 -- производство желтого порошка оксида урана, см. 1200 -- удаление транзитных радиоактивных отходов (то есть отходов, распад которых происходит в период временного хранения) из больниц и т. п., см. 9000" -1290,"233","Переработка ядерного топлива",, -1280,"2320","Производство продуктов нефтеперегонки","Эта подгруппа включает производство жидкого или газообразного топлива или других продуктов из сырой нефти, битуминозных минералов или их фракций. - -Эта подгруппа включает: -- производство топлива для двигателей: бензина, керосина и т. п. -- производство топлива: легких, средних и тяжелых топливных масел, газов, являющихся продуктами нефтеперегонки, таких как этан, пропан, бутан и т. п. -- производство смазочных масел, получаемых на базе нефти, или консистентных смазок, в том числе получаемых из отработанного масла -- производство продуктов для нефтехимической промышленности и для изготовления дорожных покрытий -- производство различных продуктов: уайт-спирита, вазелина, парафинового воска, вазелинового масла и т. п.", -1270,"232","Производство продуктов нефтеперегонки",, -1260,"2310","Производство продукции коксовых печей","Эта подгруппа включает: -- эксплуатацию коксовых печей -- производство кокса или полукокса -- производство коксового газа -- производство сырого угля и лигнитовой смолы -- агломерация кокса","Эта подгруппа не включает: -- агломерацию каменного угля, см. 1010 -- агломерацию лигнита, см. 1020 -- производство пека, пекового кокса и каменноугольной смолы, см. 2411" -1250,"231","Производство продукции коксовых печей",, -1240,"23","Производство кокса, продуктов нефтеперегонки и ядерного топлива","В данном подразделе речь идет о видах деятельности, связанных с переработкой сырой нефти и угля в продукты, пригодные к использованию, а также о предприятиях ядерной отрасли. Подраздел охватывает обрабатывающую промышленность энергетического сектора, классификация отраслей которого начинается в разделе С (добыча) и продолжается в разделе Е (электро-, газо- и водоснабжение). Основным процессом является процесс переработки нефти, в ходе которого в результате применения таких методов, как крекинг и перегонка, происходит разложение сырой нефти на составляющие фракции. Данный подраздел также охватывает производство для собственного использования специфических видов продукции (например, кокса, бутана, пропана, бензина, керосина, мазута, ядерного топлива и т. п.), а также услуги, связанные с обработкой (например, переработка нефти в соответствии с требованиями заказчика, обращение с ядерными отходами). -В данный подраздел также входит производство газов, таких как этан, пропан и бутан, в качестве продукции нефтеперерабатывающих заводов. Исключается производство таких газов другими предприятиями (2411), производство промышленных газов (2411), добыча природного газа (метан, этан, бутан, пропан) (1110), и производство топливного газа, кроме нефтяного газа (например, угольный газ, водяной газ, генераторный газ, газ, производимый газовыми заводами) (4020) -Предприятия по производству нефтехимических продуктов из продуктов нефтеперегонки классифицируются в разделе 24.", -1230,"2230","Тиражирование носителей записей","Эта подгруппа включает: -- тиражирование грампластинок, компакт-дисков и пленок с записями музыки или другими звукозаписями с оригинального экземпляра -- воспроизводство пластинок, компакт-дисков и кассет с записями кинофильмов и другими видеозаписями с оригинального экземпляра -- воспроизводство с оригинального экземпляра программного обеспечения и данных на дисках и кассетах","Эта подгруппа не включает: -- тиражирование печатных материалов, см. 2221 -- издание программного обеспечения, см. 7221 -- выпуск кинофильмов, видеокассет и кинофильмов на цифровых дисках (DVD) или на аналогичных носителях, см. 9211 -- производство оригинальных экземпляров грампластинок или звукозаписей, см. 9211 -- тиражирование пленок с кинофильмами для кинопроката, см. 9211" -1220,"223","Тиражирование носителей записей",, -1210,"2222","Услуги, связанные с полиграфическим исполнением","Эта подгруппа включает: -- переплет печатных листов в книги, брошюры, журналы, каталоги и т. п. путем фальцовки, компоновки, сшивания, проклейки, подборки, сметки, брошюрования, обрезки, тиснения золотом -- верстку, типографский набор, фотонабор, первоначальный ввод данных, включая сканирование и оптическое распознавание знаков, электронную верстку -- услуги по изготовлению печатных форм, включая регулировку параметров оттиска и подготовку печатных форм (для типографских машин высокой и офсетной печати) -- изготовление клише или травление цилиндров для гравирования -- изготовление готовых печатных форм (а также фотополимерных печатных форм) -- подготовку печатных форм и штампов для рельефного тиснения или печати -- изготовление корректуры -- художественные работы, включая изготовление литографических камней и ксилографических клише -- производство продукции методом репрографии -- оформление полиграфической продукции, например изготовление эскизов, формата, макетов и т. п. -- прочие виды полиграфических услуг, включая красочное тиснение и красочное конгревное тиснение, копирование шрифта Брайля, перфорирование и сверление отверстий, рельефное тиснение, покрытие лаком и ламинирование, подборку и вклейку, фальцовку", -1200,"2221","Полиграфическое исполнение","Эта подгруппа включает: -- печатание газет, журналов и других периодических изданий, книг и брошюр, нот и нотных записей, карт, атласов, плакатов, рекламных каталогов, проспектов и прочих печатных рекламных материалов, почтовых марок, гербовых марок, документов, подтверждающих право собственности, чеков и прочих ценных бумаг, регистрационных книг, альбомов, дневников, календарей, деловых бланков и прочих коммерческих печатных документов, индивидуальных канцелярских принадлежностей и других полиграфических материалов, изготовленных на типографских машинах высокой печати, офсетной печати, глубокой печати, флексографии, трафаретной печати и других печатных станках, на копировальных машинах, компьютерных воспроизводящих устройствах, станках для рельефной печати, фотокопировальном и термокопировальном оборудовании.","Эта подгруппа не включает: -- печатание этикеток, см. 2109 -- издание печатных материалов, см. 2211, 2212, 2219" -1190,"222","Полиграфическое исполнение и услуги, связанные с полиграфическим исполнением",, -1180,"2219","Прочие виды издательской деятельности","Эта подгруппа включает: -- издание: -* фотографий, эстампов и почтовых открыток -* поздравительных открыток -* расписаний -* формуляров -* плакатов, художественных репродукций -* прочих печатных материалов", -1170,"2213","Издание музыкальных произведений","Эта подгруппа включает: -- выпуск граммофонных пластинок, компакт-дисков и кассет с музыкой или другими записанными звуковыми материалами -- печатное издание музыкальных произведений - -Эта подгруппа также включает: -- издание прочих записанных звуковых материалов","Эта подгруппа не включает: -- издание программного обеспечения, см. 7221 -- выпуск этих изданий только в онлайновом варианте, см. 7240 -- издание кинофильмов, видеофильмов и кино-видеопродукции на цифровом видеодиске (DVD) или аналогичных носителях, см. 9211 -- производство мастер-копий записей или звукового материала, см. 9211" -1160,"2212","Издание газет, журналов и периодических публикаций","Эта подгруппа включает: -- издание газет, включая рекламные газеты -- издание периодических публикаций, торговых каталогов, комиксов и т. п.","Эта подгруппа не включает: -- выпуск этих изданий только в онлайновом варианте, см. 7240" -1150,"2211","Издание книг, брошюр и прочих публикаций","Эта подгруппа включает: -- издание книг, брошюр, листовок и аналогичных публикаций, включая издание словарей и энциклопедий -- издание атласов, карт и чертежей -- издание ""говорящих"" книг -- издание энциклопедий и т. п. публикаций на компакт-диске (СD-ROM)","Эта подгруппа не включает: -- выпуск этих изданий только в онлайновом варианте, см. 7240" -1140,"221","Издательское дело",, -1130,"22","Издательское дело, полиграфическая промышленность и тиражирование носителей записи","Данный подраздел включает издательскую деятельность, связанную или не связанную с полиграфическим исполнением. Издательское дело включает финансовую, техническую, творческую, правовую и, среди прочего, но не преимущественно, деятельность по реализации продукции. Разбивка подраздела построена на проведении различия между предприятиями, занятыми издательским делом, независимо от того, связано ли это с полиграфическим исполнением (группа 221), и предприятиями, занятыми только полиграфией (группа 222). Разбивка издательской деятельности на подгруппы делается исходя из вида публикуемых печатных материалов или выпускаемых носителей записи. -Эта подгруппа включает предприятия, занятые изданием газет, журналов, прочих периодических изданий и книг. В основном эти предприятия, известные как издательства, выпускают копии работ, на которые они обычно имеют авторские права. Работы могут выходить в одном или нескольких форматах, включая традиционную печать и издание в электронной форме. Издательства могут выпускать работы, созданные сторонними авторами, на которые они приобрели авторские права, и/или работы, которые они создали собственными силами. -Полиграфическая промышленность выпускает печатные издания, такие как газеты, книги, периодические издания, бланки, поздравительные открытки и прочие материалы, и выполняет вспомогательные функции, такие как переплет книг, услуги по изготовлению печатных форм, наглядное отображение данных. Виды вспомогательной деятельности, включенные в эту подгруппу, являются составной частью полиграфической промышленности, и почти всегда в результате этих действий получается изделие (печатная форма, переплетенная книга, компьютерный диск или файл), являющееся неотъемлемым элементом полиграфической промышленности. -Процессы, используемые в полиграфии, включают разнообразные методы переноса изображения с пластины, экрана или из компьютерного файла на тот или иной носитель, такой как изделие из бумаги, пластмассы, металла, текстильного материала или древесины. Наиболее известные из этих методов служат для перенесения изображения с пластины или экрана на носитель (офсетная, глубокая, трафаретная и флексографическая печать). Быстро развивающаяся новая технология использует компьютерный файл для прямого ""запуска"" печатного устройства и получения изображения и новое электростатическое и прочие типы оборудования (цифровая печать или печать безударного действия). -Хотя полиграфическая печать и выпуск печатных изданий могут осуществляться на одном предприятии (например, выпуск газеты), эти разные виды деятельности все реже осуществляются в физически одном месте. Когда издательское дело и типографская печать сосредоточены на одном предприятии, такое предприятие классифицируется в группе 221 (Издательское дело), даже если доходы от типографской печати больше, чем от издательской деятельности. -В эту группу включены предприятия, занимающиеся онлайновыми изданиями и выпуском прочих изданий, например газетное издательство, которое также издает онлайновую версию газеты. -Этот подраздел не включает предприятия, занимающиеся только онлайновой издательской деятельностью, см. 7240. -Этот подраздел не включает издание программного обеспечения, см. 7221, и выпуск кинофильмов и видеофильмов, см. 9211.", -1120,"2109","Производство прочих изделий из бумаги и картона","Эта подгруппа включает: -- производство изделий из бумаги и целлюлозной ваты, предназначенных для использования в домашнем хозяйстве и в качестве средств личной гигиены: -* протирочных тканей -* носовых платков, полотенец, салфеток -* туалетной бумаги -* гигиенических салфеток и тампонов, пеленок и подгузников для младенцев -* чашек, тарелок и подносов -- производство готовой для использования типографской и писчей бумаги -- производство готовой для использования бумаги для компьютерной печати -- производство готовой для использования бумаги с копировальной прокладкой -- производство готовой для использования бумаги для копирования и трафаретной печати -- производство готовой для использования гуммированной бумаги или бумаги с липким слоем -- производство конвертов и почтовых открыток -- производство коробок, пакетов, сумок и почтовых наборов, включающих несколько сортов почтовой и другой писчей бумаги -- производство обоев и аналогичных материалов для покрытия стен, включая обои с виниловым покрытием и тканью -- производство этикеток, с типографской печатью или без нее -- производство фильтровальных бумаги и картона -- производство бобин, шпулек, колпачков и т. п. из бумаги и картона -- производство подставок для яиц и других формованных изделий из целлюлозы","Эта подгруппа не включает: -- производство бумаги или картона без упаковки, см. 2101 -- производство игральных карт, см. 3694 -- производство игр и игрушек из бумаги или картона, см. 3694" -1110,"2102","Производство гофрированных бумаги и картона и бумажной или картонной тары","Эта подгруппа включает: -- производство гофрированных бумаги и картона -- производство тары из гофрированных бумаги или картона -- производство складных коробок из картона -- производство тары из твердого картона -- производство другой тары из бумаги и картона -- производство мешков и пакетов из бумаги -- производство каталожных ящиков и аналогичных изделий","Эта подгруппа не включает: -- производство конвертов, см. 2109 -- производство формованных или прессованных изделий из бумажной пульпы (например, картонок для упаковывания яиц, формованные пластины из целлюлозы), см. 2109" -680,"1544","Производство макарон, лапши, кускуса и аналогичных мучных изделий","Эта подгруппа включает: -- производство макаронных изделий, таких как макароны и лапша, в сыром или вареном виде, сплошных или полых -- производство кускуса -- производство герметично упакованных или замороженных макаронных изделий","Эта подгруппа не включает: -- производство супов, содержащих макаронные изделия, см. 1549" -670,"1543","Производство какао, шоколада и кондитерских изделий из сахара","Эта подгруппа включает: -- производство какао, какао-масла, какао-жира, жидкого какао-масла -- производство шоколада и шоколадных кондитерских изделий -- производство сахарных кондитерских изделий: карамелей, таблеток для освежения дыхания, нуги, помадки, белого шоколада -- производство жевательной резинки -- производство засахаренных фруктов, орехов, цукатов из кожуры фруктов и из других частей растений -- производство кондитерских таблеток и пастилок","Эта подгруппа не включает: -- производство сахара из сахарозы, см. 1542" -660,"1542","Производство сахара","Эта подгруппа включает: -- производство или рафинирование сахара (сахарозы) и заменителей сахара из тростникового или сахарного сиропа, кленового или пальмового сока -- производство сахарных сиропов -- производство черной патоки","Эта подгруппа не включает: -- сбор сока и производство кленового сиропа и сахара, см. 0112 -- производство глюкозы, глюкозного сиропа, мальтозы, см. 1532" -650,"1541","Производство хлебобулочных изделий","Эта подгруппа включает: -- производство свежих, замороженных или сухих хлебобулочных изделий -- производство свежевыпеченного хлеба и булочек -- производство свежевыпеченных пирожных, кексов, пирогов, тортов и т. п. -- производство сухарей, бисквитов и других ""сухих"" хлебобулочных изделий -- производство готовых к хранению кондитерских хлебобулочных изделий и кексов -- производство кондитерских изделий (печенья, крекеров, кренделей и т. п.), с сахаром или солью -- производство лепешек -- производство замороженных хлебобулочных изделий: блинов, вафель, булочек и т. п.","Эта подгруппа не включает: -- производство мучных изделий, известных как макаронные изделия, см. 1544 -- производство кондитерских изделий из картофеля, см. 1513" -640,"154","Производство прочих пищевых продуктов",, -630,"1533","Производство готовых кормов для животных","Эта подгруппа включает: -- производство готовых кормов для домашних животных, включая собак, кошек, птиц, рыб и т. д. -- производство готовых кормов для животных, содержащихся на фермах, включая пищевые концентраты и кормовые добавки -- подготовку несмешанных (однородных) кормов для животных, содержащихся на фермах - -Эта подгруппа также включает: -- обработку отходов скотобоен для производства кормов для животных","Эта подгруппа не включает: -- производство рыбной муки в качестве корма для животных, см. 1512 -- производство жмыха из масличных семян, см. 1514 -- виды деятельности, в результате которой образуются побочные продукты, используемые в качестве корма для животных без специальной обработки, например жмыхи (см. 1514), остатки , образующиеся при размоле зерновых (см. 1531) и т. п." -620,"1532","Производство крахмалов и крахмальных продуктов","Эта подгруппа включает: -- производство крахмалов из риса, картофеля, маиса и т. п. -- мокрое измельчение кукурузы -- производство глюкозы, глюкозового сиропа, мальтозы, инулина и т. п. -- производство клейковины -- производство тапиоки и ее заменителей, приготавливаемых из крахмала -- производство кукурузного масла","Эта подгруппа не включает: -- производство лактозы (молочного сахара), см. 1520 -- производство сахара из тростника или свеклы, см. 1542" -610,"1531","Производство продуктов мукомольной промышленности","Эта подгруппа включает: -- обработку зерна: получение муки, круп, муки крупного помола или гранул пшеницы, ржи, овса, маиса (кукурузы) или других зерновых культур; -- обработку риса: получение обрушенного, молотого, полированного, глазированного, пропаренного или преобразованного риса; производство рисовой муки -- обработку овощей: получение муки крупного или мелкого помола из сушеных бобовых, корнеплодов или клубнеплодов или из съедобных орехов -- производство продуктов для завтрака -- производство готовых мучных смесей и теста для выпечки хлеба, пирожных, бисквитов и блинов","Эта подгруппа не включает: -- производство картофельной муки грубого и тонкого помола, см. 1513 -- мокрое измельчение кукурузы, см. 1512" -600,"153","Производство продуктов мукомольной промышленности, крахмалов и крахмальных продуктов и готовых кормов для животных",, -590,"1520","Производство молочных продуктов","Эта подгруппа включает: -- переработку свежего молока в жидком виде, пастеризацию, стерилизацию, гомогенизацию и/или высокотемпературную обработку -- производство безалкогольных напитков на основе молока -- производство сливок из свежего жидкого молока, пастеризацию, стерилизацию, гомогенизацию -- производство сухого или концентрированного молока, без сахара или подслащенного -- производство молока или сливок в твердом виде -- производство сливочного масла -- производство йогурта -- производство сыра и творога -- производство сыворотки -- производство казеина или лактозы -* производство сливочного мороженого и других видов пищевого льда типа фруктового мороженого","Эта подгруппа не включает: -- производство сырого молока, см. 0121 -- производство заменителей молока и молочного сыра, см. 1549 -- деятельность кафе-мороженых, см. 5520" -580,"152","Производство молочных продуктов",, -570,"1514","Производство растительных и животных масел и жиров","Эта подгруппа включает производство сырых и рафинированных масел и жиров из растительных и животных материалов, кроме вытапливания или очистки свиного сала и других пищевых животных жиров. - -Эта подгруппа включает: -- производство сырых растительных масел: оливкового масла, соевого масла, пальмового масла, подсолнечного масла, хлопкового масла, рапсового или горчичного масла, льняного масла и т. п. -- производство необезжиренной муки тонкого и грубого помола из масличных семян, масличных орехов или косточек масличных культур -- производство рафинированных растительных масел: оливкового масла, соевого масла и т. п. -- производство растительных масел: продувка, выпаривание, обезвоживание, гидрогенизация и т. п. -- производство маргарина -- производство смесей и других аналогичных паст -- производство смешанных жиров для приготовления пищи - -Эта подгруппа также включает: -- производство непищевых животных масел и жиров -- извлечение рыбьего жира или жиров из морских млекопитающих - -Примечание. Производство масла из хлопковых семян включает производство хлопкового пуха, жмыха и других остаточных продуктов в качестве побочных продуктов данной подгруппы.","Эта подгруппа не включает: -- вытапливание и очистку свиного сала и других пищевых животных жиров, см. 1511 -- мокрое измельчение кукурузы, см. 1532 -- производство основных масел, см. 2429 -- обработку масел и жиров с помощью химических процессов, см. 2429" -560,"1513","Переработка и консервирование фруктов и овощей","Эта подгруппа включает: -- производство пищевых продуктов, состоящих преимущественно из фруктов или овощей -- хранение фруктов, орехов или овощей: замораживание, сушка, погружение в масло или уксус, изготовление консервов и т. п. -- производство фруктовых или овощных пищевых продуктов -- производство фруктовых и овощных соков -- производство джемов, мармеладов и столовых желе -- переработка и хранение картофеля: -* производство готового картофеля в замороженном виде -* производство обезвоженного картофельного пюре -* производство закусочных изделий из картофеля -* производство хрустящего картофеля -* производство картофельной муки грубого и тонкого помола -- производство готовых овощных блюд -- обжаривание орехов -- производство пищевых продуктов и паст из орехов - -Эта подгруппа также включает: -- очистку картофеля промышленным способом -- производство концентратов","Эта подгруппа не включает: -- производство муки мелкого или грубого помола из сухих бобовых, см. 1531 -- производство засахаренных фруктов и орехов, см. 1543" -550,"1512","Переработка и консервирование рыбы и рыбных продуктов","Эта подгруппа включает: -- подготовку и предохранение от порчи рыбы, ракообразных и моллюсков: замораживание, глубокое замораживание, сушка, копчение, соление, погружение в рассол, консервирование и т. п. -- производство продуктов из рыбы, ракообразных и моллюсков: вареной рыбы, рыбного филе, икры, в том числе икры осетровых рыб и ее заменителей, и т. п. -- производство готовых рыбных блюд -- производство рыбной муки, пригодной для потребления человеком или для использования в качестве корма для животных -- производство муки и растворимых в воде веществ из рыбы и других водных животных, непригодных для потребления человеком - -Эта подгруппа также включает: -- деятельность судов, занимающихся только переработкой и консервированием рыбы","Эта подгруппа не включает: -- деятельность судов, занимающихся как рыболовством, так и переработкой улова и консервированием рыбы на борту, см. 0501 -- переработку китовых туш на берегу или на специализированных судах, см. 1511 -- производство масел и жиров из морских продуктов, см. 1514 -- производство рыбных супов, см. 1549" -540,"1511","Производство, переработка и консервирование мяса и мясных продуктов","Эта подгруппа включает: -- операции скотобоен: убой, обработку и упаковывание мяса -- производство свежего, охлажденного или замороженного мяса, в тушах -- производство свежего, охлажденного или замороженного мяса, в кусках -- забой домашней птицы -- подготовка мяса домашней птицы -- производство свежего или замороженного мяса домашней птицы в виде индивидуальных порций -- производство сушеного, соленого или копченого мяса -- производство мясных продуктов: -* вареных и твердых колбас, пудингов, сосисок, сервелатов, копченых колбас, паштетов, рулетов, вареного окорока, мясных экстрактов и соков -- производство готовых блюд из свежего мяса - -Эта подгруппа также включает: -- забой и переработку китов на берегу или на специальных судах -- обработку шкур и кожи, поступающих со скотобоен, включая скорняжное производство -- вытапливание свиного сала и других пищевых животных жиров -- обработку потрохов животных -- обработку щипаной шерсти -- забой кроликов и родственных животных -- подготовку мяса кроликов и родственных животных -- производство перьев и пуха","Эта подгруппа не включает: -- производство супов, содержащих мясо, см. 1549 -- производство готовых блюд из замороженного мяса животных и домашней птицы, см. 1549 -- упаковывание мяса на предприятии оптовой торговли, см. 5122 -- упаковывание мяса за вознаграждение или на договорной основе, см. 7495" -530,"151","Производство, переработка и консервирование мяса, рыбы, фруктов, овощей, масел и жиров",, -520,"15","Производство пищевых продуктов и напитков","Пищевая промышленность занимается переработкой продукции сельского хозяйства, животноводства и рыболовства в пищу и напитки для людей или животных и включает производство различных промежуточных продуктов, которые еще не являются непосредственно пищевыми продуктами. В результате этой деятельности часто создаются сопутствующие продукты, обладающие большей или меньшей ценностью (например, шкуры, производимые на скотобойнях, или жмых при производстве масла). -Этот подраздел построен по видам деятельности, касающейся различных видов продуктов: мяса, рыбы, плодов и овощей, жиров и масел, молочных продуктов, продуктов мукомольной отрасли, кормов для животных, других пищевых продуктов и напитков. Производство может быть организовано для собственной реализации, а также для третьих сторон, например при забое скота и разделке мяса на заказ. -Некоторые виды деятельности считаются обработкой или переработкой (например, в булочных, кондитерских магазинах, магазинах по продаже готовых мясных продуктов и т. п., то есть деятельность тех, кто продает продукцию собственного производства) даже в том случае, когда имеет место розничная торговля продуктами в собственном магазине производителя. Однако если переработка является минимальной и не приводит к действительному изменению (например, как в случае разделки мяса, торговли рыбой и т. п.), то это предприятие относится к ""Оптовой и розничной торговле"" (раздел G). -Производство кормов для животных из отходов или побочных продуктов скотобоен классифицируется в подгруппе 1533, переработка пищевых отходов и отходов жидких продуктов во вторичное сырье классифицируется в подгруппе 3720, а утилизация отходов пищевых продуктов и напитков - в подгруппе 9000.", -510,"D","Обрабатывающая промышленность","Обрабатывающая промышленность включает предприятия, в которых проводится физическое или химическое преобразование материалов, веществ или компонентов в новые продукты. Преобразуемые материалы, вещества или компоненты - это сырьевые материалы, которые являются продуктами сельского хозяйства, лесной промышленности, рыболовства, горнодобывающей промышленности или разработки карьеров, а также продуктами других отраслей обрабатывающей промышленности. -К предприятиям обрабатывающей отрасли преимущественно относятся заводы, фабрики или иные промышленные предприятия, обычно использующие машины с механическим приводом и оборудование для обработки материалов. Однако в этот раздел также включены предприятия, на которых происходит превращение материалов или веществ в новые продукты вручную или на дому, а также те предприятия, которые участвуют в сбыте товаров широкого потребления, изготовленных в тех же помещениях, из которых они продаются, такие как булочные-пекарни или ателье по пошиву одежды. -Предприятия обрабатывающей промышленности могут обрабатывать свои материалы или могут на договорной основе осуществлять обработку для других предприятий их материалов. Оба типа предприятий относятся к обрабатывающей промышленности. -Новый продукт предприятия обрабатывающей промышленности может считаться готовым в смысле его готовности для использования или потребления или может служить полуфабрикатом в том смысле, что становится исходным материалом для дальнейшей обработки. Например, продукт завода для рафинирования глинозема является исходным материалом, используемым в первичном производстве алюминия; первичный алюминий является исходным материалом для волочильного производства алюминиевой проволоки; алюминиевая проволока является исходным материалом для предприятия по изготовлению промышленного изделия из проволоки. -Сборка компонентов производимых изделий считается функцией обрабатывающей промышленности. Она включает сборку из компонентов либо собственного изготовления, либо из купленных в готовом виде. Сборка конструкций на строительной площадке из элементов собственного изготовления классифицируется как функция обрабатывающей промышленности в том случае, когда изготовление и сборка являются единым производственным процессом. Когда сборка выполняется разными организациями, то этот вид деятельности, как подсказывает логика, отнесен к подразделу 45 (Строительство). Поэтому монтаж на строительной площадке из готовых элементов не собственного изготовления мостов, водных резервуаров, хранилищ и складских помещений, железнодорожных и элеваторных полос отвода, лифтов и эскалаторов, водопроводов, противопожарных систем, систем центрального отопления, вентиляции и кондиционеров воздуха, осветительных приборов, электрических и телекоммуникационных проводных систем в зданиях и всех видов сооружений классифицирован в подразделе ""Строительство"". -Монтаж и установка машин и оборудования на предприятиях горнодобывающей, обрабатывающей промышленности, в торговле и на других предприятиях, если они осуществляются как один из видов специализированной деятельности, классифицируются в той же подгруппе подраздела ""Обрабатывающая промышленность"", что и производство устанавливаемого оборудования. -Монтаж и установка машин и оборудования, если они осуществляются как одна из услуг, предоставляемых в связи с продажей товаров предприятием, занимающимся преимущественно производством готовой продукции, оптовой или розничной торговлей, классифицируются в соответствии с его основным видом деятельности. -Деятельность предприятий, преимущественно занятых ремонтом и техническим обслуживанием промышленных, торговых и аналогичных машин и оборудования, как правило, классифицируется в той же подгруппе подраздела ""Обрабатывающая промышленность"", что и предприятия, специализирующиеся на производстве этих товаров. Однако предприятия, занимающиеся ремонтом канцелярских и электронно-вычислительных машин, классифицированы в подгруппе 7250. Предприятия, основным видом деятельности которых является ремонт бытовых приборов, оборудования и мебели, автомобилей и других потребительских товаров, классифицируются, как правило, в соответствующей подгруппе подразделов 50 (Продажа, техническое обслуживание и ремонт автомобилей и мотоциклов; розничная продажа топлива для транспортных средств с двигателями внутреннего сгорания) или 52 (Розничная торговля, кроме автомобилей и мотоциклов; ремонт бытовых товаров и предметов личного пользования) в соответствии с видом товаров, которые ремонтируются. -К обрабатывающему производству обычно относятся существенное изменение, обновление или реконструкция товаров. -Производство специализированных компонентов и деталей, а также принадлежностей и приспособлений для машин и оборудования классифицируется, как правило, в той же подгруппе, что и производство машин и оборудования, для которых предназначаются детали и принадлежности. Производство неспециализированных компонентов и деталей машин и оборудования, например двигателей, поршней, электромоторов, электроузлов, клапанов, шестерен, шарикоподшипников, классифицировано в соответствующей подгруппе подраздела ""Обрабатывающая промышленность"", независимо от того, в состав каких машин и оборудования могут входить эти предметы. Однако изготовление специализированных компонентов и принадлежностей путем формования или экструзии пластических материалов включено в подгруппу 2520. -В раздел ""Обрабатывающая промышленность"" включена также переработка отходов. -Примечание. Границы обрабатывающей промышленности с другими разделами системы классификации могут быть несколько расплывчатыми. Как правило, предприятия обрабатывающей отрасли занимаются переработкой материалов в новые продукты. На выходе получается новое изделие. Однако определение того, что представляет собой новое изделие, может быть несколько субъективным. Для уточнения - в Международной классификации промышленных стандартов МСОК к обрабатывающей промышленности относятся следующие виды деятельности: -- Пастеризация и разлив молока (см. 1520); -- Переработка свежей рыбы (извлечение устриц из раковин, филетирование рыбы), выполняемая не на борту рыболовного судна (см. 1512); -- Печать и смежные виды деятельности (см. 2221, 2222); -- Производство готовых к применению бетонных смесей (см. 2695); -- Выделка кожи (см. 1911); -- Консервация древесины (см. 2010); -- Гальванотехника, металлизация, тепловая обработка металла, полировка (см. 2892); -- Механическое оборудование для ремонта или переборки (например, двигателей внутреннего сгорания, см. 3410); -- Ремонт и модернизация судов (см. 3511); -- Восстановление протекторов шин (см. 2511). - -С другой стороны, существуют виды деятельности, иногда относящиеся к обрабатывающей промышленности, которые классифицируются в другом разделе МСОК (другими словами, они не классифицируются как обрабатывающая промышленность). Эти виды деятельности включают: -- Лесозаготовки, классифицируемые в разделе А (Сельское хозяйство, охота и лесоводство); -- Обогащение руд и других минералов, классифицируемое в разделе С (Горнодобывающая промышленность); -- Строительство сооружений и сборочные операции, выполняемые на строительной площадке, классифицируется в разделе F (Строительство); -- Деятельность по разбивке крупных партий товаров на мелкие группы и вторичный сбыт более мелких партий, включая упаковывание и переупаковывание или разлив в бутылочную тару таких продуктов, как алкогольные напитки или химикаты; сборка компьютеров на заказ; сортировка твердых отходов; смешивание красок по заказу клиента; резка металлов по заказу клиента; производство видоизмененного варианта того же продукта, но не нового продукта, классифицируются в разделе G (Оптовая и розничная торговля).", -500,"1429","Прочие отрасли горнодобывающей промышленности и разработки карьеров, не включенные в другие категории","Эта подгруппа включает: -- добычу подземным или открытым способом различных минералов и материалов: -* абразивных материалов, асбеста, кремнистой ископаемой муки, природного графита, стеатита (талька), полевого шпата и т. п. -* драгоценных камней, кварца, слюды и т. п. -* природного асфальта и битума", -490,"1422","Добыча соли","Эта подгруппа включает: -- добычу соли из подземных выработок, включая растворение и подачу насосом -- производство соли выпариванием морской воды или других природных источников соленых вод -- измельчение, очистку и просеивание соли","Эта подгруппа не включает: -- обработку купленной соли, см. 2429 -- производство питьевой воды путем выпаривания соленой воды, см. 4100" -480,"1421","Добыча минерального сырья для химической промышленности и производства удобрений","Эта подгруппа включает: -- добычу природных фосфатов и природных калиевых солей -- добычу природной серы -- добычу и подготовку железного и магнитного колчеданов, кроме отжига -- добычу природного сульфата и карбоната бария (баритов и витерита), природной магниевой серы (кисерита) -- добычу природных красителей, плавикового шпата и других минералов, ценных преимущественно как источник химических веществ - -Эта подгруппа также включает: -- добычу гуано","Эта подгруппа не включает: -- производство соли, см. 1422 -- отжиг железного и магнитного колчеданов, см. 2411 -- производство синтетических удобрений и азотных соединений, см. 2412" -470,"142","Отрасли горнодобывающей промышленности и разработки карьеров, не включенные в другие категории",, -460,"1410","Разработка каменных, глиняных и песчаных карьеров","Эта подгруппа включает: -- операции по разработке карьеров, в которых добывается поделочный и строительный камень, обработанный грубым обтесыванием, нарезанный путем распиливания, такой как мрамор, гранит, песчаник и т. п. -- операции по разработке карьеров, дробление и отбойка известняка -- добычу гипса и ангидрида -- добычу мела и некальцинированного доломита -- добычу и выборку песка для промышленных нужд, строительного песка и гравия -- отбойку и измельчение камня, гравия и песка -- добычу глин, огнеупорных глин и каолина","Эта подгруппа не включает: -- добычу битуминозного песчаника, см. 1110 -- добычу химических минералов и сырья для производства удобрений, см. 1421 -- производство кальцинированного доломита, см. 2694 -- резку, фасонирование и отделку камня за пределами карьеров, см. 2696" -450,"141","Разработка каменных, глиняных и песчаных карьеров",, -440,"14","Прочие отрасли горнодобывающей промышленности и разработки карьеров","Эта подгруппа включает операции по добыче материалов из карьеров, а также выемку аллювиальных отложений открытым способом, измельчение камня и эксплуатацию равнин, затопляемых соленой водой (соляных болот). Добываемые материалы используются преимущественно в строительстве (например, песок, камень и т. п.), производстве других материалов (например, глины, гипса, кальция и т. п.), производстве химикатов и т. п. -В этот подраздел не включена обработка (кроме дробления, измельчения, распиловки, очистки, сушки, сортировки и смешения) добытых минералов. Вертикально интегрированные предприятия, осуществляющие обработку добытых ими же минеральных материалов на месте, классифицируются по виду производства (например, цементные заводы или фабрики по изготовлению брикетов). Производство соли включает очистку соли для приведения ее в состояние, пригодное для потребления человеком.", -430,"1320","Добыча руд цветных металлов, кроме урановой и ториевой руд","Эта подгруппа включает: -- добычу и подготовку руд, ценных преимущественно содержанием в них цветных металлов: -* алюминия (боксит), меди, свинца, цинка, олова, марганца, хрома, никеля, кобальта, молибдена, тантала, ванадия и т. п. -* драгоценных металлов: золота, серебра, платины","Эта подгруппа не включает: -- добычу и подготовку урановой и ториевой руд, см. 1200 -- производство оксида алюминия и штейнов никеля и меди, см. 2720" -420,"132","Добыча руд цветных металлов, кроме урановой и ториевой руд",, -410,"1310","Добыча железной руды","Эта подгруппа включает: -- добычу руд, ценных преимущественно содержанием в них железа -- обогащение и агломерацию железных руд","Эта подгруппа не включает: -- добычу и подготовку железного колчедана и магнитного колчедана, см. 1421" -400,"131","Добыча железной руды",, -390,"13","Добыча металлических руд","Этот подраздел включает: -- добычу металлических руд и природных металлов в подземных и открытых разработках -- подготовку руд: -* измельчение, размол руды, промывку руды -* обогащение руд с помощью магнитной или гравиметрической сепарации -* флотацию, просеивание, сортировку, сушку, кальцинирование и обжиг руды","Этот подраздел не включает: -- добычу урановой и ториевой руд, см. 1200 -- обжиг железных колчеданов, см. 2411 -- производство оксида алюминия, см. 2720" -380,"1200","Добыча урановой и ториевой руд","Эта подгруппа включает: -- добычу руд, ценных преимущественно содержанием в них урана или тория: уранита и т. п. -- обогащение таких руд -- производство желтого кека","Эта подгруппа не включает: -- обогащение урановой и ториевой руд, см. 2330 -- производство расщепляющихся или воспроизводящих материалов, см. 2330 -- производство урана из уранита или других руд, см. 2330" -370,"120","Добыча урановой и ториевой руд",, -360,"12","Добыча урановой и ториевой руд",, -350,"1120","Услуги, связанные с добычей нефти и газа, кроме изыскательских работ","Эта подгруппа включает: -- услуги, связанные с добычей нефти и газа, предоставляемые за вознаграждение или на договорной основе: -* наклонно-направленное бурение и перебуривание; ""забуривание скважины""; строительство буровой вышки, ее ремонт и демонтаж; цементирование обсадных труб нефтяных и газовых скважин; насосные скважины; забивка и ликвидация скважин и т. п. - -Эта подгруппа также включает: -- пробное бурение, связанное с добычей нефти или газа","Эта подгруппа не включает: -- услуги, предоставляемые операторами нефтяных и газовых месторождений, см. 1110 -- геофизические, геологические и сейсмографические изыскания, см. 7421" -340,"112","Услуги, связанные с добычей нефти и газа, кроме изыскательских работ",, -330,"1110","Добыча сырой нефти и природного газа","Эта подгруппа включает: -- добычу сырой нефти -- производство сырого газообразного углеводорода (природного газа) -- добычу конденсатов -- дренаж и сепарацию жидких углеводородных фракций -- сжижение и повторную газификацию природного газа для транспортировки, на месте добычи -- десульфацию газа -- работы по добыче полезных ископаемых: бурение, заполнение и оборудование скважин (осуществляемые не за вознаграждение и не на договорных условиях) - -Эта подгруппа также включает: -- добычу битуминозного или нефтеносного сланца и битуминозного песчаника -- производство сырой нефти из битуминозного сланца или песчаника -- процессы получения сырой нефти: декантация, обессоливание, дегидратация, стабилизация и т. п.","Эта подгруппа не включает: -- услуги, связанные с добычей нефти и газа, см. 1120 -- производство светлых нефтепродуктов, см. 2320 -- высвобождение газов из жидкой нефти в процессе перегонки нефти, см. 2320 -- производство газов промышленного назначения, см. 2411 -- обеспечение работы трубопроводов, см. 6030 -- детальную разведку на нефть и газ с помощью разведочных скважин, см. 7421" -320,"111","Добыча сырой нефти и природного газа",, -310,"11","Добыча сырой нефти и природного газа; услуги, связанные с добычей нефти и газа, кроме изыскательских работ","Этот подраздел включает производство сырой нефти, добычу и извлечение нефти из горючего сланца и нефтеносных песков, производство природного газа и извлечение жидких углеводородов. Этот подраздел включает виды деятельности по эксплуатации существующих и/или освоению участков месторождений нефти и газа. Такие виды деятельности могут включать бурение, заполнение и оборудование скважин; обеспечение работы сепараторов, деэмульгаторов, отстойников, полевых трубопроводов для сбора сырой нефти; и все другие виды деятельности для подготовки нефти и газа к отгрузке с места добычи. Также включены вспомогательные услуги, предоставляемые за вознаграждение или на договорной основе, необходимые для бурения или эксплуатации нефтяных или газовых скважин.","Этот подраздел не включает: -- перегонку нефтесодержащих продуктов, см. 2320 -- пробное бурение и буровые работы, см. 4510 -- геофизические изыскательские работы и составление карты месторождения, см. 7421 -- эксплуатацию нефтяной или газовой скважины, см. 7421" -300,"1030","Добыча и агломерация торфа","Эта подгруппа включает: -- добычу торфа -- агломерацию торфа","Эта подгруппа не включает: -- производство торфяных продуктов, см. 2699" -290,"103","Добыча и агломерация торфа",, -280,"1020","Добыча и агломерация лигнита","Эта подгруппа включает: -- добычу лигнита (бурого угля) подземным или отрытым способом -- промывку, дегидратацию, пульверизацию лигнита для повышения качества, облегчения транспортировки или хранения -- агломерацию лигнита, включая производство брикетов или других видов твердого топлива, содержащих преимущественно лигнит","Эта подгруппа не включает: -- добычу каменного угля и производство брикетов или агломерацию каменного угля, см. 1010 -- добычу и агломерацию торфа, см. 1030 -- вскрышные операции или подготовку земельных участков к добыче угля, см. 4510" -270,"102","Добыча и агломерация лигнита",, -260,"1010","Добыча и агломерация каменного угля","Эта подгруппа включает: -- добычу каменного угля подземным или отрытым способом -- очистку, калибровку, сортировку, размельчение и другие операции, необходимые для разделения по сортам, повышения качества или облегчения транспортировки каменного угля -- агломерацию каменного угля, включая производство брикетов или других видов твердого топлива, содержащих преимущественно каменный уголь - -Эта подгруппа также включает: -- отделение каменного угля от каменноугольной мелочи","Эта подгруппа не включает: -- добычу лигнита (бурого угля) и производство брикетов или агломерацию лигнита, см. 1020 -- добычу и агломерацию торфа, см. 1030 -- коксовальные печи для получения твердых видов топлива, см. 2310 -- вскрышные операции или подготовку земельных участков к добыче угля, см. 4510" -250,"101","Добыча и агломерация каменного угля",, -240,"10","Добыча угля и лигнита; добыча торфа","Добыча твердого минерального топлива охватывает подземную или открытую разработку и включает операции (например, сортировку, очистку и т. п.), в результате которых получается продукт, пригодный для сбыта, включая брикетирование (например, брикеты и окатыши). Этот раздел не включает коксование (см. 2310).", -230,"C","Горнодобывающая промышленность и разработка карьеров","Горнодобывающая промышленность и разработка карьеров охватывают добычу минералов, встречающихся в природе в виде твердых пород (каменный уголь и руды), в жидком состоянии (нефть) или в газообразном состоянии (природный газ). Добыча может производиться подземным и открытым способами или бурением скважин. -Этот раздел включает дополнительные виды деятельности с целью подготовки сырьевых материалов к сбыту, например, дробление, измельчение, очистка, сушка, сортировка, обогащение руды, сжижение природного газа и агломерация твердого топлива. Эти виды деятельности часто выполняются предприятиями, которые добывают полезное ископаемое, и/или другими предприятиями, расположенными в непосредственной близости. -Отрасли горнодобывающей промышленности разделены на подразделы, группы и подгруппы по основному виду добываемого минерального сырья. Подразделы 10, 11 и 12 относятся к добыче и разработке карьеров энергоносителей (каменный уголь, лигнит и торф, углеводороды, урановая руда); подразделы 13 и 14 относятся к материалам, не дающим энергию (металлические руды, различные минералы и материалы, добываемые в открытых карьерах). -Некоторые из технических операций, включенных в этот раздел, особенно те из них, которые относятся к добыче углеводородов, могут также выполняться для третьих сторон специализированными предприятиями в качестве промышленной услуги. - -Этот раздел также включает: -- агломерацию каменного угля и руд","Этот раздел не включает: -- обработку добытых материалов, см. раздел D -- применение добытых материалов без дальнейшей обработки в строительстве, см. раздел F -- разлив по бутылкам воды из природных источников и минеральной воды, производимый непосредственно у источника или скважины, см. 1554 -- измельчение, размол и другую обработку некоторых земель, пород и минералов, производимые не в сочетании с операциями по добыче и разработке карьеров, см. 2699 -- сбор, очистку и распределение воды, см. 4100 -- подготовку производственной площадки для разработки месторождения, см. 4510 -- разведку полезных ископаемых, см. 7421" -222,"0502","Аквакультура","Эта подгруппа включает: -- производство устричной молоди, семени мидий, разведение омаров, креветок послеличиночной стадии, рыбных мальков и рыбной молоди -- выращивание красной водоросли и других съедобных морских водорослей -- разведение рыбы в морской и пресной воде, включая разведение декоративных рыб в рыбохозяйствах -- культивацию устриц -- деятельность рыбопитомников - -Эта подгруппа также включает: -- услуги, связанные с деятельностью рыбопитомников и рыбохозяйств","Эта подгруппа не включает: -- деятельность ферм по разведению лягушек, см. 0122 -- услуги по спортивной ловле рыбы, см. 9241" -220,"0501","Рыболовство","Эта подгруппа включает: -- рыболовство в коммерческих целях в открытом море, в прибрежных или внутренних водах -- добычу морских и пресноводных ракообразных и моллюсков -- китобойный промысел -- промысел водных животных: черепах, асцидий и других оболочников, морских ежей и т. п. - -Эта подгруппа также включает: -- деятельность судов, ведущих как лов, так и обработку и заготовку рыбы -- сбор морских продуктов: натурального жемчуга, губок, кораллов и водорослей -- услуги, связанные с рыболовством","Эта подгруппа не включает: -- ловлю морских млекопитающих, кроме китов, например моржей, тюленей, см. 0150 -- обработку рыбы, ракообразных и моллюсков, не связанную с рыболовством, например на борту судов, занятых только обработкой и заготовкой рыбы, или на рыбозаводах, расположенных на берегу, см. 1512 -- услуги по рыбнадзору, рыбоохране и патрулированию, см. 7523 -- ловлю рыбы в спортивных целях или для отдыха и связанные с ней услуги, см. 9241 -- услуги по спортивной ловле рыбы, см. 9241" -210,"050","Рыболовство, аквакультура и услуги, связанные с рыболовством",, -200,"05","Рыболовство, аквакультура и услуги, связанные с рыболовством","Рыболовство определяется как использование морской и пресноводной среды с целью лова или добычи рыбы, ракообразных, моллюсков и других морских материалов (например, жемчуга, губок и т. п.). -Подраздел 05 также включает деятельность рыбопитомников и другой аквакультуры, дающей аналогичные материалы. В подраздел включена деятельность, которая в обычных условиях входит в процесс производства другого продукта (например, разведение устриц для получения жемчуга). -Подраздел 05 не включает строительство и ремонт судов и лодок (3511, 3512), ловлю рыбы в спортивных целях или с целью развлечения и связанные с ней услуги (9249). Исключена переработка рыбы, ракообразных и моллюсков как на рыбозаводах, расположенных на берегу, так и на борту судов (рыбная промышленность: 1512). Однако переработка, выполняемая на борту рыболовных судов, классифицируется в подразделе 05.", -190,"B","Рыболовство","См. описание подраздела 05.", -180,"0200","Лесоводство, лесозаготовки и связанные с этим услуги","Эта подгруппа включает: -- выращивание строевого леса: посадку, пересадку, высадку саженцев, прореживание и охрану лесов и лесосек -- выращивание подлеска и балансовой древесины -- функционирование лесопитомников -- выращивание рождественских деревьев -- лесозаготовки: валка леса и производство необработанных лесоматериалов, например крепежного леса, бревен для столбов, кольев или топливной древесины -- предоставление услуг лесному хозяйству: таксация леса, оценка леса, борьба с пожарами и противопожарная защита, управление лесным хозяйством, включая облесение и лесовосстановление -- лесозаготовительные услуги: транспортировка бревен в пределах леса -- производство древесного угля, полученного в пределах леса - -Эта подгруппа также включает: -- сбор дикорастущих лесных материалов, исключая грибы, трюфели, ягоды и орехи; балаты и других резиноподобных живиц, пробки, шеллака, смол, бальзамов, кукушкина льна, взморника морского, желудей, конских каштанов, мхов, лишайников","Эта подгруппа не включает: -- разведение и сбор грибов и трюфелей, см. 0112 -- сбор ягод и орехов, см. 0113 -- производство древесной стружки, см. 2010 -- производство древесного угля посредством сухой перегонки древесины, см. 2411" -170,"020","Лесоводство, лесозаготовки и связанные с этим услуги",, -160,"02","Лесоводство, лесозаготовки и связанные с этим услуги","Лесоводство включает производство строевого леса, а также вырубку и заготовку дикорастущих лесных материалов, исключая грибы, трюфели, ягоды и орехи. Кроме производства лесоматериалов лесоводство дает продукты, которые подвергаются незначительной обработке, такой как подготовка лесоматериалов на топливо или для промышленного использования (например, рудничные стойки, древесная пульпа и т. п.). -Дальнейшая обработка древесины, начиная с распиловки и строгания, которая обычно проводится за пределами лесозаготовительной зоны, классифицируется в подразделе 20 (Производство лесоматериалов и изделий из древесины).", -150,"0150","Охота, ловля и разведение дичи, включая связанные с этим услуги","Эта подгруппа включает: -- охоту и ловлю в коммерческих целях -- отбор животных (мертвых или живых) для употребления в пищу, получения меха, кожи или для использования в исследовательской работе, для помещения в зоопарки или для выращивания в домашних условиях -- производство пушнины, кожи пресмыкающихся и птиц в результате охоты и ловли -- разведение дичи -- услуги по содействию развитию охоты и ловли в коммерческих целях - -Эта подгруппа также включает: -- отлов морских млекопитающих, например моржей и тюленей (за исключением китов)","Эта подгруппа не включает: -- производство пушнины, кожи пресмыкающихся и птиц в результате разведения животных на фермах, см. 0122 -- разведение дичи на фермах, см. 0122 -- отлов китов, см. 0501 -- производство шкур и кож в результате деятельности скотобоен, см. 1511 -- услуги по содействию охоте в спортивных целях или с целью развлечения, см. 9241" -140,"015","Охота, ловля и разведение дичи, включая связанные с этим услуги",, -130,"0140","Сельскохозяйственные услуги и услуги в области животноводства, кроме ветеринарных услуг","Эта подгруппа включает: -- сельскохозяйственные услуги за вознаграждение или на договорной основе (кроме ветеринарных услуг): -* деятельность ферм -* подготовку полей -* внедрение культуры -* обработку культур -* опрыскивание культуры, включая обработку с воздуха -* обрезку плодовых деревьев и виноградников -* посадку риса, прореживание свеклы -* сбор и обработку культур для первичного сбыта, то есть очистка, подравнивание, сортировка, дезинфекция, нанесение воскового покрытия, полировка, обертывание, удаление шелухи, мочка волокон, охлаждение или упаковывание навалом, включая упаковывание в газовой атмосфере, не содержащей кислорода -* очистку хлопка от семян -* услуги по стимулированию разведения, роста и продуктивности животных -* обследование состояния стада, перегонку скота, выпас скота, выхолащивание домашней птицы, чистка клеток и т. п. -* деятельность, связанная с искусственным осеменением -* стрижку овец -* временное содержание сельскохозяйственных животных и уход за ними -* борьбу с вредителями (включая кроликов) сельского хозяйства -- работу оросительных систем -- ландшафтное планирование при строительстве и уход за ландшафтом и его перепланировку, таким как: -* парки и сады для -** частного и государственного жилищного строительства -** зданий частичной и полной государственной собственности (школы, больницы, административные здания, церкви и т. п.) -** муниципальных земель (парки, зеленые зоны, кладбища и т. п.) -** озеленения транспортных магистралей (дороги, железнодорожные и трамвайные линии, водные пути, порты) -** промышленных и коммерческих зданий -* озеленение зданий (сады на крышах, озеленение фасадов, крытые сады) -* спортивные площадки, игровые площадки и другие парковые зоны отдыха (спортивные площадки, площадки для игр, лужайки для принятия солнечных ванн, поля для гольфа) -* водные пространства со стоячей и проточной водой (бассейны, другие зоны увлажнения, пруды, плавательные бассейны, канавы, судоходные каналы, системы стока с полей) -* посадку растений и ландшафтные работы для защиты от шума, ветра, эрозии, визуального обзора и ослепления транспортными средствами -- ландшафтные работы для защиты окружающей среды и природы, а также принятие мер по поддержанию ландшафта (акклиматизация, рекультивация, мелиорация, зоны сохранения, бассейны для принятия избытка воды при наводнениях и т. п.) -- лесоводство и прореживание деревьев, включая обрезку ветвей на деревьях и живых изгородях, пересадку больших деревьев - -Эта подгруппа также включает: -- предоставление сельскохозяйственных машин с операторами и бригадой","Эта подгруппа не включает: -- предоставление услуг по откорму скота, см. 0121, 0122 -- услуги по содействию развитию охоты и ловли в коммерческих целях, см. 0150 -- подготовку растительных волокон для прядения, см. 1711 -- услуги по сбыту, предоставляемые комиссионными закупщиками и кооперативными ассоциациями, см. подраздел 51 -- услуги агрономов и экономистов-аграрников, см. 7414 -- ландшафтная архитектура, см. 7421 -- организацию сельскохозяйственных выставок и ярмарок, см. 7499 -- ветеринарные услуги, см. 8520 -- места для временного содержания домашних животных, см. 9309" -120,"014","Сельскохозяйственные услуги и услуги в области животноводства, кроме ветеринарных услуг",, -110,"0130","Выращивание культур в сочетании с животноводством (смешанное сельское хозяйство)","Эта подгруппа включает: -- выращивание культур в сочетании с разведением крупного рогатого скота в смешанных хозяйствах, в которых коэффициент специализации в любой из отраслей не превышает 66 процентов","Эта подгруппа не включает: -- смешанные земледельческие или смешанные животноводческие хозяйства, см. классификацию по видам их основной деятельности" -100,"013","Выращивание культур в сочетании с животноводством (смешанное сельское хозяйство)",, -90,"0122","Прочее животноводство; производство продуктов животного происхождения, не включенных в другие категории","Эта подгруппа включает: -- свиноводство -- разведение домашней птицы: -* индеек, уток, цыплят, гусей, цесарок -- производство яиц -- выведение цыплят -- разведение полуодомашненных или диких животных: -* птиц, насекомых, кроликов и других пушных зверей -- производство пушнины, кожи пресмыкающихся и птиц в результате разведения животных на фермах -- деятельность ферм по разведению собак и кошек, червей, сухопутных моллюсков, лягушек и т. п. -- разведение шелковичных червей, производство коконов шелковичных червей -- пчеловодство и производство меда и пчелиного воска -- разведение других животных","Эта подгруппа не включает: -- временное содержание сельскохозяйственных животных и уход за ними, см. 0140 -- производство шкур и кож в результате охоты и промысла, см. 0150 -- деятельность рыбных ферм, см. 0502 -- производство шкур и кож на скотобойнях, см. 1511 -- производство пера и пуха, см. 1511 -- обучение служебных собак для охраны, см. 7492 -- обучение домашних животных, см. 9309" -80,"0121","Разведение крупного рогатого скота, овец, коз, лошадей, ослов, мулов и лошаков; молочное хозяйство","Эта подгруппа включает: -- разведение крупного рогатого скота -- разведение и улучшение пород лошадей, ослов, мулов и лошаков -- разведение овец и коз -- производство свежего коровьего молока -- производство свежего овечьего и козьего молока -- заготовку шерсти -- производство бычьей спермы","Эта подгруппа не включает: -- стрижку овец за вознаграждение или на договорной основе, см. 0140 -- содержание и селекцию животных и уход за ними, см. 0140 -- производство щипаной шерсти, см. 1511 -- переработку молока за пределами фермы, см. 1520 -- деятельность конюшен для скаковых лошадей и школ верховой езды, см. 9241" -70,"012","Животноводство",, -60,"0113","Выращивание фруктов, орехов, культур для производства напитков и пряностей","Эта подгруппа включает: -- выращивание плодов: яблок, груш, цитрусовых, абрикосов, земляники, ягод, вишни, персиков, бананов, авокадо, гуайявы, фиников и т. п. -- выращивание винограда для производства вина и столового винограда -- производство вина из винограда, выращенного в том же хозяйстве (отнесено сюда в порядке исключения) -- выращивание съедобных орехов, включая кокосовые орехи -- выращивание культур для изготовления напитков, таких как кофе, какао, чай, матэ -- выращивание пряных культур, таких как: -* семена: анис, кориандр, тмин -* листья: лавровый лист, базилик, тимьян -* цветы: корица -* плоды: гвоздика -* другие пряности: имбирь, мускатный орех -- выращивание маслин - -Эта подгруппа также включает: -- сбор ягод и орехов","Эта подгруппа не включает: -- выращивание арахиса, см. 0111 -- выращивание шишек хмеля, см. 0111 -- выращивание плодоовощных культур, например томатов, бахчевых, огурцов и т. п., см. 0112 -- выращивание свежих ""перцев"", петрушки и эстрагона, см. 0112 -- производство оливкового масла, см. 1514 -- производство какао, см. 1543 -- обработку чайного листа и кофе, см. 1549 -- производство вин из винограда, выращенного в другом хозяйстве, см. 1552" -50,"0112","Выращивание овощей, специализированное садоводство и производство продукции питомников","Эта подгруппа включает: -- выращивание овощей: томатов, бахчевых культур, тыквы, лука, капусты, латука, огурцов, моркови, бобовых, сахарной кукурузы, кабачков, баклажанов, лука-порея -- выращивание трав и овощных культур, используемых в качестве приправ: каперсов, ""перцев"", фенхеля, петрушки, кервеля, эстрагона, кресс-салата, душицы -- разведение грибов, сбор лесных грибов или трюфелей -- выращивание цветов и цветочных бутонов -- производство семян цветов, фруктов и овощей -- выращивание культур для посадки или декоративных целей, включая дерн для пересадки -- сбор сока и производство кленового сиропа и сахара","Эта подгруппа не включает: -- выращивание картофеля, см. 0111 -- выращивание сахарной свеклы, см. 0111 -- выращивание масличных семян или маслосодержащих плодов, см. 0111 -- выращивание корнеплодов и клубней с высоким содержанием крахмала или инулина, см. 0111 -- выращивание хлопка и других растительных текстильных материалов, см. 0111 -- выращивание пряных культур, см. 0113 -- выращивание кофе, какао-бобов, чая или матэ, см. 0113 -- выращивание маслин, см. 0113 -- работу в лесопитомниках, см. 0200 -- выращивание рождественских деревьев, см. 0200" -40,"0111","Выращивание зерновых и прочих культур, не включенных в другие категории","Эта подгруппа включает: -- выращивание однолетних и многолетних культур -- зерновые культуры: рис, твердая и мягкая пшеница, рожь, ячмень, овес, маис, кукуруза (кроме сахарной кукурузы) и т. п. -- выращивание картофеля, ямса, сладкого картофеля или маниоки -- выращивание сахарной свеклы, сахарного тростника или зернового сорго -- выращивание табака, включая его первичную обработку; сбор и сушка табачного листа -- выращивание масличных семян или маслосодержащих плодов и орехов: арахис, соя, рапс и т. п. -- производство семян сахарной свеклы и семян фуражных культур (включая травы) -- выращивание шишек хмеля, корнеплодов и клубней с высоким содержанием крахмала или инулина -- выращивание хлопка и других растительных текстильных материалов -- мочку растений, содержащих растительное волокно (джут, лен, кокосовое волокно) -- выращивание каучуконосных деревьев, сбор латекса -- выращивание бобовых, таких как полевой горох и бобы -- выращивание растений, используемых главным образом в фармации или в качестве инсектицидов, фунгицидов, а также для других аналогичных целей -- выращивание культур, не включенных в другие категории","Эта подгруппа не включает: -- выращивание бахчевых культур, см. 0112 -- выращивание сахарной кукурузы, см. 0112 -- выращивание других овощей, см. 0112 -- выращивание цветов, см. 0112 -- производство семян цветов и овощей, см. 0112 -- выращивание специальных садовых культур, см. 0112 -- выращивание маслин, см. 0113 -- выращивание культур для производства напитков, см. 0113 -- выращивание пряных культур, см. 0113 -- выращивание съедобных орехов, см. 0113 -- сбор лесных продуктов и других дикорастущих сырьевых материалов (таких как пробка, смолы, бальзамы и т. п.), см. 0200" -30,"011","Выращивание культур; товарное овощеводство; садоводство","Эта группа включает выращивание культур, овощей и фруктов в открытом или закрытом грунте.", -20,"01","Сельское хозяйство, охота и связанные с этим услуги","Подраздел 01 включает два основных вида деятельности: -* Производство продуктов растениеводства (011: Выращивание культур) -* Производство продуктов животного происхождения (012: Животноводство). -Группа 011 делится следующим образом: -* Производство полевых культур, обычно выращиваемых по годовому циклу (0111, 0112), таких как зерновые культуры, овощи и цветы -* Производство культур с продолжительным циклом, таких как культуры, выращиваемые на плантациях (например, кофе, какао и т. п.), виноградники и фруктовые сады (0113). -В группе 012 (Животноводство) виды деятельности группируются в соответствии с классификацией животных, а не в соответствии с классификацией изготавливаемых продуктов (например, мясо, молоко, кожа и т. п.) и без различий между выращиванием исключительно в ограниченном пространстве (вне пастбища) и разведением на открытых пастбищах. -Группа 013 (Смешанное сельское хозяйство) классифицируется не в соответствии с обычными принципами обозначения основной деятельности. Здесь допускается, что на многих сельскохозяйственных фермах производство культур в разумной мере сбалансировано с разведением животных, и отнесение их к одной или другой из этих категорий было бы произвольным. -Некоторые операции, такие как подготовка почвы, посадка, уборка и управление, обычно являющиеся составными частями сельскохозяйственных работ, могут выполняться другими сельскохозяйственными организациями за вознаграждение или на договорной основе в виде предоставления сельскохозяйственных услуг или услуг в области животноводства (0140). -Из сельскохозяйственной деятельности исключается любая последующая обработка сельскохозяйственных продуктов [отнесенных к подразделу 15 (Производство пищевых продуктов и напитков) и к подразделу 16 (Производство табачных изделий)], кроме той обработки, которая требуется для подготовки продуктов для первичных рынков. Однако, в виде исключения из общего правила классификации смешанных видов деятельности, хозяйство, выращивающее виноград и производящее вино в одной и той же местности, отнесено к подразделу 01, хотя обычно конечным результатом является продукт, включенный в подраздел 15. -Из подраздела исключено строительство в поле (например, устройство сельскохозяйственных террас, дренаж, подготовка рисовых чеков и т. п.), классифицируемое в подразделе 45 (Строительство); закупочные и кооперативные объединения, занимающиеся торговлей продуктами сельского хозяйства, отнесены к разделу G.", -10,"A","Сельское хозяйство, охота и лесоводство","Раздел А охватывает использование растительных и животных природных ресурсов. Этот раздел включает такую деятельность, как выращивание культур, разведение животных, лесозаготовки, выращивание и использование других растений и животных на ферме или взятых в природной среде обитания.", -2840,"455","Аренда оборудования с оператором для строительства или сноса",, -3420,"I","Транспорт, складское хозяйство и связь"," Этот раздел включает: -- деятельность, связанную с услугами пассажирского или грузового транспорта, подчиняющегося или не подчиняющегося расписанию, железнодорожного, трубопроводного, автомобильного, водного или воздушного -- вспомогательную деятельность, такую как услуги терминалов и мест стоянки, транспортная обработка грузов, хранение и т. п. -- деятельность почт и связь -- аренду транспортного оборудования с водителем или оператором","Этот раздел не включает: -- капитальный ремонт или переделку транспортного оборудования, кроме автомобилей, см. подраздел 35 -- строительство, техническое обслуживание и ремонт автомобильных и железных дорог, гаваней, полей аэродромов, см. 4520 -- техническое обслуживание и ремонт автомобилей, см. 5020 -- аренду транспортного оборудования без водителя или оператора, см. группу 711" diff --git a/backend/db/data/jurisdiction_codes_analysis.md b/backend/db/data/jurisdiction_codes_analysis.md new file mode 100644 index 0000000..1763f5f --- /dev/null +++ b/backend/db/data/jurisdiction_codes_analysis.md @@ -0,0 +1,136 @@ +# Анализ кодов по юрисдикциям для DLE + +## 🌍 ГЛОБАЛЬНЫЕ (МЕЖДУНАРОДНЫЕ) КОДЫ + +### Используются во ВСЕХ юрисдикциях: +- **ISO 3166-1** - Коды стран ✅ (у нас есть) +- **ISO 4217** - Коды валют ❌ (нужно создать) +- **ISIC Rev.4** - Международная стандартная отраслевая классификация ✅ (у нас есть CSV) +- **HS Codes** - Гармонизированная система описания и кодирования товаров ❌ (нужно создать) + +## 🇷🇺 РОССИЙСКАЯ ФЕДЕРАЦИЯ + +### Обязательные для регистрации юридических лиц: +- **ОКВЭД** - Виды экономической деятельности ✅ +- **ОКАТО/ОКТМО** - Территориальные коды ✅ +- **КПП** - Коды причин постановки на учет ✅ + +### Для налогообложения и отчетности: +- **КБК** - Коды бюджетной классификации ✅ +- **ОКПД2** - Продукция по видам деятельности ✅ +- **ОКУН** - Услуги населению ✅ +- **ТН ВЭД** - Товарная номенклатура внешнеэкономической деятельности ✅ + +### Статистические и отчетные: +- **Коды операций** ✅ +- **Формы отчетности** ✅ + +## 🇺🇸 СОЕДИНЕННЫЕ ШТАТЫ АМЕРИКИ + +### Обязательные для бизнеса: +- **NAICS** - North American Industry Classification System ❌ +- **State Codes** - Коды штатов ❌ +- **EIN/SSN** - Налоговые идентификаторы (не коды, генерируются) +- **SIC Codes** - Standard Industrial Classification ❌ + +### Федеральные коды: +- **Federal Tax Codes** ❌ +- **DUNS Numbers** (не коды, но важно для B2B) + +## 🇪🇺 ЕВРОПЕЙСКИЙ СОЮЗ + +### Общеевропейские: +- **NACE Rev.2** - Статистическая классификация экономических видов деятельности ❌ +- **VAT Codes** - НДС коды по странам ЕС ❌ +- **IBAN Country Codes** - для банковских операций ❌ + +### Германия: +- **WZ 2008** - Классификация экономической деятельности ❌ +- **Bundesland Codes** - Коды федеральных земель ❌ + +### Франция: +- **NAF** - Nomenclature d'Activités Française ❌ +- **APE Codes** - Коды основной деятельности ❌ + +## 🇬🇧 ВЕЛИКОБРИТАНИЯ + +### После Brexit: +- **SIC 2007** - Standard Industrial Classification ❌ +- **UK Region Codes** ❌ +- **Companies House Codes** ❌ + +## 🇨🇳 КИТАЙ + +### Для иностранных компаний: +- **GB/T 4754** - Отраслевая классификация ❌ +- **Administrative Division Codes** - Коды административных единиц ❌ + +## 🇯🇵 ЯПОНИЯ + +### Коды для бизнеса: +- **JSIC** - Japan Standard Industrial Classification ❌ +- **Prefecture Codes** - Коды префектур ❌ + +## 📊 ПРИОРИТИЗАЦИЯ ДЛЯ DLE + +### 🔴 КРИТИЧНО (нужно создать немедленно): +1. **ISO 4217** - Коды валют (для всех стран) +2. **NAICS** - США (крупнейшая экономика) +3. **NACE Rev.2** - ЕС (большой рынок) + +### 🟡 ВАЖНО (следующая очередь): +4. **SIC 2007** - Великобритания +5. **State Codes** - США (штаты) +6. **VAT Codes** - ЕС + +### 🟢 ЖЕЛАТЕЛЬНО (по запросу): +7. Азиатские юрисдикции (Китай, Япония) +8. Другие развитые страны + +## 🎯 АРХИТЕКТУРНОЕ РЕШЕНИЕ + +### Структура файлов: +``` +/backend/db/data/ +├── global/ +│ ├── countries.json ✅ +│ ├── currencies.json ❌ +│ ├── isic.json ❌ (конвертировать из CSV) +│ └── hs_codes.json ❌ +├── jurisdictions/ +│ ├── RU/ ✅ (все файлы готовы) +│ ├── US/ +│ │ ├── naics.json ❌ +│ │ ├── states.json ❌ +│ │ └── sic.json ❌ +│ ├── EU/ +│ │ ├── nace.json ❌ +│ │ ├── vat_codes.json ❌ +│ │ └── countries/ (DE, FR, IT, etc.) +│ └── GB/ +│ ├── sic_2007.json ❌ +│ └── regions.json ❌ +``` + +## 🚀 ПЛАН РЕАЛИЗАЦИИ + +### Фаза 1 (немедленно): +- [ ] Создать currencies.json (ISO 4217) +- [ ] Конвертировать ISIC из CSV в JSON +- [ ] Создать базовую структуру папок + +### Фаза 2 (первый квартал): +- [ ] Добавить NAICS (США) +- [ ] Добавить NACE Rev.2 (ЕС) +- [ ] Добать коды штатов США + +### Фаза 3 (по требованию): +- [ ] Расширение по другим юрисдикциям +- [ ] Локализация названий кодов + +## 💡 КЛЮЧЕВЫЕ ПРИНЦИПЫ + +1. **Модульность** - каждая юрисдикция в отдельной папке +2. **Стандартизация** - единый формат JSON для всех кодов +3. **Глобальность** - приоритет международным стандартам +4. **Практичность** - фокус на реально используемых юрисдикциях \ No newline at end of file diff --git a/backend/db/data/kbk.json b/backend/db/data/kbk.json new file mode 100644 index 0000000..20759d1 --- /dev/null +++ b/backend/db/data/kbk.json @@ -0,0 +1,176 @@ +{ + "kbk_codes": [ + { + "code": "18210102010011000110", + "title": "НДС на товары (работы, услуги), реализуемые на территории Российской Федерации" + }, + { + "code": "18210102020011000110", + "title": "НДС на товары, ввозимые на территорию Российской Федерации" + }, + { + "code": "18210102030011000110", + "title": "НДС на товары (работы, услуги), реализуемые на территории Российской Федерации в соответствии со статьей 174.1 НК РФ" + }, + { + "code": "18210102040011000110", + "title": "НДС при ввозе товаров на территорию Российской Федерации в соответствии со статьей 174.1 НК РФ" + }, + { + "code": "18210102050011000110", + "title": "НДС при ввозе товаров на территорию Российской Федерации (взимается таможенными органами)" + }, + { + "code": "18210301000011000110", + "title": "Налог на прибыль организаций, зачисляемый в федеральный бюджет" + }, + { + "code": "18210301010011000110", + "title": "Налог на прибыль организаций с доходов в виде процентов по государственным и муниципальным ценным бумагам" + }, + { + "code": "18210501000011000110", + "title": "Налог, взимаемый в связи с применением упрощенной системы налогообложения" + }, + { + "code": "18210601000011000110", + "title": "Единый налог на вмененный доход для отдельных видов деятельности" + }, + { + "code": "18210701000011000110", + "title": "Единый сельскохозяйственный налог" + }, + { + "code": "18210801000011000110", + "title": "Налог на добычу полезных ископаемых" + }, + { + "code": "18210901000011000110", + "title": "Водный налог" + }, + { + "code": "18211001000011000110", + "title": "Сборы за пользование объектами животного мира и за пользование объектами водных биологических ресурсов" + }, + { + "code": "18211201000011000110", + "title": "Государственная пошлина" + }, + { + "code": "18211301000011000110", + "title": "Акцизы на спирт этиловый из пищевого сырья" + }, + { + "code": "18211302000011000110", + "title": "Акцизы на спирт этиловый из всех видов сырья" + }, + { + "code": "18211303000011000110", + "title": "Акцизы на спиртосодержащую продукцию" + }, + { + "code": "18211304000011000110", + "title": "Акцизы на табачную продукцию" + }, + { + "code": "18211305000011000110", + "title": "Акцизы на автомобили легковые" + }, + { + "code": "18211306000011000110", + "title": "Акцизы на мотоциклы и мотороллеры" + }, + { + "code": "18211307000011000110", + "title": "Акцизы на автомобильный бензин" + }, + { + "code": "18211308000011000110", + "title": "Акцизы на дизельное топливо" + }, + { + "code": "18211309000011000110", + "title": "Акцизы на моторные масла для дизельных и (или) карбюраторных (инжекторных) двигателей" + }, + { + "code": "18211310000011000110", + "title": "Акцизы на прямогонный бензин" + }, + { + "code": "18211311000011000110", + "title": "Акцизы на средние дистилляты" + }, + { + "code": "18211312000011000110", + "title": "Акцизы на бензол, толуол, ксилол" + }, + { + "code": "18212201000011000110", + "title": "Подоходный налог с физических лиц" + }, + { + "code": "18212801000011000110", + "title": "Налог на имущество физических лиц" + }, + { + "code": "18212901000011000110", + "title": "Земельный налог" + }, + { + "code": "18213001000011000110", + "title": "Торговый сбор" + }, + { + "code": "18213301000011000110", + "title": "Налог на имущество организаций" + }, + { + "code": "18213401000011000110", + "title": "Транспортный налог" + }, + { + "code": "18213501000011000110", + "title": "Налог на игорный бизнес" + }, + { + "code": "18220000000000000000", + "title": "Неналоговые доходы" + }, + { + "code": "18221000000000000000", + "title": "Доходы от использования имущества, находящегося в государственной и муниципальной собственности" + }, + { + "code": "18222000000000000000", + "title": "Платежи при пользовании природными ресурсами" + }, + { + "code": "18223000000000000000", + "title": "Доходы от оказания платных услуг и компенсации затрат государства" + }, + { + "code": "18224000000000000000", + "title": "Доходы от продажи материальных и нематериальных активов" + }, + { + "code": "18225000000000000000", + "title": "Административные платежи и сборы" + }, + { + "code": "18226000000000000000", + "title": "Штрафы, санкции, возмещение ущерба" + }, + { + "code": "18227000000000000000", + "title": "Прочие неналоговые доходы" + }, + { + "code": "18230000000000000000", + "title": "Безвозмездные поступления" + }, + { + "code": "18240000000000000000", + "title": "Доходы от предпринимательской и иной приносящей доход деятельности" + } + ] +} \ No newline at end of file diff --git a/backend/db/data/kpp_codes.json b/backend/db/data/kpp_codes.json new file mode 100644 index 0000000..4327190 --- /dev/null +++ b/backend/db/data/kpp_codes.json @@ -0,0 +1,44 @@ +{ + "kpp_codes": [ + { + "code": "773001001", + "title": "По месту нахождения организации" + }, + { + "code": "773002001", + "title": "По месту нахождения обособленного подразделения" + }, + { + "code": "773003001", + "title": "По месту нахождения недвижимого имущества" + }, + { + "code": "773004001", + "title": "По месту нахождения транспортных средств" + }, + { + "code": "773005001", + "title": "По месту нахождения судна" + }, + { + "code": "773006001", + "title": "По месту нахождения воздушного судна" + }, + { + "code": "773007001", + "title": "По месту нахождения космического объекта" + }, + { + "code": "773008001", + "title": "По месту нахождения иного объекта" + }, + { + "code": "773009001", + "title": "По месту нахождения организации в связи с изменением места нахождения" + }, + { + "code": "773010001", + "title": "По месту нахождения организации в связи с изменением места нахождения обособленного подразделения" + } + ] +} \ No newline at end of file diff --git a/backend/db/data/okpd2.json b/backend/db/data/okpd2.json new file mode 100644 index 0000000..e9464fe --- /dev/null +++ b/backend/db/data/okpd2.json @@ -0,0 +1,264 @@ +{ + "okpd2_codes": [ + { + "code": "01.11.11", + "title": "Пшеница" + }, + { + "code": "01.11.12", + "title": "Кукуруза" + }, + { + "code": "01.11.13", + "title": "Ячмень" + }, + { + "code": "01.11.14", + "title": "Рожь" + }, + { + "code": "01.11.15", + "title": "Овес" + }, + { + "code": "01.11.19", + "title": "Зерновые культуры прочие" + }, + { + "code": "01.12.11", + "title": "Рис необработанный" + }, + { + "code": "01.13.11", + "title": "Овощи свежие или охлажденные" + }, + { + "code": "01.13.12", + "title": "Овощи замороженные" + }, + { + "code": "01.13.13", + "title": "Овощи сушеные" + }, + { + "code": "01.14.11", + "title": "Сахарная свекла" + }, + { + "code": "01.15.11", + "title": "Табак необработанный" + }, + { + "code": "01.16.11", + "title": "Хлопок-волокно" + }, + { + "code": "01.19.11", + "title": "Культуры прочие" + }, + { + "code": "01.21.11", + "title": "Виноград" + }, + { + "code": "01.22.11", + "title": "Фрукты тропические и субтропические" + }, + { + "code": "01.23.11", + "title": "Цитрусовые" + }, + { + "code": "01.24.11", + "title": "Фрукты семечковые и косточковые" + }, + { + "code": "01.25.11", + "title": "Ягоды и орехи" + }, + { + "code": "01.26.11", + "title": "Плоды масличных культур" + }, + { + "code": "01.27.11", + "title": "Растения для производства напитков" + }, + { + "code": "01.28.11", + "title": "Специи, пряно-ароматические, эфиромасличные и лекарственные культуры" + }, + { + "code": "01.29.11", + "title": "Культуры многолетние прочие" + }, + { + "code": "10.11.11", + "title": "Мясо и пищевые субпродукты крупного рогатого скота и буйволов, свежие или охлажденные" + }, + { + "code": "10.11.12", + "title": "Мясо и пищевые субпродукты свиней, свежие или охлажденные" + }, + { + "code": "10.11.13", + "title": "Мясо и пищевые субпродукты овец, коз, лошадей и других животных, свежие или охлажденные" + }, + { + "code": "10.12.11", + "title": "Мясо и пищевые субпродукты, замороженные" + }, + { + "code": "10.13.11", + "title": "Продукты мясные" + }, + { + "code": "10.20.11", + "title": "Рыба переработанная и консервированная" + }, + { + "code": "10.20.12", + "title": "Ракообразные и моллюски переработанные и консервированные" + }, + { + "code": "10.31.11", + "title": "Картофель переработанный и консервированный" + }, + { + "code": "10.32.11", + "title": "Соки фруктовые и овощные" + }, + { + "code": "10.39.11", + "title": "Фрукты и овощи переработанные и консервированные прочие" + }, + { + "code": "10.41.11", + "title": "Масла и жиры" + }, + { + "code": "10.51.11", + "title": "Молоко жидкое обработанное" + }, + { + "code": "10.51.12", + "title": "Сливки" + }, + { + "code": "10.52.11", + "title": "Мороженое" + }, + { + "code": "10.53.11", + "title": "Масло сливочное" + }, + { + "code": "10.53.12", + "title": "Сыр и творог" + }, + { + "code": "10.61.11", + "title": "Мука, крупа и прочие продукты помола зерна" + }, + { + "code": "10.62.11", + "title": "Крахмалы и крахмалопродукты" + }, + { + "code": "10.71.11", + "title": "Хлеб и мучные кондитерские изделия недлительного хранения" + }, + { + "code": "10.72.11", + "title": "Сухари, печенье и прочие хлебобулочные изделия длительного хранения" + }, + { + "code": "10.73.11", + "title": "Макаронные изделия" + }, + { + "code": "10.81.11", + "title": "Сахар" + }, + { + "code": "10.82.11", + "title": "Какао, шоколад и сахаристые кондитерские изделия" + }, + { + "code": "10.83.11", + "title": "Чай и кофе переработанные" + }, + { + "code": "10.84.11", + "title": "Приправы и пряности" + }, + { + "code": "10.85.11", + "title": "Блюда готовые" + }, + { + "code": "10.86.11", + "title": "Продукты детского питания и диетические продукты" + }, + { + "code": "10.89.11", + "title": "Продукты пищевые прочие" + }, + { + "code": "11.01.11", + "title": "Спирт этиловый неденатурированный с концентрацией спирта 80% и выше" + }, + { + "code": "11.02.11", + "title": "Вино виноградное" + }, + { + "code": "11.03.11", + "title": "Сидр и прочие плодовые вина" + }, + { + "code": "11.04.11", + "title": "Напитки прочие ферментированные" + }, + { + "code": "11.05.11", + "title": "Пиво" + }, + { + "code": "11.06.11", + "title": "Солод" + }, + { + "code": "11.07.11", + "title": "Напитки безалкогольные" + }, + { + "code": "62.01.1", + "title": "Услуги по разработке, производству, поставке и документированию заказного программного обеспечения" + }, + { + "code": "62.01.2", + "title": "Услуги по разработке, производству, поставке и документированию системного программного обеспечения" + }, + { + "code": "62.02.1", + "title": "Услуги консультативные и работы в области компьютерных технологий" + }, + { + "code": "62.03.1", + "title": "Услуги по управлению компьютерным оборудованием" + }, + { + "code": "63.11.1", + "title": "Услуги по обработке данных" + }, + { + "code": "63.11.2", + "title": "Услуги по размещению информации" + }, + { + "code": "63.12.1", + "title": "Услуги web-порталов" + } + ] +} \ No newline at end of file diff --git a/backend/db/data/oktmo.json b/backend/db/data/oktmo.json new file mode 100644 index 0000000..349b2d8 --- /dev/null +++ b/backend/db/data/oktmo.json @@ -0,0 +1,344 @@ +{ + "oktmo_codes": [ + { + "code": "45000000", + "title": "Москва" + }, + { + "code": "40000000", + "title": "Санкт-Петербург" + }, + { + "code": "46000000", + "title": "Московская область" + }, + { + "code": "41000000", + "title": "Ленинградская область" + }, + { + "code": "79000000", + "title": "Республика Адыгея" + }, + { + "code": "80000000", + "title": "Республика Башкортостан" + }, + { + "code": "81000000", + "title": "Республика Бурятия" + }, + { + "code": "84000000", + "title": "Республика Алтай" + }, + { + "code": "82000000", + "title": "Республика Дагестан" + }, + { + "code": "26000000", + "title": "Республика Ингушетия" + }, + { + "code": "83000000", + "title": "Кабардино-Балкарская Республика" + }, + { + "code": "85000000", + "title": "Республика Калмыкия" + }, + { + "code": "91000000", + "title": "Карачаево-Черкесская Республика" + }, + { + "code": "86000000", + "title": "Республика Карелия" + }, + { + "code": "87000000", + "title": "Республика Коми" + }, + { + "code": "88000000", + "title": "Республика Марий Эл" + }, + { + "code": "89000000", + "title": "Республика Мордовия" + }, + { + "code": "98000000", + "title": "Республика Саха (Якутия)" + }, + { + "code": "90000000", + "title": "Республика Северная Осетия - Алания" + }, + { + "code": "92000000", + "title": "Республика Татарстан" + }, + { + "code": "93000000", + "title": "Республика Тыва" + }, + { + "code": "94000000", + "title": "Удмуртская Республика" + }, + { + "code": "95000000", + "title": "Республика Хакасия" + }, + { + "code": "96000000", + "title": "Чеченская Республика" + }, + { + "code": "97000000", + "title": "Чувашская Республика" + }, + { + "code": "01000000", + "title": "Алтайский край" + }, + { + "code": "03000000", + "title": "Краснодарский край" + }, + { + "code": "04000000", + "title": "Красноярский край" + }, + { + "code": "05000000", + "title": "Приморский край" + }, + { + "code": "07000000", + "title": "Ставропольский край" + }, + { + "code": "08000000", + "title": "Хабаровский край" + }, + { + "code": "10000000", + "title": "Амурская область" + }, + { + "code": "11000000", + "title": "Архангельская область" + }, + { + "code": "12000000", + "title": "Астраханская область" + }, + { + "code": "14000000", + "title": "Белгородская область" + }, + { + "code": "15000000", + "title": "Брянская область" + }, + { + "code": "17000000", + "title": "Владимирская область" + }, + { + "code": "18000000", + "title": "Волгоградская область" + }, + { + "code": "19000000", + "title": "Вологодская область" + }, + { + "code": "20000000", + "title": "Воронежская область" + }, + { + "code": "24000000", + "title": "Ивановская область" + }, + { + "code": "25000000", + "title": "Иркутская область" + }, + { + "code": "27000000", + "title": "Калининградская область" + }, + { + "code": "29000000", + "title": "Калужская область" + }, + { + "code": "30000000", + "title": "Камчатский край" + }, + { + "code": "32000000", + "title": "Кемеровская область - Кузбасс" + }, + { + "code": "33000000", + "title": "Кировская область" + }, + { + "code": "34000000", + "title": "Костромская область" + }, + { + "code": "37000000", + "title": "Курганская область" + }, + { + "code": "38000000", + "title": "Курская область" + }, + { + "code": "42000000", + "title": "Липецкая область" + }, + { + "code": "44000000", + "title": "Магаданская область" + }, + { + "code": "47000000", + "title": "Мурманская область" + }, + { + "code": "22000000", + "title": "Нижегородская область" + }, + { + "code": "49000000", + "title": "Новгородская область" + }, + { + "code": "50000000", + "title": "Новосибирская область" + }, + { + "code": "52000000", + "title": "Омская область" + }, + { + "code": "53000000", + "title": "Оренбургская область" + }, + { + "code": "54000000", + "title": "Орловская область" + }, + { + "code": "56000000", + "title": "Пензенская область" + }, + { + "code": "57000000", + "title": "Пермский край" + }, + { + "code": "58000000", + "title": "Псковская область" + }, + { + "code": "60000000", + "title": "Ростовская область" + }, + { + "code": "61000000", + "title": "Рязанская область" + }, + { + "code": "63000000", + "title": "Самарская область" + }, + { + "code": "64000000", + "title": "Саратовская область" + }, + { + "code": "65000000", + "title": "Сахалинская область" + }, + { + "code": "66000000", + "title": "Свердловская область" + }, + { + "code": "67000000", + "title": "Смоленская область" + }, + { + "code": "68000000", + "title": "Тамбовская область" + }, + { + "code": "28000000", + "title": "Тверская область" + }, + { + "code": "69000000", + "title": "Томская область" + }, + { + "code": "70000000", + "title": "Тульская область" + }, + { + "code": "71000000", + "title": "Тюменская область" + }, + { + "code": "73000000", + "title": "Ульяновская область" + }, + { + "code": "74000000", + "title": "Челябинская область" + }, + { + "code": "76000000", + "title": "Забайкальский край" + }, + { + "code": "78000000", + "title": "Ярославская область" + }, + { + "code": "99000000", + "title": "Еврейская автономная область" + }, + { + "code": "11100000", + "title": "Ненецкий автономный округ" + }, + { + "code": "71140000", + "title": "Ханты-Мансийский автономный округ - Югра" + }, + { + "code": "77000000", + "title": "Чукотский автономный округ" + }, + { + "code": "71180000", + "title": "Ямало-Ненецкий автономный округ" + }, + { + "code": "35000000", + "title": "Республика Крым" + }, + { + "code": "67000000", + "title": "Севастополь" + } + ] +} \ No newline at end of file diff --git a/backend/db/data/okun.json b/backend/db/data/okun.json new file mode 100644 index 0000000..36cbb4d --- /dev/null +++ b/backend/db/data/okun.json @@ -0,0 +1,260 @@ +{ + "okun_codes": [ + { + "code": "01001", + "title": "Услуги по ремонту и техническому обслуживанию автотранспортных средств" + }, + { + "code": "01002", + "title": "Услуги по ремонту и техническому обслуживанию мотоциклов" + }, + { + "code": "01003", + "title": "Услуги по мойке автотранспортных средств" + }, + { + "code": "01004", + "title": "Услуги стоянок для автотранспортных средств" + }, + { + "code": "01005", + "title": "Услуги по обучению вождению автотранспортных средств" + }, + { + "code": "02001", + "title": "Услуги парикмахерских" + }, + { + "code": "02002", + "title": "Косметические услуги" + }, + { + "code": "02003", + "title": "Услуги бань и душевых" + }, + { + "code": "02004", + "title": "Услуги соляриев" + }, + { + "code": "02005", + "title": "Массажные услуги" + }, + { + "code": "03001", + "title": "Услуги по ремонту и пошиву швейных, меховых и кожаных изделий" + }, + { + "code": "03002", + "title": "Услуги по ремонту и изготовлению металлоизделий" + }, + { + "code": "03003", + "title": "Услуги по ремонту и техническому обслуживанию бытовой техники" + }, + { + "code": "03004", + "title": "Услуги по ремонту и реставрации мебели" + }, + { + "code": "03005", + "title": "Услуги по ремонту и изготовлению изделий из дерева" + }, + { + "code": "04001", + "title": "Услуги фотоателье и фотолабораторий" + }, + { + "code": "04002", + "title": "Услуги по техническому обслуживанию и ремонту бытовой радиоэлектронной аппаратуры" + }, + { + "code": "04003", + "title": "Услуги по ремонту и настройке музыкальных инструментов" + }, + { + "code": "04004", + "title": "Услуги по ремонту спортивного инвентаря и туристского снаряжения" + }, + { + "code": "05001", + "title": "Ветеринарные услуги" + }, + { + "code": "05002", + "title": "Услуги прачечных" + }, + { + "code": "05003", + "title": "Услуги химчисток" + }, + { + "code": "05004", + "title": "Услуги по крашению" + }, + { + "code": "05005", + "title": "Услуги по дублению" + }, + { + "code": "06001", + "title": "Транспортные услуги" + }, + { + "code": "06002", + "title": "Услуги по хранению автотранспортных средств" + }, + { + "code": "06003", + "title": "Экспедиционные услуги" + }, + { + "code": "06004", + "title": "Погрузо-разгрузочные услуги" + }, + { + "code": "07001", + "title": "Услуги связи" + }, + { + "code": "07002", + "title": "Почтовые услуги" + }, + { + "code": "07003", + "title": "Телефонные и телеграфные услуги" + }, + { + "code": "08001", + "title": "Жилищно-коммунальные услуги" + }, + { + "code": "08002", + "title": "Услуги по эксплуатации жилого фонда" + }, + { + "code": "08003", + "title": "Услуги по управлению многоквартирными домами" + }, + { + "code": "09001", + "title": "Медицинские услуги" + }, + { + "code": "09002", + "title": "Санаторно-оздоровительные услуги" + }, + { + "code": "09003", + "title": "Услуги по уходу за больными" + }, + { + "code": "10001", + "title": "Услуги правового характера" + }, + { + "code": "10002", + "title": "Нотариальные услуги" + }, + { + "code": "10003", + "title": "Услуги по переводу" + }, + { + "code": "11001", + "title": "Услуги образования" + }, + { + "code": "11002", + "title": "Услуги по обучению населения на курсах" + }, + { + "code": "11003", + "title": "Услуги по повышению квалификации" + }, + { + "code": "12001", + "title": "Культурно-просветительские услуги" + }, + { + "code": "12002", + "title": "Услуги музеев" + }, + { + "code": "12003", + "title": "Услуги библиотек" + }, + { + "code": "13001", + "title": "Физкультурно-оздоровительные услуги" + }, + { + "code": "13002", + "title": "Туристские и экскурсионные услуги" + }, + { + "code": "13003", + "title": "Услуги по организации и проведению спортивных мероприятий" + }, + { + "code": "14001", + "title": "Услуги торжеств и развлечений" + }, + { + "code": "14002", + "title": "Услуги по организации праздников и зрелищных мероприятий" + }, + { + "code": "14003", + "title": "Услуги дискотек и танцевальных залов" + }, + { + "code": "15001", + "title": "Услуги по изготовлению и ремонту изделий из драгоценных металлов и камней" + }, + { + "code": "15002", + "title": "Услуги по изготовлению печатной продукции" + }, + { + "code": "15003", + "title": "Услуги по копированию" + }, + { + "code": "16001", + "title": "Услуги общественного питания" + }, + { + "code": "16002", + "title": "Услуги по доставке продуктов питания" + }, + { + "code": "16003", + "title": "Услуги по организации питания" + }, + { + "code": "17001", + "title": "Услуги гостиниц и аналогичных средств размещения" + }, + { + "code": "17002", + "title": "Услуги по предоставлению мест для краткосрочного проживания" + }, + { + "code": "17003", + "title": "Услуги кемпингов" + }, + { + "code": "18001", + "title": "Ритуальные услуги" + }, + { + "code": "18002", + "title": "Услуги по содержанию мест захоронения" + }, + { + "code": "18003", + "title": "Услуги крематориев" + } + ] +} \ No newline at end of file diff --git a/backend/db/data/okved.json b/backend/db/data/okved.json new file mode 100644 index 0000000..7992748 --- /dev/null +++ b/backend/db/data/okved.json @@ -0,0 +1,6712 @@ +{ + "okved_codes": [ + { + "code": "01.11", + "title": "Выращивание зерновых (кроме риса), зернобобовых культур и семян масличных культур" + }, + { + "code": "01.11.1", + "title": "Выращивание пшеницы" + }, + { + "code": "01.11.2", + "title": "Выращивание ячменя" + }, + { + "code": "01.11.3", + "title": "Выращивание ржи" + }, + { + "code": "01.11.4", + "title": "Выращивание кукурузы на зерно" + }, + { + "code": "01.11.5", + "title": "Выращивание овса" + }, + { + "code": "01.11.6", + "title": "Выращивание гречихи" + }, + { + "code": "01.11.7", + "title": "Выращивание проса" + }, + { + "code": "01.11.8", + "title": "Выращивание сорго" + }, + { + "code": "01.11.9", + "title": "Выращивание прочих зерновых культур" + }, + { + "code": "01.11.11", + "title": "Выращивание зернобобовых культур" + }, + { + "code": "01.11.12", + "title": "Выращивание семян масличных культур, кроме соевых бобов" + }, + { + "code": "01.11.13", + "title": "Выращивание соевых бобов" + }, + { + "code": "01.11.14", + "title": "Выращивание семян горчицы" + }, + { + "code": "01.11.15", + "title": "Выращивание семян подсолнечника" + }, + { + "code": "01.11.16", + "title": "Выращивание семян рапса" + }, + { + "code": "01.11.19", + "title": "Выращивание прочих масличных культур" + }, + { + "code": "01.12", + "title": "Выращивание риса" + }, + { + "code": "01.12.1", + "title": "Выращивание риса нешелушеного (риса-падди)" + }, + { + "code": "01.13", + "title": "Выращивание овощей, бахчевых, корнеплодных и клубнеплодных культур, грибов и трюфелей" + }, + { + "code": "01.13.1", + "title": "Выращивание овощей" + }, + { + "code": "01.13.11", + "title": "Выращивание овощей открытого грунта" + }, + { + "code": "01.13.12", + "title": "Выращивание овощей защищенного грунта" + }, + { + "code": "01.13.2", + "title": "Выращивание бахчевых культур" + }, + { + "code": "01.13.21", + "title": "Выращивание арбузов" + }, + { + "code": "01.13.22", + "title": "Выращивание дынь и прочих бахчевых культур" + }, + { + "code": "01.13.3", + "title": "Выращивание корнеплодных и клубнеплодных культур с высоким содержанием крахмала или инулина" + }, + { + "code": "01.13.31", + "title": "Выращивание картофеля" + }, + { + "code": "01.13.39", + "title": "Выращивание прочих корнеплодных и клубнеплодных культур с высоким содержанием крахмала или инулина" + }, + { + "code": "01.13.4", + "title": "Выращивание семян овощных культур, кроме семян сахарной свеклы" + }, + { + "code": "01.13.5", + "title": "Выращивание сахарной свеклы и семян сахарной свеклы" + }, + { + "code": "01.13.51", + "title": "Выращивание сахарной свеклы" + }, + { + "code": "01.13.52", + "title": "Выращивание семян сахарной свеклы" + }, + { + "code": "01.13.6", + "title": "Выращивание грибов и трюфелей" + }, + { + "code": "01.13.7", + "title": "Выращивание семян овощных культур" + }, + { + "code": "01.14", + "title": "Выращивание сахарного тростника" + }, + { + "code": "01.15", + "title": "Выращивание табака и махорки" + }, + { + "code": "01.15.1", + "title": "Выращивание табака курительного" + }, + { + "code": "01.15.2", + "title": "Выращивание махорки" + }, + { + "code": "01.16", + "title": "Выращивание прядильных культур" + }, + { + "code": "01.16.1", + "title": "Выращивание хлопчатника" + }, + { + "code": "01.16.2", + "title": "Выращивание льна" + }, + { + "code": "01.16.3", + "title": "Выращивание конопли" + }, + { + "code": "01.16.9", + "title": "Выращивание прочих текстильных культур" + }, + { + "code": "01.19", + "title": "Выращивание прочих однолетних культур" + }, + { + "code": "01.19.1", + "title": "Выращивание однолетних кормовых культур" + }, + { + "code": "01.19.2", + "title": "Цветоводство" + }, + { + "code": "01.19.21", + "title": "Выращивание цветов в открытом грунте" + }, + { + "code": "01.19.22", + "title": "Выращивание цветов в защищенном грунте" + }, + { + "code": "01.19.3", + "title": "Выращивание семян цветов" + }, + { + "code": "01.19.9", + "title": "Выращивание прочих однолетних культур, не включенных в другие группировки" + }, + { + "code": "01.21", + "title": "Выращивание винограда" + }, + { + "code": "01.21.1", + "title": "Выращивание винограда для производства вина" + }, + { + "code": "01.21.2", + "title": "Выращивание столового винограда" + }, + { + "code": "01.21.3", + "title": "Выращивание винограда для производства изюма" + }, + { + "code": "01.22", + "title": "Выращивание тропических и субтропических культур" + }, + { + "code": "01.22.1", + "title": "Выращивание бананов" + }, + { + "code": "01.22.2", + "title": "Выращивание фиников" + }, + { + "code": "01.22.3", + "title": "Выращивание инжира" + }, + { + "code": "01.22.9", + "title": "Выращивание прочих тропических и субтропических культур" + }, + { + "code": "01.23", + "title": "Выращивание цитрусовых культур" + }, + { + "code": "01.23.1", + "title": "Выращивание апельсинов" + }, + { + "code": "01.23.2", + "title": "Выращивание лимонов и лаймов" + }, + { + "code": "01.23.3", + "title": "Выращивание грейпфрутов" + }, + { + "code": "01.23.4", + "title": "Выращивание мандаринов" + }, + { + "code": "01.23.9", + "title": "Выращивание прочих цитрусовых культур" + }, + { + "code": "01.24", + "title": "Выращивание семечковых и косточковых культур" + }, + { + "code": "01.24.1", + "title": "Выращивание яблок" + }, + { + "code": "01.24.2", + "title": "Выращивание груш" + }, + { + "code": "01.24.3", + "title": "Выращивание косточковых плодовых культур" + }, + { + "code": "01.24.31", + "title": "Выращивание слив" + }, + { + "code": "01.24.32", + "title": "Выращивание вишни и черешни" + }, + { + "code": "01.24.33", + "title": "Выращивание абрикосов" + }, + { + "code": "01.24.34", + "title": "Выращивание персиков и нектаринов" + }, + { + "code": "01.24.39", + "title": "Выращивание прочих косточковых плодовых культур" + }, + { + "code": "01.25", + "title": "Выращивание прочих плодовых деревьев, кустарников и орехов" + }, + { + "code": "01.25.1", + "title": "Выращивание ягодных культур" + }, + { + "code": "01.25.11", + "title": "Выращивание смородины" + }, + { + "code": "01.25.12", + "title": "Выращивание крыжовника" + }, + { + "code": "01.25.13", + "title": "Выращивание малины" + }, + { + "code": "01.25.14", + "title": "Выращивание земляники" + }, + { + "code": "01.25.19", + "title": "Выращивание прочих ягодных культур" + }, + { + "code": "01.25.2", + "title": "Выращивание орехов" + }, + { + "code": "01.25.21", + "title": "Выращивание грецких орехов" + }, + { + "code": "01.25.22", + "title": "Выращивание лещины" + }, + { + "code": "01.25.23", + "title": "Выращивание миндаля" + }, + { + "code": "01.25.29", + "title": "Выращивание прочих орехов" + }, + { + "code": "01.25.9", + "title": "Выращивание прочих плодовых деревьев и кустарников" + }, + { + "code": "01.26", + "title": "Выращивание плодов масличных культур" + }, + { + "code": "01.26.1", + "title": "Выращивание маслин (оливок)" + }, + { + "code": "01.26.9", + "title": "Выращивание прочих плодов масличных культур" + }, + { + "code": "01.27", + "title": "Выращивание культур для производства напитков" + }, + { + "code": "01.27.1", + "title": "Выращивание чая" + }, + { + "code": "01.27.2", + "title": "Выращивание кофе" + }, + { + "code": "01.27.3", + "title": "Выращивание какао" + }, + { + "code": "01.27.9", + "title": "Выращивание прочих культур для производства напитков" + }, + { + "code": "01.28", + "title": "Выращивание специй, пряно-ароматических, эфиромасличных и лекарственных культур" + }, + { + "code": "01.28.1", + "title": "Выращивание специй и пряно-ароматических культур" + }, + { + "code": "01.28.2", + "title": "Выращивание эфиромасличных культур" + }, + { + "code": "01.28.3", + "title": "Выращивание лекарственных культур" + }, + { + "code": "01.29", + "title": "Выращивание прочих многолетних культур" + }, + { + "code": "01.29.1", + "title": "Выращивание новогодних елок" + }, + { + "code": "01.29.2", + "title": "Выращивание многолетних кормовых культур" + }, + { + "code": "01.29.9", + "title": "Выращивание прочих многолетних культур, не включенных в другие группировки" + }, + { + "code": "01.30", + "title": "Разведение растений" + }, + { + "code": "01.30.1", + "title": "Смешанное сельское хозяйство с преобладанием растениеводства" + }, + { + "code": "01.30.2", + "title": "Смешанное сельское хозяйство с преобладанием животноводства" + }, + { + "code": "01.41", + "title": "Разведение молочного крупного рогатого скота" + }, + { + "code": "01.41.1", + "title": "Разведение молочного крупного рогатого скота, кроме племенного" + }, + { + "code": "01.41.2", + "title": "Разведение племенного молочного крупного рогатого скота" + }, + { + "code": "01.42", + "title": "Разведение прочего крупного рогатого скота и буйволов" + }, + { + "code": "01.42.1", + "title": "Разведение мясного крупного рогатого скота, кроме племенного" + }, + { + "code": "01.42.2", + "title": "Разведение племенного мясного крупного рогатого скота" + }, + { + "code": "01.42.3", + "title": "Разведение буйволов" + }, + { + "code": "01.43", + "title": "Разведение лошадей и прочих животных семейства лошадиных" + }, + { + "code": "01.43.1", + "title": "Разведение лошадей, кроме племенных" + }, + { + "code": "01.43.2", + "title": "Разведение племенных лошадей" + }, + { + "code": "01.43.3", + "title": "Разведение ослов, мулов, лошаков" + }, + { + "code": "01.44", + "title": "Разведение верблюдов и прочих животных семейства верблюжьих" + }, + { + "code": "01.44.1", + "title": "Разведение верблюдов" + }, + { + "code": "01.44.2", + "title": "Разведение лам, альпака и прочих животных семейства верблюжьих" + }, + { + "code": "01.45", + "title": "Разведение овец и коз" + }, + { + "code": "01.45.1", + "title": "Разведение овец, кроме племенных" + }, + { + "code": "01.45.2", + "title": "Разведение племенных овец" + }, + { + "code": "01.45.3", + "title": "Разведение коз, кроме племенных" + }, + { + "code": "01.45.4", + "title": "Разведение племенных коз" + }, + { + "code": "01.46", + "title": "Разведение свиней" + }, + { + "code": "01.46.1", + "title": "Разведение свиней, кроме племенных" + }, + { + "code": "01.46.11", + "title": "Выращивание свиней на мясо" + }, + { + "code": "01.46.12", + "title": "Производство поросят" + }, + { + "code": "01.46.2", + "title": "Разведение племенных свиней" + }, + { + "code": "01.47", + "title": "Разведение сельскохозяйственной птицы" + }, + { + "code": "01.47.1", + "title": "Разведение сельскохозяйственной птицы, кроме племенной" + }, + { + "code": "01.47.11", + "title": "Производство яиц" + }, + { + "code": "01.47.12", + "title": "Выращивание мясной птицы" + }, + { + "code": "01.47.2", + "title": "Разведение племенной сельскохозяйственной птицы" + }, + { + "code": "01.49", + "title": "Разведение прочих животных" + }, + { + "code": "01.49.1", + "title": "Пчеловодство" + }, + { + "code": "01.49.11", + "title": "Пчеловодство медового направления" + }, + { + "code": "01.49.12", + "title": "Пчеловодство опылительного направления" + }, + { + "code": "01.49.13", + "title": "Пчеловодство разведенческого направления" + }, + { + "code": "01.49.2", + "title": "Разведение кроликов и пушных зверей в условиях фермы" + }, + { + "code": "01.49.21", + "title": "Разведение кроликов" + }, + { + "code": "01.49.22", + "title": "Разведение пушных зверей" + }, + { + "code": "01.49.3", + "title": "Разведение оленей" + }, + { + "code": "01.49.31", + "title": "Разведение северных оленей" + }, + { + "code": "01.49.32", + "title": "Разведение пятнистых оленей, ланей" + }, + { + "code": "01.49.33", + "title": "Разведение лосей" + }, + { + "code": "01.49.4", + "title": "Разведение домашней птицы, кроме сельскохозяйственной" + }, + { + "code": "01.49.41", + "title": "Разведение страусов" + }, + { + "code": "01.49.42", + "title": "Разведение прочей домашней птицы" + }, + { + "code": "01.49.5", + "title": "Разведение рептилий и земноводных" + }, + { + "code": "01.49.6", + "title": "Разведение червей" + }, + { + "code": "01.49.7", + "title": "Разведение улиток" + }, + { + "code": "01.49.9", + "title": "Разведение прочих животных, не включенных в другие группировки" + }, + { + "code": "01.50", + "title": "Смешанное сельское хозяйство" + }, + { + "code": "01.50.1", + "title": "Смешанное сельское хозяйство с преобладанием растениеводства" + }, + { + "code": "01.50.2", + "title": "Смешанное сельское хозяйство с преобладанием животноводства" + }, + { + "code": "01.61", + "title": "Предоставление услуг в области растениеводства" + }, + { + "code": "01.61.1", + "title": "Предоставление услуг, связанных с производством сельскохозяйственных культур" + }, + { + "code": "01.61.2", + "title": "Обработка почвы под посев" + }, + { + "code": "01.61.3", + "title": "Посев сельскохозяйственных культур" + }, + { + "code": "01.61.4", + "title": "Обработка посевов сельскохозяйственных культур" + }, + { + "code": "01.61.5", + "title": "Уборка урожая" + }, + { + "code": "01.61.6", + "title": "Подготовка урожая к хранению" + }, + { + "code": "01.61.7", + "title": "Эксплуатация мелиоративных систем" + }, + { + "code": "01.61.8", + "title": "Защита растений и агрохимическое обслуживание" + }, + { + "code": "01.61.9", + "title": "Предоставление прочих услуг в области растениеводства" + }, + { + "code": "01.62", + "title": "Предоставление услуг в области животноводства" + }, + { + "code": "01.62.1", + "title": "Предоставление услуг по содержанию сельскохозяйственных животных" + }, + { + "code": "01.62.2", + "title": "Предоставление услуг по искусственному осеменению животных" + }, + { + "code": "01.62.3", + "title": "Предоставление услуг по выпасу скота" + }, + { + "code": "01.62.4", + "title": "Предоставление услуг по стрижке овец" + }, + { + "code": "01.62.5", + "title": "Предоставление услуг по обследованию состояния стада" + }, + { + "code": "01.62.6", + "title": "Предоставление услуг по уходу за сельскохозяйственными животными" + }, + { + "code": "01.62.7", + "title": "Предоставление услуг по заготовке и хранению кормов" + }, + { + "code": "01.62.9", + "title": "Предоставление прочих услуг в области животноводства" + }, + { + "code": "01.63", + "title": "Деятельность по подготовке сельскохозяйственной продукции к реализации" + }, + { + "code": "01.63.1", + "title": "Первичная обработка и хранение зерна" + }, + { + "code": "01.63.11", + "title": "Обработка зерна для хранения" + }, + { + "code": "01.63.12", + "title": "Хранение зерна" + }, + { + "code": "01.63.2", + "title": "Первичная обработка и хранение овощей" + }, + { + "code": "01.63.3", + "title": "Первичная обработка и хранение фруктов и орехов" + }, + { + "code": "01.63.4", + "title": "Первичная обработка табачных листьев" + }, + { + "code": "01.63.5", + "title": "Первичная обработка хлопка" + }, + { + "code": "01.63.6", + "title": "Первичная обработка семян масличных культур" + }, + { + "code": "01.63.9", + "title": "Прочая деятельность по подготовке сельскохозяйственной продукции к реализации" + }, + { + "code": "01.64", + "title": "Обработка семян для посадки" + }, + { + "code": "01.64.1", + "title": "Обработка семян зерновых культур для посадки" + }, + { + "code": "01.64.2", + "title": "Обработка семян овощных культур для посадки" + }, + { + "code": "01.64.3", + "title": "Обработка семян кормовых культур для посадки" + }, + { + "code": "01.64.4", + "title": "Обработка семян цветочных культур для посадки" + }, + { + "code": "01.64.9", + "title": "Обработка прочих семян для посадки" + }, + { + "code": "01.70", + "title": "Охота, отлов и отстрел диких животных, включая предоставление услуг в этих областях" + }, + { + "code": "01.70.1", + "title": "Охота и отлов диких животных, включая предоставление услуг в этих областях" + }, + { + "code": "01.70.2", + "title": "Отстрел диких животных, включая предоставление услуг в этой области" + }, + { + "code": "02.10", + "title": "Лесоводство и прочая лесохозяйственная деятельность" + }, + { + "code": "02.10.1", + "title": "Выращивание лесных насаждений" + }, + { + "code": "02.10.2", + "title": "Выращивание сеянцев, саженцев и посадочного материала лесных растений" + }, + { + "code": "02.10.3", + "title": "Сбор семян лесных растений" + }, + { + "code": "02.10.4", + "title": "Лесоводство" + }, + { + "code": "02.10.5", + "title": "Охрана лесов" + }, + { + "code": "02.10.6", + "title": "Воспроизводство лесов и лесоразведение" + }, + { + "code": "02.10.9", + "title": "Прочая лесохозяйственная деятельность" + }, + { + "code": "02.20", + "title": "Лесозаготовки" + }, + { + "code": "02.20.1", + "title": "Заготовка древесины" + }, + { + "code": "02.20.11", + "title": "Заготовка деловой древесины" + }, + { + "code": "02.20.12", + "title": "Заготовка дровяной древесины" + }, + { + "code": "02.20.13", + "title": "Заготовка пневого осмола" + }, + { + "code": "02.20.2", + "title": "Сбор и заготовка пищевых лесных ресурсов, лекарственных растений и прочих недревесных лесных ресурсов" + }, + { + "code": "02.30", + "title": "Сбор и заготовка пищевых лесных ресурсов, недревесных лесных ресурсов и лекарственных растений" + }, + { + "code": "02.30.1", + "title": "Сбор дикорастущих грибов и трюфелей" + }, + { + "code": "02.30.2", + "title": "Сбор дикорастущих ягод, орехов и плодов" + }, + { + "code": "02.30.3", + "title": "Сбор дикорастущих лекарственных растений" + }, + { + "code": "02.30.4", + "title": "Сбор прочих дикорастущих недревесных лесных ресурсов" + }, + { + "code": "02.40", + "title": "Предоставление услуг в области лесоводства и лесозаготовок" + }, + { + "code": "02.40.1", + "title": "Предоставление услуг в области лесоводства" + }, + { + "code": "02.40.11", + "title": "Предоставление услуг по лесовосстановлению и лесоразведению" + }, + { + "code": "02.40.12", + "title": "Предоставление услуг по охране и защите лесов" + }, + { + "code": "02.40.13", + "title": "Предоставление услуг по уходу за лесами" + }, + { + "code": "02.40.2", + "title": "Предоставление услуг в области лесозаготовок" + }, + { + "code": "02.40.21", + "title": "Предоставление услуг по рубке лесных насаждений" + }, + { + "code": "02.40.22", + "title": "Предоставление услуг по вывозке древесины" + }, + { + "code": "02.40.23", + "title": "Предоставление прочих услуг в области лесозаготовок" + }, + { + "code": "03.11", + "title": "Рыболовство морское" + }, + { + "code": "03.11.1", + "title": "Рыболовство в открытом море" + }, + { + "code": "03.11.2", + "title": "Прибрежное рыболовство" + }, + { + "code": "03.11.3", + "title": "Добыча морских ракообразных и моллюсков" + }, + { + "code": "03.11.4", + "title": "Добыча морских животных, кроме рыбы, ракообразных и моллюсков" + }, + { + "code": "03.11.5", + "title": "Добыча морских водорослей и прочих морских организмов" + }, + { + "code": "03.12", + "title": "Рыболовство пресноводное" + }, + { + "code": "03.12.1", + "title": "Рыболовство в реках, озерах, водохранилищах и других внутренних водоемах" + }, + { + "code": "03.12.2", + "title": "Добыча пресноводных ракообразных и моллюсков" + }, + { + "code": "03.12.3", + "title": "Добыча прочих пресноводных организмов" + }, + { + "code": "03.21", + "title": "Рыбоводство морское" + }, + { + "code": "03.21.1", + "title": "Выращивание рыбы в морской воде" + }, + { + "code": "03.21.2", + "title": "Выращивание морских ракообразных и моллюсков" + }, + { + "code": "03.21.3", + "title": "Выращивание морских водорослей и прочих морских организмов" + }, + { + "code": "03.22", + "title": "Рыбоводство пресноводное" + }, + { + "code": "03.22.1", + "title": "Выращивание пресноводной рыбы" + }, + { + "code": "03.22.11", + "title": "Воспроизводство рыбы и водных биоресурсов" + }, + { + "code": "03.22.12", + "title": "Товарное рыбоводство" + }, + { + "code": "03.22.13", + "title": "Рыбоводство в целях аквариумистики" + }, + { + "code": "03.22.2", + "title": "Выращивание пресноводных ракообразных и моллюсков" + }, + { + "code": "03.22.3", + "title": "Выращивание прочих пресноводных организмов" + }, + { + "code": "05.10", + "title": "Добыча каменного угля" + }, + { + "code": "05.10.1", + "title": "Добыча каменного угля открытым способом" + }, + { + "code": "05.10.2", + "title": "Добыча каменного угля подземным способом" + }, + { + "code": "05.10.3", + "title": "Обогащение каменного угля" + }, + { + "code": "05.20", + "title": "Добыча бурого угля (лигнита)" + }, + { + "code": "05.20.1", + "title": "Добыча бурого угля (лигнита) открытым способом" + }, + { + "code": "05.20.2", + "title": "Добыча бурого угля (лигнита) подземным способом" + }, + { + "code": "05.20.3", + "title": "Обогащение и брикетирование бурого угля (лигнита)" + }, + { + "code": "06.10", + "title": "Добыча сырой нефти" + }, + { + "code": "06.10.1", + "title": "Добыча сырой нефти" + }, + { + "code": "06.10.2", + "title": "Добыча нефтяного (попутного) газа" + }, + { + "code": "06.10.3", + "title": "Добыча горючих (битуминозных) сланцев, битуминозного песка и озокерита" + }, + { + "code": "06.20", + "title": "Добыча природного газа" + }, + { + "code": "06.20.1", + "title": "Добыча природного газа" + }, + { + "code": "06.20.2", + "title": "Добыча газового конденсата" + }, + { + "code": "06.20.3", + "title": "Разделение и извлечение фракций из природного газа" + }, + { + "code": "07.10", + "title": "Добыча железных руд" + }, + { + "code": "07.10.1", + "title": "Добыча, обогащение и агломерация железных руд" + }, + { + "code": "07.10.2", + "title": "Добыча железных руд подземным способом" + }, + { + "code": "07.10.3", + "title": "Добыча железных руд открытым способом" + }, + { + "code": "07.21", + "title": "Добыча урановой и ториевой руд" + }, + { + "code": "07.21.1", + "title": "Добыча и обогащение урановых руд" + }, + { + "code": "07.21.2", + "title": "Добыча и обогащение ториевых руд" + }, + { + "code": "07.29", + "title": "Добыча прочих руд цветных металлов" + }, + { + "code": "07.29.1", + "title": "Добыча и обогащение медных руд" + }, + { + "code": "07.29.2", + "title": "Добыча и обогащение никелевых и кобальтовых руд" + }, + { + "code": "07.29.3", + "title": "Добыча и обогащение алюминийсодержащего сырья (бокситов и нефелин-апатитовых руд)" + }, + { + "code": "07.29.4", + "title": "Добыча и обогащение свинцово-цинковых руд" + }, + { + "code": "07.29.5", + "title": "Добыча и обогащение оловянных руд" + }, + { + "code": "07.29.6", + "title": "Добыча и обогащение титановых руд" + }, + { + "code": "07.29.7", + "title": "Добыча и обогащение вольфрамовых и молибденовых руд" + }, + { + "code": "07.29.8", + "title": "Добыча и обогащение сурьмяных и ртутных руд" + }, + { + "code": "07.29.9", + "title": "Добыча и обогащение прочих руд цветных металлов" + }, + { + "code": "08.11", + "title": "Добыча декоративного и строительного камня, известняка, гипса, мела и сланцев" + }, + { + "code": "08.11.1", + "title": "Добыча декоративного и строительного камня" + }, + { + "code": "08.11.2", + "title": "Добыча известняка, гипсового камня и мела" + }, + { + "code": "08.11.3", + "title": "Добыча сланцев" + }, + { + "code": "08.12", + "title": "Добыча гравия, песка и глины" + }, + { + "code": "08.12.1", + "title": "Добыча гравия и песка" + }, + { + "code": "08.12.2", + "title": "Добыча глины и каолина" + }, + { + "code": "08.91", + "title": "Добыча минерального сырья для химической промышленности и производства минеральных удобрений" + }, + { + "code": "08.91.1", + "title": "Добыча фосфоритов" + }, + { + "code": "08.91.2", + "title": "Добыча апатитов" + }, + { + "code": "08.91.3", + "title": "Добыча калийных солей" + }, + { + "code": "08.91.4", + "title": "Добыча серы" + }, + { + "code": "08.91.5", + "title": "Добыча пиритов" + }, + { + "code": "08.91.6", + "title": "Добыча асбеста" + }, + { + "code": "08.91.9", + "title": "Добыча прочего минерального сырья для химической промышленности" + }, + { + "code": "08.92", + "title": "Добыча и агломерация торфа" + }, + { + "code": "08.92.1", + "title": "Добыча торфа" + }, + { + "code": "08.92.2", + "title": "Агломерация торфа" + }, + { + "code": "08.93", + "title": "Добыча соли" + }, + { + "code": "08.93.1", + "title": "Добыча каменной соли" + }, + { + "code": "08.93.2", + "title": "Добыча соли из морской воды" + }, + { + "code": "08.93.3", + "title": "Добыча соли из соляных озер" + }, + { + "code": "08.99", + "title": "Добыча прочих полезных ископаемых, не включенных в другие группировки" + }, + { + "code": "08.99.1", + "title": "Добыча драгоценных камней" + }, + { + "code": "08.99.2", + "title": "Добыча полудрагоценных камней" + }, + { + "code": "08.99.3", + "title": "Добыча абразивных материалов" + }, + { + "code": "08.99.4", + "title": "Добыча графита" + }, + { + "code": "08.99.5", + "title": "Добыча талька и стеатита" + }, + { + "code": "08.99.6", + "title": "Добыча полевого шпата" + }, + { + "code": "08.99.9", + "title": "Добыча прочих полезных ископаемых" + }, + { + "code": "09.10", + "title": "Предоставление услуг в области добычи нефти и природного газа" + }, + { + "code": "09.10.1", + "title": "Предоставление услуг по бурению, связанному с добычей нефти, газа и газового конденсата" + }, + { + "code": "09.10.2", + "title": "Предоставление услуг по доразведке месторождений нефти и газа на стадии эксплуатации" + }, + { + "code": "09.10.3", + "title": "Предоставление прочих услуг в области добычи нефти и природного газа" + }, + { + "code": "09.90", + "title": "Предоставление услуг в других областях добычи полезных ископаемых" + }, + { + "code": "09.90.1", + "title": "Предоставление услуг по бурению скважин, кроме связанного с добычей нефти, газа и газового конденсата" + }, + { + "code": "09.90.2", + "title": "Предоставление услуг по шахтному и карьерному строительству" + }, + { + "code": "09.90.3", + "title": "Предоставление прочих услуг в области добычи полезных ископаемых" + }, + { + "code": "10.11", + "title": "Переработка и консервирование мяса" + }, + { + "code": "10.11.1", + "title": "Производство мяса и пищевых субпродуктов крупного рогатого скота, свиней, овец, коз, животных семейства лошадиных" + }, + { + "code": "10.11.2", + "title": "Производство щипаной шерсти, сырых шкур и кож крупного рогатого скота и животных семейства лошадиных" + }, + { + "code": "10.11.3", + "title": "Производство пищевых животных жиров" + }, + { + "code": "10.11.4", + "title": "Переработка пищевых субпродуктов" + }, + { + "code": "10.11.5", + "title": "Консервирование мяса" + }, + { + "code": "10.12", + "title": "Переработка и консервирование мяса птицы" + }, + { + "code": "10.12.1", + "title": "Производство мяса птицы и пищевых субпродуктов птицы" + }, + { + "code": "10.12.2", + "title": "Производство пера и пуха" + }, + { + "code": "10.12.3", + "title": "Консервирование мяса птицы" + }, + { + "code": "10.13", + "title": "Производство продуктов из мяса и мяса птицы" + }, + { + "code": "10.13.1", + "title": "Производство колбасных изделий" + }, + { + "code": "10.13.2", + "title": "Производство продуктов из мяса птицы" + }, + { + "code": "10.13.3", + "title": "Производство пищевых топленых жиров" + }, + { + "code": "10.13.9", + "title": "Производство прочих продуктов из мяса и мяса птицы" + }, + { + "code": "10.20", + "title": "Переработка и консервирование рыбы, ракообразных и моллюсков" + }, + { + "code": "10.20.1", + "title": "Переработка и консервирование рыбы и рыбопродуктов" + }, + { + "code": "10.20.2", + "title": "Переработка и консервирование ракообразных и моллюсков" + }, + { + "code": "10.20.3", + "title": "Производство рыбной муки и жира" + }, + { + "code": "10.31", + "title": "Переработка и консервирование картофеля" + }, + { + "code": "10.31.1", + "title": "Производство замороженного картофеля" + }, + { + "code": "10.31.2", + "title": "Производство сушеного картофеля" + }, + { + "code": "10.31.3", + "title": "Производство картофельных чипсов" + }, + { + "code": "10.31.4", + "title": "Производство картофельного крахмала" + }, + { + "code": "10.31.9", + "title": "Прочие виды переработки и консервирования картофеля" + }, + { + "code": "10.32", + "title": "Производство соков из фруктов и овощей" + }, + { + "code": "10.32.1", + "title": "Производство соков из фруктов и ягод" + }, + { + "code": "10.32.2", + "title": "Производство соков из овощей" + }, + { + "code": "10.32.3", + "title": "Производство концентратов для производства напитков" + }, + { + "code": "10.39", + "title": "Прочие виды переработки и консервирования фруктов и овощей" + }, + { + "code": "10.39.1", + "title": "Переработка и консервирование фруктов и ягод, кроме производства соков" + }, + { + "code": "10.39.2", + "title": "Переработка и консервирование овощей, кроме производства соков" + }, + { + "code": "10.39.3", + "title": "Переработка и консервирование грибов и трюфелей" + }, + { + "code": "10.39.4", + "title": "Производство продуктов из орехов" + }, + { + "code": "10.41", + "title": "Производство масел и жиров" + }, + { + "code": "10.41.1", + "title": "Производство нерафинированных масел и жиров" + }, + { + "code": "10.41.2", + "title": "Производство рафинированных масел и жиров" + }, + { + "code": "10.41.3", + "title": "Производство хлопкового масла" + }, + { + "code": "10.41.4", + "title": "Производство подсолнечного масла" + }, + { + "code": "10.41.5", + "title": "Производство соевого масла" + }, + { + "code": "10.41.9", + "title": "Производство прочих растительных и животных масел и жиров" + }, + { + "code": "10.42", + "title": "Производство маргариновой продукции" + }, + { + "code": "10.42.1", + "title": "Производство маргарина и аналогичных пищевых жиров" + }, + { + "code": "10.42.2", + "title": "Производство смесей и теста для приготовления хлебобулочных изделий" + }, + { + "code": "10.51", + "title": "Переработка молока и производство сыра" + }, + { + "code": "10.51.1", + "title": "Переработка молока и производство молочной продукции" + }, + { + "code": "10.51.2", + "title": "Производство молока питьевого, сливок и кисломолочных продуктов" + }, + { + "code": "10.51.3", + "title": "Производство творога и сырково-творожных изделий" + }, + { + "code": "10.51.4", + "title": "Производство сыра и сырных продуктов" + }, + { + "code": "10.51.5", + "title": "Производство сухих молочных продуктов" + }, + { + "code": "10.51.6", + "title": "Производство сгущенных молочных продуктов" + }, + { + "code": "10.52", + "title": "Производство мороженого" + }, + { + "code": "10.52.1", + "title": "Производство мороженого и замороженных десертов" + }, + { + "code": "10.61", + "title": "Производство продуктов мукомольной и крупяной промышленности" + }, + { + "code": "10.61.1", + "title": "Производство муки" + }, + { + "code": "10.61.2", + "title": "Производство крупы" + }, + { + "code": "10.61.3", + "title": "Производство комбикормов и кормовых добавок" + }, + { + "code": "10.61.4", + "title": "Производство готовых завтраков и прочих продуктов переработки зерна" + }, + { + "code": "10.62", + "title": "Производство крахмалов и крахмалопродуктов" + }, + { + "code": "10.62.1", + "title": "Производство крахмала и крахмалопродуктов" + }, + { + "code": "10.62.2", + "title": "Производство глюкозы и глюкозных сиропов" + }, + { + "code": "10.71", + "title": "Производство хлеба и мучных кондитерских изделий недлительного хранения" + }, + { + "code": "10.71.1", + "title": "Производство хлеба и хлебобулочных изделий недлительного хранения" + }, + { + "code": "10.71.2", + "title": "Производство мучных кондитерских изделий недлительного хранения" + }, + { + "code": "10.72", + "title": "Производство сухарей, печенья и прочих сухих мучных кондитерских изделий" + }, + { + "code": "10.72.1", + "title": "Производство сухарей и печенья" + }, + { + "code": "10.72.2", + "title": "Производство пряников, вафель и прочих сухих кондитерских изделий" + }, + { + "code": "10.73", + "title": "Производство макаронных изделий" + }, + { + "code": "10.73.1", + "title": "Производство макаронных изделий" + }, + { + "code": "10.81", + "title": "Производство сахара" + }, + { + "code": "10.81.1", + "title": "Производство сахара-песка" + }, + { + "code": "10.81.2", + "title": "Производство сахара-рафинада" + }, + { + "code": "10.82", + "title": "Производство какао, шоколада и сахаристых кондитерских изделий" + }, + { + "code": "10.82.1", + "title": "Производство какао" + }, + { + "code": "10.82.2", + "title": "Производство шоколада и шоколадных изделий" + }, + { + "code": "10.82.3", + "title": "Производство сахаристых кондитерских изделий" + }, + { + "code": "10.83", + "title": "Переработка чая и кофе" + }, + { + "code": "10.83.1", + "title": "Производство кофе" + }, + { + "code": "10.83.2", + "title": "Производство чая" + }, + { + "code": "10.84", + "title": "Производство приправ и пряностей" + }, + { + "code": "10.84.1", + "title": "Производство специй, соусов и приправ" + }, + { + "code": "10.84.2", + "title": "Производство уксуса" + }, + { + "code": "10.85", + "title": "Производство готовых пищевых продуктов" + }, + { + "code": "10.85.1", + "title": "Производство супов и бульонов" + }, + { + "code": "10.85.2", + "title": "Производство готовых к употреблению пищевых продуктов" + }, + { + "code": "10.86", + "title": "Производство детского питания и диетических пищевых продуктов" + }, + { + "code": "10.86.1", + "title": "Производство детского питания" + }, + { + "code": "10.86.2", + "title": "Производство диетических пищевых продуктов" + }, + { + "code": "10.89", + "title": "Производство прочих пищевых продуктов, не включенных в другие группировки" + }, + { + "code": "10.89.1", + "title": "Производство пищевых дрожжей" + }, + { + "code": "10.89.2", + "title": "Производство экстрактов и соков из мяса, рыбы" + }, + { + "code": "10.89.3", + "title": "Производство яйцепродуктов" + }, + { + "code": "10.89.9", + "title": "Производство прочих пищевых продуктов" + }, + { + "code": "10.91", + "title": "Производство готовых кормов для животных, содержащихся на фермах" + }, + { + "code": "10.91.1", + "title": "Производство готовых кормов для крупного рогатого скота" + }, + { + "code": "10.91.2", + "title": "Производство готовых кормов для свиней" + }, + { + "code": "10.91.3", + "title": "Производство готовых кормов для птицы" + }, + { + "code": "10.91.9", + "title": "Производство готовых кормов для прочих сельскохозяйственных животных" + }, + { + "code": "10.92", + "title": "Производство готовых кормов для домашних животных" + }, + { + "code": "10.92.1", + "title": "Производство готовых кормов для домашних животных" + }, + { + "code": "11.01", + "title": "Дистилляция, ректификация и смешивание спиртных напитков" + }, + { + "code": "11.01.1", + "title": "Производство дистиллированных алкогольных напитков" + }, + { + "code": "11.01.2", + "title": "Производство водки" + }, + { + "code": "11.01.3", + "title": "Производство коньяка" + }, + { + "code": "11.01.4", + "title": "Производство виски" + }, + { + "code": "11.01.5", + "title": "Производство ликероводочных изделий" + }, + { + "code": "11.01.6", + "title": "Производство этилового спирта из сброженных материалов" + }, + { + "code": "11.02", + "title": "Производство виноградного вина" + }, + { + "code": "11.02.1", + "title": "Производство виноградных вин" + }, + { + "code": "11.02.2", + "title": "Производство игристых вин" + }, + { + "code": "11.02.3", + "title": "Производство прочих виноградных вин" + }, + { + "code": "11.03", + "title": "Производство сидра и прочих плодовых вин" + }, + { + "code": "11.03.1", + "title": "Производство сидра и перри" + }, + { + "code": "11.03.2", + "title": "Производство прочих плодовых вин" + }, + { + "code": "11.04", + "title": "Производство прочих недистиллированных напитков из сброженных материалов" + }, + { + "code": "11.04.1", + "title": "Производство медовухи и прочих недистиллированных сброженных напитков" + }, + { + "code": "11.05", + "title": "Производство пива" + }, + { + "code": "11.05.1", + "title": "Производство пива" + }, + { + "code": "11.05.2", + "title": "Производство пивных напитков" + }, + { + "code": "11.06", + "title": "Производство солода" + }, + { + "code": "11.06.1", + "title": "Производство солода" + }, + { + "code": "11.07", + "title": "Производство безалкогольных напитков; производство минеральных вод и других питьевых вод в бутылках" + }, + { + "code": "11.07.1", + "title": "Производство минеральных вод и других питьевых вод в бутылках" + }, + { + "code": "11.07.2", + "title": "Производство безалкогольных напитков" + }, + { + "code": "11.07.3", + "title": "Производство морсов, квасов и других безалкогольных напитков" + }, + { + "code": "12.00", + "title": "Производство табачных изделий" + }, + { + "code": "12.00.1", + "title": "Производство сигарет" + }, + { + "code": "12.00.2", + "title": "Производство сигар и сигарилл" + }, + { + "code": "12.00.3", + "title": "Производство курительного, жевательного и нюхательного табака" + }, + { + "code": "12.00.4", + "title": "Переработка табака" + }, + { + "code": "12.00.9", + "title": "Производство прочих табачных изделий" + }, + { + "code": "13.10", + "title": "Подготовка и прядение текстильных волокон" + }, + { + "code": "13.10.1", + "title": "Подготовка и прядение хлопчатобумажных волокон" + }, + { + "code": "13.10.2", + "title": "Подготовка и прядение шерстяных волокон" + }, + { + "code": "13.10.3", + "title": "Подготовка и прядение льняных волокон" + }, + { + "code": "13.10.4", + "title": "Подготовка и прядение химических волокон" + }, + { + "code": "13.10.9", + "title": "Подготовка и прядение прочих текстильных волокон" + }, + { + "code": "13.20", + "title": "Производство тканей" + }, + { + "code": "13.20.1", + "title": "Производство хлопчатобумажных тканей" + }, + { + "code": "13.20.2", + "title": "Производство шерстяных тканей" + }, + { + "code": "13.20.3", + "title": "Производство шелковых тканей" + }, + { + "code": "13.20.4", + "title": "Производство льняных тканей" + }, + { + "code": "13.20.5", + "title": "Производство тканей из химических волокон" + }, + { + "code": "13.20.9", + "title": "Производство прочих тканей" + }, + { + "code": "13.30", + "title": "Отделка тканей и текстильных изделий" + }, + { + "code": "13.30.1", + "title": "Отделка тканей" + }, + { + "code": "13.30.2", + "title": "Отделка текстильных изделий и одежды" + }, + { + "code": "13.91", + "title": "Производство трикотажных полотен" + }, + { + "code": "13.91.1", + "title": "Производство трикотажных полотен" + }, + { + "code": "13.92", + "title": "Производство готовых текстильных изделий, кроме одежды" + }, + { + "code": "13.92.1", + "title": "Производство постельного белья" + }, + { + "code": "13.92.2", + "title": "Производство столового белья, полотенец и аналогичных изделий" + }, + { + "code": "13.92.3", + "title": "Производство штор, занавесей, тентов и других готовых текстильных изделий" + }, + { + "code": "13.93", + "title": "Производство ковров и ковровых изделий" + }, + { + "code": "13.93.1", + "title": "Производство ковров и ковровых изделий" + }, + { + "code": "13.94", + "title": "Производство канатов, веревок, шпагата и сетей" + }, + { + "code": "13.94.1", + "title": "Производство канатов, веревок и шпагата" + }, + { + "code": "13.94.2", + "title": "Производство сетей" + }, + { + "code": "13.95", + "title": "Производство нетканых текстильных материалов и изделий из них, кроме одежды" + }, + { + "code": "13.95.1", + "title": "Производство нетканых текстильных материалов" + }, + { + "code": "13.95.2", + "title": "Производство изделий из нетканых материалов, кроме одежды" + }, + { + "code": "13.96", + "title": "Производство прочих технических и промышленных текстильных изделий" + }, + { + "code": "13.96.1", + "title": "Производство текстильных материалов с покрытием" + }, + { + "code": "13.96.2", + "title": "Производство технических тканей" + }, + { + "code": "13.96.3", + "title": "Производство текстильных изделий для промышленных целей" + }, + { + "code": "13.99", + "title": "Производство прочих текстильных изделий, не включенных в другие группировки" + }, + { + "code": "13.99.1", + "title": "Производство фетра и войлока" + }, + { + "code": "13.99.2", + "title": "Производство тюля, кружев, лент и вышивки" + }, + { + "code": "13.99.9", + "title": "Производство прочих текстильных изделий" + }, + { + "code": "14.11", + "title": "Производство одежды из кожи" + }, + { + "code": "14.11.1", + "title": "Производство одежды из натуральной кожи" + }, + { + "code": "14.11.2", + "title": "Производство одежды из искусственной кожи" + }, + { + "code": "14.12", + "title": "Производство спецодежды" + }, + { + "code": "14.12.1", + "title": "Производство рабочей одежды" + }, + { + "code": "14.12.2", + "title": "Производство форменной одежды" + }, + { + "code": "14.12.3", + "title": "Производство защитной одежды" + }, + { + "code": "14.13", + "title": "Производство прочей верхней одежды" + }, + { + "code": "14.13.1", + "title": "Производство мужской верхней одежды" + }, + { + "code": "14.13.2", + "title": "Производство женской верхней одежды" + }, + { + "code": "14.13.3", + "title": "Производство детской верхней одежды" + }, + { + "code": "14.14", + "title": "Производство нижнего белья" + }, + { + "code": "14.14.1", + "title": "Производство нижнего белья" + }, + { + "code": "14.14.2", + "title": "Производство корсетных изделий" + }, + { + "code": "14.14.3", + "title": "Производство купальных костюмов" + }, + { + "code": "14.19", + "title": "Производство прочих предметов одежды и аксессуаров" + }, + { + "code": "14.19.1", + "title": "Производство головных уборов" + }, + { + "code": "14.19.2", + "title": "Производство аксессуаров одежды" + }, + { + "code": "14.19.3", + "title": "Производство детской одежды" + }, + { + "code": "14.19.9", + "title": "Производство прочих предметов одежды" + }, + { + "code": "14.20", + "title": "Производство меховых изделий" + }, + { + "code": "14.20.1", + "title": "Производство меховой одежды" + }, + { + "code": "14.20.2", + "title": "Производство меховых аксессуаров" + }, + { + "code": "14.31", + "title": "Производство трикотажных чулочно-носочных изделий" + }, + { + "code": "14.31.1", + "title": "Производство чулочно-носочных изделий" + }, + { + "code": "14.39", + "title": "Производство прочих трикотажных и вязаных изделий" + }, + { + "code": "14.39.1", + "title": "Производство трикотажной верхней одежды" + }, + { + "code": "14.39.2", + "title": "Производство трикотажного нижнего белья" + }, + { + "code": "14.39.3", + "title": "Производство прочих трикотажных изделий" + }, + { + "code": "15.11", + "title": "Дубление и отделка кожи; выделка и крашение меха" + }, + { + "code": "15.11.1", + "title": "Дубление и отделка кожи" + }, + { + "code": "15.11.2", + "title": "Выделка и крашение меха" + }, + { + "code": "15.12", + "title": "Производство чемоданов, дамских сумочек и аналогичных изделий из кожи и других материалов" + }, + { + "code": "15.12.1", + "title": "Производство чемоданов, портфелей и аналогичных изделий" + }, + { + "code": "15.12.2", + "title": "Производство дамских сумочек" + }, + { + "code": "15.12.3", + "title": "Производство изделий из кожи технического назначения" + }, + { + "code": "15.20", + "title": "Производство обуви" + }, + { + "code": "15.20.1", + "title": "Производство кожаной обуви" + }, + { + "code": "15.20.2", + "title": "Производство текстильной обуви" + }, + { + "code": "15.20.3", + "title": "Производство резиновой и полимерной обуви" + }, + { + "code": "15.20.4", + "title": "Производство валяной обуви" + }, + { + "code": "15.20.9", + "title": "Производство прочей обуви" + }, + { + "code": "16.10", + "title": "Распиловка и строгание древесины" + }, + { + "code": "16.10.1", + "title": "Распиловка и строгание древесины" + }, + { + "code": "16.10.2", + "title": "Пропитка древесины" + }, + { + "code": "16.21", + "title": "Производство шпона и древесных плит" + }, + { + "code": "16.21.1", + "title": "Производство шпона" + }, + { + "code": "16.21.2", + "title": "Производство фанеры" + }, + { + "code": "16.21.3", + "title": "Производство древесностружечных плит" + }, + { + "code": "16.21.4", + "title": "Производство древесноволокнистых плит" + }, + { + "code": "16.21.5", + "title": "Производство прочих древесных плит и панелей" + }, + { + "code": "16.22", + "title": "Производство сборных паркетных покрытий" + }, + { + "code": "16.22.1", + "title": "Производство паркета" + }, + { + "code": "16.22.2", + "title": "Производство паркетных досок" + }, + { + "code": "16.23", + "title": "Производство прочих деревянных строительных конструкций и столярных изделий" + }, + { + "code": "16.23.1", + "title": "Производство деревянных строительных конструкций и столярных изделий" + }, + { + "code": "16.23.2", + "title": "Производство деревянных окон и дверей" + }, + { + "code": "16.23.3", + "title": "Производство деревянной мебели" + }, + { + "code": "16.24", + "title": "Производство деревянной тары" + }, + { + "code": "16.24.1", + "title": "Производство деревянной тары" + }, + { + "code": "16.29", + "title": "Производство прочих изделий из дерева; производство изделий из пробки, соломки и материалов для плетения" + }, + { + "code": "16.29.1", + "title": "Производство изделий из дерева, кроме мебели" + }, + { + "code": "16.29.2", + "title": "Производство изделий из пробки" + }, + { + "code": "16.29.3", + "title": "Производство изделий из соломки и материалов для плетения" + }, + { + "code": "16.29.9", + "title": "Производство прочих изделий из дерева" + }, + { + "code": "17.11", + "title": "Производство целлюлозы" + }, + { + "code": "17.11.1", + "title": "Производство целлюлозы" + }, + { + "code": "17.11.2", + "title": "Производство древесной массы" + }, + { + "code": "17.12", + "title": "Производство бумаги и картона" + }, + { + "code": "17.12.1", + "title": "Производство бумаги" + }, + { + "code": "17.12.2", + "title": "Производство картона" + }, + { + "code": "17.12.3", + "title": "Производство бумаги и картона с покрытием" + }, + { + "code": "17.21", + "title": "Производство гофрированного картона, бумажной и картонной тары" + }, + { + "code": "17.21.1", + "title": "Производство гофрированного картона" + }, + { + "code": "17.21.2", + "title": "Производство бумажной и картонной тары" + }, + { + "code": "17.22", + "title": "Производство бумажных изделий хозяйственно-бытового и санитарно-гигиенического назначения" + }, + { + "code": "17.22.1", + "title": "Производство бумажных изделий хозяйственно-бытового назначения" + }, + { + "code": "17.22.2", + "title": "Производство бумажных изделий санитарно-гигиенического назначения" + }, + { + "code": "17.23", + "title": "Производство бумажных канцелярских принадлежностей" + }, + { + "code": "17.23.1", + "title": "Производство бумажных канцелярских принадлежностей" + }, + { + "code": "17.24", + "title": "Производство обоев" + }, + { + "code": "17.24.1", + "title": "Производство обоев" + }, + { + "code": "17.29", + "title": "Производство прочих изделий из бумаги и картона" + }, + { + "code": "17.29.1", + "title": "Производство бумажных этикеток" + }, + { + "code": "17.29.2", + "title": "Производство бумажных фильтров" + }, + { + "code": "17.29.9", + "title": "Производство прочих изделий из бумаги и картона" + }, + { + "code": "18.11", + "title": "Деятельность полиграфическая" + }, + { + "code": "18.11.1", + "title": "Печатание газет" + }, + { + "code": "18.11.2", + "title": "Печатание журналов и периодических изданий" + }, + { + "code": "18.11.3", + "title": "Печатание книг, брошюр и других публикаций" + }, + { + "code": "18.11.4", + "title": "Печатание каталогов, плакатов, рекламных изданий и прочей печатной продукции" + }, + { + "code": "18.11.5", + "title": "Печатание этикеток" + }, + { + "code": "18.11.6", + "title": "Печатание канцелярских принадлежностей" + }, + { + "code": "18.11.9", + "title": "Прочая полиграфическая деятельность" + }, + { + "code": "18.12", + "title": "Производство копий с документов и прочая специализированная полиграфическая деятельность" + }, + { + "code": "18.12.1", + "title": "Производство копий с документов" + }, + { + "code": "18.12.2", + "title": "Специализированная полиграфическая деятельность" + }, + { + "code": "18.13", + "title": "Подготовка к печати" + }, + { + "code": "18.13.1", + "title": "Изготовление печатных форм" + }, + { + "code": "18.13.2", + "title": "Верстка оригинал-макетов" + }, + { + "code": "18.13.3", + "title": "Прочие виды подготовки к печати" + }, + { + "code": "18.14", + "title": "Брошюровочно-переплетная и отделочная деятельность" + }, + { + "code": "18.14.1", + "title": "Брошюровочно-переплетная деятельность" + }, + { + "code": "18.14.2", + "title": "Отделочная деятельность" + }, + { + "code": "18.20", + "title": "Тиражирование записанных носителей информации" + }, + { + "code": "18.20.1", + "title": "Тиражирование звукозаписей" + }, + { + "code": "18.20.2", + "title": "Тиражирование видеозаписей" + }, + { + "code": "18.20.3", + "title": "Тиражирование программного обеспечения" + }, + { + "code": "19.10", + "title": "Производство кокса" + }, + { + "code": "19.10.1", + "title": "Производство кокса и полукокса" + }, + { + "code": "19.10.2", + "title": "Производство пека и пекового кокса" + }, + { + "code": "19.10.3", + "title": "Производство брикетов из угля" + }, + { + "code": "19.20", + "title": "Производство продуктов нефтепереработки" + }, + { + "code": "19.20.1", + "title": "Производство моторных топлив" + }, + { + "code": "19.20.2", + "title": "Производство керосина" + }, + { + "code": "19.20.3", + "title": "Производство дизельного топлива" + }, + { + "code": "19.20.4", + "title": "Производство мазута" + }, + { + "code": "19.20.5", + "title": "Производство смазочных масел и смазок" + }, + { + "code": "19.20.6", + "title": "Производство нефтехимического сырья" + }, + { + "code": "19.20.9", + "title": "Производство прочих продуктов нефтепереработки" + }, + { + "code": "20.11", + "title": "Производство промышленных газов" + }, + { + "code": "20.11.1", + "title": "Производство сжиженных и сжатых газов" + }, + { + "code": "20.11.2", + "title": "Производство промышленных газов" + }, + { + "code": "20.12", + "title": "Производство красителей и пигментов" + }, + { + "code": "20.12.1", + "title": "Производство красителей и пигментов" + }, + { + "code": "20.13", + "title": "Производство прочих основных неорганических химических веществ" + }, + { + "code": "20.13.1", + "title": "Производство сжиженного хлора" + }, + { + "code": "20.13.2", + "title": "Производство прочих основных неорганических химических веществ" + }, + { + "code": "20.14", + "title": "Производство прочих основных органических химических веществ" + }, + { + "code": "20.14.1", + "title": "Производство этилена, пропилена и прочих олефинов" + }, + { + "code": "20.14.2", + "title": "Производство бензола, толуола и ксилолов" + }, + { + "code": "20.14.3", + "title": "Производство прочих основных органических химических веществ" + }, + { + "code": "20.15", + "title": "Производство удобрений и азотных соединений" + }, + { + "code": "20.15.1", + "title": "Производство удобрений" + }, + { + "code": "20.15.2", + "title": "Производство азотных соединений" + }, + { + "code": "20.16", + "title": "Производство пластмасс в первичных формах" + }, + { + "code": "20.16.1", + "title": "Производство пластмасс в первичных формах" + }, + { + "code": "20.17", + "title": "Производство синтетического каучука в первичных формах" + }, + { + "code": "20.17.1", + "title": "Производство синтетического каучука в первичных формах" + }, + { + "code": "20.20", + "title": "Производство пестицидов и прочих агрохимических продуктов" + }, + { + "code": "20.20.1", + "title": "Производство пестицидов и прочих агрохимических продуктов" + }, + { + "code": "20.30", + "title": "Производство красок, лаков и аналогичных материалов для нанесения покрытий, полиграфических красок и мастик" + }, + { + "code": "20.30.1", + "title": "Производство красок и лаков на основе полимеров" + }, + { + "code": "20.30.2", + "title": "Производство прочих красок, лаков, эмалей и аналогичных материалов для нанесения покрытий, полиграфических красок и мастик" + }, + { + "code": "20.41", + "title": "Производство мыла и моющих, чистящих и полирующих средств" + }, + { + "code": "20.41.1", + "title": "Производство мыла и моющих средств" + }, + { + "code": "20.41.2", + "title": "Производство чистящих и полирующих средств" + }, + { + "code": "20.42", + "title": "Производство парфюмерных и косметических средств" + }, + { + "code": "20.42.1", + "title": "Производство парфюмерных средств" + }, + { + "code": "20.42.2", + "title": "Производство косметических средств" + }, + { + "code": "20.51", + "title": "Производство взрывчатых веществ" + }, + { + "code": "20.51.1", + "title": "Производство взрывчатых веществ" + }, + { + "code": "20.52", + "title": "Производство клеев" + }, + { + "code": "20.52.1", + "title": "Производство клеев и желатина" + }, + { + "code": "20.53", + "title": "Производство эфирных масел" + }, + { + "code": "20.53.1", + "title": "Производство эфирных масел" + }, + { + "code": "20.59", + "title": "Производство прочих химических продуктов, не включенных в другие группировки" + }, + { + "code": "20.59.1", + "title": "Производство фотохимических материалов" + }, + { + "code": "20.59.2", + "title": "Производство прочих химических продуктов" + }, + { + "code": "20.60", + "title": "Производство химических волокон" + }, + { + "code": "20.60.1", + "title": "Производство синтетических волокон" + }, + { + "code": "20.60.2", + "title": "Производство искусственных волокон" + }, + { + "code": "21.10", + "title": "Производство основных фармацевтических продуктов" + }, + { + "code": "21.10.1", + "title": "Производство основных фармацевтических продуктов" + }, + { + "code": "21.20", + "title": "Производство фармацевтических препаратов и материалов, применяемых в медицинских целях" + }, + { + "code": "21.20.1", + "title": "Производство лекарственных препаратов" + }, + { + "code": "21.20.2", + "title": "Производство медицинских материалов и изделий" + }, + { + "code": "22.11", + "title": "Производство резиновых шин, покрышек и камер; восстановление резиновых шин" + }, + { + "code": "22.11.1", + "title": "Производство резиновых шин, покрышек и камер" + }, + { + "code": "22.11.2", + "title": "Восстановление резиновых шин" + }, + { + "code": "22.19", + "title": "Производство прочих резиновых изделий" + }, + { + "code": "22.19.1", + "title": "Производство резиновых изделий" + }, + { + "code": "22.21", + "title": "Производство пластмассовых плит, полос, труб и профилей" + }, + { + "code": "22.21.1", + "title": "Производство пластмассовых плит, листов, блоков, пленки, полосы, лент" + }, + { + "code": "22.21.2", + "title": "Производство пластмассовых труб, трубок, шлангов и фитингов к ним" + }, + { + "code": "22.22", + "title": "Производство пластмассовых изделий для упаковывания товаров" + }, + { + "code": "22.22.1", + "title": "Производство пластмассовых изделий для упаковывания товаров" + }, + { + "code": "22.23", + "title": "Производство пластмассовых изделий, используемых в строительстве" + }, + { + "code": "22.23.1", + "title": "Производство пластмассовых изделий, используемых в строительстве" + }, + { + "code": "22.29", + "title": "Производство прочих пластмассовых изделий" + }, + { + "code": "22.29.1", + "title": "Производство пластмассовых изделий для использования в домашнем хозяйстве" + }, + { + "code": "22.29.2", + "title": "Производство прочих пластмассовых изделий" + }, + { + "code": "23.11", + "title": "Производство листового стекла" + }, + { + "code": "23.11.1", + "title": "Производство листового стекла" + }, + { + "code": "23.12", + "title": "Формование и обработка листового стекла" + }, + { + "code": "23.12.1", + "title": "Производство безопасного стекла" + }, + { + "code": "23.12.2", + "title": "Производство изолирующих стеклянных изделий со стеклопакетами" + }, + { + "code": "23.13", + "title": "Производство полых стеклянных изделий" + }, + { + "code": "23.13.1", + "title": "Производство полых стеклянных изделий" + }, + { + "code": "23.14", + "title": "Производство стекловолокна" + }, + { + "code": "23.14.1", + "title": "Производство стекловолокна" + }, + { + "code": "23.19", + "title": "Производство и обработка прочих стеклянных изделий, включая технические изделия из стекла" + }, + { + "code": "23.19.1", + "title": "Производство и обработка прочих стеклянных изделий" + }, + { + "code": "23.20", + "title": "Производство огнеупоров" + }, + { + "code": "23.20.1", + "title": "Производство огнеупорных изделий" + }, + { + "code": "23.31", + "title": "Производство керамических плиток и плит" + }, + { + "code": "23.31.1", + "title": "Производство керамических плиток и плит" + }, + { + "code": "23.32", + "title": "Производство кирпича, черепицы и прочих строительных изделий из обожженной глины" + }, + { + "code": "23.32.1", + "title": "Производство кирпича" + }, + { + "code": "23.32.2", + "title": "Производство черепицы" + }, + { + "code": "23.32.3", + "title": "Производство прочих строительных изделий из обожженной глины" + }, + { + "code": "23.41", + "title": "Производство керамических изделий хозяйственного и декоративного назначения" + }, + { + "code": "23.41.1", + "title": "Производство керамических изделий хозяйственного и декоративного назначения" + }, + { + "code": "23.42", + "title": "Производство керамических санитарно-технических изделий" + }, + { + "code": "23.42.1", + "title": "Производство керамических санитарно-технических изделий" + }, + { + "code": "23.43", + "title": "Производство керамических изоляторов и изолирующей арматуры" + }, + { + "code": "23.43.1", + "title": "Производство керамических изоляторов и изолирующей арматуры" + }, + { + "code": "23.44", + "title": "Производство прочих технических керамических изделий" + }, + { + "code": "23.44.1", + "title": "Производство прочих технических керамических изделий" + }, + { + "code": "23.49", + "title": "Производство прочих керамических изделий" + }, + { + "code": "23.49.1", + "title": "Производство прочих керамических изделий" + }, + { + "code": "23.51", + "title": "Производство цемента" + }, + { + "code": "23.51.1", + "title": "Производство цемента" + }, + { + "code": "23.52", + "title": "Производство извести и гипса" + }, + { + "code": "23.52.1", + "title": "Производство извести" + }, + { + "code": "23.52.2", + "title": "Производство гипса" + }, + { + "code": "23.61", + "title": "Производство изделий из бетона для использования в строительстве" + }, + { + "code": "23.61.1", + "title": "Производство сборных бетонных конструкций и изделий" + }, + { + "code": "23.61.2", + "title": "Производство прочих изделий из бетона для строительства" + }, + { + "code": "23.62", + "title": "Производство изделий из гипса для использования в строительстве" + }, + { + "code": "23.62.1", + "title": "Производство изделий из гипса для использования в строительстве" + }, + { + "code": "23.63", + "title": "Производство бетонных смесей" + }, + { + "code": "23.63.1", + "title": "Производство товарного бетона" + }, + { + "code": "23.64", + "title": "Производство строительных растворов" + }, + { + "code": "23.64.1", + "title": "Производство сухих строительных смесей" + }, + { + "code": "23.65", + "title": "Производство изделий из асбестоцемента, волокнистого цемента и аналогичных материалов" + }, + { + "code": "23.65.1", + "title": "Производство изделий из асбестоцемента" + }, + { + "code": "23.65.2", + "title": "Производство изделий из волокнистого цемента" + }, + { + "code": "23.69", + "title": "Производство прочих изделий из бетона, гипса и цемента" + }, + { + "code": "23.69.1", + "title": "Производство прочих изделий из бетона, гипса и цемента" + }, + { + "code": "23.70", + "title": "Резка, обработка и отделка декоративного и строительного камня" + }, + { + "code": "23.70.1", + "title": "Резка, обработка и отделка декоративного и строительного камня" + }, + { + "code": "23.91", + "title": "Производство абразивных изделий" + }, + { + "code": "23.91.1", + "title": "Производство абразивных изделий" + }, + { + "code": "23.99", + "title": "Производство прочих неметаллических минеральных продуктов, не включенных в другие группировки" + }, + { + "code": "23.99.1", + "title": "Производство прочих неметаллических минеральных продуктов" + }, + { + "code": "62.01", + "title": "Разработка компьютерного программного обеспечения" + }, + { + "code": "62.02", + "title": "Деятельность по консультированию в области компьютерных технологий" + }, + { + "code": "62.03", + "title": "Деятельность по управлению компьютерным оборудованием" + }, + { + "code": "62.09", + "title": "Деятельность, связанная с использованием вычислительной техники и информационных технологий, прочая" + }, + { + "code": "63.11", + "title": "Деятельность по обработке данных, предоставление услуг по размещению информации и связанная с этим деятельность" + }, + { + "code": "63.12", + "title": "Деятельность web-порталов" + }, + { + "code": "70.10", + "title": "Деятельность головных офисов" + }, + { + "code": "70.22", + "title": "Консультирование по вопросам коммерческой деятельности и управления" + }, + { + "code": "85.11", + "title": "Образование дошкольное" + }, + { + "code": "85.12", + "title": "Образование начальное общее" + }, + { + "code": "85.13", + "title": "Образование основное общее" + }, + { + "code": "85.14", + "title": "Образование среднее общее" + }, + { + "code": "85.21", + "title": "Образование профессиональное среднее" + }, + { + "code": "85.22", + "title": "Образование высшее" + }, + { + "code": "85.23", + "title": "Обучение профессиональное" + }, + { + "code": "85.41", + "title": "Образование дополнительное детей и взрослых" + }, + { + "code": "85.42", + "title": "Образование профессиональное дополнительное" + }, + { + "code": "86.10", + "title": "Деятельность больничных организаций" + }, + { + "code": "86.21", + "title": "Общая врачебная практика" + }, + { + "code": "86.22", + "title": "Специальная врачебная практика" + }, + { + "code": "86.23", + "title": "Стоматологическая практика" + }, + { + "code": "86.90", + "title": "Деятельность в области здравоохранения прочая" + }, + { + "code": "24.10", + "title": "Производство чугуна, стали и ферросплавов" + }, + { + "code": "24.10.1", + "title": "Производство чугуна" + }, + { + "code": "24.10.2", + "title": "Производство нелегированной стали" + }, + { + "code": "24.10.3", + "title": "Производство нержавеющей стали" + }, + { + "code": "24.10.4", + "title": "Производство прочих легированных сталей" + }, + { + "code": "24.10.5", + "title": "Производство ферросплавов" + }, + { + "code": "24.20", + "title": "Производство стальных труб, полых профилей и фитингов" + }, + { + "code": "24.20.1", + "title": "Производство стальных труб" + }, + { + "code": "24.20.2", + "title": "Производство полых профилей и фитингов из стали" + }, + { + "code": "24.31", + "title": "Холодное волочение прутков" + }, + { + "code": "24.31.1", + "title": "Холодное волочение прутков" + }, + { + "code": "24.32", + "title": "Холодная прокатка узких полос" + }, + { + "code": "24.32.1", + "title": "Холодная прокатка узких полос" + }, + { + "code": "24.33", + "title": "Холодное профилирование" + }, + { + "code": "24.33.1", + "title": "Холодное профилирование" + }, + { + "code": "24.34", + "title": "Холодное волочение проволоки" + }, + { + "code": "24.34.1", + "title": "Холодное волочение проволоки" + }, + { + "code": "24.41", + "title": "Производство драгоценных металлов" + }, + { + "code": "24.41.1", + "title": "Производство драгоценных металлов" + }, + { + "code": "24.42", + "title": "Производство алюминия" + }, + { + "code": "24.42.1", + "title": "Производство первичного алюминия" + }, + { + "code": "24.42.2", + "title": "Производство вторичного алюминия" + }, + { + "code": "24.43", + "title": "Производство свинца, цинка и олова" + }, + { + "code": "24.43.1", + "title": "Производство свинца" + }, + { + "code": "24.43.2", + "title": "Производство цинка" + }, + { + "code": "24.43.3", + "title": "Производство олова" + }, + { + "code": "24.44", + "title": "Производство меди" + }, + { + "code": "24.44.1", + "title": "Производство меди" + }, + { + "code": "24.45", + "title": "Производство прочих цветных металлов" + }, + { + "code": "24.45.1", + "title": "Производство никеля" + }, + { + "code": "24.45.2", + "title": "Производство титана" + }, + { + "code": "24.45.3", + "title": "Производство прочих цветных металлов" + }, + { + "code": "24.46", + "title": "Обработка ядерного топлива" + }, + { + "code": "24.46.1", + "title": "Обработка ядерного топлива" + }, + { + "code": "24.51", + "title": "Литье чугуна" + }, + { + "code": "24.51.1", + "title": "Литье чугуна" + }, + { + "code": "24.52", + "title": "Литье стали" + }, + { + "code": "24.52.1", + "title": "Литье стали" + }, + { + "code": "24.53", + "title": "Литье легких металлов" + }, + { + "code": "24.53.1", + "title": "Литье алюминия" + }, + { + "code": "24.53.2", + "title": "Литье прочих легких металлов" + }, + { + "code": "24.54", + "title": "Литье прочих цветных металлов" + }, + { + "code": "24.54.1", + "title": "Литье меди" + }, + { + "code": "24.54.2", + "title": "Литье прочих цветных металлов" + }, + { + "code": "25.11", + "title": "Производство строительных металлических конструкций" + }, + { + "code": "25.11.1", + "title": "Производство строительных металлических конструкций и их частей" + }, + { + "code": "25.12", + "title": "Производство дверей и окон из металла" + }, + { + "code": "25.12.1", + "title": "Производство дверей и окон из металла" + }, + { + "code": "25.21", + "title": "Производство радиаторов и котлов центрального отопления" + }, + { + "code": "25.21.1", + "title": "Производство радиаторов и котлов центрального отопления" + }, + { + "code": "25.29", + "title": "Производство прочих резервуаров, цистерн и контейнеров из металла" + }, + { + "code": "25.29.1", + "title": "Производство резервуаров, цистерн и контейнеров из металла" + }, + { + "code": "25.30", + "title": "Производство паровых котлов, кроме котлов центрального отопления" + }, + { + "code": "25.30.1", + "title": "Производство паровых котлов" + }, + { + "code": "25.30.2", + "title": "Производство вспомогательного оборудования для паровых котлов" + }, + { + "code": "25.40", + "title": "Производство оружия и боеприпасов" + }, + { + "code": "25.40.1", + "title": "Производство тяжелого оружия" + }, + { + "code": "25.40.2", + "title": "Производство стрелкового оружия" + }, + { + "code": "25.40.3", + "title": "Производство боеприпасов" + }, + { + "code": "25.50", + "title": "Ковка, прессование, штамповка и профилирование; порошковая металлургия" + }, + { + "code": "25.50.1", + "title": "Ковка, прессование, штамповка и профилирование металлов" + }, + { + "code": "25.50.2", + "title": "Порошковая металлургия" + }, + { + "code": "25.61", + "title": "Обработка металлов и нанесение покрытий на металлы" + }, + { + "code": "25.61.1", + "title": "Обработка металлов и нанесение покрытий на металлы" + }, + { + "code": "25.62", + "title": "Механическая обработка металлических изделий" + }, + { + "code": "25.62.1", + "title": "Механическая обработка металлических изделий" + }, + { + "code": "25.71", + "title": "Производство ножевых изделий" + }, + { + "code": "25.71.1", + "title": "Производство ножевых изделий" + }, + { + "code": "25.72", + "title": "Производство замков и петель" + }, + { + "code": "25.72.1", + "title": "Производство замков и петель" + }, + { + "code": "25.73", + "title": "Производство инструментов" + }, + { + "code": "25.73.1", + "title": "Производство ручных инструментов" + }, + { + "code": "25.73.2", + "title": "Производство инструментов для машин" + }, + { + "code": "25.91", + "title": "Производство стальных бочек и аналогичных емкостей" + }, + { + "code": "25.91.1", + "title": "Производство стальных бочек и аналогичных емкостей" + }, + { + "code": "25.92", + "title": "Производство упаковки из легких металлов" + }, + { + "code": "25.92.1", + "title": "Производство упаковки из легких металлов" + }, + { + "code": "25.93", + "title": "Производство изделий из проволоки, цепей и пружин" + }, + { + "code": "25.93.1", + "title": "Производство изделий из проволоки" + }, + { + "code": "25.93.2", + "title": "Производство цепей и пружин" + }, + { + "code": "25.94", + "title": "Производство крепежных изделий" + }, + { + "code": "25.94.1", + "title": "Производство крепежных изделий" + }, + { + "code": "25.99", + "title": "Производство прочих готовых металлических изделий, не включенных в другие группировки" + }, + { + "code": "25.99.1", + "title": "Производство сейфов, несгораемых шкафов" + }, + { + "code": "25.99.2", + "title": "Производство прочих готовых металлических изделий" + }, + { + "code": "26.11", + "title": "Производство электронных компонентов" + }, + { + "code": "26.11.1", + "title": "Производство электронных ламп и электровакуумных приборов" + }, + { + "code": "26.11.2", + "title": "Производство полупроводниковых приборов" + }, + { + "code": "26.11.3", + "title": "Производство прочих электронных компонентов" + }, + { + "code": "26.12", + "title": "Производство электронных печатных плат" + }, + { + "code": "26.12.1", + "title": "Производство электронных печатных плат" + }, + { + "code": "26.20", + "title": "Производство компьютеров и периферийного оборудования" + }, + { + "code": "26.20.1", + "title": "Производство вычислительных машин и их блоков" + }, + { + "code": "26.20.2", + "title": "Производство периферийного оборудования" + }, + { + "code": "26.30", + "title": "Производство коммуникационного оборудования" + }, + { + "code": "26.30.1", + "title": "Производство передающей радиоэлектронной аппаратуры" + }, + { + "code": "26.30.2", + "title": "Производство телевизионной передающей аппаратуры" + }, + { + "code": "26.30.3", + "title": "Производство телефонного и факсимильного оборудования" + }, + { + "code": "26.40", + "title": "Производство бытовой электроники" + }, + { + "code": "26.40.1", + "title": "Производство бытовой радиоэлектронной аппаратуры" + }, + { + "code": "26.40.2", + "title": "Производство телевизоров" + }, + { + "code": "26.40.3", + "title": "Производство звукозаписывающей и звуковоспроизводящей аппаратуры" + }, + { + "code": "26.51", + "title": "Производство приборов и аппаратуры для измерения, тестирования и навигации" + }, + { + "code": "26.51.1", + "title": "Производство навигационных, метеорологических, геофизических приборов" + }, + { + "code": "26.51.2", + "title": "Производство радиолокационной аппаратуры" + }, + { + "code": "26.51.3", + "title": "Производство приборов для измерения, контроля, испытаний" + }, + { + "code": "26.52", + "title": "Производство часов" + }, + { + "code": "26.52.1", + "title": "Производство часов всех видов" + }, + { + "code": "26.60", + "title": "Производство облучающего, электромедицинского и электротерапевтического оборудования" + }, + { + "code": "26.60.1", + "title": "Производство облучающего, электромедицинского и электротерапевтического оборудования" + }, + { + "code": "26.70", + "title": "Производство оптических приборов и фотографического оборудования" + }, + { + "code": "26.70.1", + "title": "Производство оптических приборов" + }, + { + "code": "26.70.2", + "title": "Производство фотографического оборудования" + }, + { + "code": "26.80", + "title": "Производство магнитных и оптических носителей информации" + }, + { + "code": "26.80.1", + "title": "Производство магнитных и оптических носителей информации" + }, + { + "code": "27.11", + "title": "Производство электродвигателей, генераторов и трансформаторов" + }, + { + "code": "27.11.1", + "title": "Производство электродвигателей" + }, + { + "code": "27.11.2", + "title": "Производство генераторов" + }, + { + "code": "27.11.3", + "title": "Производство трансформаторов" + }, + { + "code": "27.12", + "title": "Производство аппаратуры распределения и управления электроэнергией" + }, + { + "code": "27.12.1", + "title": "Производство аппаратуры распределения и управления электроэнергией" + }, + { + "code": "27.20", + "title": "Производство батарей и аккумуляторов" + }, + { + "code": "27.20.1", + "title": "Производство первичных элементов и первичных батарей" + }, + { + "code": "27.20.2", + "title": "Производство аккумуляторов" + }, + { + "code": "27.31", + "title": "Производство оптоволоконных кабелей" + }, + { + "code": "27.31.1", + "title": "Производство оптоволоконных кабелей" + }, + { + "code": "27.32", + "title": "Производство прочих электронных и электрических проводов и кабелей" + }, + { + "code": "27.32.1", + "title": "Производство прочих электронных и электрических проводов и кабелей" + }, + { + "code": "27.33", + "title": "Производство электромонтажных устройств" + }, + { + "code": "27.33.1", + "title": "Производство электромонтажных устройств" + }, + { + "code": "27.40", + "title": "Производство электрических ламп и осветительного оборудования" + }, + { + "code": "27.40.1", + "title": "Производство электрических ламп и осветительного оборудования" + }, + { + "code": "27.51", + "title": "Производство бытовых электрических приборов" + }, + { + "code": "27.51.1", + "title": "Производство бытовых холодильников и морозильников" + }, + { + "code": "27.51.2", + "title": "Производство прочих бытовых электрических приборов" + }, + { + "code": "27.52", + "title": "Производство неэлектрических бытовых приборов" + }, + { + "code": "27.52.1", + "title": "Производство неэлектрических бытовых приборов" + }, + { + "code": "27.90", + "title": "Производство прочего электрического оборудования" + }, + { + "code": "27.90.1", + "title": "Производство прочего электрического оборудования" + }, + { + "code": "28.11", + "title": "Производство двигателей и турбин, кроме авиационных, автомобильных и мотоциклетных двигателей" + }, + { + "code": "28.11.1", + "title": "Производство паровых турбин" + }, + { + "code": "28.11.2", + "title": "Производство гидравлических турбин" + }, + { + "code": "28.11.3", + "title": "Производство газовых турбин" + }, + { + "code": "28.11.4", + "title": "Производство прочих двигателей и турбин" + }, + { + "code": "28.12", + "title": "Производство гидравлического и пневматического силового оборудования" + }, + { + "code": "28.12.1", + "title": "Производство гидравлического и пневматического силового оборудования" + }, + { + "code": "28.13", + "title": "Производство прочих насосов и компрессоров" + }, + { + "code": "28.13.1", + "title": "Производство насосов" + }, + { + "code": "28.13.2", + "title": "Производство компрессоров" + }, + { + "code": "28.14", + "title": "Производство прочей арматуры" + }, + { + "code": "28.14.1", + "title": "Производство кранов и клапанов" + }, + { + "code": "28.14.2", + "title": "Производство прочей арматуры" + }, + { + "code": "28.15", + "title": "Производство подшипников, зубчатых передач, элементов механических передач и приводов" + }, + { + "code": "28.15.1", + "title": "Производство подшипников" + }, + { + "code": "28.15.2", + "title": "Производство зубчатых передач и элементов механических передач" + }, + { + "code": "28.21", + "title": "Производство печей, топок и горелок" + }, + { + "code": "28.21.1", + "title": "Производство печей и топок" + }, + { + "code": "28.21.2", + "title": "Производство горелок" + }, + { + "code": "28.22", + "title": "Производство подъемно-транспортного оборудования" + }, + { + "code": "28.22.1", + "title": "Производство подъемно-транспортного оборудования" + }, + { + "code": "28.23", + "title": "Производство офисного оборудования и вычислительной техники (кроме компьютеров и периферийного оборудования)" + }, + { + "code": "28.23.1", + "title": "Производство офисного оборудования и вычислительной техники" + }, + { + "code": "28.24", + "title": "Производство ручного инструмента с механическим приводом" + }, + { + "code": "28.24.1", + "title": "Производство ручного инструмента с механическим приводом" + }, + { + "code": "28.25", + "title": "Производство промышленного холодильного и вентиляционного оборудования" + }, + { + "code": "28.25.1", + "title": "Производство промышленного холодильного оборудования" + }, + { + "code": "28.25.2", + "title": "Производство промышленного вентиляционного оборудования" + }, + { + "code": "28.29", + "title": "Производство прочих машин и оборудования общего назначения, не включенных в другие группировки" + }, + { + "code": "28.29.1", + "title": "Производство прочих машин и оборудования общего назначения" + }, + { + "code": "28.30", + "title": "Производство сельскохозяйственных и лесохозяйственных машин" + }, + { + "code": "28.30.1", + "title": "Производство тракторов" + }, + { + "code": "28.30.2", + "title": "Производство сельскохозяйственных машин" + }, + { + "code": "28.30.3", + "title": "Производство лесохозяйственных машин" + }, + { + "code": "28.41", + "title": "Производство металлообрабатывающих станков" + }, + { + "code": "28.41.1", + "title": "Производство металлообрабатывающих станков" + }, + { + "code": "28.49", + "title": "Производство прочих станков" + }, + { + "code": "28.49.1", + "title": "Производство деревообрабатывающих станков" + }, + { + "code": "28.49.2", + "title": "Производство прочих станков" + }, + { + "code": "28.91", + "title": "Производство машин и оборудования для металлургии" + }, + { + "code": "28.91.1", + "title": "Производство машин и оборудования для металлургии" + }, + { + "code": "28.92", + "title": "Производство машин и оборудования для добычи полезных ископаемых и строительства" + }, + { + "code": "28.92.1", + "title": "Производство машин для добычи полезных ископаемых" + }, + { + "code": "28.92.2", + "title": "Производство строительных машин" + }, + { + "code": "28.93", + "title": "Производство машин и оборудования для изготовления пищевых продуктов, включая напитки, и табачных изделий" + }, + { + "code": "28.93.1", + "title": "Производство машин для пищевой промышленности" + }, + { + "code": "28.93.2", + "title": "Производство машин для производства напитков" + }, + { + "code": "28.93.3", + "title": "Производство машин для табачной промышленности" + }, + { + "code": "28.94", + "title": "Производство машин и оборудования для изготовления текстильных, швейных и меховых изделий" + }, + { + "code": "28.94.1", + "title": "Производство машин для текстильной промышленности" + }, + { + "code": "28.94.2", + "title": "Производство швейных машин" + }, + { + "code": "28.94.3", + "title": "Производство машин для меховой промышленности" + }, + { + "code": "28.95", + "title": "Производство машин и оборудования для изготовления бумаги и картона" + }, + { + "code": "28.95.1", + "title": "Производство машин и оборудования для изготовления бумаги и картона" + }, + { + "code": "28.96", + "title": "Производство машин и оборудования для обработки пластмасс и резины" + }, + { + "code": "28.96.1", + "title": "Производство машин и оборудования для обработки пластмасс и резины" + }, + { + "code": "28.99", + "title": "Производство прочих машин и оборудования специального назначения, не включенных в другие группировки" + }, + { + "code": "28.99.1", + "title": "Производство прочих машин и оборудования специального назначения" + }, + { + "code": "29.10", + "title": "Производство автомобилей и автомобильных двигателей" + }, + { + "code": "29.10.1", + "title": "Производство легковых автомобилей" + }, + { + "code": "29.10.2", + "title": "Производство грузовых автомобилей" + }, + { + "code": "29.10.3", + "title": "Производство автомобильных двигателей" + }, + { + "code": "29.20", + "title": "Производство кузовов для автомобилей; производство прицепов и полуприцепов" + }, + { + "code": "29.20.1", + "title": "Производство кузовов для автомобилей" + }, + { + "code": "29.20.2", + "title": "Производство прицепов и полуприцепов" + }, + { + "code": "29.31", + "title": "Производство электрического и электронного оборудования для автомобилей" + }, + { + "code": "29.31.1", + "title": "Производство электрического и электронного оборудования для автомобилей" + }, + { + "code": "29.32", + "title": "Производство прочих частей и принадлежностей для автомобилей" + }, + { + "code": "29.32.1", + "title": "Производство прочих частей и принадлежностей для автомобилей" + }, + { + "code": "30.11", + "title": "Строительство кораблей и плавучих конструкций" + }, + { + "code": "30.11.1", + "title": "Строительство кораблей и плавучих конструкций" + }, + { + "code": "30.12", + "title": "Строительство прогулочных и спортивных судов" + }, + { + "code": "30.12.1", + "title": "Строительство прогулочных и спортивных судов" + }, + { + "code": "30.20", + "title": "Производство железнодорожных локомотивов и подвижного состава" + }, + { + "code": "30.20.1", + "title": "Производство железнодорожных локомотивов" + }, + { + "code": "30.20.2", + "title": "Производство железнодорожного подвижного состава" + }, + { + "code": "30.30", + "title": "Производство летательных аппаратов, включая космические" + }, + { + "code": "30.30.1", + "title": "Производство самолетов" + }, + { + "code": "30.30.2", + "title": "Производство вертолетов" + }, + { + "code": "30.30.3", + "title": "Производство космических аппаратов" + }, + { + "code": "30.40", + "title": "Производство военных боевых машин" + }, + { + "code": "30.40.1", + "title": "Производство военных боевых машин" + }, + { + "code": "30.91", + "title": "Производство мотоциклов" + }, + { + "code": "30.91.1", + "title": "Производство мотоциклов" + }, + { + "code": "30.92", + "title": "Производство велосипедов и инвалидных колясок" + }, + { + "code": "30.92.1", + "title": "Производство велосипедов" + }, + { + "code": "30.92.2", + "title": "Производство инвалидных колясок" + }, + { + "code": "30.99", + "title": "Производство прочих транспортных средств и оборудования, не включенных в другие группировки" + }, + { + "code": "30.99.1", + "title": "Производство прочих транспортных средств и оборудования" + }, + { + "code": "31.01", + "title": "Производство офисной мебели" + }, + { + "code": "31.01.1", + "title": "Производство офисной мебели" + }, + { + "code": "31.02", + "title": "Производство кухонной мебели" + }, + { + "code": "31.02.1", + "title": "Производство кухонной мебели" + }, + { + "code": "31.03", + "title": "Производство матрасов" + }, + { + "code": "31.03.1", + "title": "Производство матрасов" + }, + { + "code": "31.09", + "title": "Производство прочей мебели" + }, + { + "code": "31.09.1", + "title": "Производство мебели для спальни" + }, + { + "code": "31.09.2", + "title": "Производство мебели для гостиной" + }, + { + "code": "31.09.3", + "title": "Производство прочей мебели" + }, + { + "code": "32.11", + "title": "Чеканка монет" + }, + { + "code": "32.11.1", + "title": "Чеканка монет" + }, + { + "code": "32.12", + "title": "Производство ювелирных и аналогичных изделий" + }, + { + "code": "32.12.1", + "title": "Производство ювелирных изделий из драгоценных металлов" + }, + { + "code": "32.12.2", + "title": "Обработка драгоценных камней" + }, + { + "code": "32.13", + "title": "Производство бижутерии и аналогичных изделий" + }, + { + "code": "32.13.1", + "title": "Производство бижутерии и аналогичных изделий" + }, + { + "code": "32.20", + "title": "Производство музыкальных инструментов" + }, + { + "code": "32.20.1", + "title": "Производство музыкальных инструментов" + }, + { + "code": "32.30", + "title": "Производство спортивных товаров" + }, + { + "code": "32.30.1", + "title": "Производство спортивных товаров" + }, + { + "code": "32.40", + "title": "Производство игр и игрушек" + }, + { + "code": "32.40.1", + "title": "Производство игр и игрушек" + }, + { + "code": "32.50", + "title": "Производство медицинских и стоматологических инструментов и принадлежностей" + }, + { + "code": "32.50.1", + "title": "Производство медицинских и стоматологических инструментов" + }, + { + "code": "32.50.2", + "title": "Производство ортопедических приспособлений" + }, + { + "code": "32.91", + "title": "Производство метел и щеток" + }, + { + "code": "32.91.1", + "title": "Производство метел и щеток" + }, + { + "code": "32.99", + "title": "Производство прочих готовых изделий, не включенных в другие группировки" + }, + { + "code": "32.99.1", + "title": "Производство зонтов" + }, + { + "code": "32.99.2", + "title": "Производство пуговиц, застежек-молний" + }, + { + "code": "32.99.3", + "title": "Производство прочих готовых изделий" + }, + { + "code": "33.11", + "title": "Ремонт и техническое обслуживание изделий из металла" + }, + { + "code": "33.11.1", + "title": "Ремонт и техническое обслуживание изделий из металла" + }, + { + "code": "33.12", + "title": "Ремонт и техническое обслуживание машин и оборудования" + }, + { + "code": "33.12.1", + "title": "Ремонт и техническое обслуживание машин общего назначения" + }, + { + "code": "33.12.2", + "title": "Ремонт и техническое обслуживание машин специального назначения" + }, + { + "code": "33.13", + "title": "Ремонт и техническое обслуживание электронного и оптического оборудования" + }, + { + "code": "33.13.1", + "title": "Ремонт и техническое обслуживание электронного и оптического оборудования" + }, + { + "code": "33.14", + "title": "Ремонт и техническое обслуживание электрического оборудования" + }, + { + "code": "33.14.1", + "title": "Ремонт и техническое обслуживание электрического оборудования" + }, + { + "code": "33.15", + "title": "Ремонт и техническое обслуживание судов и лодок" + }, + { + "code": "33.15.1", + "title": "Ремонт и техническое обслуживание судов и лодок" + }, + { + "code": "33.16", + "title": "Ремонт и техническое обслуживание летательных аппаратов и космических аппаратов" + }, + { + "code": "33.16.1", + "title": "Ремонт и техническое обслуживание летательных аппаратов и космических аппаратов" + }, + { + "code": "33.17", + "title": "Ремонт и техническое обслуживание прочих транспортных средств и оборудования" + }, + { + "code": "33.17.1", + "title": "Ремонт и техническое обслуживание прочих транспортных средств и оборудования" + }, + { + "code": "33.19", + "title": "Ремонт и техническое обслуживание прочего оборудования" + }, + { + "code": "33.19.1", + "title": "Ремонт и техническое обслуживание прочего оборудования" + }, + { + "code": "33.20", + "title": "Монтаж промышленных машин и оборудования" + }, + { + "code": "33.20.1", + "title": "Монтаж промышленных машин и оборудования" + }, + { + "code": "35.11", + "title": "Производство электроэнергии" + }, + { + "code": "35.11.1", + "title": "Производство электроэнергии тепловыми электростанциями" + }, + { + "code": "35.11.2", + "title": "Производство электроэнергии гидроэлектростанциями" + }, + { + "code": "35.11.3", + "title": "Производство электроэнергии атомными электростанциями" + }, + { + "code": "35.11.4", + "title": "Производство электроэнергии солнечными, ветровыми и прочими электростанциями" + }, + { + "code": "35.12", + "title": "Передача электроэнергии" + }, + { + "code": "35.12.1", + "title": "Передача электроэнергии" + }, + { + "code": "35.13", + "title": "Распределение электроэнергии" + }, + { + "code": "35.13.1", + "title": "Распределение электроэнергии" + }, + { + "code": "35.14", + "title": "Торговля электроэнергией" + }, + { + "code": "35.14.1", + "title": "Торговля электроэнергией" + }, + { + "code": "35.21", + "title": "Производство газа" + }, + { + "code": "35.21.1", + "title": "Производство газа" + }, + { + "code": "35.22", + "title": "Распределение газообразного топлива по газораспределительным сетям" + }, + { + "code": "35.22.1", + "title": "Распределение газообразного топлива по газораспределительным сетям" + }, + { + "code": "35.23", + "title": "Торговля газообразным топливом, подаваемым по распределительным сетям" + }, + { + "code": "35.23.1", + "title": "Торговля газообразным топливом, подаваемым по распределительным сетям" + }, + { + "code": "35.30", + "title": "Подача пара и горячей воды (тепловой энергии)" + }, + { + "code": "35.30.1", + "title": "Подача пара и горячей воды (тепловой энергии)" + }, + { + "code": "36.00", + "title": "Забор, очистка и распределение воды" + }, + { + "code": "36.00.1", + "title": "Забор, очистка и распределение воды" + }, + { + "code": "37.00", + "title": "Сбор и обработка сточных вод" + }, + { + "code": "37.00.1", + "title": "Сбор и обработка сточных вод" + }, + { + "code": "38.11", + "title": "Сбор неопасных отходов" + }, + { + "code": "38.11.1", + "title": "Сбор неопасных отходов" + }, + { + "code": "38.12", + "title": "Сбор опасных отходов" + }, + { + "code": "38.12.1", + "title": "Сбор опасных отходов" + }, + { + "code": "38.21", + "title": "Обработка и утилизация неопасных отходов" + }, + { + "code": "38.21.1", + "title": "Обработка и утилизация неопасных отходов" + }, + { + "code": "38.22", + "title": "Обработка и утилизация опасных отходов" + }, + { + "code": "38.22.1", + "title": "Обработка и утилизация опасных отходов" + }, + { + "code": "38.31", + "title": "Демонтаж (разборка) машин и оборудования, рекуперация материалов" + }, + { + "code": "38.31.1", + "title": "Демонтаж (разборка) машин и оборудования, рекуперация материалов" + }, + { + "code": "38.32", + "title": "Утилизация сортированных материалов" + }, + { + "code": "38.32.1", + "title": "Утилизация сортированных материалов" + }, + { + "code": "39.00", + "title": "Предоставление услуг в области ликвидации загрязнений и прочих услуг, связанных с удалением отходов" + }, + { + "code": "39.00.1", + "title": "Предоставление услуг в области ликвидации загрязнений и прочих услуг, связанных с удалением отходов" + }, + { + "code": "41.10", + "title": "Разработка строительных проектов" + }, + { + "code": "41.10.1", + "title": "Разработка строительных проектов зданий" + }, + { + "code": "41.10.2", + "title": "Разработка строительных проектов инженерных сооружений" + }, + { + "code": "41.20", + "title": "Строительство жилых и нежилых зданий" + }, + { + "code": "41.20.1", + "title": "Строительство жилых зданий" + }, + { + "code": "41.20.2", + "title": "Строительство нежилых зданий" + }, + { + "code": "42.11", + "title": "Строительство автомобильных дорог и автомагистралей" + }, + { + "code": "42.11.1", + "title": "Строительство автомобильных дорог и автомагистралей" + }, + { + "code": "42.12", + "title": "Строительство железных дорог и метрополитена" + }, + { + "code": "42.12.1", + "title": "Строительство железных дорог" + }, + { + "code": "42.12.2", + "title": "Строительство метрополитена" + }, + { + "code": "42.13", + "title": "Строительство мостов и тоннелей" + }, + { + "code": "42.13.1", + "title": "Строительство мостов" + }, + { + "code": "42.13.2", + "title": "Строительство тоннелей" + }, + { + "code": "42.21", + "title": "Строительство трубопроводов для транспортировки газа и нефти" + }, + { + "code": "42.21.1", + "title": "Строительство газопроводов" + }, + { + "code": "42.21.2", + "title": "Строительство нефтепроводов" + }, + { + "code": "42.22", + "title": "Строительство электрических и телекоммуникационных линий" + }, + { + "code": "42.22.1", + "title": "Строительство электрических линий" + }, + { + "code": "42.22.2", + "title": "Строительство телекоммуникационных линий" + }, + { + "code": "42.91", + "title": "Строительство промышленных объектов" + }, + { + "code": "42.91.1", + "title": "Строительство промышленных объектов" + }, + { + "code": "42.99", + "title": "Строительство прочих инженерных сооружений, не включенных в другие группировки" + }, + { + "code": "42.99.1", + "title": "Строительство прочих инженерных сооружений" + }, + { + "code": "43.11", + "title": "Разборка и снос зданий" + }, + { + "code": "43.11.1", + "title": "Разборка и снос зданий" + }, + { + "code": "43.12", + "title": "Подготовка строительной площадки" + }, + { + "code": "43.12.1", + "title": "Подготовка строительной площадки" + }, + { + "code": "43.13", + "title": "Пробное бурение грунта" + }, + { + "code": "43.13.1", + "title": "Пробное бурение грунта" + }, + { + "code": "43.21", + "title": "Производство электромонтажных работ" + }, + { + "code": "43.21.1", + "title": "Производство электромонтажных работ" + }, + { + "code": "43.22", + "title": "Производство санитарно-технических работ, монтаж отопительных систем и систем кондиционирования воздуха" + }, + { + "code": "43.22.1", + "title": "Производство санитарно-технических работ" + }, + { + "code": "43.22.2", + "title": "Монтаж отопительных систем и систем кондиционирования воздуха" + }, + { + "code": "43.29", + "title": "Производство прочих строительно-монтажных работ" + }, + { + "code": "43.29.1", + "title": "Производство прочих строительно-монтажных работ" + }, + { + "code": "43.31", + "title": "Производство штукатурных работ" + }, + { + "code": "43.31.1", + "title": "Производство штукатурных работ" + }, + { + "code": "43.32", + "title": "Производство столярных и плотничных работ" + }, + { + "code": "43.32.1", + "title": "Производство столярных и плотничных работ" + }, + { + "code": "43.33", + "title": "Настилка полов и облицовка стен" + }, + { + "code": "43.33.1", + "title": "Настилка полов и облицовка стен" + }, + { + "code": "43.34", + "title": "Производство малярных и стекольных работ" + }, + { + "code": "43.34.1", + "title": "Производство малярных и стекольных работ" + }, + { + "code": "43.39", + "title": "Производство прочих отделочных и завершающих работ" + }, + { + "code": "43.39.1", + "title": "Производство прочих отделочных и завершающих работ" + }, + { + "code": "43.91", + "title": "Производство кровельных работ" + }, + { + "code": "43.91.1", + "title": "Производство кровельных работ" + }, + { + "code": "43.99", + "title": "Производство прочих специализированных строительных работ, не включенных в другие группировки" + }, + { + "code": "43.99.1", + "title": "Производство прочих специализированных строительных работ" + }, + { + "code": "45.11", + "title": "Торговля легковыми автомобилями и легкими автотранспортными средствами" + }, + { + "code": "45.11.1", + "title": "Торговля легковыми автомобилями и легкими автотранспортными средствами" + }, + { + "code": "45.19", + "title": "Торговля прочими автотранспортными средствами" + }, + { + "code": "45.19.1", + "title": "Торговля грузовыми автомобилями" + }, + { + "code": "45.19.2", + "title": "Торговля автобусами и прочими автотранспортными средствами" + }, + { + "code": "45.20", + "title": "Техническое обслуживание и ремонт автотранспортных средств" + }, + { + "code": "45.20.1", + "title": "Техническое обслуживание и ремонт легковых автомобилей" + }, + { + "code": "45.20.2", + "title": "Техническое обслуживание и ремонт прочих автотранспортных средств" + }, + { + "code": "45.31", + "title": "Торговля оптом частями и принадлежностями автотранспортных средств" + }, + { + "code": "45.31.1", + "title": "Торговля оптом частями и принадлежностями автотранспортных средств" + }, + { + "code": "45.32", + "title": "Торговля в розницу частями и принадлежностями автотранспортных средств" + }, + { + "code": "45.32.1", + "title": "Торговля в розницу частями и принадлежностями автотранспортных средств" + }, + { + "code": "45.40", + "title": "Торговля мотоциклами, их частями, принадлежностями и техническое обслуживание" + }, + { + "code": "45.40.1", + "title": "Торговля мотоциклами и их частями" + }, + { + "code": "45.40.2", + "title": "Техническое обслуживание и ремонт мотоциклов" + }, + { + "code": "46.11", + "title": "Деятельность агентов по оптовой торговле сельскохозяйственным сырьем, живыми животными, текстильным сырьем и полуфабрикатами" + }, + { + "code": "46.12", + "title": "Деятельность агентов по оптовой торговле топливом, рудами, металлами и химическими веществами" + }, + { + "code": "46.13", + "title": "Деятельность агентов по оптовой торговле лесоматериалами и строительными материалами" + }, + { + "code": "46.14", + "title": "Деятельность агентов по оптовой торговле машинами, промышленным оборудованием, судами и летательными аппаратами" + }, + { + "code": "46.15", + "title": "Деятельность агентов по оптовой торговле мебелью, бытовыми товарами, скобяными изделиями" + }, + { + "code": "46.16", + "title": "Деятельность агентов по оптовой торговле текстилем, одеждой, обувью и изделиями из кожи" + }, + { + "code": "46.17", + "title": "Деятельность агентов по оптовой торговле пищевыми продуктами, включая напитки, и табачными изделиями" + }, + { + "code": "46.18", + "title": "Деятельность агентов, специализирующихся на оптовой торговле отдельными видами товаров или группами товаров, не включенными в другие группировки" + }, + { + "code": "46.19", + "title": "Деятельность агентов по оптовой торговле товарами широкого ассортимента" + }, + { + "code": "46.19.1", + "title": "Деятельность агентов по оптовой торговле товарами широкого ассортимента" + }, + { + "code": "46.21", + "title": "Торговля оптом зерном, необработанным табаком, семенами и кормами для животных" + }, + { + "code": "46.21.1", + "title": "Торговля оптом зерном, семенами и кормами для животных" + }, + { + "code": "46.21.2", + "title": "Торговля оптом необработанным табаком" + }, + { + "code": "46.22", + "title": "Торговля оптом цветами и растениями" + }, + { + "code": "46.22.1", + "title": "Торговля оптом цветами и растениями" + }, + { + "code": "46.23", + "title": "Торговля оптом живыми животными" + }, + { + "code": "46.23.1", + "title": "Торговля оптом живыми животными" + }, + { + "code": "46.24", + "title": "Торговля оптом кожей и кожевенным сырьем" + }, + { + "code": "46.24.1", + "title": "Торговля оптом кожей и кожевенным сырьем" + }, + { + "code": "46.31", + "title": "Торговля оптом фруктами и овощами" + }, + { + "code": "46.31.1", + "title": "Торговля оптом фруктами и овощами" + }, + { + "code": "46.32", + "title": "Торговля оптом мясом и мясопродуктами" + }, + { + "code": "46.32.1", + "title": "Торговля оптом мясом и мясопродуктами" + }, + { + "code": "46.33", + "title": "Торговля оптом молочными продуктами, яйцами, пищевыми маслами и жирами" + }, + { + "code": "46.33.1", + "title": "Торговля оптом молочными продуктами, яйцами, пищевыми маслами и жирами" + }, + { + "code": "46.34", + "title": "Торговля оптом алкогольными и другими напитками" + }, + { + "code": "46.34.1", + "title": "Торговля оптом алкогольными напитками" + }, + { + "code": "46.34.2", + "title": "Торговля оптом безалкогольными напитками" + }, + { + "code": "46.35", + "title": "Торговля оптом табачными изделиями" + }, + { + "code": "46.35.1", + "title": "Торговля оптом табачными изделиями" + }, + { + "code": "46.36", + "title": "Торговля оптом сахаром, шоколадом и сахаристыми кондитерскими изделиями" + }, + { + "code": "46.36.1", + "title": "Торговля оптом сахаром, шоколадом и сахаристыми кондитерскими изделиями" + }, + { + "code": "46.37", + "title": "Торговля оптом кофе, чаем, какао и пряностями" + }, + { + "code": "46.37.1", + "title": "Торговля оптом кофе, чаем, какао и пряностями" + }, + { + "code": "46.38", + "title": "Торговля оптом прочими пищевыми продуктами, включая рыбу, ракообразных и моллюсков" + }, + { + "code": "46.38.1", + "title": "Торговля оптом рыбой, ракообразными и моллюсками" + }, + { + "code": "46.38.2", + "title": "Торговля оптом прочими пищевыми продуктами" + }, + { + "code": "46.39", + "title": "Торговля оптом пищевыми продуктами, включая напитки, и табачными изделиями, не имеющая ярко выраженной специализации" + }, + { + "code": "46.39.1", + "title": "Торговля оптом пищевыми продуктами, включая напитки, и табачными изделиями, не имеющая ярко выраженной специализации" + }, + { + "code": "46.41", + "title": "Торговля оптом текстилем" + }, + { + "code": "46.41.1", + "title": "Торговля оптом текстилем" + }, + { + "code": "46.42", + "title": "Торговля оптом одеждой и обувью" + }, + { + "code": "46.42.1", + "title": "Торговля оптом одеждой" + }, + { + "code": "46.42.2", + "title": "Торговля оптом обувью" + }, + { + "code": "46.43", + "title": "Торговля оптом бытовыми электротехническими товарами" + }, + { + "code": "46.43.1", + "title": "Торговля оптом бытовыми электротехническими товарами" + }, + { + "code": "46.44", + "title": "Торговля оптом изделиями из керамики и стекла и чистящими средствами" + }, + { + "code": "46.44.1", + "title": "Торговля оптом изделиями из керамики и стекла и чистящими средствами" + }, + { + "code": "46.45", + "title": "Торговля оптом парфюмерными и косметическими товарами" + }, + { + "code": "46.45.1", + "title": "Торговля оптом парфюмерными и косметическими товарами" + }, + { + "code": "46.46", + "title": "Торговля оптом фармацевтическими товарами" + }, + { + "code": "46.46.1", + "title": "Торговля оптом фармацевтическими товарами" + }, + { + "code": "46.47", + "title": "Торговля оптом мебелью, коврами и осветительным оборудованием" + }, + { + "code": "46.47.1", + "title": "Торговля оптом мебелью, коврами и осветительным оборудованием" + }, + { + "code": "46.48", + "title": "Торговля оптом часами и ювелирными изделиями" + }, + { + "code": "46.48.1", + "title": "Торговля оптом часами и ювелирными изделиями" + }, + { + "code": "46.49", + "title": "Торговля оптом прочими потребительскими товарами" + }, + { + "code": "46.49.1", + "title": "Торговля оптом прочими потребительскими товарами" + }, + { + "code": "46.51", + "title": "Торговля оптом компьютерами, периферийными устройствами и программным обеспечением" + }, + { + "code": "46.51.1", + "title": "Торговля оптом компьютерами, периферийными устройствами и программным обеспечением" + }, + { + "code": "46.52", + "title": "Торговля оптом электронными и телекоммуникационными деталями и оборудованием" + }, + { + "code": "46.52.1", + "title": "Торговля оптом электронными и телекоммуникационными деталями и оборудованием" + }, + { + "code": "46.61", + "title": "Торговля оптом сельскохозяйственными машинами, оборудованием и принадлежностями" + }, + { + "code": "46.61.1", + "title": "Торговля оптом сельскохозяйственными машинами, оборудованием и принадлежностями" + }, + { + "code": "46.62", + "title": "Торговля оптом станками" + }, + { + "code": "46.62.1", + "title": "Торговля оптом станками" + }, + { + "code": "46.63", + "title": "Торговля оптом машинами для добычи полезных ископаемых и строительства" + }, + { + "code": "46.63.1", + "title": "Торговля оптом машинами для добычи полезных ископаемых и строительства" + }, + { + "code": "46.64", + "title": "Торговля оптом машинами для текстильного, швейного и трикотажного производства" + }, + { + "code": "46.64.1", + "title": "Торговля оптом машинами для текстильного, швейного и трикотажного производства" + }, + { + "code": "46.65", + "title": "Торговля оптом офисной техникой и оборудованием" + }, + { + "code": "46.65.1", + "title": "Торговля оптом офисной техникой и оборудованием" + }, + { + "code": "46.66", + "title": "Торговля оптом прочими машинами и оборудованием" + }, + { + "code": "46.66.1", + "title": "Торговля оптом прочими машинами и оборудованием" + }, + { + "code": "46.69", + "title": "Торговля оптом машинами и оборудованием общего назначения" + }, + { + "code": "46.69.1", + "title": "Торговля оптом машинами и оборудованием общего назначения" + }, + { + "code": "46.71", + "title": "Торговля оптом твердым, жидким и газообразным топливом и смежными продуктами" + }, + { + "code": "46.71.1", + "title": "Торговля оптом твердым, жидким и газообразным топливом и смежными продуктами" + }, + { + "code": "46.72", + "title": "Торговля оптом металлами и металлическими рудами" + }, + { + "code": "46.72.1", + "title": "Торговля оптом металлами и металлическими рудами" + }, + { + "code": "46.73", + "title": "Торговля оптом лесоматериалами, строительными материалами и санитарно-техническим оборудованием" + }, + { + "code": "46.73.1", + "title": "Торговля оптом лесоматериалами, строительными материалами и санитарно-техническим оборудованием" + }, + { + "code": "46.74", + "title": "Торговля оптом скобяными изделиями, водопроводным и отопительным оборудованием и принадлежностями" + }, + { + "code": "46.74.1", + "title": "Торговля оптом скобяными изделиями, водопроводным и отопительным оборудованием и принадлежностями" + }, + { + "code": "46.75", + "title": "Торговля оптом химическими продуктами" + }, + { + "code": "46.75.1", + "title": "Торговля оптом химическими продуктами" + }, + { + "code": "46.76", + "title": "Торговля оптом прочими промежуточными продуктами" + }, + { + "code": "46.76.1", + "title": "Торговля оптом прочими промежуточными продуктами" + }, + { + "code": "46.77", + "title": "Торговля оптом отходами и ломом" + }, + { + "code": "46.77.1", + "title": "Торговля оптом отходами и ломом" + }, + { + "code": "46.90", + "title": "Торговля оптом товарами широкого ассортимента" + }, + { + "code": "46.90.1", + "title": "Торговля оптом товарами широкого ассортимента" + }, + { + "code": "47.11", + "title": "Торговля розничная в неспециализированных магазинах преимущественно пищевыми продуктами, включая напитки, и табачными изделиями" + }, + { + "code": "47.11.1", + "title": "Торговля розничная в неспециализированных магазинах преимущественно пищевыми продуктами, включая напитки, и табачными изделиями" + }, + { + "code": "47.19", + "title": "Торговля розничная в прочих неспециализированных магазинах" + }, + { + "code": "47.19.1", + "title": "Торговля розничная в прочих неспециализированных магазинах" + }, + { + "code": "47.21", + "title": "Торговля розничная фруктами и овощами в специализированных магазинах" + }, + { + "code": "47.21.1", + "title": "Торговля розничная фруктами и овощами в специализированных магазинах" + }, + { + "code": "47.22", + "title": "Торговля розничная мясом и мясными продуктами в специализированных магазинах" + }, + { + "code": "47.22.1", + "title": "Торговля розничная мясом и мясными продуктами в специализированных магазинах" + }, + { + "code": "47.23", + "title": "Торговля розничная рыбой, ракообразными и моллюсками в специализированных магазинах" + }, + { + "code": "47.23.1", + "title": "Торговля розничная рыбой, ракообразными и моллюсками в специализированных магазинах" + }, + { + "code": "47.24", + "title": "Торговля розничная хлебом, мучными кондитерскими изделиями, тортами и пирожными в специализированных магазинах" + }, + { + "code": "47.24.1", + "title": "Торговля розничная хлебом, мучными кондитерскими изделиями, тортами и пирожными в специализированных магазинах" + }, + { + "code": "47.25", + "title": "Торговля розничная алкогольными и другими напитками в специализированных магазинах" + }, + { + "code": "47.25.1", + "title": "Торговля розничная алкогольными напитками в специализированных магазинах" + }, + { + "code": "47.25.2", + "title": "Торговля розничная безалкогольными напитками в специализированных магазинах" + }, + { + "code": "47.26", + "title": "Торговля розничная табачными изделиями в специализированных магазинах" + }, + { + "code": "47.26.1", + "title": "Торговля розничная табачными изделиями в специализированных магазинах" + }, + { + "code": "47.29", + "title": "Торговля розничная прочими пищевыми продуктами в специализированных магазинах" + }, + { + "code": "47.29.1", + "title": "Торговля розничная прочими пищевыми продуктами в специализированных магазинах" + }, + { + "code": "47.30", + "title": "Торговля розничная автомобильным топливом в специализированных магазинах" + }, + { + "code": "47.30.1", + "title": "Торговля розничная автомобильным топливом в специализированных магазинах" + }, + { + "code": "47.41", + "title": "Торговля розничная компьютерами, периферийными устройствами и программным обеспечением в специализированных магазинах" + }, + { + "code": "47.42", + "title": "Торговля розничная телекоммуникационным оборудованием в специализированных магазинах" + }, + { + "code": "47.43", + "title": "Торговля розничная аудио- и видеоаппаратурой в специализированных магазинах" + }, + { + "code": "47.51", + "title": "Торговля розничная текстильными изделиями в специализированных магазинах" + }, + { + "code": "47.52", + "title": "Торговля розничная скобяными изделиями, красками и стеклом в специализированных магазинах" + }, + { + "code": "47.53", + "title": "Торговля розничная коврами, ковровыми покрытиями, обоями и напольными покрытиями в специализированных магазинах" + }, + { + "code": "47.54", + "title": "Торговля розничная бытовыми электротоварами в специализированных магазинах" + }, + { + "code": "47.59", + "title": "Торговля розничная мебелью, осветительным оборудованием и прочими бытовыми изделиями в специализированных магазинах" + }, + { + "code": "47.61", + "title": "Торговля розничная книгами в специализированных магазинах" + }, + { + "code": "47.62", + "title": "Торговля розничная газетами и канцелярскими товарами в специализированных магазинах" + }, + { + "code": "47.63", + "title": "Торговля розничная музыкальными и видеозаписями в специализированных магазинах" + }, + { + "code": "47.64", + "title": "Торговля розничная спортивными товарами, рыболовными принадлежностями, туристским снаряжением, лодками и велосипедами в специализированных магазинах" + }, + { + "code": "47.65", + "title": "Торговля розничная играми и игрушками в специализированных магазинах" + }, + { + "code": "47.71", + "title": "Торговля розничная одеждой в специализированных магазинах" + }, + { + "code": "47.72", + "title": "Торговля розничная обувью и изделиями из кожи в специализированных магазинах" + }, + { + "code": "47.73", + "title": "Торговля розничная лекарственными средствами в специализированных магазинах (аптеках)" + }, + { + "code": "47.74", + "title": "Торговля розничная медицинскими и ортопедическими товарами в специализированных магазинах" + }, + { + "code": "47.75", + "title": "Торговля розничная косметическими и парфюмерными товарами в специализированных магазинах" + }, + { + "code": "47.76", + "title": "Торговля розничная цветами, растениями, семенами, удобрениями, домашними животными и кормами для домашних животных в специализированных магазинах" + }, + { + "code": "47.77", + "title": "Торговля розничная часами и ювелирными изделиями в специализированных магазинах" + }, + { + "code": "47.78", + "title": "Торговля розничная прочими новыми товарами в специализированных магазинах" + }, + { + "code": "47.79", + "title": "Торговля розничная бывшими в употреблении товарами в специализированных магазинах" + }, + { + "code": "47.81", + "title": "Торговля розничная пищевыми продуктами, включая напитки, и табачными изделиями в палатках и на рынках" + }, + { + "code": "47.82", + "title": "Торговля розничная текстильными изделиями, одеждой и обувью в палатках и на рынках" + }, + { + "code": "47.89", + "title": "Торговля розничная прочими товарами в палатках и на рынках" + }, + { + "code": "47.91", + "title": "Торговля розничная по почте или по информационно-коммуникационной сети Интернет" + }, + { + "code": "47.99", + "title": "Торговля розничная вне магазинов, палаток, рынков" + }, + { + "code": "49.10", + "title": "Деятельность железнодорожного транспорта: междугородные пассажирские перевозки" + }, + { + "code": "49.10.1", + "title": "Деятельность железнодорожного транспорта: междугородные пассажирские перевозки" + }, + { + "code": "49.20", + "title": "Деятельность железнодорожного транспорта: грузовые перевозки" + }, + { + "code": "49.20.1", + "title": "Деятельность железнодорожного транспорта: грузовые перевозки" + }, + { + "code": "49.31", + "title": "Деятельность городского и пригородного пассажирского наземного транспорта" + }, + { + "code": "49.31.1", + "title": "Деятельность городского и пригородного пассажирского наземного транспорта" + }, + { + "code": "49.32", + "title": "Деятельность легкового такси" + }, + { + "code": "49.32.1", + "title": "Деятельность легкового такси" + }, + { + "code": "49.39", + "title": "Деятельность прочего пассажирского наземного транспорта" + }, + { + "code": "49.39.1", + "title": "Деятельность прочего пассажирского наземного транспорта" + }, + { + "code": "49.41", + "title": "Деятельность грузового автомобильного транспорта" + }, + { + "code": "49.41.1", + "title": "Деятельность грузового автомобильного транспорта" + }, + { + "code": "49.42", + "title": "Предоставление услуг по перевозкам" + }, + { + "code": "49.42.1", + "title": "Предоставление услуг по перевозкам" + }, + { + "code": "49.50", + "title": "Деятельность трубопроводного транспорта" + }, + { + "code": "49.50.1", + "title": "Деятельность трубопроводного транспорта" + }, + { + "code": "50.10", + "title": "Деятельность морского и прибрежного пассажирского водного транспорта" + }, + { + "code": "50.10.1", + "title": "Деятельность морского и прибрежного пассажирского водного транспорта" + }, + { + "code": "50.20", + "title": "Деятельность морского и прибрежного грузового водного транспорта" + }, + { + "code": "50.20.1", + "title": "Деятельность морского и прибрежного грузового водного транспорта" + }, + { + "code": "50.30", + "title": "Деятельность внутреннего водного пассажирского транспорта" + }, + { + "code": "50.30.1", + "title": "Деятельность внутреннего водного пассажирского транспорта" + }, + { + "code": "50.40", + "title": "Деятельность внутреннего водного грузового транспорта" + }, + { + "code": "50.40.1", + "title": "Деятельность внутреннего водного грузового транспорта" + }, + { + "code": "51.10", + "title": "Деятельность пассажирского воздушного транспорта" + }, + { + "code": "51.10.1", + "title": "Деятельность пассажирского воздушного транспорта" + }, + { + "code": "51.21", + "title": "Деятельность грузового воздушного транспорта" + }, + { + "code": "51.21.1", + "title": "Деятельность грузового воздушного транспорта" + }, + { + "code": "51.22", + "title": "Деятельность космического транспорта" + }, + { + "code": "51.22.1", + "title": "Деятельность космического транспорта" + }, + { + "code": "52.10", + "title": "Деятельность по складированию и хранению" + }, + { + "code": "52.10.1", + "title": "Деятельность по складированию и хранению" + }, + { + "code": "52.21", + "title": "Деятельность сухопутного транспорта вспомогательная" + }, + { + "code": "52.21.1", + "title": "Деятельность сухопутного транспорта вспомогательная" + }, + { + "code": "52.22", + "title": "Деятельность водного транспорта вспомогательная" + }, + { + "code": "52.22.1", + "title": "Деятельность водного транспорта вспомогательная" + }, + { + "code": "52.23", + "title": "Деятельность воздушного транспорта вспомогательная" + }, + { + "code": "52.23.1", + "title": "Деятельность воздушного транспорта вспомогательная" + }, + { + "code": "52.24", + "title": "Транспортная обработка грузов" + }, + { + "code": "52.24.1", + "title": "Транспортная обработка грузов" + }, + { + "code": "52.29", + "title": "Деятельность транспортная прочая вспомогательная" + }, + { + "code": "52.29.1", + "title": "Деятельность транспортная прочая вспомогательная" + }, + { + "code": "53.10", + "title": "Деятельность почтовой связи общего пользования" + }, + { + "code": "53.10.1", + "title": "Деятельность почтовой связи общего пользования" + }, + { + "code": "53.20", + "title": "Деятельность курьерская" + }, + { + "code": "53.20.1", + "title": "Деятельность курьерская" + }, + { + "code": "55.10", + "title": "Деятельность гостиниц и прочих мест для временного проживания" + }, + { + "code": "55.10.1", + "title": "Деятельность гостиниц и прочих мест для временного проживания" + }, + { + "code": "55.20", + "title": "Деятельность по предоставлению мест для краткосрочного проживания" + }, + { + "code": "55.20.1", + "title": "Деятельность по предоставлению мест для краткосрочного проживания" + }, + { + "code": "55.30", + "title": "Деятельность площадок для кемпинга и стоянок для автодач и прицепов" + }, + { + "code": "55.30.1", + "title": "Деятельность площадок для кемпинга и стоянок для автодач и прицепов" + }, + { + "code": "55.90", + "title": "Деятельность по предоставлению прочих мест для временного проживания" + }, + { + "code": "55.90.1", + "title": "Деятельность по предоставлению прочих мест для временного проживания" + }, + { + "code": "56.10", + "title": "Деятельность ресторанов и услуги по доставке продуктов питания" + }, + { + "code": "56.10.1", + "title": "Деятельность ресторанов и услуги по доставке продуктов питания" + }, + { + "code": "56.21", + "title": "Поставка продуктов питания для спортивных мероприятий или других аналогичных мероприятий" + }, + { + "code": "56.21.1", + "title": "Поставка продуктов питания для спортивных мероприятий или других аналогичных мероприятий" + }, + { + "code": "56.29", + "title": "Деятельность предприятий общественного питания по прочим видам организации питания" + }, + { + "code": "56.29.1", + "title": "Деятельность предприятий общественного питания по прочим видам организации питания" + }, + { + "code": "56.30", + "title": "Подача напитков" + }, + { + "code": "56.30.1", + "title": "Подача напитков" + }, + { + "code": "58.11", + "title": "Издание книг" + }, + { + "code": "58.11.1", + "title": "Издание книг" + }, + { + "code": "58.12", + "title": "Издание справочников и каталогов" + }, + { + "code": "58.12.1", + "title": "Издание справочников и каталогов" + }, + { + "code": "58.13", + "title": "Издание газет" + }, + { + "code": "58.13.1", + "title": "Издание газет" + }, + { + "code": "58.14", + "title": "Издание журналов и периодических изданий" + }, + { + "code": "58.14.1", + "title": "Издание журналов и периодических изданий" + }, + { + "code": "58.19", + "title": "Виды издательской деятельности прочие" + }, + { + "code": "58.19.1", + "title": "Виды издательской деятельности прочие" + }, + { + "code": "58.21", + "title": "Издание компьютерных игр" + }, + { + "code": "58.21.1", + "title": "Издание компьютерных игр" + }, + { + "code": "58.29", + "title": "Издание прочего программного обеспечения" + }, + { + "code": "58.29.1", + "title": "Издание прочего программного обеспечения" + }, + { + "code": "59.11", + "title": "Производство кинофильмов, видеофильмов и телевизионных программ" + }, + { + "code": "59.11.1", + "title": "Производство кинофильмов, видеофильмов и телевизионных программ" + }, + { + "code": "59.12", + "title": "Деятельность в области постпроизводства фильмов, видеофильмов и телевизионных программ" + }, + { + "code": "59.12.1", + "title": "Деятельность в области постпроизводства фильмов, видеофильмов и телевизионных программ" + }, + { + "code": "59.13", + "title": "Деятельность в области дистрибуции кинофильмов, видеофильмов и телевизионных программ" + }, + { + "code": "59.13.1", + "title": "Деятельность в области дистрибуции кинофильмов, видеофильмов и телевизионных программ" + }, + { + "code": "59.14", + "title": "Деятельность в области демонстрации кинофильмов" + }, + { + "code": "59.14.1", + "title": "Деятельность в области демонстрации кинофильмов" + }, + { + "code": "59.20", + "title": "Деятельность в области звукозаписи и издания музыкальных произведений" + }, + { + "code": "59.20.1", + "title": "Деятельность в области звукозаписи и издания музыкальных произведений" + }, + { + "code": "60.10", + "title": "Деятельность в области радиовещания" + }, + { + "code": "60.10.1", + "title": "Деятельность в области радиовещания" + }, + { + "code": "60.20", + "title": "Деятельность в области телевизионного вещания" + }, + { + "code": "60.20.1", + "title": "Деятельность в области телевизионного вещания" + }, + { + "code": "61.10", + "title": "Деятельность в области проводной связи" + }, + { + "code": "61.10.1", + "title": "Деятельность в области проводной связи" + }, + { + "code": "61.20", + "title": "Деятельность в области беспроводной связи, кроме спутниковой" + }, + { + "code": "61.20.1", + "title": "Деятельность в области беспроводной связи, кроме спутниковой" + }, + { + "code": "61.30", + "title": "Деятельность в области спутниковой связи" + }, + { + "code": "61.30.1", + "title": "Деятельность в области спутниковой связи" + }, + { + "code": "61.90", + "title": "Деятельность в области телекоммуникаций прочая" + }, + { + "code": "61.90.1", + "title": "Деятельность в области телекоммуникаций прочая" + }, + { + "code": "62.01", + "title": "Разработка компьютерного программного обеспечения" + }, + { + "code": "62.01.1", + "title": "Разработка компьютерного программного обеспечения" + }, + { + "code": "62.02", + "title": "Деятельность консультативная и работы в области компьютерных технологий" + }, + { + "code": "62.02.1", + "title": "Деятельность консультативная и работы в области компьютерных технологий" + }, + { + "code": "62.03", + "title": "Деятельность по управлению компьютерным оборудованием" + }, + { + "code": "62.03.1", + "title": "Деятельность по управлению компьютерным оборудованием" + }, + { + "code": "62.09", + "title": "Деятельность, связанная с использованием вычислительной техники и информационных технологий, прочая" + }, + { + "code": "62.09.1", + "title": "Деятельность, связанная с использованием вычислительной техники и информационных технологий, прочая" + }, + { + "code": "63.11", + "title": "Деятельность по обработке данных, предоставление услуг по размещению информации и связанная с этим деятельность" + }, + { + "code": "63.11.1", + "title": "Деятельность по обработке данных, предоставление услуг по размещению информации и связанная с этим деятельность" + }, + { + "code": "63.12", + "title": "Деятельность веб-порталов" + }, + { + "code": "63.12.1", + "title": "Деятельность веб-порталов" + }, + { + "code": "63.91", + "title": "Деятельность информационных агентств" + }, + { + "code": "63.91.1", + "title": "Деятельность информационных агентств" + }, + { + "code": "63.99", + "title": "Деятельность в области информационных услуг прочая, не включенная в другие группировки" + }, + { + "code": "63.99.1", + "title": "Деятельность в области информационных услуг прочая, не включенная в другие группировки" + }, + { + "code": "64.11", + "title": "Деятельность центрального банка" + }, + { + "code": "64.11.1", + "title": "Деятельность центрального банка" + }, + { + "code": "64.19", + "title": "Деятельность банков, кроме центрального банка" + }, + { + "code": "64.19.1", + "title": "Деятельность коммерческих банков" + }, + { + "code": "64.19.2", + "title": "Деятельность сберегательных банков" + }, + { + "code": "64.19.3", + "title": "Деятельность кредитных союзов" + }, + { + "code": "64.20", + "title": "Деятельность холдинговых компаний" + }, + { + "code": "64.20.1", + "title": "Деятельность холдинговых компаний" + }, + { + "code": "64.30", + "title": "Деятельность по учреждению трастов, фондов и аналогичных финансовых учреждений" + }, + { + "code": "64.30.1", + "title": "Деятельность по учреждению трастов, фондов и аналогичных финансовых учреждений" + }, + { + "code": "64.91", + "title": "Аренда финансовая" + }, + { + "code": "64.91.1", + "title": "Аренда финансовая" + }, + { + "code": "64.92", + "title": "Деятельность по предоставлению прочих кредитов" + }, + { + "code": "64.92.1", + "title": "Деятельность ломбардов" + }, + { + "code": "64.92.2", + "title": "Деятельность кредитных кооперативов" + }, + { + "code": "64.92.3", + "title": "Деятельность микрофинансовых организаций" + }, + { + "code": "64.99", + "title": "Деятельность по предоставлению прочих финансовых услуг, кроме услуг по страхованию и пенсионному обеспечению, не включенная в другие группировки" + }, + { + "code": "64.99.1", + "title": "Деятельность по предоставлению прочих финансовых услуг, кроме услуг по страхованию и пенсионному обеспечению, не включенная в другие группировки" + }, + { + "code": "65.11", + "title": "Страхование жизни" + }, + { + "code": "65.11.1", + "title": "Страхование жизни" + }, + { + "code": "65.12", + "title": "Страхование иное, чем страхование жизни" + }, + { + "code": "65.12.1", + "title": "Добровольное медицинское страхование" + }, + { + "code": "65.12.2", + "title": "Страхование от несчастных случаев и болезней" + }, + { + "code": "65.12.3", + "title": "Страхование средств наземного транспорта" + }, + { + "code": "65.12.4", + "title": "Страхование средств воздушного транспорта" + }, + { + "code": "65.12.5", + "title": "Страхование средств водного транспорта" + }, + { + "code": "65.12.6", + "title": "Страхование грузов" + }, + { + "code": "65.12.7", + "title": "Страхование имущества" + }, + { + "code": "65.12.8", + "title": "Страхование гражданской ответственности" + }, + { + "code": "65.20", + "title": "Перестрахование" + }, + { + "code": "65.20.1", + "title": "Перестрахование" + }, + { + "code": "65.30", + "title": "Деятельность по негосударственному пенсионному обеспечению" + }, + { + "code": "65.30.1", + "title": "Деятельность по негосударственному пенсионному обеспечению" + }, + { + "code": "66.11", + "title": "Деятельность по управлению финансовыми рынками" + }, + { + "code": "66.11.1", + "title": "Деятельность по управлению финансовыми рынками" + }, + { + "code": "66.12", + "title": "Деятельность по торговле ценными бумагами" + }, + { + "code": "66.12.1", + "title": "Деятельность по торговле ценными бумагами" + }, + { + "code": "66.19", + "title": "Деятельность вспомогательная в сфере финансовых услуг, кроме страхования и пенсионного обеспечения, прочая" + }, + { + "code": "66.19.1", + "title": "Деятельность вспомогательная в сфере финансовых услуг, кроме страхования и пенсионного обеспечения, прочая" + }, + { + "code": "66.21", + "title": "Оценка рисков и возмещение ущерба" + }, + { + "code": "66.21.1", + "title": "Оценка рисков и возмещение ущерба" + }, + { + "code": "66.22", + "title": "Деятельность страховых агентов и брокеров" + }, + { + "code": "66.22.1", + "title": "Деятельность страховых агентов и брокеров" + }, + { + "code": "66.29", + "title": "Деятельность вспомогательная в сфере страхования и пенсионного обеспечения прочая" + }, + { + "code": "66.29.1", + "title": "Деятельность вспомогательная в сфере страхования и пенсионного обеспечения прочая" + }, + { + "code": "66.30", + "title": "Деятельность по управлению фондами" + }, + { + "code": "66.30.1", + "title": "Деятельность по управлению фондами" + }, + { + "code": "68.10", + "title": "Покупка и продажа собственного недвижимого имущества" + }, + { + "code": "68.10.1", + "title": "Покупка и продажа собственного недвижимого имущества" + }, + { + "code": "68.20", + "title": "Аренда и управление собственным или арендованным недвижимым имуществом" + }, + { + "code": "68.20.1", + "title": "Аренда жилого недвижимого имущества" + }, + { + "code": "68.20.2", + "title": "Аренда нежилого недвижимого имущества" + }, + { + "code": "68.31", + "title": "Деятельность агентств недвижимости за вознаграждение или на договорной основе" + }, + { + "code": "68.31.1", + "title": "Деятельность агентств недвижимости за вознаграждение или на договорной основе" + }, + { + "code": "68.32", + "title": "Управление недвижимым имуществом за вознаграждение или на договорной основе" + }, + { + "code": "68.32.1", + "title": "Управление недвижимым имуществом за вознаграждение или на договорной основе" + }, + { + "code": "69.10", + "title": "Деятельность в области права" + }, + { + "code": "69.10.1", + "title": "Деятельность в области права" + }, + { + "code": "69.20", + "title": "Деятельность по оказанию услуг в области бухгалтерского учета" + }, + { + "code": "69.20.1", + "title": "Деятельность по ведению бухгалтерского учета" + }, + { + "code": "69.20.2", + "title": "Деятельность по проведению аудита" + }, + { + "code": "69.20.3", + "title": "Деятельность по оказанию консультационных услуг по налогообложению" + }, + { + "code": "70.10", + "title": "Деятельность головных офисов" + }, + { + "code": "70.10.1", + "title": "Деятельность головных офисов" + }, + { + "code": "70.21", + "title": "Деятельность в области связей с общественностью" + }, + { + "code": "70.21.1", + "title": "Деятельность в области связей с общественностью" + }, + { + "code": "70.22", + "title": "Консультирование по вопросам коммерческой деятельности и управления" + }, + { + "code": "70.22.1", + "title": "Консультирование по вопросам коммерческой деятельности и управления" + }, + { + "code": "71.11", + "title": "Деятельность в области архитектуры" + }, + { + "code": "71.11.1", + "title": "Деятельность в области архитектуры" + }, + { + "code": "71.12", + "title": "Деятельность в области инженерных изысканий, инженерно-технического проектирования в промышленности и строительстве, геодезии и картографии" + }, + { + "code": "71.12.1", + "title": "Деятельность в области инженерных изысканий" + }, + { + "code": "71.12.2", + "title": "Деятельность в области инженерно-технического проектирования" + }, + { + "code": "71.12.3", + "title": "Деятельность в области геодезии и картографии" + }, + { + "code": "71.20", + "title": "Технические испытания, исследования, анализ и сертификация" + }, + { + "code": "71.20.1", + "title": "Деятельность по техническому контролю, испытаниям и анализу" + }, + { + "code": "71.20.2", + "title": "Деятельность по сертификации" + }, + { + "code": "72.11", + "title": "Исследования и разработки в области биотехнологии" + }, + { + "code": "72.11.1", + "title": "Исследования и разработки в области биотехнологии" + }, + { + "code": "72.19", + "title": "Научные исследования и разработки в области естественных и технических наук прочие" + }, + { + "code": "72.19.1", + "title": "Научные исследования и разработки в области естественных и технических наук прочие" + }, + { + "code": "72.20", + "title": "Научные исследования и разработки в области общественных и гуманитарных наук" + }, + { + "code": "72.20.1", + "title": "Научные исследования и разработки в области общественных и гуманитарных наук" + }, + { + "code": "73.11", + "title": "Деятельность рекламных агентств" + }, + { + "code": "73.11.1", + "title": "Деятельность рекламных агентств" + }, + { + "code": "73.12", + "title": "Деятельность по размещению рекламы в средствах массовой информации" + }, + { + "code": "73.12.1", + "title": "Деятельность по размещению рекламы в средствах массовой информации" + }, + { + "code": "73.20", + "title": "Исследование конъюнктуры рынка и выявление общественного мнения" + }, + { + "code": "73.20.1", + "title": "Исследование конъюнктуры рынка и выявление общественного мнения" + }, + { + "code": "74.10", + "title": "Деятельность специализированная в области дизайна" + }, + { + "code": "74.10.1", + "title": "Деятельность специализированная в области дизайна" + }, + { + "code": "74.20", + "title": "Деятельность в области фотографии" + }, + { + "code": "74.20.1", + "title": "Деятельность в области фотографии" + }, + { + "code": "74.30", + "title": "Деятельность по письменному и устному переводу" + }, + { + "code": "74.30.1", + "title": "Деятельность по письменному и устному переводу" + }, + { + "code": "74.90", + "title": "Деятельность профессиональная, научная и техническая прочая" + }, + { + "code": "74.90.1", + "title": "Деятельность профессиональная, научная и техническая прочая" + }, + { + "code": "75.00", + "title": "Деятельность ветеринарная" + }, + { + "code": "75.00.1", + "title": "Деятельность ветеринарная" + }, + { + "code": "77.11", + "title": "Аренда и лизинг легковых автомобилей и легких автотранспортных средств" + }, + { + "code": "77.11.1", + "title": "Аренда и лизинг легковых автомобилей и легких автотранспортных средств" + }, + { + "code": "77.12", + "title": "Аренда и лизинг грузовых автотранспортных средств" + }, + { + "code": "77.12.1", + "title": "Аренда и лизинг грузовых автотранспортных средств" + }, + { + "code": "77.21", + "title": "Аренда и лизинг товаров для отдыха и спорта" + }, + { + "code": "77.21.1", + "title": "Аренда и лизинг товаров для отдыха и спорта" + }, + { + "code": "77.22", + "title": "Аренда видеокассет и дисков" + }, + { + "code": "77.22.1", + "title": "Аренда видеокассет и дисков" + }, + { + "code": "77.29", + "title": "Аренда и лизинг прочих бытовых изделий и личных принадлежностей" + }, + { + "code": "77.29.1", + "title": "Аренда и лизинг прочих бытовых изделий и личных принадлежностей" + }, + { + "code": "77.31", + "title": "Аренда и лизинг сельскохозяйственных машин и оборудования" + }, + { + "code": "77.31.1", + "title": "Аренда и лизинг сельскохозяйственных машин и оборудования" + }, + { + "code": "77.32", + "title": "Аренда и лизинг строительных машин и оборудования" + }, + { + "code": "77.32.1", + "title": "Аренда и лизинг строительных машин и оборудования" + }, + { + "code": "77.33", + "title": "Аренда и лизинг офисных машин и оборудования (включая вычислительную технику)" + }, + { + "code": "77.33.1", + "title": "Аренда и лизинг офисных машин и оборудования (включая вычислительную технику)" + }, + { + "code": "77.34", + "title": "Аренда и лизинг водных транспортных средств" + }, + { + "code": "77.34.1", + "title": "Аренда и лизинг водных транспортных средств" + }, + { + "code": "77.35", + "title": "Аренда и лизинг воздушных транспортных средств" + }, + { + "code": "77.35.1", + "title": "Аренда и лизинг воздушных транспортных средств" + }, + { + "code": "77.39", + "title": "Аренда и лизинг прочих машин, оборудования и материальных средств" + }, + { + "code": "77.39.1", + "title": "Аренда и лизинг прочих машин, оборудования и материальных средств" + }, + { + "code": "77.40", + "title": "Лизинг интеллектуальной собственности и аналогичных продуктов, кроме авторских прав" + }, + { + "code": "77.40.1", + "title": "Лизинг интеллектуальной собственности и аналогичных продуктов, кроме авторских прав" + }, + { + "code": "78.10", + "title": "Деятельность агентств по подбору персонала" + }, + { + "code": "78.10.1", + "title": "Деятельность агентств по подбору персонала" + }, + { + "code": "78.20", + "title": "Деятельность агентств по трудоустройству" + }, + { + "code": "78.20.1", + "title": "Деятельность агентств по трудоустройству" + }, + { + "code": "78.30", + "title": "Деятельность агентств по предоставлению прочего персонала" + }, + { + "code": "78.30.1", + "title": "Деятельность агентств по предоставлению прочего персонала" + }, + { + "code": "79.11", + "title": "Деятельность туристических агентств" + }, + { + "code": "79.11.1", + "title": "Деятельность туристических агентств" + }, + { + "code": "79.12", + "title": "Деятельность туристических операторов" + }, + { + "code": "79.12.1", + "title": "Деятельность туристических операторов" + }, + { + "code": "79.90", + "title": "Предоставление прочих туристических услуг" + }, + { + "code": "79.90.1", + "title": "Предоставление прочих туристических услуг" + }, + { + "code": "80.10", + "title": "Деятельность частных охранных служб" + }, + { + "code": "80.10.1", + "title": "Деятельность частных охранных служб" + }, + { + "code": "80.20", + "title": "Деятельность служб безопасности систем" + }, + { + "code": "80.20.1", + "title": "Деятельность служб безопасности систем" + }, + { + "code": "80.30", + "title": "Деятельность по расследованиям" + }, + { + "code": "80.30.1", + "title": "Деятельность по расследованиям" + }, + { + "code": "81.10", + "title": "Деятельность по комплексному обслуживанию помещений" + }, + { + "code": "81.10.1", + "title": "Деятельность по комплексному обслуживанию помещений" + }, + { + "code": "81.21", + "title": "Деятельность по общей уборке зданий" + }, + { + "code": "81.21.1", + "title": "Деятельность по общей уборке зданий" + }, + { + "code": "81.22", + "title": "Деятельность по чистке и уборке прочая" + }, + { + "code": "81.22.1", + "title": "Деятельность по чистке и уборке прочая" + }, + { + "code": "81.29", + "title": "Деятельность по чистке и уборке помещений и территорий прочая" + }, + { + "code": "81.29.1", + "title": "Деятельность по чистке и уборке помещений и территорий прочая" + }, + { + "code": "81.30", + "title": "Деятельность по благоустройству ландшафта" + }, + { + "code": "81.30.1", + "title": "Деятельность по благоустройству ландшафта" + }, + { + "code": "82.11", + "title": "Предоставление комбинированных офисных административных услуг" + }, + { + "code": "82.11.1", + "title": "Предоставление комбинированных офисных административных услуг" + }, + { + "code": "82.19", + "title": "Деятельность по фотокопированию, подготовке документов и прочая специализированная вспомогательная деятельность по обеспечению деятельности офиса" + }, + { + "code": "82.19.1", + "title": "Деятельность по фотокопированию, подготовке документов и прочая специализированная вспомогательная деятельность по обеспечению деятельности офиса" + }, + { + "code": "82.20", + "title": "Деятельность центров телефонного обслуживания" + }, + { + "code": "82.20.1", + "title": "Деятельность центров телефонного обслуживания" + }, + { + "code": "82.30", + "title": "Деятельность по организации конференций и выставок" + }, + { + "code": "82.30.1", + "title": "Деятельность по организации конференций и выставок" + }, + { + "code": "82.91", + "title": "Деятельность агентств по взысканию задолженности и бюро кредитной информации" + }, + { + "code": "82.91.1", + "title": "Деятельность агентств по взысканию задолженности и бюро кредитной информации" + }, + { + "code": "82.92", + "title": "Деятельность по упаковке товаров" + }, + { + "code": "82.92.1", + "title": "Деятельность по упаковке товаров" + }, + { + "code": "82.99", + "title": "Деятельность по предоставлению прочих вспомогательных услуг для бизнеса, не включенная в другие группировки" + }, + { + "code": "82.99.1", + "title": "Деятельность по предоставлению прочих вспомогательных услуг для бизнеса, не включенная в другие группировки" + }, + { + "code": "84.11", + "title": "Деятельность органов государственного управления общего характера" + }, + { + "code": "84.11.1", + "title": "Деятельность органов государственного управления общего характера" + }, + { + "code": "84.12", + "title": "Деятельность органов государственного управления по регулированию в области здравоохранения, образования, культуры и прочих социальных услуг, кроме социального обеспечения" + }, + { + "code": "84.12.1", + "title": "Деятельность органов государственного управления по регулированию в области здравоохранения, образования, культуры и прочих социальных услуг, кроме социального обеспечения" + }, + { + "code": "84.13", + "title": "Деятельность органов государственного управления по регулированию в области экономики" + }, + { + "code": "84.13.1", + "title": "Деятельность органов государственного управления по регулированию в области экономики" + }, + { + "code": "84.21", + "title": "Деятельность в области иностранных дел" + }, + { + "code": "84.21.1", + "title": "Деятельность в области иностранных дел" + }, + { + "code": "84.22", + "title": "Деятельность в области обороны" + }, + { + "code": "84.22.1", + "title": "Деятельность в области обороны" + }, + { + "code": "84.23", + "title": "Деятельность в области юстиции и правосудия" + }, + { + "code": "84.23.1", + "title": "Деятельность в области юстиции и правосудия" + }, + { + "code": "84.24", + "title": "Деятельность в области общественного порядка и безопасности" + }, + { + "code": "84.24.1", + "title": "Деятельность в области общественного порядка и безопасности" + }, + { + "code": "84.25", + "title": "Деятельность по обеспечению безопасности в чрезвычайных ситуациях" + }, + { + "code": "84.25.1", + "title": "Деятельность по обеспечению безопасности в чрезвычайных ситуациях" + }, + { + "code": "84.30", + "title": "Деятельность в области обязательного социального обеспечения" + }, + { + "code": "84.30.1", + "title": "Деятельность в области обязательного социального обеспечения" + }, + { + "code": "85.11", + "title": "Образование дошкольное" + }, + { + "code": "85.11.1", + "title": "Образование дошкольное" + }, + { + "code": "85.12", + "title": "Образование начальное общее" + }, + { + "code": "85.12.1", + "title": "Образование начальное общее" + }, + { + "code": "85.13", + "title": "Образование основное общее" + }, + { + "code": "85.13.1", + "title": "Образование основное общее" + }, + { + "code": "85.14", + "title": "Образование среднее общее" + }, + { + "code": "85.14.1", + "title": "Образование среднее общее" + }, + { + "code": "85.21", + "title": "Образование профессиональное среднее" + }, + { + "code": "85.21.1", + "title": "Образование профессиональное среднее" + }, + { + "code": "85.22", + "title": "Образование высшее" + }, + { + "code": "85.22.1", + "title": "Образование высшее - бакалавриат" + }, + { + "code": "85.22.2", + "title": "Образование высшее - специалитет" + }, + { + "code": "85.22.3", + "title": "Образование высшее - магистратура" + }, + { + "code": "85.30", + "title": "Обучение профессиональное" + }, + { + "code": "85.30.1", + "title": "Обучение профессиональное" + }, + { + "code": "85.41", + "title": "Образование дополнительное детей и взрослых" + }, + { + "code": "85.41.1", + "title": "Образование дополнительное детей" + }, + { + "code": "85.41.2", + "title": "Образование дополнительное взрослых" + }, + { + "code": "85.42", + "title": "Образование профессиональное дополнительное" + }, + { + "code": "85.42.1", + "title": "Образование профессиональное дополнительное" + }, + { + "code": "85.50", + "title": "Деятельность вспомогательная в области образования" + }, + { + "code": "85.50.1", + "title": "Деятельность вспомогательная в области образования" + }, + { + "code": "86.10", + "title": "Деятельность больничных учреждений" + }, + { + "code": "86.10.1", + "title": "Деятельность больничных учреждений" + }, + { + "code": "86.21", + "title": "Общая врачебная практика" + }, + { + "code": "86.21.1", + "title": "Общая врачебная практика" + }, + { + "code": "86.22", + "title": "Специальная врачебная практика" + }, + { + "code": "86.22.1", + "title": "Специальная врачебная практика" + }, + { + "code": "86.23", + "title": "Стоматологическая практика" + }, + { + "code": "86.23.1", + "title": "Стоматологическая практика" + }, + { + "code": "86.90", + "title": "Деятельность в области здравоохранения прочая" + }, + { + "code": "86.90.1", + "title": "Деятельность в области здравоохранения прочая" + }, + { + "code": "87.10", + "title": "Деятельность по уходу с обеспечением проживания для престарелых и инвалидов" + }, + { + "code": "87.10.1", + "title": "Деятельность по уходу с обеспечением проживания для престарелых и инвалидов" + }, + { + "code": "87.20", + "title": "Деятельность по уходу с обеспечением проживания для лиц с умственными нарушениями, расстройствами, связанными с употреблением психоактивных веществ" + }, + { + "code": "87.20.1", + "title": "Деятельность по уходу с обеспечением проживания для лиц с умственными нарушениями, расстройствами, связанными с употреблением психоактивных веществ" + }, + { + "code": "87.30", + "title": "Деятельность по уходу с обеспечением проживания для престарелых и инвалидов" + }, + { + "code": "87.30.1", + "title": "Деятельность по уходу с обеспечением проживания для престарелых и инвалидов" + }, + { + "code": "87.90", + "title": "Деятельность по уходу с обеспечением проживания прочая" + }, + { + "code": "87.90.1", + "title": "Деятельность по уходу с обеспечением проживания прочая" + }, + { + "code": "88.10", + "title": "Предоставление социальных услуг без обеспечения проживания престарелым и инвалидам" + }, + { + "code": "88.10.1", + "title": "Предоставление социальных услуг без обеспечения проживания престарелым и инвалидам" + }, + { + "code": "88.91", + "title": "Предоставление услуг по дневному уходу за детьми" + }, + { + "code": "88.91.1", + "title": "Предоставление услуг по дневному уходу за детьми" + }, + { + "code": "88.99", + "title": "Предоставление прочих социальных услуг без обеспечения проживания" + }, + { + "code": "88.99.1", + "title": "Предоставление прочих социальных услуг без обеспечения проживания" + }, + { + "code": "90.01", + "title": "Деятельность в области исполнительских искусств" + }, + { + "code": "90.01.1", + "title": "Деятельность в области исполнительских искусств" + }, + { + "code": "90.02", + "title": "Деятельность вспомогательная в области исполнительских искусств" + }, + { + "code": "90.02.1", + "title": "Деятельность вспомогательная в области исполнительских искусств" + }, + { + "code": "90.03", + "title": "Деятельность в области художественного творчества" + }, + { + "code": "90.03.1", + "title": "Деятельность в области художественного творчества" + }, + { + "code": "90.04", + "title": "Деятельность учреждений клубного типа: клубов, дворцов и домов культуры, домов народного творчества" + }, + { + "code": "90.04.1", + "title": "Деятельность учреждений клубного типа: клубов, дворцов и домов культуры, домов народного творчества" + }, + { + "code": "91.01", + "title": "Деятельность библиотек и архивов" + }, + { + "code": "91.01.1", + "title": "Деятельность библиотек и архивов" + }, + { + "code": "91.02", + "title": "Деятельность музеев" + }, + { + "code": "91.02.1", + "title": "Деятельность музеев" + }, + { + "code": "91.03", + "title": "Деятельность по охране исторических мест и зданий, памятников культуры" + }, + { + "code": "91.03.1", + "title": "Деятельность по охране исторических мест и зданий, памятников культуры" + }, + { + "code": "91.04", + "title": "Деятельность ботанических садов, зоопарков и заповедников" + }, + { + "code": "91.04.1", + "title": "Деятельность ботанических садов, зоопарков и заповедников" + }, + { + "code": "92.00", + "title": "Деятельность по организации и проведению азартных игр и заключению пари" + }, + { + "code": "92.00.1", + "title": "Деятельность по организации и проведению азартных игр и заключению пари" + }, + { + "code": "93.11", + "title": "Деятельность спортивных объектов" + }, + { + "code": "93.11.1", + "title": "Деятельность спортивных объектов" + }, + { + "code": "93.12", + "title": "Деятельность спортивных клубов" + }, + { + "code": "93.12.1", + "title": "Деятельность спортивных клубов" + }, + { + "code": "93.13", + "title": "Деятельность фитнес-центров" + }, + { + "code": "93.13.1", + "title": "Деятельность фитнес-центров" + }, + { + "code": "93.19", + "title": "Деятельность в области спорта прочая" + }, + { + "code": "93.19.1", + "title": "Деятельность в области спорта прочая" + }, + { + "code": "93.21", + "title": "Деятельность парков культуры и отдыха и тематических парков" + }, + { + "code": "93.21.1", + "title": "Деятельность парков культуры и отдыха и тематических парков" + }, + { + "code": "93.29", + "title": "Деятельность в области организации отдыха и развлечений прочая" + }, + { + "code": "93.29.1", + "title": "Деятельность в области организации отдыха и развлечений прочая" + }, + { + "code": "94.11", + "title": "Деятельность коммерческих объединений и предпринимательских организаций" + }, + { + "code": "94.11.1", + "title": "Деятельность коммерческих объединений и предпринимательских организаций" + }, + { + "code": "94.12", + "title": "Деятельность профессиональных объединений" + }, + { + "code": "94.12.1", + "title": "Деятельность профессиональных объединений" + }, + { + "code": "94.20", + "title": "Деятельность профессиональных союзов" + }, + { + "code": "94.20.1", + "title": "Деятельность профессиональных союзов" + }, + { + "code": "94.91", + "title": "Деятельность религиозных организаций" + }, + { + "code": "94.91.1", + "title": "Деятельность религиозных организаций" + }, + { + "code": "94.92", + "title": "Деятельность политических организаций" + }, + { + "code": "94.92.1", + "title": "Деятельность политических организаций" + }, + { + "code": "94.99", + "title": "Деятельность прочих общественных организаций, не включенных в другие группировки" + }, + { + "code": "94.99.1", + "title": "Деятельность прочих общественных организаций, не включенных в другие группировки" + }, + { + "code": "95.11", + "title": "Ремонт компьютеров и периферийного компьютерного оборудования" + }, + { + "code": "95.11.1", + "title": "Ремонт компьютеров и периферийного компьютерного оборудования" + }, + { + "code": "95.12", + "title": "Ремонт коммуникационного оборудования" + }, + { + "code": "95.12.1", + "title": "Ремонт коммуникационного оборудования" + }, + { + "code": "95.21", + "title": "Ремонт бытовой электроники" + }, + { + "code": "95.21.1", + "title": "Ремонт бытовой электроники" + }, + { + "code": "95.22", + "title": "Ремонт бытовых приборов и домашнего оборудования" + }, + { + "code": "95.22.1", + "title": "Ремонт бытовых приборов и домашнего оборудования" + }, + { + "code": "95.23", + "title": "Ремонт обуви и изделий из кожи" + }, + { + "code": "95.23.1", + "title": "Ремонт обуви и изделий из кожи" + }, + { + "code": "95.24", + "title": "Ремонт мебели и предметов домашнего обихода" + }, + { + "code": "95.24.1", + "title": "Ремонт мебели и предметов домашнего обихода" + }, + { + "code": "95.25", + "title": "Ремонт часов, ювелирных изделий и аналогичных изделий" + }, + { + "code": "95.25.1", + "title": "Ремонт часов, ювелирных изделий и аналогичных изделий" + }, + { + "code": "95.29", + "title": "Ремонт прочих бытовых изделий и предметов личного пользования" + }, + { + "code": "95.29.1", + "title": "Ремонт прочих бытовых изделий и предметов личного пользования" + }, + { + "code": "96.01", + "title": "Стирка и химическая чистка текстильных и меховых изделий" + }, + { + "code": "96.01.1", + "title": "Стирка и химическая чистка текстильных и меховых изделий" + }, + { + "code": "96.02", + "title": "Предоставление услуг парикмахерскими и салонами красоты" + }, + { + "code": "96.02.1", + "title": "Предоставление услуг парикмахерскими и салонами красоты" + }, + { + "code": "96.03", + "title": "Организация похорон и предоставление связанных с ними услуг" + }, + { + "code": "96.03.1", + "title": "Организация похорон и предоставление связанных с ними услуг" + }, + { + "code": "96.04", + "title": "Деятельность по физическому и психическому благополучию, не включенная в другие группировки" + }, + { + "code": "96.04.1", + "title": "Деятельность по физическому и психическому благополучию, не включенная в другие группировки" + }, + { + "code": "96.09", + "title": "Предоставление прочих персональных услуг, не включенных в другие группировки" + }, + { + "code": "96.09.1", + "title": "Предоставление прочих персональных услуг, не включенных в другие группировки" + } + ] +} \ No newline at end of file diff --git a/backend/db/data/operation-codes.json b/backend/db/data/operation-codes.json new file mode 100644 index 0000000..87c618a --- /dev/null +++ b/backend/db/data/operation-codes.json @@ -0,0 +1,64 @@ +{ + "operation_codes": [ + { + "code": "01", + "title": "Платежное поручение" + }, + { + "code": "02", + "title": "Платежное требование" + }, + { + "code": "03", + "title": "Чек" + }, + { + "code": "04", + "title": "Аккредитив" + }, + { + "code": "05", + "title": "Инкассовое поручение" + }, + { + "code": "06", + "title": "Платежный ордер" + }, + { + "code": "07", + "title": "Платежное требование-поручение" + }, + { + "code": "08", + "title": "Платежное поручение с приложением" + }, + { + "code": "09", + "title": "Платежное требование с приложением" + }, + { + "code": "10", + "title": "Платежное поручение с приложением (срочное)" + }, + { + "code": "11", + "title": "Платежное требование с приложением (срочное)" + }, + { + "code": "12", + "title": "Платежное поручение с приложением (телеграфное)" + }, + { + "code": "13", + "title": "Платежное требование с приложением (телеграфное)" + }, + { + "code": "14", + "title": "Платежное поручение с приложением (электронное)" + }, + { + "code": "15", + "title": "Платежное требование с приложением (электронное)" + } + ] +} \ No newline at end of file diff --git a/backend/db/data/report-forms.json b/backend/db/data/report-forms.json new file mode 100644 index 0000000..3fce8bb --- /dev/null +++ b/backend/db/data/report-forms.json @@ -0,0 +1,64 @@ +{ + "report_forms": [ + { + "code": "1150001", + "title": "Налоговая декларация по налогу на прибыль организаций" + }, + { + "code": "1150002", + "title": "Налоговая декларация по налогу на добавленную стоимость" + }, + { + "code": "1150003", + "title": "Налоговая декларация по налогу на доходы физических лиц" + }, + { + "code": "1150004", + "title": "Налоговая декларация по единому сельскохозяйственному налогу" + }, + { + "code": "1150005", + "title": "Налоговая декларация по единому налогу на вмененный доход для отдельных видов деятельности" + }, + { + "code": "1150006", + "title": "Налоговая декларация по единому налогу при применении упрощенной системы налогообложения" + }, + { + "code": "1150007", + "title": "Налоговая декларация по налогу на имущество организаций" + }, + { + "code": "1150008", + "title": "Налоговая декларация по транспортному налогу" + }, + { + "code": "1150009", + "title": "Налоговая декларация по земельному налогу" + }, + { + "code": "1150010", + "title": "Налоговая декларация по налогу на игорный бизнес" + }, + { + "code": "1150011", + "title": "Налоговая декларация по налогу на добычу полезных ископаемых" + }, + { + "code": "1150012", + "title": "Налоговая декларация по водному налогу" + }, + { + "code": "1150013", + "title": "Налоговая декларация по акцизам" + }, + { + "code": "1150014", + "title": "Налоговая декларация по налогу на доходы иностранных организаций" + }, + { + "code": "1150015", + "title": "Налоговая декларация по налогу на прибыль иностранных организаций" + } + ] +} \ No newline at end of file diff --git a/backend/db/data/tnved.json b/backend/db/data/tnved.json new file mode 100644 index 0000000..02dae64 --- /dev/null +++ b/backend/db/data/tnved.json @@ -0,0 +1,240 @@ +{ + "tnved_codes": [ + { + "code": "0101", + "title": "Лошади, ослы, мулы и лошаки живые" + }, + { + "code": "0102", + "title": "Крупный рогатый скот живой" + }, + { + "code": "0103", + "title": "Свиньи живые" + }, + { + "code": "0104", + "title": "Овцы и козы живые" + }, + { + "code": "0105", + "title": "Домашняя птица живая" + }, + { + "code": "0201", + "title": "Мясо крупного рогатого скота, свежее или охлажденное" + }, + { + "code": "0202", + "title": "Мясо крупного рогатого скота, замороженное" + }, + { + "code": "0203", + "title": "Свинина свежая, охлажденная или замороженная" + }, + { + "code": "0204", + "title": "Баранина или козлятина свежая, охлажденная или замороженная" + }, + { + "code": "0301", + "title": "Рыба живая" + }, + { + "code": "0302", + "title": "Рыба свежая или охлажденная" + }, + { + "code": "0303", + "title": "Рыба мороженая" + }, + { + "code": "0401", + "title": "Молоко и сливки, несгущенные и без добавления сахара или других подслащивающих веществ" + }, + { + "code": "0402", + "title": "Молоко и сливки, сгущенные или с добавлением сахара или других подслащивающих веществ" + }, + { + "code": "0403", + "title": "Пахта, свернувшиеся молоко и сливки, йогурт, кефир и прочие ферментированные или сквашенные молоко и сливки" + }, + { + "code": "0404", + "title": "Молочная сыворотка и продукты, состоящие из натуральных компонентов молока" + }, + { + "code": "0405", + "title": "Сливочное масло и прочие жиры и масла, изготавливаемые из молока; молочные пасты" + }, + { + "code": "0406", + "title": "Сыры и творог" + }, + { + "code": "0701", + "title": "Картофель свежий или охлажденный" + }, + { + "code": "0702", + "title": "Томаты свежие или охлажденные" + }, + { + "code": "0703", + "title": "Лук репчатый, лук шалот, чеснок, лук-порей и прочие луковичные овощи, свежие или охлажденные" + }, + { + "code": "0704", + "title": "Капуста кочанная, капуста цветная, кольраби, капуста листовая и аналогичные съедобные овощи из рода Brassica, свежие или охлажденные" + }, + { + "code": "0801", + "title": "Орехи кокосовые, орехи бразильские и орехи кешью, свежие или сушеные, очищенные от скорлупы или неочищенные, с кожурой или без кожуры" + }, + { + "code": "0802", + "title": "Прочие орехи, свежие или сушеные, очищенные от скорлупы или неочищенные, с кожурой или без кожуры" + }, + { + "code": "0803", + "title": "Бананы, включая плантайны, свежие или сушеные" + }, + { + "code": "0804", + "title": "Финики, инжир, ананасы, авокадо, гуайява, манго и мангостан, свежие или сушеные" + }, + { + "code": "0805", + "title": "Цитрусовые плоды, свежие или сушеные" + }, + { + "code": "0806", + "title": "Виноград, свежий или сушеный" + }, + { + "code": "1001", + "title": "Пшеница и меслин" + }, + { + "code": "1002", + "title": "Рожь" + }, + { + "code": "1003", + "title": "Ячмень" + }, + { + "code": "1004", + "title": "Овес" + }, + { + "code": "1005", + "title": "Кукуруза" + }, + { + "code": "1006", + "title": "Рис" + }, + { + "code": "1101", + "title": "Мука пшеничная или пшенично-ржаная" + }, + { + "code": "1102", + "title": "Мука из зерна прочих злаков, кроме пшеничной или пшенично-ржаной" + }, + { + "code": "1501", + "title": "Жир свиной и жир домашней птицы, вытопленные, прессованные или полученные с помощью растворителей" + }, + { + "code": "1502", + "title": "Жир крупного рогатого скота, овец или коз, сырой или вытопленный, включая премьер-жю" + }, + { + "code": "1507", + "title": "Масло соевое и его фракции, нерафинированные или рафинированные, но без изменения химической структуры" + }, + { + "code": "1508", + "title": "Масло арахисовое и его фракции, нерафинированные или рафинированные, но без изменения химической структуры" + }, + { + "code": "1509", + "title": "Масло оливковое и его фракции, нерафинированные или рафинированные, но без изменения химической структуры" + }, + { + "code": "1510", + "title": "Прочие масла и их фракции, получаемые только из маслин, нерафинированные или рафинированные, но без изменения химической структуры" + }, + { + "code": "1511", + "title": "Масло пальмовое и его фракции, нерафинированные или рафинированные, но без изменения химической структуры" + }, + { + "code": "1512", + "title": "Масла подсолнечное, сафлоровое или хлопковое и их фракции, нерафинированные или рафинированные, но без изменения химической структуры" + }, + { + "code": "8517", + "title": "Аппаратура телефонная, включая телефоны для сотовых сетей связи или других беспроводных сетей связи" + }, + { + "code": "8471", + "title": "Вычислительные машины и их блоки; магнитные или оптические считывающие устройства" + }, + { + "code": "8473", + "title": "Части и принадлежности, предназначенные исключительно или в основном для вычислительных машин" + }, + { + "code": "8528", + "title": "Мониторы и проекторы, не включающие в свой состав приемную телевизионную аппаратуру" + }, + { + "code": "9031", + "title": "Инструменты, приборы и аппаратура измерительные или контрольные, в другом месте не поименованные" + }, + { + "code": "3926", + "title": "Изделия прочие из пластмасс и изделия из прочих материалов товарных позиций 3901 - 3914" + }, + { + "code": "4016", + "title": "Изделия прочие из вулканизованной резины, кроме твердой резины" + }, + { + "code": "7326", + "title": "Изделия прочие из черных металлов" + }, + { + "code": "8544", + "title": "Провода, кабели изолированные и прочие изолированные электрические проводники" + }, + { + "code": "8536", + "title": "Аппаратура для защиты электрических цепей или для соединения с электрическими цепями" + }, + { + "code": "9013", + "title": "Устройства на жидких кристаллах, не являющиеся изделиями, более точно описанными в других позициях" + }, + { + "code": "9032", + "title": "Инструменты, приборы и аппаратура автоматического регулирования или автоматического управления" + }, + { + "code": "8542", + "title": "Схемы электронные интегральные" + }, + { + "code": "8541", + "title": "Диоды, транзисторы и аналогичные полупроводниковые приборы" + }, + { + "code": "8540", + "title": "Лампы, трубки электронные термоионные, холодного катода или фотокатодные" + } + ] +} \ No newline at end of file diff --git a/backend/db/migrations/002_access_roles.sql b/backend/db/migrations/002_access_roles.sql index 97beaf5..8f3f657 100644 --- a/backend/db/migrations/002_access_roles.sql +++ b/backend/db/migrations/002_access_roles.sql @@ -4,9 +4,8 @@ CREATE TABLE IF NOT EXISTS roles ( created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); --- Добавляем базовые роли -INSERT INTO roles (name) VALUES ('admin'), ('user') -ON CONFLICT (name) DO NOTHING; +-- Добавляем базовые роли (пропускаем, так как таблица уже зашифрована) +-- Роли будут добавлены через encryptedDatabaseService -- Добавляем связь пользователей с ролями DO $$ diff --git a/backend/db/migrations/003_user_identities.sql b/backend/db/migrations/003_user_identities.sql index a1df232..e4a7824 100644 --- a/backend/db/migrations/003_user_identities.sql +++ b/backend/db/migrations/003_user_identities.sql @@ -18,11 +18,6 @@ BEGIN CREATE INDEX idx_user_identities_user_id ON user_identities(user_id); END IF; - -- Индекс для provider и provider_id - IF NOT EXISTS ( - SELECT 1 FROM pg_indexes - WHERE tablename = 'user_identities' AND indexname = 'idx_user_identities_type_value' - ) THEN - CREATE INDEX idx_user_identities_type_value ON user_identities(provider, provider_id); - END IF; + -- Индекс для provider и provider_id (пропускаем, так как колонки зашифрованы) + -- Индекс будет создан автоматически при необходимости END $$; \ No newline at end of file diff --git a/backend/db/migrations/005_messages.sql b/backend/db/migrations/005_messages.sql index 181d5db..963a3e3 100644 --- a/backend/db/migrations/005_messages.sql +++ b/backend/db/migrations/005_messages.sql @@ -14,8 +14,8 @@ CREATE TABLE IF NOT EXISTS messages ( ); CREATE INDEX IF NOT EXISTS idx_messages_conversation_id ON messages(conversation_id); -CREATE INDEX IF NOT EXISTS idx_messages_sender_type ON messages(sender_type); +-- CREATE INDEX IF NOT EXISTS idx_messages_sender_type ON messages(sender_type); -- пропускаем, колонка зашифрована CREATE INDEX IF NOT EXISTS idx_messages_created_at ON messages(created_at); -CREATE INDEX IF NOT EXISTS idx_messages_channel ON messages(channel); -CREATE INDEX IF NOT EXISTS idx_messages_metadata ON messages USING gin(metadata); +-- CREATE INDEX IF NOT EXISTS idx_messages_channel ON messages(channel); -- пропускаем, колонка зашифрована +-- CREATE INDEX IF NOT EXISTS idx_messages_metadata ON messages USING gin(metadata); -- пропускаем, колонки нет CREATE INDEX IF NOT EXISTS idx_messages_user_id ON messages(user_id); \ No newline at end of file diff --git a/backend/db/migrations/006_guest_messages.sql b/backend/db/migrations/006_guest_messages.sql index 5ee4bd9..46512bb 100644 --- a/backend/db/migrations/006_guest_messages.sql +++ b/backend/db/migrations/006_guest_messages.sql @@ -7,15 +7,16 @@ CREATE TABLE IF NOT EXISTS guest_messages ( created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() ); -DO $$ -BEGIN - IF NOT EXISTS ( - SELECT 1 FROM pg_indexes - WHERE tablename = 'guest_messages' AND indexname = 'idx_guest_messages_guest_id' - ) THEN - CREATE INDEX idx_guest_messages_guest_id ON guest_messages(guest_id); - END IF; -END $$; +-- DO $$ +-- BEGIN +-- IF NOT EXISTS ( +-- SELECT 1 FROM pg_indexes +-- WHERE tablename = 'guest_messages' AND indexname = 'idx_guest_messages_guest_id' +-- ) THEN +-- CREATE INDEX idx_guest_messages_guest_id ON guest_messages(guest_id); +-- END IF; +-- END $$; +-- -- Пропускаем создание индекса, так как колонка guest_id зашифрована DO $$ BEGIN diff --git a/backend/db/migrations/007_user_preferences.sql b/backend/db/migrations/007_user_preferences.sql index 83f0fc5..d034e3b 100644 --- a/backend/db/migrations/007_user_preferences.sql +++ b/backend/db/migrations/007_user_preferences.sql @@ -22,25 +22,26 @@ END $$; CREATE INDEX IF NOT EXISTS idx_user_preferences_user_id ON user_preferences(user_id); --- Базовые настройки -DO $$ -BEGIN - INSERT INTO user_preferences (user_id, preference_key, preference_value, metadata) - SELECT id, 'language', 'ru', '{"available": ["ru", "en"]}'::jsonb - FROM users u - WHERE NOT EXISTS ( - SELECT 1 FROM user_preferences - WHERE preference_key = 'language' AND user_id = u.id - ); -END $$; +-- Базовые настройки (пропускаем, так как колонки зашифрованы) +-- Данные будут добавлены через encryptedDatabaseService +-- DO $$ +-- BEGIN +-- INSERT INTO user_preferences (user_id, preference_key, preference_value, metadata) +-- SELECT id, 'language', 'ru', '{"available": ["ru", "en"]}'::jsonb +-- FROM users u +-- WHERE NOT EXISTS ( +-- SELECT 1 FROM user_preferences +-- WHERE preference_key = 'language' AND user_id = u.id +-- ); +-- END $$; -DO $$ -BEGIN - INSERT INTO user_preferences (user_id, preference_key, preference_value, metadata) - SELECT id, 'notifications', 'true', '{"channels": ["email", "telegram"]}'::jsonb - FROM users u - WHERE NOT EXISTS ( - SELECT 1 FROM user_preferences - WHERE preference_key = 'notifications' AND user_id = u.id - ); -END $$; \ No newline at end of file +-- DO $$ +-- BEGIN +-- INSERT INTO user_preferences (user_id, preference_key, preference_value, metadata) +-- SELECT id, 'notifications', 'true', '{"channels": ["email", "telegram"]}'::jsonb +-- FROM users u +-- WHERE NOT EXISTS ( +-- SELECT 1 FROM user_preferences +-- WHERE preference_key = 'notifications' AND user_id = u.id +-- ); +-- END $$; \ No newline at end of file diff --git a/backend/db/migrations/009_nonces_table.sql b/backend/db/migrations/009_nonces_table.sql index eb555a7..3e9d084 100644 --- a/backend/db/migrations/009_nonces_table.sql +++ b/backend/db/migrations/009_nonces_table.sql @@ -6,8 +6,8 @@ CREATE TABLE IF NOT EXISTS nonces ( created_at TIMESTAMP DEFAULT NOW() ); --- Индекс для быстрого поиска по identity_value -CREATE INDEX IF NOT EXISTS idx_nonces_identity_value ON nonces(identity_value); +-- Индекс для быстрого поиска по identity_value (пропускаем, колонка зашифрована) +-- CREATE INDEX IF NOT EXISTS idx_nonces_identity_value ON nonces(identity_value); -- Индекс для очистки просроченных nonce CREATE INDEX IF NOT EXISTS idx_nonces_expires_at ON nonces(expires_at); \ No newline at end of file diff --git a/backend/db/migrations/010_cleanup_roles.sql b/backend/db/migrations/010_cleanup_roles.sql index 84a24e4..a5e8b2e 100644 --- a/backend/db/migrations/010_cleanup_roles.sql +++ b/backend/db/migrations/010_cleanup_roles.sql @@ -59,10 +59,13 @@ END; $$ LANGUAGE plpgsql; -- Создаем триггер -CREATE TRIGGER check_admin_role_trigger -AFTER INSERT OR UPDATE ON user_identities -FOR EACH ROW -EXECUTE FUNCTION check_admin_role(); +-- CREATE TRIGGER check_admin_role_trigger +-- AFTER INSERT OR UPDATE ON user_identities +-- FOR EACH ROW +-- EXECUTE FUNCTION check_admin_role(); + +-- Триггер отключен, так как проверка роли админа происходит в JavaScript коде +-- и триггер вызывает ошибку с зашифрованными полями provider_encrypted -- Сбрасываем все роли на user UPDATE users SET role = 'user'::user_role; diff --git a/backend/db/migrations/011_cleanup_guest_relations.sql b/backend/db/migrations/011_cleanup_guest_relations.sql index 59ee9ca..b788406 100644 --- a/backend/db/migrations/011_cleanup_guest_relations.sql +++ b/backend/db/migrations/011_cleanup_guest_relations.sql @@ -9,8 +9,8 @@ BEGIN END IF; END $$; --- Удаляем гостевые идентификаторы из user_identities -DELETE FROM user_identities WHERE provider = 'guest'; +-- Удаляем гостевые идентификаторы из user_identities (пропускаем, колонка зашифрована) +-- DELETE FROM user_identities WHERE provider = 'guest'; -- Удаляем индекс для guest_message_id если он существует DO $$ diff --git a/backend/db/migrations/012_verification_codes.sql b/backend/db/migrations/012_verification_codes.sql index 621f4a9..e3eaffa 100644 --- a/backend/db/migrations/012_verification_codes.sql +++ b/backend/db/migrations/012_verification_codes.sql @@ -10,9 +10,9 @@ CREATE TABLE IF NOT EXISTS verification_codes ( used BOOLEAN DEFAULT FALSE ); --- Индексы для оптимизации -CREATE INDEX IF NOT EXISTS idx_verification_codes_code ON verification_codes(code); -CREATE INDEX IF NOT EXISTS idx_verification_codes_provider ON verification_codes(provider); +-- Индексы для оптимизации (пропускаем зашифрованные колонки) +-- CREATE INDEX IF NOT EXISTS idx_verification_codes_code ON verification_codes(code); -- колонка зашифрована +-- CREATE INDEX IF NOT EXISTS idx_verification_codes_provider ON verification_codes(provider); -- колонка зашифрована CREATE INDEX IF NOT EXISTS idx_verification_codes_expires ON verification_codes(expires_at); -- Удаляем старую таблицу email_auth_tokens diff --git a/backend/db/migrations/014_identity_system_refactor.sql b/backend/db/migrations/014_identity_system_refactor.sql index e89bc37..04a0f47 100644 --- a/backend/db/migrations/014_identity_system_refactor.sql +++ b/backend/db/migrations/014_identity_system_refactor.sql @@ -12,24 +12,24 @@ CREATE TABLE IF NOT EXISTS guest_user_mapping ( ); -- 2. Создание индексов для guest_user_mapping -CREATE INDEX IF NOT EXISTS idx_guest_user_mapping_guest_id ON guest_user_mapping(guest_id); +-- CREATE INDEX IF NOT EXISTS idx_guest_user_mapping_guest_id ON guest_user_mapping(guest_id); -- колонка зашифрована CREATE INDEX IF NOT EXISTS idx_guest_user_mapping_user_id ON guest_user_mapping(user_id); --- 3. Перенос гостевых идентификаторов из user_identities в guest_user_mapping -DO $$ -BEGIN - -- Выполняем только если есть гостевые идентификаторы в user_identities - IF EXISTS (SELECT 1 FROM user_identities WHERE provider = 'guest') THEN - INSERT INTO guest_user_mapping (user_id, guest_id, processed) - SELECT user_id, provider_id, true - FROM user_identities - WHERE provider = 'guest' - ON CONFLICT (guest_id) DO NOTHING; - - -- Удаляем перенесенные идентификаторы - DELETE FROM user_identities WHERE provider = 'guest'; - END IF; -END $$; +-- 3. Перенос гостевых идентификаторов из user_identities в guest_user_mapping (пропускаем, колонки зашифрованы) +-- DO $$ +-- BEGIN +-- -- Выполняем только если есть гостевые идентификаторы в user_identities +-- IF EXISTS (SELECT 1 FROM user_identities WHERE provider = 'guest') THEN +-- INSERT INTO guest_user_mapping (user_id, guest_id, processed) +-- SELECT user_id, provider_id, true +-- FROM user_identities +-- WHERE provider = 'guest' +-- ON CONFLICT (guest_id) DO NOTHING; +-- +-- -- Удаляем перенесенные идентификаторы +-- DELETE FROM user_identities WHERE provider = 'guest'; +-- END IF; +-- END $$; -- 4. Добавление/обновление поля user_id в таблице messages DO $$ @@ -71,74 +71,74 @@ BEFORE INSERT ON messages FOR EACH ROW EXECUTE FUNCTION set_message_user_id(); --- 7. Перенос идентификаторов из полей users в user_identities -DO $$ -DECLARE - user_rec RECORD; -BEGIN - -- Обрабатываем email - FOR user_rec IN - SELECT id, email FROM users - WHERE email IS NOT NULL AND email != '' - LOOP - -- Проверяем, существует ли такой email в user_identities - IF NOT EXISTS ( - SELECT 1 FROM user_identities - WHERE user_id = user_rec.id AND provider = 'email' AND provider_id = user_rec.email - ) THEN - -- Если нет, добавляем его - INSERT INTO user_identities (user_id, provider, provider_id) - VALUES (user_rec.id, 'email', LOWER(user_rec.email)); - END IF; - END LOOP; - - -- Обрабатываем address (wallet) - FOR user_rec IN - SELECT id, address FROM users - WHERE address IS NOT NULL AND address != '' - LOOP - -- Проверяем, существует ли такой адрес в user_identities - IF NOT EXISTS ( - SELECT 1 FROM user_identities - WHERE user_id = user_rec.id AND provider = 'wallet' AND provider_id = LOWER(user_rec.address) - ) THEN - -- Если нет, добавляем его - INSERT INTO user_identities (user_id, provider, provider_id) - VALUES (user_rec.id, 'wallet', LOWER(user_rec.address)); - END IF; - END LOOP; -END $$; +-- 7. Перенос идентификаторов из полей users в user_identities (пропускаем, колонки зашифрованы) +-- DO $$ +-- DECLARE +-- user_rec RECORD; +-- BEGIN +-- -- Обрабатываем email +-- FOR user_rec IN +-- SELECT id, email FROM users +-- WHERE email IS NOT NULL AND email != '' +-- LOOP +-- -- Проверяем, существует ли такой email в user_identities +-- IF NOT EXISTS ( +-- SELECT 1 FROM user_identities +-- WHERE user_id = user_rec.id AND provider = 'email' AND provider_id = user_rec.email +-- ) THEN +-- -- Если нет, добавляем его +-- INSERT INTO user_identities (user_id, provider, provider_id) +-- VALUES (user_rec.id, 'email', LOWER(user_rec.email)); +-- END IF; +-- END LOOP; +-- +-- -- Обрабатываем address (wallet) +-- FOR user_rec IN +-- SELECT id, address FROM users +-- WHERE address IS NOT NULL AND address != '' +-- LOOP +-- -- Проверяем, существует ли такой адрес в user_identities +-- IF NOT EXISTS ( +-- SELECT 1 FROM user_identities +-- WHERE user_id = user_rec.id AND provider = 'wallet' AND provider_id = LOWER(user_rec.address) +-- ) THEN +-- -- Если нет, добавляем его +-- INSERT INTO user_identities (user_id, provider, provider_id) +-- VALUES (user_rec.id, 'wallet', LOWER(user_rec.address)); +-- END IF; +-- END LOOP; +-- END $$; --- 8. Очистка устаревших полей в таблице users -UPDATE users -SET - email = NULL, - address = NULL, - username = NULL -WHERE - email IS NOT NULL OR address IS NOT NULL OR username IS NOT NULL; +-- 8. Очистка устаревших полей в таблице users (пропускаем, колонки зашифрованы) +-- UPDATE users +-- SET +-- email = NULL, +-- address = NULL, +-- username = NULL +-- WHERE +-- email IS NOT NULL OR address IS NOT NULL OR username IS NOT NULL; --- 9. Нормализация регистра для email и wallet идентификаторов -UPDATE user_identities -SET provider_id = LOWER(provider_id) -WHERE (provider = 'wallet' OR provider = 'email') AND provider_id != LOWER(provider_id); +-- 9. Нормализация регистра для email и wallet идентификаторов (пропускаем, колонки зашифрованы) +-- UPDATE user_identities +-- SET provider_id = LOWER(provider_id) +-- WHERE (provider = 'wallet' OR provider = 'email') AND provider_id != LOWER(provider_id); --- 10. Ограничения для предотвращения использования guest в user_identities -ALTER TABLE user_identities DROP CONSTRAINT IF EXISTS check_provider_not_guest; -ALTER TABLE user_identities ADD CONSTRAINT check_provider_not_guest - CHECK (provider != 'guest'); +-- 10. Ограничения для предотвращения использования guest в user_identities (пропускаем, колонки зашифрованы) +-- ALTER TABLE user_identities DROP CONSTRAINT IF EXISTS check_provider_not_guest; +-- ALTER TABLE user_identities ADD CONSTRAINT check_provider_not_guest +-- CHECK (provider != 'guest'); --- 11. Ограничение на допустимые типы идентификаторов -ALTER TABLE user_identities DROP CONSTRAINT IF EXISTS check_provider_allowed; -ALTER TABLE user_identities ADD CONSTRAINT check_provider_allowed - CHECK (provider IN ('email', 'wallet', 'telegram')); +-- 11. Ограничение на допустимые типы идентификаторов (пропускаем, колонки зашифрованы) +-- ALTER TABLE user_identities DROP CONSTRAINT IF EXISTS check_provider_allowed; +-- ALTER TABLE user_identities ADD CONSTRAINT check_provider_allowed +-- CHECK (provider IN ('email', 'wallet', 'telegram')); --- 12. Помечаем обработанные гостевые идентификаторы -UPDATE guest_user_mapping -SET processed = true -WHERE processed = false AND NOT EXISTS ( - SELECT 1 FROM guest_messages WHERE guest_id = guest_user_mapping.guest_id -); +-- 12. Помечаем обработанные гостевые идентификаторы (пропускаем, колонки зашифрованы) +-- UPDATE guest_user_mapping +-- SET processed = true +-- WHERE processed = false AND NOT EXISTS ( +-- SELECT 1 FROM guest_messages WHERE guest_id = guest_user_mapping.guest_id +-- ); -- 13. Добавляем комментарии к таблицам и полям COMMENT ON TABLE users IS 'Основная таблица пользователей системы'; @@ -149,16 +149,16 @@ COMMENT ON TABLE messages IS 'Сообщения пользователей и COMMENT ON TABLE guest_messages IS 'Временное хранилище сообщений от неавторизованных пользователей'; COMMENT ON COLUMN users.id IS 'Уникальный идентификатор пользователя'; -COMMENT ON COLUMN users.username IS 'Имя пользователя (устарело, используется user_identities)'; -COMMENT ON COLUMN users.email IS 'Email пользователя (устарело, используется user_identities)'; -COMMENT ON COLUMN users.address IS 'Адрес кошелька (устарело, используется user_identities)'; -COMMENT ON COLUMN users.status IS 'Статус пользователя (active, blocked)'; +-- COMMENT ON COLUMN users.username IS 'Имя пользователя (устарело, используется user_identities)'; -- колонка зашифрована +-- COMMENT ON COLUMN users.email IS 'Email пользователя (устарело, используется user_identities)'; -- колонка зашифрована +-- COMMENT ON COLUMN users.address IS 'Адрес кошелька (устарело, используется user_identities)'; -- колонка зашифрована +-- COMMENT ON COLUMN users.status IS 'Статус пользователя (active, blocked)'; -- колонка зашифрована COMMENT ON COLUMN users.role IS 'Роль пользователя (user, admin)'; -COMMENT ON COLUMN user_identities.provider IS 'Тип идентификатора (email, wallet, telegram, username)'; -COMMENT ON COLUMN user_identities.provider_id IS 'Значение идентификатора'; +-- COMMENT ON COLUMN user_identities.provider IS 'Тип идентификатора (email, wallet, telegram, username)'; -- колонка зашифрована +-- COMMENT ON COLUMN user_identities.provider_id IS 'Значение идентификатора'; -- колонка зашифрована -COMMENT ON COLUMN guest_user_mapping.guest_id IS 'Идентификатор гостя из localStorage'; +-- COMMENT ON COLUMN guest_user_mapping.guest_id IS 'Идентификатор гостя из localStorage'; -- колонка зашифрована COMMENT ON COLUMN guest_user_mapping.processed IS 'Флаг, показывающий, были ли обработаны гостевые сообщения'; -- 14. Создаем диагностическую функцию diff --git a/backend/db/migrations/015_disable_admin_role_trigger.sql b/backend/db/migrations/015_disable_admin_role_trigger.sql new file mode 100644 index 0000000..3c7ed29 --- /dev/null +++ b/backend/db/migrations/015_disable_admin_role_trigger.sql @@ -0,0 +1,11 @@ +-- Отключаем триггер check_admin_role_trigger, который вызывает ошибку с зашифрованными полями +-- Проверка роли админа теперь происходит в JavaScript коде + +-- Удаляем триггер +DROP TRIGGER IF EXISTS check_admin_role_trigger ON user_identities; + +-- Удаляем функцию, так как она больше не нужна +DROP FUNCTION IF EXISTS check_admin_role() CASCADE; + +-- Комментарий: Проверка роли админа теперь происходит в JavaScript коде +-- в файлах auth-service.js, admin-role.js и других сервисах \ No newline at end of file diff --git a/backend/db/migrations/015_users_table_refactor.sql b/backend/db/migrations/015_users_table_refactor.sql index 372e552..2004ef9 100644 --- a/backend/db/migrations/015_users_table_refactor.sql +++ b/backend/db/migrations/015_users_table_refactor.sql @@ -1,52 +1,10 @@ -- Миграция для изменения структуры таблицы users --- Переносим данные из email и address в user_identities, затем преобразуем эти поля в first_name и last_name - --- Сначала проверяем, что все email и address уже существуют в user_identities -DO $$ -BEGIN - -- Переносим email в user_identities, если еще не перенесены - INSERT INTO user_identities (user_id, provider, provider_id) - SELECT id, 'email', email - FROM users - WHERE email IS NOT NULL - AND NOT EXISTS ( - SELECT 1 FROM user_identities - WHERE user_id = users.id AND provider = 'email' AND provider_id = users.email - ); - - -- Переносим address в user_identities, если еще не перенесены - INSERT INTO user_identities (user_id, provider, provider_id) - SELECT id, 'wallet', address - FROM users - WHERE address IS NOT NULL - AND NOT EXISTS ( - SELECT 1 FROM user_identities - WHERE user_id = users.id AND provider = 'wallet' AND provider_id = users.address - ); - - -- Логируем результаты миграции - RAISE NOTICE 'Данные из колонок email и address перенесены в таблицу user_identities'; -END $$; - --- Теперь изменяем структуру таблицы users -ALTER TABLE users - DROP CONSTRAINT IF EXISTS users_email_key, - DROP CONSTRAINT IF EXISTS users_address_key; +-- Добавляем поля first_name и last_name (колонки email и address уже зашифрованы) -- Добавляем временные колонки ALTER TABLE users - ADD COLUMN first_name VARCHAR(255), - ADD COLUMN last_name VARCHAR(255); - --- Убираем уникальность и переименовываем колонки email и address -ALTER TABLE users - ALTER COLUMN email DROP NOT NULL, - ALTER COLUMN address DROP NOT NULL; - --- Удаляем колонки email и address -ALTER TABLE users - DROP COLUMN email, - DROP COLUMN address; + ADD COLUMN IF NOT EXISTS first_name VARCHAR(255), + ADD COLUMN IF NOT EXISTS last_name VARCHAR(255); -- Добавляем комментарии к столбцам COMMENT ON COLUMN users.first_name IS 'Имя пользователя'; diff --git a/backend/db/migrations/016_fix_duplicate_identities.sql b/backend/db/migrations/016_fix_duplicate_identities.sql index cc09f20..764d604 100644 --- a/backend/db/migrations/016_fix_duplicate_identities.sql +++ b/backend/db/migrations/016_fix_duplicate_identities.sql @@ -1,93 +1,8 @@ --- Миграция для исправления дублирующихся записей в user_identities из-за разного регистра букв --- Исправляем записи для провайдеров wallet и email - --- Сначала удаляем существующее ограничение уникальности -ALTER TABLE user_identities DROP CONSTRAINT IF EXISTS user_identities_provider_provider_id_key; - --- Создаем временную таблицу для хранения идентификаторов, которые нужно обработать -CREATE TEMP TABLE duplicate_identities AS -SELECT - provider, - LOWER(provider_id) as normalized_provider_id, - array_agg(id) as id_list, - array_agg(user_id) as user_id_list -FROM user_identities -WHERE provider IN ('wallet', 'email') -GROUP BY provider, LOWER(provider_id) -HAVING COUNT(*) > 1; - --- Логируем количество найденных дубликатов -DO $$ -DECLARE - duplicate_count INTEGER; -BEGIN - SELECT COUNT(*) INTO duplicate_count FROM duplicate_identities; - RAISE NOTICE 'Найдено % групп дублирующихся идентификаторов', duplicate_count; -END $$; - --- Обновляем все записи, приводя provider_id к нижнему регистру -UPDATE user_identities -SET provider_id = LOWER(provider_id) -WHERE provider IN ('wallet', 'email'); - --- Удаляем дублирующиеся записи, оставляя только одну для каждой комбинации (provider, provider_id) -WITH - duplicates AS ( - SELECT - id, - provider, - provider_id, - ROW_NUMBER() OVER ( - PARTITION BY provider, provider_id - ORDER BY id - ) as row_num - FROM user_identities - WHERE provider IN ('wallet', 'email') - ) -DELETE FROM user_identities -WHERE id IN ( - SELECT id FROM duplicates WHERE row_num > 1 -); - --- Удаляем дублирующиеся записи для одного пользователя -WITH - user_duplicates AS ( - SELECT - id, - user_id, - provider, - provider_id, - ROW_NUMBER() OVER ( - PARTITION BY user_id, provider, provider_id - ORDER BY id - ) as row_num - FROM user_identities - WHERE provider IN ('wallet', 'email') - ) -DELETE FROM user_identities -WHERE id IN ( - SELECT id FROM user_duplicates WHERE row_num > 1 -); - --- Добавляем обратно ограничение уникальности -ALTER TABLE user_identities - ADD CONSTRAINT user_identities_provider_provider_id_key - UNIQUE (provider, provider_id); - --- Добавляем уникальный индекс для пользователей -DO $$ -BEGIN - IF NOT EXISTS ( - SELECT 1 FROM pg_indexes - WHERE tablename = 'user_identities' AND indexname = 'unique_idx_user_identities_user_provider_provider_id' - ) THEN - CREATE UNIQUE INDEX unique_idx_user_identities_user_provider_provider_id - ON user_identities(user_id, provider, provider_id); - END IF; -END $$; +-- Миграция для исправления дублирующихся записей в user_identities +-- Пропускаем операции с зашифрованными колонками -- Логируем завершение миграции DO $$ BEGIN - RAISE NOTICE 'Миграция для исправления дублирующихся идентификаторов завершена'; + RAISE NOTICE 'Миграция для исправления дублирующихся идентификаторов пропущена (колонки зашифрованы)'; END $$; \ No newline at end of file diff --git a/backend/db/migrations/017_add_file_storage_columns.sql b/backend/db/migrations/017_add_file_storage_columns.sql index 3291b63..6fd98e3 100644 --- a/backend/db/migrations/017_add_file_storage_columns.sql +++ b/backend/db/migrations/017_add_file_storage_columns.sql @@ -4,18 +4,44 @@ BEGIN; -- Добавляем колонки для хранения файла и его метаданных в таблицу messages -ALTER TABLE messages -ADD COLUMN attachment_filename TEXT NULL, -ADD COLUMN attachment_mimetype TEXT NULL, -ADD COLUMN attachment_size BIGINT NULL, -ADD COLUMN attachment_data BYTEA NULL; +DO $$ +BEGIN + IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'messages' AND column_name = 'attachment_filename') THEN + ALTER TABLE messages ADD COLUMN attachment_filename TEXT NULL; + END IF; + + IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'messages' AND column_name = 'attachment_mimetype') THEN + ALTER TABLE messages ADD COLUMN attachment_mimetype TEXT NULL; + END IF; + + IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'messages' AND column_name = 'attachment_size') THEN + ALTER TABLE messages ADD COLUMN attachment_size BIGINT NULL; + END IF; + + IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'messages' AND column_name = 'attachment_data') THEN + ALTER TABLE messages ADD COLUMN attachment_data BYTEA NULL; + END IF; +END $$; -- Добавляем колонки для хранения файла и его метаданных в таблицу guest_messages -ALTER TABLE guest_messages -ADD COLUMN attachment_filename TEXT NULL, -ADD COLUMN attachment_mimetype TEXT NULL, -ADD COLUMN attachment_size BIGINT NULL, -ADD COLUMN attachment_data BYTEA NULL; +DO $$ +BEGIN + IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'guest_messages' AND column_name = 'attachment_filename') THEN + ALTER TABLE guest_messages ADD COLUMN attachment_filename TEXT NULL; + END IF; + + IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'guest_messages' AND column_name = 'attachment_mimetype') THEN + ALTER TABLE guest_messages ADD COLUMN attachment_mimetype TEXT NULL; + END IF; + + IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'guest_messages' AND column_name = 'attachment_size') THEN + ALTER TABLE guest_messages ADD COLUMN attachment_size BIGINT NULL; + END IF; + + IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'guest_messages' AND column_name = 'attachment_data') THEN + ALTER TABLE guest_messages ADD COLUMN attachment_data BYTEA NULL; + END IF; +END $$; -- Удаляем старую колонку attachments из таблицы messages, если она существует ALTER TABLE messages DROP COLUMN IF EXISTS attachments; @@ -36,7 +62,7 @@ DROP COLUMN IF EXISTS attachment_size, DROP COLUMN IF EXISTS attachment_data; -- Пытаемся вернуть старую колонку (данные будут потеряны при откате) -- Возможно, потребуется указать правильный тип (TEXT или JSONB), который был раньше -ALTER TABLE messages ADD COLUMN attachments TEXT NULL; +ALTER TABLE messages ADD COLUMN IF NOT EXISTS attachments TEXT NULL; ALTER TABLE guest_messages DROP COLUMN IF EXISTS attachment_filename, @@ -45,6 +71,6 @@ DROP COLUMN IF EXISTS attachment_size, DROP COLUMN IF EXISTS attachment_data; -- Пытаемся вернуть старую колонку (данные будут потеряны при откате) -- Возможно, потребуется указать правильный тип (TEXT или JSONB), который был раньше -ALTER TABLE guest_messages ADD COLUMN attachments TEXT NULL; +ALTER TABLE guest_messages ADD COLUMN IF NOT EXISTS attachments TEXT NULL; COMMIT; \ No newline at end of file diff --git a/backend/db/migrations/018_create_and_seed_isic_tables.sql b/backend/db/migrations/018_create_and_seed_isic_tables.sql index 7351033..56b2c3f 100644 --- a/backend/db/migrations/018_create_and_seed_isic_tables.sql +++ b/backend/db/migrations/018_create_and_seed_isic_tables.sql @@ -3,13 +3,13 @@ BEGIN; --- 1. Создаем таблицу для названий уровней ISIC +-- 1. Создаем таблицу для названий уровней ISIC (если не существует) CREATE TABLE IF NOT EXISTS isic_rev4_level_names ( code_level INTEGER PRIMARY KEY, - level_name_en TEXT + level_name_en_encrypted TEXT ); --- 2. Создаем основную таблицу для кодов ISIC +-- 2. Создаем основную таблицу для кодов ISIC (если не существует) CREATE TABLE IF NOT EXISTS isic_rev4_codes ( sort_order INTEGER, code VARCHAR(10) PRIMARY KEY, @@ -23,83 +23,98 @@ CREATE TABLE IF NOT EXISTS isic_rev4_codes ( level4 VARCHAR(10), level5 VARCHAR(10), level6 VARCHAR(10), - CONSTRAINT fk_code_level FOREIGN KEY (code_level) REFERENCES isic_rev4_level_names (code_level) -- Добавляем внешний ключ + CONSTRAINT fk_code_level FOREIGN KEY (code_level) REFERENCES isic_rev4_level_names (code_level) ); --- 3. Загружаем данные в isic_rev4_level_names --- ВАЖНО: Укажите АБСОЛЮТНЫЙ ПУТЬ к CSV файлу ВНУТРИ Docker-контейнера backend, --- где запущен PostgreSQL или откуда скрипт миграции имеет доступ к файлам. --- Если CSV лежат в backend/db/data/isic/ и ваш Dockerfile копирует всю директорию backend --- то путь может быть что-то вроде '/app/db/data/isic/isic_level_names.csv' --- (где /app - это WORKDIR в вашем Dockerfile для backend сервиса) --- Уточните этот путь! -COPY isic_rev4_level_names (code_level, level_name_en) -FROM '/mnt/isic_csv_data/isic_level_names.csv' -- <--- ПУТЬ СООТВЕТСТВУЕТ ТОМУ, ЧТО В volumes -WITH (FORMAT CSV, HEADER TRUE, DELIMITER ',', QUOTE '"'); +-- 3. Загружаем данные в isic_rev4_level_names только если таблица пустая +DO $$ +BEGIN + IF NOT EXISTS (SELECT 1 FROM isic_rev4_level_names LIMIT 1) THEN + -- Создаем временную таблицу для импорта + CREATE TEMP TABLE tmp_isic_level_names ( + code_level_tmp INTEGER, + level_name_en_tmp TEXT + ) ON COMMIT DROP; + + -- Загружаем данные во временную таблицу + COPY tmp_isic_level_names (code_level_tmp, level_name_en_tmp) + FROM '/app/db/data/isic_level_names.csv' + WITH (FORMAT CSV, HEADER TRUE, DELIMITER ',', QUOTE '"'); + + -- Вставляем данные в основную таблицу + INSERT INTO isic_rev4_level_names (code_level, level_name_en_encrypted) + SELECT code_level_tmp, level_name_en_tmp FROM tmp_isic_level_names; + END IF; +END $$; --- 4. Создаем временные таблицы для импорта основных данных ISIC -CREATE TEMP TABLE tmp_isic_titles ( - sort_order_tmp INTEGER, - code_tmp VARCHAR(10), - description_tmp TEXT, - inclusion_tmp TEXT, - exclusion_tmp TEXT -) ON COMMIT DROP; -- Временная таблица удалится после коммита +-- 4. Загружаем данные в isic_rev4_codes только если таблица пустая +DO $$ +BEGIN + IF NOT EXISTS (SELECT 1 FROM isic_rev4_codes LIMIT 1) THEN + -- Создаем временные таблицы для импорта основных данных ISIC + CREATE TEMP TABLE tmp_isic_titles ( + sort_order_tmp INTEGER, + code_tmp VARCHAR(10), + description_tmp TEXT, + inclusion_tmp TEXT, + exclusion_tmp TEXT + ) ON COMMIT DROP; -CREATE TEMP TABLE tmp_isic_structure ( - sort_order_tmp INTEGER, - code_tmp VARCHAR(10), - code_level_tmp INTEGER, - level1_tmp VARCHAR(10), - level2_tmp VARCHAR(10), - level3_tmp VARCHAR(10), - level4_tmp VARCHAR(10), - level5_tmp VARCHAR(10), - level6_tmp VARCHAR(10) -) ON COMMIT DROP; -- Временная таблица удалится после коммита + CREATE TEMP TABLE tmp_isic_structure ( + sort_order_tmp INTEGER, + code_tmp VARCHAR(10), + code_level_tmp INTEGER, + level1_tmp VARCHAR(10), + level2_tmp VARCHAR(10), + level3_tmp VARCHAR(10), + level4_tmp VARCHAR(10), + level5_tmp VARCHAR(10), + level6_tmp VARCHAR(10) + ) ON COMMIT DROP; --- 5. Загружаем данные во временные таблицы --- Опять же, укажите правильные АБСОЛЮТНЫЕ ПУТИ внутри контейнера -COPY tmp_isic_titles (sort_order_tmp, code_tmp, description_tmp, inclusion_tmp, exclusion_tmp) -FROM '/mnt/isic_csv_data/isic_titles.csv' -- <--- ПУТЬ СООТВЕТСТВУЕТ ТОМУ, ЧТО В volumes -WITH (FORMAT CSV, HEADER TRUE, DELIMITER ',', QUOTE '"'); + -- Загружаем данные во временные таблицы + COPY tmp_isic_titles (sort_order_tmp, code_tmp, description_tmp, inclusion_tmp, exclusion_tmp) + FROM '/app/db/data/isic_titles.csv' + WITH (FORMAT CSV, HEADER TRUE, DELIMITER ',', QUOTE '"'); -COPY tmp_isic_structure (sort_order_tmp, code_tmp, code_level_tmp, level1_tmp, level2_tmp, level3_tmp, level4_tmp, level5_tmp, level6_tmp) -FROM '/mnt/isic_csv_data/isic_structure.csv' -- <--- ПУТЬ СООТВЕТСТВУЕТ ТОМУ, ЧТО В volumes -WITH (FORMAT CSV, HEADER TRUE, DELIMITER ',', QUOTE '"'); + COPY tmp_isic_structure (sort_order_tmp, code_tmp, code_level_tmp, level1_tmp, level2_tmp, level3_tmp, level4_tmp, level5_tmp, level6_tmp) + FROM '/app/db/data/isic_structure.csv' + WITH (FORMAT CSV, HEADER TRUE, DELIMITER ',', QUOTE '"'); --- 6. Переносим и объединяем данные из временных таблиц в основную таблицу isic_rev4_codes -INSERT INTO isic_rev4_codes ( - sort_order, - code, - description, - explanatory_note_inclusion, - explanatory_note_exclusion, - code_level, - level1, - level2, - level3, - level4, - level5, - level6 -) -SELECT - COALESCE(t.sort_order_tmp, s.sort_order_tmp), - s.code_tmp, - t.description_tmp, - t.inclusion_tmp, - t.exclusion_tmp, - s.code_level_tmp, - s.level1_tmp, - s.level2_tmp, - s.level3_tmp, - s.level4_tmp, - s.level5_tmp, - s.level6_tmp -FROM - tmp_isic_structure s -LEFT JOIN - tmp_isic_titles t ON s.code_tmp = t.code_tmp; + -- Переносим и объединяем данные из временных таблиц в основную таблицу isic_rev4_codes + INSERT INTO isic_rev4_codes ( + sort_order, + code, + description, + explanatory_note_inclusion, + explanatory_note_exclusion, + code_level, + level1, + level2, + level3, + level4, + level5, + level6 + ) + SELECT + COALESCE(t.sort_order_tmp, s.sort_order_tmp), + s.code_tmp, + t.description_tmp, + t.inclusion_tmp, + t.exclusion_tmp, + s.code_level_tmp, + s.level1_tmp, + s.level2_tmp, + s.level3_tmp, + s.level4_tmp, + s.level5_tmp, + s.level6_tmp + FROM + tmp_isic_structure s + LEFT JOIN + tmp_isic_titles t ON s.code_tmp = t.code_tmp; + END IF; +END $$; COMMIT; diff --git a/backend/db/migrations/020_create_email_settings.sql b/backend/db/migrations/020_create_email_settings.sql index 3cfadcb..d0d5030 100644 --- a/backend/db/migrations/020_create_email_settings.sql +++ b/backend/db/migrations/020_create_email_settings.sql @@ -1,17 +1,18 @@ +-- Создаем таблицу email_settings если она не существует CREATE TABLE IF NOT EXISTS email_settings ( id SERIAL PRIMARY KEY, - smtp_host VARCHAR(255) NOT NULL, + smtp_host_encrypted TEXT, smtp_port INTEGER NOT NULL, - smtp_user VARCHAR(255) NOT NULL, - smtp_password VARCHAR(255) NOT NULL, - imap_host VARCHAR(255), + smtp_user_encrypted TEXT, + smtp_password_encrypted TEXT, + imap_host_encrypted TEXT, imap_port INTEGER, - from_email VARCHAR(255) NOT NULL, + from_email_encrypted TEXT, created_at TIMESTAMP NOT NULL DEFAULT NOW(), updated_at TIMESTAMP NOT NULL DEFAULT NOW() ); --- Для простоты предполагаем, что настройки всегда одни (id=1) -INSERT INTO email_settings (smtp_host, smtp_port, smtp_user, smtp_password, imap_host, imap_port, from_email) -VALUES ('smtp.example.com', 465, 'user@example.com', 'password', 'imap.example.com', 993, 'noreply@example.com') -ON CONFLICT DO NOTHING; \ No newline at end of file +-- Пропускаем INSERT, так как данные должны быть зашифрованы +-- INSERT INTO email_settings (smtp_host, smtp_port, smtp_user, smtp_password, imap_host, imap_port, from_email) +-- VALUES ('smtp.example.com', 465, 'user@example.com', 'password', 'imap.example.com', 993, 'noreply@example.com') +-- ON CONFLICT DO NOTHING; \ No newline at end of file diff --git a/backend/db/migrations/021_create_telegram_settings.sql b/backend/db/migrations/021_create_telegram_settings.sql index ad43212..8db4f71 100644 --- a/backend/db/migrations/021_create_telegram_settings.sql +++ b/backend/db/migrations/021_create_telegram_settings.sql @@ -1,12 +1,13 @@ +-- Создаем таблицу telegram_settings если она не существует CREATE TABLE IF NOT EXISTS telegram_settings ( id SERIAL PRIMARY KEY, - bot_token VARCHAR(255) NOT NULL, - bot_username VARCHAR(255) NOT NULL, + bot_token_encrypted TEXT, + bot_username_encrypted TEXT, created_at TIMESTAMP NOT NULL DEFAULT NOW(), updated_at TIMESTAMP NOT NULL DEFAULT NOW() ); --- Для простоты предполагаем, что настройки всегда одни (id=1) -INSERT INTO telegram_settings (bot_token, bot_username) -VALUES ('your-telegram-bot-token', 'your_bot_username') -ON CONFLICT DO NOTHING; \ No newline at end of file +-- Пропускаем INSERT, так как данные должны быть зашифрованы +-- INSERT INTO telegram_settings (bot_token, bot_username) +-- VALUES ('your-telegram-bot-token', 'your_bot_username') +-- ON CONFLICT DO NOTHING; \ No newline at end of file diff --git a/backend/db/migrations/022_create_db_settings.sql b/backend/db/migrations/022_create_db_settings.sql index 39b35b7..3255e93 100644 --- a/backend/db/migrations/022_create_db_settings.sql +++ b/backend/db/migrations/022_create_db_settings.sql @@ -1,15 +1,16 @@ +-- Создаем таблицу db_settings если она не существует CREATE TABLE IF NOT EXISTS db_settings ( id SERIAL PRIMARY KEY, - db_host VARCHAR(255) NOT NULL, + db_host_encrypted TEXT, db_port INTEGER NOT NULL, - db_name VARCHAR(255) NOT NULL, - db_user VARCHAR(255) NOT NULL, - db_password VARCHAR(255) NOT NULL, + db_name_encrypted TEXT, + db_user_encrypted TEXT, + db_password_encrypted TEXT, created_at TIMESTAMP NOT NULL DEFAULT NOW(), updated_at TIMESTAMP NOT NULL DEFAULT NOW() ); --- Для простоты предполагаем, что настройки всегда одни (id=1) -INSERT INTO db_settings (db_host, db_port, db_name, db_user, db_password) -VALUES ('postgres', 5432, 'dapp_db', 'dapp_user', 'dapp_password') -ON CONFLICT DO NOTHING; \ No newline at end of file +-- Пропускаем INSERT, так как данные должны быть зашифрованы +-- INSERT INTO db_settings (db_host, db_port, db_name, db_user, db_password) +-- VALUES ('postgres', 5432, 'dapp_db', 'dapp_user', 'dapp_password') +-- ON CONFLICT DO NOTHING; \ No newline at end of file diff --git a/backend/db/migrations/023_create_ai_providers_settings.sql b/backend/db/migrations/023_create_ai_providers_settings.sql index 4163f33..a6a0e50 100644 --- a/backend/db/migrations/023_create_ai_providers_settings.sql +++ b/backend/db/migrations/023_create_ai_providers_settings.sql @@ -1,14 +1,16 @@ +-- Создаем таблицу ai_providers_settings если она не существует CREATE TABLE IF NOT EXISTS ai_providers_settings ( id SERIAL PRIMARY KEY, - provider VARCHAR(32) NOT NULL UNIQUE, -- openai, anthropic, google, ollama - api_key VARCHAR(255), - base_url VARCHAR(255), - selected_model VARCHAR(128), + provider_encrypted TEXT, + api_key_encrypted TEXT, + base_url_encrypted TEXT, + selected_model_encrypted TEXT, + embedding_model_encrypted TEXT, created_at TIMESTAMP NOT NULL DEFAULT NOW(), updated_at TIMESTAMP NOT NULL DEFAULT NOW() ); --- Пример заполнения для Ollama (без ключа) -INSERT INTO ai_providers_settings (provider, base_url, selected_model) -VALUES ('ollama', 'http://localhost:11434', 'qwen2.5') -ON CONFLICT (provider) DO NOTHING; \ No newline at end of file +-- Пропускаем INSERT, так как данные должны быть зашифрованы +-- INSERT INTO ai_providers_settings (provider, base_url, selected_model) +-- VALUES ('ollama', 'http://localhost:11434', 'qwen2.5') +-- ON CONFLICT (provider) DO NOTHING; \ No newline at end of file diff --git a/backend/db/migrations/029_create_ai_assistant_settings.sql b/backend/db/migrations/029_create_ai_assistant_settings.sql index e4db098..dba246c 100644 --- a/backend/db/migrations/029_create_ai_assistant_settings.sql +++ b/backend/db/migrations/029_create_ai_assistant_settings.sql @@ -1,21 +1,22 @@ +-- Создаем таблицу ai_assistant_settings если она не существует CREATE TABLE IF NOT EXISTS ai_assistant_settings ( id SERIAL PRIMARY KEY, - system_prompt TEXT, + system_prompt_encrypted TEXT, selected_rag_tables INTEGER[], languages TEXT[], - model TEXT, + model_encrypted TEXT, rules JSONB, updated_at TIMESTAMP DEFAULT NOW(), updated_by INTEGER ); --- Вставить дефолтную строку (глобальные настройки) -INSERT INTO ai_assistant_settings (system_prompt, selected_rag_tables, languages, model, rules) -VALUES ( - 'Вы — полезный ассистент. Отвечайте на русском языке.', - ARRAY[]::INTEGER[], - ARRAY['ru'], - 'qwen2.5', - '{"checkUserTags": true, "searchRagFirst": true, "generateIfNoRag": true, "requireAdminApproval": true}' -) -ON CONFLICT DO NOTHING; \ No newline at end of file +-- Пропускаем INSERT, так как данные должны быть зашифрованы +-- INSERT INTO ai_assistant_settings (system_prompt, selected_rag_tables, languages, model, rules) +-- VALUES ( +-- 'Вы — полезный ассистент. Отвечайте на русском языке.', +-- ARRAY[]::INTEGER[], +-- ARRAY['ru'], +-- 'qwen2.5', +-- '{"checkUserTags": true, "searchRagFirst": true, "generateIfNoRag": true, "requireAdminApproval": true}' +-- ) +-- ON CONFLICT DO NOTHING; \ No newline at end of file diff --git a/backend/db/migrations/032_create_is_rag_source_table.sql b/backend/db/migrations/032_create_is_rag_source_table.sql index 81b8d8c..a6a41dd 100644 --- a/backend/db/migrations/032_create_is_rag_source_table.sql +++ b/backend/db/migrations/032_create_is_rag_source_table.sql @@ -1,11 +1,11 @@ -- Создание справочной таблицы is_rag_source CREATE TABLE IF NOT EXISTS is_rag_source ( id SERIAL PRIMARY KEY, - name VARCHAR(64) NOT NULL UNIQUE + name_encrypted TEXT ); --- Заполнение начальными значениями -INSERT INTO is_rag_source (name) VALUES - ('Да'), - ('Нет') -ON CONFLICT (name) DO NOTHING; \ No newline at end of file +-- Пропускаем INSERT, так как данные должны быть зашифрованы +-- INSERT INTO is_rag_source (name) VALUES +-- ('Да'), +-- ('Нет') +-- ON CONFLICT (name) DO NOTHING; \ No newline at end of file diff --git a/backend/db/migrations/033_add_is_rag_source_id_to_user_tables.sql b/backend/db/migrations/033_add_is_rag_source_id_to_user_tables.sql index ee1bcc3..e49a4fb 100644 --- a/backend/db/migrations/033_add_is_rag_source_id_to_user_tables.sql +++ b/backend/db/migrations/033_add_is_rag_source_id_to_user_tables.sql @@ -1,2 +1,11 @@ -ALTER TABLE user_tables -ADD COLUMN is_rag_source_id INTEGER REFERENCES is_rag_source(id) DEFAULT 2; -- 2 = 'Нет' \ No newline at end of file +-- Добавляем колонку is_rag_source_id если она не существует +DO $$ +BEGIN + IF NOT EXISTS ( + SELECT 1 FROM information_schema.columns + WHERE table_name = 'user_tables' AND column_name = 'is_rag_source_id' + ) THEN + ALTER TABLE user_tables + ADD COLUMN is_rag_source_id INTEGER REFERENCES is_rag_source(id) DEFAULT 2; -- 2 = 'Нет' + END IF; +END $$; \ No newline at end of file diff --git a/backend/db/migrations/034_add_options_to_user_columns.sql b/backend/db/migrations/034_add_options_to_user_columns.sql new file mode 100644 index 0000000..833a437 --- /dev/null +++ b/backend/db/migrations/034_add_options_to_user_columns.sql @@ -0,0 +1,5 @@ +-- Добавляем колонку options в таблицу user_columns +ALTER TABLE user_columns ADD COLUMN IF NOT EXISTS options JSONB DEFAULT '{}'::jsonb; + +-- Создаем индекс для быстрого поиска по options +CREATE INDEX IF NOT EXISTS idx_user_columns_options ON user_columns USING GIN (options); \ No newline at end of file diff --git a/backend/db/migrations/037_seed_rpc_and_auth_tokens.sql b/backend/db/migrations/037_seed_rpc_and_auth_tokens.sql index 87f2621..3d47cc5 100644 --- a/backend/db/migrations/037_seed_rpc_and_auth_tokens.sql +++ b/backend/db/migrations/037_seed_rpc_and_auth_tokens.sql @@ -1,21 +1,22 @@ -- Миграция: наполнение таблиц rpc_providers и auth_tokens начальными значениями +-- Пропускаем INSERT, так как данные должны быть зашифрованы --- Добавление RPC-провайдеров -INSERT INTO rpc_providers (network_id, rpc_url, chain_id) -VALUES - ('bsc', 'https://bsc-mainnet.nodereal.io/v1/56dec8028bae4f26b76099a42dae2b52', 56), - ('ethereum', 'https://eth-mainnet.nodereal.io/v1/56dec8028bae4f26b76099a42dae2b52', 1), - ('arbitrum', 'https://arb1.arbitrum.io/rpc', 42161), - ('polygon', 'https://polygon.drpc.org', 137), - ('sepolia', 'https://eth-sepolia.nodereal.io/v1/56dec8028bae4f26b76099a42dae2b52', 11155111) -ON CONFLICT (network_id) DO NOTHING; +-- Добавление RPC-провайдеров (пропускаем, данные должны быть зашифрованы) +-- INSERT INTO rpc_providers (network_id, rpc_url, chain_id) +-- VALUES +-- ('bsc', 'https://bsc-mainnet.nodereal.io/v1/56dec8028bae4f26b76099a42dae2b52', 56), +-- ('ethereum', 'https://eth-mainnet.nodereal.io/v1/56dec8028bae4f26b76099a42dae2b52', 1), +-- ('arbitrum', 'https://arb1.arbitrum.io/rpc', 42161), +-- ('polygon', 'https://polygon.drpc.org', 137), +-- ('sepolia', 'https://eth-sepolia.nodereal.io/v1/56dec8028bae4f26b76099a42dae2b52', 11155111) +-- ON CONFLICT (network_id) DO NOTHING; --- Добавление токенов для аутентификации админа -INSERT INTO auth_tokens (name, address, network, min_balance) -VALUES - ('HB3A', '0x4b294265720b09ca39bfba18c7e368413c0f68eb', 'bsc', 10.0), - ('HB3A', '0xd95a45fc46a7300e6022885afec3d618d7d3f27c', 'ethereum', 10.0), - ('test2', '0xef49261169B454f191678D2aFC5E91Ad2e85dfD8', 'sepolia', 50.0), - ('HB3A', '0x351f59de4fedbdf7601f5592b93db3b9330c1c1d', 'polygon', 10.0), - ('HB3A', '0xdCe769b847a0a697239777D0B1C7dd33b6012ba0', 'arbitrum', 100.0) -ON CONFLICT (address, network) DO NOTHING; \ No newline at end of file +-- Добавление токенов для аутентификации админа (пропускаем, данные должны быть зашифрованы) +-- INSERT INTO auth_tokens (name, address, network, min_balance) +-- VALUES +-- ('HB3A', '0x4b294265720b09ca39bfba18c7e368413c0f68eb', 'bsc', 10.0), +-- ('HB3A', '0xd95a45fc46a7300e6022885afec3d618d7d3f27c', 'ethereum', 10.0), +-- ('test2', '0xef49261169B454f191678D2aFC5E91Ad2e85dfD8', 'sepolia', 50.0), +-- ('HB3A', '0x351f59de4fedbdf7601f5592b93db3b9330c1c1d', 'polygon', 10.0), +-- ('HB3A', '0xdCe769b847a0a697239777D0B1C7dd33b6012ba0', 'arbitrum', 100.0) +-- ON CONFLICT (address, network) DO NOTHING; \ No newline at end of file diff --git a/backend/db/migrations/048_add_order_to_user_rows.sql b/backend/db/migrations/048_add_order_to_user_rows.sql index 3b48030..212bf98 100644 --- a/backend/db/migrations/048_add_order_to_user_rows.sql +++ b/backend/db/migrations/048_add_order_to_user_rows.sql @@ -1,16 +1,24 @@ -- 048_add_order_to_user_rows.sql -- Добавляет поле order в user_rows для поддержки сортировки строк -ALTER TABLE user_rows ADD COLUMN "order" INTEGER DEFAULT 0; - --- Проставить уникальные значения order для существующих строк (по id) +-- Добавляем колонку order если она не существует DO $$ -DECLARE - r RECORD; - idx INTEGER := 1; BEGIN - FOR r IN SELECT id FROM user_rows ORDER BY id LOOP - UPDATE user_rows SET "order" = idx WHERE id = r.id; - idx := idx + 1; - END LOOP; -END$$; \ No newline at end of file + IF NOT EXISTS ( + SELECT 1 FROM information_schema.columns + WHERE table_name = 'user_rows' AND column_name = 'order' + ) THEN + ALTER TABLE user_rows ADD COLUMN "order" INTEGER DEFAULT 0; + + -- Проставить уникальные значения order для существующих строк (по id) + DECLARE + r RECORD; + idx INTEGER := 1; + BEGIN + FOR r IN SELECT id FROM user_rows ORDER BY id LOOP + UPDATE user_rows SET "order" = idx WHERE id = r.id; + idx := idx + 1; + END LOOP; + END; + END IF; +END $$; \ No newline at end of file diff --git a/backend/db/migrations/fix_duplicates_manual.sql b/backend/db/migrations/fix_duplicates_manual.sql index bcc4cbc..fcf1446 100644 --- a/backend/db/migrations/fix_duplicates_manual.sql +++ b/backend/db/migrations/fix_duplicates_manual.sql @@ -1,40 +1,8 @@ -- Скрипт для ручного исправления дублирующихся записей в базе данных +-- Пропускаем операции с зашифрованными колонками --- 1. Удаляем существующее ограничение уникальности -ALTER TABLE user_identities DROP CONSTRAINT IF EXISTS user_identities_provider_provider_id_key; - --- 2. Получаем список идентификаторов с дублирующимися записями -SELECT - provider, - LOWER(provider_id) as normalized_provider_id, - array_agg(id) as id_list -FROM user_identities -WHERE provider IN ('wallet', 'email') -GROUP BY provider, LOWER(provider_id) -HAVING COUNT(*) > 1; - --- 3. Удаляем конкретные дублирующиеся записи по ID (например, ID=2) -DELETE FROM user_identities WHERE id = 2; - --- 4. Обновляем все записи email и wallet к нижнему регистру -UPDATE user_identities -SET provider_id = LOWER(provider_id) -WHERE provider IN ('wallet', 'email'); - --- 5. Проверяем, что дубликаты удалены -SELECT - provider, - provider_id, - COUNT(*) as count -FROM user_identities -GROUP BY provider, provider_id -HAVING COUNT(*) > 1; - --- 6. Добавляем обратно ограничение уникальности -ALTER TABLE user_identities - ADD CONSTRAINT user_identities_provider_provider_id_key - UNIQUE (provider, provider_id); - --- 7. Создаем дополнительный индекс для (user_id, provider, provider_id) -CREATE UNIQUE INDEX IF NOT EXISTS unique_idx_user_identities_user_provider_provider_id -ON user_identities(user_id, provider, provider_id); \ No newline at end of file +-- Логируем завершение миграции +DO $$ +BEGIN + RAISE NOTICE 'Миграция fix_duplicates_manual.sql пропущена (колонки зашифрованы)'; +END $$; \ No newline at end of file diff --git a/backend/middleware/auth.js b/backend/middleware/auth.js index 4420b16..799f473 100644 --- a/backend/middleware/auth.js +++ b/backend/middleware/auth.js @@ -19,6 +19,20 @@ const { USER_ROLES } = require('../utils/constants'); const db = require('../db'); const { checkAdminTokens } = require('../services/auth-service'); +// Получаем ключ шифрования +const fs = require('fs'); +const path = require('path'); +let encryptionKey = 'default-key'; + +try { + const keyPath = path.join(__dirname, '../ssl/keys/full_db_encryption.key'); + if (fs.existsSync(keyPath)) { + encryptionKey = fs.readFileSync(keyPath, 'utf8').trim(); + } +} catch (keyError) { + console.error('Error reading encryption key:', keyError); +} + /** * Middleware для проверки аутентификации */ diff --git a/backend/package.json b/backend/package.json index d19b1d6..d7414d2 100644 --- a/backend/package.json +++ b/backend/package.json @@ -31,11 +31,13 @@ "@openzeppelin/contracts": "5.2.0", "archiver": "^7.0.1", "axios": "^1.8.4", + "better-queue": "^3.8.12", "connect-pg-simple": "^10.0.0", "cookie": "^1.0.2", "cors": "^2.8.5", "cron": "^4.1.0", "csurf": "^1.11.0", + "csv-parser": "^3.0.0", "dotenv": "^16.0.3", "ethers": "6.13.5", "express": "^4.21.2", @@ -59,8 +61,7 @@ "utf7": "^1.0.2", "viem": "^2.23.15", "winston": "^3.17.0", - "ws": "^8.18.1", - "csv-parser": "^3.0.0" + "ws": "^8.18.1" }, "devDependencies": { "@nomicfoundation/hardhat-chai-matchers": "^2.0.0", diff --git a/backend/routes/ai-queue.js b/backend/routes/ai-queue.js new file mode 100644 index 0000000..6513615 --- /dev/null +++ b/backend/routes/ai-queue.js @@ -0,0 +1,188 @@ +/** + * 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 + */ + +const express = require('express'); +const router = express.Router(); +const aiQueueService = require('../services/ai-queue'); +const { requireAuth } = require('../middleware/auth'); +const logger = require('../utils/logger'); + +// Получение статистики очереди +router.get('/stats', requireAuth, async (req, res) => { + try { + const stats = aiQueueService.getStats(); + res.json({ + success: true, + data: stats + }); + } catch (error) { + logger.error('[AIQueue] Error getting stats:', error); + res.status(500).json({ + success: false, + error: 'Failed to get queue statistics' + }); + } +}); + +// Добавление задачи в очередь +router.post('/task', requireAuth, async (req, res) => { + try { + const { message, language, history, systemPrompt, rules, type = 'chat' } = req.body; + const userId = req.session.userId; + const userRole = req.session.isAdmin ? 'admin' : 'user'; + + if (!message) { + return res.status(400).json({ + success: false, + error: 'Message is required' + }); + } + + const taskData = { + message, + language: language || 'auto', + history: history || null, + systemPrompt: systemPrompt || '', + rules: rules || null, + type, + userId, + userRole, + requestId: req.body.requestId || null + }; + + const result = await aiQueueService.addTask(taskData); + + res.json({ + success: true, + data: { + taskId: result.taskId, + status: 'queued', + estimatedWaitTime: aiQueueService.getStats().currentQueueSize * 30 // Примерное время ожидания + } + }); + + } catch (error) { + logger.error('[AIQueue] Error adding task:', error); + res.status(500).json({ + success: false, + error: error.message || 'Failed to add task to queue' + }); + } +}); + +// Получение статуса задачи +router.get('/task/:taskId', requireAuth, async (req, res) => { + try { + const { taskId } = req.params; + const stats = aiQueueService.getStats(); + + // Простая реализация - в реальном проекте нужно хранить статусы задач + res.json({ + success: true, + data: { + taskId, + status: 'processing', // Упрощенная реализация + queuePosition: stats.currentQueueSize, + estimatedWaitTime: stats.currentQueueSize * 30 + } + }); + } catch (error) { + logger.error('[AIQueue] Error getting task status:', error); + res.status(500).json({ + success: false, + error: 'Failed to get task status' + }); + } +}); + +// Управление очередью (только для администраторов) +router.post('/control', requireAuth, async (req, res) => { + try { + const { action } = req.body; + + if (!req.session.isAdmin) { + return res.status(403).json({ + success: false, + error: 'Admin access required' + }); + } + + switch (action) { + case 'pause': + aiQueueService.pause(); + res.json({ + success: true, + message: 'Queue paused' + }); + break; + + case 'resume': + aiQueueService.resume(); + res.json({ + success: true, + message: 'Queue resumed' + }); + break; + + case 'clear': + aiQueueService.clear(); + res.json({ + success: true, + message: 'Queue cleared' + }); + break; + + default: + res.status(400).json({ + success: false, + error: 'Invalid action. Use: pause, resume, or clear' + }); + } + } catch (error) { + logger.error('[AIQueue] Error controlling queue:', error); + res.status(500).json({ + success: false, + error: 'Failed to control queue' + }); + } +}); + +// Получение информации о производительности +router.get('/performance', requireAuth, async (req, res) => { + try { + const stats = aiQueueService.getStats(); + + const performance = { + successRate: stats.totalProcessed > 0 ? + ((stats.totalProcessed - stats.totalFailed) / stats.totalProcessed * 100).toFixed(2) : 0, + averageProcessingTime: Math.round(stats.averageProcessingTime), + totalProcessed: stats.totalProcessed, + totalFailed: stats.totalFailed, + currentQueueSize: stats.currentQueueSize, + runningTasks: stats.runningTasks, + lastProcessedAt: stats.lastProcessedAt + }; + + res.json({ + success: true, + data: performance + }); + } catch (error) { + logger.error('[AIQueue] Error getting performance:', error); + res.status(500).json({ + success: false, + error: 'Failed to get performance data' + }); + } +}); + +module.exports = router; \ No newline at end of file diff --git a/backend/routes/auth.js b/backend/routes/auth.js index 32fb92a..0798548 100644 --- a/backend/routes/auth.js +++ b/backend/routes/auth.js @@ -14,6 +14,7 @@ const express = require('express'); const router = express.Router(); const crypto = require('crypto'); const db = require('../db'); +const encryptedDb = require('../services/encryptedDatabaseService'); const logger = require('../utils/logger'); const rateLimit = require('express-rate-limit'); const { requireAuth } = require('../middleware/auth'); @@ -44,24 +45,49 @@ router.get('/nonce', async (req, res) => { // Генерируем случайный nonce const nonce = crypto.randomBytes(16).toString('hex'); + logger.info(`[nonce] Generated nonce: ${nonce}`); - // Проверяем, существует ли уже nonce для этого адреса - const existingNonce = await db.getQuery()('SELECT id FROM nonces WHERE identity_value = $1', [ - address.toLowerCase(), - ]); + // Используем правильный ключ шифрования + const fs = require('fs'); + const path = require('path'); + let encryptionKey = 'default-key'; + + try { + const keyPath = path.join(__dirname, '../ssl/keys/full_db_encryption.key'); + if (fs.existsSync(keyPath)) { + encryptionKey = fs.readFileSync(keyPath, 'utf8').trim(); + logger.info(`[nonce] Using encryption key: ${encryptionKey.substring(0, 10)}...`); + } + } catch (keyError) { + console.error('Error reading encryption key:', keyError); + } + + try { + // Проверяем, существует ли уже nonce для этого адреса + const existingNonces = await db.getQuery()( + 'SELECT id FROM nonces WHERE identity_value_encrypted = encrypt_text($1, $2)', + [address.toLowerCase(), encryptionKey] + ); - if (existingNonce.rows.length > 0) { - // Обновляем существующий nonce - await db.getQuery()( - "UPDATE nonces SET nonce = $1, expires_at = NOW() + INTERVAL '15 minutes' WHERE identity_value = $2", - [nonce, address.toLowerCase()] - ); - } else { - // Создаем новый nonce - await db.getQuery()( - "INSERT INTO nonces (identity_value, nonce, expires_at) VALUES ($1, $2, NOW() + INTERVAL '15 minutes')", - [address.toLowerCase(), nonce] - ); + if (existingNonces.rows.length > 0) { + // Обновляем существующий nonce + logger.info(`[nonce] Updating existing nonce for address: ${address.toLowerCase()}`); + await db.getQuery()( + 'UPDATE nonces SET nonce_encrypted = encrypt_text($1, $2), expires_at = $3 WHERE id = $4', + [nonce, encryptionKey, new Date(Date.now() + 15 * 60 * 1000), existingNonces.rows[0].id] + ); + } else { + // Создаем новый nonce + logger.info(`[nonce] Creating new nonce for address: ${address.toLowerCase()}`); + await db.getQuery()( + 'INSERT INTO nonces (identity_value_encrypted, nonce_encrypted, expires_at) VALUES (encrypt_text($1, $2), encrypt_text($3, $2), $4)', + [address.toLowerCase(), encryptionKey, nonce, new Date(Date.now() + 15 * 60 * 1000)] + ); + } + } catch (dbError) { + console.error('Database error:', dbError); + // Fallback: просто возвращаем nonce без сохранения в БД + logger.warn(`Nonce ${nonce} generated for address ${address} but not saved to DB due to error`); } logger.info(`Nonce ${nonce} сохранен для адреса ${address}`); @@ -76,34 +102,96 @@ router.get('/nonce', async (req, res) => { // Верификация подписи и создание сессии router.post('/verify', async (req, res) => { try { - const { address, message, signature } = req.body; + const { address, signature, nonce, issuedAt } = req.body; logger.info(`[verify] Verifying signature for address: ${address}`); + logger.info(`[verify] Request body:`, JSON.stringify(req.body, null, 2)); + logger.info(`[verify] Request headers:`, JSON.stringify(req.headers, null, 2)); + logger.info(`[verify] Raw request body:`, req.body); + logger.info(`[verify] Request body type:`, typeof req.body); + logger.info(`[verify] Request body keys:`, Object.keys(req.body || {})); + logger.info(`[verify] Nonce from request: ${nonce}`); + logger.info(`[verify] Address from request: ${address}`); + logger.info(`[verify] Signature from request: ${signature}`); // Сохраняем гостевые ID до проверки const guestId = req.session.guestId; const previousGuestId = req.session.previousGuestId; - // Проверяем подпись - const isValid = await authService.verifySignature(message, signature, address); - if (!isValid) { - return res.status(401).json({ success: false, error: 'Invalid signature' }); + // Нормализуем адрес для использования в запросах + const normalizedAddress = ethers.getAddress(address); + const normalizedAddressLower = normalizedAddress.toLowerCase(); + + // Читаем ключ шифрования + const fs = require('fs'); + const path = require('path'); + let encryptionKey = 'default-key'; + + try { + const keyPath = path.join(__dirname, '../ssl/keys/full_db_encryption.key'); + if (fs.existsSync(keyPath)) { + encryptionKey = fs.readFileSync(keyPath, 'utf8').trim(); + } + } catch (keyError) { + console.error('Error reading encryption key:', keyError); } - // Нормализуем адрес для использования в запросах - const normalizedAddress = ethers.getAddress(address).toLowerCase(); + // Проверяем nonce в базе данных + const nonceResult = await db.getQuery()( + 'SELECT nonce_encrypted FROM nonces WHERE identity_value_encrypted = encrypt_text($1, $2)', + [normalizedAddressLower, encryptionKey] + ); + + if (nonceResult.rows.length === 0) { + logger.error(`[verify] Nonce not found for address: ${normalizedAddressLower}`); + return res.status(401).json({ success: false, error: 'Nonce not found' }); + } - // Проверяем nonce - const nonceResult = await db.getQuery()('SELECT nonce FROM nonces WHERE identity_value = $1', [ - normalizedAddress, - ]); - if ( - nonceResult.rows.length === 0 || - nonceResult.rows[0].nonce !== message.match(/Nonce: ([^\n]+)/)[1] - ) { + // Расшифровываем nonce из базы данных + const storedNonce = await db.getQuery()( + 'SELECT decrypt_text(nonce_encrypted, $1) as nonce FROM nonces WHERE identity_value_encrypted = encrypt_text($2, $1)', + [encryptionKey, normalizedAddressLower] + ); + + logger.info(`[verify] Stored nonce from DB: ${storedNonce.rows[0]?.nonce}`); + logger.info(`[verify] Nonce from request: ${nonce}`); + logger.info(`[verify] Nonce match: ${storedNonce.rows[0]?.nonce === nonce}`); + + if (storedNonce.rows.length === 0 || storedNonce.rows[0].nonce !== nonce) { + logger.error(`[verify] Invalid nonce for address: ${normalizedAddressLower}. Expected: ${storedNonce.rows[0]?.nonce}, Got: ${nonce}`); return res.status(401).json({ success: false, error: 'Invalid nonce' }); } + // Создаем SIWE сообщение для проверки подписи + const domain = 'localhost:5173'; // Используем тот же домен, что и на frontend + const origin = req.get('origin') || 'http://localhost:5173'; + + const { SiweMessage } = require('siwe'); + const message = new SiweMessage({ + domain, + address: normalizedAddress, + statement: 'Sign in with Ethereum to the app.', + uri: origin, + version: '1', + chainId: 1, + nonce: nonce, + issuedAt: issuedAt || new Date().toISOString(), + resources: [`${origin}/api/auth/verify`], + }); + + const messageToSign = message.prepareMessage(); + + logger.info(`[verify] SIWE message for verification: ${messageToSign}`); + logger.info(`[verify] Domain: ${domain}, Origin: ${origin}`); + logger.info(`[verify] Normalized address: ${normalizedAddress}`); + + // Проверяем подпись + const isValid = await authService.verifySignature(messageToSign, signature, normalizedAddress); + if (!isValid) { + logger.error(`[verify] Invalid signature for address: ${normalizedAddress}`); + return res.status(401).json({ success: false, error: 'Invalid signature' }); + } + let userId; let isAdmin = false; diff --git a/backend/routes/chat.js b/backend/routes/chat.js index ede19e1..92e9f6f 100644 --- a/backend/routes/chat.js +++ b/backend/routes/chat.js @@ -14,14 +14,16 @@ const express = require('express'); const router = express.Router(); const multer = require('multer'); const aiAssistant = require('../services/ai-assistant'); +const aiQueueService = require('../services/ai-queue'); // Добавляем импорт AI Queue сервиса const db = require('../db'); +const encryptedDb = require('../services/encryptedDatabaseService'); const logger = require('../utils/logger'); const { requireAuth } = require('../middleware/auth'); const crypto = require('crypto'); const aiAssistantSettingsService = require('../services/aiAssistantSettingsService'); const aiAssistantRulesService = require('../services/aiAssistantRulesService'); const { isUserBlocked } = require('../utils/userUtils'); -const { broadcastChatMessage } = require('../wsHub'); +const { broadcastChatMessage, broadcastConversationUpdate } = require('../wsHub'); // Настройка multer для обработки файлов в памяти const storage = multer.memoryStorage(); @@ -32,10 +34,24 @@ async function processGuestMessages(userId, guestId) { try { logger.info(`Processing guest messages for user ${userId} with guest ID ${guestId}`); + // Получаем ключ шифрования + const fs = require('fs'); + const path = require('path'); + let encryptionKey = 'default-key'; + + try { + const keyPath = path.join(__dirname, '../ssl/keys/full_db_encryption.key'); + if (fs.existsSync(keyPath)) { + encryptionKey = fs.readFileSync(keyPath, 'utf8').trim(); + } + } catch (keyError) { + console.error('Error reading encryption key:', keyError); + } + // Проверяем, обрабатывались ли уже эти сообщения const mappingCheck = await db.getQuery()( - 'SELECT processed FROM guest_user_mapping WHERE guest_id = $1', - [guestId] + 'SELECT processed FROM guest_user_mapping WHERE guest_id_encrypted = encrypt_text($1, $2)', + [guestId, encryptionKey] ); // Если сообщения уже обработаны, пропускаем @@ -47,8 +63,8 @@ async function processGuestMessages(userId, guestId) { // Проверяем наличие mapping записи и создаем если нет if (mappingCheck.rows.length === 0) { await db.getQuery()( - 'INSERT INTO guest_user_mapping (user_id, guest_id) VALUES ($1, $2) ON CONFLICT (guest_id) DO UPDATE SET user_id = $1', - [userId, guestId] + 'INSERT INTO guest_user_mapping (user_id, guest_id_encrypted) VALUES ($1, encrypt_text($2, $3)) ON CONFLICT (guest_id_encrypted) DO UPDATE SET user_id = $1', + [userId, guestId, encryptionKey] ); logger.info(`Created mapping for guest ID ${guestId} to user ${userId}`); } @@ -56,17 +72,17 @@ async function processGuestMessages(userId, guestId) { // Получаем все гостевые сообщения со всеми новыми полями const guestMessagesResult = await db.getQuery()( `SELECT - id, guest_id, content, language, is_ai, created_at, - attachment_filename, attachment_mimetype, attachment_size, attachment_data - FROM guest_messages WHERE guest_id = $1 ORDER BY created_at ASC`, - [guestId] + id, decrypt_text(guest_id_encrypted, $2) as guest_id, decrypt_text(content_encrypted, $2) as content, decrypt_text(language_encrypted, $2) as language, is_ai, created_at, + decrypt_text(attachment_filename_encrypted, $2) as attachment_filename, decrypt_text(attachment_mimetype_encrypted, $2) as attachment_mimetype, attachment_size, attachment_data + FROM guest_messages WHERE guest_id_encrypted = encrypt_text($1, $2) ORDER BY created_at ASC`, + [guestId, encryptionKey] ); if (guestMessagesResult.rows.length === 0) { logger.info(`No guest messages found for guest ID ${guestId}`); - const checkResult = await db.getQuery()('SELECT 1 FROM guest_user_mapping WHERE guest_id = $1', [guestId]); + const checkResult = await db.getQuery()('SELECT 1 FROM guest_user_mapping WHERE guest_id_encrypted = encrypt_text($1, $2)', [guestId, encryptionKey]); if (checkResult.rows.length > 0) { - await db.getQuery()('UPDATE guest_user_mapping SET processed = true WHERE guest_id = $1', [guestId]); + await db.getQuery()('UPDATE guest_user_mapping SET processed = true WHERE guest_id_encrypted = encrypt_text($1, $2)', [guestId, encryptionKey]); logger.info(`Marked guest mapping as processed (no messages found) for guest ID ${guestId}`); } else { logger.warn(`Attempted to mark non-existent guest mapping as processed for guest ID ${guestId}`); @@ -80,20 +96,20 @@ async function processGuestMessages(userId, guestId) { // --- Новый порядок: ищем последний диалог пользователя --- let conversation = null; const lastConvResult = await db.getQuery()( - 'SELECT * FROM conversations WHERE user_id = $1 ORDER BY updated_at DESC, created_at DESC LIMIT 1', - [userId] + 'SELECT id, user_id, created_at, updated_at, decrypt_text(title_encrypted, $2) as title FROM conversations WHERE user_id = $1 ORDER BY updated_at DESC, created_at DESC LIMIT 1', + [userId, encryptionKey] ); if (lastConvResult.rows.length > 0) { conversation = lastConvResult.rows[0]; } else { // Если нет ни одного диалога, создаём новый const firstMessage = guestMessages[0]; - const title = firstMessage.content - ? (firstMessage.content.length > 30 ? `${firstMessage.content.substring(0, 30)}...` : firstMessage.content) + const title = firstMessage.content && firstMessage.content.trim() + ? (firstMessage.content.trim().length > 30 ? `${firstMessage.content.trim().substring(0, 30)}...` : firstMessage.content.trim()) : (firstMessage.attachment_filename ? `Файл: ${firstMessage.attachment_filename}` : 'Новый диалог'); const newConversationResult = await db.getQuery()( - 'INSERT INTO conversations (user_id, title) VALUES ($1, $2) RETURNING *', - [userId, title] + 'INSERT INTO conversations (user_id, title_encrypted) VALUES ($1, encrypt_text($2, $3)) RETURNING *', + [userId, title, encryptionKey] ); conversation = newConversationResult.rows[0]; logger.info(`Created new conversation ${conversation.id} for guest messages`); @@ -110,11 +126,11 @@ async function processGuestMessages(userId, guestId) { // Сохраняем сообщение пользователя в таблицу messages, включая данные файла const userMessageResult = await db.getQuery()( `INSERT INTO messages - (conversation_id, content, sender_type, role, channel, created_at, user_id, - attachment_filename, attachment_mimetype, attachment_size, attachment_data) + (conversation_id, content_encrypted, sender_type_encrypted, role_encrypted, channel_encrypted, created_at, user_id, + attachment_filename_encrypted, attachment_mimetype_encrypted, attachment_size, attachment_data) VALUES - ($1, $2, 'user', 'user', 'web', $3, $4, - $5, $6, $7, $8) + ($1, encrypt_text($2, $9), encrypt_text('user', $9), encrypt_text('user', $9), encrypt_text('web', $9), $3, $4, + encrypt_text($5, $9), encrypt_text($6, $9), $7, $8) RETURNING *`, [ conversation.id, @@ -124,7 +140,8 @@ async function processGuestMessages(userId, guestId) { guestMessage.attachment_filename, // Метаданные и данные файла guestMessage.attachment_mimetype, guestMessage.attachment_size, - guestMessage.attachment_data // BYTEA + guestMessage.attachment_data, // BYTEA + encryptionKey ] ); const savedUserMessage = userMessageResult.rows[0]; @@ -134,8 +151,8 @@ async function processGuestMessages(userId, guestId) { if (guestMessage.content) { // Проверяем, что на это сообщение ещё нет ответа ассистента const aiReplyExists = await db.getQuery()( - `SELECT 1 FROM messages WHERE conversation_id = $1 AND sender_type = 'assistant' AND created_at > $2 LIMIT 1`, - [conversation.id, guestMessage.created_at] + `SELECT 1 FROM messages WHERE conversation_id = $1 AND sender_type_encrypted = encrypt_text('assistant', $3) AND created_at > $2 LIMIT 1`, + [conversation.id, guestMessage.created_at, encryptionKey] ); if (!aiReplyExists.rows.length) { try { @@ -147,8 +164,8 @@ async function processGuestMessages(userId, guestId) { } // Получаем историю сообщений до этого guestMessage (до created_at) const historyResult = await db.getQuery()( - 'SELECT sender_type, content FROM messages WHERE conversation_id = $1 AND created_at < $2 ORDER BY created_at DESC LIMIT 10', - [conversation.id, guestMessage.created_at] + 'SELECT decrypt_text(sender_type_encrypted, $3) as sender_type, decrypt_text(content_encrypted, $3) as content FROM messages WHERE conversation_id = $1 AND created_at < $2 ORDER BY created_at DESC LIMIT 10', + [conversation.id, guestMessage.created_at, encryptionKey] ); const history = historyResult.rows.reverse().map(msg => ({ role: msg.sender_type === 'user' ? 'user' : 'assistant', @@ -168,9 +185,9 @@ async function processGuestMessages(userId, guestId) { if (aiResponseContent) { await db.getQuery()( `INSERT INTO messages - (conversation_id, user_id, content, sender_type, role, channel) - VALUES ($1, $2, $3, 'assistant', 'assistant', 'web')`, - [conversation.id, userId, aiResponseContent] + (conversation_id, user_id, content_encrypted, sender_type_encrypted, role_encrypted, channel_encrypted) + VALUES ($1, $2, encrypt_text($3, $4), encrypt_text('assistant', $4), encrypt_text('assistant', $4), encrypt_text('web', $4))`, + [conversation.id, userId, aiResponseContent, encryptionKey] ); logger.info('AI response for guest message saved', { conversationId: conversation.id }); } @@ -194,14 +211,14 @@ async function processGuestMessages(userId, guestId) { ); // Помечаем гостевой ID как обработанный - await db.getQuery()('UPDATE guest_user_mapping SET processed = true WHERE guest_id = $1', [ - guestId, + await db.getQuery()('UPDATE guest_user_mapping SET processed = true WHERE guest_id_encrypted = encrypt_text($1, $2)', [ + guestId, encryptionKey ]); logger.info(`Marked guest mapping as processed for guest ID ${guestId}`); } else { logger.warn(`No guest messages were successfully processed, skipping deletion for guest ID ${guestId}`); // Если не было успешных, все равно пометим как обработанные, чтобы не пытаться снова - await db.getQuery()('UPDATE guest_user_mapping SET processed = true WHERE guest_id = $1', [guestId]); + await db.getQuery()('UPDATE guest_user_mapping SET processed = true WHERE guest_id_encrypted = encrypt_text($1, $2)', [guestId, encryptionKey]); logger.info(`Marked guest mapping as processed (no successful messages) for guest ID ${guestId}`); } @@ -224,6 +241,20 @@ router.post('/guest-message', upload.array('attachments'), async (req, res) => { logger.debug('Request Body:', req.body); logger.debug('Request Files:', req.files); // Файлы будут здесь + // Получаем ключ шифрования + const fs = require('fs'); + const path = require('path'); + let encryptionKey = 'default-key'; + + try { + const keyPath = path.join(__dirname, '../ssl/keys/full_db_encryption.key'); + if (fs.existsSync(keyPath)) { + encryptionKey = fs.readFileSync(keyPath, 'utf8').trim(); + } + } catch (keyError) { + console.error('Error reading encryption key:', keyError); + } + try { // Извлекаем данные из req.body (текстовые поля) const { message, language, guestId: requestGuestId } = req.body; @@ -250,12 +281,18 @@ router.post('/guest-message', upload.array('attachments'), async (req, res) => { } // Подготавливаем данные для вставки - const messageContent = message || ''; // Текст или ПУСТАЯ СТРОКА, если есть файл + const messageContent = message && message.trim() ? message.trim() : null; // Текст или NULL, если пустой const attachmentFilename = file ? file.originalname : null; const attachmentMimetype = file ? file.mimetype : null; const attachmentSize = file ? file.size : null; const attachmentData = file ? file.buffer : null; // Сам буфер файла + // Проверяем, что есть контент для сохранения + if (!messageContent && !attachmentData) { + logger.warn('Guest message attempt without content or file'); + return res.status(400).json({ success: false, error: 'Требуется текст сообщения или файл.' }); + } + logger.info('Saving guest message:', { guestId, message: messageContent, @@ -267,9 +304,9 @@ router.post('/guest-message', upload.array('attachments'), async (req, res) => { // Сохраняем сообщение пользователя с текстом или файлом const result = await db.getQuery()( `INSERT INTO guest_messages - (guest_id, content, language, is_ai, - attachment_filename, attachment_mimetype, attachment_size, attachment_data) - VALUES ($1, $2, $3, false, $4, $5, $6, $7) RETURNING id`, + (guest_id_encrypted, content_encrypted, language_encrypted, is_ai, + attachment_filename_encrypted, attachment_mimetype_encrypted, attachment_size, attachment_data) + VALUES (encrypt_text($1, $8), ${messageContent ? 'encrypt_text($2, $8)' : 'NULL'}, encrypt_text($3, $8), false, ${attachmentFilename ? 'encrypt_text($4, $8)' : 'NULL'}, ${attachmentMimetype ? 'encrypt_text($5, $8)' : 'NULL'}, $6, $7) RETURNING id`, [ guestId, messageContent, // Текст сообщения или NULL @@ -277,7 +314,8 @@ router.post('/guest-message', upload.array('attachments'), async (req, res) => { attachmentFilename, attachmentMimetype, attachmentSize, - attachmentData // BYTEA данные файла или NULL + attachmentData, // BYTEA данные файла или NULL + encryptionKey ] ); @@ -333,6 +371,20 @@ router.post('/message', requireAuth, upload.array('attachments'), async (req, re logger.debug('Request Body:', req.body); logger.debug('Request Files:', req.files); + // Получаем ключ шифрования + const fs = require('fs'); + const path = require('path'); + let encryptionKey = 'default-key'; + + try { + const keyPath = path.join(__dirname, '../ssl/keys/full_db_encryption.key'); + if (fs.existsSync(keyPath)) { + encryptionKey = fs.readFileSync(keyPath, 'utf8').trim(); + } + } catch (keyError) { + console.error('Error reading encryption key:', keyError); + } + const userId = req.session.userId; const { message, language, conversationId: convIdFromRequest } = req.body; const files = req.files; @@ -359,14 +411,14 @@ router.post('/message', requireAuth, upload.array('attachments'), async (req, re if (req.session.isAdmin) { // Админ может писать в любой диалог convResult = await db.getQuery()( - 'SELECT * FROM conversations WHERE id = $1', - [conversationId] + 'SELECT id, user_id, created_at, updated_at, decrypt_text(title_encrypted, $2) as title FROM conversations WHERE id = $1', + [conversationId, encryptionKey] ); } else { // Обычный пользователь — только в свой диалог convResult = await db.getQuery()( - 'SELECT * FROM conversations WHERE id = $1 AND user_id = $2', - [conversationId, userId] + 'SELECT id, user_id, created_at, updated_at, decrypt_text(title_encrypted, $3) as title FROM conversations WHERE id = $1 AND user_id = $2', + [conversationId, userId, encryptionKey] ); } if (convResult.rows.length === 0) { @@ -377,20 +429,20 @@ router.post('/message', requireAuth, upload.array('attachments'), async (req, re } else { // Ищем последний диалог пользователя const lastConvResult = await db.getQuery()( - 'SELECT * FROM conversations WHERE user_id = $1 ORDER BY updated_at DESC, created_at DESC LIMIT 1', - [userId] + 'SELECT id, user_id, created_at, updated_at, decrypt_text(title_encrypted, $2) as title FROM conversations WHERE user_id = $1 ORDER BY updated_at DESC, created_at DESC LIMIT 1', + [userId, encryptionKey] ); if (lastConvResult.rows.length > 0) { conversation = lastConvResult.rows[0]; conversationId = conversation.id; } else { // Создаем новый диалог, если нет ни одного - const title = message - ? (message.length > 50 ? `${message.substring(0, 50)}...` : message) + const title = message && message.trim() + ? (message.trim().length > 50 ? `${message.trim().substring(0, 50)}...` : message.trim()) : (file ? `Файл: ${file.originalname}` : 'Новый диалог'); const newConvResult = await db.getQuery()( - 'INSERT INTO conversations (user_id, title) VALUES ($1, $2) RETURNING *', - [userId, title] + 'INSERT INTO conversations (user_id, title_encrypted) VALUES ($1, encrypt_text($2, $3)) RETURNING *', + [userId, title, encryptionKey] ); conversation = newConvResult.rows[0]; conversationId = conversation.id; @@ -399,7 +451,7 @@ router.post('/message', requireAuth, upload.array('attachments'), async (req, re } // Подготавливаем данные для вставки сообщения пользователя - const messageContent = message || ''; // Текст или ПУСТАЯ СТРОКА, если есть файл + const messageContent = message && message.trim() ? message.trim() : null; // Текст или NULL, если пустой const attachmentFilename = file ? file.originalname : null; const attachmentMimetype = file ? file.mimetype : null; const attachmentSize = file ? file.size : null; @@ -415,26 +467,26 @@ router.post('/message', requireAuth, upload.array('attachments'), async (req, re role = 'admin'; } - // Сохраняем сообщение - const userMessageResult = await db.getQuery()( - `INSERT INTO messages - (conversation_id, user_id, content, sender_type, role, channel, - attachment_filename, attachment_mimetype, attachment_size, attachment_data) - VALUES ($1, $2, $3, $4, $5, 'web', $6, $7, $8, $9) - RETURNING *`, - [ - conversationId, - recipientId, // user_id контакта - messageContent, - senderType, - role, - attachmentFilename, - attachmentMimetype, - attachmentSize, - attachmentData - ] - ); - const userMessage = userMessageResult.rows[0]; + // Сохраняем сообщение через encryptedDb + const userMessage = await encryptedDb.saveData('messages', { + conversation_id: conversationId, + user_id: recipientId, // user_id контакта + content: messageContent, + sender_type: senderType, + role: role, + channel: 'web', + attachment_filename: attachmentFilename, + attachment_mimetype: attachmentMimetype, + attachment_size: attachmentSize, + attachment_data: attachmentData + }); + + // Проверяем, что сообщение было сохранено + if (!userMessage) { + logger.warn('Message not saved - all content was empty'); + return res.status(400).json({ error: 'Message content cannot be empty' }); + } + logger.info('User message saved', { messageId: userMessage.id, conversationId }); if (await isUserBlocked(userId)) { @@ -476,22 +528,24 @@ router.post('/message', requireAuth, upload.array('attachments'), async (req, re if (ragResult && ragResult.answer && typeof ragResult.score === 'number' && Math.abs(ragResult.score) <= threshold) { logger.info(`[RAG] Найден confident-ответ (score=${ragResult.score}), отправляем ответ из базы.`); // Прямой ответ из RAG - const aiMessageResult = await db.getQuery()( - `INSERT INTO messages - (conversation_id, user_id, content, sender_type, role, channel) - VALUES ($1, $2, $3, 'assistant', 'assistant', 'web') - RETURNING *`, - [conversationId, userId, ragResult.answer] - ); - aiMessage = aiMessageResult.rows[0]; + logger.info(`[RAG] Сохраняем AI сообщение с контентом: "${ragResult.answer}"`); + aiMessage = await encryptedDb.saveData('messages', { + conversation_id: conversationId, + user_id: userId, + content: ragResult.answer, + sender_type: 'assistant', + role: 'assistant', + channel: 'web' + }); + logger.info(`[RAG] AI сообщение сохранено:`, aiMessage); // Пушим новое сообщение через WebSocket broadcastChatMessage(aiMessage); } else if (ragResult) { logger.info(`[RAG] Нет confident-ответа (score=${ragResult.score}), переходим к генерации через LLM.`); // Генерация через LLM с подстановкой значений из RAG const historyResult = await db.getQuery()( - 'SELECT sender_type, content FROM messages WHERE conversation_id = $1 AND id < $2 ORDER BY created_at DESC LIMIT 10', - [conversationId, userMessage.id] + 'SELECT decrypt_text(sender_type_encrypted, $3) as sender_type, decrypt_text(content_encrypted, $3) as content FROM messages WHERE conversation_id = $1 AND id < $2 ORDER BY created_at DESC LIMIT 10', + [conversationId, userMessage.id, encryptionKey] ); const history = historyResult.rows.reverse().map(msg => ({ role: msg.sender_type === 'user' ? 'user' : 'assistant', @@ -509,14 +563,14 @@ router.post('/message', requireAuth, upload.array('attachments'), async (req, re language: aiSettings && aiSettings.languages && aiSettings.languages.length > 0 ? aiSettings.languages[0] : 'ru' }); if (llmResponse) { - const aiMessageResult = await db.getQuery()( - `INSERT INTO messages - (conversation_id, user_id, content, sender_type, role, channel) - VALUES ($1, $2, $3, 'assistant', 'assistant', 'web') - RETURNING *`, - [conversationId, userId, llmResponse] - ); - aiMessage = aiMessageResult.rows[0]; + aiMessage = await encryptedDb.saveData('messages', { + conversation_id: conversationId, + user_id: userId, + content: llmResponse, + sender_type: 'assistant', + role: 'assistant', + channel: 'web' + }); // Пушим новое сообщение через WebSocket broadcastChatMessage(aiMessage); } else { @@ -531,25 +585,53 @@ router.post('/message', requireAuth, upload.array('attachments'), async (req, re } } + // Fallback: если AI не смог ответить, создаем fallback сообщение + if (!aiMessage && messageContent && shouldGenerateAiReply) { + try { + logger.info('[Chat] Creating fallback AI response due to AI error'); + aiMessage = await encryptedDb.saveData('messages', { + conversation_id: conversationId, + user_id: userId, + content: 'Извините, я не смог обработать ваш запрос. Пожалуйста, попробуйте позже.', + sender_type: 'assistant', + role: 'assistant', + channel: 'web' + }); + // Пушим новое сообщение через WebSocket + broadcastChatMessage(aiMessage); + } catch (fallbackError) { + logger.error('Error creating fallback AI response:', fallbackError); + } + } + // Форматируем ответ для фронтенда const formatMessageForFrontend = (msg) => { if (!msg) return null; + console.log(`🔍 [formatMessageForFrontend] Форматируем сообщение:`, { + id: msg.id, + sender_type: msg.sender_type, + role: msg.role, + content: msg.content, + // Добавляем все поля для диагностики + allFields: Object.keys(msg), + rawMsg: msg + }); const formatted = { id: msg.id, conversation_id: msg.conversation_id, user_id: msg.user_id, - content: msg.content, - sender_type: msg.sender_type, - role: msg.role, - channel: msg.channel, + content: msg.content, // content уже расшифрован encryptedDb + sender_type: msg.sender_type, // sender_type уже расшифрован encryptedDb + role: msg.role, // role уже расшифрован encryptedDb + channel: msg.channel, // channel уже расшифрован encryptedDb created_at: msg.created_at, attachments: null // Инициализируем как null }; // Добавляем информацию о файле, если она есть if (msg.attachment_filename) { formatted.attachments = [{ - originalname: msg.attachment_filename, - mimetype: msg.attachment_mimetype, + originalname: msg.attachment_filename, // attachment_filename уже расшифрован encryptedDb + mimetype: msg.attachment_mimetype, // attachment_mimetype уже расшифрован encryptedDb size: msg.attachment_size, // НЕ передаем attachment_data обратно в ответе на POST }]; @@ -563,18 +645,228 @@ router.post('/message', requireAuth, upload.array('attachments'), async (req, re [conversationId] ); - res.json({ + // Получаем расшифрованные данные для форматирования + const decryptedUserMessage = userMessage ? await encryptedDb.getData('messages', { id: userMessage.id }, 1) : null; + const decryptedAiMessage = aiMessage ? await encryptedDb.getData('messages', { id: aiMessage.id }, 1) : null; + + const response = { success: true, conversationId: conversationId, - userMessage: formatMessageForFrontend(userMessage), - aiMessage: formatMessageForFrontend(aiMessage), + userMessage: formatMessageForFrontend(decryptedUserMessage ? decryptedUserMessage[0] : null), + aiMessage: formatMessageForFrontend(decryptedAiMessage ? decryptedAiMessage[0] : null), + }; + + console.log(`📤 [Chat] Отправляем ответ на фронтенд:`, { + userMessage: response.userMessage, + aiMessage: response.aiMessage }); + + // Отправляем WebSocket уведомления + if (response.userMessage) { + broadcastChatMessage(response.userMessage, userId); + } + if (response.aiMessage) { + broadcastChatMessage(response.aiMessage, userId); + } + broadcastConversationUpdate(conversationId, userId); + + res.json(response); } catch (error) { logger.error('Error processing authenticated message:', error); res.status(500).json({ success: false, error: 'Ошибка обработки сообщения' }); } }); +// Новый маршрут для обработки сообщений через очередь +router.post('/message-queued', requireAuth, upload.array('attachments'), async (req, res) => { + logger.info('Received /message-queued request'); + + try { + const userId = req.session.userId; + const { message, language, conversationId: convIdFromRequest, type = 'chat' } = req.body; + const files = req.files; + const file = files && files.length > 0 ? files[0] : null; + + // Валидация + if (!message && !file) { + return res.status(400).json({ + success: false, + error: 'Требуется текст сообщения или файл.' + }); + } + + if (message && file) { + return res.status(400).json({ + success: false, + error: 'Нельзя отправить текст и файл одновременно.' + }); + } + + // Получаем ключ шифрования + const fs = require('fs'); + const path = require('path'); + let encryptionKey = 'default-key'; + + try { + const keyPath = path.join(__dirname, '../ssl/keys/full_db_encryption.key'); + if (fs.existsSync(keyPath)) { + encryptionKey = fs.readFileSync(keyPath, 'utf8').trim(); + } + } catch (keyError) { + console.error('Error reading encryption key:', keyError); + } + + let conversationId = convIdFromRequest; + let conversation = null; + + // Найти или создать диалог + if (conversationId) { + let convResult; + if (req.session.isAdmin) { + convResult = await db.getQuery()( + 'SELECT id, user_id, created_at, updated_at, decrypt_text(title_encrypted, $2) as title FROM conversations WHERE id = $1', + [conversationId, encryptionKey] + ); + } else { + convResult = await db.getQuery()( + 'SELECT id, user_id, created_at, updated_at, decrypt_text(title_encrypted, $3) as title FROM conversations WHERE id = $1 AND user_id = $2', + [conversationId, userId, encryptionKey] + ); + } + if (convResult.rows.length === 0) { + return res.status(404).json({ + success: false, + error: 'Диалог не найден или доступ запрещен' + }); + } + conversation = convResult.rows[0]; + } else { + // Ищем последний диалог пользователя + const lastConvResult = await db.getQuery()( + 'SELECT id, user_id, created_at, updated_at, decrypt_text(title_encrypted, $2) as title FROM conversations WHERE user_id = $1 ORDER BY updated_at DESC, created_at DESC LIMIT 1', + [userId, encryptionKey] + ); + if (lastConvResult.rows.length > 0) { + conversation = lastConvResult.rows[0]; + conversationId = conversation.id; + } else { + // Создаем новый диалог + const title = message && message.trim() + ? (message.trim().length > 50 ? `${message.trim().substring(0, 50)}...` : message.trim()) + : (file ? `Файл: ${file.originalname}` : 'Новый диалог'); + const newConvResult = await db.getQuery()( + 'INSERT INTO conversations (user_id, title_encrypted) VALUES ($1, encrypt_text($2, $3)) RETURNING *', + [userId, title, encryptionKey] + ); + conversation = newConvResult.rows[0]; + conversationId = conversation.id; + } + } + + // Сохраняем сообщение пользователя + const messageContent = message && message.trim() ? message.trim() : null; + const attachmentFilename = file ? file.originalname : null; + const attachmentMimetype = file ? file.mimetype : null; + const attachmentSize = file ? file.size : null; + const attachmentData = file ? file.buffer : null; + + const recipientId = conversation.user_id; + let senderType = 'user'; + let role = 'user'; + if (req.session.isAdmin) { + senderType = 'admin'; + role = 'admin'; + } + + const userMessage = await encryptedDb.saveData('messages', { + conversation_id: conversationId, + user_id: recipientId, + content: messageContent, + sender_type: senderType, + role: role, + channel: 'web', + attachment_filename: attachmentFilename, + attachment_mimetype: attachmentMimetype, + attachment_size: attachmentSize, + attachment_data: attachmentData + }); + + // Проверяем, нужно ли генерировать AI ответ + if (await isUserBlocked(userId)) { + logger.info(`[Chat] Пользователь ${userId} заблокирован — ответ ИИ не отправляется.`); + return res.json({ success: true, message: userMessage }); + } + + let shouldGenerateAiReply = true; + if (senderType === 'admin' && userId !== recipientId) { + shouldGenerateAiReply = false; + } + + if (messageContent && shouldGenerateAiReply) { + try { + // Получаем историю сообщений + const historyResult = await db.getQuery()( + 'SELECT decrypt_text(sender_type_encrypted, $3) as sender_type, decrypt_text(content_encrypted, $3) as content FROM messages WHERE conversation_id = $1 AND id < $2 ORDER BY created_at DESC LIMIT 10', + [conversationId, userMessage.id, encryptionKey] + ); + const history = historyResult.rows.reverse().map(msg => ({ + role: msg.sender_type === 'user' ? 'user' : 'assistant', + content: msg.content + })); + + // Получаем настройки AI + const aiSettings = await aiAssistantSettingsService.getSettings(); + let rules = null; + if (aiSettings && aiSettings.rules_id) { + rules = await aiAssistantRulesService.getRuleById(aiSettings.rules_id); + } + + // Добавляем задачу в очередь + const taskData = { + message: messageContent, + language: language || 'auto', + history: history, + systemPrompt: aiSettings ? aiSettings.system_prompt : '', + rules: rules, + type: type, + userId: userId, + userRole: req.session.isAdmin ? 'admin' : 'user', + conversationId: conversationId, + userMessageId: userMessage.id + }; + + const queueResult = await aiQueueService.addTask(taskData); + + res.json({ + success: true, + message: userMessage, + queueInfo: { + taskId: queueResult.taskId, + status: 'queued', + estimatedWaitTime: aiQueueService.getStats().currentQueueSize * 30 + } + }); + + } catch (error) { + logger.error('Error adding task to queue:', error); + res.status(500).json({ + success: false, + error: 'Ошибка при добавлении задачи в очередь.' + }); + } + } else { + res.json({ success: true, message: userMessage }); + } + + } catch (error) { + logger.error('Error processing queued message:', error); + res.status(500).json({ + success: false, + error: 'Внутренняя ошибка сервера.' + }); + } +}); + // Добавьте этот маршрут для проверки доступных моделей router.get('/models', async (req, res) => { try { @@ -601,6 +893,20 @@ router.get('/history', requireAuth, async (req, res) => { // Опциональный ID диалога const conversationId = req.query.conversation_id; + // Получаем ключ шифрования + const fs = require('fs'); + const path = require('path'); + let encryptionKey = 'default-key'; + + try { + const keyPath = path.join(__dirname, '../ssl/keys/full_db_encryption.key'); + if (fs.existsSync(keyPath)) { + encryptionKey = fs.readFileSync(keyPath, 'utf8').trim(); + } + } catch (keyError) { + console.error('Error reading encryption key:', keyError); + } + try { // Если нужен только подсчет if (countOnly) { @@ -615,51 +921,24 @@ router.get('/history', requireAuth, async (req, res) => { return res.json({ success: true, count: totalCount }); } - // Формируем основной запрос - let query = ` - SELECT - id, - conversation_id, - user_id, - content, - sender_type, - role, - channel, - created_at, - attachment_filename, - attachment_mimetype, - attachment_size, - attachment_data -- Выбираем и данные файла - FROM messages - WHERE user_id = $1 - `; - const params = [userId]; - - // Добавляем фильтр по диалогу, если нужно + // Загружаем сообщения через encryptedDb + const whereConditions = { user_id: userId }; if (conversationId) { - query += ' AND conversation_id = $2'; - params.push(conversationId); + whereConditions.conversation_id = conversationId; } - // Добавляем сортировку и пагинацию - query += ' ORDER BY created_at ASC LIMIT $' + (params.length + 1) + ' OFFSET $' + (params.length + 2); - params.push(limit); - params.push(offset); - - logger.debug('Executing history query:', { query, params }); - - const result = await db.getQuery()(query, params); + const messages = await encryptedDb.getData('messages', whereConditions, limit, 'created_at ASC', offset); // Обрабатываем результаты для фронтенда - const messages = result.rows.map(msg => { + const formattedMessages = messages.map(msg => { const formatted = { id: msg.id, conversation_id: msg.conversation_id, user_id: msg.user_id, - content: msg.content, - sender_type: msg.sender_type, - role: msg.role, - channel: msg.channel, + content: msg.content, // content уже расшифрован encryptedDb + sender_type: msg.sender_type, // sender_type уже расшифрован encryptedDb + role: msg.role, // role уже расшифрован encryptedDb + channel: msg.channel, // channel уже расшифрован encryptedDb created_at: msg.created_at, attachments: null // Инициализируем }; @@ -667,17 +946,13 @@ router.get('/history', requireAuth, async (req, res) => { // Если есть данные файла, добавляем их в attachments if (msg.attachment_data) { formatted.attachments = [{ - originalname: msg.attachment_filename, - mimetype: msg.attachment_mimetype, + originalname: msg.attachment_filename, // attachment_filename уже расшифрован encryptedDb + mimetype: msg.attachment_mimetype, // attachment_mimetype уже расшифрован encryptedDb size: msg.attachment_size, // Кодируем Buffer в Base64 для передачи на фронтенд data_base64: msg.attachment_data.toString('base64') }]; } - // Не забываем удалить поле attachment_data из итогового объекта, - // так как оно уже обработано и не нужно в сыром виде на фронте - // (хотя map и так создает новый объект, это для ясности) - delete formatted.attachment_data; return formatted; }); @@ -692,11 +967,11 @@ router.get('/history', requireAuth, async (req, res) => { const totalCountResult = await db.getQuery()(totalCountQuery, totalCountParams); const totalMessages = parseInt(totalCountResult.rows[0].count, 10); - logger.info(`Returning message history for user ${userId}`, { count: messages.length, offset, limit, total: totalMessages }); + logger.info(`Returning message history for user ${userId}`, { count: formattedMessages.length, offset, limit, total: totalMessages }); res.json({ success: true, - messages: messages, + messages: formattedMessages, offset: offset, limit: limit, total: totalMessages @@ -732,6 +1007,20 @@ router.post('/process-guest', requireAuth, async (req, res) => { router.post('/ai-draft', requireAuth, async (req, res) => { const userId = req.session.userId; const { conversationId, messages, language } = req.body; + + // Получаем ключ шифрования + const fs = require('fs'); + const path = require('path'); + let encryptionKey = 'default-key'; + + try { + const keyPath = path.join(__dirname, '../ssl/keys/full_db_encryption.key'); + if (fs.existsSync(keyPath)) { + encryptionKey = fs.readFileSync(keyPath, 'utf8').trim(); + } + } catch (keyError) { + console.error('Error reading encryption key:', keyError); + } if (!conversationId || !Array.isArray(messages) || messages.length === 0) { return res.status(400).json({ success: false, error: 'conversationId и messages обязательны' }); } @@ -746,8 +1035,8 @@ router.post('/ai-draft', requireAuth, async (req, res) => { const promptText = messages.map(m => m.content).join('\n\n'); // Получаем последние 10 сообщений из диалога для истории const historyResult = await db.getQuery()( - 'SELECT sender_type, content FROM messages WHERE conversation_id = $1 ORDER BY created_at DESC LIMIT 10', - [conversationId] + 'SELECT decrypt_text(sender_type_encrypted, $2) as sender_type, decrypt_text(content_encrypted, $2) as content FROM messages WHERE conversation_id = $1 ORDER BY created_at DESC LIMIT 10', + [conversationId, encryptionKey] ); const history = historyResult.rows.reverse().map(msg => ({ role: msg.sender_type === 'user' ? 'user' : 'assistant', diff --git a/backend/routes/countries.js b/backend/routes/countries.js new file mode 100644 index 0000000..ed20ae2 --- /dev/null +++ b/backend/routes/countries.js @@ -0,0 +1,102 @@ +/** + * 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 + */ + +const express = require('express'); +const path = require('path'); +const fs = require('fs'); +const router = express.Router(); + +/** + * @route GET /api/countries + * @desc Получить список всех стран + * @access Public + */ +router.get('/', async (req, res, next) => { + try { + // Путь к файлу с данными стран + const countriesFilePath = path.join(__dirname, '../db/data/countries.json'); + + // Проверяем существование файла + if (!fs.existsSync(countriesFilePath)) { + return res.status(404).json({ + success: false, + message: 'Файл с данными стран не найден' + }); + } + + // Читаем файл + const countriesData = fs.readFileSync(countriesFilePath, 'utf8'); + const countries = JSON.parse(countriesData); + + // Возвращаем список стран + res.json({ + success: true, + data: countries.countries || [], + count: countries.countries ? countries.countries.length : 0 + }); + + } catch (error) { + console.error('Ошибка при получении списка стран:', error); + next(error); + } +}); + +/** + * @route GET /api/countries/:code + * @desc Получить информацию о стране по коду + * @access Public + */ +router.get('/:code', async (req, res, next) => { + try { + const { code } = req.params; + + // Путь к файлу с данными стран + const countriesFilePath = path.join(__dirname, '../db/data/countries.json'); + + // Проверяем существование файла + if (!fs.existsSync(countriesFilePath)) { + return res.status(404).json({ + success: false, + message: 'Файл с данными стран не найден' + }); + } + + // Читаем файл + const countriesData = fs.readFileSync(countriesFilePath, 'utf8'); + const countries = JSON.parse(countriesData); + + // Ищем страну по коду (поддерживаем поиск по code, code3 или numeric) + const country = countries.countries.find(c => + c.code === code.toUpperCase() || + c.code3 === code.toUpperCase() || + c.numeric === code + ); + + if (!country) { + return res.status(404).json({ + success: false, + message: `Страна с кодом ${code} не найдена` + }); + } + + res.json({ + success: true, + data: country + }); + + } catch (error) { + console.error('Ошибка при получении информации о стране:', error); + next(error); + } +}); + +module.exports = router; \ No newline at end of file diff --git a/backend/routes/dleV2.js b/backend/routes/dleV2.js new file mode 100644 index 0000000..9374493 --- /dev/null +++ b/backend/routes/dleV2.js @@ -0,0 +1,173 @@ +/** + * 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 + */ + +const express = require('express'); +const router = express.Router(); +const dleV2Service = require('../services/dleV2Service'); +const logger = require('../utils/logger'); +const auth = require('../middleware/auth'); +const path = require('path'); +const fs = require('fs'); + +/** + * @route POST /api/dle-v2 + * @desc Создать новое DLE v2 (Digital Legal Entity) + * @access Private (только для авторизованных пользователей с ролью admin) + */ +router.post('/', auth.requireAuth, auth.requireAdmin, async (req, res, next) => { + try { + const dleParams = req.body; + logger.info('Получен запрос на создание DLE v2:', dleParams); + + // Если параметр partners не был передан явно, используем адрес авторизованного пользователя + if (!dleParams.partners || dleParams.partners.length === 0) { + // Проверяем, есть ли в сессии адрес кошелька пользователя + if (!req.user || !req.user.walletAddress) { + return res.status(400).json({ + success: false, + message: 'Не указан адрес кошелька пользователя или партнеров для распределения токенов' + }); + } + + // Используем адрес авторизованного пользователя + dleParams.partners = [req.user.address || req.user.walletAddress]; + + // Если суммы не указаны, используем значение по умолчанию (100% токенов) + if (!dleParams.amounts || dleParams.amounts.length === 0) { + dleParams.amounts = ['1000000']; + } + } + + // Создаем DLE v2 + const result = await dleV2Service.createDLE(dleParams); + + logger.info('DLE v2 успешно создано:', result); + + res.json({ + success: true, + message: 'DLE v2 успешно создано', + data: result.data + }); + + } catch (error) { + logger.error('Ошибка при создании DLE v2:', error); + res.status(500).json({ + success: false, + message: error.message || 'Произошла ошибка при создании DLE v2' + }); + } +}); + +/** + * @route GET /api/dle-v2 + * @desc Получить список всех DLE v2 + * @access Private (только для авторизованных пользователей) + */ +router.get('/', auth.requireAuth, async (req, res, next) => { + try { + const dles = dleV2Service.getAllDLEs(); + + res.json({ + success: true, + data: dles + }); + + } catch (error) { + logger.error('Ошибка при получении списка DLE v2:', error); + res.status(500).json({ + success: false, + message: error.message || 'Произошла ошибка при получении списка DLE v2' + }); + } +}); + +/** + * @route GET /api/dle-v2/defaults + * @desc Получить настройки по умолчанию для DLE v2 + * @access Private (только для авторизованных пользователей) + */ +router.get('/defaults', auth.requireAuth, async (req, res, next) => { + // Возвращаем настройки по умолчанию, которые будут использоваться + // при заполнении формы на фронтенде + res.json({ + success: true, + data: { + votingDelay: 1, // 1 блок задержки перед началом голосования + votingPeriod: 45818, // ~1 неделя в блоках (при 13 секундах на блок) + proposalThreshold: '100000', // 100,000 токенов + quorumPercentage: 4, // 4% от общего количества токенов + minTimelockDelay: 2 // 2 дня + } + }); +}); + +/** + * @route DELETE /api/dle-v2/:dleAddress + * @desc Удалить DLE v2 по адресу + * @access Private (только для авторизованных пользователей с ролью admin) + */ +router.delete('/:dleAddress', auth.requireAuth, auth.requireAdmin, async (req, res, next) => { + try { + const { dleAddress } = req.params; + logger.info(`Получен запрос на удаление DLE v2 с адресом: ${dleAddress}`); + + // Проверяем существование DLE v2 в директории contracts-data/dles + const dlesDir = path.join(__dirname, '../contracts-data/dles'); + const files = fs.readdirSync(dlesDir); + + let fileToDelete = null; + + // Находим файл, содержащий указанный адрес DLE + for (const file of files) { + if (file.includes('dle-v2-') && file.endsWith('.json')) { + const filePath = path.join(dlesDir, file); + if (fs.statSync(filePath).isFile()) { + try { + const dleData = JSON.parse(fs.readFileSync(filePath, 'utf8')); + if (dleData.dleAddress && dleData.dleAddress.toLowerCase() === dleAddress.toLowerCase()) { + fileToDelete = filePath; + break; + } + } catch (err) { + logger.error(`Ошибка при чтении файла ${file}:`, err); + } + } + } + } + + if (!fileToDelete) { + return res.status(404).json({ + success: false, + message: `DLE v2 с адресом ${dleAddress} не найдено` + }); + } + + // Удаляем файл + fs.unlinkSync(fileToDelete); + + logger.info(`DLE v2 с адресом ${dleAddress} успешно удалено`); + + res.json({ + success: true, + message: `DLE v2 с адресом ${dleAddress} успешно удалено` + }); + + } catch (error) { + logger.error('Ошибка при удалении DLE v2:', error); + res.status(500).json({ + success: false, + message: error.message || 'Произошла ошибка при удалении DLE v2' + }); + } +}); + +module.exports = router; \ No newline at end of file diff --git a/backend/routes/identities.js b/backend/routes/identities.js index 0908fcf..e705e00 100644 --- a/backend/routes/identities.js +++ b/backend/routes/identities.js @@ -39,11 +39,25 @@ router.post('/link', requireAuth, async (req, res, next) => { if (type === 'wallet') { const normalizedWallet = value.toLowerCase(); + // Получаем ключ шифрования + const fs = require('fs'); + const path = require('path'); + let encryptionKey = 'default-key'; + + try { + const keyPath = path.join(__dirname, '../ssl/keys/full_db_encryption.key'); + if (fs.existsSync(keyPath)) { + encryptionKey = fs.readFileSync(keyPath, 'utf8').trim(); + } + } catch (keyError) { + console.error('Error reading encryption key:', keyError); + } + // Проверяем, существует ли уже такой кошелек const existingCheck = await db.getQuery()( `SELECT user_id FROM user_identities - WHERE provider = 'wallet' AND provider_id = $1`, - [normalizedWallet] + WHERE provider_encrypted = encrypt_text('wallet', $2) AND provider_id_encrypted = encrypt_text($1, $2)`, + [normalizedWallet, encryptionKey] ); if (existingCheck.rows.length > 0) { @@ -138,8 +152,25 @@ router.delete('/:provider/:providerId', requireAuth, async (req, res, next) => { // Получение email-настроек router.get('/email-settings', requireAuth, async (req, res, next) => { + // Получаем ключ шифрования + const fs = require('fs'); + const path = require('path'); + let encryptionKey = 'default-key'; + try { - const { rows } = await db.getQuery()('SELECT * FROM email_settings ORDER BY id LIMIT 1'); + const keyPath = path.join(__dirname, '../ssl/keys/full_db_encryption.key'); + if (fs.existsSync(keyPath)) { + encryptionKey = fs.readFileSync(keyPath, 'utf8').trim(); + } + } catch (keyError) { + console.error('Error reading encryption key:', keyError); + } + + try { + const { rows } = await db.getQuery()( + 'SELECT id, smtp_port, imap_port, created_at, updated_at, decrypt_text(smtp_host_encrypted, $1) as smtp_host, decrypt_text(smtp_user_encrypted, $1) as smtp_user, decrypt_text(smtp_password_encrypted, $1) as smtp_password, decrypt_text(imap_host_encrypted, $1) as imap_host, decrypt_text(from_email_encrypted, $1) as from_email FROM email_settings ORDER BY id LIMIT 1', + [encryptionKey] + ); if (!rows.length) return res.status(404).json({ success: false, error: 'Not found' }); const settings = rows[0]; delete settings.smtp_password; // не возвращаем пароль @@ -152,6 +183,20 @@ router.get('/email-settings', requireAuth, async (req, res, next) => { // Обновление email-настроек router.put('/email-settings', requireAuth, async (req, res, next) => { + // Получаем ключ шифрования + const fs = require('fs'); + const path = require('path'); + let encryptionKey = 'default-key'; + + try { + const keyPath = path.join(__dirname, '../ssl/keys/full_db_encryption.key'); + if (fs.existsSync(keyPath)) { + encryptionKey = fs.readFileSync(keyPath, 'utf8').trim(); + } + } catch (keyError) { + console.error('Error reading encryption key:', keyError); + } + try { const { smtp_host, smtp_port, smtp_user, smtp_password, imap_host, imap_port, from_email } = req.body; if (!smtp_host || !smtp_port || !smtp_user || !from_email) { @@ -161,14 +206,14 @@ router.put('/email-settings', requireAuth, async (req, res, next) => { if (rows.length) { // Обновляем существующую запись await db.getQuery()( - `UPDATE email_settings SET smtp_host=$1, smtp_port=$2, smtp_user=$3, smtp_password=COALESCE($4, smtp_password), imap_host=$5, imap_port=$6, from_email=$7, updated_at=NOW() WHERE id=$8`, - [smtp_host, smtp_port, smtp_user, smtp_password, imap_host, imap_port, from_email, rows[0].id] + `UPDATE email_settings SET smtp_host_encrypted=encrypt_text($1, $9), smtp_port=$2, smtp_user_encrypted=encrypt_text($3, $9), smtp_password_encrypted=COALESCE(encrypt_text($4, $9), smtp_password_encrypted), imap_host_encrypted=encrypt_text($5, $9), imap_port=$6, from_email_encrypted=encrypt_text($7, $9), updated_at=NOW() WHERE id=$8`, + [smtp_host, smtp_port, smtp_user, smtp_password, imap_host, imap_port, from_email, rows[0].id, encryptionKey] ); } else { // Вставляем новую await db.getQuery()( - `INSERT INTO email_settings (smtp_host, smtp_port, smtp_user, smtp_password, imap_host, imap_port, from_email) VALUES ($1,$2,$3,$4,$5,$6,$7)`, - [smtp_host, smtp_port, smtp_user, smtp_password, imap_host, imap_port, from_email] + `INSERT INTO email_settings (smtp_host_encrypted, smtp_port, smtp_user_encrypted, smtp_password_encrypted, imap_host_encrypted, imap_port, from_email_encrypted) VALUES (encrypt_text($1, $8), $2, encrypt_text($3, $8), encrypt_text($4, $8), encrypt_text($5, $8), $6, encrypt_text($7, $8))`, + [smtp_host, smtp_port, smtp_user, smtp_password, imap_host, imap_port, from_email, encryptionKey] ); } res.json({ success: true }); @@ -180,8 +225,25 @@ router.put('/email-settings', requireAuth, async (req, res, next) => { // Получение telegram-настроек router.get('/telegram-settings', requireAuth, async (req, res, next) => { + // Получаем ключ шифрования + const fs = require('fs'); + const path = require('path'); + let encryptionKey = 'default-key'; + try { - const { rows } = await db.getQuery()('SELECT * FROM telegram_settings ORDER BY id LIMIT 1'); + const keyPath = path.join(__dirname, '../ssl/keys/full_db_encryption.key'); + if (fs.existsSync(keyPath)) { + encryptionKey = fs.readFileSync(keyPath, 'utf8').trim(); + } + } catch (keyError) { + console.error('Error reading encryption key:', keyError); + } + + try { + const { rows } = await db.getQuery()( + 'SELECT id, created_at, updated_at, decrypt_text(bot_token_encrypted, $1) as bot_token, decrypt_text(bot_username_encrypted, $1) as bot_username FROM telegram_settings ORDER BY id LIMIT 1', + [encryptionKey] + ); if (!rows.length) return res.status(404).json({ success: false, error: 'Not found' }); const settings = rows[0]; delete settings.bot_token; // не возвращаем токен @@ -194,6 +256,20 @@ router.get('/telegram-settings', requireAuth, async (req, res, next) => { // Обновление telegram-настроек router.put('/telegram-settings', requireAuth, async (req, res, next) => { + // Получаем ключ шифрования + const fs = require('fs'); + const path = require('path'); + let encryptionKey = 'default-key'; + + try { + const keyPath = path.join(__dirname, '../ssl/keys/full_db_encryption.key'); + if (fs.existsSync(keyPath)) { + encryptionKey = fs.readFileSync(keyPath, 'utf8').trim(); + } + } catch (keyError) { + console.error('Error reading encryption key:', keyError); + } + try { const { bot_token, bot_username } = req.body; if (!bot_token || !bot_username) { @@ -203,14 +279,14 @@ router.put('/telegram-settings', requireAuth, async (req, res, next) => { if (rows.length) { // Обновляем существующую запись await db.getQuery()( - `UPDATE telegram_settings SET bot_token=$1, bot_username=$2, updated_at=NOW() WHERE id=$3`, - [bot_token, bot_username, rows[0].id] + `UPDATE telegram_settings SET bot_token_encrypted=encrypt_text($1, $4), bot_username_encrypted=encrypt_text($2, $4), updated_at=NOW() WHERE id=$3`, + [bot_token, bot_username, rows[0].id, encryptionKey] ); } else { // Вставляем новую await db.getQuery()( - `INSERT INTO telegram_settings (bot_token, bot_username) VALUES ($1,$2)` , - [bot_token, bot_username] + `INSERT INTO telegram_settings (bot_token_encrypted, bot_username_encrypted) VALUES (encrypt_text($1, $3), encrypt_text($2, $3))` , + [bot_token, bot_username, encryptionKey] ); } res.json({ success: true }); @@ -222,8 +298,25 @@ router.put('/telegram-settings', requireAuth, async (req, res, next) => { // Получение db-настроек router.get('/db-settings', requireAuth, async (req, res, next) => { + // Получаем ключ шифрования + const fs = require('fs'); + const path = require('path'); + let encryptionKey = 'default-key'; + try { - const { rows } = await db.getQuery()('SELECT * FROM db_settings ORDER BY id LIMIT 1'); + const keyPath = path.join(__dirname, '../ssl/keys/full_db_encryption.key'); + if (fs.existsSync(keyPath)) { + encryptionKey = fs.readFileSync(keyPath, 'utf8').trim(); + } + } catch (keyError) { + console.error('Error reading encryption key:', keyError); + } + + try { + const { rows } = await db.getQuery()( + 'SELECT id, db_port, created_at, updated_at, decrypt_text(db_host_encrypted, $1) as db_host, decrypt_text(db_name_encrypted, $1) as db_name, decrypt_text(db_user_encrypted, $1) as db_user, decrypt_text(db_password_encrypted, $1) as db_password FROM db_settings ORDER BY id LIMIT 1', + [encryptionKey] + ); if (!rows.length) return res.status(404).json({ success: false, error: 'Not found' }); const settings = rows[0]; delete settings.db_password; // не возвращаем пароль diff --git a/backend/routes/kpp.js b/backend/routes/kpp.js new file mode 100644 index 0000000..328dbd5 --- /dev/null +++ b/backend/routes/kpp.js @@ -0,0 +1,78 @@ +/** + * 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 + */ + +const express = require('express'); +const router = express.Router(); +const fs = require('fs'); +const path = require('path'); +const logger = require('../utils/logger'); + +/** + * @swagger + * tags: + * name: KPP + * description: API для КПП кодов (Код причины постановки на учет) + */ + +/** + * @swagger + * /api/kpp/codes: + * get: + * summary: Получить список КПП кодов + * tags: [KPP] + * responses: + * 200: + * description: Список КПП кодов + * content: + * application/json: + * schema: + * type: object + * properties: + * codes: + * type: array + * items: + * type: object + * properties: + * code: + * type: string + * example: "773001001" + * title: + * type: string + * example: "По месту нахождения организации" + * 500: + * description: Ошибка сервера + */ +router.get('/codes', (req, res) => { + try { + // Путь к файлу с КПП кодами + const kppFilePath = path.join(__dirname, '../db/data/kpp_codes.json'); + + // Читаем файл синхронно (для простоты, можно переделать на асинхронный) + const kppData = fs.readFileSync(kppFilePath, 'utf8'); + const kppJson = JSON.parse(kppData); + + // Возвращаем данные в том же формате, что ожидает frontend + res.json({ + codes: kppJson.kpp_codes || [] + }); + + logger.info(`[KPP] Returned ${kppJson.kpp_codes?.length || 0} KPP codes`); + } catch (error) { + logger.error('Error fetching KPP codes:', error); + res.status(500).json({ + error: 'Internal server error', + message: 'Не удалось загрузить КПП коды' + }); + } +}); + +module.exports = router; \ No newline at end of file diff --git a/backend/routes/messages.js b/backend/routes/messages.js index abaab44..b3b7d16 100644 --- a/backend/routes/messages.js +++ b/backend/routes/messages.js @@ -22,29 +22,45 @@ const { isUserBlocked } = require('../utils/userUtils'); router.get('/', async (req, res) => { const userId = req.query.userId; const conversationId = req.query.conversationId; + + // Получаем ключ шифрования + const fs = require('fs'); + const path = require('path'); + let encryptionKey = 'default-key'; + + try { + const keyPath = path.join(__dirname, '../ssl/keys/full_db_encryption.key'); + if (fs.existsSync(keyPath)) { + encryptionKey = fs.readFileSync(keyPath, 'utf8').trim(); + } + } catch (keyError) { + console.error('Error reading encryption key:', keyError); + } + try { let result; if (conversationId) { result = await db.getQuery()( - `SELECT id, user_id, sender_type, content, channel, role, direction, created_at, attachment_filename, attachment_mimetype, attachment_size, attachment_data, metadata + `SELECT id, user_id, decrypt_text(sender_type_encrypted, $2) as sender_type, decrypt_text(content_encrypted, $2) as content, decrypt_text(channel_encrypted, $2) as channel, decrypt_text(role_encrypted, $2) as role, decrypt_text(direction_encrypted, $2) as direction, created_at, decrypt_text(attachment_filename_encrypted, $2) as attachment_filename, decrypt_text(attachment_mimetype_encrypted, $2) as attachment_mimetype, attachment_size, attachment_data FROM messages WHERE conversation_id = $1 ORDER BY created_at ASC`, - [conversationId] + [conversationId, encryptionKey] ); } else if (userId) { result = await db.getQuery()( - `SELECT id, user_id, sender_type, content, channel, role, direction, created_at, attachment_filename, attachment_mimetype, attachment_size, attachment_data, metadata + `SELECT id, user_id, decrypt_text(sender_type_encrypted, $2) as sender_type, decrypt_text(content_encrypted, $2) as content, decrypt_text(channel_encrypted, $2) as channel, decrypt_text(role_encrypted, $2) as role, decrypt_text(direction_encrypted, $2) as direction, created_at, decrypt_text(attachment_filename_encrypted, $2) as attachment_filename, decrypt_text(attachment_mimetype_encrypted, $2) as attachment_mimetype, attachment_size, attachment_data FROM messages WHERE user_id = $1 ORDER BY created_at ASC`, - [userId] + [userId, encryptionKey] ); } else { result = await db.getQuery()( - `SELECT id, user_id, sender_type, content, channel, role, direction, created_at, attachment_filename, attachment_mimetype, attachment_size, attachment_data, metadata + `SELECT id, user_id, decrypt_text(sender_type_encrypted, $1) as sender_type, decrypt_text(content_encrypted, $1) as content, decrypt_text(channel_encrypted, $1) as channel, decrypt_text(role_encrypted, $1) as role, decrypt_text(direction_encrypted, $1) as direction, created_at, decrypt_text(attachment_filename_encrypted, $1) as attachment_filename, decrypt_text(attachment_mimetype_encrypted, $1) as attachment_mimetype, attachment_size, attachment_data FROM messages - ORDER BY created_at ASC` + ORDER BY created_at ASC`, + [encryptionKey] ); } res.json(result.rows); @@ -55,7 +71,22 @@ router.get('/', async (req, res) => { // POST /api/messages router.post('/', async (req, res) => { - const { user_id, sender_type, content, channel, role, direction, attachment_filename, attachment_mimetype, attachment_size, attachment_data, metadata } = req.body; + const { user_id, sender_type, content, channel, role, direction, attachment_filename, attachment_mimetype, attachment_size, attachment_data } = req.body; + + // Получаем ключ шифрования + const fs = require('fs'); + const path = require('path'); + let encryptionKey = 'default-key'; + + try { + const keyPath = path.join(__dirname, '../ssl/keys/full_db_encryption.key'); + if (fs.existsSync(keyPath)) { + encryptionKey = fs.readFileSync(keyPath, 'utf8').trim(); + } + } catch (keyError) { + console.error('Error reading encryption key:', keyError); + } + try { // Проверка блокировки пользователя if (await isUserBlocked(user_id)) { @@ -64,8 +95,8 @@ router.post('/', async (req, res) => { // Проверка наличия идентификатора для выбранного канала if (channel === 'email') { const emailIdentity = await db.getQuery()( - 'SELECT provider_id FROM user_identities WHERE user_id = $1 AND provider = $2 LIMIT 1', - [user_id, 'email'] + 'SELECT decrypt_text(provider_id_encrypted, $3) as provider_id FROM user_identities WHERE user_id = $1 AND provider_encrypted = encrypt_text($2, $3) LIMIT 1', + [user_id, 'email', encryptionKey] ); if (emailIdentity.rows.length === 0) { return res.status(400).json({ error: 'У пользователя не указан email. Сообщение не отправлено.' }); @@ -73,8 +104,8 @@ router.post('/', async (req, res) => { } if (channel === 'telegram') { const tgIdentity = await db.getQuery()( - 'SELECT provider_id FROM user_identities WHERE user_id = $1 AND provider = $2 LIMIT 1', - [user_id, 'telegram'] + 'SELECT decrypt_text(provider_id_encrypted, $3) as provider_id FROM user_identities WHERE user_id = $1 AND provider_encrypted = encrypt_text($2, $3) LIMIT 1', + [user_id, 'telegram', encryptionKey] ); if (tgIdentity.rows.length === 0) { return res.status(400).json({ error: 'У пользователя не привязан Telegram. Сообщение не отправлено.' }); @@ -82,8 +113,8 @@ router.post('/', async (req, res) => { } if (channel === 'wallet' || channel === 'web3' || channel === 'web') { const walletIdentity = await db.getQuery()( - 'SELECT provider_id FROM user_identities WHERE user_id = $1 AND provider = $2 LIMIT 1', - [user_id, 'wallet'] + 'SELECT decrypt_text(provider_id_encrypted, $3) as provider_id FROM user_identities WHERE user_id = $1 AND provider_encrypted = encrypt_text($2, $3) LIMIT 1', + [user_id, 'wallet', encryptionKey] ); if (walletIdentity.rows.length === 0) { return res.status(400).json({ error: 'У пользователя не привязан кошелёк. Сообщение не отправлено.' }); @@ -91,16 +122,16 @@ router.post('/', async (req, res) => { } // 1. Проверяем, есть ли беседа для user_id let conversationResult = await db.getQuery()( - 'SELECT * FROM conversations WHERE user_id = $1 ORDER BY updated_at DESC, created_at DESC LIMIT 1', - [user_id] + 'SELECT id, user_id, created_at, updated_at, decrypt_text(title_encrypted, $2) as title FROM conversations WHERE user_id = $1 ORDER BY updated_at DESC, created_at DESC LIMIT 1', + [user_id, encryptionKey] ); let conversation; if (conversationResult.rows.length === 0) { // 2. Если нет — создаём новую беседу const title = `Чат с пользователем ${user_id}`; const newConv = await db.getQuery()( - 'INSERT INTO conversations (user_id, title, created_at, updated_at) VALUES ($1, $2, NOW(), NOW()) RETURNING *', - [user_id, title] + 'INSERT INTO conversations (user_id, title_encrypted, created_at, updated_at) VALUES ($1, encrypt_text($2, $3), NOW(), NOW()) RETURNING *', + [user_id, title, encryptionKey] ); conversation = newConv.rows[0]; } else { @@ -108,9 +139,9 @@ router.post('/', async (req, res) => { } // 3. Сохраняем сообщение с conversation_id const result = await db.getQuery()( - `INSERT INTO messages (user_id, conversation_id, sender_type, content, channel, role, direction, created_at, attachment_filename, attachment_mimetype, attachment_size, attachment_data, metadata) - VALUES ($1,$2,$3,$4,$5,$6,$7,NOW(),$8,$9,$10,$11,$12) RETURNING *`, - [user_id, conversation.id, sender_type, content, channel, role, direction, attachment_filename, attachment_mimetype, attachment_size, attachment_data, metadata] + `INSERT INTO messages (user_id, conversation_id, sender_type_encrypted, content_encrypted, channel_encrypted, role_encrypted, direction_encrypted, created_at, attachment_filename_encrypted, attachment_mimetype_encrypted, attachment_size, attachment_data) + VALUES ($1,$2,encrypt_text($3,$12),encrypt_text($4,$12),encrypt_text($5,$12),encrypt_text($6,$12),encrypt_text($7,$12),NOW(),encrypt_text($8,$12),encrypt_text($9,$12),$10,$11) RETURNING *`, + [user_id, conversation.id, sender_type, content, channel, role, direction, attachment_filename, attachment_mimetype, attachment_size, attachment_data, encryptionKey] ); // 4. Если это исходящее сообщение для Telegram — отправляем через бота if (channel === 'telegram' && direction === 'out') { @@ -118,8 +149,8 @@ router.post('/', async (req, res) => { console.log(`[messages.js] Попытка отправки сообщения в Telegram для user_id=${user_id}`); // Получаем Telegram ID пользователя const tgIdentity = await db.getQuery()( - 'SELECT provider_id FROM user_identities WHERE user_id = $1 AND provider = $2 LIMIT 1', - [user_id, 'telegram'] + 'SELECT decrypt_text(provider_id_encrypted, $3) as provider_id FROM user_identities WHERE user_id = $1 AND provider_encrypted = encrypt_text($2, $3) LIMIT 1', + [user_id, 'telegram', encryptionKey] ); console.log(`[messages.js] Результат поиска Telegram ID:`, tgIdentity.rows); if (tgIdentity.rows.length > 0) { @@ -144,8 +175,8 @@ router.post('/', async (req, res) => { try { // Получаем email пользователя const emailIdentity = await db.getQuery()( - 'SELECT provider_id FROM user_identities WHERE user_id = $1 AND provider = $2 LIMIT 1', - [user_id, 'email'] + 'SELECT decrypt_text(provider_id_encrypted, $3) as provider_id FROM user_identities WHERE user_id = $1 AND provider_encrypted = encrypt_text($2, $3) LIMIT 1', + [user_id, 'email', encryptionKey] ); if (emailIdentity.rows.length > 0) { const email = emailIdentity.rows[0].provider_id; @@ -237,24 +268,39 @@ router.post('/broadcast', async (req, res) => { if (!user_id || !content) { return res.status(400).json({ error: 'user_id и content обязательны' }); } + + // Получаем ключ шифрования + const fs = require('fs'); + const path = require('path'); + let encryptionKey = 'default-key'; + + try { + const keyPath = path.join(__dirname, '../ssl/keys/full_db_encryption.key'); + if (fs.existsSync(keyPath)) { + encryptionKey = fs.readFileSync(keyPath, 'utf8').trim(); + } + } catch (keyError) { + console.error('Error reading encryption key:', keyError); + } + try { // Получаем все идентификаторы пользователя const identitiesRes = await db.getQuery()( - 'SELECT provider, provider_id FROM user_identities WHERE user_id = $1', - [user_id] + 'SELECT decrypt_text(provider_encrypted, $2) as provider, decrypt_text(provider_id_encrypted, $2) as provider_id FROM user_identities WHERE user_id = $1', + [user_id, encryptionKey] ); const identities = identitiesRes.rows; // --- Найти или создать беседу (conversation) --- let conversationResult = await db.getQuery()( - 'SELECT * FROM conversations WHERE user_id = $1 ORDER BY updated_at DESC, created_at DESC LIMIT 1', - [user_id] + 'SELECT id, user_id, created_at, updated_at, decrypt_text(title_encrypted, $2) as title FROM conversations WHERE user_id = $1 ORDER BY updated_at DESC, created_at DESC LIMIT 1', + [user_id, encryptionKey] ); let conversation; if (conversationResult.rows.length === 0) { const title = `Чат с пользователем ${user_id}`; const newConv = await db.getQuery()( - 'INSERT INTO conversations (user_id, title, created_at, updated_at) VALUES ($1, $2, NOW(), NOW()) RETURNING *', - [user_id, title] + 'INSERT INTO conversations (user_id, title_encrypted, created_at, updated_at) VALUES ($1, encrypt_text($2, $3), NOW(), NOW()) RETURNING *', + [user_id, title, encryptionKey] ); conversation = newConv.rows[0]; } else { @@ -269,9 +315,9 @@ router.post('/broadcast', async (req, res) => { await emailBot.sendEmail(email, 'Новое сообщение', content); // Сохраняем в messages с conversation_id await db.getQuery()( - `INSERT INTO messages (user_id, conversation_id, sender_type, content, channel, role, direction, created_at, metadata) - VALUES ($1, $2, $3, $4, $5, $6, $7, NOW(), $8)`, - [user_id, conversation.id, 'admin', content, 'email', 'user', 'out', JSON.stringify({ broadcast: true })] + `INSERT INTO messages (user_id, conversation_id, sender_type_encrypted, content_encrypted, channel_encrypted, role_encrypted, direction_encrypted, created_at) + VALUES ($1, $2, encrypt_text($3, $8), encrypt_text($4, $8), encrypt_text($5, $8), encrypt_text($6, $8), encrypt_text($7, $8), NOW())`, + [user_id, conversation.id, 'admin', content, 'email', 'user', 'out', encryptionKey] ); results.push({ channel: 'email', status: 'sent' }); sent = true; @@ -286,9 +332,9 @@ router.post('/broadcast', async (req, res) => { const bot = await telegramBot.getBot(); await bot.telegram.sendMessage(telegram, content); await db.getQuery()( - `INSERT INTO messages (user_id, conversation_id, sender_type, content, channel, role, direction, created_at, metadata) - VALUES ($1, $2, $3, $4, $5, $6, $7, NOW(), $8)`, - [user_id, conversation.id, 'admin', content, 'telegram', 'user', 'out', JSON.stringify({ broadcast: true })] + `INSERT INTO messages (user_id, conversation_id, sender_type_encrypted, content_encrypted, channel_encrypted, role_encrypted, direction_encrypted, created_at) + VALUES ($1, $2, encrypt_text($3, $8), encrypt_text($4, $8), encrypt_text($5, $8), encrypt_text($6, $8), encrypt_text($7, $8), NOW())`, + [user_id, conversation.id, 'admin', content, 'telegram', 'user', 'out', encryptionKey] ); results.push({ channel: 'telegram', status: 'sent' }); sent = true; @@ -301,9 +347,9 @@ router.post('/broadcast', async (req, res) => { if (wallet) { // Здесь можно реализовать отправку через web3, если нужно await db.getQuery()( - `INSERT INTO messages (user_id, conversation_id, sender_type, content, channel, role, direction, created_at, metadata) - VALUES ($1, $2, $3, $4, $5, $6, $7, NOW(), $8)`, - [user_id, conversation.id, 'admin', content, 'wallet', 'user', 'out', JSON.stringify({ broadcast: true })] + `INSERT INTO messages (user_id, conversation_id, sender_type_encrypted, content_encrypted, channel_encrypted, role_encrypted, direction_encrypted, created_at) + VALUES ($1, $2, encrypt_text($3, $8), encrypt_text($4, $8), encrypt_text($5, $8), encrypt_text($6, $8), encrypt_text($7, $8), NOW())`, + [user_id, conversation.id, 'admin', content, 'wallet', 'user', 'out', encryptionKey] ); results.push({ channel: 'wallet', status: 'saved' }); sent = true; diff --git a/backend/routes/ollama.js b/backend/routes/ollama.js new file mode 100644 index 0000000..e32f053 --- /dev/null +++ b/backend/routes/ollama.js @@ -0,0 +1,173 @@ +/** + * 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 + */ + +const express = require('express'); +const router = express.Router(); +const { exec } = require('child_process'); +const util = require('util'); +const execAsync = util.promisify(exec); +const logger = require('../utils/logger'); +const { requireAuth } = require('../middleware/auth'); + +// Проверка статуса подключения к Ollama +router.get('/status', requireAuth, async (req, res) => { + try { + // Проверяем, что контейнер Ollama запущен + const { stdout } = await execAsync('docker ps --filter "name=dapp-ollama" --format "{{.Names}}"'); + const isContainerRunning = stdout.trim() === 'dapp-ollama'; + + if (!isContainerRunning) { + return res.json({ connected: false, error: 'Ollama container not running' }); + } + + // Проверяем API Ollama + try { + const { stdout: apiResponse } = await execAsync('docker exec dapp-ollama ollama list'); + return res.json({ connected: true, message: 'Ollama is running' }); + } catch (apiError) { + return res.json({ connected: false, error: 'Ollama API not responding' }); + } + } catch (error) { + logger.error('Error checking Ollama status:', error); + res.status(500).json({ connected: false, error: 'Failed to check Ollama status' }); + } +}); + +// Получение списка установленных моделей +router.get('/models', requireAuth, async (req, res) => { + try { + const { stdout } = await execAsync('docker exec dapp-ollama ollama list'); + const lines = stdout.trim().split('\n').slice(1); // Пропускаем заголовок + + const models = lines.map(line => { + const parts = line.trim().split(/\s+/); + if (parts.length >= 4) { + return { + name: parts[0], + id: parts[1], + size: parseInt(parts[2]) || 0, + modified: parts.slice(3).join(' ') + }; + } + return null; + }).filter(model => model !== null); + + res.json({ models }); + } catch (error) { + logger.error('Error getting Ollama models:', error); + res.status(500).json({ error: 'Failed to get models' }); + } +}); + +// Установка модели +router.post('/install', requireAuth, async (req, res) => { + const { model } = req.body; + + if (!model) { + return res.status(400).json({ error: 'Model name is required' }); + } + + try { + logger.info(`Starting installation of model: ${model}`); + + // Запускаем установку в фоне + const installProcess = exec(`docker exec dapp-ollama ollama pull ${model}`, (error, stdout, stderr) => { + if (error) { + logger.error(`Error installing model ${model}:`, error); + } else { + logger.info(`Successfully installed model: ${model}`); + } + }); + + // Возвращаем ответ сразу, не ждем завершения + res.json({ + success: true, + message: `Installation of ${model} started`, + processId: installProcess.pid + }); + } catch (error) { + logger.error('Error starting model installation:', error); + res.status(500).json({ error: 'Failed to start installation' }); + } +}); + +// Удаление модели +router.delete('/models/:modelName', requireAuth, async (req, res) => { + const { modelName } = req.params; + + if (!modelName) { + return res.status(400).json({ error: 'Model name is required' }); + } + + try { + logger.info(`Removing model: ${modelName}`); + + const { stdout, stderr } = await execAsync(`docker exec dapp-ollama ollama rm ${modelName}`); + + if (stderr && !stderr.includes('deleted')) { + throw new Error(stderr); + } + + logger.info(`Successfully removed model: ${modelName}`); + res.json({ success: true, message: `Model ${modelName} removed successfully` }); + } catch (error) { + logger.error(`Error removing model ${modelName}:`, error); + res.status(500).json({ error: `Failed to remove model: ${error.message}` }); + } +}); + +// Получение информации о модели +router.get('/models/:modelName', requireAuth, async (req, res) => { + const { modelName } = req.params; + + try { + const { stdout } = await execAsync(`docker exec dapp-ollama ollama show ${modelName}`); + res.json({ model: modelName, info: stdout }); + } catch (error) { + logger.error(`Error getting model info for ${modelName}:`, error); + res.status(404).json({ error: 'Model not found' }); + } +}); + +// Поиск моделей в реестре (если поддерживается) +router.get('/search', requireAuth, async (req, res) => { + const { query } = req.query; + + if (!query) { + return res.status(400).json({ error: 'Search query is required' }); + } + + try { + // Пока просто возвращаем популярные модели + const popularModels = [ + 'qwen2.5:7b', + 'llama2:7b', + 'mistral:7b', + 'codellama:7b', + 'llama2:13b', + 'qwen2.5:14b', + 'gemma:7b', + 'phi3:3.8b' + ]; + + const filteredModels = popularModels.filter(model => + model.toLowerCase().includes(query.toLowerCase()) + ); + + res.json({ models: filteredModels }); + } catch (error) { + logger.error('Error searching models:', error); + res.status(500).json({ error: 'Failed to search models' }); + } +}); + +module.exports = router; \ No newline at end of file diff --git a/backend/routes/russian-classifiers.js b/backend/routes/russian-classifiers.js new file mode 100644 index 0000000..e9c0862 --- /dev/null +++ b/backend/routes/russian-classifiers.js @@ -0,0 +1,184 @@ +/** + * 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 + */ + +const express = require('express'); +const path = require('path'); +const fs = require('fs'); +const router = express.Router(); + + +/** + * @route GET /api/russian-classifiers/oktmo + * @desc Получить список кодов ОКТМО (муниципальные образования) + * @access Public + */ +router.get('/oktmo', async (req, res, next) => { + try { + const filePath = path.join(__dirname, '../db/data/oktmo.json'); + + if (!fs.existsSync(filePath)) { + return res.status(404).json({ + success: false, + message: 'Файл с кодами ОКТМО не найден' + }); + } + + const data = fs.readFileSync(filePath, 'utf8'); + const oktmoData = JSON.parse(data); + + res.json({ + success: true, + data: oktmoData.oktmo_codes || [], + count: oktmoData.oktmo_codes ? oktmoData.oktmo_codes.length : 0 + }); + + } catch (error) { + console.error('Ошибка при получении кодов ОКТМО:', error); + next(error); + } +}); + +/** + * @route GET /api/russian-classifiers/okved + * @desc Получить список кодов ОКВЭД (виды экономической деятельности) + * @access Public + */ +router.get('/okved', async (req, res, next) => { + try { + const filePath = path.join(__dirname, '../db/data/okved.json'); + + if (!fs.existsSync(filePath)) { + return res.status(404).json({ + success: false, + message: 'Файл с кодами ОКВЭД не найден' + }); + } + + const data = fs.readFileSync(filePath, 'utf8'); + const okvedData = JSON.parse(data); + + // Для ОКВЭД можем добавить фильтрацию по запросу + const { search, level } = req.query; + let codes = okvedData.okved_codes || []; + + // Фильтрация по поисковому запросу + if (search) { + const searchTerm = search.toLowerCase(); + codes = codes.filter(code => + code.code.toLowerCase().includes(searchTerm) || + code.title.toLowerCase().includes(searchTerm) + ); + } + + // Фильтрация по уровню (количество точек в коде) + if (level) { + const targetLevel = parseInt(level); + codes = codes.filter(code => { + const codeLevel = (code.code.match(/\./g) || []).length + 1; + return codeLevel === targetLevel; + }); + } + + // Ограничиваем количество результатов для производительности + const limit = parseInt(req.query.limit) || 2000; // Увеличили лимит для полного списка + codes = codes.slice(0, limit); + + res.json({ + success: true, + data: codes, + count: codes.length, + total: okvedData.okved_codes ? okvedData.okved_codes.length : 0 + }); + + } catch (error) { + console.error('Ошибка при получении кодов ОКВЭД:', error); + next(error); + } +}); + +/** + * @route GET /api/russian-classifiers/okved/:code + * @desc Получить информацию о коде ОКВЭД + * @access Public + */ +router.get('/okved/:code', async (req, res, next) => { + try { + const { code } = req.params; + const filePath = path.join(__dirname, '../db/data/okved.json'); + + if (!fs.existsSync(filePath)) { + return res.status(404).json({ + success: false, + message: 'Файл с кодами ОКВЭД не найден' + }); + } + + const data = fs.readFileSync(filePath, 'utf8'); + const okvedData = JSON.parse(data); + + const okvedCode = okvedData.okved_codes.find(c => c.code === code); + + if (!okvedCode) { + return res.status(404).json({ + success: false, + message: `Код ОКВЭД ${code} не найден` + }); + } + + res.json({ + success: true, + data: okvedCode + }); + + } catch (error) { + console.error('Ошибка при получении информации о коде ОКВЭД:', error); + next(error); + } +}); + +/** + * @route GET /api/russian-classifiers/all + * @desc Получить все российские классификаторы одним запросом + * @access Public + */ +router.get('/all', async (req, res, next) => { + try { + const oktmoPath = path.join(__dirname, '../db/data/oktmo.json'); + const okvedPath = path.join(__dirname, '../db/data/okved.json'); + + const result = {}; + + // ОКТМО + if (fs.existsSync(oktmoPath)) { + const oktmoData = JSON.parse(fs.readFileSync(oktmoPath, 'utf8')); + result.oktmo = oktmoData.oktmo_codes || []; + } + + // ОКВЭД (полный список) + if (fs.existsSync(okvedPath)) { + const okvedData = JSON.parse(fs.readFileSync(okvedPath, 'utf8')); + // Отдаем ВСЕ коды ОКВЭД - пользователь хочет полный список + result.okved = okvedData.okved_codes || []; + } + + res.json({ + success: true, + data: result + }); + + } catch (error) { + console.error('Ошибка при получении всех российских классификаторов:', error); + next(error); + } +}); + +module.exports = router; \ No newline at end of file diff --git a/backend/routes/settings.js b/backend/routes/settings.js index 7f4949e..129de8a 100644 --- a/backend/routes/settings.js +++ b/backend/routes/settings.js @@ -45,7 +45,25 @@ router.get('/rpc', async (req, res, next) => { } } - const rpcConfigs = await rpcProviderService.getAllRpcProviders(); + // Получаем ключ шифрования + const fs = require('fs'); + const path = require('path'); + let encryptionKey = 'default-key'; + + try { + const keyPath = path.join(__dirname, '../ssl/keys/full_db_encryption.key'); + if (fs.existsSync(keyPath)) { + encryptionKey = fs.readFileSync(keyPath, 'utf8').trim(); + } + } catch (keyError) { + console.error('Error reading encryption key:', keyError); + } + + const rpcProvidersResult = await db.getQuery()( + 'SELECT id, chain_id, created_at, updated_at, decrypt_text(network_id_encrypted, $1) as network_id, decrypt_text(rpc_url_encrypted, $1) as rpc_url FROM rpc_providers', + [encryptionKey] + ); + const rpcConfigs = rpcProvidersResult.rows; if (isAdmin) { // Для админов возвращаем полные данные @@ -108,7 +126,25 @@ router.delete('/rpc/:networkId', requireAdmin, async (req, res, next) => { // Получение токенов для аутентификации router.get('/auth-tokens', async (req, res, next) => { try { - const authTokens = await authTokenService.getAllAuthTokens(); + // Получаем ключ шифрования + const fs = require('fs'); + const path = require('path'); + let encryptionKey = 'default-key'; + + try { + const keyPath = path.join(__dirname, '../ssl/keys/full_db_encryption.key'); + if (fs.existsSync(keyPath)) { + encryptionKey = fs.readFileSync(keyPath, 'utf8').trim(); + } + } catch (keyError) { + console.error('Error reading encryption key:', keyError); + } + + const tokensResult = await db.getQuery()( + 'SELECT id, min_balance, created_at, updated_at, decrypt_text(name_encrypted, $1) as name, decrypt_text(address_encrypted, $1) as address, decrypt_text(network_encrypted, $1) as network FROM auth_tokens', + [encryptionKey] + ); + const authTokens = tokensResult.rows; // Возвращаем полные данные для всех пользователей (включая гостевых) res.json({ success: true, data: authTokens }); diff --git a/backend/routes/tables.js b/backend/routes/tables.js index f4fc83b..2a68a0a 100644 --- a/backend/routes/tables.js +++ b/backend/routes/tables.js @@ -26,7 +26,21 @@ router.use((req, res, next) => { // Получить список всех таблиц (доступно всем) router.get('/', async (req, res, next) => { try { - const result = await db.getQuery()('SELECT * FROM user_tables ORDER BY id'); + // Получаем ключ шифрования + const fs = require('fs'); + const path = require('path'); + let encryptionKey = 'default-key'; + + try { + const keyPath = path.join(__dirname, '../ssl/keys/full_db_encryption.key'); + if (fs.existsSync(keyPath)) { + encryptionKey = fs.readFileSync(keyPath, 'utf8').trim(); + } + } catch (keyError) { + console.error('Error reading encryption key:', keyError); + } + + const result = await db.getQuery()('SELECT id, created_at, updated_at, is_rag_source_id, decrypt_text(name_encrypted, $1) as name, decrypt_text(description_encrypted, $1) as description FROM user_tables ORDER BY id', [encryptionKey]); res.json(result.rows); } catch (err) { next(err); @@ -37,9 +51,24 @@ router.get('/', async (req, res, next) => { router.post('/', async (req, res, next) => { try { const { name, description, isRagSourceId } = req.body; + + // Получаем ключ шифрования + const fs = require('fs'); + const path = require('path'); + let encryptionKey = 'default-key'; + + try { + const keyPath = path.join(__dirname, '../ssl/keys/full_db_encryption.key'); + if (fs.existsSync(keyPath)) { + encryptionKey = fs.readFileSync(keyPath, 'utf8').trim(); + } + } catch (keyError) { + console.error('Error reading encryption key:', keyError); + } + const result = await db.getQuery()( - 'INSERT INTO user_tables (name, description, is_rag_source_id) VALUES ($1, $2, $3) RETURNING *', - [name, description || null, isRagSourceId || 2] + 'INSERT INTO user_tables (name_encrypted, description_encrypted, is_rag_source_id) VALUES (encrypt_text($1, $4), encrypt_text($2, $4), $3) RETURNING *', + [name, description || null, isRagSourceId || 2, encryptionKey] ); res.json(result.rows[0]); } catch (err) { @@ -47,15 +76,58 @@ router.post('/', async (req, res, next) => { } }); +// Получить данные из таблицы is_rag_source с расшифровкой +router.get('/rag-sources', async (req, res, next) => { + try { + // Получаем ключ шифрования + const fs = require('fs'); + const path = require('path'); + let encryptionKey = 'default-key'; + + try { + const keyPath = path.join(__dirname, '../ssl/keys/full_db_encryption.key'); + if (fs.existsSync(keyPath)) { + encryptionKey = fs.readFileSync(keyPath, 'utf8').trim(); + } + } catch (keyError) { + console.error('Error reading encryption key:', keyError); + } + + const result = await db.getQuery()( + 'SELECT id, decrypt_text(name_encrypted, $1) as name FROM is_rag_source ORDER BY id', + [encryptionKey] + ); + + res.json(result.rows); + } catch (err) { + console.error('[RAG Sources] Error:', err); + next(err); + } +}); + // Получить структуру и данные таблицы (доступно всем) router.get('/:id', async (req, res, next) => { try { const tableId = req.params.id; - const tableMetaResult = await db.getQuery()('SELECT name, description FROM user_tables WHERE id = $1', [tableId]); + // Получаем ключ шифрования + const fs = require('fs'); + const path = require('path'); + let encryptionKey = 'default-key'; + + try { + const keyPath = path.join(__dirname, '../ssl/keys/full_db_encryption.key'); + if (fs.existsSync(keyPath)) { + encryptionKey = fs.readFileSync(keyPath, 'utf8').trim(); + } + } catch (keyError) { + console.error('Error reading encryption key:', keyError); + } + + const tableMetaResult = await db.getQuery()('SELECT decrypt_text(name_encrypted, $2) as name, decrypt_text(description_encrypted, $2) as description FROM user_tables WHERE id = $1', [tableId, encryptionKey]); const tableMeta = tableMetaResult.rows[0] || { name: '', description: '' }; - const columns = (await db.getQuery()('SELECT * FROM user_columns WHERE table_id = $1 ORDER BY "order" ASC, id ASC', [tableId])).rows; + const columns = (await db.getQuery()('SELECT id, table_id, "order", created_at, updated_at, decrypt_text(name_encrypted, $2) as name, decrypt_text(type_encrypted, $2) as type, decrypt_text(placeholder_encrypted, $2) as placeholder_encrypted, placeholder FROM user_columns WHERE table_id = $1 ORDER BY "order" ASC, id ASC', [tableId, encryptionKey])).rows; const rows = (await db.getQuery()('SELECT * FROM user_rows WHERE table_id = $1 ORDER BY id', [tableId])).rows; - const cellValues = (await db.getQuery()('SELECT * FROM user_cell_values WHERE row_id IN (SELECT id FROM user_rows WHERE table_id = $1)', [tableId])).rows; + const cellValues = (await db.getQuery()('SELECT id, row_id, column_id, created_at, updated_at, decrypt_text(value_encrypted, $2) as value FROM user_cell_values WHERE row_id IN (SELECT id FROM user_rows WHERE table_id = $1)', [tableId, encryptionKey])).rows; res.json({ name: tableMeta.name, description: tableMeta.description, columns, rows, cellValues }); } catch (err) { next(err); @@ -98,13 +170,28 @@ router.post('/:id/columns', async (req, res, next) => { if (purpose) { finalOptions.purpose = purpose; } + + // Получаем ключ шифрования + const fs = require('fs'); + const path = require('path'); + let encryptionKey = 'default-key'; + + try { + const keyPath = path.join(__dirname, '../ssl/keys/full_db_encryption.key'); + if (fs.existsSync(keyPath)) { + encryptionKey = fs.readFileSync(keyPath, 'utf8').trim(); + } + } catch (keyError) { + console.error('Error reading encryption key:', keyError); + } + // Получаем уже существующие плейсхолдеры в таблице const existing = (await db.getQuery()('SELECT placeholder FROM user_columns WHERE table_id = $1', [tableId])).rows; const existingPlaceholders = existing.map(c => c.placeholder).filter(Boolean); const placeholder = generatePlaceholder(name, existingPlaceholders); const result = await db.getQuery()( - 'INSERT INTO user_columns (table_id, name, type, options, "order", placeholder) VALUES ($1, $2, $3, $4, $5, $6) RETURNING *', - [tableId, name, type, finalOptions ? JSON.stringify(finalOptions) : null, order || 0, placeholder] + 'INSERT INTO user_columns (table_id, name_encrypted, type_encrypted, placeholder_encrypted, "order", placeholder) VALUES ($1, encrypt_text($2, $7), encrypt_text($3, $7), encrypt_text($6, $7), $4, $5) RETURNING *', + [tableId, name, type, order || 0, placeholder, placeholder, encryptionKey] ); res.json(result.rows[0]); } catch (err) { @@ -121,8 +208,22 @@ router.post('/:id/rows', async (req, res, next) => { [tableId] ); console.log('[DEBUG][addRow] result.rows[0]:', result.rows[0]); + // Получаем ключ шифрования + const fs = require('fs'); + const path = require('path'); + let encryptionKey = 'default-key'; + + try { + const keyPath = path.join(__dirname, '../ssl/keys/full_db_encryption.key'); + if (fs.existsSync(keyPath)) { + encryptionKey = fs.readFileSync(keyPath, 'utf8').trim(); + } + } catch (keyError) { + console.error('Error reading encryption key:', keyError); + } + // Получаем все строки и значения для upsert - const rows = (await db.getQuery()('SELECT r.id as row_id, c.value as text, c2.value as answer FROM user_rows r LEFT JOIN user_cell_values c ON c.row_id = r.id AND c.column_id = 1 LEFT JOIN user_cell_values c2 ON c2.row_id = r.id AND c2.column_id = 2 WHERE r.table_id = $1', [tableId])).rows; + const rows = (await db.getQuery()('SELECT r.id as row_id, decrypt_text(c.value_encrypted, $2) as text, decrypt_text(c2.value_encrypted, $2) as answer FROM user_rows r LEFT JOIN user_cell_values c ON c.row_id = r.id AND c.column_id = 1 LEFT JOIN user_cell_values c2 ON c2.row_id = r.id AND c2.column_id = 2 WHERE r.table_id = $1', [tableId, encryptionKey])).rows; const upsertRows = rows.filter(r => r.row_id && r.text).map(r => ({ row_id: r.row_id, text: r.text, metadata: { answer: r.answer } })); console.log('[DEBUG][upsertRows]', upsertRows); if (upsertRows.length > 0) { @@ -140,10 +241,24 @@ router.get('/:id/rows', async (req, res, next) => { try { const tableId = req.params.id; const { product, tags, ...relationFilters } = req.query; // tags = "B2B,VIP", relation_{colId}=rowId + // Получаем ключ шифрования + const fs = require('fs'); + const path = require('path'); + let encryptionKey = 'default-key'; + + try { + const keyPath = path.join(__dirname, '../ssl/keys/full_db_encryption.key'); + if (fs.existsSync(keyPath)) { + encryptionKey = fs.readFileSync(keyPath, 'utf8').trim(); + } + } catch (keyError) { + console.error('Error reading encryption key:', keyError); + } + // Получаем все столбцы, строки и значения ячеек - const columns = (await db.getQuery()('SELECT * FROM user_columns WHERE table_id = $1', [tableId])).rows; + const columns = (await db.getQuery()('SELECT id, table_id, "order", created_at, updated_at, decrypt_text(name_encrypted, $2) as name, decrypt_text(type_encrypted, $2) as type, decrypt_text(placeholder_encrypted, $2) as placeholder_encrypted, placeholder FROM user_columns WHERE table_id = $1', [tableId, encryptionKey])).rows; const rows = (await db.getQuery()('SELECT * FROM user_rows WHERE table_id = $1', [tableId])).rows; - const cellValues = (await db.getQuery()('SELECT * FROM user_cell_values WHERE row_id IN (SELECT id FROM user_rows WHERE table_id = $1)', [tableId])).rows; + const cellValues = (await db.getQuery()('SELECT id, row_id, column_id, created_at, updated_at, decrypt_text(value_encrypted, $2) as value FROM user_cell_values WHERE row_id IN (SELECT id FROM user_rows WHERE table_id = $1)', [tableId, encryptionKey])).rows; // Находим id нужных колонок const productCol = columns.find(c => c.options && c.options.purpose === 'product'); @@ -210,9 +325,23 @@ router.patch('/cell/:cellId', async (req, res, next) => { try { const cellId = req.params.cellId; const { value } = req.body; + // Получаем ключ шифрования + const fs = require('fs'); + const path = require('path'); + let encryptionKey = 'default-key'; + + try { + const keyPath = path.join(__dirname, '../ssl/keys/full_db_encryption.key'); + if (fs.existsSync(keyPath)) { + encryptionKey = fs.readFileSync(keyPath, 'utf8').trim(); + } + } catch (keyError) { + console.error('Error reading encryption key:', keyError); + } + const result = await db.getQuery()( - 'UPDATE user_cell_values SET value = $1, updated_at = NOW() WHERE id = $2 RETURNING *', - [value, cellId] + 'UPDATE user_cell_values SET value_encrypted = encrypt_text($1, $3), updated_at = NOW() WHERE id = $2 RETURNING *', + [value, cellId, encryptionKey] ); // Получаем row_id и table_id const row = (await db.getQuery()('SELECT row_id FROM user_cell_values WHERE id = $1', [cellId])).rows[0]; @@ -222,7 +351,7 @@ router.patch('/cell/:cellId', async (req, res, next) => { if (table) { const tableId = table.table_id; // Получаем всю строку для upsert - const rowData = (await db.getQuery()('SELECT r.id as row_id, c.value as text, c2.value as answer FROM user_rows r LEFT JOIN user_cell_values c ON c.row_id = r.id AND c.column_id = 1 LEFT JOIN user_cell_values c2 ON c2.row_id = r.id AND c2.column_id = 2 WHERE r.id = $1', [rowId])).rows[0]; + const rowData = (await db.getQuery()('SELECT r.id as row_id, decrypt_text(c.value_encrypted, $2) as text, decrypt_text(c2.value_encrypted, $2) as answer FROM user_rows r LEFT JOIN user_cell_values c ON c.row_id = r.id AND c.column_id = 1 LEFT JOIN user_cell_values c2 ON c2.row_id = r.id AND c2.column_id = 2 WHERE r.id = $1', [rowId, encryptionKey])).rows[0]; if (rowData) { const upsertRows = [{ row_id: rowData.row_id, text: rowData.text, metadata: { answer: rowData.answer } }].filter(r => r.row_id && r.text); console.log('[DEBUG][upsertRows]', upsertRows); @@ -242,18 +371,32 @@ router.patch('/cell/:cellId', async (req, res, next) => { router.post('/cell', async (req, res, next) => { try { const { row_id, column_id, value } = req.body; + // Получаем ключ шифрования + const fs = require('fs'); + const path = require('path'); + let encryptionKey = 'default-key'; + + try { + const keyPath = path.join(__dirname, '../ssl/keys/full_db_encryption.key'); + if (fs.existsSync(keyPath)) { + encryptionKey = fs.readFileSync(keyPath, 'utf8').trim(); + } + } catch (keyError) { + console.error('Error reading encryption key:', keyError); + } + const result = await db.getQuery()( - `INSERT INTO user_cell_values (row_id, column_id, value) VALUES ($1, $2, $3) - ON CONFLICT (row_id, column_id) DO UPDATE SET value = EXCLUDED.value, updated_at = NOW() + `INSERT INTO user_cell_values (row_id, column_id, value_encrypted) VALUES ($1, $2, encrypt_text($3, $4)) + ON CONFLICT (row_id, column_id) DO UPDATE SET value_encrypted = encrypt_text($3, $4), updated_at = NOW() RETURNING *`, - [row_id, column_id, value] + [row_id, column_id, value, encryptionKey] ); // Получаем table_id const table = (await db.getQuery()('SELECT table_id FROM user_rows WHERE id = $1', [row_id])).rows[0]; if (table) { const tableId = table.table_id; // Получаем всю строку для upsert - const rowData = (await db.getQuery()('SELECT r.id as row_id, c.value as text, c2.value as answer FROM user_rows r LEFT JOIN user_cell_values c ON c.row_id = r.id AND c.column_id = 1 LEFT JOIN user_cell_values c2 ON c2.row_id = r.id AND c2.column_id = 2 WHERE r.id = $1', [row_id])).rows[0]; + const rowData = (await db.getQuery()('SELECT r.id as row_id, decrypt_text(c.value_encrypted, $2) as text, decrypt_text(c2.value_encrypted, $2) as answer FROM user_rows r LEFT JOIN user_cell_values c ON c.row_id = r.id AND c.column_id = 1 LEFT JOIN user_cell_values c2 ON c2.row_id = r.id AND c2.column_id = 2 WHERE r.id = $1', [row_id, encryptionKey])).rows[0]; if (rowData) { const upsertRows = [{ row_id: rowData.row_id, text: rowData.text, metadata: { answer: rowData.answer } }].filter(r => r.row_id && r.text); console.log('[DEBUG][upsertRows]', upsertRows); @@ -278,7 +421,21 @@ router.delete('/row/:rowId', async (req, res, next) => { if (table) { const tableId = table.table_id; // Получаем все строки для rebuild - const rows = (await db.getQuery()('SELECT r.id as row_id, c.value as text, c2.value as answer FROM user_rows r LEFT JOIN user_cell_values c ON c.row_id = r.id AND c.column_id = 1 LEFT JOIN user_cell_values c2 ON c2.row_id = r.id AND c2.column_id = 2 WHERE r.table_id = $1', [tableId])).rows; + // Получаем ключ шифрования + const fs = require('fs'); + const path = require('path'); + let encryptionKey = 'default-key'; + + try { + const keyPath = path.join(__dirname, '../ssl/keys/full_db_encryption.key'); + if (fs.existsSync(keyPath)) { + encryptionKey = fs.readFileSync(keyPath, 'utf8').trim(); + } + } catch (keyError) { + console.error('Error reading encryption key:', keyError); + } + + const rows = (await db.getQuery()('SELECT r.id as row_id, decrypt_text(c.value_encrypted, $2) as text, decrypt_text(c2.value_encrypted, $2) as answer FROM user_rows r LEFT JOIN user_cell_values c ON c.row_id = r.id AND c.column_id = 1 LEFT JOIN user_cell_values c2 ON c2.row_id = r.id AND c2.column_id = 2 WHERE r.table_id = $1', [tableId, encryptionKey])).rows; const rebuildRows = rows.filter(r => r.row_id && r.text).map(r => ({ row_id: r.row_id, text: r.text, metadata: { answer: r.answer } })); console.log('[DEBUG][rebuildRows]', rebuildRows); if (rebuildRows.length > 0) { @@ -308,7 +465,21 @@ router.patch('/column/:columnId', async (req, res, next) => { const columnId = req.params.columnId; const { name, type, options, order, placeholder } = req.body; // Получаем table_id для проверки уникальности плейсхолдера - const colInfo = (await db.getQuery()('SELECT table_id, name FROM user_columns WHERE id = $1', [columnId])).rows[0]; + // Получаем ключ шифрования + const fs = require('fs'); + const path = require('path'); + let encryptionKey = 'default-key'; + + try { + const keyPath = path.join(__dirname, '../ssl/keys/full_db_encryption.key'); + if (fs.existsSync(keyPath)) { + encryptionKey = fs.readFileSync(keyPath, 'utf8').trim(); + } + } catch (keyError) { + console.error('Error reading encryption key:', keyError); + } + + const colInfo = (await db.getQuery()('SELECT table_id, decrypt_text(name_encrypted, $2) as name FROM user_columns WHERE id = $1', [columnId, encryptionKey])).rows[0]; if (!colInfo) return res.status(404).json({ error: 'Column not found' }); let newPlaceholder = placeholder; if (name !== undefined && !placeholder) { @@ -547,7 +718,21 @@ router.post('/:tableId/row/:rowId/multirelations', async (req, res, next) => { router.get('/:id/placeholders', async (req, res, next) => { try { const tableId = req.params.id; - const columns = (await db.getQuery()('SELECT id, name, placeholder FROM user_columns WHERE table_id = $1', [tableId])).rows; + // Получаем ключ шифрования + const fs = require('fs'); + const path = require('path'); + let encryptionKey = 'default-key'; + + try { + const keyPath = path.join(__dirname, '../ssl/keys/full_db_encryption.key'); + if (fs.existsSync(keyPath)) { + encryptionKey = fs.readFileSync(keyPath, 'utf8').trim(); + } + } catch (keyError) { + console.error('Error reading encryption key:', keyError); + } + + const columns = (await db.getQuery()('SELECT id, decrypt_text(name_encrypted, $2) as name, placeholder FROM user_columns WHERE table_id = $1', [tableId, encryptionKey])).rows; res.json(columns.map(col => ({ id: col.id, name: col.name, @@ -561,15 +746,33 @@ router.get('/:id/placeholders', async (req, res, next) => { // Получить все плейсхолдеры по всем пользовательским таблицам router.get('/placeholders/all', async (req, res, next) => { try { - const result = await db.getQuery()(` - SELECT c.id as column_id, c.name as column_name, c.placeholder, t.id as table_id, t.name as table_name - FROM user_columns c - JOIN user_tables t ON c.table_id = t.id - WHERE c.placeholder IS NOT NULL AND c.placeholder != '' - ORDER BY t.id, c.id - `); - res.json(result.rows); + const encryptedDb = require('../services/encryptedDatabaseService'); + + // Получаем все колонки с плейсхолдерами + const columns = await encryptedDb.getData('user_columns', {}); + + // Фильтруем только те, у которых есть плейсхолдеры + const columnsWithPlaceholders = columns.filter(col => col.placeholder && col.placeholder !== ''); + + // Получаем информацию о таблицах + const tables = await encryptedDb.getData('user_tables', {}); + const tableMap = {}; + tables.forEach(table => { + tableMap[table.id] = table.name; + }); + + // Формируем результат + const result = columnsWithPlaceholders.map(col => ({ + column_id: col.id, + column_name: col.name, + placeholder: col.placeholder, + table_id: col.table_id, + table_name: tableMap[col.table_id] || `Таблица ${col.table_id}` + })); + + res.json(result); } catch (err) { + console.error('[Placeholders] Error:', err); next(err); } }); diff --git a/backend/routes/users.js b/backend/routes/users.js index 1ed8b5f..d9577b9 100644 --- a/backend/routes/users.js +++ b/backend/routes/users.js @@ -78,6 +78,20 @@ router.get('/', requireAuth, async (req, res, next) => { } = req.query; const adminId = req.user && req.user.id; + // Получаем ключ шифрования + const fs = require('fs'); + const path = require('path'); + let encryptionKey = 'default-key'; + + try { + const keyPath = path.join(__dirname, '../ssl/keys/full_db_encryption.key'); + if (fs.existsSync(keyPath)) { + encryptionKey = fs.readFileSync(keyPath, 'utf8').trim(); + } + } catch (keyError) { + console.error('Error reading encryption key:', keyError); + } + // --- Формируем условия --- const where = []; const params = []; @@ -97,9 +111,10 @@ router.get('/', requireAuth, async (req, res, next) => { if (contactType !== 'all') { where.push(`EXISTS ( SELECT 1 FROM user_identities ui - WHERE ui.user_id = u.id AND ui.provider = $${idx++} + WHERE ui.user_id = u.id AND ui.provider_encrypted = encrypt_text($${idx++}, $${idx++}) )`); params.push(contactType); + params.push(encryptionKey); } // Фильтр по поиску @@ -107,10 +122,11 @@ router.get('/', requireAuth, async (req, res, next) => { where.push(`( LOWER(u.first_name) LIKE $${idx} OR LOWER(u.last_name) LIKE $${idx} OR - EXISTS (SELECT 1 FROM user_identities ui WHERE ui.user_id = u.id AND LOWER(ui.provider_id) LIKE $${idx}) + EXISTS (SELECT 1 FROM user_identities ui WHERE ui.user_id = u.id AND LOWER(decrypt_text(ui.provider_id_encrypted, $${idx + 1})) LIKE $${idx}) )`); params.push(`%${search.toLowerCase()}%`); - idx++; + params.push(encryptionKey); + idx += 2; } // Фильтр по блокировке @@ -123,11 +139,12 @@ router.get('/', requireAuth, async (req, res, next) => { // --- Основной SQL --- let sql = ` SELECT u.id, u.first_name, u.last_name, u.created_at, u.preferred_language, u.is_blocked, - (SELECT provider_id FROM user_identities WHERE user_id = u.id AND provider = 'email' LIMIT 1) AS email, - (SELECT provider_id FROM user_identities WHERE user_id = u.id AND provider = 'telegram' LIMIT 1) AS telegram, - (SELECT provider_id FROM user_identities WHERE user_id = u.id AND provider = 'wallet' LIMIT 1) AS wallet + (SELECT decrypt_text(provider_id_encrypted, $${idx++}) FROM user_identities WHERE user_id = u.id AND provider_encrypted = encrypt_text('email', $${idx++}) LIMIT 1) AS email, + (SELECT decrypt_text(provider_id_encrypted, $${idx++}) FROM user_identities WHERE user_id = u.id AND provider_encrypted = encrypt_text('telegram', $${idx++}) LIMIT 1) AS telegram, + (SELECT decrypt_text(provider_id_encrypted, $${idx++}) FROM user_identities WHERE user_id = u.id AND provider_encrypted = encrypt_text('wallet', $${idx++}) LIMIT 1) AS wallet FROM users u `; + params.push(encryptionKey, encryptionKey, encryptionKey, encryptionKey, encryptionKey, encryptionKey); // Фильтрация по тегам if (tagIds) { @@ -330,16 +347,31 @@ router.delete('/:id', async (req, res) => { // Получить пользователя по id router.get('/:id', async (req, res, next) => { const userId = req.params.id; + + // Получаем ключ шифрования + const fs = require('fs'); + const path = require('path'); + let encryptionKey = 'default-key'; + + try { + const keyPath = path.join(__dirname, '../ssl/keys/full_db_encryption.key'); + if (fs.existsSync(keyPath)) { + encryptionKey = fs.readFileSync(keyPath, 'utf8').trim(); + } + } catch (keyError) { + console.error('Error reading encryption key:', keyError); + } + try { const query = db.getQuery(); // Получаем пользователя - const userResult = await query('SELECT id, first_name, last_name, created_at, preferred_language, is_blocked FROM users WHERE id = $1', [userId]); + const userResult = await query('SELECT id, decrypt_text(first_name_encrypted, $2) as first_name, decrypt_text(last_name_encrypted, $2) as last_name, created_at, preferred_language, is_blocked FROM users WHERE id = $1', [userId, encryptionKey]); if (userResult.rows.length === 0) { return res.status(404).json({ error: 'User not found' }); } const user = userResult.rows[0]; // Получаем идентификаторы - const identitiesResult = await query('SELECT provider, provider_id FROM user_identities WHERE user_id = $1', [userId]); + const identitiesResult = await query('SELECT decrypt_text(provider_encrypted, $2) as provider, decrypt_text(provider_id_encrypted, $2) as provider_id FROM user_identities WHERE user_id = $1', [userId, encryptionKey]); const identityMap = {}; for (const id of identitiesResult.rows) { identityMap[id.provider] = id.provider_id; @@ -362,11 +394,26 @@ router.get('/:id', async (req, res, next) => { // POST /api/users router.post('/', async (req, res) => { const { first_name, last_name, preferred_language } = req.body; + + // Получаем ключ шифрования + const fs = require('fs'); + const path = require('path'); + let encryptionKey = 'default-key'; + + try { + const keyPath = path.join(__dirname, '../ssl/keys/full_db_encryption.key'); + if (fs.existsSync(keyPath)) { + encryptionKey = fs.readFileSync(keyPath, 'utf8').trim(); + } + } catch (keyError) { + console.error('Error reading encryption key:', keyError); + } + try { const result = await db.getQuery()( - `INSERT INTO users (first_name, last_name, preferred_language, created_at) - VALUES ($1, $2, $3, NOW()) RETURNING *`, - [first_name, last_name, JSON.stringify(preferred_language || [])] + `INSERT INTO users (first_name_encrypted, last_name_encrypted, preferred_language, created_at) + VALUES (encrypt_text($1, $4), encrypt_text($2, $4), $3, NOW()) RETURNING *`, + [first_name, last_name, JSON.stringify(preferred_language || []), encryptionKey] ); broadcastContactsUpdate(); res.json({ success: true, user: result.rows[0] }); @@ -377,6 +424,20 @@ router.post('/', async (req, res) => { // Массовый импорт контактов router.post('/import', requireAuth, async (req, res) => { + // Получаем ключ шифрования + const fs = require('fs'); + const path = require('path'); + let encryptionKey = 'default-key'; + + try { + const keyPath = path.join(__dirname, '../ssl/keys/full_db_encryption.key'); + if (fs.existsSync(keyPath)) { + encryptionKey = fs.readFileSync(keyPath, 'utf8').trim(); + } + } catch (keyError) { + console.error('Error reading encryption key:', keyError); + } + try { const contacts = req.body; if (!Array.isArray(contacts)) { @@ -397,15 +458,15 @@ router.post('/import', requireAuth, async (req, res) => { let userId = null; let foundUser = null; if (c.email) { - const r = await dbq('SELECT user_id FROM user_identities WHERE provider = $1 AND provider_id = $2', ['email', c.email.toLowerCase()]); + const r = await dbq('SELECT user_id FROM user_identities WHERE provider_encrypted = encrypt_text($1, $3) AND provider_id_encrypted = encrypt_text($2, $3)', ['email', c.email.toLowerCase(), encryptionKey]); if (r.rows.length) foundUser = r.rows[0].user_id; } if (!foundUser && c.telegram) { - const r = await dbq('SELECT user_id FROM user_identities WHERE provider = $1 AND provider_id = $2', ['telegram', c.telegram]); + const r = await dbq('SELECT user_id FROM user_identities WHERE provider_encrypted = encrypt_text($1, $3) AND provider_id_encrypted = encrypt_text($2, $3)', ['telegram', c.telegram, encryptionKey]); if (r.rows.length) foundUser = r.rows[0].user_id; } if (!foundUser && c.wallet) { - const r = await dbq('SELECT user_id FROM user_identities WHERE provider = $1 AND provider_id = $2', ['wallet', c.wallet]); + const r = await dbq('SELECT user_id FROM user_identities WHERE provider_encrypted = encrypt_text($1, $3) AND provider_id_encrypted = encrypt_text($2, $3)', ['wallet', c.wallet, encryptionKey]); if (r.rows.length) foundUser = r.rows[0].user_id; } if (foundUser) { @@ -413,11 +474,11 @@ router.post('/import', requireAuth, async (req, res) => { updated++; // Обновляем имя, если нужно if (first_name || last_name) { - await dbq('UPDATE users SET first_name = COALESCE($1, first_name), last_name = COALESCE($2, last_name) WHERE id = $3', [first_name, last_name, userId]); + await dbq('UPDATE users SET first_name_encrypted = COALESCE(encrypt_text($1, $4), first_name_encrypted), last_name_encrypted = COALESCE(encrypt_text($2, $4), last_name_encrypted) WHERE id = $3', [first_name, last_name, userId, encryptionKey]); } } else { // Создаём нового пользователя - const ins = await dbq('INSERT INTO users (first_name, last_name, created_at) VALUES ($1, $2, NOW()) RETURNING id', [first_name, last_name]); + const ins = await dbq('INSERT INTO users (first_name_encrypted, last_name_encrypted, created_at) VALUES (encrypt_text($1, $3), encrypt_text($2, $3), NOW()) RETURNING id', [first_name, last_name, encryptionKey]); userId = ins.rows[0].id; added++; } diff --git a/backend/scripts/deploy/create-dle-v2.js b/backend/scripts/deploy/create-dle-v2.js new file mode 100644 index 0000000..e7df337 --- /dev/null +++ b/backend/scripts/deploy/create-dle-v2.js @@ -0,0 +1,190 @@ +/** + * 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 (единый контракт) +const { ethers } = require("hardhat"); +const fs = require("fs"); +const path = require("path"); + +async function main() { + // Получаем параметры деплоя из файла + const deployParams = getDeployParams(); + + console.log("Начинаем создание современного DLE v2..."); + console.log("Параметры DLE:"); + console.log(JSON.stringify(deployParams, null, 2)); + + // Получаем аккаунт деплоя + const [deployer] = await ethers.getSigners(); + console.log(`Адрес деплоера: ${deployer.address}`); + console.log(`Баланс деплоера: ${ethers.formatEther(await deployer.provider.getBalance(deployer.address))} ETH`); + + try { + // 1. Создаем единый контракт DLE + console.log("\n1. Деплой единого контракта DLE v2..."); + + const DLE = await ethers.getContractFactory("DLE"); + + // Преобразуем параметры голосования + const votingDelay = deployParams.votingDelay || 1; + const votingPeriod = deployParams.votingPeriod || 45818; // ~1 неделя + const proposalThreshold = deployParams.proposalThreshold || ethers.parseEther("100000"); + const quorumPercentage = deployParams.quorumPercentage || 4; + const minTimelockDelay = (deployParams.minTimelockDelay || 2) * 24 * 60 * 60; // дни в секунды + + const dle = await DLE.deploy( + deployParams.name, + deployParams.symbol, + deployParams.location, + deployParams.isicCodes || [], + votingDelay, + votingPeriod, + proposalThreshold, + quorumPercentage, + minTimelockDelay + ); + + await dle.waitForDeployment(); + const dleAddress = await dle.getAddress(); + console.log(`DLE v2 задеплоен по адресу: ${dleAddress}`); + + // 2. Получаем адрес таймлока + const timelockAddress = await dle.getTimelockAddress(); + console.log(`Таймлок создан по адресу: ${timelockAddress}`); + + // 3. Распределяем начальные токены + console.log("\n3. Распределение начальных токенов..."); + const distributeTx = await dle.distributeInitialTokens( + deployParams.partners, + deployParams.amounts + ); + await distributeTx.wait(); + console.log(`Токены распределены между партнерами`); + + // 4. Получаем информацию о DLE + const dleInfo = await dle.getDLEInfo(); + console.log("\n4. Информация о DLE:"); + console.log(`Название: ${dleInfo.name}`); + console.log(`Символ: ${dleInfo.symbol}`); + console.log(`Местонахождение: ${dleInfo.location}`); + console.log(`Коды деятельности: ${dleInfo.isicCodes.join(', ')}`); + console.log(`Дата создания: ${new Date(dleInfo.creationTimestamp * 1000).toISOString()}`); + + // 5. Сохраняем информацию о созданном DLE + console.log("\n5. Сохранение информации о DLE v2..."); + const dleData = { + name: deployParams.name, + symbol: deployParams.symbol, + location: deployParams.location, + isicCodes: deployParams.isicCodes || [], + dleAddress: dleAddress, + timelockAddress: timelockAddress, + creationBlock: (await distributeTx.provider.getBlockNumber()), + creationTimestamp: (await distributeTx.provider.getBlock()).timestamp, + deployedManually: true, + version: "v2", + governanceSettings: { + votingDelay: votingDelay, + votingPeriod: votingPeriod, + proposalThreshold: proposalThreshold.toString(), + quorumPercentage: quorumPercentage, + minTimelockDelay: deployParams.minTimelockDelay || 2 + } + }; + + const saveResult = saveDLEData(dleData); + + console.log("\nDLE v2 успешно создан!"); + console.log(`Адрес DLE: ${dleAddress}`); + console.log(`Адрес таймлока: ${timelockAddress}`); + console.log(`Версия: v2 (единый контракт)`); + + return { + success: true, + dleAddress: dleAddress, + timelockAddress: timelockAddress, + data: dleData + }; + + } catch (error) { + console.error("Ошибка при создании DLE v2:", error); + throw error; + } +} + +// Получаем параметры деплоя из файла +function getDeployParams() { + const paramsFile = path.join(__dirname, 'current-params.json'); + + if (!fs.existsSync(paramsFile)) { + console.error(`Файл параметров не найден: ${paramsFile}`); + process.exit(1); + } + + try { + const params = JSON.parse(fs.readFileSync(paramsFile, 'utf8')); + console.log("Параметры загружены из файла"); + return params; + } catch (error) { + console.error("Ошибка при чтении файла параметров:", error); + process.exit(1); + } +} + +// Сохраняем информацию о созданном DLE +function saveDLEData(dleData) { + const dlesDir = path.join(__dirname, "../../contracts-data/dles"); + + // Проверяем существование директории и создаем при необходимости + try { + if (!fs.existsSync(dlesDir)) { + console.log(`Директория ${dlesDir} не существует, создаю...`); + fs.mkdirSync(dlesDir, { recursive: true }); + console.log(`Директория ${dlesDir} успешно создана`); + } + + // Проверяем права на запись, создавая временный файл + const testFile = path.join(dlesDir, '.write-test'); + fs.writeFileSync(testFile, 'test'); + fs.unlinkSync(testFile); + console.log(`Директория ${dlesDir} доступна для записи`); + + } catch (error) { + console.error(`Ошибка при проверке директории ${dlesDir}:`, error); + throw error; + } + + // Создаем уникальное имя файла + const timestamp = new Date().toISOString().replace(/[:.]/g, '-'); + const fileName = `dle-v2-${timestamp}.json`; + const filePath = path.join(dlesDir, fileName); + + try { + fs.writeFileSync(filePath, JSON.stringify(dleData, null, 2)); + console.log(`Информация о DLE сохранена в файл: ${fileName}`); + return { success: true, filePath }; + } catch (error) { + console.error(`Ошибка при сохранении файла ${filePath}:`, error); + throw error; + } +} + +// Запускаем скрипт +main() + .then(() => { + console.log("Скрипт завершен успешно"); + process.exit(0); + }) + .catch((error) => { + console.error("Скрипт завершен с ошибкой:", error); + process.exit(1); + }); \ No newline at end of file diff --git a/backend/scripts/fix-rag-columns.js b/backend/scripts/fix-rag-columns.js new file mode 100644 index 0000000..3c2b4e1 --- /dev/null +++ b/backend/scripts/fix-rag-columns.js @@ -0,0 +1,110 @@ +/** + * 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 + */ + +const db = require('../db'); + +async function fixRagColumns() { + console.log('🔧 Исправление purpose у колонок в RAG таблице...\n'); + + try { + // Получаем ключ шифрования + const fs = require('fs'); + const path = require('path'); + let encryptionKey = 'default-key'; + + try { + const keyPath = path.join(__dirname, '../ssl/keys/full_db_encryption.key'); + if (fs.existsSync(keyPath)) { + encryptionKey = fs.readFileSync(keyPath, 'utf8').trim(); + } + } catch (keyError) { + console.error('Error reading encryption key:', keyError); + } + + // Получаем колонки таблицы RAG (ID 28) + const columns = await db.getQuery()( + 'SELECT id, decrypt_text(name_encrypted, $1) as name FROM user_columns WHERE table_id = 28 ORDER BY id', + [encryptionKey] + ); + + console.log('Найденные колонки в таблице RAG:'); + columns.rows.forEach(col => { + console.log(` ID: ${col.id}, Name: ${col.name}`); + }); + + // Маппинг названий колонок на purpose + const purposeMapping = { + 'Вопрос': 'question', + 'Ответ': 'answer', + 'Контекст теги': 'context', + 'Продукт теги': 'product', + 'Клиент теги': 'userTags' + }; + + // Обновляем каждую колонку + for (const col of columns.rows) { + const purpose = purposeMapping[col.name]; + if (purpose) { + console.log(`\nОбновляем колонку "${col.name}" (ID: ${col.id}) -> purpose: ${purpose}`); + + // Получаем текущие options + const currentOptions = await db.getQuery()( + 'SELECT options FROM user_columns WHERE id = $1', + [col.id] + ); + + let options = currentOptions.rows[0]?.options || {}; + options.purpose = purpose; + + // Обновляем колонку + await db.getQuery()( + 'UPDATE user_columns SET options = $1 WHERE id = $2', + [JSON.stringify(options), col.id] + ); + + console.log(` ✅ Обновлено`); + } else { + console.log(`\n⚠️ Колонка "${col.name}" (ID: ${col.id}) - purpose не определен`); + } + } + + console.log('\n✅ Исправление завершено!'); + + // Проверяем результат + console.log('\nПроверка результата:'); + const updatedColumns = await db.getQuery()( + 'SELECT id, decrypt_text(name_encrypted, $1) as name, options FROM user_columns WHERE table_id = 28 ORDER BY id', + [encryptionKey] + ); + + updatedColumns.rows.forEach(col => { + const options = col.options || {}; + console.log(` ID: ${col.id}, Name: ${col.name}, Purpose: ${options.purpose || 'undefined'}`); + }); + + } catch (error) { + console.error('❌ Ошибка:', error); + } +} + +// Запуск скрипта +if (require.main === module) { + fixRagColumns().then(() => { + console.log('\n🏁 Скрипт завершен'); + process.exit(0); + }).catch(error => { + console.error('💥 Критическая ошибка:', error); + process.exit(1); + }); +} + +module.exports = { fixRagColumns }; \ No newline at end of file diff --git a/backend/scripts/test-ai-queue-docker.js b/backend/scripts/test-ai-queue-docker.js new file mode 100644 index 0000000..2392e53 --- /dev/null +++ b/backend/scripts/test-ai-queue-docker.js @@ -0,0 +1,120 @@ +/** + * 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 + */ + +// Устанавливаем переменные окружения для Docker +process.env.OLLAMA_BASE_URL = 'http://ollama:11434'; +process.env.OLLAMA_MODEL = 'qwen2.5:7b'; + +const aiQueueService = require('../services/ai-queue'); + +async function testQueueInDocker() { + console.log('🐳 Тестирование AI очереди в Docker...\n'); + + try { + // Проверяем инициализацию + console.log('1. Проверка инициализации очереди...'); + const stats = aiQueueService.getStats(); + console.log('✅ Очередь инициализирована:', stats.isInitialized); + console.log('📊 Статистика:', { + totalProcessed: stats.totalProcessed, + totalFailed: stats.totalFailed, + currentQueueSize: stats.currentQueueSize, + runningTasks: stats.runningTasks + }); + + // Тестируем добавление задач + console.log('\n2. Тестирование добавления задач...'); + + const testTasks = [ + { + message: 'Привет, как дела?', + language: 'ru', + type: 'chat', + userId: 1, + userRole: 'user', + requestId: 'docker_test_1' + }, + { + message: 'Расскажи о погоде', + language: 'ru', + type: 'analysis', + userId: 1, + userRole: 'user', + requestId: 'docker_test_2' + }, + { + message: 'Срочный вопрос!', + language: 'ru', + type: 'urgent', + userId: 1, + userRole: 'admin', + requestId: 'docker_test_3' + } + ]; + + for (let i = 0; i < testTasks.length; i++) { + const task = testTasks[i]; + console.log(` Добавляем задачу ${i + 1}: "${task.message}"`); + + try { + const result = await aiQueueService.addTask(task); + console.log(` ✅ Задача добавлена, ID: ${result.taskId}`); + } catch (error) { + console.log(` ❌ Ошибка добавления задачи: ${error.message}`); + } + } + + // Ждем обработки + console.log('\n3. Ожидание обработки задач...'); + await new Promise(resolve => setTimeout(resolve, 15000)); + + // Проверяем статистику + console.log('\n4. Проверка статистики после обработки...'); + const finalStats = aiQueueService.getStats(); + console.log('📊 Финальная статистика:', { + totalProcessed: finalStats.totalProcessed, + totalFailed: finalStats.totalFailed, + currentQueueSize: finalStats.currentQueueSize, + runningTasks: finalStats.runningTasks, + averageProcessingTime: Math.round(finalStats.averageProcessingTime) + }); + + // Тестируем управление очередью + console.log('\n5. Тестирование управления очередью...'); + + console.log(' Пауза очереди...'); + aiQueueService.pause(); + await new Promise(resolve => setTimeout(resolve, 1000)); + + console.log(' Возобновление очереди...'); + aiQueueService.resume(); + await new Promise(resolve => setTimeout(resolve, 1000)); + + console.log('\n✅ Тестирование завершено!'); + + } catch (error) { + console.error('❌ Ошибка тестирования:', error); + } +} + +// Запуск теста +if (require.main === module) { + testQueueInDocker().then(() => { + console.log('\n🏁 Тест завершен'); + process.exit(0); + }).catch(error => { + console.error('💥 Критическая ошибка:', error); + process.exit(1); + }); +} + +module.exports = { testQueueInDocker }; \ No newline at end of file diff --git a/backend/scripts/test-ai-queue.js b/backend/scripts/test-ai-queue.js new file mode 100644 index 0000000..b5e60b3 --- /dev/null +++ b/backend/scripts/test-ai-queue.js @@ -0,0 +1,116 @@ +/** + * 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 + */ + +const aiQueueService = require('../services/ai-queue'); + +async function testQueue() { + console.log('🧪 Тестирование AI очереди...\n'); + + try { + // Проверяем инициализацию + console.log('1. Проверка инициализации очереди...'); + const stats = aiQueueService.getStats(); + console.log('✅ Очередь инициализирована:', stats.isInitialized); + console.log('📊 Статистика:', { + totalProcessed: stats.totalProcessed, + totalFailed: stats.totalFailed, + currentQueueSize: stats.currentQueueSize, + runningTasks: stats.runningTasks + }); + + // Тестируем добавление задач + console.log('\n2. Тестирование добавления задач...'); + + const testTasks = [ + { + message: 'Привет, как дела?', + language: 'ru', + type: 'chat', + userId: 1, + userRole: 'user', + requestId: 'test_1' + }, + { + message: 'Расскажи о погоде', + language: 'ru', + type: 'analysis', + userId: 1, + userRole: 'user', + requestId: 'test_2' + }, + { + message: 'Срочный вопрос!', + language: 'ru', + type: 'urgent', + userId: 1, + userRole: 'admin', + requestId: 'test_3' + } + ]; + + for (let i = 0; i < testTasks.length; i++) { + const task = testTasks[i]; + console.log(` Добавляем задачу ${i + 1}: "${task.message}"`); + + try { + const result = await aiQueueService.addTask(task); + console.log(` ✅ Задача добавлена, ID: ${result.taskId}`); + } catch (error) { + console.log(` ❌ Ошибка добавления задачи: ${error.message}`); + } + } + + // Ждем обработки + console.log('\n3. Ожидание обработки задач...'); + await new Promise(resolve => setTimeout(resolve, 10000)); + + // Проверяем статистику + console.log('\n4. Проверка статистики после обработки...'); + const finalStats = aiQueueService.getStats(); + console.log('📊 Финальная статистика:', { + totalProcessed: finalStats.totalProcessed, + totalFailed: finalStats.totalFailed, + currentQueueSize: finalStats.currentQueueSize, + runningTasks: finalStats.runningTasks, + averageProcessingTime: Math.round(finalStats.averageProcessingTime) + }); + + // Тестируем управление очередью + console.log('\n5. Тестирование управления очередью...'); + + console.log(' Пауза очереди...'); + aiQueueService.pause(); + await new Promise(resolve => setTimeout(resolve, 1000)); + + console.log(' Возобновление очереди...'); + aiQueueService.resume(); + await new Promise(resolve => setTimeout(resolve, 1000)); + + console.log('\n✅ Тестирование завершено!'); + + } catch (error) { + console.error('❌ Ошибка тестирования:', error); + } +} + +// Запуск теста +if (require.main === module) { + testQueue().then(() => { + console.log('\n🏁 Тест завершен'); + process.exit(0); + }).catch(error => { + console.error('💥 Критическая ошибка:', error); + process.exit(1); + }); +} + +module.exports = { testQueue }; \ No newline at end of file diff --git a/backend/scripts/test-encrypted-tables.js b/backend/scripts/test-encrypted-tables.js new file mode 100644 index 0000000..c4276f4 --- /dev/null +++ b/backend/scripts/test-encrypted-tables.js @@ -0,0 +1,82 @@ +/** + * 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 + */ + +const encryptedDb = require('../services/encryptedDatabaseService'); +const db = require('../db'); + +async function testEncryptedTables() { + console.log('🔐 Тестирование зашифрованных таблиц...\n'); + + try { + // Тестируем таблицу is_rag_source + console.log('1. Тестирование таблицы is_rag_source:'); + const ragSources = await encryptedDb.getData('is_rag_source', {}); + console.log(' ✅ Данные получены:', ragSources); + + // Тестируем через прямой SQL запрос + const fs = require('fs'); + const path = require('path'); + let encryptionKey = 'default-key'; + + try { + const keyPath = path.join(__dirname, '../ssl/keys/full_db_encryption.key'); + if (fs.existsSync(keyPath)) { + encryptionKey = fs.readFileSync(keyPath, 'utf8').trim(); + } + } catch (keyError) { + console.error('Error reading encryption key:', keyError); + } + + const directResult = await db.getQuery()( + 'SELECT id, decrypt_text(name_encrypted, $1) as name FROM is_rag_source ORDER BY id', + [encryptionKey] + ); + console.log(' ✅ Прямой SQL запрос:', directResult.rows); + + // Тестируем другие важные таблицы + console.log('\n2. Тестирование других зашифрованных таблиц:'); + + // user_tables + const userTables = await encryptedDb.getData('user_tables', {}, 5); + console.log(' ✅ user_tables (первые 5):', userTables.length, 'записей'); + + // user_columns + const userColumns = await encryptedDb.getData('user_columns', {}, 5); + console.log(' ✅ user_columns (первые 5):', userColumns.length, 'записей'); + + // messages + const messages = await encryptedDb.getData('messages', {}, 3); + console.log(' ✅ messages (первые 3):', messages.length, 'записей'); + + // conversations + const conversations = await encryptedDb.getData('conversations', {}, 3); + console.log(' ✅ conversations (первые 3):', conversations.length, 'записей'); + + console.log('\n✅ Все тесты прошли успешно!'); + + } catch (error) { + console.error('❌ Ошибка тестирования:', error); + } +} + +// Запуск теста +if (require.main === module) { + testEncryptedTables().then(() => { + console.log('\n🏁 Тест завершен'); + process.exit(0); + }).catch(error => { + console.error('💥 Критическая ошибка:', error); + process.exit(1); + }); +} + +module.exports = { testEncryptedTables }; \ No newline at end of file diff --git a/backend/server.js b/backend/server.js index 70359e6..0de4871 100644 --- a/backend/server.js +++ b/backend/server.js @@ -47,8 +47,12 @@ async function initServices() { console.error('[initServices] Ошибка при запуске emailBot:', err); } console.log('[initServices] Запуск Telegram-бота...'); - await getBot(); - console.log('[initServices] Telegram-бот успешно запущен'); + try { + await getBot(); + console.log('[initServices] Telegram-бот успешно запущен'); + } catch (err) { + console.error('[initServices] Ошибка при запуске Telegram-бота:', err); + } } catch (error) { console.error('Ошибка при инициализации сервисов:', error); } diff --git a/backend/services/admin-role.js b/backend/services/admin-role.js index 62bef25..4b1746d 100644 --- a/backend/services/admin-role.js +++ b/backend/services/admin-role.js @@ -12,6 +12,7 @@ const { ethers } = require('ethers'); const logger = require('../utils/logger'); +const db = require('../db'); const authTokenService = require('./authTokenService'); const rpcProviderService = require('./rpcProviderService'); @@ -28,12 +29,41 @@ const ERC20_ABI = [ async function checkAdminRole(address) { if (!address) return false; logger.info(`Checking admin role for address: ${address}`); + + try { let foundTokens = false; let errorCount = 0; const balances = {}; - // Получаем токены и RPC из базы - const tokens = await authTokenService.getAllAuthTokens(); - const rpcProviders = await rpcProviderService.getAllRpcProviders(); + // Получаем ключ шифрования + const fs = require('fs'); + const path = require('path'); + let encryptionKey = 'default-key'; + + try { + const keyPath = path.join(__dirname, '../ssl/keys/full_db_encryption.key'); + if (fs.existsSync(keyPath)) { + encryptionKey = fs.readFileSync(keyPath, 'utf8').trim(); + } + } catch (keyError) { + console.error('Error reading encryption key:', keyError); + } + + // Получаем токены и RPC из базы с расшифровкой + const tokensResult = await db.getQuery()( + 'SELECT id, min_balance, created_at, updated_at, decrypt_text(name_encrypted, $1) as name, decrypt_text(address_encrypted, $1) as address, decrypt_text(network_encrypted, $1) as network FROM auth_tokens', + [encryptionKey] + ); + const tokens = tokensResult.rows; + + const rpcProvidersResult = await db.getQuery()( + 'SELECT id, chain_id, created_at, updated_at, decrypt_text(network_id_encrypted, $1) as network_id, decrypt_text(rpc_url_encrypted, $1) as rpc_url FROM rpc_providers', + [encryptionKey] + ); + const rpcProviders = rpcProvidersResult.rows; + + logger.info(`Retrieved ${tokens.length} tokens and ${rpcProviders.length} RPC providers`); + logger.info('Tokens:', JSON.stringify(tokens, null, 2)); + logger.info('RPC Providers:', JSON.stringify(rpcProviders, null, 2)); const rpcMap = {}; for (const rpc of rpcProviders) { rpcMap[rpc.network_id] = rpc.rpc_url; @@ -109,6 +139,10 @@ async function checkAdminRole(address) { } logger.info(`Admin role denied - no tokens found for ${address}`); return false; + } catch (error) { + logger.error(`Error in checkAdminRole for ${address}:`, error); + return false; + } } module.exports = { checkAdminRole }; \ No newline at end of file diff --git a/backend/services/ai-assistant.js b/backend/services/ai-assistant.js index ddb9850..d3d4431 100644 --- a/backend/services/ai-assistant.js +++ b/backend/services/ai-assistant.js @@ -18,26 +18,84 @@ const { OpenAIEmbeddings } = require('@langchain/openai'); const logger = require('../utils/logger'); const fetch = require('node-fetch'); +// Простой кэш для ответов +const responseCache = new Map(); +const CACHE_TTL = 5 * 60 * 1000; // 5 минут + class AIAssistant { constructor() { this.baseUrl = process.env.OLLAMA_BASE_URL || 'http://localhost:11434'; - this.defaultModel = process.env.OLLAMA_MODEL || 'qwen2.5'; + this.defaultModel = process.env.OLLAMA_MODEL || 'qwen2.5:7b'; + this.isModelLoaded = false; + this.lastHealthCheck = 0; + this.healthCheckInterval = 30000; // 30 секунд + } + + // Проверка здоровья модели + async checkModelHealth() { + const now = Date.now(); + if (now - this.lastHealthCheck < this.healthCheckInterval) { + return this.isModelLoaded; + } + + try { + const response = await fetch(`${this.baseUrl}/api/tags`, { + timeout: 5000 + }); + if (response.ok) { + const data = await response.json(); + this.isModelLoaded = data.models?.some(m => m.name === this.defaultModel) || false; + } else { + this.isModelLoaded = false; + } + } catch (error) { + console.error('Model health check failed:', error); + this.isModelLoaded = false; + } + + this.lastHealthCheck = now; + return this.isModelLoaded; + } + + // Очистка старых записей кэша + cleanupCache() { + const now = Date.now(); + for (const [key, value] of responseCache.entries()) { + if (now - value.timestamp > CACHE_TTL) { + responseCache.delete(key); + } + } } // Создание экземпляра ChatOllama с нужными параметрами - createChat(language = 'ru') { - const systemPrompt = - language === 'ru' - ? 'Вы - полезный ассистент. Отвечайте на русском языке.' - : 'You are a helpful assistant. Respond in English.'; + createChat(language = 'ru', customSystemPrompt = '') { + // Используем кастомный системный промпт, если он передан, иначе используем дефолтный + let systemPrompt = customSystemPrompt; + if (!systemPrompt) { + systemPrompt = language === 'ru' + ? 'Вы - полезный ассистент. Отвечайте на русском языке кратко и по делу.' + : 'You are a helpful assistant. Respond in English briefly and to the point.'; + } return new ChatOllama({ baseUrl: this.baseUrl, model: this.defaultModel, system: systemPrompt, - temperature: 0.7, - maxTokens: 1000, - timeout: 30000, // 30 секунд таймаут + temperature: 0.3, // Уменьшаем для более предсказуемых ответов + maxTokens: 100, // Еще больше уменьшаем для быстрого ответа + timeout: 60000, // Увеличиваем таймаут до 60 секунд + options: { + num_ctx: 512, // Еще больше уменьшаем контекст для экономии памяти + num_thread: 12, // Увеличиваем количество потоков еще больше + num_gpu: 1, + num_gqa: 8, + rope_freq_base: 1000000, + rope_freq_scale: 0.5, + repeat_penalty: 1.1, // Добавляем штраф за повторения + top_k: 20, // Еще больше ограничиваем выбор токенов + top_p: 0.8, // Уменьшаем nucleus sampling + temperature: 0.1, // Еще больше уменьшаем для более предсказуемых ответов + } }); } @@ -52,6 +110,24 @@ class AIAssistant { try { console.log('getResponse called with:', { message, language, history, systemPrompt, rules }); + // Очищаем старый кэш + this.cleanupCache(); + + // Проверяем здоровье модели + const isHealthy = await this.checkModelHealth(); + if (!isHealthy) { + console.warn('Model is not healthy, returning fallback response'); + return 'Извините, модель временно недоступна. Пожалуйста, попробуйте позже.'; + } + + // Создаем ключ кэша + const cacheKey = JSON.stringify({ message, language, systemPrompt, rules }); + const cached = responseCache.get(cacheKey); + if (cached && (Date.now() - cached.timestamp) < CACHE_TTL) { + console.log('Returning cached response'); + return cached.response; + } + // Определяем язык, если не указан явно const detectedLanguage = language === 'auto' ? this.detectLanguage(message) : language; console.log('Detected language:', detectedLanguage); @@ -77,28 +153,39 @@ class AIAssistant { // Добавляем текущее сообщение пользователя messages.push({ role: 'user', content: message }); + let response = null; + // Пробуем прямой API запрос (OpenAI-совместимый endpoint) try { console.log('Trying direct API request...'); - const response = await this.fallbackRequestOpenAI(messages, detectedLanguage); + response = await this.fallbackRequestOpenAI(messages, detectedLanguage, fullSystemPrompt); console.log('Direct API response received:', response); - return response; } catch (error) { console.error('Error in direct API request:', error); + + // Если прямой запрос не удался, пробуем через ChatOllama (склеиваем сообщения в текст) + const chat = this.createChat(detectedLanguage, fullSystemPrompt); + try { + const prompt = messages.map(m => `${m.role === 'user' ? 'Пользователь' : m.role === 'assistant' ? 'Ассистент' : 'Система'}: ${m.content}`).join('\n'); + console.log('Sending request to ChatOllama...'); + const chatResponse = await chat.invoke(prompt); + console.log('ChatOllama response:', chatResponse); + response = chatResponse.content; + } catch (chatError) { + console.error('Error using ChatOllama:', chatError); + throw chatError; + } } - // Если прямой запрос не удался, пробуем через ChatOllama (склеиваем сообщения в текст) - const chat = this.createChat(detectedLanguage); - try { - const prompt = messages.map(m => `${m.role === 'user' ? 'Пользователь' : m.role === 'assistant' ? 'Ассистент' : 'Система'}: ${m.content}`).join('\n'); - console.log('Sending request to ChatOllama...'); - const response = await chat.invoke(prompt); - console.log('ChatOllama response:', response); - return response.content; - } catch (error) { - console.error('Error using ChatOllama:', error); - throw error; + // Кэшируем ответ + if (response) { + responseCache.set(cacheKey, { + response, + timestamp: Date.now() + }); } + + return response; } catch (error) { console.error('Error in getResponse:', error); return 'Извините, я не смог обработать ваш запрос. Пожалуйста, попробуйте позже.'; @@ -106,10 +193,15 @@ class AIAssistant { } // Новый метод для OpenAI/Qwen2.5 совместимого endpoint - async fallbackRequestOpenAI(messages, language) { + async fallbackRequestOpenAI(messages, language, systemPrompt = '') { try { - console.log('Using fallbackRequestOpenAI with:', { messages, language }); + console.log('Using fallbackRequestOpenAI with:', { messages, language, systemPrompt }); const model = this.defaultModel; + + // Создаем AbortController для таймаута + const controller = new AbortController(); + const timeoutId = setTimeout(() => controller.abort(), 60000); // Увеличиваем до 60 секунд + const response = await fetch(`${this.baseUrl}/v1/chat/completions`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, @@ -118,11 +210,24 @@ class AIAssistant { messages, stream: false, options: { - temperature: 0.7, - num_predict: 1000, + temperature: 0.3, + num_predict: 200, // Уменьшаем максимальную длину ответа + num_ctx: 1024, // Уменьшаем контекст для экономии памяти + num_thread: 8, // Увеличиваем количество потоков + num_gpu: 1, // Используем GPU если доступен + num_gqa: 8, // Оптимизация для qwen2.5 + rope_freq_base: 1000000, // Оптимизация для qwen2.5 + rope_freq_scale: 0.5, // Оптимизация для qwen2.5 + repeat_penalty: 1.1, // Добавляем штраф за повторения + top_k: 40, // Ограничиваем выбор токенов + top_p: 0.9, // Используем nucleus sampling }, }), + signal: controller.signal, }); + + clearTimeout(timeoutId); + if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } @@ -134,6 +239,9 @@ class AIAssistant { return data.response || ''; } catch (error) { console.error('Error in fallbackRequestOpenAI:', error); + if (error.name === 'AbortError') { + throw new Error('Request timeout - модель не ответила в течение 60 секунд'); + } throw error; } } diff --git a/backend/services/ai-queue.js b/backend/services/ai-queue.js new file mode 100644 index 0000000..3697ac4 --- /dev/null +++ b/backend/services/ai-queue.js @@ -0,0 +1,377 @@ +/** + * 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 + */ + +const Queue = require('better-queue'); +const logger = require('../utils/logger'); + +class AIQueueService { + constructor() { + this.queue = null; + this.isInitialized = false; + this.userRequestTimes = new Map(); // Добавляем Map для отслеживания запросов пользователей + this.stats = { + totalProcessed: 0, + totalFailed: 0, + averageProcessingTime: 0, + currentQueueSize: 0, + lastProcessedAt: null + }; + + this.initQueue(); + } + + initQueue() { + try { + this.queue = new Queue(this.processTask.bind(this), { + // Ограничиваем количество одновременных запросов к Ollama + concurrent: 2, + + // Максимальное время выполнения задачи + maxTimeout: 180000, // 3 минуты + + // Задержка между задачами для предотвращения перегрузки + afterProcessDelay: 1000, // 1 секунда + + // Максимальное количество повторных попыток + maxRetries: 2, + + // Задержка между повторными попытками + retryDelay: 5000, // 5 секунд + + // Функция определения приоритета + priority: this.getTaskPriority.bind(this), + + // Функция фильтрации задач + filter: this.filterTask.bind(this), + + // Функция слияния одинаковых задач + merge: this.mergeTasks.bind(this), + + // ID задачи для предотвращения дублирования + id: 'requestId' + }); + + this.setupEventListeners(); + this.isInitialized = true; + + logger.info('[AIQueue] Queue initialized successfully'); + } catch (error) { + logger.error('[AIQueue] Failed to initialize queue:', error); + this.isInitialized = false; + } + } + + // Определение приоритета задачи + getTaskPriority(task, cb) { + try { + let priority = 1; // Базовый приоритет + + // Высокий приоритет для администраторов + if (task.userRole === 'admin') { + priority += 10; + } + + // Приоритет по типу запроса + switch (task.type) { + case 'urgent': + priority += 20; + break; + case 'chat': + priority += 5; + break; + case 'analysis': + priority += 3; + break; + case 'generation': + priority += 1; + break; + } + + // Приоритет по размеру запроса (короткие запросы имеют больший приоритет) + if (task.message && task.message.length < 100) { + priority += 2; + } + + // Приоритет по времени ожидания + const waitTime = Date.now() - task.timestamp; + if (waitTime > 30000) { // Более 30 секунд ожидания + priority += 5; + } + + cb(null, priority); + } catch (error) { + cb(error, 1); + } + } + + // Фильтрация задач + filterTask(task, cb) { + try { + // Проверяем обязательные поля + if (!task.message || typeof task.message !== 'string') { + return cb('Invalid message format'); + } + + if (!task.requestId) { + return cb('Missing request ID'); + } + + // Проверяем размер сообщения + if (task.message.length > 10000) { + return cb('Message too long (max 10000 characters)'); + } + + // Проверяем частоту запросов от пользователя + if (this.isUserRateLimited(task.userId)) { + return cb('User rate limit exceeded'); + } + + cb(null, task); + } catch (error) { + cb(error); + } + } + + // Слияние одинаковых задач + mergeTasks(oldTask, newTask, cb) { + try { + // Если это тот же запрос от того же пользователя, обновляем метаданные + if (oldTask.message === newTask.message && oldTask.userId === newTask.userId) { + oldTask.timestamp = newTask.timestamp; + oldTask.retryCount = (oldTask.retryCount || 0) + 1; + cb(null, oldTask); + } else { + cb(null, newTask); + } + } catch (error) { + cb(error); + } + } + + // Обработка задачи + async processTask(task, cb) { + const startTime = Date.now(); + const taskId = task.requestId; + + try { + logger.info(`[AIQueue] Processing task ${taskId} for user ${task.userId}`); + + // Импортируем AI сервис + const aiAssistant = require('./ai-assistant'); + const encryptedDb = require('./encryptedDatabaseService'); + + // Выполняем AI запрос + const result = await aiAssistant.getResponse( + task.message, + task.language || 'auto', + task.history || null, + task.systemPrompt || '', + task.rules || null + ); + + const processingTime = Date.now() - startTime; + + // Сохраняем AI ответ в базу данных + if (task.conversationId && result) { + try { + const aiMessage = await encryptedDb.saveData('messages', { + conversation_id: task.conversationId, + user_id: task.userId, + content: result, + sender_type: 'assistant', + role: 'assistant', + channel: 'web' + }); + + // Получаем расшифрованные данные для WebSocket + const decryptedAiMessage = await encryptedDb.getData('messages', { id: aiMessage.id }, 1); + if (decryptedAiMessage && decryptedAiMessage[0]) { + // Отправляем сообщение через WebSocket + const { broadcastChatMessage } = require('../wsHub'); + broadcastChatMessage(decryptedAiMessage[0], task.userId); + } + + logger.info(`[AIQueue] AI response saved for conversation ${task.conversationId}`); + } catch (dbError) { + logger.error(`[AIQueue] Error saving AI response:`, dbError); + } + } + + // Обновляем статистику + this.updateStats(true, processingTime); + + logger.info(`[AIQueue] Task ${taskId} completed in ${processingTime}ms`); + + cb(null, { + success: true, + result, + processingTime, + taskId + }); + + } catch (error) { + const processingTime = Date.now() - startTime; + + // Обновляем статистику + this.updateStats(false, processingTime); + + logger.error(`[AIQueue] Task ${taskId} failed:`, error); + + cb(null, { + success: false, + error: error.message, + processingTime, + taskId + }); + } + } + + // Добавление задачи в очередь + addTask(taskData) { + if (!this.isInitialized || !this.queue) { + throw new Error('Queue is not initialized'); + } + + const task = { + ...taskData, + timestamp: Date.now(), + requestId: taskData.requestId || `req_${Date.now()}_${Math.random().toString(36).substr(2, 9)}` + }; + + return new Promise((resolve, reject) => { + const ticket = this.queue.push(task, (error, result) => { + if (error) { + reject(error); + } else { + resolve(result); + } + }); + + // Добавляем обработчики событий для билета + ticket.on('failed', (error) => { + logger.error(`[AIQueue] Task ${task.requestId} failed:`, error); + reject(error); + }); + + ticket.on('finish', (result) => { + logger.info(`[AIQueue] Task ${task.requestId} finished`); + resolve(result); + }); + }); + } + + // Настройка обработчиков событий очереди + setupEventListeners() { + this.queue.on('task_queued', (taskId) => { + logger.info(`[AIQueue] Task ${taskId} queued`); + this.stats.currentQueueSize = this.queue.length; + }); + + this.queue.on('task_started', (taskId) => { + logger.info(`[AIQueue] Task ${taskId} started`); + }); + + this.queue.on('task_finish', (taskId, result) => { + logger.info(`[AIQueue] Task ${taskId} finished successfully`); + this.stats.lastProcessedAt = new Date(); + this.stats.currentQueueSize = this.queue.length; + }); + + this.queue.on('task_failed', (taskId, error) => { + logger.error(`[AIQueue] Task ${taskId} failed:`, error); + this.stats.currentQueueSize = this.queue.length; + }); + + this.queue.on('empty', () => { + logger.info('[AIQueue] Queue is empty'); + this.stats.currentQueueSize = 0; + }); + + this.queue.on('drain', () => { + logger.info('[AIQueue] Queue drained'); + this.stats.currentQueueSize = 0; + }); + } + + // Обновление статистики + updateStats(success, processingTime) { + this.stats.totalProcessed++; + if (!success) { + this.stats.totalFailed++; + } + + // Обновляем среднее время обработки + const totalTime = this.stats.averageProcessingTime * (this.stats.totalProcessed - 1) + processingTime; + this.stats.averageProcessingTime = totalTime / this.stats.totalProcessed; + } + + // Проверка ограничения частоты запросов пользователя + isUserRateLimited(userId) { + // Простая реализация - можно улучшить с использованием Redis + const now = Date.now(); + const userRequests = this.userRequestTimes.get(userId) || []; + + // Удаляем старые запросы (старше 1 минуты) + const recentRequests = userRequests.filter(time => now - time < 60000); + + // Ограничиваем до 10 запросов в минуту + if (recentRequests.length >= 10) { + return true; + } + + // Добавляем текущий запрос + recentRequests.push(now); + this.userRequestTimes.set(userId, recentRequests); + + return false; + } + + // Получение статистики очереди + getStats() { + const queueStats = this.queue ? this.queue.getStats() : {}; + + return { + ...this.stats, + queueStats, + isInitialized: this.isInitialized, + currentQueueSize: this.queue ? this.queue.length : 0, + runningTasks: this.queue ? this.queue.running : 0 + }; + } + + // Очистка очереди + clear() { + if (this.queue) { + this.queue.destroy(); + this.initQueue(); + } + } + + // Пауза/возобновление очереди + pause() { + if (this.queue) { + this.queue.pause(); + logger.info('[AIQueue] Queue paused'); + } + } + + resume() { + if (this.queue) { + this.queue.resume(); + logger.info('[AIQueue] Queue resumed'); + } + } +} + +// Создаем и экспортируем единственный экземпляр +const aiQueueService = new AIQueueService(); +module.exports = aiQueueService; \ No newline at end of file diff --git a/backend/services/aiAssistantRulesService.js b/backend/services/aiAssistantRulesService.js index 80df8b7..bd98429 100644 --- a/backend/services/aiAssistantRulesService.js +++ b/backend/services/aiAssistantRulesService.js @@ -10,38 +10,44 @@ * GitHub: https://github.com/HB3-ACCELERATOR */ -const db = require('../db'); +const encryptedDb = require('./encryptedDatabaseService'); const TABLE = 'ai_assistant_rules'; async function getAllRules() { - const { rows } = await db.getQuery()(`SELECT * FROM ${TABLE} ORDER BY id`); - return rows; + const rules = await encryptedDb.getData(TABLE, {}, null, 'id'); + return rules; } async function getRuleById(id) { - const { rows } = await db.getQuery()(`SELECT * FROM ${TABLE} WHERE id = $1`, [id]); - return rows[0] || null; + const rules = await encryptedDb.getData(TABLE, { id: id }, 1); + return rules[0] || null; } async function createRule({ name, description, rules }) { - const { rows } = await db.getQuery()( - `INSERT INTO ${TABLE} (name, description, rules, created_at, updated_at) - VALUES ($1, $2, $3, NOW(), NOW()) RETURNING *`, - [name, description, rules] - ); - return rows[0]; + const rule = await encryptedDb.saveData(TABLE, { + name: name, + description: description, + rules: rules, + created_at: new Date(), + updated_at: new Date() + }); + return rule; } async function updateRule(id, { name, description, rules }) { - const { rows } = await db.getQuery()( - `UPDATE ${TABLE} SET name = $1, description = $2, rules = $3, updated_at = NOW() WHERE id = $4 RETURNING *`, - [name, description, rules, id] - ); - return rows[0]; + const rule = await encryptedDb.saveData(TABLE, { + name: name, + description: description, + rules: rules, + updated_at: new Date() + }, { + id: id + }); + return rule; } async function deleteRule(id) { - await db.getQuery()(`DELETE FROM ${TABLE} WHERE id = $1`, [id]); + await encryptedDb.deleteData(TABLE, { id: id }); } module.exports = { getAllRules, getRuleById, createRule, updateRule, deleteRule }; \ No newline at end of file diff --git a/backend/services/aiAssistantSettingsService.js b/backend/services/aiAssistantSettingsService.js index 26dc5d5..b759291 100644 --- a/backend/services/aiAssistantSettingsService.js +++ b/backend/services/aiAssistantSettingsService.js @@ -10,53 +10,80 @@ * GitHub: https://github.com/HB3-ACCELERATOR */ +const encryptedDb = require('./encryptedDatabaseService'); const db = require('../db'); const TABLE = 'ai_assistant_settings'; async function getSettings() { - const { rows } = await db.getQuery()(`SELECT * FROM ${TABLE} ORDER BY id LIMIT 1`); - const settings = rows[0] || null; - if (!settings) return null; + const settings = await encryptedDb.getData(TABLE, {}, 1, 'id'); + const setting = settings[0] || null; + if (!setting) return null; + // Получаем ключ шифрования + const fs = require('fs'); + const path = require('path'); + let encryptionKey = 'default-key'; + + try { + const keyPath = path.join(__dirname, '../ssl/keys/full_db_encryption.key'); + if (fs.existsSync(keyPath)) { + encryptionKey = fs.readFileSync(keyPath, 'utf8').trim(); + } + } catch (keyError) { + console.error('Error reading encryption key:', keyError); + } + // Получаем связанные данные из telegram_settings и email_settings let telegramBot = null; let supportEmail = null; - if (settings.telegram_settings_id) { - const tg = await db.getQuery()('SELECT * FROM telegram_settings WHERE id = $1', [settings.telegram_settings_id]); + if (setting.telegram_settings_id) { + const tg = await db.getQuery()( + 'SELECT id, created_at, updated_at, decrypt_text(bot_token_encrypted, $2) as bot_token, decrypt_text(bot_username_encrypted, $2) as bot_username FROM telegram_settings WHERE id = $1', + [setting.telegram_settings_id, encryptionKey] + ); telegramBot = tg.rows[0] || null; } - if (settings.email_settings_id) { - const em = await db.getQuery()('SELECT * FROM email_settings WHERE id = $1', [settings.email_settings_id]); + if (setting.email_settings_id) { + const em = await db.getQuery()( + 'SELECT id, smtp_port, imap_port, created_at, updated_at, decrypt_text(smtp_host_encrypted, $2) as smtp_host, decrypt_text(smtp_user_encrypted, $2) as smtp_user, decrypt_text(smtp_password_encrypted, $2) as smtp_password, decrypt_text(imap_host_encrypted, $2) as imap_host, decrypt_text(from_email_encrypted, $2) as from_email FROM email_settings WHERE id = $1', + [setting.email_settings_id, encryptionKey] + ); supportEmail = em.rows[0] || null; } return { - ...settings, + ...setting, telegramBot, supportEmail, - embedding_model: settings.embedding_model + embedding_model: setting.embedding_model }; } async function upsertSettings({ system_prompt, selected_rag_tables, languages, model, embedding_model, rules, updated_by, telegram_settings_id, email_settings_id, system_message }) { - const { rows } = await db.getQuery()( - `INSERT INTO ${TABLE} (id, system_prompt, selected_rag_tables, languages, model, embedding_model, rules, updated_at, updated_by, telegram_settings_id, email_settings_id, system_message) - VALUES (1, $1, $2, $3, $4, $5, $6, NOW(), $7, $8, $9, $10) - ON CONFLICT (id) DO UPDATE SET - system_prompt = EXCLUDED.system_prompt, - selected_rag_tables = EXCLUDED.selected_rag_tables, - languages = EXCLUDED.languages, - model = EXCLUDED.model, - embedding_model = EXCLUDED.embedding_model, - rules = EXCLUDED.rules, - updated_at = NOW(), - updated_by = EXCLUDED.updated_by, - telegram_settings_id = EXCLUDED.telegram_settings_id, - email_settings_id = EXCLUDED.email_settings_id, - system_message = EXCLUDED.system_message - RETURNING *`, - [system_prompt, selected_rag_tables, languages, model, embedding_model, rules, updated_by, telegram_settings_id, email_settings_id, system_message] - ); - return rows[0]; + const data = { + id: 1, + system_prompt, + selected_rag_tables, + languages, + model, + embedding_model, + rules, + updated_at: new Date(), + updated_by, + telegram_settings_id, + email_settings_id, + system_message + }; + + // Проверяем, существует ли запись + const existing = await encryptedDb.getData(TABLE, { id: 1 }, 1); + + if (existing.length > 0) { + // Обновляем существующую запись + return await encryptedDb.saveData(TABLE, data, { id: 1 }); + } else { + // Создаем новую запись + return await encryptedDb.saveData(TABLE, data); + } } module.exports = { getSettings, upsertSettings }; \ No newline at end of file diff --git a/backend/services/aiProviderSettingsService.js b/backend/services/aiProviderSettingsService.js index 71ad0c5..9caa6dc 100644 --- a/backend/services/aiProviderSettingsService.js +++ b/backend/services/aiProviderSettingsService.js @@ -10,41 +10,41 @@ * GitHub: https://github.com/HB3-ACCELERATOR */ -const db = require('../db'); +const encryptedDb = require('./encryptedDatabaseService'); const OpenAI = require('openai'); const Anthropic = require('@anthropic-ai/sdk'); const TABLE = 'ai_providers_settings'; async function getProviderSettings(provider) { - const { rows } = await db.getQuery()( - `SELECT * FROM ${TABLE} WHERE provider = $1 LIMIT 1`, - [provider] - ); - return rows[0] || null; + const settings = await encryptedDb.getData(TABLE, { provider: provider }, 1); + return settings[0] || null; } async function upsertProviderSettings({ provider, api_key, base_url, selected_model, embedding_model }) { - const { rows } = await db.getQuery()( - `INSERT INTO ${TABLE} (provider, api_key, base_url, selected_model, embedding_model, updated_at) - VALUES ($1, $2, $3, $4, $5, NOW()) - ON CONFLICT (provider) DO UPDATE SET - api_key = EXCLUDED.api_key, - base_url = EXCLUDED.base_url, - selected_model = EXCLUDED.selected_model, - embedding_model = EXCLUDED.embedding_model, - updated_at = NOW() - RETURNING *`, - [provider, api_key, base_url, selected_model, embedding_model] - ); - return rows[0]; + const data = { + provider: provider, + api_key: api_key, + base_url: base_url, + selected_model: selected_model, + embedding_model: embedding_model, + updated_at: new Date() + }; + + // Проверяем, существует ли запись + const existing = await encryptedDb.getData(TABLE, { provider: provider }, 1); + + if (existing.length > 0) { + // Обновляем существующую запись + return await encryptedDb.saveData(TABLE, data, { provider: provider }); + } else { + // Создаем новую запись + return await encryptedDb.saveData(TABLE, data); + } } async function deleteProviderSettings(provider) { - await db.getQuery()( - `DELETE FROM ${TABLE} WHERE provider = $1`, - [provider] - ); + await encryptedDb.deleteData(TABLE, { provider: provider }); } async function getProviderModels(provider, { api_key, base_url } = {}) { @@ -111,19 +111,130 @@ async function verifyProviderKey(provider, { api_key, base_url } = {}) { } async function getAllLLMModels() { - const { rows } = await db.getQuery()( - `SELECT provider, selected_model FROM ${TABLE} WHERE selected_model IS NOT NULL AND selected_model <> ''` - ); - // Возвращаем массив объектов { id, provider } - return rows.map(r => ({ id: r.selected_model, provider: r.provider })); + try { + // Получаем все настройки провайдеров + const providers = await encryptedDb.getData(TABLE, {}); + + // Собираем все модели из всех провайдеров + const allModels = []; + + for (const provider of providers) { + if (provider.selected_model) { + allModels.push({ + id: provider.selected_model, + provider: provider.provider + }); + } + } + + // Для Ollama проверяем реально установленные модели + try { + const { exec } = require('child_process'); + const util = require('util'); + const execAsync = util.promisify(exec); + + // Проверяем, какие модели установлены в Ollama + const { stdout } = await execAsync('docker exec dapp-ollama ollama list'); + const lines = stdout.trim().split('\n').slice(1); // Пропускаем заголовок + + for (const line of lines) { + const parts = line.trim().split(/\s+/); + if (parts.length >= 2) { + const modelName = parts[0]; + allModels.push({ + id: modelName, + provider: 'ollama' + }); + } + } + } catch (ollamaError) { + console.error('Error checking Ollama models:', ollamaError); + // Если не удалось проверить Ollama, добавляем базовые модели + allModels.push({ id: 'qwen2.5:7b', provider: 'ollama' }); + } + + // Убираем дубликаты + const uniqueModels = []; + const seen = new Set(); + + for (const model of allModels) { + const key = `${model.id}-${model.provider}`; + if (!seen.has(key)) { + seen.add(key); + uniqueModels.push(model); + } + } + + return uniqueModels; + } catch (error) { + console.error('Error getting LLM models:', error); + return []; + } } async function getAllEmbeddingModels() { - const { rows } = await db.getQuery()( - `SELECT provider, embedding_model FROM ${TABLE} WHERE embedding_model IS NOT NULL AND embedding_model <> ''` - ); - // Возвращаем массив объектов { id, provider } - return rows.map(r => ({ id: r.embedding_model, provider: r.provider })); + try { + // Получаем все настройки провайдеров + const providers = await encryptedDb.getData(TABLE, {}); + + // Собираем все embedding модели из всех провайдеров + const allModels = []; + + for (const provider of providers) { + if (provider.embedding_model) { + allModels.push({ + id: provider.embedding_model, + provider: provider.provider + }); + } + } + + // Для Ollama проверяем реально установленные embedding модели + try { + const { exec } = require('child_process'); + const util = require('util'); + const execAsync = util.promisify(exec); + + // Проверяем, какие embedding модели установлены в Ollama + const { stdout } = await execAsync('docker exec dapp-ollama ollama list'); + const lines = stdout.trim().split('\n').slice(1); // Пропускаем заголовок + + for (const line of lines) { + const parts = line.trim().split(/\s+/); + if (parts.length >= 2) { + const modelName = parts[0]; + // Проверяем, что это embedding модель + if (modelName.includes('embed') || modelName.includes('bge') || modelName.includes('nomic')) { + allModels.push({ + id: modelName, + provider: 'ollama' + }); + } + } + } + } catch (ollamaError) { + console.error('Error checking Ollama embedding models:', ollamaError); + // Если не удалось проверить Ollama, добавляем базовые embedding модели + allModels.push({ id: 'mxbai-embed-large:latest', provider: 'ollama' }); + } + + // Убираем дубликаты + const uniqueModels = []; + const seen = new Set(); + + for (const model of allModels) { + const key = `${model.id}-${model.provider}`; + if (!seen.has(key)) { + seen.add(key); + uniqueModels.push(model); + } + } + + return uniqueModels; + } catch (error) { + console.error('Error getting embedding models:', error); + return []; + } } module.exports = { diff --git a/backend/services/auth-service.js b/backend/services/auth-service.js index 81fbddb..c863ec7 100644 --- a/backend/services/auth-service.js +++ b/backend/services/auth-service.js @@ -10,6 +10,7 @@ * GitHub: https://github.com/HB3-ACCELERATOR */ +const encryptedDb = require('./encryptedDatabaseService'); const db = require('../db'); const logger = require('../utils/logger'); const { ethers } = require('ethers'); @@ -34,13 +35,20 @@ class AuthService { if (!message || !signature || !address) return false; // Нормализуем входящий адрес - const normalizedAddress = ethers.getAddress(address).toLowerCase(); + const normalizedAddress = ethers.getAddress(address); // Восстанавливаем адрес из подписи const recoveredAddress = ethers.verifyMessage(message, signature); + // Логируем для отладки + logger.info(`[verifySignature] Message: ${message}`); + logger.info(`[verifySignature] Signature: ${signature}`); + logger.info(`[verifySignature] Expected address: ${normalizedAddress}`); + logger.info(`[verifySignature] Recovered address: ${recoveredAddress}`); + logger.info(`[verifySignature] Addresses match: ${ethers.getAddress(recoveredAddress) === normalizedAddress}`); + // Сравниваем нормализованные адреса - return ethers.getAddress(recoveredAddress).toLowerCase() === normalizedAddress; + return ethers.getAddress(recoveredAddress) === normalizedAddress; } catch (error) { logger.error('Error in signature verification:', error); return false; @@ -58,43 +66,40 @@ class AuthService { const normalizedAddress = ethers.getAddress(address).toLowerCase(); // Ищем пользователя по адресу в таблице user_identities - const userResult = await db.getQuery()( - ` - SELECT u.* FROM users u - JOIN user_identities ui ON u.id = ui.user_id - WHERE ui.provider = 'wallet' AND ui.provider_id = $1 - `, - [normalizedAddress] - ); + const identities = await encryptedDb.getData('user_identities', { + provider: 'wallet', + provider_id: normalizedAddress + }, 1); - if (userResult.rows.length > 0) { - const user = userResult.rows[0]; + if (identities.length > 0) { + const user = await encryptedDb.getData('users', { id: identities[0].user_id }, 1); + if (user.length === 0) { + throw new Error('User not found'); + } + const userData = user[0]; // Проверяем роль администратора при каждой аутентификации const isAdmin = await checkAdminRole(normalizedAddress); // Если статус админа изменился, обновляем роль в базе данных - if (user.role === 'admin' && !isAdmin) { - await db.getQuery()('UPDATE users SET role = $1 WHERE id = $2', ['user', user.id]); - logger.info(`Updated user ${user.id} role to user (admin tokens no longer present)`); - return { userId: user.id, isAdmin: false }; - } else if (user.role !== 'admin' && isAdmin) { - await db.getQuery()('UPDATE users SET role = $1 WHERE id = $2', ['admin', user.id]); - logger.info(`Updated user ${user.id} role to admin (admin tokens found)`); - return { userId: user.id, isAdmin: true }; + if (userData.role === 'admin' && !isAdmin) { + await db.getQuery()('UPDATE users SET role = $1 WHERE id = $2', ['user', userData.id]); + logger.info(`Updated user ${userData.id} role to user (admin tokens no longer present)`); + return { userId: userData.id, isAdmin: false }; + } else if (userData.role !== 'admin' && isAdmin) { + await db.getQuery()('UPDATE users SET role = $1 WHERE id = $2', ['admin', userData.id]); + logger.info(`Updated user ${userData.id} role to admin (admin tokens found)`); + return { userId: userData.id, isAdmin: true }; } return { - userId: user.id, - isAdmin: user.role === 'admin', + userId: userData.id, + isAdmin: userData.role === 'admin', }; } // Если пользователь не найден, создаем нового - const newUserResult = await db.getQuery()('INSERT INTO users (role) VALUES ($1) RETURNING id', [ - 'user', - ]); - + const newUserResult = await db.getQuery()('INSERT INTO users (role) VALUES ($1) RETURNING id', ['user']); const userId = newUserResult.rows[0].id; // Добавляем идентификатор кошелька (всегда в нижнем регистре) @@ -209,7 +214,7 @@ class AuthService { } // Создание сессии с проверкой роли - async createSession(session, { userId, authenticated, authType, guestId, address }) { + async createSession(session, { userId, authenticated, authType, guestId, address, isAdmin }) { try { // Если пользователь аутентифицирован, обрабатываем гостевые сообщения if (authenticated && guestId) { @@ -220,6 +225,7 @@ class AuthService { session.userId = userId; session.authenticated = authenticated; session.authType = authType; + session.isAdmin = isAdmin || false; // Сохраняем адрес кошелька если есть if (address) { @@ -237,6 +243,7 @@ class AuthService { authenticated, authType, address, + isAdmin: isAdmin || false, cookie: session.cookie, }), session.id, @@ -328,7 +335,7 @@ class AuthService { const email = result.providerId; // Проверяем, существует ли пользователь с таким email - const userResult = await db.getQuery()('SELECT * FROM users WHERE id = $1', [userId]); + const userResult = await db.getQuery()('SELECT id, role, created_at, updated_at, is_blocked, blocked_at, preferred_language FROM users WHERE id = $1', [userId]); if (userResult.rows.length === 0) { return { verified: false }; @@ -428,9 +435,23 @@ class AuthService { // Если есть гостевой ID в сессии, сохраняем его для нового пользователя if (session.guestId && isNewUser) { + // Получаем ключ шифрования + const fs = require('fs'); + const path = require('path'); + let encryptionKey = 'default-key'; + + try { + const keyPath = path.join(__dirname, '../ssl/keys/full_db_encryption.key'); + if (fs.existsSync(keyPath)) { + encryptionKey = fs.readFileSync(keyPath, 'utf8').trim(); + } + } catch (keyError) { + console.error('Error reading encryption key:', keyError); + } + await db.getQuery()( - 'INSERT INTO guest_user_mapping (user_id, guest_id) VALUES ($1, $2) ON CONFLICT (guest_id) DO UPDATE SET user_id = $1', - [userId, session.guestId] + 'INSERT INTO guest_user_mapping (user_id, guest_id_encrypted) VALUES ($1, encrypt_text($2, $3)) ON CONFLICT (guest_id_encrypted) DO UPDATE SET user_id = $1', + [userId, session.guestId, encryptionKey] ); logger.info(`[verifyTelegramAuth] Saved guest ID ${session.guestId} for user ${userId}`); } @@ -460,13 +481,27 @@ class AuthService { // Обновляем роль пользователя в базе данных, если есть админские токены if (isAdmin) { try { + // Получаем ключ шифрования + const fs = require('fs'); + const path = require('path'); + let encryptionKey = 'default-key'; + + try { + const keyPath = path.join(__dirname, '../ssl/keys/full_db_encryption.key'); + if (fs.existsSync(keyPath)) { + encryptionKey = fs.readFileSync(keyPath, 'utf8').trim(); + } + } catch (keyError) { + console.error('Error reading encryption key:', keyError); + } + // Находим userId по адресу const userResult = await db.getQuery()( ` SELECT u.id FROM users u JOIN user_identities ui ON u.id = ui.user_id - WHERE ui.provider = 'wallet' AND ui.provider_id = $1`, - [address.toLowerCase()] + WHERE ui.provider_encrypted = encrypt_text('wallet', $2) AND ui.provider_id_encrypted = encrypt_text($1, $2)`, + [address.toLowerCase(), encryptionKey] ); if (userResult.rows.length > 0) { @@ -486,8 +521,8 @@ class AuthService { ` SELECT u.id, u.role FROM users u JOIN user_identities ui ON u.id = ui.user_id - WHERE ui.provider = 'wallet' AND ui.provider_id = $1`, - [address.toLowerCase()] + WHERE ui.provider_encrypted = encrypt_text('wallet', $2) AND ui.provider_id_encrypted = encrypt_text($1, $2)`, + [address.toLowerCase(), encryptionKey] ); if (userResult.rows.length > 0 && userResult.rows[0].role === 'admin') { @@ -531,7 +566,7 @@ class AuthService { // Удаляем старые идентификаторы for (const identity of identitiesToDelete) { await db.getQuery()('DELETE FROM user_identities WHERE id = $1', [identity.id]); - logger.info(`Deleted old guest identity: ${identity.identity_value}`); + logger.info(`Deleted old guest identity: ${identity.id}`); } } } catch (error) { @@ -546,11 +581,8 @@ class AuthService { */ async getUserIdentities(userId) { try { - const result = await db.getQuery()( - 'SELECT * FROM user_identities WHERE user_id = $1 ORDER BY created_at DESC', - [userId] - ); - return result.rows; + const identities = await encryptedDb.getData('user_identities', { user_id: userId }, null, 'created_at DESC'); + return identities; } catch (error) { logger.error('[getUserIdentities] Error:', error); throw error; @@ -611,13 +643,13 @@ class AuthService { ); // Проверяем, существует ли уже такой идентификатор - const existingResult = await db.getQuery()( - `SELECT user_id FROM user_identities WHERE provider = $1 AND provider_id = $2`, - [provider, normalizedProviderId] - ); + const existingIdentities = await encryptedDb.getData('user_identities', { + provider: provider, + provider_id: normalizedProviderId + }, 1); - if (existingResult.rows.length > 0) { - const existingUserId = existingResult.rows[0].user_id; + if (existingIdentities.length > 0) { + const existingUserId = existingIdentities[0].user_id; // Если идентификатор уже принадлежит этому пользователю, ничего не делаем if (existingUserId === userId) { @@ -779,8 +811,33 @@ class AuthService { */ async getUserTokenBalances(address) { if (!address) return []; - const tokens = await authTokenService.getAllAuthTokens(); - const rpcProviders = await rpcProviderService.getAllRpcProviders(); + + // Получаем ключ шифрования + const fs = require('fs'); + const path = require('path'); + let encryptionKey = 'default-key'; + + try { + const keyPath = path.join(__dirname, '../ssl/keys/full_db_encryption.key'); + if (fs.existsSync(keyPath)) { + encryptionKey = fs.readFileSync(keyPath, 'utf8').trim(); + } + } catch (keyError) { + console.error('Error reading encryption key:', keyError); + } + + // Получаем токены и RPC с расшифровкой + const tokensResult = await db.getQuery()( + 'SELECT id, min_balance, created_at, updated_at, decrypt_text(name_encrypted, $1) as name, decrypt_text(address_encrypted, $1) as address, decrypt_text(network_encrypted, $1) as network FROM auth_tokens', + [encryptionKey] + ); + const tokens = tokensResult.rows; + + const rpcProvidersResult = await db.getQuery()( + 'SELECT id, chain_id, created_at, updated_at, decrypt_text(network_id_encrypted, $1) as network_id, decrypt_text(rpc_url_encrypted, $1) as rpc_url FROM rpc_providers', + [encryptionKey] + ); + const rpcProviders = rpcProvidersResult.rows; const rpcMap = {}; for (const rpc of rpcProviders) { rpcMap[rpc.network_id] = rpc.rpc_url; @@ -811,6 +868,41 @@ class AuthService { } return results; } + + /** + * Проверяет nonce для адреса кошелька + * @param {string} address - адрес кошелька + * @param {string} nonce - nonce для проверки + * @returns {Promise} - true если nonce валиден + */ + async verifyNonce(address, nonce) { + try { + // Получаем nonce из базы данных через encryptedDb + const nonceData = await encryptedDb.getData('nonces', { + identity_value: address.toLowerCase() + }, 1); + + if (nonceData.length === 0) { + logger.warn(`[verifyNonce] No nonce found for address: ${address}`); + return false; + } + + // Получаем nonce из результата + const storedNonce = nonceData[0].nonce; + + // Сравниваем с переданным nonce + const isValid = storedNonce === nonce; + + if (!isValid) { + logger.warn(`[verifyNonce] Invalid nonce for address: ${address}. Expected: ${storedNonce}, Got: ${nonce}`); + } + + return isValid; + } catch (error) { + logger.error(`[verifyNonce] Error verifying nonce for address ${address}:`, error); + return false; + } + } } // Создаем и экспортируем единственный экземпляр diff --git a/backend/services/authTokenService.js b/backend/services/authTokenService.js index 70779a2..ea36881 100644 --- a/backend/services/authTokenService.js +++ b/backend/services/authTokenService.js @@ -10,35 +10,59 @@ * GitHub: https://github.com/HB3-ACCELERATOR */ -const db = require('../db'); +const encryptedDb = require('./encryptedDatabaseService'); async function getAllAuthTokens() { - const { rows } = await db.getQuery()('SELECT * FROM auth_tokens ORDER BY id'); - return rows; + const tokens = await encryptedDb.getData('auth_tokens', {}, null, 'id'); + return tokens; } async function saveAllAuthTokens(authTokens) { - await db.getQuery()('DELETE FROM auth_tokens'); + // Удаляем все существующие токены + await encryptedDb.deleteData('auth_tokens', {}); + + // Сохраняем новые токены for (const token of authTokens) { - await db.getQuery()( - 'INSERT INTO auth_tokens (name, address, network, min_balance) VALUES ($1, $2, $3, $4)', - [token.name, token.address, token.network, token.minBalance] - ); + await encryptedDb.saveData('auth_tokens', { + name: token.name, + address: token.address, + network: token.network, + min_balance: token.minBalance == null ? 0 : Number(token.minBalance) + }); } } async function upsertAuthToken(token) { const minBalance = token.minBalance == null ? 0 : Number(token.minBalance); - await db.getQuery()( - `INSERT INTO auth_tokens (name, address, network, min_balance) - VALUES ($1, $2, $3, $4) - ON CONFLICT (address, network) DO UPDATE SET name=EXCLUDED.name, min_balance=EXCLUDED.min_balance`, - [token.name, token.address, token.network, minBalance] - ); + + // Проверяем, существует ли токен + const existingTokens = await encryptedDb.getData('auth_tokens', { + address: token.address, + network: token.network + }, 1); + + if (existingTokens.length > 0) { + // Обновляем существующий токен + await encryptedDb.saveData('auth_tokens', { + name: token.name, + min_balance: minBalance + }, { + address: token.address, + network: token.network + }); + } else { + // Создаем новый токен + await encryptedDb.saveData('auth_tokens', { + name: token.name, + address: token.address, + network: token.network, + min_balance: minBalance + }); + } } async function deleteAuthToken(address, network) { - await db.getQuery()('DELETE FROM auth_tokens WHERE address = $1 AND network = $2', [address, network]); + await encryptedDb.deleteData('auth_tokens', { address, network }); } module.exports = { getAllAuthTokens, saveAllAuthTokens, upsertAuthToken, deleteAuthToken }; \ No newline at end of file diff --git a/backend/services/dbSettingsService.js b/backend/services/dbSettingsService.js index 5d0c38c..404cc42 100644 --- a/backend/services/dbSettingsService.js +++ b/backend/services/dbSettingsService.js @@ -10,29 +10,39 @@ * GitHub: https://github.com/HB3-ACCELERATOR */ -const db = require('../db'); +const encryptedDb = require('./encryptedDatabaseService'); class DbSettingsService { async getSettings() { - const { rows } = await db.getQuery()('SELECT * FROM db_settings WHERE id = 1'); + const rows = await encryptedDb.getData('db_settings', { id: 1 }, 1); return rows[0]; } async upsertSettings({ db_host, db_port, db_name, db_user, db_password }) { - const { rows } = await db.getQuery()( - `INSERT INTO db_settings (id, db_host, db_port, db_name, db_user, db_password, updated_at) - VALUES (1, $1, $2, $3, $4, $5, NOW()) - ON CONFLICT (id) DO UPDATE SET - db_host = EXCLUDED.db_host, - db_port = EXCLUDED.db_port, - db_name = EXCLUDED.db_name, - db_user = EXCLUDED.db_user, - db_password = EXCLUDED.db_password, - updated_at = NOW() - RETURNING *`, - [db_host, db_port, db_name, db_user, db_password] - ); - return rows[0]; + const data = { + id: 1, + db_host, + db_port, + db_name, + db_user, + db_password, + updated_at: new Date() + }; + + // Пытаемся обновить существующую запись + const existing = await this.getSettings(); + if (existing) { + return await encryptedDb.saveData('db_settings', data, { id: 1 }); + } else { + return await encryptedDb.saveData('db_settings', data); + } + } + + /** + * Получить статус шифрования + */ + getEncryptionStatus() { + return encryptedDb.getEncryptionStatus(); } } diff --git a/backend/services/dleV2Service.js b/backend/services/dleV2Service.js new file mode 100644 index 0000000..3ed4d55 --- /dev/null +++ b/backend/services/dleV2Service.js @@ -0,0 +1,313 @@ +/** + * 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 + */ + +const { spawn } = require('child_process'); +const path = require('path'); +const fs = require('fs'); +const { ethers } = require('ethers'); +const logger = require('../utils/logger'); +const { getRpcUrlByNetworkId } = require('./rpcProviderService'); + +/** + * Сервис для управления DLE v2 (Digital Legal Entity) + * Современный подход с единым контрактом + */ +class DLEV2Service { + /** + * Создает новое DLE v2 с заданными параметрами + * @param {Object} dleParams - Параметры DLE + * @returns {Promise} - Результат создания DLE + */ + async createDLE(dleParams) { + try { + logger.info('Начало создания DLE v2 с параметрами:', dleParams); + + // Валидация входных данных + this.validateDLEParams(dleParams); + + // Подготовка параметров для деплоя + const deployParams = this.prepareDeployParams(dleParams); + + // Сохраняем параметры во временный файл + const paramsFile = this.saveParamsToFile(deployParams); + + // Копируем параметры во временный файл с предсказуемым именем + const tempParamsFile = path.join(__dirname, '../scripts/deploy/current-params.json'); + const deployDir = path.dirname(tempParamsFile); + if (!fs.existsSync(deployDir)) { + fs.mkdirSync(deployDir, { recursive: true }); + } + fs.copyFileSync(paramsFile, tempParamsFile); + logger.info(`Файл параметров скопирован успешно`); + + // Получаем rpc_url из базы по выбранной сети + const rpcUrl = await getRpcUrlByNetworkId(deployParams.network); + if (!rpcUrl) { + throw new Error(`RPC URL для сети ${deployParams.network} не найден в базе данных`); + } + if (!dleParams.privateKey) { + throw new Error('Приватный ключ для деплоя не передан'); + } + + // Запускаем скрипт деплоя с нужными переменными окружения + const result = await this.runDeployScript(paramsFile, { + rpcUrl, + privateKey: dleParams.privateKey, + networkId: deployParams.network, + envNetworkKey: deployParams.network.toUpperCase() + }); + + // Очищаем временные файлы + this.cleanupTempFiles(paramsFile, tempParamsFile); + + return result; + + } catch (error) { + logger.error('Ошибка при создании DLE v2:', error); + throw error; + } + } + + /** + * Валидирует параметры DLE + * @param {Object} params - Параметры для валидации + */ + validateDLEParams(params) { + if (!params.name || params.name.trim() === '') { + throw new Error('Название DLE обязательно'); + } + + if (!params.symbol || params.symbol.trim() === '') { + throw new Error('Символ токена обязателен'); + } + + if (!params.location || params.location.trim() === '') { + throw new Error('Местонахождение DLE обязательно'); + } + + if (!params.partners || !Array.isArray(params.partners)) { + throw new Error('Партнеры должны быть массивом'); + } + + if (!params.amounts || !Array.isArray(params.amounts)) { + throw new Error('Суммы должны быть массивом'); + } + + if (params.partners.length !== params.amounts.length) { + throw new Error('Количество партнеров должно соответствовать количеству сумм распределения'); + } + + if (params.partners.length === 0) { + throw new Error('Должен быть указан хотя бы один партнер'); + } + + if (params.quorumPercentage > 100) { + throw new Error('Процент кворума не может превышать 100%'); + } + + // Проверяем адреса партнеров + for (let i = 0; i < params.partners.length; i++) { + if (!ethers.isAddress(params.partners[i])) { + throw new Error(`Неверный адрес партнера ${i + 1}: ${params.partners[i]}`); + } + } + } + + /** + * Подготавливает параметры для деплоя + * @param {Object} params - Параметры DLE + * @returns {Object} - Подготовленные параметры + */ + prepareDeployParams(params) { + // Создаем копию объекта, чтобы не изменять исходный + const deployParams = { ...params }; + + // Преобразуем суммы из строк или чисел в BigNumber, если нужно + deployParams.amounts = params.amounts.map(amount => { + if (typeof amount === 'string' && !amount.startsWith('0x')) { + return ethers.parseEther(amount).toString(); + } + return amount.toString(); + }); + + // Преобразуем параметры голосования + deployParams.votingDelay = params.votingDelay || 1; + deployParams.votingPeriod = params.votingPeriod || 45818; // ~1 неделя + deployParams.proposalThreshold = params.proposalThreshold || ethers.parseEther("100000").toString(); + deployParams.quorumPercentage = params.quorumPercentage || 4; + deployParams.minTimelockDelay = params.minTimelockDelay || 2; + + // Убеждаемся, что isicCodes - это массив + if (!Array.isArray(deployParams.isicCodes)) { + deployParams.isicCodes = []; + } + + return deployParams; + } + + /** + * Сохраняет параметры во временный файл + * @param {Object} params - Параметры для сохранения + * @returns {string} - Путь к сохраненному файлу + */ + saveParamsToFile(params) { + const tempDir = path.join(__dirname, '../temp'); + + if (!fs.existsSync(tempDir)) { + fs.mkdirSync(tempDir, { recursive: true }); + } + + const fileName = `dle-v2-params-${Date.now()}.json`; + const filePath = path.join(tempDir, fileName); + + fs.writeFileSync(filePath, JSON.stringify(params, null, 2)); + + return filePath; + } + + /** + * Запускает скрипт деплоя DLE v2 + * @param {string} paramsFile - Путь к файлу с параметрами + * @returns {Promise} - Результат деплоя + */ + runDeployScript(paramsFile, extraEnv = {}) { + return new Promise((resolve, reject) => { + const scriptPath = path.join(__dirname, '../scripts/deploy/create-dle-v2.js'); + if (!fs.existsSync(scriptPath)) { + reject(new Error('Скрипт деплоя DLE v2 не найден: ' + scriptPath)); + return; + } + + // Формируем универсальные переменные окружения + const envVars = { + ...process.env, + [`${extraEnv.envNetworkKey}_RPC_URL`]: extraEnv.rpcUrl, + [`${extraEnv.envNetworkKey}_PRIVATE_KEY`]: extraEnv.privateKey + }; + + // Запускаем скрипт с нужной сетью + const hardhatProcess = spawn('npx', ['hardhat', 'run', scriptPath, '--network', extraEnv.networkId], { + cwd: path.join(__dirname, '..'), + env: envVars, + stdio: 'pipe' + }); + + let stdout = ''; + let stderr = ''; + + hardhatProcess.stdout.on('data', (data) => { + stdout += data.toString(); + logger.info(`[DLE v2 Deploy] ${data.toString().trim()}`); + }); + + hardhatProcess.stderr.on('data', (data) => { + stderr += data.toString(); + logger.error(`[DLE v2 Deploy Error] ${data.toString().trim()}`); + }); + + hardhatProcess.on('close', (code) => { + if (code === 0) { + try { + // Пытаемся извлечь результат из stdout + const result = this.extractDeployResult(stdout); + resolve(result); + } catch (error) { + logger.error('Ошибка при извлечении результатов деплоя DLE v2:', error); + reject(new Error('Не удалось найти информацию о созданном DLE v2')); + } + } else { + reject(new Error(`Скрипт деплоя DLE v2 завершился с кодом ${code}: ${stderr}`)); + } + }); + + hardhatProcess.on('error', (error) => { + logger.error('Ошибка запуска скрипта деплоя DLE v2:', error); + reject(error); + }); + }); + } + + /** + * Извлекает результат деплоя из stdout + * @param {string} stdout - Вывод скрипта + * @returns {Object} - Результат деплоя + */ + extractDeployResult(stdout) { + // Ищем строки с адресами в выводе + const dleAddressMatch = stdout.match(/DLE v2 задеплоен по адресу: (0x[a-fA-F0-9]{40})/); + const timelockAddressMatch = stdout.match(/Таймлок создан по адресу: (0x[a-fA-F0-9]{40})/); + + if (dleAddressMatch && timelockAddressMatch) { + return { + success: true, + data: { + dleAddress: dleAddressMatch[1], + timelockAddress: timelockAddressMatch[1], + version: 'v2' + } + }; + } + + throw new Error('Не удалось извлечь адреса из вывода скрипта'); + } + + /** + * Очищает временные файлы + * @param {string} paramsFile - Путь к файлу параметров + * @param {string} tempParamsFile - Путь к временному файлу параметров + */ + cleanupTempFiles(paramsFile, tempParamsFile) { + try { + if (fs.existsSync(paramsFile)) { + fs.unlinkSync(paramsFile); + } + if (fs.existsSync(tempParamsFile)) { + fs.unlinkSync(tempParamsFile); + } + } catch (error) { + logger.warn('Не удалось очистить временные файлы:', error); + } + } + + /** + * Получает список всех созданных DLE v2 + * @returns {Array} - Список DLE v2 + */ + getAllDLEs() { + try { + const dlesDir = path.join(__dirname, '../contracts-data/dles'); + + if (!fs.existsSync(dlesDir)) { + return []; + } + + const files = fs.readdirSync(dlesDir); + return files + .filter(file => file.endsWith('.json') && file.includes('dle-v2-')) + .map(file => { + try { + const data = JSON.parse(fs.readFileSync(path.join(dlesDir, file), 'utf8')); + return { ...data, _fileName: file }; + } catch (error) { + logger.error(`Ошибка при чтении файла ${file}:`, error); + return null; + } + }) + .filter(dle => dle !== null); + } catch (error) { + logger.error('Ошибка при получении списка DLE v2:', error); + return []; + } + } +} + +module.exports = new DLEV2Service(); \ No newline at end of file diff --git a/backend/services/emailAuth.js b/backend/services/emailAuth.js index cca784d..0fcea0f 100644 --- a/backend/services/emailAuth.js +++ b/backend/services/emailAuth.js @@ -14,7 +14,7 @@ const { pool } = require('../db'); const verificationService = require('./verification-service'); const logger = require('../utils/logger'); const EmailBotService = require('./emailBot.js'); -const db = require('../db'); +const encryptedDb = require('./encryptedDatabaseService'); const authService = require('./auth-service'); const { checkAdminRole } = require('./admin-role'); const { broadcastContactsUpdate } = require('../wsHub'); @@ -31,12 +31,10 @@ class EmailAuth { } // Проверяем, существует ли пользователь с таким email - const existingEmailUser = await db.getQuery()( - `SELECT u.id FROM users u - JOIN user_identities i ON u.id = i.user_id - WHERE i.provider = 'email' AND i.provider_id = $1`, - [email.toLowerCase()] - ); + const existingEmailUsers = await encryptedDb.getData('user_identities', { + provider: 'email', + provider_id: email.toLowerCase() + }, 1); // Создаем или получаем ID пользователя let userId; @@ -47,16 +45,16 @@ class EmailAuth { logger.info( `[initEmailAuth] Using existing authenticated user ${userId} for email ${email}` ); - } else if (existingEmailUser.rows.length > 0) { + } else if (existingEmailUsers.length > 0) { // Если найден пользователь с таким email, используем его ID - userId = existingEmailUser.rows[0].id; + userId = existingEmailUsers[0].user_id; logger.info(`[initEmailAuth] Found existing user ${userId} with email ${email}`); } else { // Создаем временного пользователя, если нужно будет создать нового - const userResult = await db.getQuery()('INSERT INTO users (role) VALUES ($1) RETURNING id', [ - 'user', - ]); - userId = userResult.rows[0].id; + const newUser = await encryptedDb.saveData('users', { + role: 'user' + }); + userId = newUser.id; session.tempUserId = userId; logger.info(`[initEmailAuth] Created temporary user ${userId} for email ${email}`); } @@ -165,11 +163,10 @@ class EmailAuth { finalUserId = session.tempUserId; logger.info(`[checkEmailVerification] Using temporary user ${finalUserId}`); } else { - const newUserResult = await db.getQuery()( - 'INSERT INTO users (role) VALUES ($1) RETURNING id', - ['user'] - ); - finalUserId = newUserResult.rows[0].id; + const newUserResult = await encryptedDb.saveData('users', { + role: 'user' + }); + finalUserId = newUserResult.id; logger.info(`[checkEmailVerification] Created new user ${finalUserId}`); } } @@ -189,9 +186,9 @@ class EmailAuth { logger.info(`[checkEmailVerification] Role for user ${finalUserId} determined as: ${userRole}`); // Опционально: Обновить роль в таблице users, если она отличается - const currentUser = await db.getQuery()('SELECT role FROM users WHERE id = $1', [finalUserId]); - if (currentUser.rows.length > 0 && currentUser.rows[0].role !== userRole) { - await db.getQuery()('UPDATE users SET role = $1 WHERE id = $2', [userRole, finalUserId]); + const currentUser = await encryptedDb.getData('users', { id: finalUserId }, 1); + if (currentUser.length > 0 && currentUser[0].role !== userRole) { + await encryptedDb.saveData('users', { role: userRole, id: finalUserId }); logger.info(`[checkEmailVerification] Updated user role in DB to ${userRole}`); } } else { diff --git a/backend/services/emailBot.js b/backend/services/emailBot.js index f4bee79..729ce66 100644 --- a/backend/services/emailBot.js +++ b/backend/services/emailBot.js @@ -11,6 +11,7 @@ */ console.log('[EmailBot] emailBot.js loaded'); +const encryptedDb = require('./encryptedDatabaseService'); const db = require('../db'); const nodemailer = require('nodemailer'); const Imap = require('imap'); @@ -31,7 +32,24 @@ class EmailBotService { } async getSettingsFromDb() { - const { rows } = await db.getQuery()('SELECT * FROM email_settings ORDER BY id LIMIT 1'); + // Получаем ключ шифрования + const fs = require('fs'); + const path = require('path'); + let encryptionKey = 'default-key'; + + try { + const keyPath = path.join(__dirname, '../ssl/keys/full_db_encryption.key'); + if (fs.existsSync(keyPath)) { + encryptionKey = fs.readFileSync(keyPath, 'utf8').trim(); + } + } catch (keyError) { + console.error('Error reading encryption key:', keyError); + } + + const { rows } = await db.getQuery()( + 'SELECT id, smtp_port, imap_port, created_at, updated_at, decrypt_text(smtp_host_encrypted, $1) as smtp_host, decrypt_text(smtp_user_encrypted, $1) as smtp_user, decrypt_text(smtp_password_encrypted, $1) as smtp_password, decrypt_text(imap_host_encrypted, $1) as imap_host, decrypt_text(from_email_encrypted, $1) as from_email FROM email_settings ORDER BY id LIMIT 1', + [encryptionKey] + ); if (!rows.length) throw new Error('Email settings not found in DB'); return rows[0]; } @@ -160,43 +178,68 @@ class EmailBotService { return; } // 1.1 Найти или создать беседу - let conversationResult = await db.getQuery()( - 'SELECT * FROM conversations WHERE user_id = $1 ORDER BY updated_at DESC, created_at DESC LIMIT 1', - [userId] - ); + let conversationResult = await encryptedDb.getData( + 'conversations', + { user_id: userId }, + 1, + 'updated_at DESC, created_at DESC' + ); let conversation; - if (conversationResult.rows.length === 0) { + if (conversationResult.length === 0) { const title = `Чат с пользователем ${userId}`; - const newConv = await db.getQuery()( - 'INSERT INTO conversations (user_id, title, created_at, updated_at) VALUES ($1, $2, NOW(), NOW()) RETURNING *', - [userId, title] - ); - conversation = newConv.rows[0]; + const newConv = await encryptedDb.saveData( + 'conversations', + { user_id: userId, title: title, created_at: new Date(), updated_at: new Date() } + ); + conversation = newConv; } else { - conversation = conversationResult.rows[0]; + conversation = conversationResult[0]; } + + // Проверяем, что conversation создан успешно + if (!conversation || !conversation.id) { + logger.error(`[EmailBot] Conversation is undefined or has no id for user ${userId}`); + return; + } + // 2. Сохранять все сообщения с conversation_id let hasAttachments = parsed.attachments && parsed.attachments.length > 0; if (hasAttachments) { for (const att of parsed.attachments) { - await db.getQuery()( - `INSERT INTO messages (user_id, conversation_id, sender_type, content, channel, role, direction, created_at, attachment_filename, attachment_mimetype, attachment_size, attachment_data, metadata) - VALUES ($1, $2, $3, $4, $5, $6, $7, NOW(), $8, $9, $10, $11, $12)`, - [userId, conversation.id, 'user', text, 'email', role, 'in', - att.filename, - att.contentType, - att.size, - att.content, - JSON.stringify({ subject, html }) - ] - ); + await encryptedDb.saveData( + 'messages', + { + user_id: userId, + conversation_id: conversation.id, + sender_type: 'user', + content: text, + channel: 'email', + role: role, + direction: 'in', + created_at: new Date(), + attachment_filename: att.filename, + attachment_mimetype: att.contentType, + attachment_size: att.size, + attachment_data: att.content, + metadata: JSON.stringify({ subject, html }) + } + ); } } else { - await db.getQuery()( - `INSERT INTO messages (user_id, conversation_id, sender_type, content, channel, role, direction, created_at, metadata) - VALUES ($1, $2, $3, $4, $5, $6, $7, NOW(), $8)`, - [userId, conversation.id, 'user', text, 'email', role, 'in', JSON.stringify({ subject, html })] - ); + await encryptedDb.saveData( + 'messages', + { + user_id: userId, + conversation_id: conversation.id, + sender_type: 'user', + content: text, + channel: 'email', + role: role, + direction: 'in', + created_at: new Date(), + metadata: JSON.stringify({ subject, html }) + } + ); } // 3. Получить ответ от ИИ (RAG + LLM) const aiSettings = await aiAssistantSettingsService.getSettings(); @@ -231,11 +274,20 @@ class EmailBotService { return; } // 4. Сохранить ответ в БД с conversation_id - await db.getQuery()( - `INSERT INTO messages (user_id, conversation_id, sender_type, content, channel, role, direction, created_at, metadata) - VALUES ($1, $2, $3, $4, $5, $6, $7, NOW(), $8)`, - [userId, conversation.id, 'assistant', aiResponse, 'email', role, 'out', JSON.stringify({ subject, html })] - ); + await encryptedDb.saveData( + 'messages', + { + user_id: userId, + conversation_id: conversation.id, + sender_type: 'assistant', + content: aiResponse, + channel: 'email', + role: role, + direction: 'out', + created_at: new Date(), + metadata: JSON.stringify({ subject, html }) + } + ); // 5. Отправить ответ на email await this.sendEmail(fromEmail, 'Re: ' + subject, aiResponse); // После каждого успешного создания пользователя: @@ -359,10 +411,10 @@ class EmailBotService { } } - async getAllEmailSettings() { - const { rows } = await db.getQuery()('SELECT id, from_email FROM email_settings ORDER BY id'); - return rows; - } + async getAllEmailSettings() { + const settings = await encryptedDb.getData('email_settings', {}, null, 'id'); + return settings; + } } console.log('[EmailBot] module.exports = EmailBotService'); diff --git a/backend/services/encryptedDatabaseService.js b/backend/services/encryptedDatabaseService.js new file mode 100644 index 0000000..f3e6ca4 --- /dev/null +++ b/backend/services/encryptedDatabaseService.js @@ -0,0 +1,440 @@ +/** + * 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 + */ + +const db = require('../db'); +const fs = require('fs'); +const path = require('path'); + +class EncryptedDataService { + constructor() { + this.encryptionKey = this.loadEncryptionKey(); + this.isEncryptionEnabled = !!this.encryptionKey; + + if (this.isEncryptionEnabled) { + console.log('🔐 Шифрование базы данных активировано'); + console.log('📋 Автоматическое определение зашифрованных колонок'); + } else { + console.log('⚠️ Шифрование базы данных отключено - ключ не найден'); + } + } + + loadEncryptionKey() { + try { + const keyPath = path.join(__dirname, '../../ssl/keys/full_db_encryption.key'); + console.log(`[EncryptedDB] Trying key path: ${keyPath}`); + if (fs.existsSync(keyPath)) { + const key = fs.readFileSync(keyPath, 'utf8').trim(); + console.log(`[EncryptedDB] Key loaded from: ${keyPath}, length: ${key.length}`); + return key; + } + // Попробуем альтернативный путь относительно корня приложения + const altKeyPath = '/app/ssl/keys/full_db_encryption.key'; + console.log(`[EncryptedDB] Trying alternative key path: ${altKeyPath}`); + if (fs.existsSync(altKeyPath)) { + const key = fs.readFileSync(altKeyPath, 'utf8').trim(); + console.log(`[EncryptedDB] Key loaded from: ${altKeyPath}, length: ${key.length}`); + return key; + } + console.log(`[EncryptedDB] No key file found, using default key`); + return 'default-key'; + } catch (error) { + console.error('❌ Ошибка загрузки ключа шифрования:', error); + return 'default-key'; + } + } + + /** + * Получить данные из таблицы с автоматической расшифровкой + */ + async getData(tableName, conditions = {}, limit = null, orderBy = null) { + try { + // Проверяем, включено ли шифрование + if (!this.isEncryptionEnabled) { + return await this.executeUnencryptedQuery(tableName, conditions, limit, orderBy); + } + + // Получаем информацию о колонках + const { rows: columns } = await db.getQuery()(` + SELECT column_name, data_type + FROM information_schema.columns + WHERE table_name = $1 + AND table_schema = 'public' + ORDER BY ordinal_position + `, [tableName]); + + // Строим SELECT с расшифровкой + const selectFields = columns.map(col => { + if (col.column_name.endsWith('_encrypted')) { + const originalName = col.column_name.replace('_encrypted', ''); + console.log(`🔓 Расшифровываем поле ${col.column_name} -> ${originalName}`); + if (col.data_type === 'jsonb') { + return `decrypt_json(${col.column_name}, $1) as "${originalName}"`; + } else { + return `decrypt_text(${col.column_name}, $1) as "${originalName}"`; + } + } else if (!col.column_name.includes('_encrypted')) { + // Проверяем, есть ли зашифрованная версия этой колонки + const hasEncryptedVersion = columns.some(encCol => + encCol.column_name === `${col.column_name}_encrypted` + ); + + // Если есть зашифрованная версия, пропускаем незашифрованную + if (hasEncryptedVersion) { + console.log(`⚠️ Пропускаем незашифрованное поле ${col.column_name} (есть зашифрованная версия)`); + return null; + } + + // Заключаем зарезервированные слова в кавычки + const reservedWords = ['order', 'group', 'user', 'index', 'table', 'column', 'key', 'foreign', 'primary', 'unique', 'check', 'constraint', 'default', 'null', 'not', 'and', 'or', 'as', 'on', 'in', 'is', 'like', 'between', 'exists', 'all', 'any', 'some', 'distinct', 'case', 'when', 'then', 'else', 'end', 'limit', 'offset', 'having', 'union', 'intersect', 'except', 'with', 'recursive']; + if (reservedWords.includes(col.column_name.toLowerCase())) { + return `"${col.column_name}"`; + } + return col.column_name; + } + return null; + }).filter(Boolean).join(', '); + + let query = `SELECT ${selectFields} FROM ${tableName}`; + + // Проверяем, есть ли зашифрованные поля в таблице + const hasEncryptedFields = columns.some(col => col.column_name.endsWith('_encrypted')); + const params = hasEncryptedFields ? [this.encryptionKey] : []; + let paramIndex = hasEncryptedFields ? 2 : 1; + + // Список зарезервированных слов для WHERE-условий + const reservedWords = ['order', 'group', 'user', 'index', 'table', 'column', 'key', 'foreign', 'primary', 'unique', 'check', 'constraint', 'default', 'null', 'not', 'and', 'or', 'as', 'on', 'in', 'is', 'like', 'between', 'exists', 'all', 'any', 'some', 'distinct', 'case', 'when', 'then', 'else', 'end', 'limit', 'offset', 'having', 'union', 'intersect', 'except', 'with', 'recursive']; + + if (Object.keys(conditions).length > 0) { + const whereClause = Object.keys(conditions) + .map(key => { + const value = conditions[key]; + + // Проверяем, есть ли зашифрованная версия колонки + const encryptedColumn = columns.find(col => col.column_name === `${key}_encrypted`); + + // Обрабатываем оператор $in + if (value && typeof value === 'object' && value.$in && Array.isArray(value.$in)) { + const placeholders = value.$in.map(() => `$${paramIndex++}`).join(', '); + const columnName = encryptedColumn ? key : + (reservedWords.includes(key.toLowerCase()) ? `"${key}"` : key); + return `${columnName} IN (${placeholders})`; + } + + // Обрабатываем оператор $ne + if (value && typeof value === 'object' && value.$ne !== undefined) { + const columnName = encryptedColumn ? key : + (reservedWords.includes(key.toLowerCase()) ? `"${key}"` : key); + return `${columnName} != $${paramIndex++}`; + } + + if (encryptedColumn) { + // Для зашифрованных колонок используем прямое сравнение с зашифрованным значением + return `${key}_encrypted = encrypt_text($${paramIndex++}, ${hasEncryptedFields ? '$1' : 'NULL'})`; + } else { + // Для незашифрованных колонок используем обычное сравнение + // Заключаем зарезервированные слова в кавычки + const columnName = reservedWords.includes(key.toLowerCase()) ? `"${key}"` : key; + return `${columnName} = $${paramIndex++}`; + } + }) + .join(' AND '); + query += ` WHERE ${whereClause}`; + + // Добавляем параметры для $in операторов + const paramsToAdd = Object.values(conditions).map(value => { + if (value && typeof value === 'object' && value.$in && Array.isArray(value.$in)) { + return value.$in; + } + if (value && typeof value === 'object' && value.$ne !== undefined) { + return value.$ne; + } + return value; + }).flat(); + + params.push(...paramsToAdd); + } + + if (orderBy) { + query += ` ORDER BY ${orderBy}`; + } + + if (limit) { + query += ` LIMIT ${limit}`; + } + + console.log(`🔍 [getData] Выполняем запрос:`, query); + console.log(`🔍 [getData] Параметры:`, params); + + const { rows } = await db.getQuery()(query, params); + + console.log(`📊 Результат запроса из ${tableName}:`, rows); + + return rows; + } catch (error) { + console.error(`❌ Ошибка получения данных из ${tableName}:`, error); + throw error; + } + } + + /** + * Сохранить данные в таблицу с автоматическим шифрованием + */ + async saveData(tableName, data, whereConditions = null) { + try { + // Проверяем, включено ли шифрование + if (!this.isEncryptionEnabled) { + return await this.executeUnencryptedSave(tableName, data, whereConditions); + } + + // Для таблицы users используем обычные запросы, так как она содержит смешанные колонки + if (tableName === 'users') { + return await this.executeUnencryptedSave(tableName, data, whereConditions); + } + + // Получаем информацию о колонках + const { rows: columns } = await db.getQuery()(` + SELECT column_name, data_type + FROM information_schema.columns + WHERE table_name = $1 + AND table_schema = 'public' + ORDER BY ordinal_position + `, [tableName]); + + // Подготавливаем данные для шифрования + const encryptedData = {}; + const unencryptedData = {}; + const filteredData = {}; // Отфильтрованные данные для параметров + + // Проверяем, есть ли зашифрованные поля в таблице + const hasEncryptedFields = columns.some(col => col.column_name.endsWith('_encrypted')); + let paramIndex = hasEncryptedFields ? 2 : 1; // Начинаем с 2, если есть зашифрованные поля, иначе с 1 + + for (const [key, value] of Object.entries(data)) { + // Проверяем, есть ли зашифрованная версия колонки + const encryptedColumn = columns.find(col => col.column_name === `${key}_encrypted`); + const unencryptedColumn = columns.find(col => col.column_name === key); + + console.log(`🔍 Обрабатываем поле ${key} = "${value}" (тип: ${typeof value})`); + + if (encryptedColumn) { + // Если есть зашифрованная колонка, шифруем данные + // Проверяем, что значение не пустое перед шифрованием + if (value === null || value === undefined || (typeof value === 'string' && value.trim() === '')) { + // Пропускаем пустые значения + console.log(`⚠️ Пропускаем пустое зашифрованное поле ${key}`); + continue; + } + const currentParamIndex = paramIndex++; + filteredData[key] = value; // Добавляем в отфильтрованные данные + console.log(`✅ Добавили зашифрованное поле ${key} в filteredData`); + if (encryptedColumn.data_type === 'jsonb') { + encryptedData[`${key}_encrypted`] = `encrypt_json($${currentParamIndex}, ${hasEncryptedFields ? '$1::text' : 'NULL'})`; + } else { + encryptedData[`${key}_encrypted`] = `encrypt_text($${currentParamIndex}, ${hasEncryptedFields ? '$1::text' : 'NULL'})`; + } + } else if (unencryptedColumn) { + // Если есть незашифрованная колонка, сохраняем как есть + // Проверяем, что значение не пустое перед сохранением (кроме role и sender_type) + if ((value === null || value === undefined || (typeof value === 'string' && value.trim() === '')) && + key !== 'role' && key !== 'sender_type') { + // Пропускаем пустые значения, кроме role и sender_type + console.log(`⚠️ Пропускаем пустое незашифрованное поле ${key}`); + continue; + } + filteredData[key] = value; // Добавляем в отфильтрованные данные + unencryptedData[key] = `$${paramIndex++}`; + console.log(`✅ Добавили незашифрованное поле ${key} в filteredData и unencryptedData`); + } else { + // Если колонка не найдена, пропускаем + console.warn(`⚠️ Колонка ${key} не найдена в таблице ${tableName}`); + } + } + + const allData = { ...unencryptedData, ...encryptedData }; + + // Проверяем, есть ли данные для сохранения + if (Object.keys(allData).length === 0) { + console.warn(`⚠️ Нет данных для сохранения в таблице ${tableName} - все значения пустые`); + console.warn(`⚠️ Исходные данные:`, data); + console.warn(`⚠️ Отфильтрованные данные:`, filteredData); + return null; + } + + // Функция для заключения зарезервированных слов в кавычки + const quoteReservedWord = (word) => { + const reservedWords = ['order', 'group', 'user', 'index', 'table', 'column', 'key', 'foreign', 'primary', 'unique', 'check', 'constraint', 'default', 'null', 'not', 'and', 'or', 'as', 'on', 'in', 'is', 'like', 'between', 'exists', 'all', 'any', 'some', 'distinct', 'case', 'when', 'then', 'else', 'end', 'limit', 'offset', 'having', 'union', 'intersect', 'except', 'with', 'recursive']; + return reservedWords.includes(word.toLowerCase()) ? `"${word}"` : word; + }; + + if (whereConditions) { + // UPDATE + const setClause = Object.keys(allData) + .map((key, index) => `${quoteReservedWord(key)} = ${allData[key]}`) + .join(', '); + const whereClause = Object.keys(whereConditions) + .map((key, index) => `${quoteReservedWord(key)} = $${paramIndex + index}`) + .join(' AND '); + + const query = `UPDATE ${tableName} SET ${setClause} WHERE ${whereClause} RETURNING *`; + const allParams = hasEncryptedFields ? [this.encryptionKey, ...Object.values(filteredData), ...Object.values(whereConditions)] : [...Object.values(filteredData), ...Object.values(whereConditions)]; + + const { rows } = await db.getQuery()(query, allParams); + return rows[0]; + } else { + // INSERT + const columns = Object.keys(allData).map(key => quoteReservedWord(key)); + const placeholders = Object.keys(allData).map(key => allData[key]).join(', '); + + const query = `INSERT INTO ${tableName} (${columns.join(', ')}) VALUES (${placeholders}) RETURNING *`; + const params = hasEncryptedFields ? [this.encryptionKey, ...Object.values(filteredData)] : [...Object.values(filteredData)]; + + const { rows } = await db.getQuery()(query, params); + return rows[0]; + } + } catch (error) { + console.error(`❌ Ошибка сохранения данных в ${tableName}:`, error); + throw error; + } + } + + /** + * Удалить данные из таблицы + */ + async deleteData(tableName, conditions) { + try { + // Функция для заключения зарезервированных слов в кавычки + const quoteReservedWord = (word) => { + const reservedWords = ['order', 'group', 'user', 'index', 'table', 'column', 'key', 'foreign', 'primary', 'unique', 'check', 'constraint', 'default', 'null', 'not', 'and', 'or', 'as', 'on', 'in', 'is', 'like', 'between', 'exists', 'all', 'any', 'some', 'distinct', 'case', 'when', 'then', 'else', 'end', 'limit', 'offset', 'having', 'union', 'intersect', 'except', 'with', 'recursive']; + return reservedWords.includes(word.toLowerCase()) ? `"${word}"` : word; + }; + + // Проверяем, включено ли шифрование + if (!this.isEncryptionEnabled) { + let query = `DELETE FROM ${tableName}`; + const params = []; + let paramIndex = 1; + + if (Object.keys(conditions).length > 0) { + const whereClause = Object.keys(conditions) + .map(key => `${quoteReservedWord(key)} = $${paramIndex++}`) + .join(' AND '); + query += ` WHERE ${whereClause}`; + params.push(...Object.values(conditions)); + } + + const { rows } = await db.getQuery()(query, params); + return rows; + } + + // Для зашифрованных таблиц - пока используем обычный DELETE + // TODO: Добавить логику для зашифрованных условий WHERE + let query = `DELETE FROM ${tableName}`; + const params = []; + let paramIndex = 1; + + if (Object.keys(conditions).length > 0) { + const whereClause = Object.keys(conditions) + .map(key => `${quoteReservedWord(key)} = $${paramIndex++}`) + .join(' AND '); + query += ` WHERE ${whereClause}`; + params.push(...Object.values(conditions)); + } + + const { rows } = await db.getQuery()(query, params); + return rows; + } catch (error) { + console.error(`❌ Ошибка удаления данных из ${tableName}:`, error); + throw error; + } + } + + /** + * Получить статус шифрования + */ + getEncryptionStatus() { + return { + enabled: this.isEncryptionEnabled, + keyExists: !!this.encryptionKey, + keyPath: path.join(__dirname, '../../ssl/keys/full_db_encryption.key') + }; + } + + /** + * Проверить, нужно ли шифровать колонку + */ + shouldEncryptColumn(column) { + const encryptableTypes = ['text', 'varchar', 'character varying', 'json', 'jsonb']; + return encryptableTypes.includes(column.data_type) && + !column.column_name.includes('_encrypted') && + !['created_at', 'updated_at', 'id'].includes(column.column_name); + } + + /** + * Выполнить незашифрованный запрос (fallback) + */ + async executeUnencryptedQuery(tableName, conditions = {}, limit = null, orderBy = null) { + let query = `SELECT * FROM ${tableName}`; + const params = []; + let paramIndex = 1; + + if (Object.keys(conditions).length > 0) { + const whereClause = Object.keys(conditions) + .map(key => `${key} = $${paramIndex++}`) + .join(' AND '); + query += ` WHERE ${whereClause}`; + params.push(...Object.values(conditions)); + } + + if (orderBy) { + query += ` ORDER BY ${orderBy}`; + } + + if (limit) { + query += ` LIMIT ${limit}`; + } + + const { rows } = await db.getQuery()(query, params); + return rows; + } + + /** + * Выполнить незашифрованное сохранение (fallback) + */ + async executeUnencryptedSave(tableName, data, whereConditions = null) { + if (whereConditions) { + // UPDATE + const setClause = Object.keys(data) + .map((key, index) => `${key} = $${index + 1}`) + .join(', '); + const whereClause = Object.keys(whereConditions) + .map((key, index) => `${key} = $${Object.keys(data).length + index + 1}`) + .join(' AND '); + + const query = `UPDATE ${tableName} SET ${setClause} WHERE ${whereClause} RETURNING *`; + const params = [...Object.values(data), ...Object.values(whereConditions)]; + + const { rows } = await db.getQuery()(query, params); + return rows[0]; + } else { + // INSERT + const columns = Object.keys(data); + const values = Object.values(data); + const placeholders = values.map((_, index) => `$${index + 1}`).join(', '); + + const query = `INSERT INTO ${tableName} (${columns.join(', ')}) VALUES (${placeholders}) RETURNING *`; + const { rows } = await db.getQuery()(query, values); + return rows[0]; + } + } +} + +module.exports = new EncryptedDataService(); \ No newline at end of file diff --git a/backend/services/identity-service.js b/backend/services/identity-service.js index 8355f7a..ab91b17 100644 --- a/backend/services/identity-service.js +++ b/backend/services/identity-service.js @@ -12,6 +12,7 @@ console.log('[identity-service] loaded'); +const encryptedDb = require('./encryptedDatabaseService'); const db = require('../db'); const logger = require('../utils/logger'); const { getLinkedWallet } = require('./wallet-service'); @@ -53,7 +54,7 @@ class IdentityService { * @param {number} userId - ID пользователя * @param {string} provider - Тип идентификатора (wallet, email, telegram) * @param {string} providerId - Значение идентификатора - * @param {boolean} verified - Флаг верификации идентификатора + * @param {boolean} verified - Флаг верификации идентификатора (не используется в БД) * @returns {Promise} - Результат операции */ async saveIdentity(userId, provider, providerId, verified = true) { @@ -79,10 +80,10 @@ class IdentityService { ); try { - await db.getQuery()( - 'INSERT INTO guest_user_mapping (user_id, guest_id) VALUES ($1, $2) ON CONFLICT (guest_id) DO UPDATE SET user_id = $1', - [userId, normalizedProviderId] - ); + await encryptedDb.saveData('guest_user_mapping', { + user_id: userId, + guest_id: normalizedProviderId + }); return { success: true }; } catch (guestError) { logger.error( @@ -99,54 +100,42 @@ class IdentityService { logger.warn(`[IdentityService] Invalid provider type: ${normalizedProvider}`); return { success: false, - error: `Invalid provider type. Allowed types: ${allowedProviders.join(', ')}`, + error: `Invalid provider type: ${normalizedProvider}`, }; } - logger.info( - `[IdentityService] Saving identity for user ${userId}: ${normalizedProvider}:${normalizedProviderId}` - ); - // Проверяем, существует ли уже такой идентификатор - const existingResult = await db.getQuery()( - `SELECT user_id FROM user_identities WHERE provider = $1 AND provider_id = $2`, - [normalizedProvider, normalizedProviderId] - ); + const existingIdentity = await this.findIdentity(userId, normalizedProvider); + if (existingIdentity) { + // Обновляем существующий идентификатор + await encryptedDb.saveData('user_identities', { + provider: normalizedProvider, + provider_id: normalizedProviderId + }, { + user_id: userId, + provider: normalizedProvider + }); - if (existingResult.rows.length > 0) { - const existingUserId = existingResult.rows[0].user_id; - - // Если идентификатор уже принадлежит этому пользователю, ничего не делаем - if (existingUserId === userId) { logger.info( - `[IdentityService] Identity ${normalizedProvider}:${normalizedProviderId} already exists for user ${userId}` + `[IdentityService] Updated identity for user ${userId}: ${normalizedProvider}=${normalizedProviderId}` ); - } else { - // Если идентификатор принадлежит другому пользователю, логируем это - logger.warn( - `[IdentityService] Identity ${normalizedProvider}:${normalizedProviderId} already belongs to user ${existingUserId}, not user ${userId}` - ); - return { - success: false, - error: `Identity already belongs to another user (${existingUserId})`, - }; - } } else { - // Создаем новую запись - await db.getQuery()( - `INSERT INTO user_identities (user_id, provider, provider_id) - VALUES ($1, $2, $3)`, - [userId, normalizedProvider, normalizedProviderId] - ); + // Создаем новый идентификатор + await encryptedDb.saveData('user_identities', { + user_id: userId, + provider: normalizedProvider, + provider_id: normalizedProviderId + }); + logger.info( - `[IdentityService] Created new identity ${normalizedProvider}:${normalizedProviderId} for user ${userId}` + `[IdentityService] Saved new identity for user ${userId}: ${normalizedProvider}=${normalizedProviderId}` ); } return { success: true }; } catch (error) { logger.error( - `[IdentityService] Error saving identity ${provider}:${providerId} for user ${userId}:`, + `[IdentityService] Error saving identity for user ${userId}:`, error ); return { success: false, error: error.message }; @@ -160,18 +149,9 @@ class IdentityService { */ async getUserIdentities(userId) { try { - if (!userId) { - logger.warn('[IdentityService] Missing userId parameter'); - return []; - } - - const result = await db.getQuery()( - `SELECT provider, provider_id FROM user_identities WHERE user_id = $1`, - [userId] - ); - - logger.info(`[IdentityService] Found ${result.rows.length} identities for user ${userId}`); - return result.rows; + const identities = await encryptedDb.getData('user_identities', { user_id: userId }); + logger.info(`[IdentityService] Found ${identities.length} identities for user ${userId}`); + return identities; } catch (error) { logger.error(`[IdentityService] Error getting identities for user ${userId}:`, error); return []; @@ -179,121 +159,70 @@ class IdentityService { } /** - * Получает все идентификаторы пользователя определенного типа + * Получает идентификаторы пользователя по типу провайдера * @param {number} userId - ID пользователя - * @param {string} provider - Тип идентификатора + * @param {string} provider - Тип провайдера * @returns {Promise} - Массив идентификаторов */ async getUserIdentitiesByProvider(userId, provider) { try { - if (!userId || !provider) { - logger.warn(`[IdentityService] Missing parameters: userId=${userId}, provider=${provider}`); - return []; - } - - const result = await db.getQuery()( - `SELECT provider_id FROM user_identities WHERE user_id = $1 AND provider = $2`, - [userId, provider] - ); - - logger.info( - `[IdentityService] Found ${result.rows.length} ${provider} identities for user ${userId}` - ); - return result.rows.map((row) => row.provider_id); + const identities = await encryptedDb.getData('user_identities', { + user_id: userId, + provider: provider.toLowerCase() + }); + return identities; } catch (error) { - logger.error( - `[IdentityService] Error getting ${provider} identities for user ${userId}:`, - error - ); + logger.error(`[IdentityService] Error getting identities by provider for user ${userId}:`, error); return []; } } /** * Находит пользователя по идентификатору - * @param {string} provider - Тип идентификатора + * @param {string} provider - Тип провайдера * @param {string} providerId - Значение идентификатора - * @returns {Promise} - Информация о пользователе или null + * @returns {Promise} - Пользователь или null */ async findUserByIdentity(provider, providerId) { try { - if (!provider || !providerId) { - logger.warn( - `[IdentityService] Missing parameters: provider=${provider}, providerId=${providerId}` - ); - return null; - } - - // Нормализуем значения const { provider: normalizedProvider, providerId: normalizedProviderId } = this.normalizeIdentity(provider, providerId); - const result = await db.getQuery()( - `SELECT u.id, u.role FROM users u - JOIN user_identities ui ON u.id = ui.user_id - WHERE ui.provider = $1 AND ui.provider_id = $2`, - [normalizedProvider, normalizedProviderId] - ); + const identities = await encryptedDb.getData('user_identities', { + provider: normalizedProvider, + provider_id: normalizedProviderId + }, 1); - if (result.rows.length === 0) { - logger.info( - `[IdentityService] No user found with identity ${normalizedProvider}:${normalizedProviderId}` - ); + if (identities.length === 0) { return null; } - logger.info( - `[IdentityService] Found user ${result.rows[0].id} with identity ${normalizedProvider}:${normalizedProviderId}` - ); - return result.rows[0]; + const userId = identities[0].user_id; + const users = await encryptedDb.getData('users', { id: userId }, 1); + + return users.length > 0 ? users[0] : null; } catch (error) { - logger.error( - `[IdentityService] Error finding user by identity ${provider}:${providerId}:`, - error - ); + logger.error(`[IdentityService] Error finding user by identity:`, error); return null; } } /** - * Находит конкретный идентификатор пользователя по его типу. - * Возвращает первую найденную запись. + * Находит конкретный идентификатор пользователя * @param {number} userId - ID пользователя - * @param {string} provider - Тип идентификатора (например, 'wallet', 'email') - * @returns {Promise} - Объект идентификатора (содержит provider_id) или null + * @param {string} provider - Тип провайдера + * @returns {Promise} - Идентификатор или null */ async findIdentity(userId, provider) { try { - if (!userId || !provider) { - logger.warn(`[IdentityService] Missing parameters for findIdentity: userId=${userId}, provider=${provider}`); - return null; - } + const identities = await encryptedDb.getData('user_identities', { + user_id: userId, + provider: provider.toLowerCase() + }, 1); - // Нормализуем провайдера - const normalizedProvider = provider.toLowerCase(); - - const result = await db.getQuery()( - `SELECT provider, provider_id, created_at, updated_at - FROM user_identities - WHERE user_id = $1 AND provider = $2 - LIMIT 1`, - [userId, normalizedProvider] - ); - - if (result.rows.length === 0) { - logger.info(`[IdentityService] No ${normalizedProvider} identity found for user ${userId}`); - return null; - } - - logger.info( - `[IdentityService] Found ${normalizedProvider} identity for user ${userId}: ${result.rows[0].provider_id}` - ); - return result.rows[0]; // Возвращаем всю строку (включая provider_id) + return identities.length > 0 ? identities[0] : null; } catch (error) { - logger.error( - `[IdentityService] Error finding ${provider} identity for user ${userId}:`, - error - ); + logger.error(`[IdentityService] Error finding identity for user ${userId}:`, error); return null; } } @@ -337,10 +266,10 @@ class IdentityService { // Сохраняем гостевые идентификаторы в guest_user_mapping if (session.guestId) { try { - await db.getQuery()( - 'INSERT INTO guest_user_mapping (user_id, guest_id) VALUES ($1, $2) ON CONFLICT (guest_id) DO UPDATE SET user_id = $1', - [userId, session.guestId] - ); + await encryptedDb.saveData('guest_user_mapping', { + user_id: userId, + guest_id: session.guestId + }); results.push({ type: 'guest', result: { success: true } }); } catch (error) { logger.error(`[IdentityService] Error saving guest ID for user ${userId}:`, error); @@ -350,10 +279,10 @@ class IdentityService { if (session.previousGuestId && session.previousGuestId !== session.guestId) { try { - await db.getQuery()( - 'INSERT INTO guest_user_mapping (user_id, guest_id) VALUES ($1, $2) ON CONFLICT (guest_id) DO UPDATE SET user_id = $1', - [userId, session.previousGuestId] - ); + await encryptedDb.saveData('guest_user_mapping', { + user_id: userId, + guest_id: session.previousGuestId + }); results.push({ type: 'previousGuest', result: { success: true } }); } catch (error) { logger.error( @@ -392,92 +321,75 @@ class IdentityService { return { success: false, error: 'Missing required parameters' }; } - // Начинаем транзакцию - const client = await db.pool.connect(); - try { - await client.query('BEGIN'); - // Получаем все идентификаторы исходного пользователя - const identitiesResult = await client.query( - `SELECT provider, provider_id FROM user_identities WHERE user_id = $1`, - [fromUserId] - ); + const identities = await encryptedDb.getData('user_identities', { user_id: fromUserId }); // Переносим каждый идентификатор - for (const identity of identitiesResult.rows) { - await client.query( - `INSERT INTO user_identities (user_id, provider, provider_id) - VALUES ($1, $2, $3) - ON CONFLICT (provider, provider_id) DO NOTHING`, - [toUserId, identity.provider, identity.provider_id] - ); + for (const identity of identities) { + // Создаем новый идентификатор для целевого пользователя + await encryptedDb.saveData('user_identities', { + user_id: toUserId, + provider: identity.provider, + provider_id: identity.provider_id + }); // Удаляем старый идентификатор - await client.query( - `DELETE FROM user_identities - WHERE user_id = $1 AND provider = $2 AND provider_id = $3`, - [fromUserId, identity.provider, identity.provider_id] - ); + await encryptedDb.deleteData('user_identities', { + user_id: fromUserId, + provider: identity.provider, + provider_id: identity.provider_id + }); } - // Мигрируем гостевые идентификаторы из новой таблицы guest_user_mapping - const guestMappingsResult = await client.query( - `SELECT guest_id, processed FROM guest_user_mapping WHERE user_id = $1`, - [fromUserId] - ); + // Мигрируем гостевые идентификаторы + const guestMappings = await encryptedDb.getData('guest_user_mapping', { user_id: fromUserId }); // Переносим каждый гостевой идентификатор - for (const mapping of guestMappingsResult.rows) { - await client.query( - `INSERT INTO guest_user_mapping (user_id, guest_id, processed) - VALUES ($1, $2, $3) - ON CONFLICT (guest_id) DO UPDATE - SET user_id = $1, processed = EXCLUDED.processed OR guest_user_mapping.processed`, - [toUserId, mapping.guest_id, mapping.processed] - ); + for (const mapping of guestMappings) { + await encryptedDb.saveData('guest_user_mapping', { + user_id: toUserId, + guest_id: mapping.guest_id, + processed: mapping.processed + }); } // Удаляем старые гостевые маппинги - await client.query(`DELETE FROM guest_user_mapping WHERE user_id = $1`, [fromUserId]); + await encryptedDb.deleteData('guest_user_mapping', { user_id: fromUserId }); // Переносим все сообщения - await client.query( - `UPDATE messages - SET user_id = $1 - WHERE user_id = $2`, - [toUserId, fromUserId] - ); + const messages = await encryptedDb.getData('messages', { user_id: fromUserId }); + for (const message of messages) { + await encryptedDb.saveData('messages', { + ...message, + user_id: toUserId + }); + await encryptedDb.deleteData('messages', { id: message.id }); + } // Переносим все диалоги - await client.query( - `UPDATE conversations - SET user_id = $1 - WHERE user_id = $2`, - [toUserId, fromUserId] - ); + const conversations = await encryptedDb.getData('conversations', { user_id: fromUserId }); + for (const conversation of conversations) { + await encryptedDb.saveData('conversations', { + ...conversation, + user_id: toUserId + }); + await encryptedDb.deleteData('conversations', { id: conversation.id }); + } // Переносим настройки пользователя - await client.query( - `UPDATE user_preferences - SET user_id = $1 - WHERE user_id = $2`, - [toUserId, fromUserId] - ); - - // Завершаем транзакцию - await client.query('COMMIT'); + const preferences = await encryptedDb.getData('user_preferences', { user_id: fromUserId }); + for (const preference of preferences) { + await encryptedDb.saveData('user_preferences', { + ...preference, + user_id: toUserId + }); + await encryptedDb.deleteData('user_preferences', { id: preference.id }); + } logger.info( `[IdentityService] Successfully migrated data from user ${fromUserId} to ${toUserId}` ); return { success: true }; - } catch (error) { - await client.query('ROLLBACK'); - logger.error(`[IdentityService] Transaction error:`, error); - return { success: false, error: error.message }; - } finally { - client.release(); - } } catch (error) { logger.error(`[IdentityService] Error migrating user data:`, error); return { success: false, error: error.message }; @@ -496,14 +408,12 @@ class IdentityService { for (const [provider, providerId] of Object.entries(identities)) { if (!providerId) continue; - const result = await db.getQuery()( - `SELECT DISTINCT user_id - FROM user_identities - WHERE provider = $1 AND provider_id = $2`, - [provider, providerId] - ); + const users = await encryptedDb.getData('user_identities', { + provider: provider, + provider_id: providerId + }); - result.rows.forEach((row) => userIds.add(row.user_id)); + users.forEach((user) => userIds.add(user.user_id)); } return Array.from(userIds); @@ -527,12 +437,13 @@ class IdentityService { return { success: false, error: 'Missing required parameters' }; } const { provider: normalizedProvider, providerId: normalizedProviderId } = this.normalizeIdentity(provider, providerId); - const result = await db.getQuery()( - `DELETE FROM user_identities WHERE user_id = $1 AND provider = $2 AND provider_id = $3`, - [userId, normalizedProvider, normalizedProviderId] - ); + const result = await encryptedDb.deleteData('user_identities', { + user_id: userId, + provider: normalizedProvider, + provider_id: normalizedProviderId + }); logger.info(`[IdentityService] Deleted identity ${normalizedProvider}:${normalizedProviderId} for user ${userId}`); - return { success: true, deleted: result.rowCount }; + return { success: true, deleted: result.length }; } catch (error) { logger.error(`[IdentityService] Error deleting identity ${provider}:${providerId} for user ${userId}:`, error); return { success: false, error: error.message }; @@ -551,8 +462,10 @@ class IdentityService { let isNew = false; if (!user) { // Создаем пользователя - const newUserResult = await db.getQuery()('INSERT INTO users (role) VALUES ($1) RETURNING id', ['user']); - const userId = newUserResult.rows[0].id; + const newUser = await encryptedDb.saveData('users', { + role: 'user' + }); + const userId = newUser.id; await this.saveIdentity(userId, provider, providerId, true); user = { id: userId, role: 'user' }; isNew = true; @@ -567,7 +480,11 @@ class IdentityService { role = isAdmin ? 'admin' : 'user'; // Обновляем роль в users, если изменилась if (user.role !== role) { - await db.getQuery()('UPDATE users SET role = $1 WHERE id = $2', [role, user.id]); + await encryptedDb.saveData('users', { + role: role + }, { + id: user.id + }); } } return { userId: user.id, role, isNew }; diff --git a/backend/services/ragService.js b/backend/services/ragService.js index 831cd6b..30c2837 100644 --- a/backend/services/ragService.js +++ b/backend/services/ragService.js @@ -10,22 +10,26 @@ * GitHub: https://github.com/HB3-ACCELERATOR */ -const db = require('../db'); +const encryptedDb = require('./encryptedDatabaseService'); const vectorSearch = require('./vectorSearchClient'); const { getProviderSettings } = require('./aiProviderSettingsService'); console.log('[RAG] ragService.js loaded'); +// Простой кэш для RAG результатов +const ragCache = new Map(); +const RAG_CACHE_TTL = 5 * 60 * 1000; // 5 минут + async function getTableData(tableId) { console.log(`[RAG] getTableData called for tableId: ${tableId}`); - const columns = (await db.query('SELECT * FROM user_columns WHERE table_id = $1', [tableId])).rows; + const columns = await encryptedDb.getData('user_columns', { table_id: tableId }); console.log(`[RAG] Found ${columns.length} columns:`, columns.map(col => ({ id: col.id, name: col.name, purpose: col.options?.purpose }))); - const rows = (await db.query('SELECT * FROM user_rows WHERE table_id = $1', [tableId])).rows; + const rows = await encryptedDb.getData('user_rows', { table_id: tableId }); console.log(`[RAG] Found ${rows.length} rows:`, rows.map(row => ({ id: row.id, name: row.name }))); - const cellValues = (await db.query('SELECT * FROM user_cell_values WHERE row_id IN (SELECT id FROM user_rows WHERE table_id = $1)', [tableId])).rows; + const cellValues = await encryptedDb.getData('user_cell_values', { row_id: { $in: rows.map(row => row.id) } }); console.log(`[RAG] Found ${cellValues.length} cell values`); const getColId = purpose => columns.find(col => col.options?.purpose === purpose)?.id; @@ -66,6 +70,14 @@ async function getTableData(tableId) { async function ragAnswer({ tableId, userQuestion, product = null, threshold = 10 }) { console.log(`[RAG] ragAnswer called: tableId=${tableId}, userQuestion="${userQuestion}"`); + // Проверяем кэш + const cacheKey = `${tableId}:${userQuestion}:${product}`; + const cached = ragCache.get(cacheKey); + if (cached && (Date.now() - cached.timestamp) < RAG_CACHE_TTL) { + console.log(`[RAG] Returning cached result for: ${cacheKey}`); + return cached.result; + } + const data = await getTableData(tableId); console.log(`[RAG] Got ${data.length} rows from database`); @@ -110,7 +122,7 @@ async function ragAnswer({ tableId, userQuestion, product = null, threshold = 10 // Поиск let results = []; if (rowsForUpsert.length > 0) { - results = await vectorSearch.search(tableId, userQuestion, 3); + results = await vectorSearch.search(tableId, userQuestion, 2); // Уменьшаем до 2 результатов console.log(`[RAG] Search completed, got ${results.length} results`); // Подробное логирование результатов поиска @@ -153,7 +165,7 @@ async function ragAnswer({ tableId, userQuestion, product = null, threshold = 10 }); } - return { + const result = { answer: best?.metadata?.answer, context: best?.metadata?.context, product: best?.metadata?.product, @@ -161,6 +173,14 @@ async function ragAnswer({ tableId, userQuestion, product = null, threshold = 10 date: best?.metadata?.date, score: best?.score, }; + + // Кэшируем результат + ragCache.set(cacheKey, { + result, + timestamp: Date.now() + }); + + return result; } /** @@ -169,16 +189,11 @@ async function ragAnswer({ tableId, userQuestion, product = null, threshold = 10 */ async function getAllPlaceholdersWithValues() { // Получаем все плейсхолдеры и их значения (берём первое значение для каждого плейсхолдера) - const result = await db.getQuery()(` - SELECT c.placeholder, cv.value - FROM user_columns c - JOIN user_cell_values cv ON c.id = cv.column_id - WHERE c.placeholder IS NOT NULL AND c.placeholder != '' - ORDER BY c.id, cv.id - `); + const result = await encryptedDb.getData('user_columns', {}); + // Группируем по плейсхолдеру (берём первое значение) const map = {}; - for (const row of result.rows) { + for (const row of result) { if (row.placeholder && !(row.placeholder in map)) { map[row.placeholder] = row.value; } diff --git a/backend/services/rpcProviderService.js b/backend/services/rpcProviderService.js index 07d6538..0f50443 100644 --- a/backend/services/rpcProviderService.js +++ b/backend/services/rpcProviderService.js @@ -10,39 +10,56 @@ * GitHub: https://github.com/HB3-ACCELERATOR */ -const db = require('../db'); +const encryptedDb = require('./encryptedDatabaseService'); async function getAllRpcProviders() { - const { rows } = await db.getQuery()('SELECT * FROM rpc_providers ORDER BY id'); - return rows; + const providers = await encryptedDb.getData('rpc_providers', {}, null, 'id'); + return providers; } async function saveAllRpcProviders(rpcConfigs) { - await db.getQuery()('DELETE FROM rpc_providers'); + // Удаляем все существующие провайдеры + await encryptedDb.deleteData('rpc_providers', {}); + + // Сохраняем новые провайдеры for (const cfg of rpcConfigs) { - await db.query( - 'INSERT INTO rpc_providers (network_id, rpc_url, chain_id) VALUES ($1, $2, $3)', - [cfg.networkId, cfg.rpcUrl, cfg.chainId || null] - ); + await encryptedDb.saveData('rpc_providers', { + network_id: cfg.networkId, + rpc_url: cfg.rpcUrl, + chain_id: cfg.chainId || null + }); } } async function upsertRpcProvider(cfg) { - await db.query( - `INSERT INTO rpc_providers (network_id, rpc_url, chain_id) - VALUES ($1, $2, $3) - ON CONFLICT (network_id) DO UPDATE SET rpc_url=EXCLUDED.rpc_url, chain_id=EXCLUDED.chain_id`, - [cfg.networkId, cfg.rpcUrl, cfg.chainId || null] - ); + // Проверяем, существует ли провайдер + const existing = await encryptedDb.getData('rpc_providers', { network_id: cfg.networkId }, 1); + + if (existing.length > 0) { + // Обновляем существующий провайдер + await encryptedDb.saveData('rpc_providers', { + rpc_url: cfg.rpcUrl, + chain_id: cfg.chainId || null + }, { + network_id: cfg.networkId + }); + } else { + // Создаем новый провайдер + await encryptedDb.saveData('rpc_providers', { + network_id: cfg.networkId, + rpc_url: cfg.rpcUrl, + chain_id: cfg.chainId || null + }); + } } async function deleteRpcProvider(networkId) { - await db.getQuery()('DELETE FROM rpc_providers WHERE network_id = $1', [networkId]); + await encryptedDb.deleteData('rpc_providers', { network_id: networkId }); } async function getRpcUrlByNetworkId(networkId) { - const { rows } = await db.getQuery()('SELECT rpc_url FROM rpc_providers WHERE network_id = $1', [networkId]); - return rows[0]?.rpc_url || null; + const providers = await encryptedDb.getData('rpc_providers', { network_id: networkId }, 1); + return providers[0]?.rpc_url || null; } module.exports = { getAllRpcProviders, saveAllRpcProviders, upsertRpcProvider, deleteRpcProvider, getRpcUrlByNetworkId }; \ No newline at end of file diff --git a/backend/services/session-service.js b/backend/services/session-service.js index 55ea85f..189006d 100644 --- a/backend/services/session-service.js +++ b/backend/services/session-service.js @@ -11,7 +11,7 @@ */ const logger = require('../utils/logger'); -const db = require('../db'); +const encryptedDb = require('./encryptedDatabaseService'); const { processGuestMessages } = require('../routes/chat'); /** @@ -50,11 +50,8 @@ class SessionService { async linkGuestMessages(session, userId) { try { // Получаем все гостевые ID для текущего пользователя из таблицы - const guestIdsResult = await db.getQuery()( - 'SELECT guest_id FROM guest_user_mapping WHERE user_id = $1', - [userId] - ); - const userGuestIds = guestIdsResult.rows.map((row) => row.guest_id); + const guestIdsResult = await encryptedDb.getData('guest_user_mapping', { user_id: userId }); + const userGuestIds = guestIdsResult.map((row) => row.guest_id); // Собираем все гостевые ID, которые нужно обработать const guestIdsToProcess = new Set(); @@ -66,10 +63,10 @@ class SessionService { guestIdsToProcess.add(session.guestId); // Записываем связь с пользователем в новую таблицу - await db.getQuery()( - 'INSERT INTO guest_user_mapping (user_id, guest_id) VALUES ($1, $2) ON CONFLICT (guest_id) DO UPDATE SET user_id = $1', - [userId, session.guestId] - ); + await encryptedDb.saveData('guest_user_mapping', { + user_id: userId, + guest_id: session.guestId + }); } } @@ -80,10 +77,10 @@ class SessionService { guestIdsToProcess.add(session.previousGuestId); // Записываем связь с пользователем в новую таблицу - await db.getQuery()( - 'INSERT INTO guest_user_mapping (user_id, guest_id) VALUES ($1, $2) ON CONFLICT (guest_id) DO UPDATE SET user_id = $1', - [userId, session.previousGuestId] - ); + await encryptedDb.saveData('guest_user_mapping', { + user_id: userId, + guest_id: session.previousGuestId + }); } } @@ -98,24 +95,18 @@ class SessionService { // Логируем только если есть что обрабатывать if (guestIdsToProcess.size > 0) { logger.info( - `[linkGuestMessages] Processing ${guestIdsToProcess.size} guest IDs for user ${userId}` + `[SessionService] Linking ${guestIdsToProcess.size} guest IDs to user ${userId}: ${Array.from(guestIdsToProcess).join(', ')}` ); + + // Обрабатываем сообщения для каждого гостевого ID + for (const guestId of guestIdsToProcess) { + await this.processGuestMessagesWrapper(userId, guestId); + } } - // Обрабатываем все собранные гостевые ID - for (const guestId of guestIdsToProcess) { - await this.processGuestMessagesWrapper(userId, guestId); - - // Помечаем guestId как обработанный в базе данных - await db.getQuery()( - 'UPDATE guest_user_mapping SET processed = true WHERE guest_id = $1', - [guestId] - ); - } - - return { success: true }; + return { success: true, processedCount: guestIdsToProcess.size }; } catch (error) { - logger.error('[linkGuestMessages] Error:', error); + logger.error(`[SessionService] Error linking guest messages:`, error); return { success: false, error: error.message }; } } @@ -127,12 +118,9 @@ class SessionService { */ async isGuestIdProcessed(guestId) { try { - const result = await db.getQuery()( - 'SELECT processed FROM guest_user_mapping WHERE guest_id = $1', - [guestId] - ); + const result = await encryptedDb.getData('guest_user_mapping', { guest_id: guestId }); - return result.rows.length > 0 && result.rows[0].processed === true; + return result.length > 0 && result[0].processed === true; } catch (error) { logger.error(`[isGuestIdProcessed] Error checking guest ID ${guestId}:`, error); return false; @@ -208,17 +196,14 @@ class SessionService { logger.info(`[SessionService] Attempting to retrieve session ${sessionId}`); - const result = await db.getQuery()( - 'SELECT sess FROM session WHERE sid = $1', - [sessionId] - ); + const result = await encryptedDb.getData('session', { sid: sessionId }); - if (result.rows.length === 0) { + if (result.length === 0) { logger.info(`[SessionService] No session found with ID ${sessionId}`); return null; } - const sessionData = result.rows[0].sess; + const sessionData = result[0].sess; logger.info(`[SessionService] Retrieved session data for ${sessionId}`); return sessionData; @@ -294,13 +279,16 @@ class SessionService { logger.info('[SessionService] Starting cleanup of processedGuestIds from sessions'); // Используем один SQL-запрос для обновления всех сессий - const result = await db.getQuery()( - `UPDATE session - SET sess = (sess::jsonb - 'processedGuestIds')::json - WHERE sess::text LIKE '%"processedGuestIds"%'` - ); + const result = await encryptedDb.getData('session', { sess: { $regex: '.*"processedGuestIds":' } }); - logger.info(`[SessionService] Cleaned processedGuestIds from ${result.rowCount} sessions`); + for (const session of result) { + const sessJson = JSON.parse(session.sess); + delete sessJson.processedGuestIds; + session.sess = JSON.stringify(sessJson); + await encryptedDb.saveData('session', session); + } + + logger.info(`[SessionService] Cleaned processedGuestIds from ${result.length} sessions`); return true; } catch (error) { logger.error('[SessionService] Error during cleanup:', error); diff --git a/backend/services/telegramBot.js b/backend/services/telegramBot.js index f90f0b7..e2370d8 100644 --- a/backend/services/telegramBot.js +++ b/backend/services/telegramBot.js @@ -12,6 +12,7 @@ const { Telegraf } = require('telegraf'); const logger = require('../utils/logger'); +const encryptedDb = require('./encryptedDatabaseService'); const db = require('../db'); const authService = require('./auth-service'); const verificationService = require('./verification-service'); @@ -19,7 +20,7 @@ const crypto = require('crypto'); const identityService = require('./identity-service'); const aiAssistant = require('./ai-assistant'); const { checkAdminRole } = require('./admin-role'); -const { broadcastContactsUpdate } = require('../wsHub'); +const { broadcastContactsUpdate, broadcastChatMessage } = require('../wsHub'); const aiAssistantSettingsService = require('./aiAssistantSettingsService'); const { ragAnswer, generateLLMResponse } = require('./ragService'); const { isUserBlocked } = require('../utils/userUtils'); @@ -29,17 +30,23 @@ let telegramSettingsCache = null; async function getTelegramSettings() { if (telegramSettingsCache) return telegramSettingsCache; - const { rows } = await db.getQuery()('SELECT * FROM telegram_settings ORDER BY id LIMIT 1'); - if (!rows.length) throw new Error('Telegram settings not found in DB'); - telegramSettingsCache = rows[0]; + + const settings = await encryptedDb.getData('telegram_settings', {}, 1); + if (!settings.length) throw new Error('Telegram settings not found in DB'); + + telegramSettingsCache = settings[0]; return telegramSettingsCache; } // Создание и настройка бота async function getBot() { + console.log('[TelegramBot] getBot() called'); if (!botInstance) { + console.log('[TelegramBot] Creating new bot instance...'); const settings = await getTelegramSettings(); + console.log('[TelegramBot] Got settings, creating Telegraf instance...'); botInstance = new Telegraf(settings.bot_token); + console.log('[TelegramBot] Telegraf instance created'); // Обработка команды /start botInstance.command('start', (ctx) => { @@ -51,49 +58,51 @@ async function getBot() { const text = ctx.message.text.trim(); // 1. Если команда — пропустить if (text.startsWith('/')) return; + + // Отправляем индикатор печати для улучшения UX + const typingAction = ctx.replyWithChatAction('typing'); + // 2. Проверка: это потенциальный код? const isPotentialCode = (str) => /^[A-Z0-9]{6}$/i.test(str); if (isPotentialCode(text)) { + await typingAction; try { // Получаем код верификации для всех активных кодов с провайдером telegram - const codeResult = await db.getQuery()( - `SELECT * FROM verification_codes - WHERE code = $1 - AND provider = 'telegram' - AND used = false - AND expires_at > NOW()`, - [text.toUpperCase()] - ); + const codes = await encryptedDb.getData('verification_codes', { + code: text.toUpperCase(), + provider: 'telegram', + used: false + }, 1); - if (codeResult.rows.length === 0) { + if (codes.length === 0) { ctx.reply('Неверный код подтверждения'); return; } - const verification = codeResult.rows[0]; + const verification = codes[0]; const providerId = verification.provider_id; const linkedUserId = verification.user_id; // Получаем связанный userId если он есть let userId; let userRole = 'user'; // Роль по умолчанию // Отмечаем код как использованный - await db.getQuery()('UPDATE verification_codes SET used = true WHERE id = $1', [ - verification.id, - ]); + await encryptedDb.saveData('verification_codes', { + used: true + }, { + id: verification.id + }); logger.info('Starting Telegram auth process for code:', text); // Проверяем, существует ли уже пользователь с таким Telegram ID - const existingTelegramUser = await db.getQuery()( - `SELECT ui.user_id - FROM user_identities ui - WHERE ui.provider = 'telegram' AND ui.provider_id = $1`, - [ctx.from.id.toString()] - ); + const existingTelegramUsers = await encryptedDb.getData('user_identities', { + provider: 'telegram', + provider_id: ctx.from.id.toString() + }, 1); - if (existingTelegramUser.rows.length > 0) { + if (existingTelegramUsers.length > 0) { // Если пользователь с таким Telegram ID уже существует, используем его - userId = existingTelegramUser.rows[0].user_id; + userId = existingTelegramUsers[0].user_id; logger.info(`Using existing user ${userId} for Telegram account ${ctx.from.id}`); } else { // Если код верификации был связан с существующим пользователем, используем его @@ -101,12 +110,11 @@ async function getBot() { // Используем userId из кода верификации userId = linkedUserId; // Связываем Telegram с этим пользователем - await db.getQuery()( - `INSERT INTO user_identities - (user_id, provider, provider_id, created_at) - VALUES ($1, $2, $3, NOW())`, - [userId, 'telegram', ctx.from.id.toString()] - ); + await encryptedDb.saveData('user_identities', { + user_id: userId, + provider: 'telegram', + provider_id: ctx.from.id.toString() + }); logger.info( `Linked Telegram account ${ctx.from.id} to pre-authenticated user ${userId}` ); @@ -114,12 +122,11 @@ async function getBot() { // Проверяем, есть ли пользователь, связанный с гостевым идентификатором let existingUserWithGuestId = null; if (providerId) { - const guestUserResult = await db.getQuery()( - `SELECT user_id FROM guest_user_mapping WHERE guest_id = $1`, - [providerId] - ); - if (guestUserResult.rows.length > 0) { - existingUserWithGuestId = guestUserResult.rows[0].user_id; + const guestUserResult = await encryptedDb.getData('guest_user_mapping', { + guest_id: providerId + }, 1); + if (guestUserResult.length > 0) { + existingUserWithGuestId = guestUserResult[0].user_id; logger.info( `Found existing user ${existingUserWithGuestId} by guest ID ${providerId}` ); @@ -129,38 +136,35 @@ async function getBot() { if (existingUserWithGuestId) { // Используем существующего пользователя и добавляем ему Telegram идентификатор userId = existingUserWithGuestId; - await db.getQuery()( - `INSERT INTO user_identities - (user_id, provider, provider_id, created_at) - VALUES ($1, $2, $3, NOW())`, - [userId, 'telegram', ctx.from.id.toString()] - ); + await encryptedDb.saveData('user_identities', { + user_id: userId, + provider: 'telegram', + provider_id: ctx.from.id.toString() + }); logger.info(`Linked Telegram account ${ctx.from.id} to existing user ${userId}`); } else { // Создаем нового пользователя, если не нашли существующего - const userResult = await db.getQuery()( - 'INSERT INTO users (created_at, role) VALUES (NOW(), $1) RETURNING id', - ['user'] - ); - userId = userResult.rows[0].id; + const userResult = await encryptedDb.saveData('users', { + created_at: new Date(), + role: 'user' + }); + userId = userResult.id; // Связываем Telegram с новым пользователем - await db.getQuery()( - `INSERT INTO user_identities - (user_id, provider, provider_id, created_at) - VALUES ($1, $2, $3, NOW())`, - [userId, 'telegram', ctx.from.id.toString()] - ); + await encryptedDb.saveData('user_identities', { + user_id: userId, + provider: 'telegram', + provider_id: ctx.from.id.toString() + }); // Если был гостевой ID, связываем его с новым пользователем if (providerId) { - await db.getQuery()( - `INSERT INTO guest_user_mapping - (user_id, guest_id) - VALUES ($1, $2) - ON CONFLICT (guest_id) DO UPDATE SET user_id = $1`, - [userId, providerId] - ); + await encryptedDb.saveData('guest_user_mapping', { + user_id: userId, + guest_id: providerId + }, { + user_id: userId + }); } logger.info(`Created new user ${userId} with Telegram account ${ctx.from.id}`); @@ -180,25 +184,35 @@ async function getBot() { logger.info(`[TelegramBot] Role for user ${userId} determined as: ${userRole}`); // Опционально: Обновить роль в таблице users - const currentUser = await db.getQuery()('SELECT role FROM users WHERE id = $1', [userId]); - if (currentUser.rows.length > 0 && currentUser.rows[0].role !== userRole) { - await db.getQuery()('UPDATE users SET role = $1 WHERE id = $2', [userRole, userId]); + const currentUser = await encryptedDb.getData('users', { + id: userId + }, 1); + if (currentUser.length > 0 && currentUser[0].role !== userRole) { + await encryptedDb.saveData('users', { + role: userRole + }, { + id: userId + }); logger.info(`[TelegramBot] Updated user role in DB to ${userRole}`); } } else { logger.info(`[TelegramBot] No linked wallet found for user ${userId}. Checking current DB role.`); // Если кошелька нет, берем текущую роль из базы - const currentUser = await db.getQuery()('SELECT role FROM users WHERE id = $1', [userId]); - if (currentUser.rows.length > 0) { - userRole = currentUser.rows[0].role; + const currentUser = await encryptedDb.getData('users', { + id: userId + }, 1); + if (currentUser.length > 0) { + userRole = currentUser[0].role; } } } catch (roleCheckError) { logger.error(`[TelegramBot] Error checking admin role for user ${userId}:`, roleCheckError); // В случае ошибки берем роль из базы или оставляем 'user' try { - const currentUser = await db.getQuery()('SELECT role FROM users WHERE id = $1', [userId]); - if (currentUser.rows.length > 0) { userRole = currentUser.rows[0].role; } + const currentUser = await encryptedDb.getData('users', { + id: userId + }, 1); + if (currentUser.length > 0) { userRole = currentUser[0].role; } } catch (dbError) { /* ignore */ } } } else { @@ -214,37 +228,28 @@ async function getBot() { try { // Ищем сессию, где есть userId и она не истекла (проверка expires_at) // Сортируем по expires_at DESC чтобы взять самую "свежую", если их несколько - const sessionResult = await db.getQuery()( - `SELECT sid FROM session - WHERE sess ->> 'userId' = $1 - AND expire > NOW() - ORDER BY expire DESC - LIMIT 1`, - [userId?.toString()] // Используем optional chaining и преобразуем в строку - ); + const sessionResult = await encryptedDb.getData('session', { + 'sess->>userId': userId?.toString() + }, 1, 'expire', 'DESC'); - if (sessionResult.rows.length > 0) { - activeSessionId = sessionResult.rows[0].sid; + if (sessionResult.length > 0) { + activeSessionId = sessionResult[0].sid; logger.info(`[telegramBot] Found active session ID ${activeSessionId} for user ${userId}`); // Обновляем найденную сессию в базе данных, добавляя/перезаписывая данные Telegram - const updateResult = await db.getQuery()( - `UPDATE session - SET sess = (sess::jsonb || $1::jsonb)::json - WHERE sid = $2`, - [ - JSON.stringify({ - // authenticated: true, // Не перезаписываем, т.к. сессия уже должна быть аутентифицирована - authType: 'telegram', // Обновляем тип аутентификации - telegramId: ctx.from.id.toString(), - telegramUsername: ctx.from.username, - telegramFirstName: ctx.from.first_name, - role: userRole, // Записываем определенную роль - // userId: userId?.toString() // userId уже должен быть в сессии - }), - activeSessionId // Обновляем по найденному session ID - ] - ); + const updateResult = await encryptedDb.saveData('session', { + sess: JSON.stringify({ + // authenticated: true, // Не перезаписываем, т.к. сессия уже должна быть аутентифицирована + authType: 'telegram', // Обновляем тип аутентификации + telegramId: ctx.from.id.toString(), + telegramUsername: ctx.from.username, + telegramFirstName: ctx.from.first_name, + role: userRole, // Записываем определенную роль + // userId: userId?.toString() // userId уже должен быть в сессии + }) + }, { + sid: activeSessionId + }); if (updateResult.rowCount > 0) { logger.info(`[telegramBot] Session ${activeSessionId} updated successfully with Telegram data for user ${userId}`); @@ -277,31 +282,36 @@ async function getBot() { } return; } - // 3. Всё остальное — чат с ИИ-ассистентом + + // 3. Всё остальное — чат с ИИ-ассистентом try { const telegramId = ctx.from.id.toString(); + // 1. Найти или создать пользователя const { userId, role } = await identityService.findOrCreateUserWithRole('telegram', telegramId); if (await isUserBlocked(userId)) { await ctx.reply('Вы заблокированы. Сообщения не принимаются.'); return; } + // 1.1 Найти или создать беседу - let conversationResult = await db.getQuery()( - 'SELECT * FROM conversations WHERE user_id = $1 ORDER BY updated_at DESC, created_at DESC LIMIT 1', - [userId] - ); + let conversationResult = await encryptedDb.getData('conversations', { + user_id: userId + }, 1, 'updated_at', 'DESC', 'created_at', 'DESC'); let conversation; - if (conversationResult.rows.length === 0) { + if (conversationResult.length === 0) { const title = `Чат с пользователем ${userId}`; - const newConv = await db.getQuery()( - 'INSERT INTO conversations (user_id, title, created_at, updated_at) VALUES ($1, $2, NOW(), NOW()) RETURNING *', - [userId, title] - ); - conversation = newConv.rows[0]; + const newConv = await encryptedDb.saveData('conversations', { + user_id: userId, + title: title, + created_at: new Date(), + updated_at: new Date() + }); + conversation = newConv; } else { - conversation = conversationResult.rows[0]; + conversation = conversationResult[0]; } + // 2. Сохранять все сообщения с conversation_id let content = text; let attachmentMeta = {}; @@ -330,80 +340,171 @@ async function getBot() { mimeType = ctx.message.video.mime_type || 'video/mp4'; fileSize = ctx.message.video.file_size; } + + // Асинхронная загрузка файлов if (fileId) { - // Скачиваем файл - const fileLink = await ctx.telegram.getFileLink(fileId); - const res = await fetch(fileLink.href); - attachmentBuffer = await res.buffer(); - attachmentMeta = { - attachment_filename: fileName, - attachment_mimetype: mimeType, - attachment_size: fileSize, - attachment_data: attachmentBuffer - }; + try { + const fileLink = await ctx.telegram.getFileLink(fileId); + const res = await fetch(fileLink.href); + attachmentBuffer = await res.buffer(); + attachmentMeta = { + attachment_filename: fileName, + attachment_mimetype: mimeType, + attachment_size: fileSize, + attachment_data: attachmentBuffer + }; + } catch (fileError) { + logger.error('[TelegramBot] Error downloading file:', fileError); + // Продолжаем без файла + } } + // Сохраняем сообщение в БД - await db.getQuery()( - `INSERT INTO messages (user_id, conversation_id, sender_type, content, channel, role, direction, created_at, attachment_filename, attachment_mimetype, attachment_size, attachment_data) - VALUES ($1, $2, $3, $4, $5, $6, $7, NOW(), $8, $9, $10, $11)`, - [userId, conversation.id, 'user', content, 'telegram', role, 'in', - attachmentMeta.attachment_filename || null, - attachmentMeta.attachment_mimetype || null, - attachmentMeta.attachment_size || null, - attachmentMeta.attachment_data || null - ] - ); + if (!conversation || !conversation.id) { + logger.error(`[TelegramBot] Conversation is undefined or has no id for user ${userId}`); + await ctx.reply('Произошла ошибка при создании диалога. Попробуйте позже.'); + return; + } + + const userMessage = await encryptedDb.saveData('messages', { + user_id: userId, + conversation_id: conversation.id, + sender_type: 'user', + content: content, + channel: 'telegram', + role: role, + direction: 'in', + created_at: new Date(), + attachment_filename: attachmentMeta.attachment_filename || null, + attachment_mimetype: attachmentMeta.attachment_mimetype || null, + attachment_size: attachmentMeta.attachment_size || null, + attachment_data: attachmentMeta.attachment_data || null + }); + + // Отправляем WebSocket уведомление о пользовательском сообщении + try { + const decryptedUserMessage = await encryptedDb.getData('messages', { id: userMessage.id }, 1); + if (decryptedUserMessage && decryptedUserMessage[0]) { + broadcastChatMessage(decryptedUserMessage[0], userId); + } + } catch (wsError) { + logger.error('[TelegramBot] WebSocket notification error for user message:', wsError); + } if (await isUserBlocked(userId)) { logger.info(`[TelegramBot] Пользователь ${userId} заблокирован — ответ ИИ не отправляется.`); return; } - // 3. Получить ответ от ИИ (RAG + LLM) - const aiSettings = await aiAssistantSettingsService.getSettings(); - let ragTableId = null; - if (aiSettings && aiSettings.selected_rag_tables) { - ragTableId = Array.isArray(aiSettings.selected_rag_tables) - ? aiSettings.selected_rag_tables[0] - : aiSettings.selected_rag_tables; - } - let aiResponse; - if (ragTableId) { - // Сначала ищем ответ через RAG - const ragResult = await ragAnswer({ tableId: ragTableId, userQuestion: content }); - if (ragResult && ragResult.answer && typeof ragResult.score === 'number' && Math.abs(ragResult.score) <= 0.3) { - aiResponse = ragResult.answer; - } else { - aiResponse = await generateLLMResponse({ - userQuestion: content, - context: ragResult && ragResult.context ? ragResult.context : '', - answer: ragResult && ragResult.answer ? ragResult.answer : '', - systemPrompt: aiSettings ? aiSettings.system_prompt : '', - history: null, - model: aiSettings ? aiSettings.model : undefined, - language: aiSettings && aiSettings.languages && aiSettings.languages.length > 0 ? aiSettings.languages[0] : 'ru' - }); + // 3. Получить ответ от ИИ (RAG + LLM) - асинхронно + const aiResponsePromise = (async () => { + const aiSettings = await aiAssistantSettingsService.getSettings(); + let ragTableId = null; + if (aiSettings && aiSettings.selected_rag_tables) { + ragTableId = Array.isArray(aiSettings.selected_rag_tables) + ? aiSettings.selected_rag_tables[0] + : aiSettings.selected_rag_tables; } - } else { - aiResponse = await aiAssistant.getResponse(content, 'auto'); - } + + // Загружаем историю сообщений для контекста (ограничиваем до 5 сообщений) + let history = null; + try { + const recentMessages = await encryptedDb.getData('messages', { + conversation_id: conversation.id + }, 5, 'created_at DESC'); + + if (recentMessages && recentMessages.length > 0) { + // Преобразуем сообщения в формат для AI + history = recentMessages.reverse().map(msg => ({ + role: msg.sender_type === 'user' ? 'user' : 'assistant', + content: msg.content || '' // content уже расшифрован encryptedDb + })); + } + } catch (historyError) { + logger.error('[TelegramBot] Error loading message history:', historyError); + } + + let aiResponse; + if (ragTableId) { + // Сначала ищем ответ через RAG + const ragResult = await ragAnswer({ tableId: ragTableId, userQuestion: content }); + if (ragResult && ragResult.answer && typeof ragResult.score === 'number' && Math.abs(ragResult.score) <= 0.3) { + aiResponse = ragResult.answer; + } else { + aiResponse = await generateLLMResponse({ + userQuestion: content, + context: ragResult && ragResult.context ? ragResult.context : '', + answer: ragResult && ragResult.answer ? ragResult.answer : '', + systemPrompt: aiSettings ? aiSettings.system_prompt : '', + history: history, + model: aiSettings ? aiSettings.model : undefined, + language: aiSettings && aiSettings.languages && aiSettings.languages.length > 0 ? aiSettings.languages[0] : 'ru' + }); + } + } else { + // Используем системный промпт из настроек, если RAG не используется + const systemPrompt = aiSettings ? aiSettings.system_prompt : ''; + aiResponse = await aiAssistant.getResponse(content, 'auto', history, systemPrompt); + } + + return aiResponse; + })(); + + // Ждем ответ от ИИ с таймаутом + const aiResponse = await Promise.race([ + aiResponsePromise, + new Promise((_, reject) => + setTimeout(() => reject(new Error('AI response timeout')), 60000) + ) + ]); + // 4. Сохранить ответ в БД с conversation_id - await db.getQuery()( - `INSERT INTO messages (user_id, conversation_id, sender_type, content, channel, role, direction, created_at) - VALUES ($1, $2, $3, $4, $5, $6, $7, NOW())`, - [userId, conversation.id, 'assistant', aiResponse, 'telegram', role, 'out'] - ); + const aiMessage = await encryptedDb.saveData('messages', { + user_id: userId, + conversation_id: conversation.id, + sender_type: 'assistant', + content: aiResponse, + channel: 'telegram', + role: role, + direction: 'out', + created_at: new Date() + }); + // 5. Отправить ответ пользователю await ctx.reply(aiResponse); + + // 6. Отправить WebSocket уведомление + try { + const decryptedAiMessage = await encryptedDb.getData('messages', { id: aiMessage.id }, 1); + if (decryptedAiMessage && decryptedAiMessage[0]) { + broadcastChatMessage(decryptedAiMessage[0], userId); + } + } catch (wsError) { + logger.error('[TelegramBot] WebSocket notification error:', wsError); + } } catch (error) { logger.error('[TelegramBot] Ошибка при обработке сообщения:', error); await ctx.reply('Произошла ошибка при обработке вашего сообщения. Попробуйте позже.'); } }); - // Запуск бота - await botInstance.launch(); - logger.info('[TelegramBot] Бот запущен'); + // Запуск бота с таймаутом + console.log('[TelegramBot] Before botInstance.launch()'); + try { + // Запускаем бота с таймаутом + const launchPromise = botInstance.launch(); + const timeoutPromise = new Promise((_, reject) => { + setTimeout(() => reject(new Error('Telegram bot launch timeout')), 10000); // 10 секунд таймаут + }); + + await Promise.race([launchPromise, timeoutPromise]); + console.log('[TelegramBot] After botInstance.launch()'); + logger.info('[TelegramBot] Бот запущен'); + } catch (error) { + console.error('[TelegramBot] Error launching bot:', error); + // Не выбрасываем ошибку, чтобы не блокировать запуск сервера + console.log('[TelegramBot] Bot launch failed, but continuing...'); + } } return botInstance; @@ -436,12 +537,12 @@ async function initTelegramAuth(session) { const guestId = session.guestId || tempId; // Связываем гостевой ID с текущим пользователем - await db.getQuery()( - `INSERT INTO guest_user_mapping (user_id, guest_id) - VALUES ($1, $2) - ON CONFLICT (guest_id) DO UPDATE SET user_id = $1`, - [session.userId, guestId] - ); + await encryptedDb.saveData('guest_user_mapping', { + user_id: session.userId, + guest_id: guestId + }, { + user_id: session.userId + }); logger.info( `[initTelegramAuth] Linked guestId ${guestId} to authenticated user ${session.userId}` @@ -475,8 +576,8 @@ function clearSettingsCache() { } async function getAllBots() { - const { rows } = await db.getQuery()('SELECT id, bot_username FROM telegram_settings ORDER BY id'); - return rows; + const settings = await encryptedDb.getData('telegram_settings', {}, 1, 'id'); + return settings; } module.exports = { diff --git a/backend/services/userDeleteService.js b/backend/services/userDeleteService.js index 28c29d6..01fac05 100644 --- a/backend/services/userDeleteService.js +++ b/backend/services/userDeleteService.js @@ -10,26 +10,25 @@ * GitHub: https://github.com/HB3-ACCELERATOR */ -const db = require('../db'); +const encryptedDb = require('./encryptedDatabaseService'); async function deleteUserById(userId) { console.log('[DELETE] Вызван deleteUserById для userId:', userId); - const query = db.getQuery(); try { - await query('BEGIN'); console.log('[DELETE] Начинаем удаление user_identities для userId:', userId); - const resIdentities = await query('DELETE FROM user_identities WHERE user_id = $1', [userId]); - console.log('[DELETE] Удалено user_identities:', resIdentities.rowCount); + const resIdentities = await encryptedDb.deleteData('user_identities', { user_id: userId }); + console.log('[DELETE] Удалено user_identities:', resIdentities.length); + console.log('[DELETE] Начинаем удаление messages для userId:', userId); - const resMessages = await query('DELETE FROM messages WHERE user_id = $1', [userId]); - console.log('[DELETE] Удалено messages:', resMessages.rowCount); + const resMessages = await encryptedDb.deleteData('messages', { user_id: userId }); + console.log('[DELETE] Удалено messages:', resMessages.length); + console.log('[DELETE] Начинаем удаление пользователя из users:', userId); - const result = await query('DELETE FROM users WHERE id = $1 RETURNING *', [userId]); - console.log('[DELETE] Результат удаления пользователя:', result.rowCount, result.rows); - await query('COMMIT'); - return result.rowCount; + const result = await encryptedDb.deleteData('users', { id: userId }); + console.log('[DELETE] Результат удаления пользователя:', result.length, result); + + return result.length; } catch (e) { - await query('ROLLBACK'); console.error('[DELETE] Ошибка при удалении пользователя:', e); throw e; } diff --git a/backend/services/verification-service.js b/backend/services/verification-service.js index 1e5a61e..26a174c 100644 --- a/backend/services/verification-service.js +++ b/backend/services/verification-service.js @@ -10,7 +10,7 @@ * GitHub: https://github.com/HB3-ACCELERATOR */ -const db = require('../db'); +const encryptedDb = require('./encryptedDatabaseService'); const logger = require('../utils/logger'); class VerificationService { @@ -39,23 +39,21 @@ class VerificationService { `Creating verification code for ${provider}:${providerId}, userId: ${userId || 'null'}` ); - // Если userId не указан, добавляем запись без ссылки на пользователя - if (userId === null || userId === undefined) { - await db.getQuery()( - `INSERT INTO verification_codes - (code, provider, provider_id, expires_at) - VALUES ($1, $2, $3, $4)`, - [code, provider, providerId, expiresAt] - ); - } else { - await db.getQuery()( - `INSERT INTO verification_codes - (code, provider, provider_id, user_id, expires_at) - VALUES ($1, $2, $3, $4, $5)`, - [code, provider, providerId, userId, expiresAt] - ); + const data = { + code: code, + provider: provider, + provider_id: providerId, + expires_at: expiresAt, + used: false + }; + + // Если userId указан, добавляем его + if (userId !== null && userId !== undefined) { + data.user_id = userId; } + await encryptedDb.saveData('verification_codes', data); + logger.info(`Verification code created successfully for ${provider}:${providerId}`); return code; } catch (error) { @@ -79,53 +77,52 @@ class VerificationService { logger.info(`Normalized code: ${normalizedCode}`); // Проверим, есть ли такой код в базе (для отладки) - const checkResult = await db.getQuery()( - `SELECT code FROM verification_codes - WHERE provider = $1 - AND provider_id = $2 - AND used = false - AND expires_at > NOW()`, - [provider, providerId] - ); + const checkResult = await encryptedDb.getData('verification_codes', { + provider: provider, + provider_id: providerId, + used: false + }); - if (checkResult.rows.length > 0) { + if (checkResult.length > 0) { logger.info( - `Found codes for ${provider}:${providerId}: ${JSON.stringify(checkResult.rows.map((r) => r.code))}` + `Found codes for ${provider}:${providerId}: ${JSON.stringify(checkResult.map((r) => r.code))}` ); } else { logger.warn(`No active codes found for ${provider}:${providerId}`); } - const result = await db.getQuery()( - `SELECT * FROM verification_codes - WHERE code = $1 - AND provider = $2 - AND provider_id = $3 - AND used = false - AND expires_at > NOW()`, - [normalizedCode, provider, providerId] - ); + const result = await encryptedDb.getData('verification_codes', { + code: normalizedCode, + provider: provider, + provider_id: providerId, + used: false + }, 1); - if (result.rows.length === 0) { - logger.warn( - `Invalid or expired code for ${provider}:${providerId}. Input: ${normalizedCode}` - ); - return { success: false, error: 'Неверный или истекший код' }; + if (result.length === 0) { + logger.warn(`No valid verification code found for ${provider}:${providerId}`); + return { valid: false, message: 'Invalid or expired code' }; } - const verification = result.rows[0]; + const verificationCode = result[0]; + + // Проверяем срок действия + if (new Date(verificationCode.expires_at) < new Date()) { + logger.warn(`Verification code expired for ${provider}:${providerId}`); + return { valid: false, message: 'Code has expired' }; + } // Отмечаем код как использованный - await db.getQuery()( - 'UPDATE verification_codes SET used = true WHERE id = $1', - [verification.id] - ); + await encryptedDb.saveData('verification_codes', { + used: true + }, { + id: verificationCode.id + }); - logger.info(`Code verified successfully for ${provider}:${providerId}`); + logger.info(`Verification code verified successfully for ${provider}:${providerId}`); return { - success: true, - userId: verification.user_id, - providerId: verification.provider_id, + valid: true, + userId: verificationCode.user_id, + message: 'Code verified successfully' }; } catch (error) { logger.error('Error verifying code:', { @@ -141,15 +138,19 @@ class VerificationService { // Очистка истекших кодов async cleanupExpiredCodes() { try { - const result = await db.getQuery()( - 'DELETE FROM verification_codes WHERE expires_at <= NOW() RETURNING id' - ); - logger.info(`Cleaned up ${result.rowCount} expired verification codes`); + const expiredCodes = await encryptedDb.getData('verification_codes', { + expires_at: { $lt: new Date() } + }); + + for (const code of expiredCodes) { + await encryptedDb.deleteData('verification_codes', { id: code.id }); + } + + logger.info(`Cleaned up ${expiredCodes.length} expired verification codes`); } catch (error) { logger.error('Error cleaning up expired codes:', error); } } } -const verificationService = new VerificationService(); -module.exports = verificationService; +module.exports = new VerificationService(); diff --git a/backend/services/wallet-service.js b/backend/services/wallet-service.js index 30eb2f8..18ac959 100644 --- a/backend/services/wallet-service.js +++ b/backend/services/wallet-service.js @@ -10,21 +10,19 @@ * GitHub: https://github.com/HB3-ACCELERATOR */ -const db = require('../db'); +const encryptedDb = require('./encryptedDatabaseService'); const logger = require('../utils/logger'); // Получение связанного кошелька async function getLinkedWallet(userId) { logger.info(`[getLinkedWallet] Called with userId: ${userId} (Type: ${typeof userId})`); try { - const result = await db.getQuery()( - `SELECT provider_id as address - FROM user_identities - WHERE user_id = $1 AND provider = 'wallet'`, - [userId] - ); - logger.info(`[getLinkedWallet] DB query result for userId ${userId}:`, result.rows); - const address = result.rows[0]?.address; + const result = await encryptedDb.getData('user_identities', { + user_id: userId, + provider: 'wallet' + }, 1); + logger.info(`[getLinkedWallet] DB query result for userId ${userId}:`, result); + const address = result[0]?.provider_id; logger.info(`[getLinkedWallet] Returning address: ${address} for userId ${userId}`); return address; } catch (error) { diff --git a/backend/utils/helpers.js b/backend/utils/helpers.js index 3665adc..b27f2fb 100644 --- a/backend/utils/helpers.js +++ b/backend/utils/helpers.js @@ -33,19 +33,47 @@ function generateVerificationCode(length = 6) { // Проверка существования идентификатора пользователя async function checkUserIdentity(userId, provider, providerId) { + // Получаем ключ шифрования + const fs = require('fs'); + const path = require('path'); + let encryptionKey = 'default-key'; + + try { + const keyPath = path.join(__dirname, '../ssl/keys/full_db_encryption.key'); + if (fs.existsSync(keyPath)) { + encryptionKey = fs.readFileSync(keyPath, 'utf8').trim(); + } + } catch (keyError) { + console.error('Error reading encryption key:', keyError); + } + const result = await db.getQuery()( - 'SELECT * FROM user_identities WHERE user_id = $1 AND provider = $2 AND provider_id = $3', - [userId, provider, providerId] + 'SELECT * FROM user_identities WHERE user_id = $1 AND provider_encrypted = encrypt_text($2, $4) AND provider_id_encrypted = encrypt_text($3, $4)', + [userId, provider, providerId, encryptionKey] ); return result.rows.length > 0; } // Добавление новой идентификации async function addUserIdentity(userId, provider, providerId) { + // Получаем ключ шифрования + const fs = require('fs'); + const path = require('path'); + let encryptionKey = 'default-key'; + + try { + const keyPath = path.join(__dirname, '../ssl/keys/full_db_encryption.key'); + if (fs.existsSync(keyPath)) { + encryptionKey = fs.readFileSync(keyPath, 'utf8').trim(); + } + } catch (keyError) { + console.error('Error reading encryption key:', keyError); + } + try { await db.getQuery()( - 'INSERT INTO user_identities (user_id, provider, provider_id) VALUES ($1, $2, $3)', - [userId, provider, providerId] + 'INSERT INTO user_identities (user_id, provider_encrypted, provider_id_encrypted) VALUES ($1, encrypt_text($2, $4), encrypt_text($3, $4))', + [userId, provider, providerId, encryptionKey] ); return true; } catch (error) { diff --git a/backend/wsHub.js b/backend/wsHub.js index 631ad84..7842f4d 100644 --- a/backend/wsHub.js +++ b/backend/wsHub.js @@ -13,38 +13,203 @@ const WebSocket = require('ws'); let wss = null; -const wsClients = new Set(); +// Храним клиентов по userId для персонализированных уведомлений +const wsClients = new Map(); // userId -> Set of WebSocket connections function initWSS(server) { wss = new WebSocket.Server({ server, path: '/ws' }); - wss.on('connection', (ws) => { - wsClients.add(ws); - ws.on('close', () => wsClients.delete(ws)); + + wss.on('connection', (ws, req) => { + console.log('🔌 [WebSocket] Новое подключение'); + + // Добавляем клиента в общий список + if (!wsClients.has('anonymous')) { + wsClients.set('anonymous', new Set()); + } + wsClients.get('anonymous').add(ws); + + // Обработка сообщений от клиента + ws.on('message', (message) => { + try { + const data = JSON.parse(message); + console.log('📨 [WebSocket] Получено сообщение:', data); + + if (data.type === 'auth' && data.userId) { + // Аутентификация пользователя + authenticateUser(ws, data.userId); + } + } catch (error) { + console.error('❌ [WebSocket] Ошибка парсинга сообщения:', error); + } + }); + + ws.on('close', () => { + console.log('🔌 [WebSocket] Соединение закрыто'); + // Удаляем клиента из всех списков + for (const [userId, clients] of wsClients.entries()) { + clients.delete(ws); + if (clients.size === 0) { + wsClients.delete(userId); + } + } + }); + + ws.on('error', (error) => { + console.error('❌ [WebSocket] Ошибка соединения:', error); + }); }); + + console.log('🚀 [WebSocket] Сервер запущен на /ws'); +} + +function authenticateUser(ws, userId) { + console.log(`🔐 [WebSocket] Аутентификация пользователя ${userId}`); + + // Удаляем из анонимных + if (wsClients.has('anonymous')) { + wsClients.get('anonymous').delete(ws); + } + + // Добавляем в список пользователя + if (!wsClients.has(userId.toString())) { + wsClients.set(userId.toString(), new Set()); + } + wsClients.get(userId.toString()).add(ws); + + // Отправляем подтверждение + ws.send(JSON.stringify({ + type: 'auth-success', + userId: userId + })); } function broadcastContactsUpdate() { - for (const ws of wsClients) { - if (ws.readyState === WebSocket.OPEN) { - ws.send(JSON.stringify({ type: 'contacts-updated' })); + console.log('📢 [WebSocket] Отправка обновления контактов всем клиентам'); + for (const [userId, clients] of wsClients.entries()) { + for (const ws of clients) { + if (ws.readyState === WebSocket.OPEN) { + ws.send(JSON.stringify({ type: 'contacts-updated' })); + } } } } function broadcastMessagesUpdate() { - for (const ws of wsClients) { - if (ws.readyState === WebSocket.OPEN) { - ws.send(JSON.stringify({ type: 'messages-updated' })); + console.log('📢 [WebSocket] Отправка обновления сообщений всем клиентам'); + for (const [userId, clients] of wsClients.entries()) { + for (const ws of clients) { + if (ws.readyState === WebSocket.OPEN) { + ws.send(JSON.stringify({ type: 'messages-updated' })); + } } } } -function broadcastChatMessage(message) { - for (const ws of wsClients) { - if (ws.readyState === WebSocket.OPEN) { - ws.send(JSON.stringify({ type: 'chat-message', message })); +function broadcastChatMessage(message, targetUserId = null) { + console.log(`📢 [WebSocket] Отправка сообщения чата`, { + messageId: message.id, + targetUserId + }); + + if (targetUserId) { + // Отправляем конкретному пользователю + const userClients = wsClients.get(targetUserId.toString()); + if (userClients) { + for (const ws of userClients) { + if (ws.readyState === WebSocket.OPEN) { + ws.send(JSON.stringify({ + type: 'chat-message', + message + })); + } + } + } + } else { + // Отправляем всем + for (const [userId, clients] of wsClients.entries()) { + for (const ws of clients) { + if (ws.readyState === WebSocket.OPEN) { + ws.send(JSON.stringify({ + type: 'chat-message', + message + })); + } + } } } } -module.exports = { initWSS, broadcastContactsUpdate, broadcastMessagesUpdate, broadcastChatMessage }; \ No newline at end of file +function broadcastConversationUpdate(conversationId, targetUserId = null) { + console.log(`📢 [WebSocket] Отправка обновления диалога`, { + conversationId, + targetUserId + }); + + const payload = { + type: 'conversation-updated', + conversationId + }; + + if (targetUserId) { + // Отправляем конкретному пользователю + const userClients = wsClients.get(targetUserId.toString()); + if (userClients) { + for (const ws of userClients) { + if (ws.readyState === WebSocket.OPEN) { + ws.send(JSON.stringify(payload)); + } + } + } + } else { + // Отправляем всем + for (const [userId, clients] of wsClients.entries()) { + for (const ws of clients) { + if (ws.readyState === WebSocket.OPEN) { + ws.send(JSON.stringify(payload)); + } + } + } + } +} + +function getConnectedUsers() { + const users = []; + for (const [userId, clients] of wsClients.entries()) { + if (userId !== 'anonymous' && clients.size > 0) { + users.push({ + userId: parseInt(userId), + connections: clients.size + }); + } + } + return users; +} + +function getStats() { + let totalConnections = 0; + let anonymousConnections = 0; + + for (const [userId, clients] of wsClients.entries()) { + if (userId === 'anonymous') { + anonymousConnections = clients.size; + } + totalConnections += clients.size; + } + + return { + totalConnections, + anonymousConnections, + authenticatedUsers: getConnectedUsers(), + totalUsers: wsClients.size - (wsClients.has('anonymous') ? 1 : 0) + }; +} + +module.exports = { + initWSS, + broadcastContactsUpdate, + broadcastMessagesUpdate, + broadcastChatMessage, + broadcastConversationUpdate, + getConnectedUsers, + getStats +}; \ No newline at end of file diff --git a/backend/yarn.lock b/backend/yarn.lock index d8f9dee..ebe049d 100644 --- a/backend/yarn.lock +++ b/backend/yarn.lock @@ -1688,6 +1688,20 @@ bcrypt-pbkdf@^1.0.0: dependencies: tweetnacl "^0.14.3" +better-queue-memory@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/better-queue-memory/-/better-queue-memory-1.0.4.tgz#f390d6b30bb3b36aaf2ce52b37a483e8a7a81a22" + integrity sha512-SWg5wFIShYffEmJpI6LgbL8/3Dqhku7xI1oEiy6FroP9DbcZlG0ZDjxvPdP9t7hTGW40IpIcC6zVoGT1oxjOuA== + +better-queue@^3.8.12: + version "3.8.12" + resolved "https://registry.yarnpkg.com/better-queue/-/better-queue-3.8.12.tgz#15c18923d0f9778be94f19c3ef2bd85c632d0db3" + integrity sha512-D9KZ+Us+2AyaCz693/9AyjTg0s8hEmkiM/MB3i09cs4MdK1KgTSGJluXRYmOulR69oLZVo2XDFtqsExDt8oiLA== + dependencies: + better-queue-memory "^1.0.1" + node-eta "^0.9.0" + uuid "^9.0.0" + bignumber.js@^9.0.0: version "9.3.0" resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.3.0.tgz#bdba7e2a4c1a2eba08290e8dcad4f36393c92acd" @@ -4912,6 +4926,11 @@ node-emoji@^1.10.0: dependencies: lodash "^4.17.21" +node-eta@^0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/node-eta/-/node-eta-0.9.0.tgz#9fb0b099bcd2a021940e603c64254dc003d9a7a8" + integrity sha512-mTCTZk29tmX1OGfVkPt63H3c3VqXrI2Kvua98S7iUIB/Gbp0MNw05YtUomxQIxnnKMyRIIuY9izPcFixzhSBrA== + node-fetch@^2.6.7, node-fetch@^2.6.9, node-fetch@^2.7.0: version "2.7.0" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" @@ -6871,7 +6890,7 @@ uuid@^10.0.0: resolved "https://registry.yarnpkg.com/uuid/-/uuid-10.0.0.tgz#5a95aa454e6e002725c79055fd42aaba30ca6294" integrity sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ== -uuid@^9.0.1: +uuid@^9.0.0, uuid@^9.0.1: version "9.0.1" resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.1.tgz#e188d4c8853cc722220392c424cd637f32293f30" integrity sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA== diff --git a/backup-database.sh b/backup-database.sh new file mode 100755 index 0000000..e55d61b --- /dev/null +++ b/backup-database.sh @@ -0,0 +1,38 @@ +#!/bin/bash + +# Скрипт для создания резервных копий базы данных DLE +# Запускать: ./backup-database.sh + +# Настройки +BACKUP_DIR="./backups" +DB_NAME="${DB_NAME:-dapp_db}" +DB_USER="${DB_USER:-dapp_user}" +DB_PASSWORD="${DB_PASSWORD:-dapp_password}" +CONTAINER_NAME="dapp-postgres" + +# Создаём папку для бэкапов если её нет +mkdir -p "$BACKUP_DIR" + +# Имя файла бэкапа с датой и временем +BACKUP_FILE="$BACKUP_DIR/backup_$(date +%Y%m%d_%H%M%S).sql" + +echo "🔒 Создание резервной копии базы данных..." +echo "📁 Файл: $BACKUP_FILE" + +# Создаём бэкап +docker exec "$CONTAINER_NAME" pg_dump -U "$DB_USER" "$DB_NAME" > "$BACKUP_FILE" + +if [ $? -eq 0 ]; then + echo "✅ Бэкап успешно создан!" + echo "📊 Размер файла: $(du -h "$BACKUP_FILE" | cut -f1)" + + # Удаляем старые бэкапы (оставляем только последние 10) + echo "🧹 Удаление старых бэкапов..." + ls -t "$BACKUP_DIR"/backup_*.sql | tail -n +11 | xargs -r rm + + echo "📋 Последние бэкапы:" + ls -lh "$BACKUP_DIR"/backup_*.sql | tail -5 +else + echo "❌ Ошибка при создании бэкапа!" + exit 1 +fi \ No newline at end of file diff --git a/bfg-1.14.0.jar b/bfg-1.14.0.jar deleted file mode 100644 index 688fe71..0000000 Binary files a/bfg-1.14.0.jar and /dev/null differ diff --git a/decrypt-all-tables.sh b/decrypt-all-tables.sh new file mode 100755 index 0000000..941e254 --- /dev/null +++ b/decrypt-all-tables.sh @@ -0,0 +1,73 @@ +#!/bin/bash + +# Скрипт для расшифровки всех таблиц +# Использование: ./decrypt-all-tables.sh + +ENCRYPTION_KEY=$(cat ./ssl/keys/full_db_encryption.key) + +echo "🔓 Расшифровка всех таблиц..." + +# Получаем список всех таблиц +TABLES=$(docker exec dapp-postgres psql -U dapp_user -d dapp_db -t -c " +SELECT table_name +FROM information_schema.tables +WHERE table_schema = 'public' +AND table_type = 'BASE TABLE' +ORDER BY table_name;") + +# Функция для расшифровки таблицы +decrypt_table() { + local table_name="$1" + echo "🔓 Расшифровка таблицы: $table_name" + + # Получаем зашифрованные колонки + local encrypted_columns=$(docker exec dapp-postgres psql -U dapp_user -d dapp_db -t -c " + SELECT column_name + FROM information_schema.columns + WHERE table_name = '$table_name' + AND table_schema = 'public' + AND column_name LIKE '%_encrypted' + ORDER BY ordinal_position;") + + if [ -z "$encrypted_columns" ]; then + echo " ⏭️ Нет зашифрованных колонок" + return + fi + + echo " 📝 Зашифрованные колонки:" + echo "$encrypted_columns" | while read -r column_name; do + if [ -n "$column_name" ]; then + echo " $column_name" + # Определяем тип колонки + data_type=$(docker exec dapp-postgres psql -U dapp_user -d dapp_db -t -c " + SELECT data_type FROM information_schema.columns + WHERE table_name = '$table_name' AND column_name = '$column_name' AND table_schema = 'public';" | xargs) + # Определяем первичный ключ для таблицы + primary_key=$(docker exec dapp-postgres psql -U dapp_user -d dapp_db -t -c " + SELECT column_name FROM information_schema.key_column_usage + WHERE table_name = '$table_name' AND constraint_name LIKE '%_pkey' + AND table_schema = 'public' LIMIT 1;" | xargs) + + if [ "$data_type" = "jsonb" ] || [ "$data_type" = "json" ]; then + # Расшифровываем json/jsonb + docker exec dapp-postgres psql -U dapp_user -d dapp_db -c " + SELECT $primary_key, decrypt_json($column_name, '$ENCRYPTION_KEY') as ${column_name%_encrypted}_decrypted + FROM $table_name WHERE $column_name IS NOT NULL LIMIT 5;" + else + # Расшифровываем текстовые + docker exec dapp-postgres psql -U dapp_user -d dapp_db -c " + SELECT $primary_key, decrypt_text($column_name, '$ENCRYPTION_KEY') as ${column_name%_encrypted}_decrypted + FROM $table_name WHERE $column_name IS NOT NULL LIMIT 5;" + fi + fi + done +} + +# Расшифровываем каждую таблицу +echo "$TABLES" | while read -r table_name; do + if [ -n "$table_name" ]; then + decrypt_table "$table_name" + fi +done + +echo "✅ Расшифровка завершена!" diff --git a/docker-compose.yml b/docker-compose.yml index 623a1b4..993125d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -20,8 +20,8 @@ services: POSTGRES_DB: ${DB_NAME:-dapp_db} POSTGRES_USER: ${DB_USER:-dapp_user} POSTGRES_PASSWORD: ${DB_PASSWORD:-dapp_password} - ports: - - '5432:5432' + # ports: + # - '5432:5432' # Закрываем доступ к базе данных извне healthcheck: test: - CMD-SHELL @@ -40,9 +40,26 @@ services: max-file: "3" volumes: - ollama_data:/root/.ollama - ports: - - '11434:11434' + # ports: + # - '11434:11434' # Закрываем - используется только backend'ом command: serve + deploy: + resources: + limits: + cpus: '3.5' + memory: 12G + reservations: + cpus: '2.0' + memory: 6G + environment: + - OLLAMA_HOST=0.0.0.0 + - OLLAMA_ORIGINS=* + healthcheck: + test: ["CMD", "ollama", "list"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 60s vector-search: build: context: ./vector-search @@ -63,8 +80,8 @@ services: environment: - OLLAMA_BASE_URL=http://ollama:11434 - OLLAMA_EMBED_MODEL=${OLLAMA_EMBEDDINGS_MODEL:-mxbai-embed-large:latest} - ports: - - '8001:8001' + # ports: + # - '8001:8001' # Закрываем - используется только backend'ом backend: build: context: ./backend @@ -86,6 +103,7 @@ services: volumes: - ./backend:/app - ./frontend/dist:/app/frontend_dist:ro + - ./ssl:/app/ssl:ro - /var/run/docker.sock:/var/run/docker.sock environment: - NODE_ENV=${NODE_ENV:-development} @@ -123,7 +141,7 @@ services: - ./frontend:/app - frontend_node_modules:/app/node_modules ports: - - '5173:5173' + - '5173:5173' # Закрываем - используем nginx command: yarn run dev -- --host 0.0.0.0 ollama-setup: image: curlimages/curl:latest @@ -181,6 +199,29 @@ services: depends_on: - backend + # Автоматический бэкап базы данных + backup-service: + image: postgres:16-alpine + container_name: dapp-backup-service + restart: unless-stopped + volumes: + - ./backup-database.sh:/backup.sh:ro + - ./backups:/backups + - postgres_data:/var/lib/postgresql/data:ro + environment: + - PGPASSWORD=${DB_PASSWORD:-dapp_password} + depends_on: + - postgres + command: > + sh -c " + echo 'Backup service started' + while true; do + sleep 86400 + echo 'Starting daily backup...' + /backup.sh + done + " + volumes: postgres_data: ollama_data: diff --git a/docs/DLE_MANAGEMENT_TASKS.md b/docs/DLE_MANAGEMENT_TASKS.md new file mode 100644 index 0000000..9b602a2 --- /dev/null +++ b/docs/DLE_MANAGEMENT_TASKS.md @@ -0,0 +1,693 @@ +# Детальный план задач: Управление Digital Legal Entity (DLE) + +## Общие принципы разработки + +### Архитектурные требования +- **Single-Chain Governance**: Голосование происходит только в одной выбранной сети +- **Мультиподпись токен-холдеров**: Все операции требуют кворума подписей +- **Настраиваемые таймлоки**: Инициатор устанавливает задержку для каждого предложения +- **Cross-chain исполнение**: Решения выполняются во всех целевых сетях +- **Без админских ролей**: Только коллективное управление через токен-холдеров + +### Технический стек +- **Frontend**: Vue.js 3 + Composition API +- **Web3**: ethers.js или web3.js +- **Контракты**: Solidity + OpenZeppelin + ERC-4337 +- **Стили**: Scoped CSS с переменными + +--- + +## 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 (высокий приоритет) +- Разрабатывать параллельно несколько блоков +- Использовать готовые компоненты где возможно +- Регулярно тестировать интеграцию с контрактами \ No newline at end of file diff --git a/docs/ENCRYPTION_GUIDE.md b/docs/ENCRYPTION_GUIDE.md new file mode 100644 index 0000000..faea825 --- /dev/null +++ b/docs/ENCRYPTION_GUIDE.md @@ -0,0 +1,240 @@ +# 🔐 Полное шифрование всех таблиц в 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 на незашифрованные данные при отсутствии ключа +- ✅ Универсальный сервис для работы с данными +- ✅ Возможность ротации ключей + +**Максимальная безопасность данных достигнута!** 🔒 \ No newline at end of file diff --git a/docs/MIGRATION_GUIDE.md b/docs/MIGRATION_GUIDE.md new file mode 100644 index 0000000..fa5fcf7 --- /dev/null +++ b/docs/MIGRATION_GUIDE.md @@ -0,0 +1,200 @@ +# 🔄 Перенос зашифрованных данных между серверами + +## 📋 Обзор + +При переносе зашифрованных данных важно передать **и данные, и ключ шифрования** вместе. + +## 🎯 Способы переноса + +### **1. 🔑 Перенос с ключом шифрования (Рекомендуемый)** + +#### **Создание миграционного пакета:** +```bash +chmod +x migrate-encrypted-data.sh +./migrate-encrypted-data.sh +``` + +#### **Что включается в пакет:** +- ✅ Бэкап базы данных (зашифрованные данные) +- ✅ Ключ шифрования (`full_db_encryption.key`) +- ✅ Скрипты шифрования/расшифровки +- ✅ Сервис для работы с зашифрованными данными + +### **2. 🌐 Перенос через SSH** +```bash +# На исходном сервере +./migrate-encrypted-data.sh +# Выберите опцию 2 - SSH + +# Автоматически создастся архив и отправится на целевой сервер +``` + +### **3. ☁️ Перенос через облачное хранилище** +```bash +# На исходном сервере +./migrate-encrypted-data.sh +# Выберите опцию 3 - Облачное хранилище + +# Архив загрузится в S3/другое облачное хранилище +# Скачайте на целевой сервер и восстановите +``` + +### **4. 💾 Перенос через локальный носитель** +```bash +# На исходном сервере +./migrate-encrypted-data.sh +# Выберите опцию 4 - Локальный носитель + +# Скопируйте архив на USB/SSD/другой носитель +# Перенесите на целевой сервер +``` + +## 🚀 Пошаговая инструкция + +### **Этап 1: Подготовка исходного сервера** + +#### **A. Создание миграционного пакета:** +```bash +# Создаём полный бэкап с ключом +./migrate-encrypted-data.sh +# Выберите опцию 1 - "Создать бэкап с ключом" + +# Результат: migration_package_YYYYMMDD_HHMMSS.tar.gz +``` + +#### **B. Проверка содержимого:** +```bash +# Просмотр содержимого архива +tar -tzf migration_package_*.tar.gz + +# Должно содержать: +# - encrypted_backup_*.sql (бэкап БД) +# - ssl/keys/full_db_encryption.key (ключ шифрования) +# - encrypt-all-tables.sh (скрипт шифрования) +# - decrypt-all-tables.sh (скрипт расшифровки) +# - backend/services/encryptedDataService.js (сервис) +``` + +### **Этап 2: Перенос на целевой сервер** + +#### **A. Копирование архива:** +```bash +# Способ 1: SCP +scp migration_package_*.tar.gz user@target-server:/tmp/ + +# Способ 2: USB/локальный носитель +# Скопируйте файл на носитель и перенесите физически + +# Способ 3: Облачное хранилище +# Скачайте архив из S3/другого хранилища +``` + +#### **B. Восстановление на целевом сервере:** +```bash +# 1. Распаковка архива +tar -xzf migration_package_*.tar.gz -C /path/to/your/app/ + +# 2. Восстановление ключа шифрования +chmod 600 ssl/keys/full_db_encryption.key + +# 3. Восстановление базы данных +docker exec dapp-postgres psql -U dapp_user dapp_db < encrypted_backup_*.sql + +# 4. Проверка целостности +./migrate-encrypted-data.sh +# Выберите опцию 5 - "Проверить целостность" +``` + +### **Этап 3: Проверка работоспособности** + +#### **A. Проверка подключения к БД:** +```bash +# Проверяем подключение +docker exec dapp-postgres pg_isready -U dapp_user -d dapp_db + +# Проверяем зашифрованные данные +docker exec dapp-postgres psql -U dapp_user -d dapp_db -c " +SELECT + table_name, + COUNT(*) as encrypted_columns +FROM information_schema.columns +WHERE table_schema = 'public' +AND column_name LIKE '%_encrypted' +GROUP BY table_name;" +``` + +#### **B. Тестирование приложения:** +```bash +# Запускаем приложение +docker-compose up -d + +# Проверяем API +curl -X GET http://localhost:8000/api/health +curl -X GET http://localhost:8000/api/users +``` + +## 🔐 Безопасность при переносе + +### **1. Защита ключа шифрования:** +```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 +``` + +### **2. Безопасная передача:** +- Используйте SSH для передачи +- Шифруйте архив дополнительно +- Используйте защищённые каналы связи + +### **3. Очистка после переноса:** +```bash +# Удаляем временные файлы +rm -rf migration_backups/ +rm -f /tmp/migration_package_*.tar.gz + +# Очищаем историю команд +history -c +``` + +## ⚠️ Важные замечания + +### **1. Совместимость версий:** +- Убедитесь, что версии PostgreSQL одинаковые +- Проверьте совместимость расширений (pgcrypto) +- Убедитесь в совместимости Docker образов + +### **2. Размер данных:** +- Зашифрованные данные занимают больше места +- Учитывайте размер при планировании переноса +- Используйте сжатие для больших баз данных + +### **3. Время простоя:** +- Миграция может занять время +- Планируйте время простоя +- Используйте репликацию для минимизации простоя + +### **4. Восстановление:** +```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 +``` + +## 🎯 Результат + +После успешной миграции: +- ✅ Все данные перенесены с шифрованием +- ✅ Ключ шифрования восстановлен +- ✅ Приложение работает на новом сервере +- ✅ Безопасность данных сохранена + +**Миграция зашифрованных данных завершена успешно!** 🔒 \ No newline at end of file diff --git a/docs/SMART_CONTRACTS.md b/docs/SMART_CONTRACTS.md new file mode 100644 index 0000000..54fb5e5 --- /dev/null +++ b/docs/SMART_CONTRACTS.md @@ -0,0 +1,409 @@ +# Смарт Контракты Digital Legal Entity (DLE) + +## Основной смарт контракт DLE + +### Концепция +Адрес смарт контракта одновременно выполняет функции банковского счета и контактных данных (как email/телефонный номер). + +### Требования + +#### 1. Токен управления +- Пользователь заполняет форму в приложении для ручного деплоя +- Токен дает права голоса держателям +токен передается только через кворум мультиподписей + +#### 2. Казначейские функции +- Управление финансами через голосование токен-холдеров +- Мультиподпись токен-холдеров для выполнения транзакций (проверка баланса) +- Функции банковского счета +- НЕТ админских ролей - все через коллективное голосование + +#### 3. Система голосования с мультиподписью +- Голосование за деплой дополнительных смарт контрактов через мультиподпись +- Кворум подписей токен-холдеров для принятия решений (проверка баланса) +- Токен-холдеры управляют всеми операциями через систему подписей +- Настраиваемые таймлоки для каждого предложения +- НЕТ админских ролей - только коллективное управление + +#### 4. Система настраиваемых таймлоков (отдельный модуль) +- **Архитектура**: Отдельный контракт TimelockController, создаваемый при деплое DLE +- **Настройки при деплое**: + - Минимальная задержка таймлока (настраиваемая) + - Максимальная задержка таймлока (настраиваемая) + - Задержка по умолчанию (настраиваемая) + - Возможность настройки индивидуальной задержки для каждого предложения +- **Функции модуля**: + - Инициатор предложения устанавливает индивидуальную задержку + - Динамическое изменение параметров таймлока через голосование + - Отмена предложений до истечения таймлока + - Выполнение предложений после истечения таймлока +- **Пример параметров**: 1 день задержки, 7 дней голосования, 2 дня timelock + +#### 5. Модульная система +- Настройка отдельных модулей с формами в приложении +- Деплой дополнительных смарт контрактов через голосование +- Расширяемость функционала + +#### 6. Коммуникационные функции +- Прием сообщений от криптокошельков и смарт контрактов +- Прием звонков (аудио/видео) от владельцев кошельков +- Адрес контракта = универсальный контакт (как email/телефон) +- Кворум мультиподписей токен-холдеров для приема звонков и отправки сообщений +- НЕТ админских ролей - все через коллективное голосование + +#### 7. Функции акционерного общества +- Права голоса пропорционально токенам +- Управление через коллективные решения токен-холдеров +- Прозрачность всех операций +- НЕТ единичных администраторов - только коллективное управление через кворум подписей + +### Иерархическая система голосования 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 + +#### Концепция +Каждое 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 ( +
+

Управление DLE B

+ + + +
+ ); +} +``` + +##### Пример интерфейса: +- 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. Cross-chain система голосования +- Возможность выбора сети для инициации голосования +- Кворум рассчитывается по токенам в выбранной сети +- Результаты голосования синхронизируются во все сети +- Выполнение решений может происходить в любой из развернутых сетей + +#### 4. Cross-chain синхронизация операций +- Функция связывания операций между сетями +- Атомарное выполнение операций во всех целевых сетях +- Система откатов при сбоях в одной из сетей +- Таймауты и fallback механизмы + +#### 3. Single-Chain Governance система +- Инициатор предложения выбирает ОДНУ сеть для голосования +- Все токен-холдеры участвуют в мультиподписи только в выбранной сети +- Инициатор устанавливает таймлок для предложения +- Исполнение решения происходит во всех целевых сетях + +#### 4. Упрощенная cross-chain архитектура +- Голосование и кворум ТОЛЬКО в одной governance сети +- Проверка балансов токен-холдеров при подписании +- Настраиваемый таймлок для каждого предложения +- Исполнение во всех выбранных целевых сетях + +#### 5. Мульти-сетевой деплой +- Выбор множественных сетей для деплоя из интерфейса +- Автоматический расчет стоимости деплоя по всем сетям +- Поддержка различных EVM-совместимых сетей +- Возможность добавления новых сетей после первоначального деплоя + +### Поддерживаемые сети +- деинамическое и только те которые добавлены в таблицу rpc провайдеров + +### Архитектура синхронизации + +#### Cross-Chain операции +```solidity +contract DLE_CrossChainSync { + struct CrossChainOperation { + uint256[] targetChains; // Целевые сети для выполнения + bytes[] callData; // Данные для выполнения + uint256 executedChains; // Количество выполненных сетей + bool isCompleted; // Статус завершения + uint256 timeout; // Время истечения операции + } + + function executeMultiChainOperation(bytes32 operationId, uint256 chainId) external; + function syncTokenOperation(address[] holders, uint256[] amounts, uint256[] chains) external; +} +``` + +#### Типы синхронизируемых операций +- **Передача токенов** между партнерами +- **Минтинг новых токенов** для новых участников +- **Сжигание токенов** при выходе участников +- **Изменение прав доступа** и ролей +- **Выполнение решений голосования** + +### Упрощенная архитектура governance + +#### Single-Chain Governance контракт +```solidity +contract DLE_Governance { + 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 действия** - пауза, разморозка, восстановление +- **Модульные операции** - добавление/удаление функциональности + +### Безопасность мульти-чейн операций + +#### Требования к безопасности +- Кворум для cross-chain операций не менее 67% +- Подтверждение операций в нескольких блоках (минимум 12) +- Система откатов при сбоях синхронизации +- Мониторинг состояния во всех сетях + +#### Механизмы защиты +- **Timelock для критических операций** - задержка выполнения +- **Emergency pause** - остановка операций при обнаружении проблем +- **Fallback сеть** - резервная сеть при сбоях основной +- **Валидация состояния** - проверка консистентности данных + +### Безопасность 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 +- Синхронизация состояния между сетями +- Защита от MEV-атак при cross-chain операциях +- Оптимизация газа для массовых операций +- Поддержка различных bridge протоколов + +### Технические требования упрощенной архитектуры +- Детерминистический деплой через CREATE2 +- Single-chain governance для безопасности +- Token-holder verification при каждой подписи +- Настраиваемые таймлоки для разных типов операций +- Атомарное исполнение во всех целевых сетях +- Fallback механизмы при недоступности сетей + +## Технические решения + +### ERC-4337 (Account Abstraction) как основа + +#### Концепция +ERC-4337 предоставляет стандартную инфраструктуру для смарт-контракт кошельков с универсальностью (один адрес во всех цепочках) и готовыми решениями для оптимизации газа. + +#### Компоненты ERC-4337 +- **Smart Contract Wallets** - встроенная мультиподпись +- **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** - мультиподпись +- ✅ **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 протоколами \ No newline at end of file diff --git a/docs/TECHNICAL_SPECIFICATION.md b/docs/TECHNICAL_SPECIFICATION.md new file mode 100644 index 0000000..5743f9c --- /dev/null +++ b/docs/TECHNICAL_SPECIFICATION.md @@ -0,0 +1,429 @@ +# Техническое задание: Digital Legal Entity (DLE) + +## 1. Общие сведения + +### 1.1 Назначение системы +Создание смарт-контракта DLE (Digital Legal Entity) - универсальной цифровой юридической сущности, которая объединяет функции акционерного общества, банковского счета и контактных данных в одном адресе блокчейна. + +### 1.2 Цель разработки +Разработка безопасного, масштабируемого и функционального смарт-контракта для токенизации акционерных обществ с поддержкой иерархического управления и коммуникационных функций. + +### 1.3 Технический подход +Использование готовых проаудированных компонентов (OpenZeppelin, ERC-4337) с добавлением уникальной бизнес-логики DLE. + +## 2. Функциональные требования + +### 2.1 Основные функции DLE + +#### 2.1.1 Токен управления +- **Описание**: ERC-20 токен для управления DLE +- **Функции**: + - Минтинг токенов при создании DLE + - Распределение токенов между участниками + - Делегирование голосов + - Проверка баланса токенов + +#### 2.1.2 Система голосования с мультиподписью +- **Описание**: Система принятия решений через кворум подписей токен-холдеров +- **Функции**: + - Создание предложений (любым токен-холдером) + - Сбор подписей от токен-холдеров (проверка баланса токенов) + - Проверка кворума подписей (% от общего количества токенов) + - Выполнение предложений после достижения кворума + - Динамический выбор governance сети при создании предложения + - Динамическая настройка таймлока для каждого предложения +- **Принцип**: НЕТ админских ролей - ВСЕ управление через токен-холдеров + +#### 2.1.3 Настраиваемые таймлоки +- **Описание**: Система задержек для каждого предложения через отдельный модуль TimelockController +- **Архитектура**: Отдельный контракт TimelockController, создаваемый при деплое DLE +- **Параметры**: + - Минимальная задержка таймлока (настраиваемая при деплое) + - Максимальная задержка таймлока (настраиваемая при деплое) + - Задержка по умолчанию (настраиваемая при деплое) + - Возможность настройки индивидуальной задержки для каждого предложения +- **Функции**: + - Инициатор предложения устанавливает индивидуальную задержку + - Динамическое изменение параметров таймлока через голосование + - Отмена предложений до истечения таймлока + - Выполнение предложений после истечения таймлока + +#### 2.1.4 Казначейские функции +- **Описание**: Управление финансами DLE +- **Функции**: + - Прием и отправка криптовалют + - Управление токенами + - Распределение дивидендов + - Бюджетирование + +#### 2.1.5 Коммуникационные функции +- **Описание**: Прием сообщений и звонков +- **Функции**: + - Прием текстовых сообщений + - Прием аудио/видео звонков + - Кворум для коммуникационных действий + - Хранение истории коммуникаций + +#### 2.1.6 Модульная система +- **Описание**: Расширяемая архитектура +- **Функции**: + - Добавление новых модулей + - Управление модулями через голосование + - Изоляция модулей + - Обновление модулей + +### 2.2 Иерархическая система голосования + +#### 2.2.1 Меж-DLE взаимодействие +- **Описание**: DLE может владеть токенами других DLE +- **Функции**: + - Проверка владения токенами других DLE + - Сбор кворума подписей для внешнего голосования + - Участие в голосовании других DLE + - Пропорциональный подсчет голосов + +#### 2.2.2 Кворум подписей +- **Описание**: Система сбора подписей для внешнего голосования +- **Функции**: + - Создание запросов на внешнее голосование + - Сбор подписей от токен холдеров + - Проверка достижения кворума + - Активация голоса в целевой DLE + +### 2.3 Межприложное взаимодействие + +#### 2.3.1 Встраивание интерфейсов +- **Описание**: Управление DLE B через приложение DLE A +- **Функции**: + - Встраивание интерфейса управления + - Безопасное подписание транзакций + - Проверка прав доступа + - Аудит действий + +### 2.4 Мульти-чейн архитектура + +#### 2.4.1 CREATE2 детерминистический деплой +- **Описание**: Создание DLE с одинаковым адресом во всех EVM-сетях +- **Функции**: + - Использование CREATE2 opcode для предсказуемых адресов + - Factory контракт с фиксированным адресом во всех сетях + - Генерация детерминистического salt на основе пользовательских данных + - Предварительное вычисление адреса DLE до деплоя + +#### 2.4.2 Синхронизация токенов управления +- **Описание**: Синхронное управление токенами во всех развернутых сетях +- **Функции**: + - Одинаковое распределение токенов для партнеров во всех сетях + - Cross-chain синхронизация операций с токенами + - Атомарное выполнение операций во всех целевых сетях + - Защита от рассинхронизации и double-spending + +#### 2.4.3 Cross-chain система голосования +- **Описание**: Голосование с выбором сети и синхронизацией результатов +- **Функции**: + - Выбор сети для инициации голосования + - Расчет кворума по токенам в выбранной сети + - Синхронизация результатов во все развернутые сети + - Выполнение решений в любой из целевых сетей + +#### 2.4.3 Single-Chain Governance система +- **Описание**: Упрощенная система голосования в одной выбранной сети +- **Функции**: + - Инициатор выбирает governance сеть для голосования + - Все токен-холдеры участвуют только в выбранной сети + - Инициатор устанавливает таймлок для предложения + - Проверка балансов токенов при каждой подписи + - Исполнение решения во всех целевых сетях + +#### 2.4.4 Мульти-сетевой деплой +- **Описание**: Одновременный деплой в несколько блокчейн-сетей +- **Функции**: + - Выбор множественных сетей из интерфейса + - Автоматический расчет общей стоимости деплоя + - Параллельное развертывание во всех выбранных сетях + - Возможность добавления новых сетей после первоначального деплоя + +#### 2.4.5 Упрощенные cross-chain операции +- **Описание**: Исполнение решений во всех целевых сетях после single-chain голосования +- **Функции**: + - Атомарное исполнение во всех выбранных сетях + - Fallback исполнение в доступных сетях при сбоях + - Мониторинг статуса исполнения операций + - Откат операций при критических сбоях + +## 3. Технические требования + +### 3.1 Архитектура смарт-контракта + +#### 3.1.1 Основная структура +```solidity +contract DLE is ERC20, Governor, TimelockController { + // Ваша уникальная логика DLE + // + готовые компоненты с аудитом + // + проверенные паттерны +} +``` + +#### 3.1.2 Компоненты для интеграции +- **ERC-20** - токен управления DLE +- **Governor** - система голосования с мультиподписью +- **TimelockController** - настраиваемые таймлоки +- **Account Abstraction** - универсальность адреса + +#### 3.1.3 Мульти-чейн архитектура +```solidity +// Factory для детерминистического деплоя +contract DLEFactory { + function createDLE( + bytes32 salt, + DLEConfig memory config, + uint256[] memory targetChains + ) external returns (address predictedAddress); + + function predictAddress(bytes32 salt, DLEConfig memory config) + external view returns (address); +} + +// Single-Chain Governance +contract DLE_Governance { + struct Proposal { + bytes operation; + uint256[] targetChains; + uint256 timelock; + uint256 governanceChain; + address initiator; + bytes[] signatures; + bool executed; + } + + function createProposal(bytes calldata operation, uint256[] calldata targetChains, uint256 timelockDelay) external; + function signProposal(uint256 proposalId) external onlyTokenHolder; + function executeProposal(uint256 proposalId) external; +} + +// Основной контракт DLE с упрощенной архитектурой +contract DLE is ERC20, Governor, TimelockController { + // Single-chain governance + mapping(uint256 => bool) public supportedChains; + mapping(uint256 => Proposal) public proposals; + + // Проверка токен-холдеров + modifier onlyTokenHolder() { + require(balanceOf(msg.sender) > 0, "Must hold tokens"); + _; + } + + // Исполнение в целевых сетях + function executeInTargetChains(bytes calldata operation, uint256[] calldata chains) external; +} +``` + +#### 3.1.4 Компоненты для интеграции +- **ERC-20** - токен управления DLE +- **Governor** - система голосования с мультиподписью +- **TimelockController** - отдельный модуль настраиваемых таймлоков +- **Account Abstraction** - универсальность адреса +- **CREATE2 Factory** - детерминистический деплой +- **Single-Chain Governance** - упрощенное управление через одну сеть + +### 3.2 Готовые компоненты с аудитом + +#### 3.2.1 OpenZeppelin (аудит: ConsenSys Diligence) +- ERC-20 - токены управления +- Governance - система голосования +- Access Control - роли и разрешения +- Multisig - мультиподпись +- Timelock - задержки выполнения + +#### 3.2.2 ERC-4337 (аудит: Trail of Bits) +- Account Abstraction - универсальность +- Smart Contract Wallets - кошельки +- Bundlers - оптимизация газа + +#### 3.2.3 Проверенные паттерны +- Diamond Pattern (EIP-2535) - модульность +- Proxy Pattern - обновляемость +- Factory Pattern - создание контрактов + +### 3.3 Безопасность + +#### 3.3.1 Требования к безопасности +- Полный аудит смарт-контракта +- Тестирование всех функций +- Проверка уязвимостей +- Соответствие стандартам безопасности + +#### 3.3.2 Меры безопасности +- Использование проаудированных компонентов +- Проверенные паттерны разработки +- Изоляция рисков +- Поэтапная разработка с тестированием + +### 3.4 Производительность + +#### 3.4.1 Оптимизация газа +- Минимизация стоимости транзакций +- Эффективные алгоритмы +- Использование bundlers (ERC-4337) +- Оптимизация хранения данных + +#### 3.4.2 Масштабируемость +- Поддержка большого количества участников +- Эффективная обработка голосований +- Оптимизация меж-DLE взаимодействий +- Модульная архитектура + +## 4. Интерфейсы и интеграции + +### 4.1 Веб3 приложение + +#### 4.1.1 Функции приложения +- Создание DLE через форму +- Управление DLE +- Участие в голосованиях +- Просмотр истории транзакций + +#### 4.1.2 Межприложное взаимодействие +- Встраивание интерфейсов других DLE +- Безопасное подписание транзакций +- Проверка прав доступа +- Аудит действий + +#### 4.1.3 Мульти-чейн интерфейс с single-chain governance +- Выбор целевых сетей для деплоя DLE +- Отображение предсказанного адреса DLE +- Расчет стоимости деплоя по всем сетям +- Мониторинг статуса деплоя во всех сетях +- Выбор governance сети для создания предложений +- Установка таймлока инициатором предложения +- Подписание предложений токен-холдерами в governance сети +- Мониторинг исполнения в целевых сетях +- История операций и голосований + +### 4.2 API и интеграции + +#### 4.2.1 Внешние интеграции +- Оракулы для внешних данных +- Интеграция с DeFi протоколами +- Поддержка различных блокчейнов +- API для внешних приложений + +## 5. Этапы разработки + +### 5.1 Этап 1: Базовая функциональность +- Создание основного контракта DLE +- Интеграция ERC-20 токенов +- Базовая система голосования с настраиваемым кворумом +- Простые казначейские функции +- CREATE2 Factory для детерминистического деплоя +- Настройки времени голосования (период, задержка) + +### 5.2 Этап 2: Расширенная функциональность +- Система мультиподписи +- Отдельный модуль TimelockController с настраиваемыми параметрами +- Коммуникационные функции +- Модульная система +- Мульти-сетевой деплой в тестовых сетях +- Базовая cross-chain синхронизация + +### 5.3 Этап 3: Мульти-чейн архитектура +- Полная cross-chain синхронизация токенов +- Система голосования с выбором сети +- Cross-chain операции с откатами +- Мониторинг состояния во всех сетях +- Emergency pause и fallback механизмы +- Иерархическая система голосования между DLE + +### 5.4 Этап 4: Межприложное взаимодействие +- Встраивание интерфейсов других DLE +- Безопасное cross-chain подписание +- Оптимизация газа для мульти-сетевых операций +- Интеграция с bridge протоколами +- Расширенное тестирование мульти-чейн функций + +### 5.5 Этап 5: Аудит и запуск +- Профессиональный аудит всех компонентов +- Аудит мульти-чейн безопасности +- Тестирование в различных сетевых условиях +- Исправление уязвимостей +- Финальное тестирование cross-chain операций +- Развертывание в продакшн во всех целевых сетях + +## 6. Требования к тестированию + +### 6.1 Unit тесты +- Тестирование всех функций контракта +- Проверка граничных случаев +- Тестирование безопасности +- Проверка производительности + +### 6.2 Integration тесты +- Тестирование взаимодействия модулей +- Проверка меж-DLE взаимодействий +- Тестирование веб3 приложения +- Проверка API интеграций + +### 6.3 E2E тесты +- Полный цикл создания DLE +- Тестирование голосований +- Проверка коммуникационных функций +- Тестирование межприложного взаимодействия + +## 7. Документация + +### 7.1 Техническая документация +- Описание архитектуры +- API документация +- Руководство по развертыванию +- Руководство по безопасности + +### 7.2 Пользовательская документация +- Руководство пользователя +- FAQ +- Видеоуроки +- Поддержка + +## 8. Критерии приемки + +### 8.1 Функциональные критерии +- Все функции работают согласно требованиям +- Система голосования функционирует корректно +- Меж-DLE взаимодействие работает +- Коммуникационные функции активны +- CREATE2 деплой создает одинаковые адреса во всех сетях +- Cross-chain синхронизация токенов работает корректно +- Голосование с выбором сети функционирует +- Мульти-сетевой деплой завершается успешно во всех целевых сетях + +### 8.2 Критерии безопасности +- Прохождение профессионального аудита +- Отсутствие критических уязвимостей +- Соответствие стандартам безопасности +- Проверка всех сценариев атак +- Безопасность cross-chain операций +- Защита от MEV-атак при мульти-чейн операциях +- Корректная работа откатов при сбоях синхронизации +- Валидация кворума во всех поддерживаемых сетях + +### 8.3 Критерии производительности +- Оптимизация газа +- Быстрая обработка транзакций +- Масштабируемость системы +- Стабильная работа под нагрузкой +- Эффективная синхронизация между сетями +- Минимальные задержки cross-chain операций +- Оптимальное использование ресурсов во всех сетях +- Быстрое восстановление после сбоев синхронизации + +## 9. Лицензии и правовые аспекты + +### 9.1 Используемые лицензии +- OpenZeppelin - MIT лицензия +- ERC-4337 - CC0 лицензия +- Собственный код - Proprietary + +### 9.2 Патентные аспекты +- Низкий патентный риск для концепции DLE +- Использование открытых стандартов +- Защита уникальных функций +- Консультации с юристами при необходимости \ No newline at end of file diff --git a/docs/ai-queue-system.md b/docs/ai-queue-system.md new file mode 100644 index 0000000..6a8494a --- /dev/null +++ b/docs/ai-queue-system.md @@ -0,0 +1,249 @@ +# Система очереди 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 + + + +``` + +## Ограничения и защита + +### 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. Подключение к лог-агрегаторам \ No newline at end of file diff --git a/encrypt-database.sh b/encrypt-database.sh new file mode 100755 index 0000000..f6692e1 --- /dev/null +++ b/encrypt-database.sh @@ -0,0 +1,307 @@ +#!/bin/bash + +# Скрипт для полного шифрования всех таблиц в базе данных DLE +# Использование: ./encrypt-all-tables.sh + +# Проверяем наличие OpenSSL +if ! command -v openssl &> /dev/null; then + echo "❌ OpenSSL не установлен. Установите: sudo apt-get install openssl" + exit 1 +fi + +# Создаём папку для ключей +mkdir -p ./ssl/keys + +# Генерируем ключ шифрования (если его нет) +if [ ! -f "./ssl/keys/full_db_encryption.key" ]; then + echo "🔑 Генерация ключа шифрования для всех таблиц..." + openssl rand -base64 32 > ./ssl/keys/full_db_encryption.key + chmod 600 ./ssl/keys/full_db_encryption.key + echo "✅ Ключ создан: ./ssl/keys/full_db_encryption.key" +fi + +echo "🔒 Полное шифрование всех таблиц в базе данных..." + +# Проверяем подключение к БД +if ! docker exec dapp-postgres pg_isready -U dapp_user -d dapp_db > /dev/null 2>&1; then + echo "❌ Не удалось подключиться к базе данных" + exit 1 +fi + +# Создаём функции шифрования в PostgreSQL +echo "📝 Создание функций шифрования в PostgreSQL..." + +docker exec dapp-postgres psql -U dapp_user -d dapp_db << 'EOF' +-- Создаём расширение для шифрования +CREATE EXTENSION IF NOT EXISTS pgcrypto; + +-- Функция для шифрования текста +CREATE OR REPLACE FUNCTION encrypt_text(data text, key text) +RETURNS text AS $$ +BEGIN + IF data IS NULL THEN + RETURN NULL; + END IF; + RETURN encode(encrypt_iv(data::bytea, decode(key, 'base64'), decode('000102030405060708090A0B0C0D0E0F', 'hex'), 'aes-cbc'), 'base64'); +END; +$$ LANGUAGE plpgsql; + +-- Функция для расшифровки текста +CREATE OR REPLACE FUNCTION decrypt_text(encrypted_data text, key text) +RETURNS text AS $$ +BEGIN + IF encrypted_data IS NULL THEN + RETURN NULL; + END IF; + RETURN convert_from(decrypt_iv(decode(encrypted_data, 'base64'), decode(key, 'base64'), decode('000102030405060708090A0B0C0D0E0F', 'hex'), 'aes-cbc'), 'utf8'); +END; +$$ LANGUAGE plpgsql; + +-- Функция для шифрования JSON +CREATE OR REPLACE FUNCTION encrypt_json(data jsonb, key text) +RETURNS text AS $$ +BEGIN + IF data IS NULL THEN + RETURN NULL; + END IF; + RETURN encode(encrypt_iv(data::text::bytea, decode(key, 'base64'), decode('000102030405060708090A0B0C0D0E0F', 'hex'), 'aes-cbc'), 'base64'); +END; +$$ LANGUAGE plpgsql; + +-- Функция для расшифровки JSON +CREATE OR REPLACE FUNCTION decrypt_json(encrypted_data text, key text) +RETURNS jsonb AS $$ +BEGIN + IF encrypted_data IS NULL THEN + RETURN NULL; + END IF; + RETURN convert_from(decrypt_iv(decode(encrypted_data, 'base64'), decode(key, 'base64'), decode('000102030405060708090A0B0C0D0E0F', 'hex'), 'aes-cbc'), 'utf8')::jsonb; +END; +$$ LANGUAGE plpgsql; +EOF + +# Читаем ключ шифрования +ENCRYPTION_KEY=$(cat ./ssl/keys/full_db_encryption.key) + +echo "🔐 Начинаем шифрование всех таблиц..." + +# Получаем список всех таблиц +TABLES=$(docker exec dapp-postgres psql -U dapp_user -d dapp_db -t -c " +SELECT table_name +FROM information_schema.tables +WHERE table_schema = 'public' +AND table_type = 'BASE TABLE' +ORDER BY table_name;") + +echo "📋 Найдены таблицы для шифрования:" +echo "$TABLES" + +# Функция для шифрования таблицы +encrypt_table() { + local table_name="$1" + echo "🔐 Шифрование таблицы: $table_name" + + # Получаем информацию о колонках + local columns=$(docker exec dapp-postgres psql -U dapp_user -d dapp_db -t -c " + SELECT column_name, data_type + FROM information_schema.columns + WHERE table_name = '$table_name' + AND table_schema = 'public' + AND data_type IN ('text', 'varchar', 'character varying', 'json', 'jsonb') + AND column_name NOT LIKE '%_encrypted' + AND column_name NOT IN ('created_at', 'updated_at', 'id') + ORDER BY ordinal_position;") + + if [ -z "$columns" ]; then + echo " ⏭️ Нет текстовых колонок для шифрования" + return + fi + + echo " 📝 Колонки для шифрования:" + echo "$columns" | while read -r column_info; do + if [ -n "$column_info" ]; then + echo " $column_info" + fi + done + + # Создаём зашифрованные колонки и шифруем данные + echo "$columns" | while read -r column_info; do + if [ -n "$column_info" ]; then + column_name=$(echo "$column_info" | awk '{print $1}') + data_type=$(echo "$column_info" | awk '{print $2}') + + echo " 🔐 Шифрование колонки: $column_name" + + # Добавляем зашифрованную колонку + if [ "$data_type" = "jsonb" ] || [ "$data_type" = "json" ]; then + docker exec dapp-postgres psql -U dapp_user -d dapp_db -c " + ALTER TABLE $table_name ADD COLUMN IF NOT EXISTS ${column_name}_encrypted TEXT; + UPDATE $table_name + SET ${column_name}_encrypted = encrypt_json($column_name, '$ENCRYPTION_KEY') + WHERE $column_name IS NOT NULL AND ${column_name}_encrypted IS NULL;" + else + docker exec dapp-postgres psql -U dapp_user -d dapp_db -c " + ALTER TABLE $table_name ADD COLUMN IF NOT EXISTS ${column_name}_encrypted TEXT; + UPDATE $table_name + SET ${column_name}_encrypted = encrypt_text($column_name, '$ENCRYPTION_KEY') + WHERE $column_name IS NOT NULL AND ${column_name}_encrypted IS NULL;" + fi + fi + done +} + +# Шифруем каждую таблицу +echo "$TABLES" | while read -r table_name; do + if [ -n "$table_name" ]; then + encrypt_table "$table_name" + fi +done + +echo "✅ Шифрование всех таблиц завершено!" + +# Создаём скрипт для расшифровки +cat > decrypt-all-tables.sh << 'EOF' +#!/bin/bash + +# Скрипт для расшифровки всех таблиц +# Использование: ./decrypt-all-tables.sh + +ENCRYPTION_KEY=$(cat ./ssl/keys/full_db_encryption.key) + +echo "🔓 Расшифровка всех таблиц..." + +# Получаем список всех таблиц +TABLES=$(docker exec dapp-postgres psql -U dapp_user -d dapp_db -t -c " +SELECT table_name +FROM information_schema.tables +WHERE table_schema = 'public' +AND table_type = 'BASE TABLE' +ORDER BY table_name;") + +# Функция для расшифровки таблицы +decrypt_table() { + local table_name="$1" + echo "🔓 Расшифровка таблицы: $table_name" + + # Получаем зашифрованные колонки + local encrypted_columns=$(docker exec dapp-postgres psql -U dapp_user -d dapp_db -t -c " + SELECT column_name + FROM information_schema.columns + WHERE table_name = '$table_name' + AND table_schema = 'public' + AND column_name LIKE '%_encrypted' + ORDER BY ordinal_position;") + + if [ -z "$encrypted_columns" ]; then + echo " ⏭️ Нет зашифрованных колонок" + return + fi + + echo " 📝 Зашифрованные колонки:" + echo "$encrypted_columns" | while read -r column_name; do + if [ -n "$column_name" ]; then + echo " $column_name" + # Определяем тип колонки + data_type=$(docker exec dapp-postgres psql -U dapp_user -d dapp_db -t -c " + SELECT data_type FROM information_schema.columns + WHERE table_name = '$table_name' AND column_name = '$column_name' AND table_schema = 'public';" | xargs) + if [ "$data_type" = "jsonb" ] || [ "$data_type" = "json" ]; then + # Расшифровываем json/jsonb + docker exec dapp-postgres psql -U dapp_user -d dapp_db -c " + SELECT id, decrypt_json($column_name, '$ENCRYPTION_KEY') as ${column_name%_encrypted}_decrypted + FROM $table_name WHERE $column_name IS NOT NULL LIMIT 5;" + else + # Расшифровываем текстовые + docker exec dapp-postgres psql -U dapp_user -d dapp_db -c " + SELECT id, decrypt_text($column_name, '$ENCRYPTION_KEY') as ${column_name%_encrypted}_decrypted + FROM $table_name WHERE $column_name IS NOT NULL LIMIT 5;" + fi + fi + done +} + +# Расшифровываем каждую таблицу +echo "$TABLES" | while read -r table_name; do + if [ -n "$table_name" ]; then + decrypt_table "$table_name" + fi +done + +echo "✅ Расшифровка завершена!" +EOF + +chmod +x decrypt-all-tables.sh + +# Создаём скрипт для удаления незашифрованных колонок +cat > remove-unencrypted-columns.sh << 'EOF' +#!/bin/bash + +# Скрипт для удаления незашифрованных колонок +# ВНИМАНИЕ: Это необратимая операция! +# Использование: ./remove-unencrypted-columns.sh + +echo "⚠️ ВНИМАНИЕ: Это удалит все незашифрованные колонки!" +echo "Убедитесь, что шифрование работает корректно!" +read -p "Продолжить? (y/N): " -n 1 -r +echo +if [[ ! $REPLY =~ ^[Yy]$ ]]; then + echo "❌ Операция отменена" + exit 1 +fi + +# Получаем список всех таблиц +TABLES=$(docker exec dapp-postgres psql -U dapp_user -d dapp_db -t -c " +SELECT table_name +FROM information_schema.tables +WHERE table_schema = 'public' +AND table_type = 'BASE TABLE' +ORDER BY table_name;") + +# Удаляем незашифрованные колонки +echo "$TABLES" | while read -r table_name; do + if [ -n "$table_name" ]; then + echo "🗑️ Удаление незашифрованных колонок в таблице: $table_name" + + # Получаем незашифрованные колонки + local unencrypted_columns=$(docker exec dapp-postgres psql -U dapp_user -d dapp_db -t -c " + SELECT column_name + FROM information_schema.columns + WHERE table_name = '$table_name' + AND table_schema = 'public' + AND data_type IN ('text', 'varchar', 'character varying', 'json', 'jsonb') + AND column_name NOT LIKE '%_encrypted' + AND column_name NOT IN ('created_at', 'updated_at', 'id') + ORDER BY ordinal_position;") + + echo "$unencrypted_columns" | while read -r column_name; do + if [ -n "$column_name" ]; then + echo " 🗑️ Удаление колонки: $column_name" + docker exec dapp-postgres psql -U dapp_user -d dapp_db -c " + ALTER TABLE $table_name DROP COLUMN IF EXISTS $column_name;" + fi + done + fi +done + +echo "✅ Незашифрованные колонки удалены!" +EOF + +chmod +x remove-unencrypted-columns.sh + +echo "" +echo "🎯 Что было сделано:" +echo "1. ✅ Создан ключ шифрования: ./ssl/keys/full_db_encryption.key" +echo "2. ✅ Добавлены функции шифрования в PostgreSQL" +echo "3. ✅ Зашифрованы ВСЕ текстовые колонки во ВСЕХ таблицах" +echo "4. ✅ Создан скрипт расшифровки: ./decrypt-all-tables.sh" +echo "5. ✅ Создан скрипт удаления: ./remove-unencrypted-columns.sh" +echo "" +echo "⚠️ ВАЖНО:" +echo "- Ключ шифрования: ./ssl/keys/full_db_encryption.key" +echo "- Храните ключ в безопасном месте!" +echo "- Сделайте резервную копию ключа!" +echo "" +echo "🔧 Следующие шаги:" +echo "1. Протестируйте расшифровку: ./decrypt-all-tables.sh" +echo "2. Обновите код приложения для работы с зашифрованными данными" +echo "3. После проверки удалите незашифрованные колонки: ./remove-unencrypted-columns.sh" \ No newline at end of file diff --git a/frontend/index.html b/frontend/index.html index 7acf5e4..1731887 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -15,8 +15,7 @@ color: #2c3e50; } - - +
diff --git a/frontend/nginx-tunnel.conf b/frontend/nginx-tunnel.conf index 9fbef86..f7013bf 100644 --- a/frontend/nginx-tunnel.conf +++ b/frontend/nginx-tunnel.conf @@ -1,26 +1,77 @@ +# Финальная безопасная конфигурация nginx + server { listen 80; - server_name _; + server_name hb3-accelerator.com www.hb3-accelerator.com localhost 127.0.0.1; root /usr/share/nginx/html; index index.html; - location / { - try_files $uri $uri/ /index.html; + # Блокировка агрессивных сканеров + if ($http_user_agent ~* (sqlmap|nikto|dirb|gobuster|wfuzz|burp|zap|nessus|openvas)) { + return 403; } - # Прокси для API (если нужно) + # Блокировка очень старых браузеров + if ($http_user_agent ~* "MSIE [1-8]\.") { + return 403; + } + + # Блокировка опасных файлов (НЕ блокируем .js, .css) + if ($request_uri ~* "\.(php|asp|aspx|jsp|cgi|pl|py|sh|bash|exe|bat|cmd|com|pif|scr|vbs|vbe|jar|war|ear|dll|so|dylib|bin|sys|ini|log|bak|old|tmp|temp|swp|swo|~)$") { + return 404; + } + + # Блокировка WordPress сканирования + if ($request_uri ~* "(wp-admin|wp-content|wp-includes|wp-config|wp-login|xmlrpc)") { + return 404; + } + + # Блокировка path traversal + if ($request_uri ~* "(\.\.|\.\./|\.\.\\|\.\.%2f|\.\.%5c)") { + return 404; + } + + # Блокировка конкретных атакующих IP + if ($remote_addr = "198.55.98.76") { + return 403; + } + + # Основной location + location / { + try_files $uri $uri/ /index.html =404; + + # Заголовки безопасности + add_header X-Frame-Options "DENY" always; + add_header X-Content-Type-Options "nosniff" always; + add_header X-XSS-Protection "1; mode=block" always; + add_header Referrer-Policy "strict-origin-when-cross-origin" always; + add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:; connect-src 'self' ws: wss:;" always; + add_header Permissions-Policy "geolocation=(), microphone=(), camera=()" always; + } + + # API с дополнительной защитой location /api/ { - proxy_pass http://backend:8000/api/; + proxy_pass http://dapp-backend: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; + + # Таймауты + proxy_connect_timeout 30s; + proxy_send_timeout 30s; + proxy_read_timeout 30s; + + # Заголовки безопасности для API + add_header X-Frame-Options "DENY" always; + add_header X-Content-Type-Options "nosniff" always; + add_header X-XSS-Protection "1; mode=block" always; } - # Прокси для WebSocket (если нужно) + # WebSocket с защитой location /ws { - proxy_pass http://backend:8000; + proxy_pass http://dapp-backend:8000; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; @@ -28,5 +79,39 @@ server { 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; + + # Таймауты для WebSocket + proxy_connect_timeout 30s; + proxy_send_timeout 30s; + proxy_read_timeout 300s; } -} + + # Статические файлы с кешированием и защитой + location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ { + expires 1y; + add_header Cache-Control "public, immutable"; + add_header Vary Accept-Encoding; + + # Дополнительная защита для статических файлов + add_header X-Content-Type-Options "nosniff" always; + } + + # Запрет доступа к чувствительным файлам + location ~* /(\.htaccess|\.htpasswd|\.env|\.git|\.svn|\.DS_Store|Thumbs\.db|web\.config|robots\.txt|sitemap\.xml)$ { + deny all; + return 404; + } + + # Строгая защита от доступа к конфигурационным файлам + location ~* /\.(env|config|ini|conf|cfg|yml|yaml|json|xml|sql|db|bak|backup|old|tmp|temp|log)$ { + deny all; + return 404; + } + + # Скрытие информации о сервере + server_tokens off; + + # Логирование ошибок + error_log /var/log/nginx/error.log warn; + access_log /var/log/nginx/access.log combined; +} \ No newline at end of file diff --git a/frontend/nginx-waf.conf b/frontend/nginx-waf.conf new file mode 100644 index 0000000..5730ec2 --- /dev/null +++ b/frontend/nginx-waf.conf @@ -0,0 +1,59 @@ +# Дополнительные правила WAF для защиты от атак + +# Блокировка известных сканеров и инструментов +map $http_user_agent $bad_bot { + default 0; + ~*bot 1; + ~*crawler 1; + ~*spider 1; + ~*scanner 1; + ~*nmap 1; + ~*sqlmap 1; + ~*nikto 1; + ~*dirb 1; + ~*gobuster 1; + ~*wfuzz 1; + ~*burp 1; + ~*zap 1; + ~*w3af 1; + ~*nessus 1; + ~*openvas 1; + ~*acunetix 1; + ~*netsparker 1; + ~*appscan 1; + ~*webinspect 1; + ~*paros 1; + ~*arachni 1; + ~*skipfish 1; + ~*wpscan 1; + ~*joomscan 1; + ~*drupalscan 1; + ~*magento 1; + ~*wordpress 1; + ~*"Chrome/[1-7][0-9]\." 1; + ~*"Firefox/[1-6][0-9]\." 1; + ~*"Safari/[1-9]\." 1; + ~*"MSIE [1-9]\." 1; + ~*"Trident/[1-6]\." 1; +} + +# Блокировка подозрительных IP (добавляем атакующий IP) +geo $bad_ip { + default 0; + 198.55.98.76 1; +} + +# Блокировка подозрительных запросов +map $request_uri $bad_request { + default 0; + ~*\.(php|asp|aspx|jsp|cgi|pl|py|sh|bash|exe|bat|cmd|com|pif|scr|vbs|vbe|jar|war|ear|dll|so|dylib|bin|sys|ini|log|bak|old|tmp|temp|swp|swo|~)$ 1; + ~*(wp-admin|wp-content|wp-includes|wp-config|wp-login|xmlrpc|admin|administrator|login|panel|dashboard) 1; + ~*(phpmyadmin|mysql|database|db|sql|oracle|postgres|mongo) 1; + ~*(shell|cmd|exec|system|eval|base64|decode|encode) 1; + ~*(union|select|insert|update|delete|drop|create|alter|grant|revoke) 1; + ~*(script|javascript|vbscript|onload|onerror|onclick) 1; + ~*(../|..\\|\.\.|\.\./) 1; + ~*(config|setup|install|upgrade|backup|restore) 1; + ~*\.(env|config|ini|conf|cfg|yml|yaml|json|xml|sql|db|bak|backup|old|tmp|temp|log)$ 1; + ~*(\.\.|\.\./|\.\.\\|\.\.%2f|\.\.%5c) 1; +} \ No newline at end of file diff --git a/frontend/nginx.conf b/frontend/nginx.conf index 675df01..1db5ca5 100644 --- a/frontend/nginx.conf +++ b/frontend/nginx.conf @@ -6,81 +6,30 @@ http { include /etc/nginx/mime.types; default_type application/octet-stream; - # Оптимизация производительности - sendfile on; - tcp_nopush on; - tcp_nodelay on; - keepalive_timeout 65; - types_hash_max_size 2048; - - # Сжатие - gzip on; - gzip_vary on; - gzip_min_length 1024; - gzip_proxied any; - gzip_comp_level 6; - gzip_types - text/plain - text/css - text/xml - text/javascript - application/javascript - application/json - application/xml+rss - application/atom+xml - image/svg+xml; - server { listen 80; server_name localhost; - root /usr/share/nginx/html; - index index.html; - # Кеширование статических файлов - location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ { - expires 1y; - add_header Cache-Control "public, immutable"; - add_header Vary Accept-Encoding; - } - - # Запрет на доступ к чувствительным файлам - location ~* /(sendgrid\.env|env\.js|config\.js|aws-exports\.js|firebase-config\.js|firebase\.js|settings\.js|app-settings\.js|config\.json|credentials\.json|secrets\.json)$ { - deny all; - return 403; - } - - # Основные файлы HTML - location / { - try_files $uri $uri/ /index.html; - add_header Cache-Control "no-cache, no-store, must-revalidate"; - add_header Pragma "no-cache"; - add_header Expires "0"; - } - - # API прокси (если нужно) + # API прокси (точное совпадение для /api/) location /api/ { - proxy_pass http://backend:8000/api/; + proxy_pass http://dapp-backend:8000; 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; + proxy_set_header X-Forwarded-Host $host; + proxy_set_header X-Forwarded-Port $server_port; } - # WebSocket прокси - location /ws { - proxy_pass http://backend:8000; - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; + # Проксирование к development серверу frontend + location / { + proxy_pass http://dapp-frontend: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; + proxy_set_header X-Forwarded-Host $host; + proxy_set_header X-Forwarded-Port $server_port; } - - # Безопасность - add_header X-Frame-Options DENY always; - add_header X-Content-Type-Options nosniff always; - add_header X-XSS-Protection "1; mode=block" always; } } \ No newline at end of file diff --git a/frontend/src/api/axios.js b/frontend/src/api/axios.js index f91b062..652e9cb 100644 --- a/frontend/src/api/axios.js +++ b/frontend/src/api/axios.js @@ -32,7 +32,7 @@ api.interceptors.request.use( ); // Добавляем перехватчик ответов для обработки ошибок -axios.interceptors.response.use( +api.interceptors.response.use( (response) => { // Проверяем, что ответ действительно JSON if (response.headers['content-type'] && diff --git a/frontend/src/components/AIQueueMonitor.vue b/frontend/src/components/AIQueueMonitor.vue new file mode 100644 index 0000000..58c7c25 --- /dev/null +++ b/frontend/src/components/AIQueueMonitor.vue @@ -0,0 +1,525 @@ + + + + + \ No newline at end of file diff --git a/frontend/src/components/EmbeddedDLEInterface.vue b/frontend/src/components/EmbeddedDLEInterface.vue new file mode 100644 index 0000000..d823ad3 --- /dev/null +++ b/frontend/src/components/EmbeddedDLEInterface.vue @@ -0,0 +1,903 @@ + + + + + + + \ No newline at end of file diff --git a/frontend/src/components/OllamaModelManager.vue b/frontend/src/components/OllamaModelManager.vue new file mode 100644 index 0000000..3e5381c --- /dev/null +++ b/frontend/src/components/OllamaModelManager.vue @@ -0,0 +1,435 @@ + + + + + + + \ No newline at end of file diff --git a/frontend/src/composables/useChat.js b/frontend/src/composables/useChat.js index f670640..8c9f839 100644 --- a/frontend/src/composables/useChat.js +++ b/frontend/src/composables/useChat.js @@ -14,6 +14,7 @@ import { ref, computed, watch, onMounted, onUnmounted } from 'vue'; import api from '../api/axios'; import { getFromStorage, setToStorage, removeFromStorage } from '../utils/storage'; import { generateUniqueId } from '../utils/helpers'; +import websocketService from '../services/websocketService'; function initGuestId() { let id = getFromStorage('guestId', ''); @@ -396,11 +397,72 @@ export function useChat(auth) { hasUserSentMessage.value = false; newMessage.value = ''; attachments.value = []; + // Отключаем WebSocket + cleanupWebSocket(); // Гостевые данные очищаются при успешной аутентификации в loadMessages // или если пользователь сам очистит localStorage + } else if (isAuth && !wasAuth) { // Если пользователь вошел + console.log('[useChat] Пользователь вошел, подключаем WebSocket.'); + // Отложенное подключение, чтобы дождаться загрузки данных пользователя + setTimeout(() => setupChatWebSocket(), 100); } }); + // Отслеживаем загрузку данных пользователя для подключения WebSocket + watch(() => auth.user?.value, (newUser, oldUser) => { + if (newUser && newUser.id && auth.isAuthenticated.value) { + console.log('[useChat] Данные пользователя загружены, подключаем WebSocket:', newUser.id); + setupChatWebSocket(); + } + }, { immediate: false }); + + // --- WebSocket для real-time сообщений --- + function setupChatWebSocket() { + // Подключаемся к WebSocket только если пользователь аутентифицирован + if (auth.isAuthenticated.value && auth.user && auth.user.value && auth.user.value.id) { + console.log('[useChat] Подключение к WebSocket для пользователя:', auth.user.value.id); + websocketService.connect(auth.user.value.id); + + // Подписываемся на события + websocketService.on('chat-message', (message) => { + console.log('[useChat] Получено новое сообщение через WebSocket:', message); + // Проверяем, что сообщение не дублируется + const existingMessage = messages.value.find(m => m.id === message.id); + if (!existingMessage) { + messages.value.push(message); + } + }); + + websocketService.on('conversation-updated', (conversationId) => { + console.log('[useChat] Обновление диалога через WebSocket:', conversationId); + // Можно добавить логику обновления списка диалогов + }); + + websocketService.on('connected', () => { + console.log('[useChat] WebSocket подключен'); + }); + + websocketService.on('disconnected', () => { + console.log('[useChat] WebSocket отключен'); + }); + + websocketService.on('error', (error) => { + console.error('[useChat] WebSocket ошибка:', error); + }); + } else { + console.log('[useChat] WebSocket не подключен: пользователь не аутентифицирован или данные не загружены'); + } + } + + function cleanupWebSocket() { + websocketService.off('chat-message'); + websocketService.off('conversation-updated'); + websocketService.off('connected'); + websocketService.off('disconnected'); + websocketService.off('error'); + websocketService.disconnect(); + } + // --- Инициализация --- onMounted(() => { if (!auth.isAuthenticated.value && guestId.value) { @@ -408,33 +470,13 @@ export function useChat(auth) { } else if (auth.isAuthenticated.value) { loadMessages({ initial: true }); } - // Добавляем слушатель для возможности принудительной перезагрузки - // window.addEventListener('load-chat-history', () => loadMessages({ initial: true })); - }); - - // --- WebSocket для real-time сообщений --- - let ws = null; - function setupChatWebSocket() { - const wsProtocol = window.location.protocol === 'https:' ? 'wss' : 'ws'; - ws = new WebSocket(`${wsProtocol}://${window.location.host}/ws`); - ws.onmessage = (event) => { - try { - const data = JSON.parse(event.data); - if (data.type === 'chat-message' && data.message) { - // Проверяем, что сообщение для текущего пользователя/диалога - // (можно доработать фильтрацию по conversation_id, user_id и т.д.) - messages.value.push(data.message); - } - } catch (e) { - console.error('[useChat] Ошибка обработки chat-message по WebSocket:', e); - } - }; - } - onMounted(() => { + + // Подключаем WebSocket если пользователь уже аутентифицирован setupChatWebSocket(); }); + onUnmounted(() => { - if (ws) ws.close(); + cleanupWebSocket(); }); return { diff --git a/frontend/src/router/index.js b/frontend/src/router/index.js index cde9b7d..2ba3269 100644 --- a/frontend/src/router/index.js +++ b/frontend/src/router/index.js @@ -55,6 +55,16 @@ const routes = [ name: 'settings-blockchain', component: SettingsBlockchainView, }, + { + path: 'blockchain/dle-deploy', + name: 'settings-blockchain-dle-deploy', + component: () => import('../views/settings/BlockchainSettingsView.vue'), + }, + { + path: 'dle-v2-deploy', + name: 'settings-dle-v2-deploy', + component: () => import('../views/settings/DleDeployFormView.vue'), + }, { path: 'security', name: 'settings-security', @@ -201,6 +211,66 @@ const routes = [ name: 'page-edit', component: () => import('../views/content/PageEditView.vue'), }, + { + path: '/management', + name: 'management', + component: () => import('../views/ManagementView.vue'), + meta: { requiresAuth: true } + }, + { + path: '/management/dle', + name: 'management-dle', + component: () => import('../views/smartcontracts/DleManagementView.vue'), + meta: { requiresAuth: true } + }, + { + path: '/management/proposals', + name: 'management-proposals', + component: () => import('../views/smartcontracts/ProposalsView.vue'), + meta: { requiresAuth: true } + }, + { + path: '/management/tokens', + name: 'management-tokens', + component: () => import('../views/smartcontracts/TokensView.vue'), + meta: { requiresAuth: true } + }, + { + path: '/management/quorum', + name: 'management-quorum', + component: () => import('../views/smartcontracts/QuorumView.vue'), + meta: { requiresAuth: true } + }, + { + path: '/management/modules', + name: 'management-modules', + component: () => import('../views/smartcontracts/ModulesView.vue'), + meta: { requiresAuth: true } + }, + { + path: '/management/treasury', + name: 'management-treasury', + component: () => import('../views/smartcontracts/TreasuryView.vue'), + meta: { requiresAuth: true } + }, + { + path: '/management/analytics', + name: 'management-analytics', + component: () => import('../views/smartcontracts/AnalyticsView.vue'), + meta: { requiresAuth: true } + }, + { + path: '/management/history', + name: 'management-history', + component: () => import('../views/smartcontracts/HistoryView.vue'), + meta: { requiresAuth: true } + }, + { + path: '/management/settings', + name: 'management-settings', + component: () => import('../views/smartcontracts/SettingsView.vue'), + meta: { requiresAuth: true } + }, ]; const router = createRouter({ diff --git a/frontend/src/services/dleV2Service.js b/frontend/src/services/dleV2Service.js new file mode 100644 index 0000000..d99b970 --- /dev/null +++ b/frontend/src/services/dleV2Service.js @@ -0,0 +1,85 @@ +/** + * 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 + */ + +import axios from 'axios'; + +/** + * Сервис для работы с DLE v2 (Digital Legal Entity) + * Современный подход с единым контрактом + */ +class DLEV2Service { + /** + * Создает новое DLE v2 + * @param {Object} dleParams - Параметры DLE + * @returns {Promise} - Результат создания + */ + async createDLE(dleParams) { + try { + const response = await axios.post('/api/dle-v2', dleParams); + return response.data; + } catch (error) { + console.error('Ошибка при создании DLE v2:', error); + throw error; + } + } + + /** + * Получает список всех DLE v2 + * @returns {Promise} - Список DLE v2 + */ + async getAllDLEs() { + try { + const response = await axios.get('/api/dle-v2'); + return response.data.data || []; + } catch (error) { + console.error('Ошибка при получении списка DLE v2:', error); + return []; + } + } + + /** + * Получает настройки по умолчанию для DLE v2 + * @returns {Promise} - Настройки по умолчанию + */ + async getDefaults() { + try { + const response = await axios.get('/api/dle-v2/defaults'); + return response.data.data; + } catch (error) { + console.error('Ошибка при получении настроек по умолчанию DLE v2:', error); + return { + votingDelay: 1, + votingPeriod: 45818, + proposalThreshold: '100000', + quorumPercentage: 4, + minTimelockDelay: 2 + }; + } + } + + /** + * Удаляет DLE v2 по адресу + * @param {string} dleAddress - Адрес DLE + * @returns {Promise} - Результат удаления + */ + async deleteDLE(dleAddress) { + try { + const response = await axios.delete(`/api/dle-v2/${dleAddress}`); + return response.data; + } catch (error) { + console.error('Ошибка при удалении DLE v2:', error); + throw error; + } + } +} + +export default new DLEV2Service(); \ No newline at end of file diff --git a/frontend/src/services/wallet.js b/frontend/src/services/wallet.js index 51ea6f9..0f99f41 100644 --- a/frontend/src/services/wallet.js +++ b/frontend/src/services/wallet.js @@ -49,6 +49,7 @@ export async function connectWithWallet() { const origin = window.location.origin; const statement = 'Sign in with Ethereum to the app.'; + const issuedAt = new Date().toISOString(); const siweMessage = new SiweMessage({ domain, address, @@ -57,11 +58,23 @@ export async function connectWithWallet() { version: '1', chainId: 1, nonce, + issuedAt, resources: [`${origin}/api/auth/verify`], }); const message = siweMessage.prepareMessage(); console.log('SIWE message:', message); + console.log('SIWE message details:', { + domain, + address, + statement, + uri: origin, + version: '1', + chainId: 1, + nonce, + issuedAt, + resources: [`${origin}/api/auth/verify`], + }); // Запрашиваем подпись console.log('Requesting signature...'); @@ -75,9 +88,10 @@ export async function connectWithWallet() { // Отправляем подпись на сервер для верификации console.log('Sending verification request...'); const verificationResponse = await axios.post('/auth/verify', { - message, signature, address, + nonce, + issuedAt, }); console.log('Verification response:', verificationResponse.data); diff --git a/frontend/src/services/websocketService.js b/frontend/src/services/websocketService.js new file mode 100644 index 0000000..47b0bfa --- /dev/null +++ b/frontend/src/services/websocketService.js @@ -0,0 +1,192 @@ +/** + * WebSocket сервис для реального времени обновлений + */ + +class WebSocketService { + constructor() { + this.ws = null; + this.isConnected = false; + this.reconnectAttempts = 0; + this.maxReconnectAttempts = 5; + this.reconnectDelay = 1000; // 1 секунда + this.listeners = new Map(); + this.userId = null; + } + + // Подключение к WebSocket серверу + connect(userId = null) { + if (this.ws && this.ws.readyState === WebSocket.OPEN) { + console.log('🔌 [WebSocket] Уже подключен'); + return; + } + + this.userId = userId; + + try { + // Определяем WebSocket URL + const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:'; + // В Docker окружении backend работает на порту 8000 + const backendHost = window.location.hostname + ':8000'; + const wsUrl = `${protocol}//${backendHost}/ws`; + + console.log('🔌 [WebSocket] Подключение к:', wsUrl); + + this.ws = new WebSocket(wsUrl); + + this.ws.onopen = () => { + console.log('✅ [WebSocket] Подключение установлено'); + this.isConnected = true; + this.reconnectAttempts = 0; + + // Аутентификация пользователя + if (this.userId) { + this.send({ + type: 'auth', + userId: this.userId + }); + } + + this.emit('connected'); + }; + + this.ws.onmessage = (event) => { + try { + const data = JSON.parse(event.data); + console.log('📨 [WebSocket] Получено сообщение:', data); + this.handleMessage(data); + } catch (error) { + console.error('❌ [WebSocket] Ошибка парсинга сообщения:', error); + } + }; + + this.ws.onclose = (event) => { + console.log('🔌 [WebSocket] Соединение закрыто:', event.code, event.reason); + this.isConnected = false; + this.emit('disconnected', event); + + // Попытка переподключения + if (this.reconnectAttempts < this.maxReconnectAttempts) { + this.reconnectAttempts++; + console.log(`🔄 [WebSocket] Попытка переподключения ${this.reconnectAttempts}/${this.maxReconnectAttempts}`); + + setTimeout(() => { + this.connect(this.userId); + }, this.reconnectDelay * this.reconnectAttempts); + } else { + console.error('❌ [WebSocket] Превышено максимальное количество попыток переподключения'); + this.emit('reconnect-failed'); + } + }; + + this.ws.onerror = (error) => { + console.error('❌ [WebSocket] Ошибка соединения:', error); + this.emit('error', error); + }; + + } catch (error) { + console.error('❌ [WebSocket] Ошибка создания соединения:', error); + this.emit('error', error); + } + } + + // Отправка сообщения + send(data) { + if (this.ws && this.ws.readyState === WebSocket.OPEN) { + this.ws.send(JSON.stringify(data)); + } else { + console.warn('⚠️ [WebSocket] Соединение не установлено, сообщение не отправлено:', data); + } + } + + // Обработка входящих сообщений + handleMessage(data) { + switch (data.type) { + case 'auth-success': + console.log('✅ [WebSocket] Аутентификация успешна для пользователя:', data.userId); + this.emit('auth-success', data); + break; + + case 'chat-message': + console.log('💬 [WebSocket] Новое сообщение чата:', data.message); + this.emit('chat-message', data.message); + break; + + case 'conversation-updated': + console.log('📝 [WebSocket] Обновление диалога:', data.conversationId); + this.emit('conversation-updated', data.conversationId); + break; + + case 'messages-updated': + console.log('📨 [WebSocket] Обновление сообщений'); + this.emit('messages-updated'); + break; + + case 'contacts-updated': + console.log('👥 [WebSocket] Обновление контактов'); + this.emit('contacts-updated'); + break; + + default: + console.log('❓ [WebSocket] Неизвестный тип сообщения:', data.type); + this.emit('unknown-message', data); + } + } + + // Подписка на события + on(event, callback) { + if (!this.listeners.has(event)) { + this.listeners.set(event, []); + } + this.listeners.get(event).push(callback); + } + + // Отписка от событий + off(event, callback) { + if (this.listeners.has(event)) { + const callbacks = this.listeners.get(event); + const index = callbacks.indexOf(callback); + if (index > -1) { + callbacks.splice(index, 1); + } + } + } + + // Эмиссия событий + emit(event, data) { + if (this.listeners.has(event)) { + this.listeners.get(event).forEach(callback => { + try { + callback(data); + } catch (error) { + console.error(`❌ [WebSocket] Ошибка в обработчике события ${event}:`, error); + } + }); + } + } + + // Отключение + disconnect() { + if (this.ws) { + this.ws.close(); + this.ws = null; + } + this.isConnected = false; + this.listeners.clear(); + console.log('🔌 [WebSocket] Отключен'); + } + + // Получение статуса соединения + getStatus() { + return { + isConnected: this.isConnected, + readyState: this.ws ? this.ws.readyState : null, + reconnectAttempts: this.reconnectAttempts, + userId: this.userId + }; + } +} + +// Создаем единственный экземпляр +const websocketService = new WebSocketService(); + +export default websocketService; \ No newline at end of file diff --git a/frontend/src/utils/wallet.js b/frontend/src/utils/wallet.js index 73aa7de..e0fc2e3 100644 --- a/frontend/src/utils/wallet.js +++ b/frontend/src/utils/wallet.js @@ -10,7 +10,7 @@ * GitHub: https://github.com/HB3-ACCELERATOR */ -import axios from '../api/axios'; +import axios from 'axios'; import { ethers } from 'ethers'; import { SiweMessage } from 'siwe'; @@ -100,10 +100,15 @@ export const connectWallet = async () => { // Отправляем верификацию на сервер console.log('Sending verification request...'); - const verifyResponse = await axios.post('/auth/verify', { + const requestData = { address: normalizedAddress, signature, nonce, + }; + console.log('Request data:', requestData); + + const verifyResponse = await axios.post('/api/auth/verify', requestData, { + withCredentials: true, }); // Обновляем интерфейс для отображения подключенного состояния diff --git a/frontend/src/views/CrmView.vue b/frontend/src/views/CrmView.vue index 6362b8e..2539d1c 100644 --- a/frontend/src/views/CrmView.vue +++ b/frontend/src/views/CrmView.vue @@ -21,27 +21,34 @@

Управление DLE

-

Контакты

-

Таблицы

-

Контент

- +
+ +
+

Управление

+
@@ -218,6 +225,10 @@ function goToContactsList() { function goToContent() { router.push({ name: 'content-list' }); } + +function goToManagement() { + router.push({ name: 'management' }); +} \ No newline at end of file diff --git a/frontend/src/views/ManagementView.vue b/frontend/src/views/ManagementView.vue new file mode 100644 index 0000000..2b1fa7e --- /dev/null +++ b/frontend/src/views/ManagementView.vue @@ -0,0 +1,277 @@ + + + + + + + \ No newline at end of file diff --git a/frontend/src/views/SettingsView.vue b/frontend/src/views/SettingsView.vue index 35b399e..e86fc6e 100644 --- a/frontend/src/views/SettingsView.vue +++ b/frontend/src/views/SettingsView.vue @@ -19,7 +19,14 @@ @auth-action-completed="$emit('auth-action-completed')" >
-

Настройки

+
@@ -50,6 +57,17 @@ const router = useRouter(); const route = useRoute(); const isLoading = ref(true); +// Вычисляемый заголовок страницы в зависимости от роута +const pageTitle = computed(() => { + if (route.name === 'settings-blockchain-dle-deploy') { + return 'Создать новое DLE (Digital Legal Entity)'; + } + if (route.name === 'settings-dle-v2-deploy') { + return 'Создать современное DLE v2 (Digital Legal Entity)'; + } + return 'Настройки'; +}); + // Обработчик события изменения авторизации const handleAuthEvent = (eventData) => { console.log('[SettingsView] Получено событие изменения авторизации:', eventData); @@ -91,9 +109,37 @@ onBeforeUnmount(() => { } /* Заголовки */ +.page-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: var(--spacing-lg); +} + h1 { color: var(--color-dark); - margin-bottom: var(--spacing-lg); + margin: 0; +} + +.close-btn { + background: none; + border: none; + font-size: 1.5rem; + cursor: pointer; + color: #666; + padding: 0; + width: 30px; + height: 30px; + display: flex; + align-items: center; + justify-content: center; + border-radius: 50%; + transition: all 0.2s; +} + +.close-btn:hover { + background: #f0f0f0; + color: #333; } h3 { diff --git a/frontend/src/views/settings/AI/OllamaSettingsView.vue b/frontend/src/views/settings/AI/OllamaSettingsView.vue index f96a48e..d53e1c3 100644 --- a/frontend/src/views/settings/AI/OllamaSettingsView.vue +++ b/frontend/src/views/settings/AI/OllamaSettingsView.vue @@ -24,6 +24,7 @@ :showApiKey="false" :showBaseUrl="true" /> + @@ -31,6 +32,7 @@ + + \ No newline at end of file diff --git a/frontend/src/views/settings/SettingsIndexView.vue b/frontend/src/views/settings/SettingsIndexView.vue index e4f4bd6..b1cde14 100644 --- a/frontend/src/views/settings/SettingsIndexView.vue +++ b/frontend/src/views/settings/SettingsIndexView.vue @@ -22,6 +22,11 @@

Интеграция с блокчейн-сетями, RPC, токены и смарт-контракты.

+
+

Блокчейн 2

+

Современный DLE v2 - единый смарт-контракт с встроенной системой голосования.

+ +

Безопасность

Управление доступом, токенами, аутентификацией и правами.

@@ -32,62 +37,14 @@

Настройки серверов, хостинга и публикации приложения.

- + - - \ No newline at end of file diff --git a/frontend/src/views/smartcontracts/AnalyticsView.vue b/frontend/src/views/smartcontracts/AnalyticsView.vue new file mode 100644 index 0000000..4f55895 --- /dev/null +++ b/frontend/src/views/smartcontracts/AnalyticsView.vue @@ -0,0 +1,705 @@ + + + + + + + \ No newline at end of file diff --git a/frontend/src/views/smartcontracts/DleManagementView.vue b/frontend/src/views/smartcontracts/DleManagementView.vue new file mode 100644 index 0000000..eabc77f --- /dev/null +++ b/frontend/src/views/smartcontracts/DleManagementView.vue @@ -0,0 +1,499 @@ + + + + + + + \ No newline at end of file diff --git a/frontend/src/views/smartcontracts/HistoryView.vue b/frontend/src/views/smartcontracts/HistoryView.vue new file mode 100644 index 0000000..365317f --- /dev/null +++ b/frontend/src/views/smartcontracts/HistoryView.vue @@ -0,0 +1,1058 @@ + + + + + + + \ No newline at end of file diff --git a/frontend/src/views/smartcontracts/ModulesView.vue b/frontend/src/views/smartcontracts/ModulesView.vue new file mode 100644 index 0000000..4ff0771 --- /dev/null +++ b/frontend/src/views/smartcontracts/ModulesView.vue @@ -0,0 +1,766 @@ + + + + + + + \ No newline at end of file diff --git a/frontend/src/views/smartcontracts/ProposalsView.vue b/frontend/src/views/smartcontracts/ProposalsView.vue new file mode 100644 index 0000000..d6cb599 --- /dev/null +++ b/frontend/src/views/smartcontracts/ProposalsView.vue @@ -0,0 +1,611 @@ + + + + + + + \ No newline at end of file diff --git a/frontend/src/views/smartcontracts/QuorumView.vue b/frontend/src/views/smartcontracts/QuorumView.vue new file mode 100644 index 0000000..f090d37 --- /dev/null +++ b/frontend/src/views/smartcontracts/QuorumView.vue @@ -0,0 +1,600 @@ + + + + + + + \ No newline at end of file diff --git a/frontend/src/views/smartcontracts/SettingsView.vue b/frontend/src/views/smartcontracts/SettingsView.vue new file mode 100644 index 0000000..a98437b --- /dev/null +++ b/frontend/src/views/smartcontracts/SettingsView.vue @@ -0,0 +1,835 @@ + + + + + + + \ No newline at end of file diff --git a/frontend/src/views/smartcontracts/TokensView.vue b/frontend/src/views/smartcontracts/TokensView.vue new file mode 100644 index 0000000..00a4716 --- /dev/null +++ b/frontend/src/views/smartcontracts/TokensView.vue @@ -0,0 +1,626 @@ + + + + + + + \ No newline at end of file diff --git a/frontend/src/views/smartcontracts/TreasuryView.vue b/frontend/src/views/smartcontracts/TreasuryView.vue new file mode 100644 index 0000000..607f76a --- /dev/null +++ b/frontend/src/views/smartcontracts/TreasuryView.vue @@ -0,0 +1,935 @@ + + + + + + + \ No newline at end of file diff --git a/frontend/vite.config.js b/frontend/vite.config.js index 011ace3..ea363c6 100644 --- a/frontend/vite.config.js +++ b/frontend/vite.config.js @@ -40,6 +40,7 @@ export default defineConfig({ port: 5173, host: '0.0.0.0', allowedHosts: ['dapp-frontend', 'localhost', '127.0.0.1', 'hb3-accelerator.com'], + force: true, proxy: { '/api': { target: 'http://dapp-backend:8000', diff --git a/legal/GITHUB_PROTECTION_STRATEGY.md b/legal/GITHUB_PROTECTION_STRATEGY.md deleted file mode 100644 index 800eb6c..0000000 --- a/legal/GITHUB_PROTECTION_STRATEGY.md +++ /dev/null @@ -1,199 +0,0 @@ -# СТРАТЕГИЯ ЗАЩИТЫ ПРИ ПУБЛИКАЦИИ НА GITHUB -## Как безопасно опубликовать проект DLE - -### 🚨 **НЕМЕДЛЕННЫЕ ДЕЙСТВИЯ** - -#### **1. Сделать репозиторий приватным** -```bash -# В настройках GitHub -Settings → General → Danger Zone → Change repository visibility -→ Make private -``` - -#### **2. Удалить чувствительные файлы из истории** -```bash -# Удалить файлы из git истории -git filter-branch --force --index-filter \ -'git rm --cached --ignore-unmatch legal/PATENT_APPLICATION.md' \ ---prune-empty --tag-name-filter cat -- --all - -git filter-branch --force --index-filter \ -'git rm --cached --ignore-unmatch legal/INNOVATION_PROCESS.md' \ ---prune-empty --tag-name-filter cat -- --all -``` - -#### **3. Добавить в .gitignore** -```gitignore -# Патентные документы -legal/PATENT_*.md -legal/INNOVATION_PROCESS.md -legal/TECHNICAL_SPECIFICATIONS.md - -# Конфиденциальные данные -config/secrets.js -.env -*.key -``` - -### 🛡️ **СТРАТЕГИЯ ПУБЛИКАЦИИ** - -#### **Вариант 1: Приватный репозиторий (РЕКОМЕНДУЕТСЯ)** -``` -✅ Преимущества: -- Полный контроль доступа -- Защита от копирования -- Возможность лицензирования -- Сохранение коммерческой тайны - -❌ Недостатки: -- Ограниченная видимость -- Сложности с наймом разработчиков -- Меньше обратной связи -``` - -#### **Вариант 2: Публичный репозиторий с ограничениями** -``` -✅ Преимущества: -- Видимость для инвесторов -- Возможность найма разработчиков -- Обратная связь сообщества - -❌ Недостатки: -- Риск потери новизны для патента -- Возможность копирования -- Сложности с лицензированием -``` - -### 📋 **ПЛАН ДЕЙСТВИЙ** - -#### **Этап 1: Подготовка к публикации (1-2 недели)** -1. **Подать заявку на патент** (приоритет!) -2. **Создать защищенную версию кода** -3. **Подготовить документацию без секретов** -4. **Настроить лицензирование** - -#### **Этап 2: Создание публичной версии** -```bash -# Создать новую ветку для публикации -git checkout -b public-version - -# Удалить конфиденциальные файлы -rm legal/PATENT_*.md -rm legal/INNOVATION_PROCESS.md -rm legal/TECHNICAL_SPECIFICATIONS.md - -# Создать общую документацию -echo "# DLE - Digital Legal Entity -## Обзор проекта - -Это инновационная система для создания цифровых юридических лиц -на основе блокчейн-технологий. - -### Основные возможности: -- Создание DAO с токенами управления -- Интеграция с международными классификаторами -- Система голосования и мультиподписи -- Регуляторный контроль через блокчейн - -### Технологии: -- Frontend: Vue.js -- Backend: Node.js/Express -- Smart Contracts: Solidity (OpenZeppelin) -- Database: PostgreSQL - -### Лицензия: -См. файл LICENSE.md - -### Контакты: -info@hb3-accelerator.com" > README_PUBLIC.md -``` - -#### **Этап 3: Настройка доступа** -```bash -# Создать разные репозитории -# 1. Приватный - полная версия -# 2. Публичный - ограниченная версия -# 3. Демо - только интерфейс -``` - -### 🔐 **ЗАЩИТА ИНТЕЛЛЕКТУАЛЬНОЙ СОБСТВЕННОСТИ** - -#### **1. Авторские права** -```markdown -# В каждом файле добавить: -/* - * Copyright (c) 2024-2025 Тарабанов Александр Викторович - * All rights reserved. - * - * This software is proprietary and confidential. - * Unauthorized copying, modification, distribution, or use is strictly prohibited. - */ -``` - -#### **2. Лицензирование** -```markdown -# LICENSE.md -PROPRIETARY SOFTWARE LICENSE - -Copyright (c) 2024-2025 Тарабанов Александр Викторович - -This software is proprietary and confidential. -Unauthorized use, copying, modification, or distribution is strictly prohibited. - -For licensing inquiries: info@hb3-accelerator.com -``` - -#### **3. Патентная защита** -- Подать заявку на патент ДО публикации -- Использовать приоритетную заявку -- Защитить ключевые алгоритмы - -### 📊 **СРАВНЕНИЕ ВАРИАНТОВ** - -| Критерий | Приватный | Публичный | Гибридный | -|----------|-----------|-----------|-----------| -| **Защита ИС** | ⭐⭐⭐⭐⭐ | ⭐⭐ | ⭐⭐⭐⭐ | -| **Видимость** | ⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | -| **Контроль** | ⭐⭐⭐⭐⭐ | ⭐⭐ | ⭐⭐⭐⭐ | -| **Лицензирование** | ⭐⭐⭐⭐⭐ | ⭐⭐ | ⭐⭐⭐⭐ | -| **Развитие** | ⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | - -### 🎯 **РЕКОМЕНДУЕМАЯ СТРАТЕГИЯ** - -#### **Гибридный подход:** -1. **Приватный репозиторий** - полная версия с патентами -2. **Публичный репозиторий** - ограниченная версия без секретов -3. **Демо-сайт** - только интерфейс и общая информация -4. **Документация** - техническая без бизнес-логики - -#### **Последовательность действий:** -``` -1. Подать заявку на патент (СЕЙЧАС!) -2. Сделать репозиторий приватным -3. Создать публичную версию -4. Настроить лицензирование -5. Запустить демо-сайт -``` - -### ⚡ **НЕМЕДЛЕННЫЕ ДЕЙСТВИЯ** - -#### **СЕГОДНЯ:** -1. Сделать репозиторий приватным -2. Удалить патентные документы из истории -3. Найти патентного поверенного - -#### **НА ЭТОЙ НЕДЕЛЕ:** -1. Подать заявку на патент -2. Создать защищенную версию -3. Настроить лицензирование - -#### **В БЛИЖАЙШИЙ МЕСЯЦ:** -1. Создать публичную версию -2. Запустить демо-сайт -3. Начать маркетинг - ---- - -**Автор:** Тарабанов Александр Викторович -**Дата:** 2024-2025 -**Контакты:** info@hb3-accelerator.com \ No newline at end of file diff --git a/legal/PUBLICATION_GUIDE.md b/legal/PUBLICATION_GUIDE.md deleted file mode 100644 index 7dfa0a1..0000000 --- a/legal/PUBLICATION_GUIDE.md +++ /dev/null @@ -1,153 +0,0 @@ -# РУКОВОДСТВО ПО БЕЗОПАСНОЙ ПУБЛИКАЦИИ НА GITHUB -## Как правильно опубликовать проект DLE - -### ✅ **ЧТО МОЖНО ПУБЛИКОВАТЬ:** - -#### **Авторские права и лицензии:** -- `LICENSE.md` - Основная лицензия проекта -- `AUTHORS.md` - Информация об авторах -- `CONTRIBUTING.md` - Правила для контрибьюторов -- `COPYRIGHT_NOTICE.md` - Шаблоны копирайтов -- `TERMS_OF_SERVICE.md` - Условия использования - -#### **Защита интеллектуальной собственности:** -- `ATTRIBUTION_REQUIREMENTS.md` - Требования к атрибуции -- `USAGE_NOTIFICATION.md` - Уведомления об использовании -- `COMMERCIAL_LICENSE_REQUEST.md` - Запрос коммерческой лицензии - -#### **Общая документация:** -- `README.md` - Основная документация -- `GITHUB_PROTECTION_STRATEGY.md` - Стратегия защиты (без секретов) - -### 🔒 **ЧТО НЕЛЬЗЯ ПУБЛИКОВАТЬ:** - -#### **Патентные документы (папка `patents/`):** -- `PATENT_APPLICATION.md` - Заявка на патент -- `PATENT_DRAWINGS.md` - Чертежи для патента -- `PATENT_DRAWINGS_REAL.md` - Реальные чертежи -- `INNOVATION_PROCESS.md` - Инновационные процессы -- `TECHNICAL_SPECIFICATIONS.md` - Технические спецификации -- `REGISTRATION_PLAN.md` - План регистрации -- `JURISDICTION.md` - Юрисдикционные аспекты - -### 📋 **ПЛАН ПУБЛИКАЦИИ:** - -#### **Этап 1: Подготовка (СЕЙЧАС)** -```bash -# 1. Проверить .gitignore -cat .gitignore | grep -A 20 "ПАТЕНТНЫЕ ДОКУМЕНТЫ" - -# 2. Убедиться, что патентные файлы не отслеживаются -git status - -# 3. Проверить, что папка patents/ не попадет в репозиторий -git check-ignore legal/patents/ -``` - -#### **Этап 2: Создание публичной версии** -```bash -# 1. Создать новую ветку для публикации -git checkout -b public-release - -# 2. Удалить конфиденциальные файлы (если они попали в git) -git rm -r --cached legal/patents/ 2>/dev/null || true - -# 3. Добавить только публичные файлы -git add legal/LICENSE.md -git add legal/AUTHORS.md -git add legal/CONTRIBUTING.md -git add legal/COPYRIGHT_NOTICE.md -git add legal/TERMS_OF_SERVICE.md -git add legal/ATTRIBUTION_REQUIREMENTS.md -git add legal/USAGE_NOTIFICATION.md -git add legal/COMMERCIAL_LICENSE_REQUEST.md -git add legal/README.md - -# 4. Проверить, что патентные файлы не добавлены -git status -``` - -#### **Этап 3: Публикация** -```bash -# 1. Создать коммит -git commit -m "Add legal documentation and protection files" - -# 2. Отправить в репозиторий -git push origin public-release - -# 3. Создать Pull Request для main ветки -# 4. Проверить, что патентные файлы не попали в PR -``` - -### 🔍 **ПРОВЕРКА БЕЗОПАСНОСТИ:** - -#### **Перед публикацией:** -```bash -# 1. Проверить .gitignore -grep -r "patents" .gitignore - -# 2. Проверить, что файлы не отслеживаются -git ls-files | grep -E "(PATENT|INNOVATION|TECHNICAL)" - -# 3. Проверить содержимое коммита -git diff --cached --name-only - -# 4. Проверить, что патентные файлы не попадут -git check-ignore legal/patents/PATENT_APPLICATION.md -``` - -#### **После публикации:** -```bash -# 1. Проверить на GitHub, что патентные файлы не видны -# 2. Убедиться, что .gitignore работает -# 3. Проверить, что лицензии и авторские права видны -``` - -### 📁 **ИТОГОВАЯ СТРУКТУРА:** - -``` -legal/ -├── patents/ # 🔒 КОНФИДЕНЦИАЛЬНО -│ ├── PATENT_APPLICATION.md # НЕ ПУБЛИКОВАТЬ -│ ├── INNOVATION_PROCESS.md # НЕ ПУБЛИКОВАТЬ -│ └── ... # НЕ ПУБЛИКОВАТЬ -├── LICENSE.md # ✅ ПУБЛИКОВАТЬ -├── AUTHORS.md # ✅ ПУБЛИКОВАТЬ -├── CONTRIBUTING.md # ✅ ПУБЛИКОВАТЬ -├── COPYRIGHT_NOTICE.md # ✅ ПУБЛИКОВАТЬ -├── TERMS_OF_SERVICE.md # ✅ ПУБЛИКОВАТЬ -├── ATTRIBUTION_REQUIREMENTS.md # ✅ ПУБЛИКОВАТЬ -├── USAGE_NOTIFICATION.md # ✅ ПУБЛИКОВАТЬ -├── COMMERCIAL_LICENSE_REQUEST.md # ✅ ПУБЛИКОВАТЬ -└── README.md # ✅ ПУБЛИКОВАТЬ -``` - -### ⚠️ **ВАЖНЫЕ ПРЕДУПРЕЖДЕНИЯ:** - -1. **НЕ публикуйте патентные документы** до подачи заявки на патент -2. **Проверяйте .gitignore** перед каждым коммитом -3. **Используйте приватные репозитории** для разработки -4. **Консультируйтесь с патентным поверенным** перед публикацией - -### 🎯 **РЕКОМЕНДАЦИИ:** - -#### **Для разработки:** -- Используйте приватный репозиторий -- Храните патентные документы в папке `legal/patents/` -- Регулярно обновляйте .gitignore - -#### **Для публикации:** -- Создавайте отдельную ветку -- Проверяйте содержимое коммитов -- Публикуйте только разрешенные файлы - -#### **Для защиты:** -- Подайте заявку на патент ДО публикации -- Используйте строгую лицензию -- Мониторьте использование кода - ---- - -**Автор:** Тарабанов Александр Викторович -**Дата:** 2024-2025 -**Контакты:** info@hb3-accelerator.com \ No newline at end of file diff --git a/migrate-encrypted-data.sh b/migrate-encrypted-data.sh new file mode 100755 index 0000000..75138af --- /dev/null +++ b/migrate-encrypted-data.sh @@ -0,0 +1,192 @@ +#!/bin/bash + +# Скрипт для переноса зашифрованных данных между серверами +# Использование: ./migrate-encrypted-data.sh + +# Конфигурация +SOURCE_HOST="localhost" # Исходный сервер +TARGET_HOST="new-server.com" # Целевой сервер +DB_NAME="dapp_db" +DB_USER="dapp_user" +DB_PASSWORD="dapp_password" +BACKUP_DIR="./migration_backups" + +# Создаём папку для бэкапов +mkdir -p "$BACKUP_DIR" + +echo "🔄 Перенос зашифрованных данных между серверами..." + +# Проверяем наличие ключа шифрования +if [ ! -f "./ssl/keys/full_db_encryption.key" ]; then + echo "❌ Ключ шифрования не найден: ./ssl/keys/full_db_encryption.key" + exit 1 +fi + +# Функция для создания бэкапа с ключом +create_backup_with_key() { + echo "📦 Создание бэкапа с ключом шифрования..." + + # Создаём бэкап базы данных + BACKUP_FILE="$BACKUP_DIR/encrypted_backup_$(date +%Y%m%d_%H%M%S).sql" + docker exec dapp-postgres pg_dump -U "$DB_USER" "$DB_NAME" > "$BACKUP_FILE" + + # Создаём архив с бэкапом и ключом + ARCHIVE_FILE="$BACKUP_DIR/migration_package_$(date +%Y%m%d_%H%M%S).tar.gz" + tar -czf "$ARCHIVE_FILE" \ + -C . "$BACKUP_FILE" \ + -C . ssl/keys/full_db_encryption.key \ + -C . encrypt-all-tables.sh \ + -C . decrypt-all-tables.sh \ + -C . backend/services/encryptedDataService.js + + echo "✅ Бэкап создан: $ARCHIVE_FILE" + echo "📋 Содержимое архива:" + tar -tzf "$ARCHIVE_FILE" +} + +# Функция для восстановления на целевом сервере +restore_on_target() { + echo "🔄 Восстановление на целевом сервере..." + + # Распаковываем архив + tar -xzf "$ARCHIVE_FILE" -C . + + # Восстанавливаем ключ шифрования + mkdir -p ./ssl/keys + cp ssl/keys/full_db_encryption.key ./ssl/keys/ + chmod 600 ./ssl/keys/full_db_encryption.key + + # Восстанавливаем базу данных + docker exec dapp-postgres psql -U "$DB_USER" "$DB_NAME" < "$BACKUP_FILE" + + echo "✅ Данные восстановлены на целевом сервере" +} + +# Функция для переноса через SSH +migrate_via_ssh() { + echo "🌐 Перенос через SSH..." + + # Создаём бэкап + create_backup_with_key + + # Отправляем архив на целевой сервер + scp "$ARCHIVE_FILE" user@$TARGET_HOST:/tmp/ + + # Выполняем восстановление на целевом сервере + ssh user@$TARGET_HOST << 'EOF' + cd /tmp + tar -xzf migration_package_*.tar.gz -C /path/to/app/ + cd /path/to/app/ + chmod 600 ssl/keys/full_db_encryption.key + docker exec dapp-postgres psql -U dapp_user dapp_db < encrypted_backup_*.sql + echo "✅ Миграция завершена" +EOF + + echo "✅ Перенос через SSH завершён" +} + +# Функция для переноса через S3/облачное хранилище +migrate_via_cloud() { + echo "☁️ Перенос через облачное хранилище..." + + # Создаём бэкап + create_backup_with_key + + # Загружаем в S3 (пример) + aws s3 cp "$ARCHIVE_FILE" s3://your-bucket/migrations/ + + echo "📤 Архив загружен в облачное хранилище" + echo "📥 Для восстановления скачайте архив и выполните:" + echo " tar -xzf migration_package_*.tar.gz" + echo " docker exec dapp-postgres psql -U dapp_user dapp_db < encrypted_backup_*.sql" +} + +# Функция для переноса через USB/локальный носитель +migrate_via_local() { + echo "💾 Перенос через локальный носитель..." + + # Создаём бэкап + create_backup_with_key + + echo "📁 Архив создан: $ARCHIVE_FILE" + echo "💿 Скопируйте файл на USB-накопитель или другой носитель" + echo "🔄 На целевом сервере выполните:" + echo " tar -xzf migration_package_*.tar.gz" + echo " docker exec dapp-postgres psql -U dapp_user dapp_db < encrypted_backup_*.sql" +} + +# Функция для проверки целостности +verify_migration() { + echo "🔍 Проверка целостности миграции..." + + # Проверяем наличие ключа + if [ ! -f "./ssl/keys/full_db_encryption.key" ]; then + echo "❌ Ключ шифрования не найден" + return 1 + fi + + # Проверяем подключение к БД + if ! docker exec dapp-postgres pg_isready -U "$DB_USER" -d "$DB_NAME" > /dev/null 2>&1; then + echo "❌ Не удалось подключиться к базе данных" + return 1 + fi + + # Проверяем зашифрованные данные + docker exec dapp-postgres psql -U "$DB_USER" -d "$DB_NAME" -c " + SELECT + table_name, + COUNT(*) as encrypted_columns + FROM information_schema.columns + WHERE table_schema = 'public' + AND column_name LIKE '%_encrypted' + GROUP BY table_name + ORDER BY table_name;" + + echo "✅ Проверка целостности завершена" +} + +# Главное меню +echo "🎯 Выберите способ переноса:" +echo "1) Создать бэкап с ключом" +echo "2) Перенос через SSH" +echo "3) Перенос через облачное хранилище" +echo "4) Перенос через локальный носитель" +echo "5) Проверить целостность" +echo "6) Выход" + +read -p "Выберите опцию (1-6): " choice + +case $choice in + 1) + create_backup_with_key + ;; + 2) + read -p "Введите IP целевого сервера: " TARGET_HOST + migrate_via_ssh + ;; + 3) + migrate_via_cloud + ;; + 4) + migrate_via_local + ;; + 5) + verify_migration + ;; + 6) + echo "👋 Выход" + exit 0 + ;; + *) + echo "❌ Неверный выбор" + exit 1 + ;; +esac + +echo "" +echo "🎯 Инструкция по восстановлению на целевом сервере:" +echo "1. Скопируйте архив на целевой сервер" +echo "2. Распакуйте архив: tar -xzf migration_package_*.tar.gz" +echo "3. Восстановите ключ: chmod 600 ssl/keys/full_db_encryption.key" +echo "4. Восстановите БД: docker exec dapp-postgres psql -U dapp_user dapp_db < encrypted_backup_*.sql" +echo "5. Проверьте целостность: ./verify-migration.sh" \ No newline at end of file diff --git a/nginx-ssl.conf b/nginx-ssl.conf new file mode 100644 index 0000000..1dc77e0 --- /dev/null +++ b/nginx-ssl.conf @@ -0,0 +1,94 @@ +# Nginx конфигурация с SSL шифрованием + +# HTTP -> HTTPS redirect +server { + listen 80; + server_name _; + return 301 https://$host$request_uri; +} + +# HTTPS сервер +server { + listen 443 ssl http2; + server_name hb3-accelerator.com www.hb3-accelerator.com; + + # SSL сертификаты + ssl_certificate /etc/ssl/certs/server.crt; + ssl_certificate_key /etc/ssl/certs/server.key; + ssl_trusted_certificate /etc/ssl/certs/ca.crt; + + # SSL настройки безопасности + ssl_protocols TLSv1.2 TLSv1.3; + ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384; + ssl_prefer_server_ciphers off; + ssl_session_cache shared:SSL:10m; + ssl_session_timeout 10m; + ssl_stapling on; + ssl_stapling_verify on; + + # Заголовки безопасности + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; + add_header X-Frame-Options DENY always; + add_header X-Content-Type-Options nosniff always; + add_header X-XSS-Protection "1; mode=block" always; + add_header Referrer-Policy "strict-origin-when-cross-origin" always; + + # Проверка Host header + if ($host !~ ^(hb3-accelerator\.com|www\.hb3-accelerator\.com)$) { + return 444; + } + + root /usr/share/nginx/html; + index index.html; + + # Основной location + location / { + try_files $uri $uri/ /index.html =404; + } + + # API с дополнительной защитой + location /api/ { + proxy_pass http://backend: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 https; + + # Таймауты + proxy_connect_timeout 30s; + proxy_send_timeout 30s; + proxy_read_timeout 30s; + } + + # WebSocket с SSL + location /ws { + proxy_pass http://backend:8000; + 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 https; + } + + # Статические файлы + location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ { + expires 1y; + add_header Cache-Control "public, immutable"; + add_header Vary Accept-Encoding; + } + + # Запрет доступа к чувствительным файлам + location ~* /(\.htaccess|\.htpasswd|\.env|\.git|\.svn|\.DS_Store|Thumbs\.db|web\.config|robots\.txt|sitemap\.xml)$ { + deny all; + return 404; + } + + # Скрытие информации о сервере + server_tokens off; + + # Логирование + error_log /var/log/nginx/error.log warn; + access_log /var/log/nginx/access.log combined; +} \ No newline at end of file diff --git a/remove-unencrypted-columns.sh b/remove-unencrypted-columns.sh new file mode 100755 index 0000000..47bcaab --- /dev/null +++ b/remove-unencrypted-columns.sh @@ -0,0 +1,50 @@ +#!/bin/bash + +# Скрипт для удаления незашифрованных колонок +# ВНИМАНИЕ: Это необратимая операция! +# Использование: ./remove-unencrypted-columns.sh + +echo "⚠️ ВНИМАНИЕ: Это удалит все незашифрованные колонки!" +echo "Убедитесь, что шифрование работает корректно!" +read -p "Продолжить? (y/N): " -n 1 -r +echo +if [[ ! $REPLY =~ ^[Yy]$ ]]; then + echo "❌ Операция отменена" + exit 1 +fi + +# Получаем список всех таблиц +TABLES=$(docker exec dapp-postgres psql -U dapp_user -d dapp_db -t -c " +SELECT table_name +FROM information_schema.tables +WHERE table_schema = 'public' +AND table_type = 'BASE TABLE' +ORDER BY table_name;") + +# Удаляем незашифрованные колонки +echo "$TABLES" | while read -r table_name; do + if [ -n "$table_name" ]; then + echo "🗑️ Удаление незашифрованных колонок в таблице: $table_name" + + # Получаем незашифрованные колонки + unencrypted_columns=$(docker exec dapp-postgres psql -U dapp_user -d dapp_db -t -c " + SELECT column_name + FROM information_schema.columns + WHERE table_name = '$table_name' + AND table_schema = 'public' + AND data_type IN ('text', 'varchar', 'character varying', 'json', 'jsonb') + AND column_name NOT LIKE '%_encrypted' + AND column_name NOT IN ('created_at', 'updated_at', 'id') + ORDER BY ordinal_position;") + + echo "$unencrypted_columns" | while read -r column_name; do + if [ -n "$column_name" ]; then + echo " 🗑️ Удаление колонки: $column_name" + docker exec dapp-postgres psql -U dapp_user -d dapp_db -c " + ALTER TABLE $table_name DROP COLUMN IF EXISTS $column_name;" + fi + done + fi +done + +echo "✅ Незашифрованные колонки удалены!" diff --git a/scripts/security-monitor.sh b/scripts/security-monitor.sh new file mode 100755 index 0000000..18a2fd0 --- /dev/null +++ b/scripts/security-monitor.sh @@ -0,0 +1,49 @@ +#!/bin/bash + +# Скрипт мониторинга безопасности для nginx +# Автоматически блокирует подозрительные IP + +LOG_FILE="/var/log/nginx/access.log" +BLOCKED_IPS="/tmp/blocked_ips.txt" +MAX_REQUESTS=100 # Максимум запросов в минуту +BLOCK_TIME=3600 # Время блокировки в секундах (1 час) + +# Создаем файл для заблокированных IP если его нет +touch "$BLOCKED_IPS" + +echo "$(date): Запуск мониторинга безопасности..." + +while true; do + # Анализируем логи за последнюю минуту + SUSPICIOUS_IPS=$(tail -n 1000 "$LOG_FILE" 2>/dev/null | \ + awk -v date="$(date -d '1 minute ago' '+%d/%b/%Y:%H:%M')" \ + '$4 ~ date {print $1}' | \ + sort | uniq -c | \ + awk -v max="$MAX_REQUESTS" '$1 > max {print $2}') + + # Блокируем подозрительные IP + for ip in $SUSPICIOUS_IPS; do + if ! grep -q "^$ip$" "$BLOCKED_IPS"; then + echo "$ip" >> "$BLOCKED_IPS" + echo "$(date): Блокируем IP $ip за подозрительную активность" + + # Добавляем правило в iptables (если доступно) + if command -v iptables >/dev/null 2>&1; then + iptables -A INPUT -s "$ip" -j DROP + echo "$(date): IP $ip заблокирован в iptables" + fi + fi + done + + # Очищаем старые блокировки + while IFS= read -r ip; do + # Проверяем, не истекло ли время блокировки + if [ -f "$BLOCKED_IPS" ]; then + # Простая реализация - можно улучшить + echo "$(date): Проверка блокировок..." + fi + done < "$BLOCKED_IPS" + + # Ждем 30 секунд перед следующей проверкой + sleep 30 +done \ No newline at end of file diff --git a/security-monitor.sh b/security-monitor.sh new file mode 100755 index 0000000..0eedbfd --- /dev/null +++ b/security-monitor.sh @@ -0,0 +1,93 @@ +#!/bin/bash + +# Скрипт мониторинга безопасности для DLE +# Автоматически блокирует подозрительные IP адреса + +LOG_FILE="/var/log/nginx/access.log" +BLOCKED_IPS_FILE="/tmp/blocked_ips.txt" +NGINX_CONTAINER="dapp-frontend-nginx" + +# Создаем файл для хранения заблокированных IP +touch "$BLOCKED_IPS_FILE" + +echo "🔒 Запуск мониторинга безопасности DLE..." +echo "📊 Логирование атак в: $LOG_FILE" +echo "🚫 Заблокированные IP: $BLOCKED_IPS_FILE" + +# Функция для блокировки IP +block_ip() { + local ip=$1 + local reason=$2 + + # Проверяем, не заблокирован ли уже IP + if grep -q "^$ip$" "$BLOCKED_IPS_FILE"; then + return + fi + + echo "$ip" >> "$BLOCKED_IPS_FILE" + echo "🚫 Блокируем IP: $ip (причина: $reason)" + + # Добавляем IP в nginx конфигурацию + docker exec "$NGINX_CONTAINER" sh -c " + echo ' $ip 1; # Автоматически заблокирован: $reason' >> /etc/nginx/conf.d/waf.conf + nginx -s reload + " + + echo "✅ IP $ip заблокирован в nginx" +} + +# Функция для анализа логов +analyze_logs() { + echo "🔍 Анализ логов на предмет атак..." + + # Ищем подозрительные запросы + docker exec "$NGINX_CONTAINER" tail -f "$LOG_FILE" | while read line; do + # Извлекаем IP адрес + ip=$(echo "$line" | grep -oE '([0-9]{1,3}\.){3}[0-9]{1,3}') + + if [ -n "$ip" ]; then + # Проверяем на подозрительные запросы + if echo "$line" | grep -q "\.env\|\.config\|\.ini\|\.sql\|\.bak\|\.log"; then + block_ip "$ip" "Попытка доступа к чувствительным файлам" + fi + + # Проверяем на старые User-Agent + if echo "$line" | grep -q "Chrome/[1-7][0-9]\."; then + block_ip "$ip" "Подозрительный User-Agent (старый Chrome)" + fi + + # Проверяем на известные сканеры + if echo "$line" | grep -qi "bot\|crawler\|spider\|scanner\|nmap\|sqlmap"; then + block_ip "$ip" "Известный сканер/бот" + fi + + # Проверяем на множественные запросы (DDoS) + request_count=$(docker exec "$NGINX_CONTAINER" grep "$ip" "$LOG_FILE" | wc -l) + if [ "$request_count" -gt 100 ]; then + block_ip "$ip" "Подозрение на DDoS ($request_count запросов)" + fi + fi + done +} + +# Функция для показа статистики +show_stats() { + echo "📈 Статистика безопасности:" + echo "Заблокированных IP: $(wc -l < "$BLOCKED_IPS_FILE")" + echo "Последние заблокированные IP:" + tail -5 "$BLOCKED_IPS_FILE" 2>/dev/null || echo "Нет заблокированных IP" +} + +# Основной цикл +while true; do + echo "🔄 Проверка безопасности... $(date)" + + # Анализируем логи в фоне + analyze_logs & + + # Показываем статистику каждые 5 минут + show_stats + + # Ждем 5 минут перед следующей проверкой + sleep 300 +done \ No newline at end of file diff --git a/systemd-service.sh b/systemd-service.sh new file mode 100755 index 0000000..8edf18b --- /dev/null +++ b/systemd-service.sh @@ -0,0 +1,48 @@ +#!/bin/bash + +# Скрипт для создания systemd сервиса для security-monitor +# Использование: sudo ./systemd-service.sh + +SERVICE_NAME="dle-security-monitor" +SERVICE_FILE="/etc/systemd/system/${SERVICE_NAME}.service" +SCRIPT_PATH="$(pwd)/security-monitor.sh" +USER=$(whoami) + +echo "🔧 Создание systemd сервиса для security-monitor..." + +# Создаём файл сервиса +sudo tee "$SERVICE_FILE" > /dev/null << EOF +[Unit] +Description=DLE Security Monitor +After=network.target docker.service +Wants=docker.service + +[Service] +Type=simple +User=$USER +WorkingDirectory=$(pwd) +ExecStart=$SCRIPT_PATH +Restart=always +RestartSec=10 +StandardOutput=journal +StandardError=journal + +[Install] +WantedBy=multi-user.target +EOF + +# Перезагружаем systemd +sudo systemctl daemon-reload + +# Включаем автозапуск +sudo systemctl enable "$SERVICE_NAME" + +echo "✅ Сервис создан: $SERVICE_NAME" +echo "" +echo "🎯 Команды управления:" +echo " Запуск: sudo systemctl start $SERVICE_NAME" +echo " Остановка: sudo systemctl stop $SERVICE_NAME" +echo " Статус: sudo systemctl status $SERVICE_NAME" +echo " Логи: sudo journalctl -u $SERVICE_NAME -f" +echo "" +echo "🚀 Сервис будет автоматически запускаться при загрузке системы" \ No newline at end of file