feat(akquise): Mail an Berater bei neuem Projekt

Wird in der Akquise ein Projekt mit Berater angelegt (oder ein Berater
beim Bearbeiten hinzugefuegt), bekommt er eine Mail ueber Graph sendMail
aus crm@perinco.de; Reply-To ist der eintragende Benutzer. Je Berater
abschaltbar unter Einstellungen -> Akquise (Spalte notify, Vorgabe an).
Versand laeuft nach der Antwort und kippt das Speichern nie.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Sascha Wolf
2026-10-21 09:38:13 +02:00
co-authored by Claude Opus 5.5
parent 907b010f3c
commit eaef454442
15 changed files with 402 additions and 24 deletions
+57
View File
@@ -0,0 +1,57 @@
/*
* Pruefungen der Berater-Mail (acquisitionNotify.js): laeuft mit `npm test`.
*
* Geprueft wird, wer eine Mail bekommt (nur neu hinzugekommene Berater) und
* dass der Mailtext Eingaben escaped - Titel und Beschreibung kommen aus
* Freitextfeldern und landen als HTML im Postfach des Beraters.
*/
const { addedConsultants, buildMessage } = await import('../src/acquisitionNotify.js');
let failures = 0;
function check(name, condition, detail = '') {
if (condition) {
console.log(` ok ${name}${detail ? ` - ${detail}` : ''}`);
} else {
console.log(` FAIL ${name}${detail ? ` - ${detail}` : ''}`);
failures += 1;
}
}
const same = (left, right) => JSON.stringify(left) === JSON.stringify(right);
console.log('\nWer bekommt eine Mail');
check('Anlegen: alle', same(addedConsultants(null, 'Nico, Lisa'), ['Nico', 'Lisa']));
check('Ohne Berater: niemand', same(addedConsultants(null, null), []));
check('Bearbeiten: nur neue', same(addedConsultants('Nico', 'Nico, Lisa'), ['Lisa']));
check('Schreibweise egal', same(addedConsultants('nico', 'Nico'), []));
check('Entfernen: niemand', same(addedConsultants('Nico, Lisa', 'Nico'), []));
console.log('\nMailtext');
const message = buildMessage(
{
id: 1,
title: 'SAP <script>',
company: 'ACME & Co',
provider: 'Hays',
daily_rate: 950,
start_date: '2026-11-01',
end_date: '2026-12-31',
link: 'https://example.com/p?a=1&b=2',
description: 'Zeile 1\nZeile 2',
created_by_name: 'Sascha Wolf',
},
'Jörg Müller'
);
check('Betreff mit Titel', message.subject === 'Neues Projekt für dich: SAP <script>');
check('Titel escaped', message.html.includes('SAP &lt;script&gt;') && !message.html.includes('<script>'));
check('Firma escaped', message.html.includes('ACME &amp; Co'));
check('Anrede mit Vorname', message.html.includes('Hallo Jörg,'));
check('Datum deutsch', message.html.includes('01.11.2026 bis 31.12.2026'));
check('Link enthalten', message.html.includes('href="https://example.com/p?a=1&amp;b=2"'));
check('Leere Felder fehlen', !message.html.includes('Projektpreis'));
console.log(
failures === 0 ? '\nAlle Pruefungen bestanden.' : `\n${failures} Pruefung(en) fehlgeschlagen.`
);
process.exit(failures === 0 ? 0 : 1);