Sends a one-time email ~30 days before any contract's term_end (whether renewal='auto' or 'none'), with "Behalten" and "Kündigen" action links. "Behalten" extends the contract by one renewal term; "Kündigen" sets the same cancellation effective-date logic as the customer-facing cancel flow and opens a staff ticket so the external deregistration (e.g. with a domain registrar) actually gets done. Uses a dedicated single-use token table (contract_renewal_tokens) since contracts, unlike user_tokens, are not scoped to a single user. The public confirmation page lives at /vertrag-entscheidung. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
27 lines
2.1 KiB
SQL
27 lines
2.1 KiB
SQL
-- Erinnerung vor Vertragsende: ~30 Tage vorher eine Mail mit "Behalten"/"Kündigen"-Entscheidung, egal ob der
|
|
-- Vertrag automatisch verlängert (renewal='auto') oder ausläuft (renewal='none'). "Behalten" verlängert
|
|
-- bewusst um eine Laufzeit (auch bei renewal='none', ohne die Einstellung selbst zu ändern - nächstes Mal wird
|
|
-- wieder gefragt). "Kündigen" setzt dieselbe Kündigungslogik wie die eingeloggte Kunden-Kündigung UND legt ein
|
|
-- Ticket an, damit Personal die externe Abmeldung (z. B. beim Domain-Registrar) tatsächlich vornehmen kann.
|
|
ALTER TABLE contracts ADD COLUMN renewal_reminder_sent_at DATETIME(3) NULL;
|
|
|
|
-- Eigene Token-Tabelle statt user_tokens: eine Entscheidung bezieht sich auf einen VERTRAG, nicht auf den
|
|
-- einloggenden Nutzer selbst (ein Kunde kann mehrere Verträge haben) - user_tokens hat dafür keine Spalte.
|
|
-- Gleiche Hash-/Ablauf-/Einmal-Mechanik wie user_tokens.
|
|
CREATE TABLE contract_renewal_tokens (
|
|
id CHAR(36) PRIMARY KEY,
|
|
contract_id CHAR(36) NOT NULL REFERENCES contracts(id),
|
|
token_hash CHAR(64) NOT NULL UNIQUE,
|
|
expires_at DATETIME(3) NOT NULL,
|
|
used_at DATETIME(3) NULL,
|
|
used_action ENUM('keep','cancel') NULL,
|
|
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
|
INDEX (contract_id)
|
|
);
|
|
|
|
INSERT INTO mail_templates (`key`, name, trigger_text, category, variables_json, subject, body) VALUES
|
|
('contract_renewal_reminder', 'Erinnerung vor Vertragsende', 'Automatisch, ca. 30 Tage vor Laufzeitende eines Vertrags (einmalig je Vertrag).',
|
|
'kundencenter',
|
|
JSON_ARRAY('name', 'contractNumber', 'productName', 'termEnd', 'keepLink', 'cancelLink'),
|
|
'Ihr Vertrag {{contractNumber}} läuft bald ab',
|
|
'Hallo {{name}},\n\nIhr Vertrag {{contractNumber}} ({{productName}}) läuft am {{termEnd}} aus. Über die Schaltflächen unten können Sie ihn behalten oder kündigen.\n\nBei „Behalten" verlängern wir den Vertrag automatisch um eine weitere Laufzeit. Bei „Kündigen" kümmern wir uns um die Abmeldung. Ohne Rückmeldung läuft der Vertrag nach unseren üblichen Bedingungen weiter bzw. aus.\n\n{{keepLink}}\n{{cancelLink}}\n\nBei Fragen antworten Sie gerne auf diese E-Mail.\n');
|