Как стать автором
Обновить

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

Кирилл, классная штука! Удачи в реализации!!)

Спасибо)

Правильно ли я понимаю, что вся логика вручную пишется на FunQL + TypeScript ? Или есть визуальный редактор как например в Оракл Апекс, мышкой клик - клик и готово -) ?

Всё верно. Визуальный редактор у нас в планах, но идея - дать максимальную гибкость за счёт простого, но кода.

Это очень прикольная идея. Круто, что можно на лоу коде такое реализовать. Всегда связку сервисов используем трелло, асана с гугл таблицами, а тут все в одном. Удобно)

Выглядит очень прикольно и минималистично.

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

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

Мы потестили прямо на демо инстансе, и да, вы правы, если две таски зациклить, то фронт не понимает что происходит и вешает вкладку))
Спасибо за баг! Садимся чинить

Код, который всё сломает, если есть зацикленные записи 

SELECT
	subject,
	parent_task @{ 
    	tree_parent_ids = true 
    }
FROM
	pm.tasks

И результат 🥲


Оглавление со ссылками на разделы добавим, спасибо за совет!

Выглядит интересно, спасибо!

Вопрос: есть Airtable и Notion, на которых можно собрать схожей сложности базы/формы/графики в несколько кликов. Какая цель у нового инструмента? Какую дополнительную пользу он может принести по сравнению с имеющимися?

Да, Airtable и Notion можно и даже нужно использовать для этого, но как только количество записей в таблице будет больше 50к, то уже придется искать другое решение.

У нас есть ребята, которые хранят десятки миллионов записей в озме и все летает. Надо только индексы правильно настроить.

Спасибо!

И еще вопрос вдогонку
Как обеспечивается безопасность сервиса? Планируется ли аудит безопасности? И возможно ли использовать его как self-hosted решение?

Как обеспечивается безопасность сервиса?

Авторизация сейчас на Keycloak. Чуть позднее запустим багбаунти. Может быть утром чуть больше технических деталей Николай сможет добавить к этому ответу.

Планируется ли аудит безопасности?

Да, планируем, но позднее.

возможно ли использовать его как self-hosted решение?

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

На моменте с FunQL закатил глаза: "О боже, и тут без собственного языка не обошлись". То, что это собственный язык, к сожалению, тоже не сразу очевидно (ссылка с документацией на домен ozma.io намекает, но, кажется, лучше это явно проговорить). Как я понял собственный язык нужен в основном из-за атрибутов (кстати, пояснение, как аттрибут выглядит синтаксически, следует заметно позже нескольких примеров запросов).

Для такой тяжеловестной абстракции, как собственный язык, хочется сразу увидеть рационализацию необходимости такого решения. А точно ли нельзя было сделать на чем-то существующем? Нельзя ли было сделать какую-то мета-таблицу, где в специальной колонке указывался бы тип запроса? (который @type=’board’, @type=’form’)

Или чтобы это вообще был не SQL, а ЯП общего назначения? SQL это же про данные, а не логику. А то получается, что мы GUI пытаемся на SQL нарисовать. Короче, да, почему тут SQL я не очень понял. (не отрицаю что мое непонимание возможно исходит от слабого познания SQL. С SQL мне мало приходилось работать)

Или чтобы это вообще был не SQL, а ЯП общего назначения?

PGSQL хорошо расширяется. Вот и расширили до генерации контента и данных.
Вполне логично.

Согласен, про язык можно было рассказать чуть больше. Попробую это сделать здесь.

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

Потом язык уже оброс своими фичами, которые специфичны для базы: например, оператор =>, который позволяет обходиться без JOIN, и операции с наследованием таблиц (которое у нас реализовано по-другому, чем в самом PostgreSQL). При этом мы стараемся держаться максимально близко к изначальному SQL - он зачастую хорошо известен целевой аудитории продукта, разработчикам (даже начинающим) бизнес-приложений. Хочется, чтобы они могли понять идею атрибутов за пару часов и уже эффективно работать.

При этом абсолютно верно, что данные и отображение мешать - это в целом плохой тон, и мы тут именно что рисуем GUI на SQL. Тут две мысли. Во-первых, на практике для большинства форм и таблиц это кажется приемлемым решением, потому что "логики" в запросе, как таковой, почти нет -- если убрать все атрибуты, то это простой SELECT с возможными WHERE по нескольким параметрам, и с ORDER BY, который скорее уже часть отображения. Такие запросы составляют большую часть разработки бизнес-приложений.

