feat: SMTP-Stack mit konfigurierbaren Mailvorlagen
Bisher gab es nur zwei fest im Code verdrahtete E-Mails (Einladung, Passwort-Reset) und die SMTP-Verbindung kam ausschließlich aus Umgebungsvariablen. Jetzt: - SMTP-Verbindung unter Einstellungen > E-Mail konfigurierbar (Host, Port, Verschlüsselung, Zugangsdaten verschlüsselt gespeichert, Absender), mit Testmail-Versand. Die Mail-Logik wandert dafür nach @kc/platform/mail, damit API und Worker sie gemeinsam nutzen. - Mailvorlagen-Verwaltung: jedes Ereignis hat eine feste "Definition" (Name, Auslöser, verfügbare Platzhalter/Daten), Betreff/Text sind editierbar, je Vorlage einzeln aktivierbar, mit Testversand anhand von Beispieldaten. Unbekannte Platzhalter werden beim Speichern abgelehnt. - Neue Ereignisse verdrahtet: Ticket erstellt (Bestätigung an Kunde), Personal antwortet auf Ticket (Benachrichtigung an Kunde), Rechnung ausgestellt, sowie die zuvor zurückgestellte Funktion "Panel- Zugangsdaten per E-Mail senden" nach einem Passwort-Reset. Diese laufen über die Jobqueue (mail.template), analog zu discord.notify. - Versandprotokoll (letzte 100 Versuche, ohne Inhalte) einsehbar unter Einstellungen > E-Mail. - Migration 022, Rechte email.read (Admin+) / email.write (Superadmin). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
b112647ff1
commit
a68b4cf6ec
18 changed files with 385 additions and 42 deletions
|
|
@ -1,6 +1,7 @@
|
|||
import { pool } from '@kc/platform/db';
|
||||
import { notifyAdmin } from './discord.js';
|
||||
import { JobFailure } from '@kc/platform/jobs';
|
||||
import { sendTemplateMail } from '@kc/platform/mail';
|
||||
import { executeAction, executeChild, provisionOrder, syncInstance, type ChildPayload, type ExecutePayload } from '@kc/connectors';
|
||||
|
||||
interface JobMeta { id: string; correlationId: string; attempt: number; maxAttempts: number }
|
||||
|
|
@ -19,6 +20,12 @@ const handlers: Record<string, Handler> = {
|
|||
const r = await notifyAdmin(text);
|
||||
if (r === 'skipped') return 'übersprungen: Discord nicht konfiguriert';
|
||||
},
|
||||
'mail.template': async (p: { to: string; key: string; vars: Record<string, string> }) => {
|
||||
const status = await sendTemplateMail(p.to, p.key, p.vars);
|
||||
if (status === 'failed') throw new Error('Mailversand fehlgeschlagen (siehe Protokoll unter Einstellungen > E-Mail)');
|
||||
if (status === 'no_template') throw new Error(`Unbekannte Mailvorlage: ${p.key}`);
|
||||
return status === 'not_configured' ? 'übersprungen: SMTP nicht konfiguriert' : status === 'disabled' ? 'übersprungen: Vorlage deaktiviert' : 'gesendet';
|
||||
},
|
||||
};
|
||||
handlers['connector.sync'] = async (p, j) => {
|
||||
const r = await syncInstance(p.instanceId, j.correlationId);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue