Перейти к содержанию

Студия: поля модели из интерфейса

Администратор настроек добавляет к модели своё поле без кода — в режиме студии на форме модели. Поле становится обычной колонкой таблицы и обычным полем модели: его видят список, форма, фильтры, экспорт в Excel и API /auto.

Установка

Студия по умолчанию выключена: ставит её администратор на странице Настройки → Прочее → Приложения (/apps), без рестарта. Это отключаемый сервис ("core": False): установка запускает его startup — поля вешаются на модели, схемы и роуты автокруда пересобираются; удаление зовёт shutdown — поля снимаются с моделей, роуты /studio/* вырезаются. Колонки, строки studio_fields и настройки форм остаются в базе: повторная установка вернёт всё как было. Пока студия не установлена, фронт настройки форм не грузит и не применяет (зоны «Дополнительно» и обязательности из настроек нет).

Режим студии

Иконка в шапке (как Studio в Odoo) появляется, когда открыта форма модели, модуль установлен и пользователь — администратор настроек. В режиме студии зона «Дополнительно» формы становится редактором сетки, а справа под шапкой открывается панель — форма сужается на её ширину, так что панель не закрывает ни разметку, ни зону «сбоку», ни шапку.

Над сеткой зоны — её место (снизу / сбоку / вкладка) и размер сетки (колонки × строки, пустые строки — сколько понадобится). Пустые клетки видны пунктиром; клетка под курсором подсвечивается фиолетовым, если примет поле, и красным, если нет. Подробности — в разделе «Поля формы» настроек видов.

  • Добавить — новые поля по типам и существующие поля модели; перетаскиваются в клетку зоны, поля зоны — тоже перетаскиванием (на другое поле — обмен местами), крестик убирает поле с формы. Новое поле создаётся сразу: имя x_<тип>_<номер>, подпись «Новое поле»; «Ссылка на запись» сначала спросит модель.
  • Свойства — выбранное поле: подпись и варианты (у полей студии), техническое имя, тип, ширина и высота в клетках, у строки — «Ссылка» (иконка перехода на сайт в новой вкладке, вид charUrl хранится в клетке зоны), «Обязательное», «Убрать с формы», «Удалить поле».
  • Поля формы — обязательность полей разметки; саму разметку студия не трогает. Обязательное по модели включено всегда.

Каждое действие сохраняется сразу. Фронт — модуль fara_studio, к ядру подключается крючками: registerHeaderAction (иконка и прогрев настроек форм), registerExtension('*', …, 'provide:FormFields') (поля зоны «Дополнительно» в запрос записи и обязательные поля) и registerExtension('*', …, 'wrap:Form') (обёртка разметки каждой формы: ставит зону под разметкой, сбоку или вкладкой, сообщает шапке об открытой форме, в режиме студии держит редактор, перетаскивание и панель). Зона, сетка и настройки форм — в fara_studio (zone/, useFormSettings.ts, formSettingsApi.ts); ядро о них не знает. Редактор живёт в обёртке, а не в зоне: зону во вкладке Mantine прячет через Activity, и вместе с её эффектами пропадали бы иконка и панель. Без модуля поведение ядра не меняется.

Как устроено

  • Описание — таблица studio_fields (модуль backend/base/system/studio): модель, техническое имя, подпись, тип, варианты выбора, связанная модель. Источник истины — база: дамп базы содержит и настройку.
  • Настройки форм — таблица form_settings (models/form_setting.py) тоже принадлежит студии: обязательные поля и зона «Дополнительно» (место, сетка, клетки). Читают все пользователи, меняет system_admin; права создаются при установке студии.
  • Старт. Установленный сервис studio запускается после чтения флагов установки и до автокруда (sequence 5): вешает поля на модели (DotModel.add_fields + аннотация типа для схем API) и добавляет недостающие колонки штатным DDL-синком. Схемы и роуты /auto строятся уже с ними.
  • Сразу, без перезапуска. POST /studio/fields: строка, поле на модели, ALTER TABLE … ADD COLUMN, поле в «Дополнительно» общих настроек формы, пересборка схем и авто-роутов этого воркера (около 2 с), событие studio_changed в шину — остальные воркеры и крон приводят свои модели к таблице (StudioApp.sync; на событие студия подписывается сама в startup через env.apps.bus.subscribe).
  • Правка. PATCH /studio/fields/{id} — подпись и варианты выбора; применяются на месте, без пересборки схем, остальным воркерам — то же событие.
  • Удаление. DELETE /studio/fields/{id}: строка, поле с модели, имя вычищается из настроек формы. Колонка и данные в базе остаются: поле с тем же именем и типом, созданное заново, получит прежние значения. Удаление колонки отключено намеренно (закомментировано в роутере и сервисе базы).

Правила

  • Имя: x_ плюс латиница, цифры и подчёркивание (x_segment). Префикс отличает поле студии от полей ядра и не даст им пересечься.
  • Тип и имя после создания не меняются — поле создаётся заново. Поскольку колонка после удаления остаётся, новое поле с прежним именем должно быть того же типа.
  • Типы: строка, текст, целое, дробное, флажок, дата, дата и время, выбор из списка (пары «значение — подпись»), ссылка на запись (модель из реестра). Many2many, файлы и related-поля — нет.
  • Подпись — string поля; форма и меню колонок показывают её там, где у поля нет метки в разметке.

Код

models/studio_field.py — модель и проверки (STUDIO_FIELD_*), build() собирает поле dotorm; app.py — refresh (поля к таблице, подпись и варианты на месте), rebuild (схемы и роуты через DotormCrudAutoService.rebuild), sync, publish, show_on_form, forget; routers/studio.py — четыре ручки. Ядро: DotModel.remove_fields, DotormDatabasesPostgresService.sync_tables. Фронт: fara_studio — StudioToggle (иконка), StudioFormShell (обёртка формы, DndContext, панель), StudioZone (редактор сетки), StudioPanel, useStudioEditor (черновик и запись настроек), api.ts.