fix(akquise): Zahl am Menuepunkt Archiv folgte der alten Regel

Die Liste zeigte die zurueckgefallene Bewerbung, der Zaehler am Menue nicht: er
filterte weiter auf "nie uebernommen". Genau der Fehler, den zwei Kopien
derselben Regel machen.

Fristen und Bedingungen stehen jetzt in server/src/acquisitionRules.js und
werden von der Liste, den Zaehlern, dem Aufraeumlauf und der Menuezahl
gemeinsam benutzt.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Sascha Wolf
2026-08-18 15:54:50 +02:00
co-authored by Claude Opus 5
parent c380d05b42
commit c59115c728
3 changed files with 70 additions and 44 deletions
+44
View File
@@ -0,0 +1,44 @@
/*
* Regeln der Akquise an einer Stelle: Fristen und die Frage, was ueberhaupt in
* Eingang oder Archiv gehoert.
*
* Sie werden von routes/acquisitions.js (Listen, Zaehler, Aufraeumlauf) und von
* routes/badges.js (Zahl am Menuepunkt) gebraucht. Lagen sie in beiden Dateien,
* wuerde eine Aenderung die andere Stelle vergessen - genau das ist beim
* Zurueckfallen einer Bewerbung passiert: die Liste zeigte den Eintrag, der
* Zaehler am Menue nicht.
*
* Die Zeichenketten sind SQL-Bedingungen und erwarten die Aliase `a` fuer
* crm_acquisitions und `opp` fuer die per LEFT JOIN angehaengte Opportunity.
*/
/** Grenze zwischen Eingang und Archiv, in Tagen. */
export const ARCHIVE_AFTER_DAYS = 14;
/** Ab hier loescht das Archiv selbst. */
export const DELETE_AFTER_DAYS = 90;
/**
* Die Opportunity zu einem Eintrag ist verschwunden - im Papierkorb oder
* endgueltig geloescht. `opp.id IS NULL` deckt beides ab: nie uebernommen
* (opportunity_id ist NULL) und endgueltig geloescht (der Fremdschluessel wurde
* dabei auf NULL gesetzt).
*/
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.
*/
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
* 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))';
/** Untere Grenze: was schon faellig ist, wird nicht mehr gezeigt. */
export const NOT_DUE = 'a.found_at >= DATE_SUB(CURDATE(), INTERVAL ? DAY)';