feat: DB backend and API implemementation
This commit is contained in:
1 parent
39b891cd63
commit
a78e84515a
14 files changed
+955
-652
No files matched your search
@@ -35,3 +35,23 @@ Der Import bricht ab, wenn die versionierten Contao-Tabellen bereits Inhalte ent
|
||||
## Medien
|
||||
|
||||
Medien gehören als Dateien nach `development-system/files/` und werden in Git eingecheckt. Sobald Contao-Medien verwendet werden, muss der Seed zusätzlich die Metadaten aus `tl_files` enthalten. Das ist absichtlich noch nicht automatisiert, weil die aktuelle Datenbank nur Verweise auf nicht versionierte lokale Dateien enthält.
|
||||
|
||||
## Terminbuchungs-Migrationen
|
||||
|
||||
Die Terminbuchung verwendet absichtlich keine Contao-Tabellen. Ihre separat
|
||||
versionierten SQL-Migrationen liegen unter `database/migrations/`. Jede Datei
|
||||
ist eigenständig und idempotent; sie kann deshalb auch später einzeln auf dem
|
||||
Produktivsystem ausgeführt werden.
|
||||
|
||||
Lokal werden alle Migrationen in Dateireihenfolge ausgeführt mit:
|
||||
|
||||
```powershell
|
||||
.\scripts\Invoke-BookingMigrations.ps1
|
||||
```
|
||||
|
||||
Für ein Produktivsystem wird die jeweilige Datei mit einem dort berechtigten
|
||||
MariaDB-/MySQL-Client ausgeführt. Zugangsdaten gehören dabei in die
|
||||
Betriebskonfiguration und niemals in die SQL-Datei oder das Repository. Die
|
||||
erste Migration erstellt `sufw_booking_events` und
|
||||
`sufw_booking_registrations` sowie neun ungefährliche Demo-Termine für beide
|
||||
Instanzen.
|
||||
@@ -0,0 +1,69 @@
|
||||
-- SUFW Terminbuchung: Anfangsschema und Demo-Termine
|
||||
--
|
||||
-- Diese Migration ist idempotent. Sie kann sowohl in der lokalen MariaDB als
|
||||
-- auch einzeln auf dem Produktivsystem ausgeführt werden.
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `sufw_booking_schema_migrations` (
|
||||
`version` varchar(100) NOT NULL,
|
||||
`applied_at` datetime NOT NULL DEFAULT current_timestamp(),
|
||||
PRIMARY KEY (`version`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `sufw_booking_events` (
|
||||
`id` char(36) NOT NULL,
|
||||
`project` varchar(32) NOT NULL,
|
||||
`title` varchar(160) NOT NULL,
|
||||
`starts_at` datetime NOT NULL,
|
||||
`ends_at` datetime NOT NULL,
|
||||
`capacity` tinyint unsigned NOT NULL DEFAULT 1,
|
||||
`format` varchar(24) NOT NULL,
|
||||
`introduction_required` tinyint(1) NOT NULL DEFAULT 0,
|
||||
`contact_name` varchar(160) NOT NULL,
|
||||
`contact_email` varchar(254) NOT NULL,
|
||||
`is_active` tinyint(1) NOT NULL DEFAULT 1,
|
||||
`created_at` datetime NOT NULL DEFAULT current_timestamp(),
|
||||
`updated_at` datetime NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `sufw_booking_events_project_starts_at` (`project`, `starts_at`),
|
||||
CONSTRAINT `sufw_booking_events_project_check` CHECK (`project` IN ('perspektivwerk', 'produktionsschule')),
|
||||
CONSTRAINT `sufw_booking_events_capacity_check` CHECK (`capacity` BETWEEN 1 AND 100),
|
||||
CONSTRAINT `sufw_booking_events_format_check` CHECK (`format` IN ('vor_ort', 'telefonisch')),
|
||||
CONSTRAINT `sufw_booking_events_dates_check` CHECK (`ends_at` > `starts_at`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `sufw_booking_registrations` (
|
||||
`id` char(36) NOT NULL,
|
||||
`event_id` char(36) NOT NULL,
|
||||
`status` varchar(24) NOT NULL,
|
||||
`name` varchar(160) NOT NULL,
|
||||
`email` varchar(254) NOT NULL,
|
||||
`phone` varchar(64) NOT NULL,
|
||||
`privacy_accepted_at` datetime NOT NULL,
|
||||
`introduction_attended` tinyint(1) NOT NULL DEFAULT 0,
|
||||
`introduction_date` date DEFAULT NULL,
|
||||
`created_at` datetime NOT NULL DEFAULT current_timestamp(),
|
||||
`updated_at` datetime NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `sufw_booking_registrations_event_status` (`event_id`, `status`),
|
||||
KEY `sufw_booking_registrations_person` (`email`, `name`),
|
||||
CONSTRAINT `sufw_booking_registrations_status_check` CHECK (`status` IN ('requested', 'pending_confirmation', 'confirmed', 'removed', 'expired')),
|
||||
CONSTRAINT `sufw_booking_registrations_introduction_check` CHECK ((`introduction_attended` = 0 AND `introduction_date` IS NULL) OR (`introduction_attended` = 1 AND `introduction_date` IS NOT NULL)),
|
||||
CONSTRAINT `sufw_booking_registrations_event_fk` FOREIGN KEY (`event_id`) REFERENCES `sufw_booking_events` (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- Die IDs sind bewusst stabil, damit INSERT IGNORE diese Beispieldaten bei
|
||||
-- wiederholter Ausführung nicht dupliziert.
|
||||
INSERT IGNORE INTO `sufw_booking_events`
|
||||
(`id`, `project`, `title`, `starts_at`, `ends_at`, `capacity`, `format`, `introduction_required`, `contact_name`, `contact_email`)
|
||||
VALUES
|
||||
('6c7f216b-2704-4c81-b17a-000000000001', 'perspektivwerk', 'Erstgespräch PerspektivWerk', '2026-09-02 09:00:00', '2026-09-02 10:00:00', 2, 'vor_ort', 0, 'PerspektivWerk-Team', 'perspektivwerk@sufw.de'),
|
||||
('6c7f216b-2704-4c81-b17a-000000000002', 'perspektivwerk', 'Soz. Päd. Modul PerspektivWerk', '2026-09-04 09:00:00', '2026-09-04 13:00:00', 1, 'vor_ort', 0, 'PerspektivWerk-Team', 'perspektivwerk@sufw.de'),
|
||||
('6c7f216b-2704-4c81-b17a-000000000003', 'perspektivwerk', 'Psy Modul PerspektivWerk', '2026-09-09 09:00:00', '2026-09-09 13:00:00', 2, 'telefonisch', 0, 'PerspektivWerk-Team', 'perspektivwerk@sufw.de'),
|
||||
('6c7f216b-2704-4c81-b17a-000000000004', 'perspektivwerk', 'Praxis Modul PerspektivWerk', '2026-09-14 08:00:00', '2026-09-18 16:00:00', 5, 'vor_ort', 0, 'PerspektivWerk-Team', 'perspektivwerk@sufw.de'),
|
||||
('6c7f216b-2704-4c81-b17a-000000000005', 'perspektivwerk', 'Erstgespräch PerspektivWerk', '2026-10-01 11:00:00', '2026-10-01 12:00:00', 1, 'telefonisch', 0, 'PerspektivWerk-Team', 'perspektivwerk@sufw.de'),
|
||||
('6c7f216b-2704-4c81-b17a-000000000006', 'produktionsschule', 'Voranmeldung Kennenlerntermin Produktionsschule', '2026-09-01 10:00:00', '2026-09-01 11:00:00', 3, 'vor_ort', 0, 'Produktionsschule-Team', 'produktionsschule@sufw.de'),
|
||||
('6c7f216b-2704-4c81-b17a-000000000007', 'produktionsschule', 'Voranmeldung Kennenlerntermin Produktionsschule', '2026-09-08 10:00:00', '2026-09-08 11:00:00', 3, 'vor_ort', 0, 'Produktionsschule-Team', 'produktionsschule@sufw.de'),
|
||||
('6c7f216b-2704-4c81-b17a-000000000008', 'produktionsschule', 'Probearbeiten', '2026-09-14 08:00:00', '2026-09-18 16:00:00', 2, 'vor_ort', 1, 'Produktionsschule-Team', 'produktionsschule@sufw.de'),
|
||||
('6c7f216b-2704-4c81-b17a-000000000009', 'produktionsschule', 'Voranmeldung Kennenlerntermin Produktionsschule', '2026-10-06 10:00:00', '2026-10-06 11:00:00', 3, 'telefonisch', 0, 'Produktionsschule-Team', 'produktionsschule@sufw.de');
|
||||
|
||||
INSERT IGNORE INTO `sufw_booking_schema_migrations` (`version`) VALUES ('001_booking_schema');
|
||||
Reference in new issue
Block a user