docs/PLUGINS.md

Plugin development

Private repositories and reviewed behavior hooks.

OlivERP plugins

Plugins are private, project-specific extensions installed from GitHub repository URLs. They declare a small set of reviewed behavior hooks that OlivERP executes inside its own trusted backend.

There is no marketplace or public catalog. Plugins do not open another application, replace OlivERP screens, inject JavaScript, receive the browser session, or run a remote service. An installation persists in the OlivERP account for the selected project.

How plugins work

  1. A project administrator pastes a private GitHub repository URL.
  2. OlivERP reads oliverp-plugin.json through its GitHub App.
  3. OlivERP validates the manifest and shows every requested behavior hook.
  4. The administrator reviews and activates the plugin.
  5. OlivERP stores the exact source SHA and applies those hooks in its normal backend calculations for that project.

Disabling or removing a plugin stops its hooks without deleting accounting records. Updating a repository does not silently alter an installation: paste its URL again to review and install the new version and source SHA.

Security model

  • Repositories must be private and explicitly shared with the OlivERP GitHub App using read-only contents access.
  • Only project administrators can install, activate, deactivate, or remove a plugin. Project members can use active behavior.
  • Every installation belongs to exactly one project.
  • The manifest schema is closed. Unknown hooks and fields are rejected.
  • Plugin source is not executed in the browser or evaluated dynamically by the OlivERP Worker.
  • Plugins cannot replace UI, access cookies or Convex session tokens, or send project data to an external runtime.

OlivERP stores neither GitHub installation tokens nor repository source code.

Repository manifest

Put oliverp-plugin.json at the root of the private repository:

{
  "schemaVersion": 1,
  "id": "com.example.my-private-plugin",
  "name": "My private plugin",
  "description": "Applies a private accounting rule.",
  "version": "1.0.0",
  "hooks": [
    {
      "type": "finance.other_transaction.vat_only",
      "concept": "solo_iva"
    }
  ]
}
  • id is a stable lowercase identifier and must not change between releases.
  • version follows semantic versioning.
  • hooks contains only capabilities supported and validated by OlivERP.
  • Hook values are reviewed before activation and stored with the installation.

Supported hooks

finance.other_transaction.vat_only

This hook applies only to manual income and expense transactions whose concept exactly matches concept. Matching is case-sensitive and does not normalize spaces or punctuation.

For a matching transaction, OlivERP:

  • keeps its VAT in input or output VAT totals;
  • excludes its gross amount from income, expenses, balance, and URP;
  • leaves the transaction visible and editable in the normal transaction list;
  • does not alter sales, purchases, stock, or any screen.

For example, a hook with "concept": "solo_iva" matches solo_iva, but not solo iva, Solo_IVA, or any other concept.

Add or update a private plugin

  1. Keep the GitHub repository private.
  2. Give the OlivERP GitHub App read-only access to that repository only.
  3. Open Plugins in OlivERP and paste the repository URL.
  4. Review the behavior hooks.
  5. Choose Add and activate.

The same plugin can be installed independently in different projects. Its hooks affect only projects where the plugin is both installed and active.

OlivERP deployment configuration

Private repository access uses these server-only variables:

GITHUB_PLUGINS_APP_ID=
GITHUB_PLUGINS_PRIVATE_KEY=

The private key can use the PKCS#1 PEM generated by GitHub or PKCS#8 PEM. Never expose it through a NEXT_PUBLIC_ variable. OlivERP signs a short-lived app JWT, exchanges it for a repository-scoped installation token, reads the manifest, and discards the token.