/* ======================================================================= Email Template System — Schema passend zur api.php (2025-09-06) Charset: utf8mb4 | Engine: InnoDB Hinweis: - Mandantenfähigkeit über customer_id (alle Haupttabellen + Items + Assets). - Contentspalten: Templates/Sections/Blocks = `html`, Snippets = `content`. - Referenzen: template_items (Section/Block) & section_items (Block). ======================================================================= */ SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS = 0; /* Drop-Reihenfolge: erst Items, dann Master-Tabellen */ DROP TABLE IF EXISTS `emailtemplate_section_items`; DROP TABLE IF EXISTS `emailtemplate_template_items`; DROP TABLE IF EXISTS `emailtemplate_assets`; DROP TABLE IF EXISTS `emailtemplate_snippets`; DROP TABLE IF EXISTS `emailtemplate_blocks`; DROP TABLE IF EXISTS `emailtemplate_sections`; DROP TABLE IF EXISTS `emailtemplate_templates`; /*DROP TABLE IF EXISTS `customers`; -- optional (nur falls lokal hier gepflegt) */ /*DROP TABLE IF EXISTS `customer_users`; -- optional */ SET FOREIGN_KEY_CHECKS = 1; /* ========================= Master-Tabellen ========================= */ /* 1) Templates (oberste Ebene) */ CREATE TABLE `emailtemplate_templates` ( `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, `customer_id` INT UNSIGNED NOT NULL, `name` VARCHAR(255) NOT NULL, `json_content` MEDIUMTEXT NULL, -- NEU: Speichert GrapesJS JSON-Zustand (Komponenten + Stile) `html` MEDIUMTEXT NULL, -- BLEIBT: Speichert finalen, exportierten HTML-Code `created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`), KEY `idx_tpl_customer` (`customer_id`), KEY `idx_tpl_updated` (`updated_at`), KEY `idx_tpl_name` (`name`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; /* 2) Sections (optional einem Template zugeordnet) */ CREATE TABLE `emailtemplate_sections` ( `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, `customer_id` INT UNSIGNED NOT NULL, `template_id` INT UNSIGNED NULL, `name` VARCHAR(255) NOT NULL, `type` VARCHAR(50) NOT NULL DEFAULT 'html', `json_content` MEDIUMTEXT NULL, -- NEU: Speichert GrapesJS JSON-Zustand (Komponenten + Stile) `z_index` INT NOT NULL DEFAULT 0, `html` MEDIUMTEXT NULL, -- BLEIBT: Speichert finalen, exportierten HTML-Code `created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`), KEY `idx_sec_customer` (`customer_id`), KEY `idx_sec_template` (`template_id`), KEY `idx_sec_sort` (`template_id`,`z_index`,`id`), CONSTRAINT `fk_sections_template` FOREIGN KEY (`template_id`) REFERENCES `emailtemplate_templates` (`id`) ON UPDATE CASCADE ON DELETE SET NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; /* 3) Blocks (optional einer Section zugeordnet) */ CREATE TABLE `emailtemplate_blocks` ( `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, `customer_id` INT UNSIGNED NOT NULL, `section_id` INT UNSIGNED NULL, `name` VARCHAR(255) NOT NULL, `category` VARCHAR(100) NOT NULL DEFAULT 'Default', `json_content` MEDIUMTEXT NULL, -- NEU: Speichert GrapesJS JSON-Zustand (Komponenten + Stile) `html` MEDIUMTEXT NULL, -- BLEIBT: Speichert finalen, exportierten HTML-Code `created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`), KEY `idx_blk_customer` (`customer_id`), KEY `idx_blk_section` (`section_id`), KEY `idx_blk_name` (`name`), CONSTRAINT `fk_blocks_section` FOREIGN KEY (`section_id`) REFERENCES `emailtemplate_sections` (`id`) ON UPDATE CASCADE ON DELETE SET NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; /* 4) Snippets (kleine Bausteine; BY VALUE) */ CREATE TABLE `emailtemplate_snippets` ( `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, `customer_id` INT UNSIGNED NOT NULL, `name` VARCHAR(255) NOT NULL, `category` VARCHAR(100) NOT NULL DEFAULT '', `json_content` MEDIUMTEXT NULL, -- NEU: Speichert GrapesJS JSON-Zustand `content` MEDIUMTEXT NULL, -- BLEIBT: Speichert finalen, exportierten HTML-Code `block_id` INT UNSIGNED NULL, `created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`), KEY `idx_snp_customer` (`customer_id`), KEY `idx_snp_name` (`name`), KEY `idx_snp_block` (`block_id`), CONSTRAINT `fk_snippets_block` FOREIGN KEY (`block_id`) REFERENCES `emailtemplate_blocks` (`id`) ON UPDATE CASCADE ON DELETE SET NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; /* 5) Assets (READ-only in api.php) */ CREATE TABLE `emailtemplate_assets` ( `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, `customer_id` INT UNSIGNED NOT NULL, `name` VARCHAR(255) NOT NULL, `type` VARCHAR(50) NOT NULL, `mime_type` VARCHAR(100) NOT NULL, `size_bytes` INT UNSIGNED NOT NULL DEFAULT 0, `public_url` VARCHAR(1000) NULL, `created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`), KEY `idx_ast_customer` (`customer_id`), KEY `idx_ast_updated` (`updated_at`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; /* ========================= Referenz-Item-Tabellen ========================= */ /* 6) Items im Template (Sections ODER Blocks als Referenz) */ CREATE TABLE `emailtemplate_template_items` ( `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, `customer_id` INT UNSIGNED NOT NULL, `template_id` INT UNSIGNED NOT NULL, `sort` INT NOT NULL DEFAULT 0, `ref_type` ENUM('section','block') NOT NULL, `ref_id` INT UNSIGNED NOT NULL, `overrides_json` JSON NULL, `lock_to_version` INT NULL, `created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`), KEY `idx_titems_template_sort` (`template_id`,`sort`), KEY `idx_titems_customer` (`customer_id`), KEY `idx_titems_ref` (`ref_type`,`ref_id`), CONSTRAINT `fk_titems_template` FOREIGN KEY (`template_id`) REFERENCES `emailtemplate_templates` (`id`) ON UPDATE CASCADE ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; /* 7) Items in einer Section (NUR Blocks als Referenz) */ CREATE TABLE `emailtemplate_section_items` ( `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, `customer_id` INT UNSIGNED NOT NULL, `section_id` INT UNSIGNED NOT NULL, `sort` INT NOT NULL DEFAULT 0, `ref_type` ENUM('block') NOT NULL, `ref_id` INT UNSIGNED NOT NULL, `overrides_json` JSON NULL, `lock_to_version` INT NULL, `created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`), KEY `idx_sitems_section_sort` (`section_id`,`sort`), KEY `idx_sitems_customer` (`customer_id`), KEY `idx_sitems_ref` (`ref_type`,`ref_id`), CONSTRAINT `fk_sitems_section` FOREIGN KEY (`section_id`) REFERENCES `emailtemplate_sections` (`id`) ON UPDATE CASCADE ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; /* ========================= Optionale Seed-Daten ========================= */ -- INSERT INTO `emailtemplate_templates` (`customer_id`,`name`,`html`) VALUES (1,'Newsletter-Template',''); -- INSERT INTO `emailtemplate_sections` (`customer_id`,`name`,`type`,`z_index`,`html`,`template_id`) VALUES (1,'Hero','html',10,'
| {{children}} |
| ... |
Lorem ipsum…
'); -- FK-Prüfung (falls temporär deaktiviert) wieder aktivieren SET FOREIGN_KEY_CHECKS = 1;