Javascript фреймворк разработки бизнес приложений

    Мысль о своем фреймворке зародилась когда я еще активно работал с 1С. Хотелось иметь простую и открытую платформу для создания несложных бизнес приложений (простые системы учета, CRM и прочие). Не раз искал open source решения, но ничего подходящего не находил.

    Весной 2011-го открыл здесь полемику на тему свободного ПО в области систем учета. Решили даже делать HabraERP. Мне пришлось по состоянию здоровья выпасть на два месяца, а по возвращению я ожидаемо увидел что все заглохло.

    Хоть с HabraERP дальше обсуждений дело не пошло, я понял, что создание нужной мне платформы-фреймворка - возможно.

    Спустя неполных 10 лет я готов представить вам KateJS - открытый javascript фреймворк разработки бизнес-приложений.

    История

    Как создавался фреймворк

    Было понятно, что единым языком для клиента и сервера будет Javascript. Сначала была идея сделать сервер на Java c подключенным движком для JS, однако, я довольно быстро осознал, что нужную квалификацию даже для минимальной версии буду набирать неоправданно долго. Обратил внимание на NodeJS. Пройдя первый же туториал понял - это то что нужно.

    Фронт первой версии был на ExtJS - я взял то, что визуально напоминало учетные системы. На волне популярности NoSQL в качестве СУБД была выбрана CouchDB.

    Получившийся в результате монстрик слабо напоминал фреймворк и был ужасен во всех смыслах. Однако, на нем была разработана система расчета и учета заказов для отдела продаж, которая была внедрена и проработала несколько лет в небольшой типографии.

    Признав первую версию тупиковой, я взялся за вторую.

    Намучавшись с ExtJS, фронт решено было сделать полностью своим - на базе верстки от Bootstrap, jQuery и отдельных виджетов. Бэк чуть более структурировался, а вот СУБД осталась прежней.

    В процессе разработки были сформулированы и отработаны основные принципы: скорость, простота и удобство разработки приложений. Была проработана модульная структра.

    На второй версии фреймворка было сделано несколько приложений, два из которых - учет в компании по предоставлению автомобилей в аренду, автоматизация сбора отчетности почтальонов - работают до сих пор.

    Летом 2017го я ушел с насиженного места и погрузился в профессиональную вэб-разработку - устроился front-end разработчиком, а спустя некоторое время в рамках той же компании расширил свою квалификацию до fullstack. Первое время открывал что-то новое практически каждую неделю, а когда уже поднабрался опыта решил - третьей версии фреймворка - быть.

    В основу фронта лег React, бэка - Koa
    CouchDB и map/reduce - очень удобные и красивые штуки. Но не для учетных систем: "стандартная" задача как отбор и сортировка по нескольким полям одновременно превращается в головную боль. Хоть за несколько лет я уже привык к CouchDB, по объективным причинам решил взять реляционную СУБД: в фреймворке используется ORM Sequelize, проекты тестировались на MySQL и SQLite.

    Основу удалось собрать чуть менее чем за год. Фреймворк даже пригодился на работе - один проект был полностью сделан на нем, во втором - для "админки" была использована фронт часть. Была разработана и успешно внедрена программа учета для сети компаний доставки здорового питания.

    Фреймворк прошел обкатку и достиг уровня, когда его уже можно показать сообществу.

    Идея

    В основе фреймворка KateJS заложены три основных принципа:

    • Скорость. Фреймворк минимизирует временные затраты на сопутствующие вопросы и позволяет разработчику заниматься преимущественно бизнес логикой.

    • Простота. Несложная концепция и принципы разработки позволяют решать базовые задачи через пару часов изучения фреймворка.

    • Удобство. Модульность - в основе архитектуры. Легко использовать чужие модули и делать свои.

    Приложение со стороны клиента описывается клиентским приложением, которое определяет набор форм, каждая из которых представляет собой набор элементов (поле ввода, кнопка, надпись и т.п.) и кода, который описывает их поведения. Приложение со стороны сервера описывается серверным приложением, которое определяет набор сущностей: в общем случае - классов, к методам которых идет обращение с фронта и других сущностей.

    Особенности

    Генерация по структуре

    Самое сложное - начать. Но не в нашем случае. Как только мы определим и опишем структуру данных нашего приложения, мы сразу же получаем живой прототип.

    Допустим нам нужен учет доходов в разрезе статей. Нам нужны две сущности - статьи доходов и доходы.

    import Fields from 'katejs/lib/fields';
    
    const IncomeArticle = {
      fields: [
        {
          name: 'title',
          type: Fields.STRING,
        },
      ],
    };
    
    const Income = {
      fields: [
        {
          name: 'date',
          type: Fields.DATE,
        },
        {
          name: 'article',
          type: Fields.REFERENCE,
          entity: 'IncomeArticle',
        },
        {
          name: 'sum',
          type: Fields.DECIMAL,
        },
      ],
    };
    

    Синхронизируем БД и можем добавлять статьи доходов, вводить доходы и выбирать в них созданные статьи.

    картинка из руководства - там чуть больше сущностей и полей
    картинка из руководства - там чуть больше сущностей и полей

    Сущности могут иметь не только примитивные и ссылочные поля, но также и "табличные части", на которые также автоматически генерируется интерфейс в виде редактируемых таблиц.

    Императивное управление формами

    Реактивные формы это конечно хорошо, но старый добрый императивный подход проще и понятней. Работа с интерфейсом в KateJS похожа на работу с интерфейсом в визуальных средах: накидываем контроллов на форму и прописываем обработчики событий, в которых меняя свойство атрибута элемента, мы меняем его вид/поведения.

    export default class Register extends Form {
      constructor(args) {
        super(args);
    
        this.elements = [
          {
            id: 'email',
            type: Elements.INPUT,
            title: 'E-mail',
          },
          {
            id: 'password1',
            title: 'Password',
            type: Elements.INPUT,
            onChange: () => this.validate(),
            inputType: 'password',
          },
          {
            id: 'password2',
            title: 'Confirm password',
            type: Elements.INPUT,
            onChange: () => this.validate(),
            inputType: 'password',
          },
          {
            id: 'errorMessage',
            type: Elements.LABEL,
            title: 'Passwords do not match',
            hidden: true,
          },
          {
            id: 'register',
            title: 'Register',
            type: Elements.BUTTON,
            onClick: () => this.register(),
            fullWidth: true,
          },
        ];
      }
      validate() {
        // Доступ к элементу форм происходит через this.content[element_id]
        const valid = this.content.password1.value === this.content.password1.value;
        this.content.register.disabled = !valid;
        this.content.errorMessage.hidden = valid;
      }
      register() {
        // register logic
      }
    }
    

    Модульность - наследование

    Если вам нравится чье-то открытое решение, но хочется добавить в него что-то от себя, можно, конечно, взять код и поправить его в нужных местах. Но если оригинальное решение после этого доработали, а вам нужны и эти доработки и свои, то придется непросто.

    В KateJS формы, сущности и приложения несложно изменить, не меняя их исходный код. Можно отнаследоваться от оригинального класса и поменять его поведение. Пример. Элементы формы создаются в конструкторе в свойстве-массиве elements: чтобы изменить форму, достаточно внести в этот массив изменения. В автоматически сгенерированной форме IncomeItem элементы с id wallet и article идут друг под другом; чтобы расположить их в линию - объединим их в группу. Код класса формы нам недоступен, чтобы отнаследоваться напрямую, но сам класс доступен, поэтому воспользуемся класс-миксином: IncomeFormMixin

    
    export default ItemForm => class IncomeItem extends ItemForm {
      constructor(args) {
        super(args);
        this.elements.splice(1, 2, {
          type: Elements.GRID,
          elements: [
            { ...this.elements.get('wallet'), cols: 6 },
            { ...this.elements.get('article'), cols: 6 },
          ],
        });
      }
    };
    

    поле-массив elements дополнено методом get для получения элемента по его id

    AppClient

        ...
    
        this.forms = {
          ...this.forms,
          IncomeItem: IncomeFormMixin(this.forms.IncomeItem),
        };
    
        ...
    

    Конкретно такой способ не идеален, т.к. основывается на индексе элементов, но подход иллюстрирует.

    Сами приложения - клиентское и серверное - также описываются класс-миксинами, что автоматически позволяет их использовать как модули. К примеру, приложение AppUser добавляет сущности User, Role, формы авторизации и регистрации. Все что нужно для его подключения и добавления в ваше приложение этой функциональности - просто указать его в списке родителей.

    import { AppUser } from 'katejs-modules/lib/client';
    
    const AppClient = parent => class Client extends use(parent, AppUser) {
      ...
    }
    

    Точно также и ваше приложение автоматически становится модулем и может быть использовано другими разработчиками. Если вы его опубликуете.

    В комплекте к фреймворку идет несколько модулей (пользователи и роли - один из них), которые описаны в документации.

    Примеры

    Первым примером хочу привести "проект выходного дня" - Passstore - корпоративный менеджер паролей. Приложение хоть и синтетическое, но вполне может подойти компаниям, занимающимся разработкой на заказ со штатом 5+ человек. В приложении ведется список проектов, в каждом из которых указывается список участников с указанием их роли в проекте. Учетные данные - пароли - привязываются к проекту, с указанием ролей, которым разрешено эти данные просматривать. В итоге те, кому можно, видят то, что нужно.

    Приложение для простоты использует SQLite и готово к запуску сразу после установки зависимостей. Но можно его частично оценить без лишних телодвижений: по ссылке выше можно покликать readonly вариант.

    Сам проект Passstore сделан менее чем за день. Больше времени ушло на создание readonly демо версии и оформление сайта.

    Второй пример - Ассистент - простая система учета. Позволяет вести учет денежных средств, взаиморасчетов, товарных остатков, формировать на основе данных отчеты. Каких-либо отчетных форм для ИФНС приложение не содержит.

    Пардон за повтор картинки
    Пардон за повтор картинки

    Развернуть приложение несложно - в репозитории есть базовая информация по настройке. Если планируете дорабатывать - лучше использовать его как модуль: в этом случае, при появлении обновлений достаточно будет просто поставить свежий пакет.

    Если вам интересна учетная система как пользователю - напишите мне в личку - скину доступ в развернутый вариант.

    Итого

    К фреймворку я подготовил документацию, включающую небольшое руководство: создание системы учета личных финансов. Документация и исходники доступны по ссылкам на KateJS.ru

    Фреймворк, модули, Ассистента я развиваю в свободное от работы время. Буду рад, если фреймворк придется вам по душе и вы решите что-нибудь реализовать на нем. По мере возможности готов отвечать на вопросы и исправлять недочеты.

    Если у вас появятся идеи по развитию самого фреймворка или, например, Ассистента - пишите - обсудим.

    Похожие публикации

    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама

    Комментарии 24

      +4
      Вы молодец конечно, я не буду говорить о том что это 100500 фреймворк, но вот до публикации не мешало бы написать тесты
        0
        Тесты, возможно, будут следующим шагом развития фреймворка.
        0
        Интересно. Надо попробовать на выходных. С учетом, что JS я сторонился долгое время.
          +1
          Начало хорошее. Правда пока в статье о ссылочности, формах и концепции «документ».

          Вижу в доках, что есть какая-то реализация регистров, как промежуточных данных для отчетов. Не очень понятна их реализация (ведь в 1с это реально 2 таблицы: итогов и движений, которые еще довольно хитро объединяются в процессе запроса к виртуальным таблицам: умеют часть выбирать из итогов, часть добирать из движений, причем с той стороны, с которой предположительно меньше данных).

          А также 1с — это сильно сдвинутая в аналитику система, поэтому в ней есть язык запросов, который упрощает выборку данных, а также системы отчетов, позволяющие быстро их делать. Сейчас в доках отчеты статичны. Это пока отчет лишь по 1 сущности. И, судя по коду, отчет выполняет агрегацию на клиенте — и это тупиковый путь, т.к. требует прокачки очень большого числа данных между сервером и клиентом. Собственно, отчасти таким путем работала 1с7.7 и это убивало ее производительность.
            0
            Регистры в KateJS на текущий момент на самом деле довольно простые. Таблица одна. На умеренных объемах данных этого достаточно. Будут большие объемы — будет повод заняться оптимизацией.

            Сложной аналитической системы тоже нет: данные агрегируются так как решит разработчик. бОльшую часть можно сделать силами СУБД. Своего языка запросов нет — используется api от sequelize или прямые SQL запросы.

            Систему автоматизации завода на 10к сотрудников на KateJS я бы делать не рекомендовал. А специфический учет для ИП на УСНО — вполне.
              0

              добавить таблицу итогов и виртуальную таблицу выборки итоги + движения с последнего подсчета итогов это же вопрос нескольких часов. Если вы занимаетесь разработкой этой вещи несколько лет — то повторить хотя бы структуру хранения и получения данных для основных объектов 1с вполне можно было бы. А так молодец, думаю многие думали о том же(я в их числе) и даже начинали что-то делать, чтобы избавить разработку от бесконечного бойлерплейта и привести ее к лаконичности и основательности 1с, но немногие доводили до какого то работающего решения.

            +1
            Вот все хорошо, начнешь пользоваться, напишешь систему, запустишь ее, будет работать год, а то и два, а потом решишь добавить что-то или обновить, а вы бах и забросили её уже и домен не продлили, и нет больше ни проекта, ни документации, переписывай на новом фреймворке. почему не делаете сайт и доку на github pages? тем более у вас на jekyll вроде генерится все
              0
              Оно все как раз на github pages, только да, на своих доменах. Исходники и фреймворка и доки тоже на github.
              На счет перевода со своего домена на домен github-а — подумаю.
              0

              Что б не соврать, я пытался запилить 1С с 1999года. Раза три. Кстати, тоже на JavaScript. Но безуспешно. 1С это 1С и ее сила в маркетинге.


              Надеюсь у Вас все получится. Из своих ошибок скажу, что нужны не примеры, а внедрения. Т.е. нужно сразу искать компанию (и покрупнее) где Вы переведете все с 1С на свою платформу. Успешно.


              Плюс, если серьезно задумались, нужны конверторы бд.

                0
                Мечты «запилить 1С» остались далеко в прошлом. Трансформировались в «сделать удобный инструмент для создания учетных и не только систем».

                Как уже говорил — на highload не замахиваюсь, целевая аудитория — малый бизнес.
                  +2

                  Так проблема в том, что малому бизнесу это не нужно.


                  Ему нужно бизнес делать по основному направлению. И он хочет иметь минимум проблем с учетом. Тем более с его допиливанием под изменяющиеся требования законодательства.


                  Плюс, малый бизнес использует оутсорс учета. Т.е. не нанимает бухгалтера, а платит ему за его услуги по мере необходимости. Как думаете, бухгалтеру нужен новый framework?


                  Так вот, 1С дает не систему, а экосистему для бизнеса. Где он может потреблять то, что ему нужно по мере развития. Дает методолгическую и юридическую поддержку в форме готовых систем.


                  Что касается запилить CRM на коленке, то это, на самом деле, не просто.


                  Взрослая CRM также должна встраиваться в ИТ ландшафт. Иметь готовые интерфейсы с учетным системам, системам взаимодействия с клиентом и т.п.


                  Это сложная задача и для нее есть готовые, развитые CRM системы.


                  CRM аля телефонный справочник, как грязи в Интернет. Там тоже ничего из предложенного не нужно.


                  Итого? Если Вы хотите серьезно продвинуть свою платформу, необходимо найти полигон для реального внедрения.

                    0
                    Тут смотря что считать учетом. Если речь про отчетность для ИФНС, то да, малому бизнесу проще это отдать на аутсорс. Если бизнес прям совсем-совсем малый, то и любой другой учет ему не нужен — предприниматель и так знает сколько денег у него в бумажнике. Но как только он подрастает и начинает нанимать сотрудников — то тут уже минимальная система учета ему становится необходимой как минимум для контроля.
                      0

                      И? Почему он обратит внимание на Ваш фреймворк? Бухгалтера как были обучены 1С так и остались.

                        0
                        Для ведения учета в простой системе бухгалтер не нужен — нажимать на кнопки может администратор/менеджер.
                        Предприниматель на фреймворк, разумеется, внимание не обратит. Но разработчик, которому он закажет несложную систему учета — вполне может.
                          0

                          Предприниматель действует не так. Он ищет готовое решение. Спрашивает у коллег. И действует по самому кратчайшему пути. А он, как известно — 1С.


                          Если же, вдруг, потребуется сделать то, что нет у 1С, он обратится к… франчайзе. Т.к. он знает что такое 1С. И они выберут 1С. Допилят бухгалтерию и будут его успешно доить еще года три.


                          Покажите, почему предприниматель пойдет другой дорогой?


                          Но даже, если и будет такой случай. То пойдет он во фриланс. И кого он найдет? Человека знающего Вашу платформу? Нет. Кого угодно, только не ее. Т.к. в ней нет ценности для разработчиков. Ему предложат сделать на том же реакте, только с нуля. Если не на JQuery. Потому, что он не захочет СТОЛЬКО денег платить разработчику на реакте.


                          Я неспроста в первом посте сказал об ошибках. Я этот путь уже прошел. И с малым и средним бизнесом. Только заказ и внедрение. А для этого Вам потребуется продать не фреймворк а продукт. И вот тогда… можно будет поведать миру как все стало гоооораздо лучше чем было. И как бизнес получил все блага за 5 минут.


                          Именно это заставит серьезно смотреть на фреймворк.

                            0
                            Спасибо за развернутые ответы.
                            Фреймворк для меня это не цель, а средство. Как уже упоминал, он развивался не в вакууме, а на конкретных проектах, которые были доведены до внедрения.
                            И далее будет какой-нибудь проект, который, возможно, выльется в полезное решение, по которому, возможно, будет статья о том, «как все стало лучше чем было»
                0
                Интересно. А есть ли (или планируются ли) какие-то механизмы загрузки/выгрузки информации в сторонние форматы? Хотя бы Excel и csv файлы на загрузку и csv/html на выгрузку?
                  +1
                  Есть модуль import который позволяет импортировать сущности из csv файлов. Полезно, к примеру, если нужно загрузить список клиентов в систему.

                  Экспорта нет — не очень понятно для чего он вообще нужен. БД переносить лучше через дамп.
                  Но в любом случае — сделать генерацию csv файлов — дело недолгое.
                    +1
                    Экспорт нужен чтобы делать аналитику во внешних программах, как минимум в том же Эксель.

                    Про импорт понял, спасибо.
                  0

                  Конкурировать с 1С в плане создания бизнес объектов, имхо, дело гиблое. Слишком много воды утекло со времен 6.0 и 7.7, слишком много ресурсов вложено во фреймворк имени "1С Конфигуратор". А вот дать инструмент для собственного UI на базе объектной модели 1С — очень даже может взлететь! Я бы задумывался о бэке, как о мидлваре между web/http сервисами 1С и фронтом на js. React для 1С — вот здесь есть перспективы, кмк. На мой взгляд, 1С в ближайшем будущем не сможет избавиться от своего неоднозначного "Такси" и в это сторону можно "копать".

                    0
                    1С Конфигуратор признан уже не модным. Копают в сторону EDT на Eclipse.
                    Интерфейс управляемых форм — как-то неудачно вышло, хотя идея отличная.
                    0

                    Может неудачно выразился, под фреймворком имени "1С конфигуратор" подразумевал реализованных платформой объектную модель абстрактных классов, доступную через Конфигуратор или EDT, не саму IDE.

                      +1

                      Вот не вижу тут фреймворка для бизнес приложений. Выглядит как одна из headless cms. Keystonejs к примеру

                        0
                        Попробуйте реализовать от и до, допустим, систему учета домашних финансов на Keystonejs. Если это там вообще возможно — сравните с туториалом по KateJS.

                        Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                        Самое читаемое