major update

This commit is contained in:
2026-03-04 15:56:58 +01:00
parent 16759a2732
commit 8f4dd5840d
478 changed files with 24313 additions and 8201 deletions

View File

@@ -86,6 +86,7 @@ CREATE TABLE IF NOT EXISTS `tenants` (
KEY `idx_tenants_created_by` (`created_by`),
KEY `idx_tenants_modified_by` (`modified_by`),
KEY `idx_tenants_status_changed_by` (`status_changed_by`),
CONSTRAINT `chk_tenants_status` CHECK (`status` IN ('active', 'inactive')),
CONSTRAINT `fk_tenants_created_by` FOREIGN KEY (`created_by`) REFERENCES `users` (`id`) ON DELETE SET NULL,
CONSTRAINT `fk_tenants_modified_by` FOREIGN KEY (`modified_by`) REFERENCES `users` (`id`) ON DELETE SET NULL,
CONSTRAINT `fk_tenants_status_changed_by` FOREIGN KEY (`status_changed_by`) REFERENCES `users` (`id`) ON DELETE SET NULL
@@ -395,7 +396,8 @@ CREATE TABLE IF NOT EXISTS `mail_log` (
`provider_message_id` VARCHAR(255) NULL,
PRIMARY KEY (`id`),
KEY `idx_mail_log_status` (`status`),
KEY `idx_mail_log_to_email` (`to_email`)
KEY `idx_mail_log_to_email` (`to_email`),
CONSTRAINT `chk_mail_log_status` CHECK (`status` IN ('queued', 'sent', 'failed'))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE IF NOT EXISTS `api_audit_log` (
@@ -428,6 +430,39 @@ CREATE TABLE IF NOT EXISTS `api_audit_log` (
CONSTRAINT `fk_api_audit_token` FOREIGN KEY (`api_token_id`) REFERENCES `user_api_tokens` (`id`) ON DELETE SET NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE IF NOT EXISTS `system_audit_log` (
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
`event_uuid` CHAR(36) NOT NULL,
`request_id` CHAR(36) NULL,
`channel` VARCHAR(16) NOT NULL,
`event_type` VARCHAR(64) NOT NULL,
`outcome` VARCHAR(16) NOT NULL,
`error_code` VARCHAR(100) NULL,
`actor_user_id` INT UNSIGNED NULL,
`actor_tenant_id` INT UNSIGNED NULL,
`target_type` VARCHAR(64) NULL,
`target_id` INT UNSIGNED NULL,
`target_uuid` CHAR(36) NULL,
`method` VARCHAR(8) NULL,
`path` VARCHAR(255) NULL,
`ip_hash` CHAR(64) NULL,
`user_agent_hash` CHAR(64) NULL,
`metadata_json` TEXT NULL,
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `uniq_system_audit_event_uuid` (`event_uuid`),
KEY `idx_system_audit_created` (`created_at`),
KEY `idx_system_audit_event_created` (`event_type`, `created_at`),
KEY `idx_system_audit_actor_created` (`actor_user_id`, `created_at`),
KEY `idx_system_audit_target_created` (`target_type`, `target_uuid`, `created_at`),
KEY `idx_system_audit_request_created` (`request_id`, `created_at`),
KEY `idx_system_audit_outcome_created` (`outcome`, `created_at`),
CONSTRAINT `chk_system_audit_log_channel` CHECK (`channel` IN ('web', 'api', 'scheduler', 'cli')),
CONSTRAINT `chk_system_audit_log_outcome` CHECK (`outcome` IN ('success', 'failed', 'denied')),
CONSTRAINT `fk_system_audit_actor_user` FOREIGN KEY (`actor_user_id`) REFERENCES `users` (`id`) ON DELETE SET NULL,
CONSTRAINT `fk_system_audit_actor_tenant` FOREIGN KEY (`actor_tenant_id`) REFERENCES `tenants` (`id`) ON DELETE SET NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE IF NOT EXISTS `import_audit_runs` (
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
`run_uuid` CHAR(36) NOT NULL,
@@ -451,6 +486,7 @@ CREATE TABLE IF NOT EXISTS `import_audit_runs` (
KEY `idx_import_audit_status_started` (`status`, `started_at`),
KEY `idx_import_audit_profile_started` (`profile_key`, `started_at`),
KEY `idx_import_audit_user_started` (`user_id`, `started_at`),
CONSTRAINT `chk_import_audit_runs_status` CHECK (`status` IN ('running', 'success', 'partial', 'failed')),
CONSTRAINT `fk_import_audit_user` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE SET NULL,
CONSTRAINT `fk_import_audit_tenant` FOREIGN KEY (`current_tenant_id`) REFERENCES `tenants` (`id`) ON DELETE SET NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
@@ -481,6 +517,9 @@ CREATE TABLE IF NOT EXISTS `user_lifecycle_audit_log` (
KEY `idx_user_lifecycle_target_uuid_created` (`target_user_uuid`, `created_at`),
KEY `idx_user_lifecycle_run_uuid` (`run_uuid`),
KEY `idx_user_lifecycle_restored` (`restored_at`),
CONSTRAINT `chk_user_lifecycle_action` CHECK (`action` IN ('deactivate', 'delete', 'restore')),
CONSTRAINT `chk_user_lifecycle_trigger_type` CHECK (`trigger_type` IN ('manual', 'cron', 'system')),
CONSTRAINT `chk_user_lifecycle_status` CHECK (`status` IN ('success', 'skipped', 'failed')),
CONSTRAINT `fk_user_lifecycle_actor` FOREIGN KEY (`actor_user_id`) REFERENCES `users` (`id`) ON DELETE SET NULL,
CONSTRAINT `fk_user_lifecycle_target` FOREIGN KEY (`target_user_id`) REFERENCES `users` (`id`) ON DELETE SET NULL,
CONSTRAINT `fk_user_lifecycle_restored_by` FOREIGN KEY (`restored_by_user_id`) REFERENCES `users` (`id`) ON DELETE SET NULL,
@@ -510,7 +549,8 @@ CREATE TABLE IF NOT EXISTS `scheduled_jobs` (
PRIMARY KEY (`id`),
UNIQUE KEY `uniq_scheduled_jobs_job_key` (`job_key`),
KEY `idx_scheduled_jobs_enabled_next` (`enabled`, `next_run_at`),
KEY `idx_scheduled_jobs_status` (`last_run_status`)
KEY `idx_scheduled_jobs_status` (`last_run_status`),
CONSTRAINT `chk_scheduled_jobs_last_run_status` CHECK (`last_run_status` IS NULL OR `last_run_status` IN ('running', 'success', 'failed', 'skipped'))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE IF NOT EXISTS `scheduled_job_runs` (
@@ -533,6 +573,8 @@ CREATE TABLE IF NOT EXISTS `scheduled_job_runs` (
KEY `idx_sched_runs_job_created` (`job_id`, `created_at`),
KEY `idx_sched_runs_status_created` (`status`, `created_at`),
KEY `idx_sched_runs_trigger_created` (`trigger_type`, `created_at`),
CONSTRAINT `chk_scheduled_job_runs_status` CHECK (`status` IN ('success', 'failed', 'skipped')),
CONSTRAINT `chk_scheduled_job_runs_trigger_type` CHECK (`trigger_type` IN ('scheduler', 'manual')),
CONSTRAINT `fk_sched_runs_job` FOREIGN KEY (`job_id`) REFERENCES `scheduled_jobs` (`id`) ON DELETE CASCADE,
CONSTRAINT `fk_sched_runs_actor_user` FOREIGN KEY (`actor_user_id`) REFERENCES `users` (`id`) ON DELETE SET NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
@@ -543,7 +585,8 @@ CREATE TABLE IF NOT EXISTS `scheduler_runtime_status` (
`last_result` VARCHAR(32) NULL,
`last_error_code` VARCHAR(64) NULL,
`updated_at` DATETIME NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
PRIMARY KEY (`id`),
CONSTRAINT `chk_scheduler_runtime_status_last_result` CHECK (`last_result` IS NULL OR `last_result` IN ('ok', 'lock_not_acquired', 'unexpected_error'))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE IF NOT EXISTS `request_rate_limits` (
@@ -740,6 +783,8 @@ VALUES
('docs.view', 'Can view developer documentation', 1, 1),
('mail_log.view', 'Can view mail logs', 1, 1),
('api_audit.view', 'Can view API audit logs', 1, 1),
('system_audit.view', 'Can view system audit logs', 1, 1),
('system_audit.purge', 'Can purge system audit logs', 1, 1),
('stats.view', 'Can view statistics', 1, 1)
ON DUPLICATE KEY UPDATE
`description` = VALUES(`description`),
@@ -776,6 +821,36 @@ ON DUPLICATE KEY UPDATE
`label` = VALUES(`label`),
`description` = VALUES(`description`);
INSERT INTO `scheduled_jobs` (
`job_key`,
`label`,
`description`,
`enabled`,
`timezone`,
`schedule_type`,
`schedule_interval`,
`schedule_time`,
`schedule_weekdays_csv`,
`catchup_once`,
`next_run_at`
)
VALUES (
'system_audit_purge',
'System audit purge',
'Purges system audit entries by retention policy',
1,
'Europe/Berlin',
'daily',
1,
'03:00',
NULL,
1,
NULL
)
ON DUPLICATE KEY UPDATE
`label` = VALUES(`label`),
`description` = VALUES(`description`);
INSERT INTO `scheduler_runtime_status` (
`id`,
`last_heartbeat_at`,
@@ -808,8 +883,16 @@ JOIN permissions p ON p.`key` IN (
'users.lifecycle_restore',
'custom_fields.manage', 'custom_fields.edit_values',
'api_docs.view', 'docs.view',
'mail_log.view', 'api_audit.view',
'mail_log.view', 'api_audit.view', 'system_audit.view', 'system_audit.purge',
'stats.view'
)
WHERE r.description IN ('Admin', 'Administrator') OR r.id = 1
ON DUPLICATE KEY UPDATE role_id = role_id;
INSERT INTO `settings` (`key`, `value`, `description`)
VALUES
('system_audit_enabled', '1', 'setting.system_audit_enabled'),
('system_audit_retention_days', '365', 'setting.system_audit_retention_days')
ON DUPLICATE KEY UPDATE
`value` = VALUES(`value`),
`description` = VALUES(`description`);