Beim Nightbot-Nachtriage-Durchlauf gefunden: Firmenname und Notiz im
Rechnungsjournal-CSV (aus Kunden-/Personal-Eingaben) landeten ungeprüft
in der Zelle. Beginnt ein solcher Wert mit =, +, - oder @, interpretieren
Excel/Sheets ihn beim Öffnen als Formel statt als Text (CSV-Injection).
Zellen mit einem dieser Startzeichen werden jetzt mit einem führenden
Apostroph entschärft (Standard-Gegenmaßnahme), sowohl im generischen
CSV-Export als auch im DATEV-Buchungstext (dort fließt der Firmenname
ebenfalls mit ein).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Neue Seite Rechnungen → Export mit Zeitraum-/Status-Filter und drei
Downloads, nie Entwürfe:
- Rechnungsjournal als CSV (Semikolon, Dezimalkomma, UTF-8-BOM):
Nummer, Datum, Kunde, Netto/USt/Brutto, effektiver USt-Satz, Status,
Zahlungsdatum, aufgelöste Storno-Referenzen.
- Alle zugehörigen Rechnungs-PDFs als ZIP (die eigentlichen Belege,
wie von GoBD neben dem Journal verlangt), gebaut über das lokale
zip-Binary wie in ops/backup.ts.
- Echter DATEV-Buchungsstapel (EXTF, Format 700/21) zum direkten
Import beim Steuerberater. Pro Rechnung eine Buchungszeile je
USt-Satz-Gruppe (Automatikkonten-Verfahren: Konto = aus der
Kundennummer abgeleitetes Debitorenkonto, Gegenkonto = konfiguriertes
Erlöskonto des jeweiligen Satzes – kein geratener BU-Schlüssel
nötig). Kopf- und Buchungszeilen-Layout (31 bzw. 125 Felder) gegen
die offizielle DATEV-Formatbeschreibung und ein reales Beispiel aus
github.com/ledermann/datev verifiziert, nicht aus dem Gedächtnis
geraten. Ausgabe in Windows-1252 (eigener Encoder: Node kennt nur
striktes ISO-8859-1, das den Halbgeviertstrich in den DATEV-
Spaltennamen stillschweigend verstümmelt hätte – beim Testlauf
gefunden und behoben).
Dafür neue DATEV-Stammdaten unter Einstellungen → Firma (Berater-/
Mandantennummer, SKR, Sachkontenlänge, Wirtschaftsjahresbeginn,
Erlöskonten je Steuersatz; Migration 031). Ohne diese Angaben liefert
der DATEV-Export eine klare Fehlermeldung statt einer falschen Datei;
das CSV/ZIP funktioniert unabhängig davon immer.
Gegen echte Rechnungen (RE-1001/RE-1002, Original + Storno) über eine
temporäre Test-Session verifiziert: CSV/ZIP/DATEV liefern korrekte
Inhalte, Storno kehrt Soll/Haben korrekt um, Feldzahlen exakt 31/125,
Encoding rund-trip-fest.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Mails wurden bisher nur als Klartext verschickt. sendMail/sendTemplateMail
verschicken jetzt zusätzlich eine einfache, mandantenfarbige HTML-Version
(renderTemplateHtml in @kc/platform/mail): ein Platzhalter, dessen Name auf
"Link" endet, wird darin zu einer Schaltfläche statt einer nackten URL; der
Klartext-Teil behält den Link weiterhin sichtbar (Fallback für Mailprogramme
ohne HTML-Ansicht).
ticket_created/ticket_message bekommen dafür eine neue Variable
{{ticketLink}}, invoice_issued {{invoiceLink}} (Migration 025 – nur
Vorlagen mit noch unverändertem Text werden angepasst, damit von Personal
bereits bearbeitete Texte nicht überschrieben werden).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
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>