feat(tickets): Wiederöffnen→Rückfrage mit Zeitstempel + Soft-Delete-Papierkorb + Scroll-Erhalt
Wiederöffnen eines gelösten Tickets:
- landet jetzt in „Rückfragen" (NeedsInfo) statt „Offen".
- War es ein echt gelöstes Ticket OHNE Rückfrage, wird um mehr Infos gebeten und
„Wieder geöffnet am" (ReopenedAt) gestempelt.
- Hatte es bereits eine offene Rückfrage (z. B. manuell gelöste Rückfrage), kehrt es
ohne neuen Hinweis und ohne Zeitstempel in genau diese Frage zurück.
Löschen über die UI = Soft-Delete:
- Tickets wandern in die neue Kategorie „Gelöscht" (Papierkorb) statt entfernt zu werden.
- Von dort wiederherstellbar (POST /feedback/{id}/restore → DeletedAt = null).
- Countdown „Wird in N Tagen endgültig gelöscht"; nach 30 Tagen endgültige Löschung
(lazy beim Abruf in GET /feedback).
Außerdem: Scrollposition bleibt beim Zurück-Navigieren (z. B. nach Klick auf einen
Tier-Link) erhalten, statt an den Seitenanfang zu springen.
EF-Migration FeedbackReopenedAndSoftDelete (ReopenedAt, DeletedAt — beide nullable).
Tests: 260 Backend grün (+2 Reopen-Fälle, CRUD auf Soft-Delete umgestellt), e2e Tickets
Desktop+Phone grün (+Soft-Delete/Restore/Reopen), vitest 149.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -1221,20 +1221,31 @@ export const de = {
|
||||
entityLabel: 'Datensatz',
|
||||
createdLabel: 'Gesendet am',
|
||||
resolvedLabel: 'Gelöst am',
|
||||
reopenedLabel: 'Wieder geöffnet am',
|
||||
markResolved: 'Als gelöst markieren',
|
||||
reopen: 'Wieder öffnen',
|
||||
reopenRequest:
|
||||
'Du hast dieses Ticket wieder geöffnet. Bitte beschreibe kurz, was noch fehlt oder nicht stimmt — dann schaue ich es mir erneut an.',
|
||||
edit: 'Bearbeiten',
|
||||
save: 'Speichern',
|
||||
cancel: 'Abbrechen',
|
||||
saving: 'Wird gespeichert …',
|
||||
delete: 'Löschen',
|
||||
confirmDelete: 'Diesen Fehlerbericht wirklich löschen?',
|
||||
confirmDelete: 'Dieses Ticket in den Papierkorb verschieben? Du kannst es unter „Gelöscht" wiederherstellen.',
|
||||
editTitle: 'Fehlerbericht bearbeiten',
|
||||
editLabel: 'Beschreibung',
|
||||
saved: 'Änderung gespeichert.',
|
||||
resolvedToast: 'Ticket als gelöst markiert.',
|
||||
reopenedToast: 'Ticket wieder geöffnet.',
|
||||
deletedToast: 'Ticket gelöscht.',
|
||||
deletedToast: 'Ticket in den Papierkorb verschoben.',
|
||||
restore: 'Wiederherstellen',
|
||||
restoredToast: 'Ticket wiederhergestellt.',
|
||||
restoreError: 'Ticket konnte nicht wiederhergestellt werden.',
|
||||
/** Countdown im Papierkorb bis zur endgültigen Löschung. {n} = verbleibende Tage. */
|
||||
trashCountdownDays: 'Wird in {n} Tagen endgültig gelöscht.',
|
||||
trashCountdownTomorrow: 'Wird morgen endgültig gelöscht.',
|
||||
trashCountdownToday: 'Wird heute endgültig gelöscht.',
|
||||
deletedLabel: 'Gelöscht am',
|
||||
updateError: 'Ticket konnte nicht aktualisiert werden.',
|
||||
deleteError: 'Ticket konnte nicht gelöscht werden.',
|
||||
emptyMessage: 'Bitte beschreibe den Fehler.',
|
||||
@@ -1257,11 +1268,14 @@ export const de = {
|
||||
open: 'Offen',
|
||||
/** Gruppe „Geschlossen": erledigte Tickets mit Changelog. */
|
||||
closed: 'Geschlossen',
|
||||
/** Gruppe „Gelöscht": in den Papierkorb verschobene Tickets (wiederherstellbar). */
|
||||
deleted: 'Gelöscht',
|
||||
},
|
||||
/** Leertext je gefilterter Ansicht. */
|
||||
emptyDialog: 'Aktuell keine Tickets im Dialog.',
|
||||
emptyOpen: 'Keine offenen Tickets.',
|
||||
emptyClosed: 'Noch keine geschlossenen Tickets.',
|
||||
emptyDeleted: 'Der Papierkorb ist leer.',
|
||||
/** Changelog (fixNote) auf geschlossenen Tickets. */
|
||||
changelogLabel: 'Was wurde geändert',
|
||||
/** Überschrift des Frage/Antwort-Verlaufs (frühere Runden). */
|
||||
|
||||
Reference in New Issue
Block a user