Funktionen: Zustimmung in Textform auch per WhatsApp

Terminplaner, Webshop und Buchungskalender nehmen beim Aktivieren durch das Team den Weg whatsapp an (Nachweis: „per WhatsApp in Textform“). Die Analyse bleibt bei Chat oder E-Mail.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
knsoandClaude Opus 5.5 committed 2026-10-11 15:02:49 +00:00
1 parent b264d7f734
commit 02a3732e4a
5 files changed
+31 -7

No files matched your search

+5 -3
View File
@@ -19,6 +19,8 @@ const SITE_KEY_RE = /^[a-z0-9]{16,40}$/
const COLOR_RE = /^#[0-9a-f]{6}$/
const DEFAULT_COLOR = '#111111'
const CHANNELS = new Set(['chat', 'email'])
/** Wege der Zustimmung bei Funktionen (Terminplaner, Webshop, Buchungskalender): zusaetzlich WhatsApp (eine Nachricht dort ist Textform). */
export const FUNKTION_CHANNELS = new Set(['chat', 'email', 'whatsapp'])
export const MISSING_PRIVACY_MESSAGE =
'Für die Zusatzseite fehlen in Deinen Kundendaten Firma oder Name und eine gültige E-Mail-Adresse. Schreib uns im Chat, wir ergänzen sie.'
@@ -109,9 +111,9 @@ const berlinToday = (now) => new Intl.DateTimeFormat('sv-SE', { timeZone: 'Europ
/**
* Zustimmung des Kunden in Textform (Mitarbeiter-Weg): Datum JJJJ-MM-TT (echt, nicht nach heute in Berlin,
* nicht vor der Fassung) und Weg chat/email. Wirft 400, sonst { date, channel }.
* nicht vor der Fassung) und Weg chat/email (channels: erlaubte Wege, Funktionen auch whatsapp). Wirft 400, sonst { date, channel }.
*/
export function validateTextform(textform, { today = berlinToday(new Date()), minDate = config.analyse.avvVersion } = {}) {
export function validateTextform(textform, { today = berlinToday(new Date()), minDate = config.analyse.avvVersion, channels = CHANNELS } = {}) {
const date = String(textform?.date ?? '')
const m = /^(\d{4})-(\d{2})-(\d{2})$/.exec(date)
const real = m && new Date(Date.UTC(+m[1], +m[2] - 1, +m[3])).toISOString().slice(0, 10) === date
@@ -119,7 +121,7 @@ export function validateTextform(textform, { today = berlinToday(new Date()), mi
if (date > today) throw httpError(400, 'Das Datum der Zustimmung liegt in der Zukunft')
if (date < minDate) throw httpError(400, `Das Datum der Zustimmung liegt vor der Fassung ${minDate}`)
const channel = String(textform?.channel ?? '')
if (!CHANNELS.has(channel)) throw httpError(400, 'Weg der Zustimmung fehlt: Chat oder E-Mail')
if (!channels.has(channel)) throw httpError(400, channels.has('whatsapp') ? 'Weg der Zustimmung fehlt: Chat, E-Mail oder WhatsApp' : 'Weg der Zustimmung fehlt: Chat oder E-Mail')
return { date, channel }
}
+2 -2
View File
@@ -614,7 +614,7 @@ async function assertAboLaeuftFuerAktivierung(customerId) {
if (!laeuftJetzt) throw httpError(409, KEIN_ABO_AKTIVIERUNG)
}
const TEXTFORM_WEG = { chat: 'Chat im Kundenportal', email: 'E-Mail' }
const TEXTFORM_WEG = { chat: 'Chat im Kundenportal', email: 'E-Mail', whatsapp: 'WhatsApp' }
/** Funktionen, die das Team mit Zustimmung des Kunden in Textform aktivieren kann (Modus on), und die Fassung der Unterlagen, auf die sie sich bezieht. */
export const TEXTFORM_KEYS = ['termine', 'shop', 'unterkunft']
@@ -622,7 +622,7 @@ export const textformFassung = (key) => (key === 'shop' ? config.shop.fassung :
/**
* Text des Nachweises, wenn der Kunde dem Terminplaner oder dem Webshop in Textform zugestimmt hat (Aktivierung durch das Team im
* Modus on, F13a). textform = { date: 'JJJJ-MM-TT', channel: 'chat' | 'email' } (validateTextform); fassung = textformFassung(key).
* Modus on, F13a). textform = { date: 'JJJJ-MM-TT', channel: 'chat' | 'email' | 'whatsapp' } (validateTextform); fassung = textformFassung(key).
*/
export function textformNachweisText({ date, channel }, fassung, key = 'termine') {
const [jahr, monat, tag] = String(date).split('-')