feat(akquise): Papierkorb fuer geloeschte Eintraege
Loeschen in der Akquise war ein echtes DELETE: der Eintrag stand danach in keiner Liste, auch nicht im Archiv, und war nicht zurueckholbar. Jetzt setzt es `deleted_at`/`deleted_by`, die Zeile bleibt 90 Tage stehen. Der Papierkorb ist die eine Ausnahme von der Regel, dass diese Tabelle keinen Zustand fuehrt: Loeschen von Hand ist eine Entscheidung, kein Ablauf. Was dort liegt, blenden alle anderen Abfragen ueber NOT_DELETED aus - Eingang, Archiv, Menuezahlen und Dashboard. Der Aufraeumlauf ueber `found_at` laesst geloeschte Zeilen ausdruecklich liegen, sonst waere ein alter Fund im Papierkorb sofort weg; der Papierkorb raeumt ab `deleted_at`. Zwei Rueckwege, deshalb zwei Routen. `/reopen` (bisher `/restore`) holt aus dem Archiv in den Eingang und setzt das Funddatum auf heute. `/restore` holt aus dem Papierkorb zurueck und laesst das Funddatum in Ruhe - der Eintrag soll dort auftauchen, wo er hingehoert, also im Archiv, wenn er alt ist. Die Meldung nennt das Ziel. Dazu `DELETE /:id/permanent` und `POST /trash/empty`. Im Papierkorb wird nicht gepflegt: Bearbeiten und Uebernehmen antworten 409. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
f319b8207b
commit
6e66bd39d7
@@ -25,8 +25,8 @@ interface AcquisitionTableProps {
|
||||
onEdit: (entry: Acquisition) => void;
|
||||
onDelete: (entry: Acquisition) => void;
|
||||
onConvert: (entry: Acquisition) => void;
|
||||
/** Nur im Archiv gesetzt - im Eingang gibt es nichts wiederherzustellen. */
|
||||
onRestore?: (entry: Acquisition) => void;
|
||||
/** Nur im Archiv gesetzt - im Eingang gibt es nichts zurueckzuholen. */
|
||||
onReopen?: (entry: Acquisition) => void;
|
||||
}
|
||||
|
||||
const COLUMNS: { key: AcquisitionSortKey | null; label: string; className?: string }[] = [
|
||||
@@ -118,7 +118,7 @@ export const AcquisitionTable: React.FC<AcquisitionTableProps> = ({
|
||||
onEdit,
|
||||
onDelete,
|
||||
onConvert,
|
||||
onRestore,
|
||||
onReopen,
|
||||
}) => (
|
||||
<div className="overflow-hidden rounded-2xl border border-ink-200 bg-surface shadow-card">
|
||||
<div className="scrollbar-slim overflow-x-auto">
|
||||
@@ -230,12 +230,12 @@ export const AcquisitionTable: React.FC<AcquisitionTableProps> = ({
|
||||
|
||||
<td className="whitespace-nowrap px-4 py-3 text-right">
|
||||
<div className="inline-flex gap-1">
|
||||
{onRestore && (
|
||||
{onReopen && (
|
||||
<button
|
||||
onClick={() => onRestore(entry)}
|
||||
onClick={() => onReopen(entry)}
|
||||
disabled={isBusy}
|
||||
title="Zurück in die Akquise: der Eintrag bekommt das heutige Datum und steht wieder im Eingang."
|
||||
aria-label={`${entry.title} wiederherstellen`}
|
||||
aria-label={`${entry.title} zurück in die Akquise`}
|
||||
className="rounded-lg p-2 text-ink-400 transition hover:bg-brand-50 hover:text-brand-700 disabled:opacity-50"
|
||||
>
|
||||
<svg className="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
|
||||
Reference in New Issue
Block a user