Accept + implement ADR-010 frontend plugin hooks (contract 0.7.0)
Some checks failed
CI / backend (push) Failing after 1m2s
CI / naming (push) Successful in 1s
CI / frontend (push) Successful in 7s

Four data-only hooks on BasePlugin (get_settings_cards,
get_asset_panels, get_map_overlays, get_asset_presentation) with a
GET-only /api/pluginui consumer surface copying the dashboard-widgets
semantics. Pilots: warranty declares its asset panel; measuringtools
supplies its settings card, presentation, and calibration overlay -
the last hardcoded settings-nav entry is now hook-sourced. Generic
renderers for panels/overlays/presentation deferred per the ADR's
incremental adoption plan (documented in CONTRACT-STABILITY.md).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
cproudlock
2026-07-11 19:38:32 -04:00
parent 9eed3745fc
commit 24f67d6ac5
17 changed files with 625 additions and 19 deletions

View File

@@ -156,6 +156,23 @@ def test_plugin_get_reports_is_iterable(plugin_instances, name):
)
def test_baseplugin_has_frontend_contribution_hooks():
"""The four ADR-010 frontend-contribution hooks are on the contract (0.7.0)."""
for hook in ('get_settings_cards', 'get_asset_panels',
'get_map_overlays', 'get_asset_presentation'):
assert hasattr(BasePlugin, hook), f'{hook} missing from BasePlugin'
@pytest.mark.parametrize('name', BUNDLED_PLUGINS)
def test_plugin_frontend_hooks_return_lists(plugin_instances, name):
"""The four ADR-010 hooks default to a list on every bundled plugin."""
plugin = plugin_instances[name]
assert isinstance(plugin.get_settings_cards(), list)
assert isinstance(plugin.get_asset_panels(), list)
assert isinstance(plugin.get_map_overlays(), list)
assert isinstance(plugin.get_asset_presentation(), list)
def test_get_services_hook_has_consumer(app):
"""get_services is consumed by plugin_manager.get_service (no dead hook)."""
with app.app_context():