Add GE-Enforce P3 manifest editor UI (Settings > Imaging PC Types)
All checks were successful
CI / backend (push) Successful in 1m41s
CI / naming (push) Successful in 2s
CI / frontend (push) Successful in 8s

The imaging-PC-type manifest editor, contributed as an ADR-010 settings card
(Integrations group) and an ADR-009 plugin-gated route
(/settings/imagingpctypes, hidden when geenforce is disabled).

- Scope list: every imaging PC type with phase, entry count, and published
  version (or "unpublished"). New PC Type button.
- Scope detail: ComputerType/MeasuringToolType mapping + description; Publish,
  Versions (with per-version Roll Back), Preview (draft JSON), Delete.
- Entry table: ordered with Move Up/Down (the ordering contract, not drag),
  Name/Type/Detection/Filters, Edit/Delete. Add Entry opens a typed modal whose
  fields switch on entry Type (MSI/EXE/... vs PS1 vs File vs Registry), with a
  detection block, comma-separated targeting filters, CMM version gate, payload
  source, and an Advanced disclosure for the inert ApplyMode/UpdateWindow and
  InUseCheck. RegValue is typed by RegType (DWord/QWord -> number).
- Simulator: "what would a PC get" - enter a machine profile, see which entries
  apply and which filter excluded the rest. Verified live: CMM version 2019 ->
  applies 2019 + untagged, filters 2016/2026 by _CmmVersion.

Uses the P2 admin API; JWT+admin gated. Frontend build + naming green; full
backend suite 876 green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
cproudlock
2026-07-12 17:22:49 -04:00
parent d157502d5b
commit 7eb6cebeb5
3 changed files with 542 additions and 0 deletions

View File

@@ -79,6 +79,21 @@ class GeEnforcePlugin(BasePlugin):
'geenforce'),
]
def get_settings_cards(self) -> List[Dict]:
"""ADR-010: the imaging-PC-type manifest editor settings card."""
return [
{
'group': 'Integrations',
'to': '/settings/imagingpctypes',
'icon': 'settings',
'title': 'Imaging PC Types',
'description': 'Edit imaging PC types and their GE-Enforce install '
'manifests (apps, scripts, files, registry, gates); '
'publish, roll back, and simulate.',
'position': 30,
},
]
def init_app(self, app: Flask, db_instance) -> None:
logger.info(f"GE-Enforce plugin initialized (v{self.meta.version})")