-- Produktkatalog, Bestellungen (mit unveränderlichem Preis-Snapshot) und Verträge CREATE TABLE number_sequences (name VARCHAR(30) PRIMARY KEY, next_value INT NOT NULL); INSERT INTO number_sequences VALUES ('order', 20000), ('contract', 30000); CREATE TABLE tax_rates ( id CHAR(36) PRIMARY KEY, name VARCHAR(100) NOT NULL, rate_bp INT NOT NULL, active TINYINT(1) NOT NULL DEFAULT 1, created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ); INSERT INTO tax_rates (id, name, rate_bp) VALUES (UUID(), 'Regelsteuersatz 19 %', 1900), (UUID(), 'Ermäßigter Steuersatz 7 %', 700), (UUID(), 'Steuerfrei 0 %', 0); CREATE TABLE products ( id CHAR(36) PRIMARY KEY, sku VARCHAR(50) NOT NULL UNIQUE, category ENUM('hosting','license','addon','service') NOT NULL, status ENUM('draft','active','retired') NOT NULL DEFAULT 'draft', connector_instance_id CHAR(36) NULL, orderable_by_customer TINYINT(1) NOT NULL DEFAULT 0, requires_approval TINYINT(1) NOT NULL DEFAULT 1, customer_actions JSON NOT NULL DEFAULT '[]', current_version_id CHAR(36) NULL, created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3), FOREIGN KEY (connector_instance_id) REFERENCES connector_instances(id) ON DELETE SET NULL ); -- Versionen sind unveränderlich; jede Preis-/Vertragsänderung erzeugt eine neue Version. CREATE TABLE product_versions ( id CHAR(36) PRIMARY KEY, product_id CHAR(36) NOT NULL, version INT NOT NULL, name VARCHAR(200) NOT NULL, description TEXT NULL, tax_rate_id CHAR(36) NOT NULL, tax_bp INT NOT NULL, setup_net_cents INT NOT NULL DEFAULT 0, recurring_net_cents INT NOT NULL DEFAULT 0, currency CHAR(3) NOT NULL DEFAULT 'EUR', billing_interval ENUM('once','monthly','yearly') NOT NULL, term_months INT NOT NULL DEFAULT 0, renewal ENUM('auto','none') NOT NULL DEFAULT 'none', renewal_term_months INT NOT NULL DEFAULT 0, notice_days INT NOT NULL DEFAULT 30, provisioning_json JSON NOT NULL DEFAULT '{}', created_by CHAR(36) NULL, created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), UNIQUE KEY uq_product_version (product_id, version), FOREIGN KEY (product_id) REFERENCES products(id) ON DELETE CASCADE, FOREIGN KEY (tax_rate_id) REFERENCES tax_rates(id) ); CREATE TABLE orders ( id CHAR(36) PRIMARY KEY, number VARCHAR(20) NOT NULL UNIQUE, org_id CHAR(36) NOT NULL, status ENUM('pending_approval','approved','provisioning','completed','failed','rejected','cancelled') NOT NULL, placed_by CHAR(36) NULL, placed_via ENUM('customer','staff') NOT NULL, approval_required TINYINT(1) NOT NULL DEFAULT 1, approved_by CHAR(36) NULL, approved_at DATETIME(3) NULL, note VARCHAR(500) NULL, failure_note VARCHAR(500) NULL, failure_ambiguous TINYINT(1) NOT NULL DEFAULT 0, created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3), INDEX (org_id), INDEX (status), FOREIGN KEY (org_id) REFERENCES organizations(id) ); CREATE TABLE order_items ( id CHAR(36) PRIMARY KEY, order_id CHAR(36) NOT NULL, product_version_id CHAR(36) NOT NULL, quantity INT NOT NULL DEFAULT 1, discount_bp INT NOT NULL DEFAULT 0, snapshot_json JSON NOT NULL, FOREIGN KEY (order_id) REFERENCES orders(id) ON DELETE CASCADE, FOREIGN KEY (product_version_id) REFERENCES product_versions(id) ); CREATE TABLE contracts ( id CHAR(36) PRIMARY KEY, number VARCHAR(20) NOT NULL UNIQUE, org_id CHAR(36) NOT NULL, order_item_id CHAR(36) NOT NULL UNIQUE, product_version_id CHAR(36) NOT NULL, status ENUM('pending','active','suspended','cancelled','expired','failed') NOT NULL DEFAULT 'pending', started_at DATETIME(3) NULL, term_end DATETIME(3) NULL, renewal ENUM('auto','none') NOT NULL DEFAULT 'none', renewal_term_months INT NOT NULL DEFAULT 0, notice_days INT NOT NULL DEFAULT 30, cancel_requested_at DATETIME(3) NULL, cancel_effective_at DATETIME(3) NULL, cancelled_at DATETIME(3) NULL, resource_id CHAR(36) NULL, price_snapshot_json JSON NOT NULL, created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3), INDEX (org_id), INDEX (status), FOREIGN KEY (org_id) REFERENCES organizations(id), FOREIGN KEY (order_item_id) REFERENCES order_items(id), FOREIGN KEY (product_version_id) REFERENCES product_versions(id), FOREIGN KEY (resource_id) REFERENCES resources(id) ON DELETE SET NULL );