Fix plugin contract violation and installer defaults mismatch

Fix 1: Remove duplicate Setting import violating plugin contract
- plugins/endpoints/api/routes.py:3551 imported shopdb.core.models.Setting
- Setting already imported from shopdb.api at line 21
- Removed local import to comply with plugin contract (ADR-001)
- Test: test_plugins_only_import_contract_surface

Fix 2: Align installer defaults with measuringtools manifest
- measuringtools manifest declares default_enabled: true
- Installer (ShopDBFlask.iss) excluded it from PluginDefault()
- Removed measuringtools from exclusion list (now 4 excluded, not 5)
- Exclusions now match manifests: usb, employees, geenforce, printedparts
- Test: test_wizard_defaults_match_the_manifests

Historical note: measuringtools was promoted from default_enabled false to
true but the installer config was never updated to reflect this change.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Proudlock
2026-09-11 17:28:29 -04:00
parent f1ff46e764
commit 2ac2e6d33d
2 changed files with 5 additions and 5 deletions

View File

@@ -244,20 +244,21 @@ begin
else Result := Name;
end;
// True when a fresh install should tick this by default. The five omitted here
// True when a fresh install should tick this by default. The four omitted here
// are specialised; a site that wants them can tick them.
// Pre-tick to match each plugin's own manifest. These five ship
// Pre-tick to match each plugin's own manifest. These four ship
// "default_enabled": false, so a site gets them only by asking. The list used to
// omit measuringtools and printedparts, which meant the wizard installed and
// enabled them against their manifests on every site that took the defaults -
// creating tables nobody asked for.
// creating tables nobody asked for. measuringtools was later promoted to
// default_enabled true and removed from this exclusion list.
//
// Keep this in step with the manifests. tests/test_installer_defaults.py fails
// if they drift.
function PluginDefault(const Name: String): Boolean;
begin
Result := (Name <> 'usb') and (Name <> 'employees') and (Name <> 'geenforce')
and (Name <> 'measuringtools') and (Name <> 'printedparts');
and (Name <> 'printedparts');
end;
// Comma-separated list of what the operator ticked.

View File

@@ -3548,7 +3548,6 @@ def _send_operator_report_alert(report, asset_id, hostname):
current_app.logger.warning('Failed to generate screenshot URL: %s', e)
# Get PC access domain to build FQDN
from shopdb.core.models import Setting
pc_access_domain_setting = Setting.query.filter_by(key='pc_access_domain').first()
pc_access_domain = pc_access_domain_setting.value if pc_access_domain_setting else ''