Files
interview-demo-code/docs/features/settings/CLAUDE.md
Nikita Kiselev adcca7cbc4 docs: document settings framework and telecart-pulse feature
Каркас системы настроек (docs/features/settings) и фича TeleCart Pulse
с heartbeat (docs/features/telecart-pulse); спека синхронизирована с opt-in.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 15:08:05 +03:00

6.7 KiB
Raw Permalink Blame History

Настройки модуля

Назначение

Сквозная подсистема настроек модуля: форма в админ-панели, хранение значений и чтение их на backend. Это каркас, в который встраиваются остальные фичи — когда фиче нужен свой флаг/параметр, она добавляет поле в этот пайплайн, а не строит собственный механизм.

Точки входа

action Метод Где объявлен
getSettingsForm SettingsHandler::getSettingsForm bastion/routes.php
saveSettingsForm SettingsHandler::saveSettingsForm bastion/routes.php
resetCache SettingsHandler::resetCache bastion/routes.php
getSystemInfo SettingsHandler::getSystemInfo bastion/routes.php

Ключевые файлы по слоям

  • Дефолты: module/oc_telegram_shop/upload/oc_telegram_shop/configs/app.php — структура всех настроек с дефолтными значениями (секции app, telegram, metrics, store, orders, texts, sliders, mainpage_blocks, pulse, cron).
  • Handler (админка): module/.../bastion/Handlers/SettingsHandler.phpgetSettingsForm() отдаёт срез конфига (Arr::getWithKeys по списку секций), saveSettingsForm() сохраняет тот же срез.
  • Сохранение: module/.../bastion/Services/SettingsService.phpupdate() пишет в OpenCart-таблицу oc_setting через model_setting_setting->editSetting('module_telecart', ['module_telecart_settings' => $data]), синхронизирует статус модуля module_tgshop и очищает кэш.
  • Чтение (backend): Openguru\OpenCartFramework\Config\Settingsget('a.b.c') / getAll(). Расширение для витрины — App\Services\SettingsService (наследует Settings) и DTO в src/DTO/Settings/ с типизированными геттерами (is*(), get*()).
  • Сборка конфига: module/.../bastion/ApplicationFactory.php (и точка входа admin/controller/extension/module/tgshop.php) — дефолты из configs/app.php мержатся с сохранёнными module_telecart_settings через Arr::mergeArraysRecursively, результат отдаётся в Application.
  • Фронтенд (стор): frontend/admin/src/stores/settings.js — Pinia setup-store: дефолтный state, fetchSettings() (getSettingsForm), saveSettings() (saveSettingsForm).
  • Фронтенд (поля): frontend/admin/src/components/Settings/ItemBool (toggle), ItemInput, ItemSelect, ItemImage, ItemToggleButton. ItemBoolSwitcherToggleSwitch (PrimeVue). Используются во views/*View.vue.

Поток данных

Чтение формы: getSettingsFormSettings::getAll() (уже смерженный конфиг) → срез по секциям → JSON → стор fetchSettings() → поля во *View.vue.

Сохранение: поле (v-model) → стор saveSettings()saveSettingsFormSettingsService::update()oc_setting (module_telecart_settings) + сброс кэша.

Чтение на backend: дефолты configs/app.php ⊕ сохранённые значения → ApplicationConfig\Settings / DTO → сервисы (через DI-провайдеры, которые инжектят getConfigValue('...') в конструкторы).

Как добавить новый toggle (чек-лист)

  1. Дефолт: добавить ключ в нужную секцию configs/app.php (для булева — true/false).
  2. Backend-потребитель: прочитать значение там, где оно нужно. Идиома модуля — читать в ServiceProvider ($app->getConfigValue('секция.ключ')) и инжектить в конструктор сервиса (не дёргать конфиг из глубины класса). При наличии DTO — добавить геттер.
  3. Стор: добавить ключ с дефолтом в соответствующую секцию state в frontend/admin/src/stores/settings.js.
  4. View: добавить компонент поля (для тумблера — <ItemBool label="…" v-model="settings.items.<секция>.<ключ>">…текст-подсказка…</ItemBool>) в нужный *View.vue.
  5. Убедиться, что секция уже перечислена в списках Arr::getWithKeys в getSettingsForm/ saveSettingsForm (если добавляешь поле в новую секцию — добавить и саму секцию в оба списка).

Связанные фичи

  • telecart-pulse — heartbeat использует этот каркас: флаг pulse.heartbeat_enabled проходит весь путь от формы до backend-гейта.

Нюансы и подводные камни

  • PHP 7.4 в backend-коде (без match, промоушена свойств, union-типов и т.п.).
  • getSettingsForm/saveSettingsForm работают строго по белому списку секций (Arr::getWithKeys). Поле вне перечисленных секций не отдастся и не сохранится.
  • Секция cron содержит read-only поля (cli_path, last_run), которые добавляются при выдаче и вырезаются перед сохранением — не сохраняй вычисляемые значения.
  • saveSettingsForm сейчас вызывает пустой validate() — серверной валидации значений настроек по сути нет; не полагайся на неё.
  • После сохранения кэш сбрасывается целиком (SettingsService::updatecache->clear()).
  • Существующие установки не имеют сохранённого значения нового ключа — оно берётся из дефолта configs/app.php (мерж). Выбирай дефолт так, чтобы поведение «как было».