ADR 020: Configuration manifest por plugin¶
Estado¶
Aceptado — 2026-06
Contexto¶
Los plugins registraban ajustes en Python (register_settings + SettingsBuilder) sin agrupación por género ni composición de widgets. La UI mostraba un sidebar plano de secciones. Se requiere configuración declarativa con jerarquía género → segmento → widgets embebidos (parameters | parameter_table).
Decisión¶
- Cada plugin declara
configuration/manifest.jsoncongroups,segmentsywidgets[]. - El loader de plugins auto-registra el manifest en
SettingsRegistry(aliasConfigurationRegistry). GET /api/v1/settings/panels/{panelId}devuelve{ groups, segments }.- Valores escalares:
GET/PUT /api/v1/settings/panels/{panelId}/{segmentId}(todos los camposparametersdel segmento). - Tablas de parametrización: CRUD vía API del plugin (
parameter_table); no usan el settings store. register_settingsen Python queda como shim deprecado si no existe manifest.
Leyenda: Árbol declarativo desde manifest JSON hasta el widget settings del panel. Actores: loader, SettingsRegistry, API, SettingsWidget. Estado: Implementado.
flowchart TB
subgraph plugin [Plugin Independiente]
Manifest["configuration/manifest.json"]
end
subgraph framework [Framework Dependiente]
Loader[Plugin loader boot]
Registry[SettingsRegistry]
API["GET /api/v1/settings/panels/{panelId}"]
end
subgraph panel [Panel React]
Widget[SettingsWidget]
Groups[groups acordeon]
Segments[segments sub-nav]
Params[widget parameters]
Table[widget parameter_table]
end
Manifest --> Loader --> Registry --> API --> Widget
Widget --> Groups --> Segments
Segments --> Params
Segments --> Table Leyenda: Navegación por segmento y carga lazy de widgets. Actores: operador admin, SettingsWidget, API plugin. Estado: Implementado.
sequenceDiagram
participant Op as Operador
participant SW as SettingsWidget
participant API as Settings API
participant Plug as Plugin REST
Op->>SW: click segmento connectors
SW->>SW: navigate /admin/configuration/connectors
SW->>API: GET panels/admin/connectors
API-->>SW: valores parameters
SW->>Plug: GET listPath connectors
Plug-->>SW: filas parameter_table
Op->>SW: crear fila conector
SW->>Plug: POST createPath
Plug-->>SW: 201 fila nueva Consecuencias¶
- Configuración por dominio en el namespace correcto:
operations(booking, clients),admin(sales, billing, payments),control/accountingsegún plugin. SettingsWidgetrenderiza acordeón de géneros, sub-nav de segmentos y compositor de widgets.- PoC
parameter_tableensales(aux-codes) para validar contrato API/UI. - Panel operativo: ajustes de dominio vía
/operations/configuration; back-office vía/admin/configuration.
Alternativas consideradas¶
- Mantener solo
SettingsBuilderen Python — rechazado: no escala a géneros/widgets ni documentación declarativa. - Persistir tablas en settings store — rechazado: las filas son entidades del dominio del plugin.