Fix and check builders: every fix is built from fields; today's 27 fixes carry their templates

settings/builders.py renders a fix's command from a builder (template) and its fields; validate
refuses a config whose stored command no longer equals what its fields build; the Fixes screen and
the remote checks in the key editor rebuild through /api/build and /api/build-check. config.json
adopts templates for all 27 fixes and 5 remote checks (ProPresenter's restart loop and Ableton's
quoting normalised, same behaviour); tests/test_builders.py (174 tests pass). Deployed to NA Ingest.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
2026-10-14 14:17:31 -04:00
co-authored by Claude Fable 5.1
parent 02d0c77cd9
commit 187dd464c0
8 changed files with 2014 additions and 214 deletions
+9
View File
@@ -200,6 +200,10 @@ field("fixes.*.never_auto", "bool", False, "Never runs by itself.", "Fixes")
field("fixes.*.part", "enum", None, "Which part of the switcher.", "Fixes", options=["audio", "camera"])
field("fixes.*.verify_seconds", "int", 20, "Wait this long before judging a reconnect.", "Fixes", advanced=True,
lo=5, hi=120)
field("fixes.*.template", "str", None, "How it is built (the builder); custom = typed by hand under Advanced.", "Fixes", apply="none")
field("fixes.*.params", "dict", None, "The builder's fields; the command is made from them.", "Fixes", apply="none")
field("tiles[].checks[].template", "str", None, "How the check's command is built.", "Keys", apply="none")
field("tiles[].checks[].params", "dict", None, "The builder's fields.", "Keys", apply="none")
field("fixes.*.off_seconds", "int", 2, "How long a HyperDeck's connection stays off.", "Fixes", advanced=True,
lo=1, hi=10)
field("fixes.*.hung_note", "str", None, "What the key says when the device answers ping but not Companion.",
@@ -615,6 +619,11 @@ def validate(cfg, live=None):
errors.append("%s: %r is not in the right form" % (p, v))
if f["type"] == "enum" and f["options"] and v not in f["options"]:
errors.append("%s: %r is not one of %s" % (p, v, ", ".join(f["options"])))
try:
from settings import builders
errors += builders.mismatches(cfg)
except ImportError:
pass
return errors, warnings