Во-вторых, мы хотим реализовать вызов user view (они же как функции) изнутри других user view, и написать гайдлайн, в котором будем советовать для любых нетривиальных запросов разделять так данные и отображение. Условно, один сложный запрос без атрибутов, и один или несколько, которые делают простой SELECT из него и только добавляют нужных опций (или дополнительно его фильтруют, скажем). Это всё в планах.

Про ЯП общего назначения: не хотелось давать возможность писать произвольный код внутри запроса. SQL тут хорош как раз тем, что он (в изначальном виде) только про данные. Все атрибуты у нас, как и сам результат запроса, декларативны - это либо значения, либо формулы. Поэтому в итоге выходит, что весь UI задан набором таких значений и формул. Это, с одной стороны, ограничивает разработчика (можно было бы дать возможность, скажем, писать UI на JS, и разрешить вообще что угодно). С другой -- для большинства отображений это повышает скорость разработки и читаемость кода. Например. SELECT balance @{ cell_color = CASE WHEN balance < 0 THEN 'red' ELSE 'green' } - тут сразу понятно, что выбирается и какая логика раскраски ячеек. Ну и наконец, это позволяет нам гораздо свободнее внедрять различные оптимизации и улучшения в интерфейс, чем если бы возможен был произвольный код на любом уровне.

Надеюсь, идея стала понятнее!

Прекрасная идея и решение.

Вопросы (много):

База данных

  1. Можно ли позже менять схему базы: таблицы, колонки?
    Насколько сложно, если данные уже есть?

  2. Каким образом генерятся скрипты модификации данных?
    Можно ли вмешаться процесс генерации скрипта?

  3. Можно ли менять несколько записей дочерней таблицы одновременно?

Пользовательский интерфейс:

  1. Можно ли расширить библиотеку UI controls?

  2. Как расширить существующий UI control (например, добавить свойстов) или добавить новый (например редактор диаграмм)?

  3. У вас данные и VIEW разделены, или FunQL генерит все вместе, представление, логику фронта и данные?

  4. Как происходит обновление данных в форме - обновляются только данные, или перестраивается View + Data ?

  5. Есть ли в планах UI designer именно как дизайнер, а не как код ?

  6. Для каждого UI контрола есть ли в планах завести свою формочку для упрощенной настройки, сместо редактирования кода?

Про базу. На всякий случай: фронт и базу я тут буду различать, потому что базой можно пользоваться отдельно:

  1. Да, схемы, таблицы и колонки произвольные везде, кроме схемы public и автоматического числового id во все таблицы (его тоже есть планы не требовать, но потом);

  2. Поправьте, если не про то. Логика модификации данных не генерится из SELECTов, а сделана хитрее: в запрос внутри вставляются доп. колонки, и для каждой ячейки из запроса по API возвращается информация, из какой она реально записи. Фронт использует эту информацию, чтобы давать редактировать почти любые поля. Про вмешательство не понял, можно пример?

  3. У базы есть вызов /transaction, куда можно передавать произвольный список изменений. На уровне фронта раньше было явно, сейчас нет - пользователям оказались непонятны явные гранзакции. Про дочернюю таблицу не понял, уточните?

Про интерфейс:

  1. Да, по сути графики из статьи - и есть произвольные контролы на форме. В iframe контрола прилетают данные из ячейки, и есть вызовы, чтобы данные менять;

  2. Расширять нельзя, не придумали пока, как - есть только разные атрибуты для настройки. Новый можно, как в (1);

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

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

  5. Да, планируется позже. При этом, скорее всего, в нём нельзя будет собрать совсем произвольный запрос, но всегда можно редактировать код.

  6. Хорошая мысль, потому что кажется, что такое можно сделать отдельно от (5), чуть ли не всплывающее окошко из редактора кода. Подумаем.

База

Про вмешательство не понял, можно пример?

INSERT/UPDATE statement генерится автоматически, на базе какого-то шаблона/скрипта.
Допустим мне нужно вставить свою логику в подготовку данных на серверной стороне (не на клиенте, чтоб избежать шаловливые ручки).
Причем, речь не идет о SQL триггере, который может изменить данные позже. Речь именно о генерации скрипта и вмешательстве в данные перед выполнением запроса.

Про дочернюю таблицу не понял, уточните?

Допустим, в форме редактируется основная таблица и вложенный редактируемый список, реализованный на стороне базы как дочерняя таблица.
Такая возможность сейчас есть?
Если есть, редактирование дочернего списка реализовано как одна транзакция, вместе с изменением parent record, или как масса отдельных?

UI

В iframe контрола прилетают данные из ячейки, и есть вызовы, чтобы данные менять;

