Plugins: forecast engines and import parsers
New capability can be added through a small plugin framework instead of editing the core. A plugin is a module that optionally declares a manifest (name, version, description) and registers itself into a typed extension point. Everything is discovered in a single scan at startup; a plugin that fails to load is skipped and logged, never fatal, so one bad plugin cannot take the app down.
The two extension points
- forecast_engine: a per-occurrence amount engine. The built-in amount methods (fixed, variable, derived, escalation, and the multi-driver formula) are themselves registered on this extension point, so a new engine sits alongside them with no special case.
- import_parser: a parser that turns an uploaded file into rows for the ingestion staging area, so a new file shape can be supported without changing the importer.
The safe boundary
A forecast engine that evaluates a formula does so through a restricted syntax tree: only arithmetic and references to the values the engine was given are allowed. A plugin cannot call out, read the filesystem, or run arbitrary code, so loading a plugin does not widen what the app can do to your data. The multi-driver formula engine uses exactly this boundary (see *Multi-driver forecasting*).
Seeing what is loaded
GET /plugins lists every plugin that loaded and its version; GET /forecast-engines and GET /import-parsers list the typed extension points. A version is part of the manifest so an operator can tell which build of a plugin is running.
Plugins are code shipped with the app, not user input. There is no runtime upload of a plugin from the browser; a plugin is added to the image and discovered on the next start.
In-app documentation, version 5. Generated from the product documentation source, so this matches the app exactly.