Mobile PWA für Baustellen-Doku — Foto-Upload, Sprachnotizen, Skizzen, offline-fähig. SvelteKit + Workbox.
Find a file
Eddy f560fd3a58
All checks were successful
Deploy baustelle-pwa / deploy (push) Successful in 14s
Doku: README auf SSO/awlauth + Neuer-Auftrag-Flow aktualisiert [deploy]
- Auth-Doku von JWT auf zentrales SSO (HttpOnly-Cookie awl_sso, same-origin)
  umgestellt: Stack, Feature-Login, lib-Beschreibung, /auth.php, photo.php/pdf.php
  (?jwt= entfaellt, Cookie wird same-origin auch fuer img/object mitgeschickt)
- Feature 'Neuer Auftrag' dokumentiert (Ihr Zeichen/Beschreibung/Liefertermin/Freigabe)
2026-07-18 14:55:34 +02:00
.forgejo/workflows CI: Ntfy-Benachrichtigungen (Start/Success/Failure) via data/ntfy-action 2026-05-28 06:54:44 +02:00
icons feat: Neues PWA-Logo — Klemmbrett mit Schraubenschlüssel (SVG + PNG) 2026-04-09 01:12:47 +02:00
lib Baustelle-PWA: SSO-Migration auf awlauth (JWT -> awl_sso-Cookie) 2026-07-06 15:25:53 +02:00
.gitignore feat: Initiales Release Baustelle PWA v1.0.0 [deploy] 2026-04-08 22:50:01 +02:00
app.css Feature: Live-Kamera (Schnellschuss + Filmstreifen), Datenverlust-Schutz (Persist-First) [deploy] 2026-07-03 10:46:36 +02:00
app.js Fix: Neuer-Auftrag-Formular oben statt mittig + Tastatur-Handling [deploy] 2026-07-18 13:53:26 +02:00
index.php PWA-Login: Fingerabdruck-/Passkey-Anmeldung (WebAuthn) [deploy] 2026-07-07 15:41:37 +02:00
manifest.webmanifest feat: PWA Cache-Busting via filemtime (claude-db #201) — kein manuelles Hochzählen mehr 2026-04-09 01:26:26 +02:00
README.md Doku: README auf SSO/awlauth + Neuer-Auftrag-Flow aktualisiert [deploy] 2026-07-18 14:55:34 +02:00
share.html feat: Phase 4 Block 1 — Seite bearbeiten, PDF-Vorschau, Unterschrift, Share Target 2026-04-09 01:00:24 +02:00
sw.js feat: PWA Cache-Busting via filemtime (claude-db #201) — kein manuelles Hochzählen mehr 2026-04-09 01:26:26 +02:00

Baustelle PWA

Mobile Progressive Web App für die Baustellen-Doku — Foto-Upload, Sprachnotizen, Skizzen, offline-fähig. Spricht die REST-API des Dolibarr-Bericht-Moduls.

Stack

  • Vanilla JavaScript — kein Build, keine Framework-Abhängigkeit
  • Service Worker für App-Shell-Cache (Workbox-frei, eigene Implementierung)
  • IndexedDB für die Offline-Upload-Queue (Auth-Session steckt im HttpOnly-Cookie, nicht in IndexedDB)
  • REST API des bericht-Dolibarr-Moduls unter /custom/bericht/api/

Features

Aufträge

  • Login mit Dolibarr-Credentials → zentrales SSO (HttpOnly-Cookie awl_sso, same-origin; Single-Sign-On/-Logout über alle AWL-Apps). WebAuthn/Passkey-Login möglich
  • Auftragsliste mit Suche, gefiltert auf eigene Aufträge (Multi-User)
  • Toggle "Auch abgeschlossene" (Filter in localStorage persistiert)
  • Auftragsdetail mit Kunde, Adresse, Telefon (Click-to-Call)
  • Neuer Auftrag (FAB): Kunde per Suche/Zuletzt-verwendet wählen, dann Ihr Zeichen (Pflicht), Auftragsbeschreibung (optional), Geplanter Liefertermin (Datum + Uhrzeit) und Checkbox Auftrag direkt freigeben. Kunden-Defaults (Zahlungsbedingung/Zahlart, Ansprechpartner) werden übernommen. Bei „direkt freigeben" hängt das Backend automatisch eine Std-Lohn-Zeile an (Kundenkarten-Default bzw. Fallback-Produkt, kundenspezifischer Preis) und validiert den Auftrag.

Foto-Upload

  • Live-Kamera-Modal (getUserMedia): bleibt für Serien-Aufnahmen offen — Auslöser + Filmstreifen mit Upload-Status je Foto (💾 gesichert → lädt hoch → ✓ fertig), Front-/Rückkamera-Umschaltung, Fehlschuss löschbar
  • Alternativ Aufnahme aus der Galerie
  • Clientseitige Bild-Verkleinerung auf 2000px (JPEG q=0.85)
  • Persist-First / Datenverlust-Schutz: jedes Foto wird beim Auslösen ZUERST in IndexedDB gesichert, Upload erst danach; Queue-Item wird nur nach bestätigtem Upload (HTTP 2xx mit gültigem relpath) gelöscht — überlebt fehlendes/schwaches Netz, hängende Uploads (45s-Timeout) und App-Kill. Erkennt 2xx-HTML (abgelaufene Session/Proxy-Loginseite) als Fehler statt als Erfolg
  • Auto-Sync bei "online", periodisch (15s) und bei App-Fokus; Status-Badge (🟢 alles gesichert / 🟡 lädt hoch / 🔴 offline / ⚠️ fehlgeschlagen)
  • Recovery: Tipp auf das Status-Badge öffnet die Warteschlange → erneut senden / teilen; Warnung beim Schließen mit noch ungesicherten Fotos
  • Foto-Viewer mit Zoom + Swipe
  • Foto-Skizze: Annotationen mit Pfeilen, Kreisen, Rechtecken, Text

Sprachnotizen

  • Sprachaufnahme via MediaRecorder (webm)
  • Whisper-Transkription (serverseitig, API-Aufruf)

Berichte

  • Berichte pro Auftrag anzeigen
  • Bericht erstellen mit Template-Auswahl
  • Seiten umordnen per Drag&Drop
  • Seite löschen, Notiz bearbeiten
  • Touch-Unterschrift abnehmen (mit GPS + Name)
  • Bericht finalisieren → PDF-Vorschau
  • PDF-Download

Lieferungen + Kundenunterschrift

  • Lieferungen-Liste pro Auftrag mit Status + Signed-Badge
  • Lieferschein-PDF inline (PDF.js, alle Seiten)
  • Vollbild-Querformat-Unterschrift mit HiDPI-Canvas, transparent (kein Hintergrund)
  • Trimmt Canvas automatisch auf bemalte Fläche
  • Name des Unterzeichners aus Kundendaten vorausgefüllt
  • GPS-Koordinaten (optional, timeout 3s)
  • Unterschrift wird via ODT-Hook in das Lieferschein-PDF gestempelt
  • Expedition wird nach Unterschrift automatisch validiert + geschlossen
  • Signed-PDF direkt nach Bestätigung als Vorschau

Materialliste

  • Material pro Auftrag erfassen (Label, Menge, Einheit, Notiz)
  • Material löschen

PWA

  • Service Worker für Offline-Start
  • Installierbar als PWA (Home-Screen-Icon)
  • Web Share Target API (Fotos aus anderer App teilen)
  • Nativer Android-Share-Sheet für Fotos, PDFs und Dokumente (navigator.share) — direkt an WhatsApp / Signal / Mail
  • Mehrfachauswahl in Foto- und Dokument-Liste mit Batch-Teilen
  • Android-Hardware-Back-Button schließt Modale/Ansichten sauber (History-Modal-Stack), bricht Mehrfachauswahl ab statt App zu verlassen
  • „Nochmal drücken zum Beenden"-Toast auf Top-Level-Routen
  • PIN-Schutz (optional)

Geplant

  • Push-Notifications für neue Aufträge

Hosting

Deploy per Forgejo-Pipeline (Commit-Tag [deploy]) nach /mnt/appdata/firma/dolibarr-202509/modules/baustelle/. Erreichbar unter https://awl.data-it-solution.de/custom/baustelle/. Cache-Busting automatisch via filemtime() in index.php (?v=<mtime> an JS/CSS) — kein manuelles Versions-Hochzählen nötig, die PWA aktualisiert sich beim nächsten Laden.

Verzeichnis-Struktur

baustelle-pwa/
├── index.php              App-Shell (Cache-Busting via filemtime → ?v=<mtime>)
├── share.html             Web-Share-Target-Empfänger
├── manifest.webmanifest   PWA Manifest
├── sw.js                  Service Worker (Network-First, API pass-through)
├── app.js                 Hauptlogik (Routes, Views)
├── app.css                Mobile-first Styling
├── lib/
│   ├── idb.js             IndexedDB-Wrapper (Foto-Queue)
│   ├── api.js             REST-API-Client (SSO-Cookie same-origin, JSON-Guard, Timeout)
│   ├── offline.js         Offline-Queue + Sync (Persist-First)
│   ├── router.js          Hash-Router
│   ├── pdf.min.js         PDF.js (Lieferschein-Vorschau)
│   └── pdf.worker.min.js  PDF.js Worker
└── icons/
    ├── icon-192.png
    └── icon-512.png

API

Die App spricht die Bericht-API unter /custom/bericht/api/:

Auth

  • POST /auth.php — Login mit Dolibarr-Credentials → setzt HttpOnly-Cookie awl_sso (zentrales SSO via awlauth). Folge-Requests authentisieren same-origin über das Cookie (kein Bearer-Token)

Aufträge

  • GET /orders.php — Aufträge des Users (Filter: ?open=1, ?q=suche)
  • GET /orders.php?id=X — Auftrag-Detail inkl. verknüpfte Berichte
  • GET /orders.php?id=X&action=photos — Anhang-Liste
  • POST /orders.php?id=X&action=upload_photo — Foto-Upload (multipart)

Kunden

  • GET /customers.php — Kundenliste (Filter: ?q=suche)
  • GET /customers.php?id=X — Kundendetail

Berichte

  • GET /reports.php — Alle Berichte des Users
  • GET /reports.php?id=X — Bericht-Detail mit Seiten
  • POST /reports.php?action=create — Neuen Bericht anlegen
  • POST /reports.php?id=X&action=finalize — Bericht finalisieren
  • DELETE /reports.php?id=X — Bericht löschen

Seiten

  • DELETE /pages.php?id=X — Seite löschen
  • POST /pages.php?id=X — Seite aktualisieren (note, rotation)
  • POST /pages.php?action=signature&bericht_id=X — Unterschrift hinzufügen
  • POST /pages.php?action=reorder — Seiten umordnen

Material

  • GET /materials.php?element_type=X&element_id=Y — Materialliste
  • POST /materials.php?element_type=X&element_id=Y — Material hinzufügen
  • POST /materials.php?id=X&delete=1 — Material löschen

Lieferungen

  • GET /shipments.php?order_id=X — Lieferungen zu einem Auftrag
  • GET /shipments.php?id=X — Lieferung-Detail (inkl. bericht_id falls Unterschrift vorhanden)
  • GET /shipments.php?id=X&action=pdf[&variant=auto|signed|unsigned] — Lieferschein-PDF
  • POST /shipments.php?id=X&action=confirm — Kunden-Unterschrift einstempeln (FormData mit signature_png, signer_name, gps_lat, gps_lon, signed_at). Backend setzt signed_status=1 und schließt die Expedition

Medien

  • GET /photo.php?relpath=X — Foto abrufen (mit Thumbnail: &size=thumb); Auth über awl_sso-Cookie (same-origin, auch für <img>-Tags — kein ?jwt= mehr nötig)
  • POST /delete_photo.php — Foto löschen
  • POST /voice.php?order_id=X — Sprachnotiz hochladen
  • POST /transcribe.php — Whisper-Transkription anfordern
  • GET /pdf.php?id=X — PDF abrufen (Final oder Preview); Auth über awl_sso-Cookie (same-origin)

Templates

  • GET /templates.php — Bericht-Vorlagen
  • GET /odt_templates.php — ODT-Deckblatt-Vorlagen

Lizenz

GPL v3+