Audit: Grundeinstellungen V2 (/v2/admin/settings)¶
Stand: 2026-08-03. Geprüft wurde, welche Einstellung auf der Seite eine Wirkung im V2-Backend hat, welche V1-Konfiguration in V2 noch keine Stelle hat, und welcher Block auf der Seite fachlich falsch einsortiert ist.
Korrektur zur Erstfassung
Zwei Punkte der ersten Fassung waren falsch und sind unten berichtigt:
global_certist kein SSL-/PEM-Zertifikat. Der Katalog beschrieb es als „PEM-Zertifikat für ausgehende Verbindungen", tatsächlich ist es die Zertifikatsangabe unter der Unterschrift auf Berichten (V1:add_signature == 'GLOBAL'). Die Empfehlung „raus, Betriebssache" war damit hinfällig; Label und Hilfetext sind korrigiert, das Feld gehört zu den Unterschriften.- Ersatzlos entfernen war der falsche Schluss. Alle Kandidaten
(
enable_local_user_accounts,enable_fixed_grid_header,download_folder,show_empty_doc, Barcode,pic_doc_code,certificate_field_fieldname) werden von calServer V1 aktiv gelesen. Auf einer Installation, die noch V1 fährt, ist diese Seite die einzige gepflegte Admin-Oberfläche dafür. Statt zu löschen tragen sie jetzt das Kennzeichen Nur V1 aus dem Schema (scope).
Prüfmethode: für jeden Property-Key wurde der Consumer in laravel/app/ und
frontend-v2/ gesucht. „Ohne Wirkung" heißt: der einzige Fundort ist der
Katalog app/Support/SettingsCatalog.php bzw. die Seite selbst. Der Wert wird
also gespeichert und wieder angezeigt, aber niemand liest ihn.
Befund und Umsetzung
Die Abschnitte 1 bis 4 beschreiben den Befund zum Prüfzeitpunkt, nicht den heutigen Aufbau der Oberfläche. Was daraus umgesetzt wurde, steht in Abschnitt 5; die Umzüge selbst begründet ADR-031.
Kurzfassung¶
- Die V1-Parität der Felder ist erreicht. Alle 39 Keys aus
basicSettingFields, alle 20 ausinventorySettingFieldsund alle 6 aussecuritySettingFields(httpdocs/protected/config/constants.php) haben in V2 ein Eingabefeld. Es fehlt kein V1-Feld. - Die Wirkung fehlt an 26 von rund 70 Feldern. Captcha, Cookie-Banner, Report-Briefkopf, Barcode und einige Einzelwerte sind reine Formulare.
- Was wirklich fehlt, ist der V1-Tab „Administration". Cron Jobs, Cache, Backup und Dateispeicher haben in V2 teils fertige Endpunkte, aber keine Oberfläche.
- Das Sammelbecken hat zwei Ursachen: die Seite bündelt vier fachlich unabhängige Themen, und sie hat zwei Bauweisen nebeneinander (schema-getrieben aus dem Katalog gegen handgeschriebenes Formular).
1. Ausgangslage: was die Seite heute ist¶
frontend-v2/pages/admin/settings.vue (754 Zeilen) hält vier Tabs, drei
Persistenzwege und sechs Speichern-Buttons:
| Tab | Quelle | Bauweise | Speichern |
|---|---|---|---|
| Anmeldung | settings/user, Sektionen branding + registration |
schema-getrieben (useSettingsSchema + SettingsSchemaForm) |
PUT /admin/properties |
| Passwort & Sicherheit | settings/user, Sektionen password + security + ssl + report_pdf |
schema-getrieben | derselbe PUT |
| Regeln | settings/calibration + settings/customer |
handgeschriebenes Formular, Labels im Frontend | zwei getrennte PUTs, Aufteilung per Frontend-Whitelist |
| Portal | QR_Code_Role-Flags (ADR-010) |
eigener Endpunkt | PUT /admin/portal-settings |
Der Bruch ist strukturell: Der Katalog (SettingsCatalog::all()) kennt genau
eine Gruppe, settings.user. Die Regeln-Tab-Keys stehen nicht darin, also
lebt ihre Beschreibung (Label, Typ, Hilfetext, Validierung) im Vue-Template.
Das ist die Stelle, an der die Seite wieder wächst: eine neue Regel bedeutet
Frontend-Code, keinen Katalog-Eintrag.
Nebenwirkung im Frontend: saveRules() teilt die Werte über eine
hartcodierte Menge (customerFields = new Set(['search_customer_fields']))
wieder auf die Subkategorien auf. Jede weitere settings/customer-Regel muss
an dieser Stelle nachgetragen werden, sonst landet sie still in
settings/calibration.
2. Was umgesetzt ist (mit Wirkung im Backend)¶
Tab „Anmeldung" (18 Felder, 16 wirksam)¶
| Setting | Wirkung |
|---|---|
company_name, company_login_text, logo_company, background_image_company, background_color_company |
AuthController::branding(), Login-Seite |
default_language |
Branding + Registrierung + Rollen-/Modul-Labels |
system_email |
MailerActionRunner, SystemMailService |
registration_from_name, registration_mail_list, registration_form_company |
AuthController::register(), Passwort-Reset |
enable_registration_dialog, enable_registration_mail, enable_double_opt_registration, enable_welcome_mail |
Registrierungsablauf komplett verdrahtet |
registration_pending_email, registration_welcome_email |
Double-Opt-in- und Willkommensmail |
Ohne Wirkung: information_email_for_admin, registration_terms_conditions
(die AGB werden auf pages/register.vue nirgends angezeigt oder bestätigt).
Tab „Passwort & Sicherheit" (23 Felder, 9 wirksam)¶
| Setting | Wirkung |
|---|---|
minimal_number_characters, ..._lowercase_..., ..._uppercase_..., ..._special_..., ..._digit_... |
PasswordPolicyService, wird über branding() auch ans Frontend geliefert |
password_expiry_days, warning_password_expiry_days |
AuthController (Ablauf + Vorwarnung beim Login), Ersteintrag durch AppSetup |
activate_number_of_failed_login, number_of_failed_login |
LoginSecurity, Kontosperre nach Fehlversuchen |
Ohne Wirkung: die kompletten Blöcke reCAPTCHA (3), Friendly Captcha (3), Cookie-Banner (3), SSL-Zertifikat (1) und Report-PDF (4).
Tab „Regeln" (24 Felder plus Zähler-Block, 14 wirksam)¶
| Setting | Wirkung |
|---|---|
due_date_period, critical_date_period_1..3 |
CalibrationStatusService (Fälligkeits- und Kritisch-Schwellen) |
status_field_fieldname |
MailerActionRunner |
additional_status_field_fieldname |
StatusController |
type_field_fieldname |
DeviceType, DeviceTypeBlueprintService, InventorySpecificationController |
customer_email_field |
CustomerEmailFieldResolver |
inventory_description_fields, search_customer_fields |
LookupService (Anzeige in Auswahlcombos) |
disable_double_asset_number |
InventoryController, StoreInventoryRequest |
disable_double_booking_number |
BookingController, StoreBookingRequest |
enable_user_opens_order |
OpenOrderWarningService |
enable_badge_dms_view |
FileSettingController (Freigabe-Badge) |
counter_count, counter_N |
FieldCounterService ([GLOBAL_COUNTER_N] in Vorgabewerten) |
counter_N_reset_{day,week,month,year} |
ResetGlobalCounters (nächtlicher Lauf) |
Ohne Wirkung: certificate_field_fieldname, pic_doc_code, die vier
Barcode-Felder, show_empty_doc, download_folder sowie die beiden
bereits als V1-only beschrifteten Schalter enable_local_user_accounts und
enable_fixed_grid_header.
Tab „Portal" (4 Felder, vollständig)¶
portal_enable, portal_start_address, qrlink_enable, qrlink_address
laufen über PortalSettingsController nach ADR-010, inklusive Public-User-Status
und Kundenzähler. Der einzige Tab ohne Lücke.
3. Was fehlt¶
3a. Wirkung zu vorhandenen Feldern¶
Nach Aufwand und Nutzen sortiert:
- Captcha auf der Anmeldung (6 Felder). Der Schalter suggeriert Schutz,
den es nicht gibt. Entweder in
login.vue+AuthController::login()umsetzen oder aus der UI nehmen, bis es soweit ist. Ein aktivierter Schalter ohne Prüfung ist schlechter als ein fehlender. - Report-Briefkopf und PDF-Kopf/Fuß (4 Felder). V1 druckt damit Lieferscheine und Berichte. In V2 liest die Report-Pipeline die Werte nicht.
- Cookie-Banner (3 Felder). Datenschutz-Thema mit Außenwirkung, in V2 nirgends gerendert.
- AGB-Bestätigung bei der Registrierung (
registration_terms_conditions). - Barcode/Etikett (4 Felder). Hier fehlt nicht die Konfiguration, sondern die Funktion: V2 hat keinen Etikettendruck, der einen Barcode-Typ auswerten könnte.
3b. Konfigurationsstellen, die V2 komplett fehlen¶
Der V1-Tab Administration (basicSettings/administration) hat in V2 keine
Entsprechung. Bei vier Punkten existiert der Endpunkt bereits und nur die
Oberfläche fehlt:
| Thema | V2-Backend | V2-Frontend |
|---|---|---|
| Cron Jobs | GET/POST/PUT/DELETE /admin/cron-jobs, POST /admin/cron-jobs/restart |
fehlt |
| Cache leeren | POST /admin/cache/flush |
fehlt |
| Backup-Aktionen | /admin/backup-actions inkl. clone und test-run |
fehlt (docs-v2/admin/backup.md behauptet bereits eine UI) |
| Dateispeicher-Pfade | settings/file_store (vom InitialDataSeeder gesetzt) |
fehlt |
| SymmetricDS-Pfade | settings/symmetric |
fehlt |
| Session-Timeout | nur .env |
fehlt (in V1 auf der Seite editierbar) |
Nicht nachzubauen sind aus dem V1-Tab-Set:
- Grid Feature Flags (
use_legacy_*) schalten V1-Legacy-Grids. In V2 bedeutungslos, der Endpunkt existiert nur für V1-Installationen. - Report-Engine-Flags sind bereits umgesetzt, allerdings in
/admin/reportsstatt in den Grundeinstellungen. Das ist die richtige Stelle. - Plugins-Tab: der Inhalt war im Wesentlichen MET/TEAM, das V2 unter
/admin/metteamhat.
4. Was woanders besser aufgehoben ist¶
Die Seite heißt „Grundeinstellungen", trägt aber vier verschiedene Fragen: Wie sieht das System von außen aus?, Wer darf rein und wie sicher?, Welches Feld bedeutet was? und Wie druckt der Bericht?. Nur die ersten beiden gehören hierher.
Report-PDF raus, nach /admin/reports¶
left_header_order, right_header_order, pdf_report_header,
pdf_report_footer stehen heute im Tab „Passwort & Sicherheit". Ein
Briefkopf hat mit Passwortrichtlinien nichts zu tun, und /admin/reports hat
mit „Berichtseinstellungen" bereits den passenden Tab. Der Katalog kann die
Sektion report_pdf behalten, nur die Seite muss sie anders anzeigen: ein
zweites SettingsSchemaForm mit :section-keys="['report_pdf']" in
/admin/reports genügt, die Speicherlogik ist dieselbe.
Feldzuweisungen raus, nach /admin/field-definitions¶
Acht Felder (status_field_fieldname, additional_status_field_fieldname,
type_field_fieldname, certificate_field_fieldname, customer_email_field,
inventory_description_fields, search_customer_fields, pic_doc_code)
beantworten die Frage „welches Feld übernimmt welche Rolle". Das ist
Feldverwaltung, keine Grundeinstellung.
Der Aufenthaltsort ist nicht nur kosmetisch falsch, er produziert Fehler: Alle
acht sind freie Textfelder. Der Admin muss den api_name treffen, der je
nach Installation status oder C2305 heißt (siehe
frontend-v2/CLAUDE.md, „Die V1-Codes sind die Feld-Identität"). Ein Tippfehler
fällt erst auf, wenn Wochen später eine Mail-Aktion den Status nicht findet.
Auf /admin/field-definitions steht die Registry ohnehin schon zur Verfügung,
also kann daraus eine Auswahl statt eines Textfelds werden.
Zähler-Block raus, zu den Vorgabewerten¶
counter_count, counter_N und die 4·N Reset-Flags sind ausschließlich für
[GLOBAL_COUNTER_N] in Vorgabewerten da (FieldCounterService,
DefaultValuePicker, ADR-018 „Vorgabewerte als Formeln"). Sie gehören neben
den Vorgabewert-Editor, nicht in einen Abschnitt „Sonstiges". Der Block ist
außerdem der optisch größte auf der Seite (bei 4 Zählern 20 Bedienelemente).
Kennzeichnen statt entfernen¶
Die erste Fassung wollte vier Felder löschen. Die Prüfung gegen httpdocs/
hat das widerlegt: jedes davon wird von V1 gelesen.
| Setting | V1-Consumer |
|---|---|
enable_local_user_accounts |
LoginForm.php |
enable_fixed_grid_header |
KGridViewTrait.php |
download_folder |
FrontendProperty.php |
show_empty_doc |
small_view.php, document/files.php |
certificate_field_fieldname |
drei Kalibrier-Views |
pic_doc_code |
small_view.php, view.php |
| Barcode (4) | Etikettendruck |
global_cert |
Model.php, FrontendDms.php, AdminSignatureSetting.php |
Kundensysteme laufen V1 (siehe Root-CLAUDE.md). Ein Feld aus der V2-Maske zu
werfen, das V1 auswertet, nimmt dem Admin die Bedienstelle, ohne die Einstellung
loszuwerden. Deshalb bleiben sie, tragen aber scope: 'v1' im Katalog und in der
Oberfläche das Kennzeichen Nur V1 mit Tooltip. Das ist die Information, die
der Benutzer braucht, an der Stelle, an der er sie braucht — und sie steht in
den Daten, nicht in Prosa in zwei von sechs Hilfetexten.
global_cert ist ein Sonderfall: Der Katalog beschrieb es als PEM für
ausgehende Verbindungen. Es ist die Zertifikatsangabe im Unterschriftsblock von
Berichten. Label, Hilfetext und Sektion sind korrigiert; fachlich gehört es zu
den Unterschriften unter /admin/reports, nicht in eine SSL-Sektion.
Verschieben, wenn die Funktion kommt¶
show_empty_docgehört zur Dateiverwaltung (/admin/files).- Die Barcode-Sektion gehört zum Etikettendruck, sobald es ihn gibt.
- Der Portal-Tab ist an sich richtig platziert, wäre aber zusammen mit dem
Public User (heute
/admin/users) als eigener Bereich „Öffentlicher Zugang" schlüssiger. Kein dringender Umbau, ADR-010 hat das bewusst so gelegt.
Bleiben soll¶
- Branding und Anmeldeseite.
- Registrierung.
- Passwortrichtlinie und Login-Sicherheit (inklusive Captcha, sobald wirksam).
- Fristen und Ablaufzeiträume: die vier Schwellen gelten systemweit für
Statusampeln, Dashboard und Grids.
/admin/statuseswäre denkbar, ist aber enger geschnitten als die Wirkung der Werte.
5. Zielbild und Reihenfolge¶
Zielbild /admin/settings: drei Tabs statt vier, alle aus dem Katalog
gespeist.
- Anmeldung & Branding
- Passwort & Sicherheit
- Regeln (Fristen, Doppel-Nummern-Sperren, Warnungen)
Portal bleibt als vierter Tab, bis es einen Bereich „Öffentlicher Zugang" gibt.
Reihenfolge, kleinste sinnvolle Schritte zuerst:
- ~~Tote Felder entfernen~~ → Wirkungsbereich kennzeichnen. ✅ umgesetzt:
scope: 'v1'im Katalog, Kennzeichen Nur V1 in der Oberfläche. Siehe die Korrektur oben, warum aus „entfernen" „kennzeichnen" wurde. settings/calibrationundsettings/customerin denSettingsCatalogaufnehmen. ✅ umgesetzt. Der Regeln-Tab ist jetzt genauso schema-getrieben wie die anderen, die Frontend-Whitelist insaveRules()ist weg, und Labels/Hilfen sind serverseitig übersetzbar. Das ist der Schritt, der verhindert, dass die Seite wieder zum Sammelbecken wird.- Report-PDF nach
/admin/reports, zusammen mitglobal_certin den Tab „Unterschriften". ✅ umgesetzt (ADR-031). - Feldzuweisungen nach
/admin/field-definitions, Freitext ersetzt durch Feldauswahl aus der Registry. ✅ umgesetzt (ADR-031). - Zähler-Block zu den Vorgabewerten. ✅ umgesetzt (ADR-031).
- Neue Seite
/admin/operations(„Betrieb") für Cron Jobs, Cache-Flush, Backup-Aktionen und Dateispeicher-Pfade. ✅ umgesetzt. Nicht eine Berechtigung, sondern drei: die Endpunkte tragenadministration_management,database_management_adminundbasic_setting_admin, also prüft jeder Tab seine eigene und entfällt ohne sie. - Captcha und Cookie-Banner entweder umsetzen oder ausblenden.
✅ umgesetzt als ausblenden: die neun Felder sind aus dem Katalog
genommen. Anders als bei den V1-Regeln genügte hier kein
scope: 'v1'— ein Schalter „Anmeldung mit reCAPTCHA schützen", der in V2 nichts prüft, verspricht Schutz, den es nicht gibt. Die Werte bleiben in derproperty-Tabelle, V1 wertet sie weiter aus.
Schritte 3 bis 5 verschieben Bedienelemente zwischen Admin-Seiten und ändern
damit die Menü-Topologie. Nach der Linie von ADR-014, ADR-016 und ADR-018
gehört dafür ein ADR ins laravel/docs/adr/-Verzeichnis — geschrieben als
ADR-031,
„Eine Einstellung steht da, wo sie wirkt".
Damit sind alle sieben Schritte abgearbeitet.
Was dabei nicht angefasst wird: die Speicherform. Alle Werte bleiben in der
property-Tabelle unter ihrem V1-Namen und ihrer V1-Subkategorie. Verschoben
wird nur, wo sie bedient werden. Damit bleibt jede V1-Installation
kompatibel und v1:sync trifft weiterhin dieselben Zeilen.