feat: add Backend mit allen aktuellen features + Demo Daten

This commit is contained in:
Robert Wartenberg committed 2026-08-28 16:35:59 +02:00
1 parent a78e84515a
commit e122aa8650
17 files changed
+704 -238

No files matched your search

@@ -0,0 +1,40 @@
-- SUFW Terminbuchung: Bestätigungsfluss, Test-Mailausgang und iCalendar-Feeds
-- Diese Migration ergänzt das Anfangsschema und kann gefahrlos erneut laufen.
ALTER TABLE `sufw_booking_registrations`
ADD COLUMN IF NOT EXISTS `confirmation_token_hash` char(64) DEFAULT NULL AFTER `privacy_accepted_at`,
ADD COLUMN IF NOT EXISTS `confirmation_expires_at` datetime DEFAULT NULL AFTER `confirmation_token_hash`,
ADD COLUMN IF NOT EXISTS `confirmed_at` datetime DEFAULT NULL AFTER `confirmation_expires_at`,
ADD COLUMN IF NOT EXISTS `removed_at` datetime DEFAULT NULL AFTER `confirmed_at`;
CREATE TABLE IF NOT EXISTS `sufw_booking_project_settings` (
`project` varchar(32) NOT NULL,
`feed_token` char(64) NOT NULL,
`updated_at` datetime NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
PRIMARY KEY (`project`),
UNIQUE KEY `sufw_booking_project_settings_feed_token` (`feed_token`),
CONSTRAINT `sufw_booking_project_settings_project_check` CHECK (`project` IN ('perspektivwerk', 'produktionsschule'))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE IF NOT EXISTS `sufw_booking_outbox` (
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
`registration_id` char(36) NOT NULL,
`kind` varchar(32) NOT NULL,
`recipient_email` varchar(254) NOT NULL,
`subject` varchar(255) NOT NULL,
`body` text NOT NULL,
`created_at` datetime NOT NULL DEFAULT current_timestamp(),
`sent_at` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `sufw_booking_outbox_registration_kind` (`registration_id`, `kind`),
KEY `sufw_booking_outbox_pending` (`sent_at`, `created_at`),
CONSTRAINT `sufw_booking_outbox_kind_check` CHECK (`kind` IN ('confirmation_request', 'confirmation', 'reminder')),
CONSTRAINT `sufw_booking_outbox_registration_fk` FOREIGN KEY (`registration_id`) REFERENCES `sufw_booking_registrations` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
INSERT IGNORE INTO `sufw_booking_project_settings` (`project`, `feed_token`)
VALUES
('perspektivwerk', SHA2(CONCAT(UUID(), RAND(), NOW(6)), 256)),
('produktionsschule', SHA2(CONCAT(UUID(), RAND(), NOW(6)), 256));
INSERT IGNORE INTO `sufw_booking_schema_migrations` (`version`) VALUES ('002_booking_workflow');
@@ -0,0 +1,29 @@
-- SUFW Terminbuchung: Lokale Demo-Termine und bestätigte Teilnahmen
--
-- Nur für lokale Entwicklungs- und Testdatenbanken. Diese Datei darf nicht
-- auf einem Produktivsystem ausgeführt werden: Sie legt bewusst Testpersonen
-- und Beispieltermine an. Die stabilen IDs verhindern Duplikate; beim erneuten
-- Ausführen werden die Termine relativ zum heutigen Datum aktualisiert.
INSERT INTO `sufw_booking_events`
(`id`, `project`, `title`, `starts_at`, `ends_at`, `capacity`, `format`, `introduction_required`, `contact_name`, `contact_email`, `is_active`)
VALUES
('d3c7f216-2704-4c81-b17a-000000000001', 'perspektivwerk', 'Erstgespräch PerspektivWerk', TIMESTAMP(DATE_ADD(CURDATE(), INTERVAL -1 MONTH), '09:00:00'), TIMESTAMP(DATE_ADD(CURDATE(), INTERVAL -1 MONTH), '10:00:00'), 3, 'vor_ort', 0, 'Anna Müller', 'anna.mueller@example.test', 1),
('d3c7f216-2704-4c81-b17a-000000000002', 'perspektivwerk', 'Psy Modul PerspektivWerk', TIMESTAMP(DATE_ADD(CURDATE(), INTERVAL 1 MONTH), '13:15:00'), TIMESTAMP(DATE_ADD(CURDATE(), INTERVAL 1 MONTH), '17:15:00'), 2, 'telefonisch', 0, 'Anna Müller', 'anna.mueller@example.test', 1),
('d3c7f216-2704-4c81-b17a-000000000003', 'produktionsschule', 'Voranmeldung Kennenlerntermin Produktionsschule', TIMESTAMP(DATE_ADD(CURDATE(), INTERVAL -1 MONTH), '10:30:00'), TIMESTAMP(DATE_ADD(CURDATE(), INTERVAL -1 MONTH), '11:30:00'), 3, 'vor_ort', 0, 'Bernd Fischer', 'bernd.fischer@example.test', 1),
('d3c7f216-2704-4c81-b17a-000000000004', 'produktionsschule', 'Probearbeiten', TIMESTAMP(DATE_ADD(CURDATE(), INTERVAL 1 MONTH), '08:00:00'), TIMESTAMP(DATE_ADD(CURDATE(), INTERVAL 1 MONTH), '16:00:00'), 3, 'vor_ort', 1, 'Bernd Fischer', 'bernd.fischer@example.test', 1)
ON DUPLICATE KEY UPDATE
`title` = VALUES(`title`), `starts_at` = VALUES(`starts_at`), `ends_at` = VALUES(`ends_at`), `capacity` = VALUES(`capacity`), `format` = VALUES(`format`), `introduction_required` = VALUES(`introduction_required`), `contact_name` = VALUES(`contact_name`), `contact_email` = VALUES(`contact_email`), `is_active` = VALUES(`is_active`);
INSERT INTO `sufw_booking_registrations`
(`id`, `event_id`, `status`, `name`, `email`, `phone`, `privacy_accepted_at`, `confirmed_at`, `introduction_attended`, `introduction_date`)
VALUES
('e3c7f216-2704-4c81-b17a-000000000001', 'd3c7f216-2704-4c81-b17a-000000000001', 'confirmed', 'Demo Alina Beispiel', 'alina.beispiel@example.test', '+49 000 100001', DATE_SUB(NOW(), INTERVAL 35 DAY), DATE_SUB(NOW(), INTERVAL 35 DAY), 0, NULL),
('e3c7f216-2704-4c81-b17a-000000000002', 'd3c7f216-2704-4c81-b17a-000000000001', 'confirmed', 'Demo Cem Beispiel', 'cem.beispiel@example.test', '+49 000 100002', DATE_SUB(NOW(), INTERVAL 34 DAY), DATE_SUB(NOW(), INTERVAL 34 DAY), 0, NULL),
('e3c7f216-2704-4c81-b17a-000000000003', 'd3c7f216-2704-4c81-b17a-000000000002', 'confirmed', 'Demo Dana Beispiel', 'dana.beispiel@example.test', '+49 000 100003', NOW(), NOW(), 0, NULL),
('e3c7f216-2704-4c81-b17a-000000000004', 'd3c7f216-2704-4c81-b17a-000000000003', 'confirmed', 'Demo Emir Beispiel', 'emir.beispiel@example.test', '+49 000 100004', DATE_SUB(NOW(), INTERVAL 35 DAY), DATE_SUB(NOW(), INTERVAL 35 DAY), 0, NULL),
('e3c7f216-2704-4c81-b17a-000000000005', 'd3c7f216-2704-4c81-b17a-000000000004', 'confirmed', 'Demo Frida Beispiel', 'frida.beispiel@example.test', '+49 000 100005', NOW(), NOW(), 1, CURDATE())
ON DUPLICATE KEY UPDATE
`event_id` = VALUES(`event_id`), `status` = VALUES(`status`), `name` = VALUES(`name`), `email` = VALUES(`email`), `phone` = VALUES(`phone`), `privacy_accepted_at` = VALUES(`privacy_accepted_at`), `confirmed_at` = VALUES(`confirmed_at`), `introduction_attended` = VALUES(`introduction_attended`), `introduction_date` = VALUES(`introduction_date`), `removed_at` = NULL;
INSERT IGNORE INTO `sufw_booking_schema_migrations` (`version`) VALUES ('003_booking_demo_data');
@@ -0,0 +1,34 @@
-- SUFW Terminbuchung: Telefonnummern der Ansprechpersonen
--
-- Eigenständige, idempotente Migration. Sie erweitert das Terminmodell um
-- die Telefonnummer der fachlichen Ansprechperson.
ALTER TABLE `sufw_booking_events`
ADD COLUMN IF NOT EXISTS `contact_phone` varchar(64) NOT NULL DEFAULT '' AFTER `contact_email`;
-- Die fest versionierten Demo-Termine verwenden die abgestimmten Kontaktdaten.
-- Eigene, später angelegte Termine bleiben von diesen Updates unberührt.
UPDATE `sufw_booking_events`
SET `contact_name` = 'Carina Hollederer', `contact_email` = 'c.hollederer@sufw.de', `contact_phone` = '(0176) 17922244'
WHERE `id` IN (
'6c7f216b-2704-4c81-b17a-000000000001',
'6c7f216b-2704-4c81-b17a-000000000002',
'6c7f216b-2704-4c81-b17a-000000000003',
'6c7f216b-2704-4c81-b17a-000000000004',
'6c7f216b-2704-4c81-b17a-000000000005',
'd3c7f216-2704-4c81-b17a-000000000001',
'd3c7f216-2704-4c81-b17a-000000000002'
);
UPDATE `sufw_booking_events`
SET `contact_name` = 'Sarah van den Heuvel', `contact_email` = 's.vandenHeuvel@sufw.de', `contact_phone` = '(0176) 60328929'
WHERE `id` IN (
'6c7f216b-2704-4c81-b17a-000000000006',
'6c7f216b-2704-4c81-b17a-000000000007',
'6c7f216b-2704-4c81-b17a-000000000008',
'6c7f216b-2704-4c81-b17a-000000000009',
'd3c7f216-2704-4c81-b17a-000000000003',
'd3c7f216-2704-4c81-b17a-000000000004'
);
INSERT IGNORE INTO `sufw_booking_schema_migrations` (`version`) VALUES ('004_booking_contact_phones');