CREATE TABLE IF NOT EXISTS users ( id INT AUTO_INCREMENT PRIMARY KEY, portal_user_id INT NULL, email VARCHAR(255) NOT NULL UNIQUE, display_name VARCHAR(255) NULL, is_active TINYINT(1) NOT NULL DEFAULT 1, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, last_login_at DATETIME NULL ); CREATE TABLE IF NOT EXISTS tenants ( id INT AUTO_INCREMENT PRIMARY KEY, owner_user_id INT NOT NULL, slug VARCHAR(100) NOT NULL UNIQUE, storage_root VARCHAR(500) NOT NULL, service_status VARCHAR(50) NOT NULL DEFAULT 'active', retention_mode VARCHAR(50) NOT NULL DEFAULT 'standard', created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, CONSTRAINT fk_tenants_owner FOREIGN KEY (owner_user_id) REFERENCES users(id) ); CREATE TABLE IF NOT EXISTS devices ( id INT AUTO_INCREMENT PRIMARY KEY, tenant_id INT NOT NULL, device_name VARCHAR(100) NOT NULL, device_type VARCHAR(50) NOT NULL, relative_path VARCHAR(255) NOT NULL, is_active TINYINT(1) NOT NULL DEFAULT 1, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, CONSTRAINT uq_devices_tenant_name UNIQUE (tenant_id, device_name), CONSTRAINT fk_devices_tenant FOREIGN KEY (tenant_id) REFERENCES tenants(id) ); CREATE TABLE IF NOT EXISTS files ( id BIGINT AUTO_INCREMENT PRIMARY KEY, tenant_id INT NOT NULL, device_id INT NOT NULL, parent_file_id BIGINT NULL, file_kind VARCHAR(20) NOT NULL, relative_path VARCHAR(1000) NOT NULL, directory_path VARCHAR(1000) NOT NULL, original_filename VARCHAR(255) NOT NULL, display_filename VARCHAR(255) NULL, basename VARCHAR(255) NOT NULL, extension VARCHAR(50) NOT NULL, mime_type VARCHAR(255) NULL, size_bytes BIGINT NOT NULL DEFAULT 0, sha256 CHAR(64) NULL, capture_date DATETIME NULL, uploaded_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, is_immutable TINYINT(1) NOT NULL DEFAULT 1, is_deleted TINYINT(1) NOT NULL DEFAULT 0, deleted_at DATETIME NULL, CONSTRAINT fk_files_tenant FOREIGN KEY (tenant_id) REFERENCES tenants(id), CONSTRAINT fk_files_device FOREIGN KEY (device_id) REFERENCES devices(id), CONSTRAINT fk_files_parent FOREIGN KEY (parent_file_id) REFERENCES files(id) ); CREATE TABLE IF NOT EXISTS jobs ( id BIGINT AUTO_INCREMENT PRIMARY KEY, tenant_id INT NOT NULL, file_id BIGINT NOT NULL, job_type VARCHAR(100) NOT NULL, options_json LONGTEXT NULL, status VARCHAR(50) NOT NULL DEFAULT 'queued', created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, started_at DATETIME NULL, completed_at DATETIME NULL, output_file_id BIGINT NULL, log_text LONGTEXT NULL, CONSTRAINT fk_jobs_tenant FOREIGN KEY (tenant_id) REFERENCES tenants(id), CONSTRAINT fk_jobs_file FOREIGN KEY (file_id) REFERENCES files(id) ); CREATE TABLE IF NOT EXISTS audit_logs ( id BIGINT AUTO_INCREMENT PRIMARY KEY, tenant_id INT NULL, user_id INT NULL, actor_type VARCHAR(20) NOT NULL, event_type VARCHAR(100) NOT NULL, file_id BIGINT NULL, job_id BIGINT NULL, ip_address VARCHAR(64) NULL, user_agent VARCHAR(500) NULL, event_detail LONGTEXT NULL, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, INDEX idx_audit_tenant_created (tenant_id, created_at), INDEX idx_audit_event_type (event_type) ); CREATE TABLE IF NOT EXISTS admin_access_tokens ( id BIGINT AUTO_INCREMENT PRIMARY KEY, tenant_id INT NOT NULL, issued_by_user_id INT NOT NULL, used_by_admin_id INT NULL, token_hash CHAR(64) NOT NULL, purpose VARCHAR(255) NOT NULL, status VARCHAR(50) NOT NULL DEFAULT 'issued', expires_at DATETIME NOT NULL, used_at DATETIME NULL, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, CONSTRAINT fk_admin_token_tenant FOREIGN KEY (tenant_id) REFERENCES tenants(id), CONSTRAINT fk_admin_token_owner FOREIGN KEY (issued_by_user_id) REFERENCES users(id) );