From 52eb10f5cadb1c8e52daa4d2d6c89450f644960d Mon Sep 17 00:00:00 2001 From: cproudlock Date: Wed, 12 Aug 2026 16:41:09 -0400 Subject: [PATCH] contract 0.17.0: expose DashboardDefault to plugins The enforcement reports needed to name what a display IS, and reached straight into shopdb.core.models.dashboarddefault to do it. Plugins may only touch core through shopdb.api, and the contract test said so. The role belongs on the surface rather than behind it: it lives in core, no plugin owns it, and a plugin reporting on displays has no other way to resolve it. Added there and the version bumped, which the docs test pins. --- docs/PLUGIN-HOOKS.md | 2 +- plugins/geenforce/api/routes.py | 5 +---- shopdb/__init__.py | 2 +- shopdb/api/__init__.py | 4 ++++ 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/docs/PLUGIN-HOOKS.md b/docs/PLUGIN-HOOKS.md index ef79839..0cb6e1d 100644 --- a/docs/PLUGIN-HOOKS.md +++ b/docs/PLUGIN-HOOKS.md @@ -9,7 +9,7 @@ The contract is locked in [ADR-001](../docs/adr/ADR-001-asset-as-platform-contra The framework declares its contract version in `shopdb/__init__.py`: ```python -__contract_version__ = '0.16.0' +__contract_version__ = '0.17.0' ``` Each plugin's `manifest.json` declares the range of contract versions it supports: diff --git a/plugins/geenforce/api/routes.py b/plugins/geenforce/api/routes.py index 1be975b..0473502 100644 --- a/plugins/geenforce/api/routes.py +++ b/plugins/geenforce/api/routes.py @@ -1014,10 +1014,7 @@ def _attach_display_roles(facts, hostnames): ShopDB's mirror of the display-type.txt each kiosk reads at startup. """ - try: - from shopdb.core.models.dashboarddefault import DashboardDefault - except ImportError: - return + from shopdb.api import DashboardDefault lowered = {name.lower() for name in hostnames} for default in DashboardDefault.query.filter_by(isactive=True).all(): host = (default.fqdn or '').split('.')[0].lower() diff --git a/shopdb/__init__.py b/shopdb/__init__.py index 547de78..ead6e8e 100644 --- a/shopdb/__init__.py +++ b/shopdb/__init__.py @@ -42,7 +42,7 @@ from .plugins import plugin_manager # first-time write under the declared category, and lets a plugin mark a key # readable without auth for pages that run logged out. Additive optional hook, # minor bump. -__contract_version__ = '0.16.0' +__contract_version__ = '0.17.0' # Product release version (see ADR-007). The product version and the # plugin-contract version above are distinct series with independent diff --git a/shopdb/api/__init__.py b/shopdb/api/__init__.py index 056b25a..20459f6 100644 --- a/shopdb/api/__init__.py +++ b/shopdb/api/__init__.py @@ -48,6 +48,10 @@ from shopdb.core.models import ( Role, SupportTeam, ) +# Display-role mapping (which kiosk shows which surface). On the surface +# because a plugin reporting on displays has no other way to name what a +# display IS - the role lives in core, not in any plugin. +from shopdb.core.models.dashboarddefault import DashboardDefault # Response + pagination helpers for plugin API blueprints from shopdb.utils.responses import (