У вас все UI элементы реализованы в отдельных iframe?
Спрашиваю т.к. iframe имеет ограничения.

Да, планируется позже. При этом, скорее всего, в нём нельзя будет собрать совсем произвольный запрос, но всегда можно редактировать код.

Чтоб снизить затраты на отладку и поддержку UI, может есть смысл формировать запрос из кусочков, которые формируются для каждого UI контрола.
UI контролы, в свою очередь, конфигурить через UI формы.
Тогда пользователю легче настраивать свойства контролов, а вам меньше ошибок т.к. авто-генерация FunQL на базе контрол-форм проще в отладке и надежнее в поддержке.

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

Удачи

База:

  1. Да, INSERT/UPDATE генерятся автоматически. Чтобы делать операции сложнее, чем в триггерах, и в одной транзакции, есть actions. Это примерно хранимые процедуры, но на JS и с нашим API. В них можно передавать произвольные штуки из фронта, и они могут возвращать, например, отображение, на которое после выполнения нужно перейти. Есть ещё несколько идей для похожей гибкости, например, виртуальные таблицы (тоже самое, что VIEW с INSTEAD OF-триггерами в Постгресе).

  2. Про дочернюю таблицу: да, так можно и сейчас всё будет в рамках одной транзакции. Про это мы ещё думаем -- пользователям тяжело работать "транзакционно", они привыкли, что отредактированное просто сразу сохраняется. Видимо, будем делать опциональную панель "Изменения" с кнопкой "Применить", которую можно будет включать атрибутом.

UI:

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

  2. Да, такие же мысли. Это хочется совместить с некоей "схемой" атрибутов, которая будет проверяться на стороне базы - чтобы ловить опечатки и тому подобные ошибки. Сейчас атрибуты не проверяются никак, кроме как глазами в UI "что всё работает".

Про аудиторию: кроме MVP хочется попробовать стать и платформой для
разработки бизнес-приложений. Предположение, что наша гибкость даёт возможность
реализовывать сложные проекты, а цена разработки и лицензии при этом ниже, чем у
гигантов навроде MS CRM. Проблему с техническим порогом вхождения стараемся
решать близостью FunQL к SQL, и использованием стандартного JS в остальных
местах. И ищем вендоров, которым интересно нас внедрять, чтобы внедряли не сами
компании.

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

Спасибо!

База

Да, INSERT/UPDATE генерятся автоматически. Чтобы делать операции сложнее, чем в триггерах, и в одной транзакции, есть actions.

Вы планируете ERD дизайнер для сложных VIEW и INSERT/UPDATE операций?
Может не рисовать таблицы в дизайнере, но хотя-бы отображать таблицы и связи.

Про визуальный редактор (дизайнер) для запросов или конструирования бизнес-процессов мы думали, планируем попробовать реализовать его в будушем. Но сейчас всё-таки делаем упор на код.

Касательно визуального отображения, например, связей между таблицами - это можно реализовать через iframe-ы. Мы как-то в качестве эксперимента делали такой граф связей для одного из проектов. Думаем его еще немного докрутить и добавить в публичные инстансы и admin схему, чтобы разработчики использовали для своих нужд.

а можно ли в этом low-code как-то все-таки разрабатывать как разработчик? то есть есть ли low-git и можно ли как-то организовать low-deploy? ))

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

Есть возможность выгрузить схемы целиком в архив, где вся схема в YAML, а весь код -- в отдельных файлах. Потом её можно загрузить назад. Вот тут подробнее: https://wiki.ozma.io/ru/administration/save_restore. Страница сохранения-загрузки пока прикручена сбоку ¯\(ツ)/¯ Ну и по API можно дёргать, у нас партнёр написал себе скрипты для деплоя в одну команду.

В будущем хотим сделать как раз git, то есть к каждому инстансу привязать репу, которая синкается со схемами в базе. Идея, что свои модули люди смогут выкладывать в открытый доступ на тот же GitHub, и свои собственные мы хотим выложить так же.

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

Да, гибких продуктов на рынке сейчас действительно много, и если они успешно решают задачу, то тут без вариантов лучше использовать именно их)

А Озмой мы старались (и упорно продолжаем стараться) закрыть какие-то боли, которые многие решения такого уровня часто закрыть не могут: например, если у пользователя 3-5 тысяч задачек, то лучше пойти и положить их в Трелло, а если вдруг их пара миллионов, то тут уже надо идти искать энтерпрайз решение, которое может быть слишком дорогим. И вот в подобных кейсах озма может что-то предложить - вроде и не энтерпрайз, и гибко, и с миллионами записей в сотне таблиц справится при должном усердии.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории