feat(akquise): Berater-Mail sagt "beworben" und zeigt den Link

Betreff "Du wurdest beworben: <Titel>", Text "wir haben dich auf folgendes
Projekt beworben", Link zum Projekt als ausgeschriebene Zeile in der
Tabelle statt versteckt hinter "Zur Ausschreibung".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Sascha Wolf
2026-10-21 09:49:41 +02:00
co-authored by Claude Opus 5.5
parent eaef454442
commit 6772f34b4e
4 changed files with 22 additions and 12 deletions
+10 -7
View File
@@ -65,14 +65,20 @@ export function buildMessage(acquisition, consultantName) {
['Projektpreis', formatEuro(acquisition.fixed_price)],
['Zeitraum', period || null],
['Laufzeit', acquisition.duration_days ? `${acquisition.duration_days} Tage` : null],
['Eingetragen von', acquisition.created_by_name],
['Link zum Projekt', acquisition.link],
['Beworben von', acquisition.created_by_name],
].filter(([, value]) => value !== null && value !== undefined && value !== '');
// Der Link steht ausgeschrieben da - auch wer die Mail als Text liest, sieht ihn.
const cell = (label, value) =>
label === 'Link zum Projekt'
? `<a href="${escapeHtml(value)}">${escapeHtml(value)}</a>`
: escapeHtml(value);
const table = rows
.map(
([label, value]) =>
`<tr><td style="padding:4px 16px 4px 0;color:#666;vertical-align:top">${escapeHtml(label)}</td>` +
`<td style="padding:4px 0">${escapeHtml(value)}</td></tr>`
`<td style="padding:4px 0;word-break:break-all">${cell(label, value)}</td></tr>`
)
.join('');
@@ -85,11 +91,8 @@ export function buildMessage(acquisition, consultantName) {
const html = [
'<div style="font-family:Segoe UI,Arial,sans-serif;font-size:14px;color:#222">',
`<p>Hallo ${escapeHtml(firstName)},</p>`,
'<p>in der Akquise wurde ein neues Projekt eingetragen und dir zugeordnet:</p>',
'<p>wir haben dich auf folgendes Projekt <strong>beworben</strong>:</p>',
`<table style="border-collapse:collapse;font-size:14px">${table}</table>`,
acquisition.link
? `<p><a href="${escapeHtml(acquisition.link)}">Zur Ausschreibung</a></p>`
: '',
description
? `<p style="white-space:pre-wrap;border-left:3px solid #ddd;padding-left:12px;color:#444">${escapeHtml(description)}</p>`
: '',
@@ -99,7 +102,7 @@ export function buildMessage(acquisition, consultantName) {
'</div>',
].join('');
return { subject: `Neues Projekt für dich: ${acquisition.title}`, html };
return { subject: `Du wurdest beworben: ${acquisition.title}`, html };
}
/**
+6 -2
View File
@@ -43,12 +43,16 @@ const message = buildMessage(
},
'Jörg Müller'
);
check('Betreff mit Titel', message.subject === 'Neues Projekt für dich: SAP <script>');
check('Betreff mit Titel', message.subject === 'Du wurdest beworben: SAP <script>');
check('Sagt, dass beworben wurde', message.html.includes('<strong>beworben</strong>'));
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(
'Link sichtbar',
message.html.includes('<a href="https://example.com/p?a=1&amp;b=2">https://example.com/p?a=1&amp;b=2</a>')
);
check('Leere Felder fehlen', !message.html.includes('Projektpreis'));
console.log(