feat(plugins): port plugins/extensibility to Phoenix#96
Merged
Conversation
Adds the extensibility layer to reach parity with the Laravel reference,
translated to idiomatic BEAM: plugins are host-app modules implementing
the Escalated.Plugins.Plugin behaviour and registered in config, rather
than uploaded PHP files driven by a Node SDK subprocess (neither the file
upload nor the JSON-RPC runtime bridge maps to a compiled release).
* Escalated.Plugins.Hooks — WordPress-style action/filter dispatch over
config-registered callbacks (:hooks/:filters) and active plugin
handlers; a raising handler is logged and skipped (actions swallowed,
filters fall back to the running value).
* Escalated.Plugins — registry + activate/deactivate/uninstall lifecycle,
persisting activation state in escalated_plugins and firing the
plugin_activated/deactivated/uninstalling hooks.
* Escalated.Plugins.Store — queryable per-plugin key/value store over
escalated_plugin_store, with Mongo-style operators (////
$lt/$lte/$in/$nin).
* Admin PluginController + routes (list / activate / deactivate /
uninstall). No ZIP upload — plugins are compiled host modules.
* Plugin + PluginStoreRecord schemas, migration for both tables, and
config :plugins. Verified: mix format, credo --strict, mix test (544, 0
failures).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Ports the plugins / extensibility feature to
escalated-phoenix, reaching parity with the Laravel reference. This was the last open item in the phoenix parity backlog.Approach — extensibility, translated to the BEAM
The Laravel reference is dual-track: WordPress-style PHP hooks plus a Node.js SDK subprocess bridge (JSON-RPC over stdio), ZIP upload of plugin files, and
require-at-runtime. The runtime-loading half does not map to a compiled Elixir release, so plugins here are host-app modules implementing a behaviour and registered in config — the same convention this repo already uses forEscalated.Api.HostAuth. The extensibility contract (hook dispatch, activation lifecycle, per-plugin data store, admin management) is fully preserved.What's included
Escalated.Plugins.Hooks— action/filter dispatch. Handlers come from config (:hooks/:filterscallback maps) and from active plugin modules (handle_action/2,handle_filter/3). A raising handler is logged and skipped: actions swallowed, filters fall back to the running value — a bad plugin can never crash a host request.Escalated.Plugins— registry + activate / deactivate / uninstall lifecycle. Persists state inescalated_pluginsand fires theplugin_activated/plugin_deactivated/plugin_uninstallinghooks (matching Laravel's order) plus the plugin's ownon_activate/0/on_deactivate/0.Escalated.Plugins.Store— queryable per-plugin key/value store overescalated_plugin_store, with the reference operator set ($eq $ne $gt $gte $lt $lte $in $nin), filtered in-memory so semantics are DB-agnostic.PluginController+ routes — list / activate / deactivate / uninstall under/admin/plugins. No ZIP-upload endpoint (plugins are compiled host modules).escalated_pluginsandescalated_plugin_store, and aplugins: []config entry.Escalated.Plugins.Pluginbehaviour documenting the host contract.Intentionally out of scope (documented in module docs)
Verification
Ran the exact CI toolchain (Elixir 1.15 / OTP 26) in a container:
mix format --check-formatted— cleanmix credo --stricton all new files — no issuesmix test— 544 tests, 0 failures