Feedback-Modul
Zweck
Das Feedback-Modul ermöglicht es Anwendern, Bugs, Feature-Wünsche und Verbesserungsvorschläge strukturiert zu melden — mit Screenshot, mehreren Bild-Anhängen, markiertem UI-Element und Vorgangs-Aufzeichnung. Im Standard sehen Anwender nur ihre eigenen Meldungen; Admins mit do:ViewAllFeedback sehen alle.
Das Tool ist als kleiner Feedback-Button im App-Footer unten rechts immer sichtbar. Klick öffnet ein Drawer, das den User durch Kategorie/Titel/Beschreibung/Priorität/Screenshot/Anhänge/Recording führt. Drafts werden lokal gespeichert und überleben das Schließen des Drawers.
Operative Anleitung: Feedback melden — Bugs, Features, Verbesserungsvorschläge.
Voraussetzungen
Berechtigungen (CASL)
Frontend-Page-Guard (/feedback):
| Action | Subject | Wirkung |
|---|---|---|
view | FE_Feedback | Modul-Route aufrufbar |
view | Feedback | Liste sichtbar |
API-Datenzugriff:
| Action | Subject | Wirkung |
|---|---|---|
view | Feedback | eigene Feedbacks lesen |
create | Feedback | neue Meldung anlegen |
update | Feedback | Meldung bearbeiten (Status/Priorität — typisch nur Admin) |
delete | Feedback | löschen (Soft-Delete) |
do | ViewAllFeedback | alle Feedbacks aller User sehen (Power-Permission, typisch nur IT/Kevin) |
Sichtbarkeits-Logik (BE): Ohne do:ViewAllFeedback filtert die API automatisch auf reportedBy === currentEmployeeId. Implementierung in api.speamcore.com/src/services/feedback.service.ts.
Datenmodell
| Feld | Typ | Bedeutung |
|---|---|---|
id | UUID | Primary Key |
sequenceId | Number | fortlaufend pro Mandant |
type | enum | bug | feature_request | improvement |
status | enum | open | in_review | planned | in_progress | done | rejected | forwarded (Default: open) |
priority | enum nullable | low | medium | high | critical (primär für Bugs) |
title | String, max. 255 | Kurz-Titel |
description | Text, nullable | ausführliche Beschreibung |
developerStatusNote | Text nullable | Antwort/Notiz des Entwickler-Teams — nur dieses darf schreiben (read-only für den Melder). |
developerStatusUpdatedAt | DateTime nullable | wann die Entwickler-Notiz zuletzt geändert wurde. |
masterId | UUID nullable | Verweis auf die Admin-Master-Row. Wird beim Reporter direkt nach dem Anlegen vorgestempelt (eigene id) und nach dem Push/Sync gesetzt — daran erkennt das System die gespiegelte Cross-Mandanten-Kopie. |
originTenantId | UUID nullable | nur auf dem Entwickler-Mirror gefüllt: ID des Reporter-Mandanten (woher das Feedback kam). Auf der Reporter-eigenen Row null. |
originTenantName | String nullable | Snapshot des Reporter-Mandantennamens für die Anzeige beim Entwickler. |
screenshotDocumentId | UUID nullable | FK → Document mit dem Screenshot |
targetSelector | String nullable | CSS-Selector / DOM-Pfad des markierten Elements |
route | String nullable | URL-Pfad zur Zeit der Meldung |
metadata | JSON nullable | Browser, OS, Viewport, App/API-Version, Bounding-Box des Elements |
reportedBy | UUID | Employee.id (auto aus Token) |
createdAt, updatedAt, deletedAt | DateTime | Standard-Zeitstempel + Soft-Delete |
Status-Workflow + Entwickler-Antwort (seit Juni 2026)
Das Feedback durchläuft die Stufen open → in_review → planned → in_progress → done (oder rejected). Zusätzlich gibt es forwarded: Der Admin leitet das Feedback automatisch an den Entwickler-Mandanten (reporter.primaryTenantId) weiter; dort wird es per Standard-Sync gezogen und beim Annehmen auf in_progress gesetzt. Das Entwickler-Team kann eine Antwort/Notiz hinterlegen (developerStatusNote), die beim Melder read-only angezeigt wird — so sieht der Melder den Bearbeitungsstand und die Rückmeldung der Entwickler.
Cross-Mandanten-Spiegelung (Reporter ↔ Entwickler)
Technisch läuft die Weiterleitung als bidirektionale Spiegelung über die drei Felder masterId, originTenantId und originTenantName:
- Reporter-Seite: Beim Anlegen stempelt ein
afterCreate-HookmasterIdvor und schiebt die Meldung (samt Screenshot) zum Admin. Dort entsteht die Master-Row. - Entwickler-Seite: Der Admin zieht die Master-Row in den Entwickler-Mandanten und setzt dabei
originTenantId+originTenantName— der Entwickler sieht also, von welchem Mandanten die Meldung stammt. Auf diesem Mirror darf der Entwickler nurstatus,priority,developerStatusNoteunddeveloperStatusUpdatedAtändern; der Rest (Reporter-Inhalt) ist read-only. - Rückweg: Änderungen an Status/Notiz werden automatisch zurück zum Admin und von dort zur Reporter-Row synchronisiert — der Melder sieht die Entwickler-Antwort read-only.
Module-Architektur
Screenshot-Strategie (dreistufige Fallback-Kette)
Beim Klick auf Screenshot aufnehmen läuft eine dreistufige Strategie, die je nach Plattform den qualitativ besten Pfad wählt:
| Stufe | Plattform | Technik | Ergebnis |
|---|---|---|---|
| 1 | iOS-/Android-App (Capacitor) | WKWebView.takeSnapshot() bzw. View.draw(Canvas) (Native Plugin) | Echtes Compositor-Bild, keine Permission-Prompts |
| 2 | Desktop-Browser | navigator.mediaDevices.getDisplayMedia() | Pixel-genauer Compositor-Output, Browser zeigt Tab-Picker |
| 3 | Fallback (alte Browser, blockierte Stufe 2) | html2canvas mit 3-2-1-Countdown | DOM-Clone, kann bei backdrop-filter/oklch/Custom-Fonts Artefakte zeigen |
Stufen 1 und 2 erkennt der Code per Feature-Detection (Capacitor.isNativePlatform() und navigator.mediaDevices?.getDisplayMedia). Der Drawer wird beim Native-Capture 80 ms vor dem Snapshot ausgeblendet; bei html2canvas werden [data-feedback-ui="true"]-Elemente per ignoreElements ausgespart.
Custom-Bild-Anhänge
Zusätzlich zum Screenshot kann der User beliebig viele weitere Bilder über den Button „Bild hinzufügen" an die Meldung hängen:
- File-Picker mit
accept="image/*"undmultiple— also Mehrfach-Auswahl in einem Schritt. - Jeder Anhang erhält UUID, Blob, Dateiname und eine Preview-URL (
URL.createObjectURL). - Thumbnail-Galerie 96 × 96 px mit Remove-Button pro Anhang.
- Upload-Verhalten: Anhänge werden nach der erfolgreichen Feedback-Erstellung parallel hochgeladen (
POST /api/documentsmitparentType="Feedback",parentId=<feedbackId>,documentType="image"). Schlägt ein einzelner Upload fehl, wird das per Warn-Log dokumentiert — das Feedback selbst bleibt gültig. - Im Detail-Modal lädt die Sicht die Anhänge per
listDocuments(parentType=Feedback, parentId=...)und dedupliziert sie gegenscreenshotDocumentId.
Draft-Persistenz
Solange der User das Drawer nicht absichtlich verwirft, bleibt die Meldung lokal erhalten:
- Storage-Key:
speamcore.feedback.draft.v1(localStorage) - Persistierte Felder:
type,title,description,priority,picked(markiertes Element),savedAt - Nicht persistiert:
screenshotBlobundattachments(Blob-Größen würden das localStorage-Quota sprengen) - Auto-Save: bei jeder Änderung der persistierten Felder, sofern Inhalt vorhanden
- TTL: 7 Tage — ältere Drafts werden beim nächsten Öffnen verworfen
- Cleanup: Drawer schließen → Draft bleibt; Verwerfen-Button und erfolgreicher Submit → Draft gelöscht; Confirm-Dialog beim Verwerfen, falls Inhalt vorhanden
Recording (Vorgangs-Aufzeichnung)
Die Vorgangs-Aufzeichnung erfasst die User-Interaktion in der App — keine Bildschirm-Aufnahme, sondern eine strukturierte Click-Sequenz:
- Listener auf
pointerdown(capture phase) — fängt Klicks früher alsclickund erkennt auch synthetische Events. - Element-Resolve via
closest(INTERACTIVE_SELECTOR)(Buttons, Links, Inputs, ARIA-Rollen) — leere Container-Klicks werden gefiltert. - Feedback-UI ist explizit ausgeschlossen über
data-feedback-ui="true". - De-duping: doppelte Klicks innerhalb von 250 ms auf das gleiche Target werden zusammengefasst.
- Pro Schritt erfasst:
id,timestamp(ISO),url(Pfad + Query),selector(via@medv/finder),tagName,innerText(gekürzt auf 200 Zeichen), Bounding-Box.
Verwandte Doku
- Feedback melden — Bugs, Features, Verbesserungsvorschläge — operativer Workflow
- App-Footer — Versionen und Feedback
- Multi-Mandanten — Mandanten-Trennung der Meldungen
- KI-Chat-Aktionen — KI-gestütztes Ausarbeiten der Meldung
Versionshinweise
- 2026-06-11: Cross-Mandanten-Spiegelung dokumentiert — neue Felder
masterId,originTenantId,originTenantNameund die bidirektionale Reporter ↔ Entwickler-Synchronisation (Pre-Stamp beim Reporter, Entwickler-Mirror mit Herkunfts-Snapshot, Rückweg der Status-/Notiz-Änderungen). Verifiziert anfeedback.model.ts(after-Hooks, Field-Lock) undFeedback.ts(Client-Modell). - 2026-06-09: Status
forwarded(Weiterleitung an Entwickler-Mandant) + Entwickler-Antwort (developerStatusNote/developerStatusUpdatedAt, nur Entwickler schreibt) dokumentiert; Status-Workflow ergänzt. Verifiziert anfeedback.model.ts. - 2026-05 (Welle 96): Initiale Doku basiert auf Code-Stand der
master-Branchesspeamcore.com(Tag v1.71.0) undapi.speamcore.com(Tag v1.64.0). BE-Tasks-Folder:tasks/2026-04-29_feedback-system/mit DECISIONS, PROGRESS, NEXT_STEPS. - 2026-05-12 (Welle 114): Dreistufige Screenshot-Strategie (Capacitor-Native →
getDisplayMedia→html2canvas), Custom-Bild-Anhänge als separate Documents (parentType=Feedback), Draft-Persistenz inlocalStorage(speamcore.feedback.draft.v1, 7-Tage-TTL), verbessertes Recording viapointerdown+closest(INTERACTIVE_SELECTOR)+ Feedback-UI-Ausschluss + 250 ms De-duping.