Olymp Digital

Гибкие записи в одной базе

Запись в MongoDB — это «капсула». Поля хранятся отдельно маленькими кусочками — «гранулами». Наружу отдаём «пилюлю»: всё собрано в один удобный объект.

Стартовые поля и примеры данных можно задать формулой в файлах. Работа с данными — через GraphQL.

О проекте

О проекте Pilula

Pilula — и название продукта, и то, что видит интерфейс: одна сущность с полями, тот же номер, что у записи в базе, без лишних деталей «как это лежит внутри».

Capsula — сама запись в базе (тип, статус, кто создал). Granula — одно поле у этой записи: имя поля и значение. Materia — описание поля заранее: как оно называется, какой тип, нужно ли оно обязательно. Обычно экран ходит за пилюлями; запросы про капсулы — для отладки и служебных задач.

Formula — готовый набор: какие поля завести и несколько примеров записей, чтобы быстро поднять демо или пустую среду.

Как это стыкуется

В базе
Capsula
Одна строка: номер, тип, статус — основа записи.
Поля
Granula
Много маленьких значений: у каждой капсулы свои.
Наружу
Pilula
Всё собрано в один ответ для приложения.

Термины

🧪

Formula

Файлы с описанием полей и тестовыми записями — чтобы сразу было с чем поиграть.

⚗️

Materia

Шаблон поля: как называется, какой тип, как показать в форме.

🧬

Granula

Одно значение одного поля у одной записи.

📦

Capsula

Запись в MongoDB — каркас, к которому цепляются гранулы.

💊

Pilula

То, что отдаём приложению: все поля в одном месте, просто пользоваться.

Пример из формулы

pharmacia

Фармацевтическая формула — поля и стартовые записи из materiae.yaml и seed.yaml.

Поля (materiae)

substance строка · уникально · «Обозначение вещества»
dosage число · «Дозировка, мг»

Стартовые капсулы (фрагмент seed)

Тип Вещество Мг
antidotum Analginum 500
antidotum Ibuprofenum 400
antidotum Paracetamolum 500

В репозитории: lib/core/formulae/pharmacia/

Примеры GraphQL

Полный examples.graphql

Ниже подставляется содержимое examples.graphql из корня проекта при каждом открытии страницы (шаблон Jinja). Для копирования удобен исходный файл. Запуск запросов: GraphiQL (/graphql/viewer).

# examples.graphql не найден (/app/examples.graphql)

Jinja + EAV

Данные EAV в шаблоне

В маршруте берём EAVService из контейнера запроса, вызываем getPilulaeByCapsulaType (или другие методы) и передаём в res.render список карт — в Jinja это обычные объекты для циклов.

final eav = req.container!.make<EAVService>();
final list = await eav.getPilulaeByCapsulaType('antidotum');
await res.render('home/home.html', {
  'pilulae_demo': list.take(5).map((p) => p.toJson()).toList(),
});
id Тип Статус attributes (динамика)
69d9203de4d6abad8f000000 antidotum active substance: Analginum · dosage: 500
69d9203ee4d6b0ad8f000000 antidotum active substance: Ibuprofenum · dosage: 400
69d9203ee4d6b5ad8f000000 antidotum active substance: Paracetamolum · dosage: 500
Dart MongoDB GraphQL Angel