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
@@ -424,15 +424,36 @@ CREATE TABLE IF NOT EXISTS crm_acquisitions (
|
||||
opportunity_id INT UNSIGNED NULL,
|
||||
converted_at DATETIME NULL,
|
||||
created_by INT UNSIGNED NULL,
|
||||
deleted_at DATETIME NULL, -- im Papierkorb (UTC)
|
||||
deleted_by INT UNSIGNED NULL, -- wer; bewusst ohne Fremdschluessel, s.u.
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (id),
|
||||
KEY idx_crm_acq_found (found_at),
|
||||
KEY idx_crm_acq_converted (converted_at),
|
||||
KEY idx_crm_acq_deleted (deleted_at),
|
||||
CONSTRAINT fk_crm_acq_opp FOREIGN KEY (opportunity_id) REFERENCES crm_opportunities (id) ON DELETE SET NULL,
|
||||
CONSTRAINT fk_crm_acq_user FOREIGN KEY (created_by) REFERENCES crm_users (id) ON DELETE SET NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
/*
|
||||
* Papierkorb der Akquise. Loeschen setzt `deleted_at`, die Zeile bleibt stehen -
|
||||
* vorher war es ein echtes DELETE, und ein Fehlklick war damit endgueltig: der
|
||||
* Eintrag tauchte in keiner Liste mehr auf, auch nicht im Archiv.
|
||||
*
|
||||
* Der Papierkorb hat seine eigene Uhr (`deleted_at`), nicht die des Funddatums:
|
||||
* ein von Hand geloeschter Eintrag liegt 90 Tage dort, gleich wie alt der Fund
|
||||
* ist. Der Aufraeumlauf ueber `found_at` laesst geloeschte Zeilen deshalb
|
||||
* ausdruecklich liegen - sonst wuerde ein alter Fund im Papierkorb sofort
|
||||
* verschwinden.
|
||||
*
|
||||
* `deleted_by` traegt bewusst keinen Fremdschluessel: Spalten lassen sich per
|
||||
* ADD COLUMN IF NOT EXISTS idempotent nachziehen, ein Fremdschluessel nicht.
|
||||
*/
|
||||
ALTER TABLE crm_acquisitions ADD COLUMN IF NOT EXISTS deleted_at DATETIME NULL AFTER created_by;
|
||||
ALTER TABLE crm_acquisitions ADD COLUMN IF NOT EXISTS deleted_by INT UNSIGNED NULL AFTER deleted_at;
|
||||
ALTER TABLE crm_acquisitions ADD INDEX IF NOT EXISTS idx_crm_acq_deleted (deleted_at);
|
||||
|
||||
/*
|
||||
* Auswahllisten der Akquise. "Von", "Kanal" und "Berater" sind Dropdowns, deren
|
||||
* Inhalte in den Einstellungen gepflegt werden.
|
||||
|
||||
Reference in New Issue
Block a user