Saltar a contenido

Ciclo de vida del plugin

Entiende cuándo se ejecuta tu código: en el bootstrap de la API (arranque) o en cada petición HTTP (runtime).

Cuándo leer esta página

  • Necesitas saber qué hooks existen y en qué orden se invocan.
  • Quieres distinguir registro de UI (una vez) de lógica de negocio (por request).
  • Vas a montar un panel host o contribuir a uno existente.

Discovery

El framework descubre plugins por:

  1. Entry points cortex.plugins en pyproject.toml (pip / workspace uv).
  2. Sideload con CORTEX_PLUGIN_DIRS=/ruta/extra (override por id).
  3. Filtro CORTEX_ENABLED_PLUGINS (lista separada por comas o *).

Los panel hosts se descubren aparte con entry point cortex.panels.

Orden de bootstrap

flowchart TB
  H[Panel hosts cortex.panels]
  P[Plugins cortex.plugins]
  R[Hooks por plugin]
  V[validate_panels]
  H --> P --> R --> V
  1. Panel hostsconfigure_panel(PanelBuilder) registra panels en PanelRegistry.
  2. Plugins de negociocreate_plugin() instancia cada plugin activo.
  3. Hooks — por cada módulo importado, si el hook existe se invoca con su registry.
  4. Validación — cada módulo UI referencia un panel_id existente.

Hooks de bootstrap

Hook Registry Qué publica
register_resources ResourceRegistry Manifest + dashboards + forms (recomendado)
register_dashboards DashboardRegistrar JSON en ui/ (legacy)
register_forms FormRegistrar Formularios sueltos
register_settings SettingsRegistry Secciones de configuración
register_layouts LayoutRegistrar Fragmentos de layout (merge)
register_reports ReportRegistry Reportes exportables
register_widgets WidgetRegistrar Widgets sueltos
register_render_hooks RenderHookRegistrar Slots en el shell
register_panel_plugins PanelPluginRegistrar Extensión del builder del host

Deprecado

register_panels está deprecado. Usa entry point cortex.panels y configure_panel.

Prioridad de UI

Si el paquete exporta register_resources, el loader no ejecuta register_forms ni register_dashboards por separado — el ResourceBuilder ya registra forms y dashboards.

Los hooks deben reexportarse en el __init__.py del paquete del plugin; el loader importa el módulo raíz.

Bootstrap vs runtime

Fase Qué ocurre Dónde vive tu código
Bootstrap Discovery, hooks, validación CUS resources.py, provider.py, __init__.py
Runtime Peticiones REST, persistencia, tenant plugin.pyapi_router()

El shell React nunca importa tu plugin. Consume JSON por HTTP (/api/v1/panels/..., /api/v1/ui/dashboards/...).

Contrato mínimo del plugin

class PluginProtocol:
    descriptor: PluginDescriptor
    def api_router(self) -> APIRouter: ...
    def resource_paths(self) -> list[str]: ...

resource_paths() declara los namespaces REST del dominio (ej. ["booking"]) para documentación y control.

Tenant

El tenant se resuelve por header X-Tenant-Id (configurable con CORTEX_TENANT_HEADER). No va en la ruta URL.

La URL de base de datos por tenant sigue CORTEX_DATABASE_URL_TEMPLATE, por ejemplo postgresql+asyncpg://...@localhost:5432/cortex_{tenant}.

Siguiente paso

  • API REST — contratos de listados y errores.
  • Panels — contribuir un módulo a un panel existente.
  • Panel hosts — crear un panel nuevo.

Ver también ADR 007 (persistencia) y contexto del proyecto.