.. NodaLogic documentation master file, created by sphinx-quickstart on Wed Nov 5 07:29:33 2025. You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. Архитектура платформы =========================== NodaLogic - это распределенная система, которая может быть как централизованной с сервером и клиентами- мобильными устройствами и веб клиентами, так и децентрализованной, в том плане что логика «узлов», основных кирпичиков системы, может выполняться как на сервере, так и на устройствах-клиентах, серверов может быть много, а каждый клиент в свою очередь может быть также сервером. Основа решений – «узел». Это объект, который одновременно является хранилищем данных и имеет исполняемые методы. Это такой самостоятельный микросервис, хранящий данные и готовый взаимодействовать с другими узлами. Из узлов строится фронтовое решение и бекенд (границы фронт/бек размыты в NodaLogic, так как «сервер там, где в данный момент выполняется узел») . В каком-то смысле, это как нейрон, имеющий вход/выход и веса. Узлом может быть такие сущности как «задача», «документ», «строка документа», любая другая бизнес сущность – склад, товар, ячейка. И виртуальные сущности – «остаток товара в ячейке», например. .. image:: _static/node.png :scale: 55% :align: center Данные узла хранятся в _data – это и оперативная и долговременная память. _data – это JSON-совместимая структура данных. Узел имеет ссылку на класс. Сам класс задает поведение узла, его обложку, описывает события (связь событий и методов). Данные из интерфейса и обработчиков попадают в _data, и наоборот хранимые в _data данные отображаются в интерфейсе. По сути - это обычная JSON-ориентированная NoSQL. На клиенте(мобильном устройстве или веб-клиенте) при пользовательском вводе возникает событие onInput/onInputWeb и если на него есть какой то метод-обработчик, то он обработает эти данные, сохранит, возможно вызовет другие методы или отправит другим узлам (путем вызова их методов). На картинке ниже ситуация: пользователь нажал на кнопку - сработало событие onInput, на которое есть подписка в виде метода Input (python) - метод python (на мобильном устройстве) выводит тост(сообщение) с переменной input1, в которой хранится ввод из поля ввода. .. image:: _static/event.png :scale: 55% :align: center На сервере (если узел имеет серверные методы) узел можно представить как микросервис. Когда вы создаете класс, автоматически создается REST API класса по которому можно обратиться как к классу так и к его объектам - узлам посредством HTTP-запросов. Если при этом узел имеет серверные методы, то их также можно выполнять удаленно как из внешней системы так и с мобильных клиентов. .. image:: _static/api.png :scale: 55% :align: center Таким образом, формально **узел – это данные _data + класс (описывающий методы и поведение узла в системе)**. С одной стороны узел - это единица данных, как запись в NoSQL, с другой стороны - микросервис. Вот пример класса узла в python (для мобильного клиента). Видно что он наследуется от Node и имеет какие-то свои методы. Метод Open отвечает за отрисовку, в Input - за обработку ввода. .. code-block:: Python class MyClass(Node): def __init__(self, modules, jNode, modulename, uid, _data): super().__init__(modules, jNode, modulename, uid, _data) """Class MyClass""" def Open(self, input_data=None): self.Show( [ [{"type":"Input","id":"input1","caption":"input 1","value":"@input1"}], [{"type":"Button","id":"button1","caption":"Get result"}] ] ) return True,{} def Input(self, input_data=None): toast(self._data["input1"]) return True,{} В данный момент доступны 2 типа узлов: * Обычный узел (Узел данных) с поведением, описанным выше * Пользовательский процесс – узел, существующий в одном экземпляре, который создается в интерфейсе клиента для выполнения каких то пользовательских задач. В отличии от узла – его не надо создавать или передавать, он создается при загрузке конфигурации Классы, в свою очередь хранятся в конфигурации – JSON структуре или файле. Таким образом конфигурация – это набор классов узлов. Но не только – в конфигурации также задается настройка решения в целом – общие события, разделы и так далее. Т.е. конфигурация - это JSON-хранилище классов узлов, обработчиков (в виде base64-кодированного python-файла) и общих настроек. Подробнее о структуре этого файла в разделе "Структура конфигурации" .. image:: _static/repo.png :scale: 55% :align: center На клиенте может быть загружено одновременно любое число конфигураций в «репозиторий конфигураций» и все они активны одновременно, как для пользователя так и друг для друга. Просто классы размещаются к правило в своих разделах и не мешают друг другу. На сервере такой же принцип – каждая конфигурация существует сама по себе, каждый класс имеет свой API, каждый узел живет сам по себе. Узел может работать на сервере и на клиенте или и там и там одновременно. При этом как правило, он работает локально – на той машине где выполняется, но может обращаться к узлу на сервере, о чем далее Вот сценарий *пассивного использования узла в оффлайновом решении* (как объекта данных) 1. Узлы сбрасываются HTTP-запросом на сервер. Класс в конфигурации на сервере автоматически имеет свой REST-API. По нему можно создавать узлы, запрашивать данные, выполнять методы. 2. Узлы отправляются клиентам через механизм комнат (Rooms) Устройства объединяются в rooms через WebSocket и всегда готовы принять изменения по узлам как мессенджеры принимают сообщения 3. Узел на устройстве работает самостоятельно оффлайн. Связь с сервером не нужна. На клиенте выполняется UI/UX, накапливаются данные 4. По необходимости данные отправляются в узлы на сервере, путем вызова их методов либо просто _data в таком же узле на сервере замещается _data узла с клиента 5. Внешняя система через тот же REST-API забирает данные. Сценарий, где сервер играет свою роль почти такой же, но имеет важное отличие – бизнес логика выполняется на сервере. Разберем это на примере WMS-решения: 1. Учетная система отправляет распоряжения на сервер NodaLogic – допустим это какие то накладные системы – заказы клиентов, накладные от поставщиков. 2. Узлы на сервере, которые являются генераторами задач, порождают узлы-задачи для клиентов-устройств и регистрируют их в Room, они попадают на устройство 3. На устройстве пользователь выполняет задачи, данные о фактическом выполнении сразу поступают на сервер (по сути онлайн-режим). На сервере выполняются учетные процессы, такие как вычисление остатков товаров например. 4. По выполнению либо сервер шлет HTTP-запрос во внешнюю систему, либо система обращается к узлу-генератору задач и забирает выполненные задачи (по сути-фактические данные). Также она может обратиться к учетному узлу и запросить например остатки в ячейках И также могут быть сценарии *вообще без сервера*, где просто создается мобильное решение, в котором узлы отправляются на сервер через rooms либо вообще через файлы. Либо вообще не используются узлы данных и это просто мобильное решение. Таким образом, система может быть просто конструктором мобильного клиента - фронта. Резюмируя все вышесказанное, можно сказать что узел – это некий самостоятельный объект, решение – это набор классов, а система будь то сервер или клиент - рой объектов, которые могут взаимодействовать между собой. А клиентское приложение – это «плеер» узлов, в то время как узлы доставляются в него в режиме мессенджера (или например просто через файлы через почту или другие мессенджеры), порождаются пользователем или другим узлами. Это своеобразное развитие идеи suip-файлов в SimpleUI https://uitxt.readthedocs.io/ru/latest/suip.html