Struktur und Grenzen
Dies ist die Struktur, die bekannt sein muss, wenn die Tablet-App vor Ort modifiziert oder an andere Systeme angebunden wird. Der Quellcode befindet sich im Repository plantpulse-platform/plantpulse-frontline-web.
Aufbau
태블릿 브라우저 (PWA) frontline 컨테이너 플랫폼
┌──────────────────────┐ HTTPS ┌──────────────────────────────┐ V5 ┌──────────────┐
│ React 웹 앱 │ ──────▶ │ BFF (/api/*) │ ────▶ │ server-web │
│ 서비스워커 · 입력 큐 │ 9701 │ · 기기 토큰 · 작업자 세션 │ 토큰 │ /api/v5/... │
└──────────────────────┘ │ · 범위 검사 · 감사 로그 │ 하나 └──────────────┘
└──────────────┬───────────────┘
│ JDBC
플랫폼 DB pp · 스키마 pf
| Teil | Beschreibung | Position im Repository |
|---|---|---|
| Web | React 19 + TypeScript + Vite PWA. Service Worker, Offline-Eingabewarteschlange (IndexedDB), letzte Werte pro Bildschirm (localStorage). Graphen über ECharts 6 — ein separater Chunk, der nur beim Öffnen von Bildschirmen mit Graphen geladen wird | web/ |
| BFF | Spring Boot 4.1 WAR, läuft auf einem gemeinsamen Tomcat 10.1 (runtime-base) der Platform. Der Dispatcher ist nur in /api/* konfiguriert. Bereichsprüfung (scope/), Wartung (maintenance/), Defekt (defect/) und Report (floor/ReportController) befinden sich hier | src/plantpulse/frontline/ |
| DB | Schema pf (vor 2026-10-29 frontline) der Platform-Datenbank pp, bestehendes DB-Konto der Platform. Tabellen beginnen mit fl_. Schemas werden über Flyway migriert (V1~V14) | src/db/migration/ |
| Image | docker.kopens.io/pp/plantpulse-frontline-web. Port 9701 (TLS) · 9700 (nur Health Check) | Dockerfile |
Schema-Historie
| Version | Beschreibung |
|---|---|
| V1~V4 | Bediener · PIN · Gerät · Einstellungen · Grundlisten · Schichtnotizen · Audit-Logs, Bildschirmsprache · Theme |
| V5 | CHECK IN ('ko','en') im Sprachfeld entfernt und durch fl_operator.lang · fl_operator_revision.lang · fl_device.default_lang in VARCHAR(35) (BCP 47) erweitert. Zulässige Sprachen werden durch eine Liste auf dem Server und nicht im Schema festgelegt |
| V6 | Zeile kiosk.micro_stop_seconds von fl_setting gelöscht. Das Kriterium für kurze Stopps ist eine Platform-Einstellung (alte Werte werden nicht migriert) |
| V7 | Zugewiesener Bereich. Unten |
| V8 | Index zum seitenweisen Lesen von Audit-Logs pro Person |
| V9 | Verknüpfungsfeld zwischen Bediener-Login und Platform-Mitarbeiter (pp.mm_employee) |
| V10 | Migration von Bedienerkonten zur Platform. Einführung von Login-Cache fl_account_cache und Synchronisationsstatus fl_account_sync; Session verweist nun auf Platform-Mitarbeiter-ID (alte Sessions werden gelöscht — nach dem Update müssen alle Tablets sich neu anmelden). Alte fl_operator · fl_operator_scope werden in V11 gelöscht, nachdem die Migration zur Platform bestätigt wurde |
| V11 | Löschen alter Bediener-Tabellen (fl_operator · fl_operator_scope und zugehörige Historien-Tabellen). Nur bei Installationen (fl_account_sync.imported_at), bei denen die Migration zur Platform als abgeschlossen markiert ist; bei noch nicht migrierten Installationen bleiben sie erhalten |
| V12 | Anlage «Hauptwerte» fl_key_value — bis zu 6 Tags pro Anlage, die zuerst in der Übersicht erscheinen (nur Tag-ID und Reihenfolge, Werte werden aus V5 gelesen) |
| V13 | Kundenlogo fl_brand_logo — jeweils ein PNG für helles und dunkles Design |
| V14 | Zulässige Stufen des Geräte-Standardbereichs fl_device.default_scope_type auf vier erweitert: SITE · AREA · LINE · ASSET (zuvor LINE · ASSET). Bestehende Zeilen bleiben erhalten |
Schema-Umbenennung. Die App führt ALTER SCHEMA frontline RENAME TO pf einmalig als einen einzigen Satz aus, wenn vor Flyway das Schema frontline existiert, aber pf fehlt. Tabellen, Daten, Flyway-Historie und Einstellungen (ai.url · ai.api_key) werden ohne Kopie verschoben. Beim erneuten Start passiert nichts, da pf bereits existiert (Idempotenz). Bei Neuinstallationen erstellt Flyway direkt pf. Wenn beide existieren, wird kein Versuch zur Vermutung unternommen, sondern eine Warnung ausgegeben und pf verwendet. Startet die DB nicht, wird der Vorgang abgebrochen — ein Überspringen würde dazu führen, dass Flyway ein leeres pf erstellt, was wie ein Datenverlust wirkt.
Migration von Bedienerkonten. Vor der ersten Synchronisation nach dem Start werden fl_operator · fl_operator_scope einmalig an V5 POST /app-accounts/frontline/import gesendet. PIN-Hashes werden unverändert übertragen (kein erneutes Hashen). Logins ohne Mitarbeiterverknüpfung führen dazu, dass die Platform einen Mitarbeiter EMP_FL_<로그인 번호> erstellt und zuordnet. Bereits in der Platform vorhandene Login-Nummern werden beibehalten (EXISTS). Der Vorgang gilt als abgeschlossen, wenn alle Zeilen als CREATED · EXISTS zurückkehren, andernfalls erfolgt die Übertragung im nächsten Durchgang (Idempotenz).
Grenzen zur Platform
OEE · Verfügbarkeit · Leistung · Qualität · Stoppzeit · Verlust · MTBF · MTTR basieren ausschließlich auf den Werten von Platform V5. Werte, die von der Platform nicht geliefert werden, bleiben leer, werden als «Keine Daten» angezeigt oder ausgeblendet; sie werden nicht mit 0 oder Schätzwerten gefüllt. Die einzige Berechnung im UI ist der Fortschritt (Gutteile ÷ Soll), Graphen bilden V5-Werte eins zu eins ab und ändern lediglich die Achseneinheiten. Dadurch sehen Tablet, Platform-Web, Report und AI dieselben Zahlen.
- Platform-Daten werden nur über V5 gelesen und geschrieben. Selbst wenn sie sich in derselben
ppDatenbank befinden, werden Platform-Tabellen nicht direkt gelesen oder geschrieben, und es werden keine Kopien der Platform-Daten im Schemapfangelegt. Wartungsaufrufe und Defekterfassungen haben ebenfalls keine Kopien in der App — die Originale sind die Wartungsaufträge und Defekterfassungen in V5. - Einzige Ausnahme — Login-Cache
fl_account_cache. Dieser ist notwendig, damit das Personal vor Ort auch während eines Neustarts der Platform einloggen kann. In anderen Tabellen werden keine PIN-Hashes, Mitarbeiternamen oder Beschäftigungsstatus gespeichert (dies wird durch Tests verhindert). - Keine MES-Funktionen. Bedienerkonten dienen nur als Login-Mittel (Login-Nummer, Rolle, PIN) und zur Definition des zugewiesenen Bereichs (Sichtbarkeit). Der zugewiesene Bereich ist keine Personalzuweisung des MES — Qualifikationen, Schichtpläne, Einzelleistungen oder Personalstatistiken sind nicht enthalten. Aufträge werden ausgewählt und gestartet, pausiert, fortgesetzt, beendet oder abgebrochen (mit Grundcode); die Fertigstellungsrate eines auftragsbasierten Zeitraums wird gemeldet — Erstellung und Bearbeitung erfolgen auf der Platform.
- Im Schema
pfwerden Geräte (inkl. Standardsprache und UI-Theme), grundspezifische Listen, Kiosk-Einstellungen, Schichtnotizen, Audit-Logs, Sessions sowie der Login-Cache (fl_account_cache·fl_account_sync) gespeichert. Die Originale der Bedienerkonten (Login-Nummer, PIN-Hash, Rolle, zugewiesener Bereich, UI-Sprache, Theme) liegen in Platformpp.mm_app_account·pp.mm_app_account_scope. - Bei Aufrufen von V5 wird die Sprache des Benutzers in
Accept-Languageübermittelt. Namen von Stoppgründen, Fehlermodi und Defektursachen werden exakt so angezeigt, wie V5 sie sendet.
Urteilsfindung erfolgt durch Platform
Urteile im UI werden nicht von der App, sondern von V5 vorgegeben. In der App enthaltene Entscheidungslogiken (Soll-Vergleich, Ursprung, Längenvergleich, Auswahl von Schichtfenstern und 8-Stunden-Ersatzfenstern) wurden entfernt.
| Urteil | Quelle in V5 |
|---|---|
| Fenster dieser Schicht | GET /calendar/shift-schedule/current. Auch «Letzte 9 Stunden» bei fehlendem Schichtplan wird von V5 geliefert (bei Wahl von 12 Stunden wird das Fenster entsprechend erweitert). Wenn V5 kein Fenster liefert, zeigt die Karte diese Ablehnung direkt an; die App erfindet kein Fenster |
| Auftrag «Aktueller Plan» | planned_order_id in derselben Antwort |
| Stopp ohne Grund | needs_reason pro Stopp |
| Kurzer Stopp | short pro Stopp. Kriterium ist GET /config/PP_STOP_MICRO_STOP_SECONDS (Standard 60s, Bereich 0~1800; bei 0 wird immer gefragt) |
V5-Aufrufe der App
| Lesen | Verwendung |
|---|---|
GET /site · /asset/lines/by-site/… · /asset/equipments/by-line/… · /path/asset/… | Bereichsauswahl (Standort → Linie → Anlage) |
GET /asset/… · GET /site/… · GET /asset/equipments/by-line/… | Interpretation der Knoten des zugewiesenen Bereichs (Parent-Chain). Soll-Ist-Vergleich der Linie wird über die Anlagenliste abgefragt |
GET /asset/…/status | Status und Dauer |
GET /kpi/oee/status/current · /kpi/period | Schicht-OEE, Dashboard-Periodenkennzahlen |
GET /kpi/daily | Tägliche Trends im Dashboard und Report |
GET /ram/breakdown?by=CAUSE · /failure-dictionary/alarm-cause | Pareto der Fehlerursachen und Ursprachennamen |
GET /asset/…/stops · /asset/…/stop-loss | Timeline, Stopps ohne Grund, kurze Stopps, Verluste nach Stoppgrund |
GET /asset/…/timeline/alarms | Alarm(min_priority, limit=500). Der BFF filtert nur laufende (in den letzten 7 Tagen aktiviert) und heute beendete Alarme |
GET /stop-reasons | Ursachenwörterbuch (Grundtasten, Stoppgrundliste in Einstellungen) |
GET /calendar/shift-schedule/current | Aktuelles Schichtfenster(asset_id). Antwortfelder: from_ts · to_ts · shift_code · shift_date · from_plan · planned_order_id |
GET /config/PP_STOP_MICRO_STOP_SECONDS | Kriterium für kurze Stopps (1 Min. Cache) |
GET /order/query · /order/current-asset · /order/… · /order/…/quantity | Auftragsliste · laufender Auftrag · Details · Menge |
GET /order/…/revisions · /order/…/progress | Änderungsbelege, Historie der Fertigstellungsrate. V5 liefert nur die Personalnummer, der BFF ergänzt den in der Login-Cache gefundenen Namen als names (ansonsten bleibt die Nummer stehen) |
GET /maintenance-orders · /maintenance-orders/options · /maintenance-orders/… | Wartungsboard(open=true&order=asc&limit=100, Filterung nach Bereich · Verantwortlichem), Symptom- und Code-Listen, Bestätigung vor Stornierung |
GET /asset/…/defects/options · /asset/…/defects · /order/…/defects · /defects/… | Liste der Defektursachen, Defekterfassung für Anlagen und Aufträge |
GET /asset/qr/{token} | Token des gescannten QR-Labels → Anlage. Nur vom BFF aufgerufen; Token wird nicht im Log gespeichert |
GET /order/deviation-summary · /defects/summary · /maintenance-orders/summary | Soll-Ist-Vergleich, Defektursachen, Wartungssummary im Report (langsames Lesen) |
GET /order/query nutzt line_id · site_id · status=END,ABORTED · end_since · end_before · include=oee · sort · limit=500 · order_id Filter für den Work-Order-Bildschirm. Das Auslesen des Wartungsboards wird vom BFF für 5 Sek., Wartungs- und Defektoptionen für 60 Sek. im Shared-Cache gehalten und bei Schreiben geleert.
| Schreiben | Verwendung | Header |
|---|---|---|
PUT /asset/{asset}/stops/{started_at}/reason | Erfassung Stoppgründe | Idempotency-Key |
PUT /order/{order}/quantity | Mengenkorrektur (Summe Gutteile · Defekte + Grund) | Idempotency-Key |
POST /order/{order}/start · pause · resume · end | Auftragsübergang. Zeitstempel des Klicks occurred_at (epoch ms) im Body | If-Match (Auftragsversion) |
POST /order/{order}/abort | Auftragsabbruch. abort_code · abort_notes · occurred_at | If-Match · Idempotency-Key |
POST /order/{order}/progress | Meldung Fertigstellungsrate. percent_complete (Ganzzahl 0~100) · note · reported_at | If-Match · Idempotency-Key |
POST /asset/{asset}/maintenance-orders | Wartungsruf(maintenance_kind_code: CORRECTIVE, failure_mode_code · Beschreibung · anfordernde Person) | Idempotency-Key · X-PP-Channel: FRONTLINE |
POST /maintenance-orders/{id}/transition | Übernahme · Reparaturbeginn · Abschluss(status_code + Maßnahme · Bauteil · Fehlercode), Stornierung(status_code: CANCELLED + cancel_reason_code). Version im Body | Idempotency-Key · X-PP-Channel |
POST /asset/{asset}/defects | Defekterfassung | Idempotency-Key · X-PP-Channel |
POST /defects/{id}/cancel | Stornierung Defekterfassung | If-Match · X-PP-Channel |
- Alle Schreibvorgänge übertragen
X-PP-Performed-By: 로그인한 사번. V5 speichert dies alsperformed_by, währendchanged_byals App-Konto bleibt. Auch beim späteren Senden aus der Offline-Warteschlange wird die Personalnummer der klickenden Person übertragen. - Schreibvorgänge werden mit
Idempotency-Keyversehen, damit V5 dieselbe Eingabe bei erneutem Senden aus der Offline-Warteschlange nicht doppelt verarbeitet. - Der Auftragsübergang gleicht die Version über
If-Matchab. Wurde der Auftrag in der Zwischenzeit durch eine andere Person geändert, erfolgt eine 409-Antwort und das UI zeigt «Ein anderer Benutzer hat die Daten bereits geändert». - Auftragsübergänge, -abbrüche und Defekterfassungen übertragen den Zeitpunkt des Klicks. Selbst bei verspätetem Senden aus der Warteschlange bleibt der Leistungszeitpunkt der Zeitpunkt des Klicks.
- «Vorherigen Auftrag beenden und starten» führt dazu, dass der BFF nacheinander
endundstartaufruft. Für jede Hälfte wird ein separater Idempotency-Key verwendet, aber derselbe Klickzeitpunkt. Schlägt der zweite Teil fehl, wird der erste nicht rückgängig gemacht, sondern gemeldet.
Für V5 siehe die API Dokumentation.
Aufruf über QR-Label
Die «In Frontline öffnen»-Seite der Platform Public Page wird über <PP_UI_FRONTLINE_URL>/#/qr/<token> aufgerufen. Die Adresse enthält keine Anlagen-ID.
- Die App entfernt das Token sofort aus der Adresse und speichert es in der sessionStorage dieses Tabs (
fl.qr_pending). Es wird vor dem Login nicht an den Server gesendet. - Nach dem Login wird das Token entnommen und im Body von BFF
POST /api/v1/qr/resolvegesendet — die Übertragung im Pfad würde dazu führen, dass es in jedem Access-Log erscheint. - Der BFF prüft zuerst das Token-Format (base64url 43 Zeichen), sucht die Anlage über V5
GET /asset/qr/{token}und prüft anhand von Bereichs-Chips, ob das Konto/Tablet diese Anlage auswählen darf. - Bei Erfolg verschiebt die App den Bereich auf diese Anlage und öffnet die Ansicht «Jetzt».
| Antwort | Code | Bildschirm |
|---|---|---|
| 400 | qr_token | Kein gültiges Label-Token |
| 404 | qr_unknown | Neu ausgestellt oder Anlage nicht mehr vorhanden |
| 403 | scope_denied | Außerhalb des zugewiesenen Bereichs |
Bedienerkonten V5
Bedienerkonten befinden sich in Platform V5 /api/v5/app-accounts/frontline. Aufrufe sind nur mit ADMIN-Token oder Platform-Master-Key möglich (da PIN-Hashes im Änderungsfeed enthalten sind).
| Aufruf | Verwendung |
|---|---|
GET /app-accounts/frontline | Kontoliste (inkl. Mitarbeitername, Status). Nur-Lese-Tab «Bediener» in der App |
GET /app-accounts/frontline/{employee_id} | Einzeldatensatz (ETag = Version) |
PUT /app-accounts/frontline/{employee_id} | Konto erstellen · ändern (Login-Nummer, Rolle, Erlaubnis, temporäre PIN) |
DELETE /app-accounts/frontline/{employee_id} | Login löschen (Mitarbeiter bleibt bestehen). Der letzte Administrator kann nicht gelöscht werden |
PUT /app-accounts/frontline/{employee_id}/scope | Zugewiesener Bereich — {"all": true} oder {"nodes": [...]} |
POST /app-accounts/frontline/pin/verify | Keypad-PIN-Prüfung. Antwort immer 200 mit Ergebnis(OK · INVALID · LOCKED · DISABLED · PIN_RESET_REQUIRED · EMPLOYEE_INACTIVE · EMPLOYEE_ON_LEAVE) |
POST /app-accounts/frontline/{employee_id}/pin | Eigene PIN ändern (Aktuelle PIN, Neue PIN) |
POST /app-accounts/frontline/{employee_id}/pin/reset | Administrator-PIN-Reset (Temporäre PIN, entsperrt auch Konto) |
POST /app-accounts/frontline/{employee_id}/unlock | Entsperrung |
GET /app-accounts/frontline/changes | Änderungsfeed (Cursor). Der Login-Cache liest diesen Feed |
POST /app-accounts/frontline/import | Migration alter App-Logins (Idempotenz) |
- Login. Bei Erreichbarkeit der Platform ruft der BFF nur
pin/verifyauf. Die Platform verwaltet Fehlversuche, Sperren (5 Min. nach 5 Fehlern), Kündigungen und Beurlaubungen. - Login-Cache.
AccountSyncliest alle 60 Sek. den Änderungsfeed vom Cursor bis zum Ende und gleichtfl_account_cacheab (Snapshot enthält PIN-Hash, Status, Bereich). Der Cache wird nur bei Nicht-Erreichbarkeit der Platform gelesen. Wenn die letzte erfolgreiche Synchronisation länger zurückliegt als inaccounts.offline_daysfestgelegt (Administrator-Kiosk-Ansicht, Standard 7 Tage, Bereich 1~30 Tage), wird der Offline-Login verweigert (Fail-Closed,503 offline_login_expired). - Offline-Fehler. Bei Verwendung des Caches zählt die App falsche PINs lokal (5 Versuche pro Person → 5 Min., 20 Versuche pro Gerät → 15 Min.) und sendet diese nicht an die Platform.
- Offline-Einschränkungen. PIN-Änderungen, Bildschirmsprache und Themes können nur bei Platform-Verbindung geändert werden. Kontobearbeitung, PIN-Reset und Entsperrung existieren nicht in der App (nur über «Mitarbeiter»-Konsole).
- Eigenständig änderbar sind PIN (BFF
PUT /v1/session/pin), UI-Sprache und Theme (PUT /v1/me/preferences) sowie Kontaktdaten und Fotos im «Mein Profil» (PUT /v1/me/profile·PUT /v1/me/photo, Platform-Mitarbeiterinformationen).
In der Hochverfügbarkeit (HA)
Die PG-Meta-Synchronisation der Platform-Redundanz verschiebt auch Frontline-Daten auf den Standby-Cluster.
| Synchronisiert | Nicht synchronisiert (pro Knoten) |
|---|---|
Bedienerkonten und zugewiesene Bereiche pp.mm_app_account · pp.mm_app_account_scope (inkl. PIN-Hash) | Sessions · Geräteregistrierungs-Codes · Audit-Logs · Schichtnotizen · Idempotency-Aufzeichnungen |
Kiosk-Einstellungen pf.fl_setting · anlagenspezifische Stoppgrundlisten pf.fl_asset_reason_list · registrierte Tablets pf.fl_device | Login-Cache fl_account_cache · fl_account_sync — wird pro Knoten über den eigenen Platform-Änderungsfeed gefüllt |
AI-Key(ai.api_key in fl_setting) nur bei metasync.include.tokens=true |
Bei Platform-Neustart
Ein Neustart der Platform dauert i. d. R. 1~3 Min., maximal 10 Min. Die App bleibt währenddessen aktiv.
- Wenn der BFF V5 oder die eigene DB nicht erreicht, signalisiert er dies über
503und den HeaderX-FL-Offlineals «Momentan nicht verfügbar». Dies ist von einer Ablehnung (4xx) zu unterscheiden. - Das Web signalisiert dies als Verbindungsabbruch; die UI zeigt die letzten Werte zusammen mit dem Zeitpunkt des Erhalts an (z. B. «Stand vor 3 Min.»). Es werden keine erfundenen Werte angezeigt — nur die zuletzt vom BFF gelieferten Daten.
- In die Warteschlange eingereiht werden: Stoppgründe, Auftragsübergänge (inkl. Abbruch), Meldungen der Fertigstellungsrate, Wartungsrufe und Defekterfassungen. Eingaben, die denselben Auftrag oder Stopp betreffen, wahren die Reihenfolge. Wird ein Element abgelehnt, werden nachfolgende Elemente nicht gesendet, bis eine menschliche Entscheidung vorliegt.
- Die Wiederherstellung erfolgt durch Abfragen von
/api/healthin Intervallen von 2 · 4 · 8 · 15 Sek. (danach alle 15 Sek.). Wenn sowohl DB als auch Platform den StatusUPmelden, wird die Verbindung wiederhergestellt, die Warteschlange gesendet und die UI aktualisiert. - Mengenkorrekturen, Wartungsphasenübergänge, Stornierungen von Wartungsrufen und Defekterfassungen werden nicht in die Warteschlange eingereiht, da diese Schreibvorgänge auf dem aktuellen Wert und der Version basieren und nur im verbundenen Zustand akzeptiert werden. Die Stornierung eines Wartungsrufs, der sich noch in der Warteschlange befindet, erfolgt durch Löschen aus der Warteschlange.
- Timeouts für V5-Lesevorgänge liegen bei 2 Sek. für die Verbindung und 5 Sek. für die Antwort. Nur für schwere Zusammenfassungen im Report (Soll-Ist, Defekte, Wartung) wird bis zu 20 Sek. gewartet. Ein Timeout führt nicht zum globalen Verbindungsabbruch — nur diese Karte schlägt mit
504 platform_slowfehl.
PlantPulse AI Chat
Die Funktion «AI fragen» auf dem Tablet wird vom BFF an die Frontline-Chat-API von PlantPulse AI weitergeleitet. Da dies eine separate Verbindung zur Platform V5 ist, führt ein langsamer AI-Dienst oder ein Ausfall nicht zu einem Verbindungsabbruch der Platform.
| BFF | AI-Seite | Verwendung |
|---|---|---|
GET /api/v1/chat/capabilities | GET /api/v1/chat/capabilities | Sichtbarkeit der Schaltfläche (60 Sek. Cache). Personen ohne Bereich können die AI nicht fragen («Kein Bereich») |
POST /api/v1/chat/stream | POST /api/v1/chat/stream | Empfängt Antwort via SSE und leitet diese direkt weiter |
POST /api/v1/chat/cancel | POST /api/v1/chat/cancel | Stop. Nur für Konversationen derselben Person |
- Adresse und Schlüssel liegen in DB
fl_settingunterai.url·ai.api_key(Einstellungen → AI). Der Schlüssel wird nur überX-API-Keyübertragen und nicht in Logs, Antworten oder Exception-Texten gespeichert. - Die Anfrage enthält die Personalnummer des Logged-in-Benutzers als «Fragesteller» (gleicher Wert wie
X-PP-Performed-By) sowie dessen Bereich (gleiche Regeln wie die Bereichsprüfung). Ohne Bereich erfolgt kein Aufruf der AI (403). - Die UI-Sprache wird in
Accept-Languageübertragen.
Authentifizierung — Drei Ebenen
| Ebene | Beschreibung | Ort |
|---|---|---|
| Platform-Key | Platform-Master-API-Key. Nur der BFF besitzt diesen | Container-Umgebungsvariable PP_MASTER_API_KEY |
| Gerätetoken | Zufallszahl bei Geräteregistrierung. Nur der Hash wird in der DB gespeichert. Läuft nicht ab; endet bei Deaktivierung durch Administrator. Übertragen in Authorization: Bearer | localStorage des Browsers(fl.device_token). Bei anderen Browsern, Inkognito-Modus oder nach Löschen der Browserdaten als nicht registriert erkannt |
| Bediener-Session | Gestartet mit Login-Nummer + PIN. PIN wird durch Platform geprüft (bei Nicht-Erreichbarkeit über Login-Cache). Session verweist auf Platform-Mitarbeiter-ID, gültig bis zum Auto-Logout und an Gerätetoken gebunden. Übertragen in X-FL-Session | sessionStorage des Tabs — bleibt bei Refresh erhalten, endet beim Schließen des Tabs (bei fehlendem Speicher: im Arbeitsspeicher) |
- Platform V5 akzeptiert keine USER-Rollen-Token (nur ADMIN · API). Daher kann jedem Benutzer kein eigenes Platform-Token zugewiesen werden; es wird ein einziger Master-Key verwendet. Die Identität des Ausführenden wird sowohl in
performed_by(sieheX-PP-Performed-By) der V5-Historie als auch im Audit-Log der App (fl_audit— Personalnummer · Gerät · V5-Pfad · Antwortcode · Idempotency-Key) protokolliert. - In den Platform-Audit-Logs werden Aufrufe dieser App durch den Akteur
master-api-keyund in Proxy-Logs durch den User-AgentPlantPulse-frontline-web/<version>unterschieden. - Alle BFF-Handler spezifizieren ihr Zugriffslevel — fehlt eine Angabe, ist der Zugriff standardmäßig verweigert.
- Token und PIN werden nicht in Logs, Antworten oder Exception-Texten gespeichert.
Rollenprüfung
Zulässige Rollen werden in jedem Handler über @Access definiert. Unabhängig vom Ausblenden von Schaltflächen im UI blockiert der Server den Zugriff erneut.
| Aktion | Zulässige Rollen |
|---|---|
| Übernahme Wartung · Reparaturbeginn · Abschluss | Wartung · Administrator |
| Auftragsabbruch | Vorarbeiter · Administrator |
| Wartungsruf · Stornierung Wartungsruf · Defekterfassung · Stornierung Defekterfassung | Alle vier Rollen. Stornierungen werden vom Handler erneut geprüft — muss eigener Ruf oder Vorarbeiter · Administrator sein |
Einstellungen(/v1/admin/) | Administrator |
Bereichsprüfung
Nach der Rolle wird der zugewiesene Bereich geprüft. Alle Anfragen vor Ort durchlaufen zentral scope/ScopeInterceptor (nach dem Authentifizierungs-Interceptor).
- Prüfobjekte sind Anlagen, Linien, Aufträge (Anlage via V5 geprüft), Wartungsaufträge und Defekterfassungen in Pfad oder Query. Lesezugriffe müssen im Bereich liegen, Schreibzugriffe müssen
RWsein. - Außerhalb des Bereichs erfolgt eine
403 scope_denied, bei versuchtem Schreiben in einem Nur-Lese-Bereich eine403 scope_read_only. @OpenToReadOnly(Wartungsruf, Stornierung Wartungsruf) werden nur auf Leseebene geprüft, da Personen mit «Leserechten» für eine Anlage diese ebenfalls anrufen können. Die Stornierung fremder Rufe wird durch den Handler blockiert.- Login-Bereich = Kontobereich ∩ Geräte-Standardbereich(
ScopeGuard.within). Wenn der Kontoknoten mit dem Gerätenoten identisch ist oder darunter liegt, bleibt er unverändert. Liegt er darüber, wird der Gerätenoten als Zugriff für diesen Kontoknoten gesetzt. Nicht überlappende Knoten werden verworfen. Ist das Kontoscope_all, gilt der GerätenotenRW. Das Gerät erweitert den Bereich nicht und hebtROnicht aufRWan. Geräte ohne Administratorrolle und Standardbereich schränken den Zugriff nicht ein. Der Geräte-Standardbereich kann auf jeder Ebene liegen: Standort · Zone · Linie · Anlage(DeviceScope). - Knoten werden nach unten vererbt. Erhält eine Anlage sowohl
RWals auchRO, gewinntRW. Knoten werden über V5 aufgelöst und für 5 Min. gespeichert. In V5 gelöschte Knoten haben Zugriff 0. - Dashboard und Report erfordern, dass der Knoten selbst im Bereich liegt. Der Zugriff auf eine einzelne Anlage schaltet nicht das Dashboard der gesamten Linie frei.
- Listen werden vom Handler eingeschränkt — Bereichsbaum, Linienkarten · Alarmzahl, Work-Order (mit beigefügtem access pro Zeile), Wartungsboard.
- Es gilt Fail-Closed. Ohne
scope_allund ohne Knoten kann nichts gelesen werden. Bereiche stammen aus dem Platform-Konto(pp.mm_app_account.scope_all·pp.mm_app_account_scope); die App besitzt keine API zur Bereichsänderung. V5 interpretiert leere Knotenlisten als «Keine Daten», maximale Knotenanzahl ist 200. - Die Administratorrolle hat globalen Zugriff ohne Bereichsprüfung. Die Administrations-API(
/v1/admin/) überspringt die Bereichsprüfung und prüft nur die Administratorrolle. - Nicht eingeloggte Tablets («Jetzt-Ansicht ohne PIN») lesen den Geräte-Standardbereich über
RO.
Die Login-Antwort enthält vier Feldern für den Bereich.
| Feld | Bedeutung |
|---|---|
scope | {"all": true} oder Knotenliste(id · kind · access) |
scope_none | Über dieses Tablet ist nichts sichtbar — das Web zeigt nur Hinweise und Logout ohne Menü |
scope_none_reason | Grund für scope_none. ACCOUNT bedeutet Konto hat keinen Bereich («Bereich nicht zugewiesen»), TABLET bedeutet Kontobereich überlappt nicht mit Tablet-Bereich («Kein für dieses Tablet sichtbarer Bereich») |
home_scope | Erste Anlage oder Linie, die geöffnet wird, wenn der Startbereich (zuletzt gewählter, sonst Geräte-Standard) außerhalb des Benutzerbereichs liegt |
Umgebungsvariablen
| Variable | Beschreibung |
|---|---|
PP_TZ | Anzeige-Zeitzone (Erforderlich). Speicherung erfolgt in UTC epoch, Anzeige in dieser Zeitzone. Datumswechsel, «Heute» und Datumsbündelung von Fenstern über Mitternacht folgen dieser Zeitzone |
PP_LANG | Installationssprache (Erforderlich). Muss ein Tag aus der Liste der unterstützten Sprachen sein (aktuell ko · en), inklusive Groß-/Kleinschreibung und regionaler Varianten(en-US). Startet nicht, wenn Sprache nicht in der Liste ist |
PP_SERVER_URL | Platform V5 Adresse |
PP_MASTER_API_KEY | Platform-Master-API-Key. Gleicher Wert wie server-web · batch-web · warehouse-web — bei Änderung müssen alle vier gemeinsam neu gestartet werden |
PP_POSTGRES_HOST · PP_POSTGRES_PORT | Data Lake PostgreSQL |
PP_DB_NAME · PP_PG_USER · PP_PG_PASSWORD | Platform-Datenbank(pp) und Konto. Gleicher Name · gleicher Wert wie server-web · batch-web · warehouse-web. Es gibt keine exklusiven Konten/Passwörter für frontline |
Ohne PP_MASTER_API_KEY · PP_PG_PASSWORD · PP_POSTGRES_HOST startet der Container nicht. Der JVM-Heap ist auf 512 MB (direct 128 MB) fixiert. Es wurden keine neuen Variablen für Bereich, Wartung, Defekt oder Report eingeführt.
Um eine neue UI-Sprache hinzuzufügen, wird web/src/i18n/<태그>.json in das Web-Bundle eingefügt und eine Zeile zur unterstützten Sprachenliste des Servers hinzugefügt. Das Schema (V5) wird nicht geändert.
In künftigen Versionen geplante Felder
Die folgenden Felder sind noch nicht in der App vorhanden. Es gibt keinen Platz im UI; sie werden implementiert, sobald die Platform allgemeine V5-APIs bereitstellt und Aufrufe im BFF ergänzt werden.
| Feld | Aktuell | Erforderlich in Platform |
|---|---|---|
| Wöchentliche Trends · Vergleich mit Vorperiode | Nicht vorhanden (Tägliche Trends über /kpi/daily implementiert) | Zeitreihen auf Wochenbasis |
| Energie (EMS) | Nicht vorhanden — weder Dashboard-Tab noch Report-Abschnitt | EMS API |
| Linienweite Verluste nach Stoppgrund | Nicht vorhanden — nur pro Anlage dargestellt | Aggregierte Stoppverluste auf Linienebene |
| Ist-Soll pro Stunde | Nicht vorhanden | Zeitstunden-Soll-Ist-API |
| Schichtverlust-Wasserfall | Nicht vorhanden — Schicht-OEE-Fenster enthält nur OEE · Verfügbarkeit · Leistung · Qualität und Top-Stoppgründe | Verlustzerlegung |
| Manuelle Stoppregistrierung · Mengen pro Zeitintervall | Nicht vorhanden | Pfade zum Schreiben von Stopps und Zeitintervallmengen |
Folgende Felder, die zuvor in dieser Tabelle standen, wurden implementiert:
| Feld | Implementierungsmethode |
|---|---|
| Urheber (Personalnummer im Platform-Log) | X-PP-Performed-By bei allen Schreibvorgängen → V5 performed_by |
| Wartungsruf → Übernahme → Reparaturbeginn → Abschluss | V5 /maintenance-orders |
| Defektmenge + Grund | V5 /defects |
| Tägliche Trends | V5 /kpi/daily |
| Schicht-, Tages- und Wochenreports | BFF GET /v1/report bündelt KPI-, Auftrag- und Summary-APIs von V5 |