Formular-DEFINITION speichern (der EINZIGE Schreibweg fuer formdef). Pflichtfelder: version (int>=1), title, answer_type (muss existierender Objekttyp sein, z.B. 'inspection'), fields (nicht-leer). Jedes Feld: key (Buchstabe am Anfang, a-zA-Z0-9_), widget, label; optional required, options (bei select), source (bei picker), validation. Widgets: text, textarea, int, float, select, picker, switch, slider, datepicker, file, label, subform, images, documents, signature. Reservierte Keys: formdef, usesForm, performs, udid, name, external_id. adminsql/sql/sqlparameters nur als Admin. Rechte: form_writer/admin + Schreibzugriff auf den Scope. Mit 'name'/'scope_id' werden auch die Stammdaten gesetzt. ACHTUNG: buttons/template_file/template_filename sind KEINE eigenen Parameter, sondern Felder INNERHALB des formdef-JSON (buttons/template_file/template_filename). BUTTONS: formdef.buttons=[{type,label,...}]; erlaubte type-Werte: 'save' (nur speichern), 'saveandgoto' (+url: Weiterleitung), 'send' (Mailversand mit PDF-Anhang; PFLICHT to[]; optional cc[], bcc[], subject; '$currentuseremail' wird durch die Adresse des Ausfuellenden ersetzt). Empfaenger kommen IMMER aus der formdef, nie aus dem POST. PDF-VORLAGE aus Excel: formdef.template_file = file_udid als 32-hex aus upload_file_to_object (NICHT bin2hex!) und formdef.template_filename = Dateiname — beide parallel setzen. Die Auswahl per Dateiname ueberlebt einen Neu-Upload gleichen Namens. PLATZHALTER im Excel: ##feldkey## (doppeltes Hash; ## key ## mit Leerzeichen geht auch) — {feldkey} oder %%feldkey%% funktionieren NICHT. Subform-Felder fuellen zeilenweise den naechsten freien Platzhalter (das Excel bestimmt die Maximalzahl, ueberzaehlige Zeilen werden verworfen); Bildfelder/signature werden Bildanker.