b6499eb7b3
New domain mirroring the Feedback module's conventions: single-use voucher codes (wildcard + personalized), redemption with race-safe capacity and deadline enforcement, admin CRUD for vouchers/redemptions/event settings with an audit trail, and reuse of the existing Calendar session auth. Backend pieces: - Tickets domain (public redeem flow, admin vouchers/redemptions/events) - Calendar events.service.ts: add getEventById - Mailer: attachment/HTML support, fix a shared-mutable-state race - Per-event capacity/deadline/address settings, with an "address required" option on top of "address collected" - Email format validation on redeem and admin voucher/redemption input - Docker Compose dev stack (MariaDB + seed data) for local testing Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
90 lines
4.2 KiB
SQL
90 lines
4.2 KiB
SQL
-- Local dev only. Real schema, provided directly by the repo owner
|
|
-- (calendars, events, event_versions, sessions, users) - not a guess.
|
|
USE nachklang_calendar;
|
|
|
|
CREATE TABLE `calendars` (
|
|
`calendar_id` int(11) NOT NULL AUTO_INCREMENT,
|
|
`name` text NOT NULL,
|
|
`includes_calendars` text DEFAULT NULL,
|
|
PRIMARY KEY (`calendar_id`)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
|
|
|
CREATE TABLE `users` (
|
|
`user_id` int(11) NOT NULL AUTO_INCREMENT,
|
|
`full_name` text NOT NULL,
|
|
`password_hash` text DEFAULT NULL,
|
|
`email` text NOT NULL,
|
|
`is_active` tinyint(1) DEFAULT 0,
|
|
`pw_reset_token_hash` text DEFAULT NULL,
|
|
`activation_token` text DEFAULT NULL,
|
|
PRIMARY KEY (`user_id`),
|
|
UNIQUE KEY `email` (`email`) USING HASH
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
|
|
|
CREATE TABLE `sessions` (
|
|
`session_id` int(11) NOT NULL AUTO_INCREMENT,
|
|
`user_id` int(11) NOT NULL,
|
|
`session_key_hash` text DEFAULT NULL,
|
|
`created_date` datetime DEFAULT current_timestamp(),
|
|
`valid_until` datetime DEFAULT (current_timestamp() + interval 30 day),
|
|
`last_ip` text DEFAULT NULL,
|
|
PRIMARY KEY (`session_id`),
|
|
KEY `sessions_users_user_id_fk` (`user_id`),
|
|
CONSTRAINT `sessions_users_user_id_fk` FOREIGN KEY (`user_id`) REFERENCES `users` (`user_id`)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
|
|
|
CREATE TABLE `events` (
|
|
`event_id` int(11) NOT NULL AUTO_INCREMENT,
|
|
`calendar_id` int(11) NOT NULL,
|
|
`uuid` text NOT NULL,
|
|
`created_date` datetime DEFAULT current_timestamp(),
|
|
`created_by_id` int(11) NOT NULL,
|
|
PRIMARY KEY (`event_id`),
|
|
KEY `events_calendars_calendar_id_fk` (`calendar_id`),
|
|
KEY `events_users_user_id_fk` (`created_by_id`),
|
|
CONSTRAINT `events_calendars_calendar_id_fk` FOREIGN KEY (`calendar_id`) REFERENCES `calendars` (`calendar_id`),
|
|
CONSTRAINT `events_users_user_id_fk` FOREIGN KEY (`created_by_id`) REFERENCES `users` (`user_id`)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
|
|
|
CREATE TABLE `event_versions` (
|
|
`event_version_id` int(11) NOT NULL AUTO_INCREMENT,
|
|
`event_id` int(11) NOT NULL,
|
|
`name` text DEFAULT NULL,
|
|
`description` text DEFAULT NULL,
|
|
`start_datetime` datetime DEFAULT NULL,
|
|
`end_datetime` datetime DEFAULT NULL,
|
|
`whole_day` tinyint(1) DEFAULT NULL,
|
|
`repeat_frequency` text DEFAULT NULL,
|
|
`location` text DEFAULT NULL,
|
|
`url` text DEFAULT NULL,
|
|
`version_created_by_id` int(11) DEFAULT NULL,
|
|
`status` text DEFAULT NULL,
|
|
`version_created_at` datetime DEFAULT current_timestamp(),
|
|
PRIMARY KEY (`event_version_id`),
|
|
KEY `event_versions_events_event_id_fk` (`event_id`),
|
|
KEY `event_versions_users_user_id_fk` (`version_created_by_id`),
|
|
CONSTRAINT `event_versions_events_event_id_fk` FOREIGN KEY (`event_id`) REFERENCES `events` (`event_id`) ON DELETE CASCADE ON UPDATE CASCADE,
|
|
CONSTRAINT `event_versions_users_user_id_fk` FOREIGN KEY (`version_created_by_id`) REFERENCES `users` (`user_id`)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
|
|
|
INSERT INTO calendars (calendar_id, name, includes_calendars) VALUES
|
|
(1, 'public', '[]'),
|
|
(2, 'members', '[]'),
|
|
(3, 'management', '[]'),
|
|
(4, 'choir', '[]'),
|
|
(5, 'birthdays', '[]');
|
|
|
|
-- Dev admin, password: devpassword
|
|
INSERT INTO users (email, password_hash, full_name, is_active) VALUES
|
|
('dev@nachklang.art', '$2b$10$vmj7POS/68SGE.eI7pGjMegrw0vNNZ2HVSUTra5NRsl8iOLwiMgZK', 'Dev Admin', 1);
|
|
|
|
INSERT INTO events (calendar_id, uuid, created_by_id) VALUES
|
|
(1, UUID(), 1),
|
|
(1, UUID(), 1),
|
|
(1, UUID(), 1);
|
|
|
|
INSERT INTO event_versions (event_id, name, description, start_datetime, end_datetime, whole_day, location, url, status, version_created_by_id) VALUES
|
|
(1, 'Frühlingskonzert 2026', 'Erstes Konzert der Reihe', '2026-04-18 19:00:00', '2026-04-18 21:00:00', 0, 'Musikhochschule, Karlsruhe', 'https://www.nachklang.art/events/fruehlingskonzert-2026', 'PUBLIC', 1),
|
|
(2, 'Sommerkonzert 2026', 'Zweites Konzert der Reihe', '2026-07-11 19:00:00', '2026-07-11 21:00:00', 0, 'Christuskirche, Karlsruhe', 'https://www.nachklang.art/events/sommerkonzert-2026', 'PUBLIC', 1),
|
|
(3, 'Adventskonzert 2026', 'Drittes Konzert der Reihe', '2026-12-05 19:00:00', '2026-12-05 21:00:00', 0, 'Stadtkirche, Karlsruhe', 'https://www.nachklang.art/events/adventskonzert-2026', 'DRAFT', 1);
|