Skip to content

EDB: модуль неизменяемых данных и быстрых локальных коллекций

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

Обоснование

В enterprise и отраслевых приложениях (в т.ч. авиа, транспорт) справочники (аэропорты, коды, статусы) используются повсеместно; загрузка их «по клику» даёт задержки и плохой UX. Отраслевая практика (Low-Code платформы, кэш-слои в архитектуре) — предзагрузка, индексация и локальное хранение reference-data с фоновым обновлением. Риск при отсутствии EDB: зависимость отклика от сети, дублирование логики кэширования по фичам, невозможность единообразно настраивать стратегии загрузки (preload, lazy, stale-while-revalidate).

Что есть сейчас

  • В проекте уже существует Endge.vocabs, но по своей роли это не полноценная база неизменяемых данных.
  • Текущий vocabs-слой в основном решает задачу загрузки внешних справочников по settings.general.vocabs.
  • Данные подгружаются как внешний ресурс и кладутся в Raph, что хорошо для подстановок в фильтры и формы, но недостаточно для роли платформенного data-layer.

Чего не хватает

Сейчас отсутствует отдельный модуль, который:

  • хранит локальные неизменяемые или редко меняющиеся сущности;
  • умеет работать как быстрый источник данных без обязательного сетевого запроса после клика на странице;
  • поддерживает индексы, локальный кэш, снимки, версионирование и фоновую синхронизацию;
  • настраивается через конфигуратор, а не только кодом;
  • может использоваться не только для словарей, но и для любых reference-коллекций, catalog-данных, mapping-таблиц и lookup-структур.

Именно эту роль логично вынести в отдельный модуль EDB.

Какой проблемой должен заниматься EDB

EDB нужен как слой быстрых справочных данных, который располагается между runtime и внешними API.

Его задача:

  • заранее подготовить нужные справочники;
  • хранить их локально в нормализованном виде;
  • дать очень быстрый доступ из UI, фильтров, runtime и Source Actions;
  • уменьшить зависимость пользовательского отклика от сети в момент взаимодействия.

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

Каким должен быть модуль

1. Не просто словари, а универсальные коллекции

EDB должен работать не только со "справочниками" в узком смысле, а с любыми коллекциями неизменяемых или квазистатичных данных:

  • авиакомпании;
  • аэропорты;
  • статусы;
  • типы рейсов;
  • маппинги кодов;
  • конфигурационные таблицы;
  • локальные catalog-наборы;
  • предрасчитанные lookup-индексы.

2. Много источников данных

У коллекции должен быть конфигурируемый источник:

  • inline JSON в конфигураторе;
  • импорт из Payload;
  • REST endpoint;
  • GraphQL query;
  • generated dataset;
  • локальный snapshot;
  • комбинированный режим: local snapshot + background refresh.

3. Несколько стратегий загрузки

Для каждой коллекции должна задаваться стратегия:

  • preload при bootstrap;
  • lazy при первом запросе;
  • prefetch при входе на страницу;
  • background refresh;
  • stale-while-revalidate;
  • offline-first.

4. Локальное хранение

EDB должен иметь как минимум двухуровневое хранение:

  • быстрый memory-cache для активной сессии;
  • persistent storage для повторных заходов, например IndexedDB.

Это позволит резко ускорить отклик UI после первого прогрева.

5. Индексы и быстрый lookup

Ключевая сила EDB не просто в хранении массива, а в подготовленных индексах:

  • by id
  • by identity
  • by code
  • by составному ключу
  • по relation-ключам
  • по заранее описанным lookup-полям

Тогда из runtime и UI можно получать не "весь словарь", а точечный lookup почти без вычислений.

Как это могло бы выглядеть в архитектуре

Слой модуля

Примерная роль Endge.edb:

  • регистрация коллекций;
  • инициализация локального хранилища;
  • загрузка и синхронизация данных;
  • выдача fast lookup API;
  • публикация данных в Raph и runtime;
  • контроль версий и invalidation.

Конфигурационная модель

В конфигураторе у коллекции EDB могли бы быть поля:

  • identity
  • title
  • entityType
  • source
  • loadStrategy
  • storagePolicy
  • versionPolicy
  • ttl
  • primaryKey
  • indexes
  • fields
  • normalizers
  • filters
  • projections
  • relations
  • permissions
  • warmupScopes

Это даст возможность настраивать не код, а поведение коллекции.

Runtime API

Примерно такой слой API был бы полезен:

  • Endge.edb.ensure('airlines')
  • Endge.edb.get('airlines', id)
  • Endge.edb.find('airlines', { code: 'SU' })
  • Endge.edb.list('airlines')
  • Endge.edb.select('airlines', 'byCountry', 'RU')
  • Endge.edb.prefetchForPage(pageId)
  • Endge.edb.invalidate('airlines')

Интеграция с Raph

EDB можно публиковать в реактивный граф не одним массивом, а структурированно:

  • edb.airlines.items
  • edb.airlines.byId
  • edb.airlines.byCode
  • edb.airlines.meta
  • edb.airlines.status

Тогда runtime и UI смогут подписываться на более дешёвые и точные пути данных.

Почему это ускорит отклик после клика

Сейчас многие reference-данные логично тянутся как внешний ресурс. Это создаёт задержку именно в момент пользовательского действия.

EDB позволит сместить эту работу раньше:

  • загрузить коллекции на bootstrap или при входе в раздел;
  • сохранить snapshot локально;
  • построить индексы заранее;
  • отдавать данные сразу из local cache;
  • обновлять их в фоне, не блокируя интерфейс.

Итог: пользовательский сценарий "клик -> открыть форму / фильтр / карточку / editor" станет заметно быстрее и стабильнее.

Чем EDB лучше текущего vocabs-подхода

Endge.vocabs полезен как внешний namespace-loader, но EDB должен быть шире:

  • vocabs - это внешний источник и прикладной сценарий;
  • edb - это платформенный слой хранения, кеширования, индексации и выдачи reference-data.

То есть в будущем vocabs может стать одним из source-adapter-ов для EDB, а не отдельной параллельной системой.

Почему модуль должен быть расширяемым из конфигуратора

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

Это даст:

  • добавление новых коллекций без правки ядра;
  • настройку индексов и стратегий загрузки под проект;
  • разные политики для разных экранов;
  • быстрый перенос между проектами;
  • потенциальную генерацию typed API и runtime bindings через codegen.

Вывод

Для дальнейшего развития платформы стоит планировать отдельный модуль EDB как конфигурируемый слой локальных неизменяемых данных.

Рекомендуемый подход:

  • не расширять бесконечно Endge.vocabs;
  • выделить отдельную платформенную подсистему Endge.edb;
  • сделать vocabs одним из возможных источников данных для неё;
  • использовать EDB как основу для быстрого lookup-доступа, локального кеша и ускорения отклика UI после пользовательских действий.

Риски и ограничения

  • EDB добавляет слой конфигурации и синхронизации; при большом числе коллекций и частых обновлениях нужны политики инвалидации и лимиты памяти. Зависимость от домена (настройки источников) и от Raph (публикация данных); при рефакторинге ядра (см. Core_Refactoring_And_Feature_Modularization) EDB — кандидат на отдельный модуль с явным контрактом.