feat(akquise): Uebernommene Eintraege bleiben in der Liste

Bisher verschwand ein Fund mit der Uebernahme aus Eingang und Archiv.
Beim Durchgehen blieb damit offen, ob er schon angefasst wurde. Jetzt
bleibt der Eintrag stehen und zeigt statt "Opportunity" den blauen Knopf
"Uebernommen" mit Haken; ein Klick springt zur Opportunity.

Dafuer entscheidet nicht mehr IS_OPEN ueber die Listen, sondern die neuen
Regeln IN_INBOX und RETURNED: ein Rueckfaeller (Opportunity im Papierkorb
oder geloescht) gehoert weiter ins Archiv, alles andere bleibt in seiner
Liste. Zaehler und Menuezahl folgen derselben Regel. IS_OPEN bleibt fuer
den Loeschlauf: was zu einer lebenden Opportunity gehoert, wird nicht
weggeraeumt.

Solange die Opportunity lebt, sind Bearbeiten, Loeschen und "Zurueck in
die Akquise" am Eintrag gesperrt - er ist ihr Herkunftsnachweis, und der
Rueckweg von der Opportunity braucht ihn. Das Loeschen weist auch das
Backend ab, nicht nur die Oberflaeche.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Sascha Wolf
2026-09-21 15:46:26 +02:00
co-authored by Claude Opus 5
parent 86aa7468af
commit 3e76a73f2e
8 changed files with 154 additions and 61 deletions
+24 -6
View File
@@ -44,18 +44,36 @@ export const IN_TRASH = 'a.deleted_at IS NOT NULL';
export const OPPORTUNITY_GONE = '(opp.id IS NULL OR opp.deleted_at IS NOT NULL)';
/**
* Bewerbung, die (wieder) in Eingang oder Archiv gehoert: nie uebernommen, oder
* die Opportunity ist weg. Abgeleitet statt gespeichert - wird die Opportunity
* zurueckgeholt, verschwindet der Eintrag von selbst wieder.
* Bewerbung, die noch nicht abgearbeitet ist: nie uebernommen, oder die
* Opportunity ist weg. Abgeleitet statt gespeichert - wird die Opportunity
* zurueckgeholt, gilt der Eintrag von selbst wieder als uebernommen.
*
* Fuer die Listen entscheidet das nichts mehr (uebernommene Eintraege bleiben
* stehen und zeigen dort "Uebernommen"), wohl aber fuer den Loeschlauf: was zu
* einer lebenden Opportunity gehoert, wird nie weggeraeumt.
*/
export const IS_OPEN = `(a.converted_at IS NULL OR ${OPPORTUNITY_GONE})`;
/**
* Steht im Archiv: alles Uebernommene, dessen Opportunity weg ist (unabhaengig
* vom Alter - es ist abgearbeitet, aber nicht verschwunden), plus alles, was
* Rueckfaeller: schon einmal uebernommen, aber die Opportunity ist weg. Ein
* solcher Eintrag gehoert ins Archiv - unabhaengig vom Alter, er ist
* abgearbeitet, aber nicht verschwunden.
*/
export const RETURNED = `(a.converted_at IS NOT NULL AND ${OPPORTUNITY_GONE})`;
/**
* Steht im Eingang: alles innerhalb der Archivfrist, ausser Rueckfaellern.
* Uebernommene Eintraege bleiben hier stehen: verschwaenden sie sofort, bliebe
* beim Durchgehen offen, ob ein Fund schon angefasst wurde. Erwartet die
* Archivfrist als Platzhalter.
*/
export const IN_INBOX = `(NOT ${RETURNED} AND a.found_at >= DATE_SUB(CURDATE(), INTERVAL ? DAY))`;
/**
* Steht im Archiv: jeder Rueckfaeller (unabhaengig vom Alter), plus alles, was
* aelter als die Archivfrist ist. Erwartet die Frist als Platzhalter.
*/
export const IN_ARCHIVE = '(a.converted_at IS NOT NULL OR a.found_at < DATE_SUB(CURDATE(), INTERVAL ? DAY))';
export const IN_ARCHIVE = `(${RETURNED} OR a.found_at < DATE_SUB(CURDATE(), INTERVAL ? DAY))`;
/** Untere Grenze: was schon faellig ist, wird nicht mehr gezeigt. */
export const NOT_DUE = 'a.found_at >= DATE_SUB(CURDATE(), INTERVAL ? DAY)';