-- AegisOne Engineering — Full Database Schema -- Run once on MySQL 5.7+ / MariaDB 10.3+ CREATE TABLE IF NOT EXISTS `users` ( `id` int UNSIGNED AUTO_INCREMENT PRIMARY KEY, `login` varchar(50) NOT NULL UNIQUE, `password_hash` varchar(255) NOT NULL, `role` enum('owner','engineer','technician') NOT NULL DEFAULT 'technician', `full_name` varchar(255) NOT NULL, `phone` varchar(50) DEFAULT '', `email` varchar(255) DEFAULT '', `is_active` tinyint(1) NOT NULL DEFAULT 1, `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; CREATE TABLE IF NOT EXISTS `login_attempts` ( `id` int UNSIGNED AUTO_INCREMENT PRIMARY KEY, `ip_address` varchar(45) NOT NULL, `login` varchar(50) NOT NULL DEFAULT '', `attempt_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, INDEX `idx_ip` (`ip_address`), INDEX `idx_time` (`attempt_time`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; CREATE TABLE IF NOT EXISTS `audit_log` ( `id` bigint UNSIGNED AUTO_INCREMENT PRIMARY KEY, `user_id` int UNSIGNED DEFAULT NULL, `action` varchar(255) NOT NULL, `details` text DEFAULT NULL, `ip_address` varchar(45) DEFAULT '', `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, INDEX `idx_user` (`user_id`), INDEX `idx_action` (`action`), INDEX `idx_created` (`created_at`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; CREATE TABLE IF NOT EXISTS `objects` ( `id` int UNSIGNED AUTO_INCREMENT PRIMARY KEY, `name` varchar(255) NOT NULL, `address` varchar(500) DEFAULT '', `object_type` varchar(100) DEFAULT '', `area_sqm` decimal(10,2) DEFAULT 0, `employees_count` int DEFAULT 0, `contact_person` varchar(255) DEFAULT '', `contact_phone` varchar(50) DEFAULT '', `status` enum('active','inactive','audit','prospective') NOT NULL DEFAULT 'active', `notes` text DEFAULT NULL, `risk_score` decimal(5,2) DEFAULT 0, `complexity_index` decimal(5,2) DEFAULT 0, `infrastructure_load` decimal(5,2) DEFAULT 0, `service_history` decimal(5,2) DEFAULT 0, `object_index` decimal(5,2) DEFAULT 0, `sla_price_monthly` decimal(12,2) DEFAULT 0, `region_factor` decimal(3,2) DEFAULT 1.00, `created_by` int UNSIGNED DEFAULT NULL, `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; CREATE TABLE IF NOT EXISTS `object_assignments` ( `id` int UNSIGNED AUTO_INCREMENT PRIMARY KEY, `object_id` int UNSIGNED NOT NULL, `user_id` int UNSIGNED NOT NULL, `role` enum('engineer','technician') NOT NULL, `assigned_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, `unassigned_at` datetime DEFAULT NULL, INDEX `idx_object` (`object_id`), INDEX `idx_user` (`user_id`), UNIQUE KEY `uq_active` (`object_id`,`user_id`,`unassigned_at`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; CREATE TABLE IF NOT EXISTS `tasks` ( `id` int UNSIGNED AUTO_INCREMENT PRIMARY KEY, `object_id` int UNSIGNED NOT NULL, `assigned_to` int UNSIGNED DEFAULT NULL, `created_by` int UNSIGNED DEFAULT NULL, `title` varchar(500) NOT NULL, `description` text DEFAULT NULL, `priority` enum('P1','P2','P3','P4') NOT NULL DEFAULT 'P3', `status` enum('open','in_progress','completed','cancelled') NOT NULL DEFAULT 'open', `deadline` datetime DEFAULT NULL, `sla_remaining_hours` decimal(6,1) DEFAULT 0, `response_time_minutes` int DEFAULT 0, `resolution_time_minutes` int DEFAULT 0, `sla_compliant` tinyint(1) DEFAULT NULL, `checklist_data` text DEFAULT NULL, `result_notes` text DEFAULT NULL, `closed_at` datetime DEFAULT NULL, `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, INDEX `idx_object` (`object_id`), INDEX `idx_assigned` (`assigned_to`), INDEX `idx_status` (`status`), INDEX `idx_priority` (`priority`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; CREATE TABLE IF NOT EXISTS `task_comments` ( `id` int UNSIGNED AUTO_INCREMENT PRIMARY KEY, `task_id` int UNSIGNED NOT NULL, `user_id` int UNSIGNED DEFAULT NULL, `comment` text NOT NULL, `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, INDEX `idx_task` (`task_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; CREATE TABLE IF NOT EXISTS `task_photos` ( `id` int UNSIGNED AUTO_INCREMENT PRIMARY KEY, `task_id` int UNSIGNED DEFAULT NULL, `report_id` int UNSIGNED DEFAULT NULL, `file_path` varchar(500) NOT NULL, `description` varchar(500) DEFAULT '', `type` enum('before','after','evidence','other') DEFAULT 'other', `uploaded_by` int UNSIGNED DEFAULT NULL, `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, INDEX `idx_task` (`task_id`), INDEX `idx_report` (`report_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; CREATE TABLE IF NOT EXISTS `reports` ( `id` int UNSIGNED AUTO_INCREMENT PRIMARY KEY, `object_id` int UNSIGNED NOT NULL, `created_by` int UNSIGNED DEFAULT NULL, `report_type` enum('inspection','service','emergency','audit','monthly') NOT NULL DEFAULT 'service', `title` varchar(500) DEFAULT '', `description` text DEFAULT NULL, `findings` text DEFAULT NULL, `recommendations` text DEFAULT NULL, `work_done` text DEFAULT NULL, `cause_classification` varchar(100) DEFAULT NULL, `result_status` enum('fixed','partial','revisit','ok') DEFAULT 'ok', `status` enum('draft','final','cancelled') NOT NULL DEFAULT 'draft', `client_confirmed` tinyint(1) DEFAULT 0, `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, INDEX `idx_object` (`object_id`), INDEX `idx_author` (`created_by`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; CREATE TABLE IF NOT EXISTS `questionnaire_sessions` ( `id` int UNSIGNED AUTO_INCREMENT PRIMARY KEY, `object_id` int UNSIGNED DEFAULT NULL, `client_name` varchar(255) DEFAULT '', `created_by` int UNSIGNED DEFAULT NULL, `status` enum('draft','completed','cancelled') NOT NULL DEFAULT 'draft', `current_step` tinyint UNSIGNED NOT NULL DEFAULT 1, `risk_score` decimal(5,2) DEFAULT 0, `complexity_index` decimal(5,2) DEFAULT 0, `infrastructure_load` decimal(5,2) DEFAULT 0, `service_history` decimal(5,2) DEFAULT 0, `object_index` decimal(5,2) DEFAULT 0, `sla_price_monthly` decimal(12,2) DEFAULT 0, `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, INDEX `idx_object` (`object_id`), INDEX `idx_author` (`created_by`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; CREATE TABLE IF NOT EXISTS `questionnaire_answers` ( `id` int UNSIGNED AUTO_INCREMENT PRIMARY KEY, `session_id` int UNSIGNED NOT NULL, `step` tinyint UNSIGNED NOT NULL, `question_key` varchar(100) NOT NULL, `answer_value` text DEFAULT NULL, `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, INDEX `idx_session` (`session_id`), INDEX `idx_step` (`step`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; CREATE TABLE IF NOT EXISTS `object_passports` ( `id` int UNSIGNED AUTO_INCREMENT PRIMARY KEY, `session_id` int UNSIGNED DEFAULT NULL, `object_id` int UNSIGNED DEFAULT NULL, `object_index` decimal(5,2) DEFAULT 0, `risk_score` decimal(5,2) DEFAULT 0, `complexity_index` decimal(5,2) DEFAULT 0, `sla_price_monthly` decimal(12,2) DEFAULT 0, `passport_data` json DEFAULT NULL, `created_by` int UNSIGNED DEFAULT NULL, `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, INDEX `idx_object` (`object_id`), INDEX `idx_session` (`session_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; CREATE TABLE IF NOT EXISTS `sla_contracts` ( `id` int UNSIGNED AUTO_INCREMENT PRIMARY KEY, `object_id` int UNSIGNED NOT NULL, `client_name` varchar(255) DEFAULT '', `start_date` date NOT NULL, `end_date` date DEFAULT NULL, `sla_price_monthly` decimal(12,2) NOT NULL DEFAULT 0, `penalty_rate` decimal(5,2) DEFAULT 0, `response_time_p1` int DEFAULT 4, `response_time_p2` int DEFAULT 8, `response_time_p3` int DEFAULT 24, `service_level` enum('start','business','enterprise') NOT NULL DEFAULT 'business', `status` enum('active','expired','cancelled','negotiation') NOT NULL DEFAULT 'negotiation', `created_by` int UNSIGNED DEFAULT NULL, `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, INDEX `idx_object` (`object_id`), INDEX `idx_status` (`status`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; CREATE TABLE IF NOT EXISTS `incidents` ( `id` int UNSIGNED AUTO_INCREMENT PRIMARY KEY, `object_id` int UNSIGNED NOT NULL, `reported_by` int UNSIGNED DEFAULT NULL, `assigned_to` int UNSIGNED DEFAULT NULL, `title` varchar(500) NOT NULL, `description` text DEFAULT NULL, `severity` enum('P1','P2','P3') NOT NULL DEFAULT 'P3', `status` enum('open','in_progress','resolved','closed') NOT NULL DEFAULT 'open', `resolution` text DEFAULT NULL, `cause` varchar(500) DEFAULT '', `resolution_time_minutes` int DEFAULT 0, `sla_breached` tinyint(1) DEFAULT 0, `resolved_at` datetime DEFAULT NULL, `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, INDEX `idx_object` (`object_id`), INDEX `idx_severity` (`severity`), INDEX `idx_status` (`status`), INDEX `idx_assigned` (`assigned_to`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; CREATE TABLE IF NOT EXISTS `engineer_kpi` ( `id` int UNSIGNED AUTO_INCREMENT PRIMARY KEY, `engineer_id` int UNSIGNED NOT NULL, `period_start` date NOT NULL, `period_end` date NOT NULL, `sla_compliance` decimal(5,2) DEFAULT 0, `response_time_score` decimal(5,2) DEFAULT 0, `resolution_time_score` decimal(5,2) DEFAULT 0, `diagnosis_accuracy` decimal(5,2) DEFAULT 0, `reopen_rate` decimal(5,2) DEFAULT 0, `risk_coverage_score` decimal(5,2) DEFAULT 0, `documentation_quality` decimal(5,2) DEFAULT 0, `engineer_score` decimal(5,2) DEFAULT 0, `grade` varchar(20) DEFAULT '', `components_json` json DEFAULT NULL, `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, INDEX `idx_engineer` (`engineer_id`), INDEX `idx_period` (`period_start`,`period_end`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; CREATE TABLE IF NOT EXISTS `shs_records` ( `id` int UNSIGNED AUTO_INCREMENT PRIMARY KEY, `recorded_by` int UNSIGNED DEFAULT NULL, `period_start` date NOT NULL, `period_end` date NOT NULL, `sla_stability` decimal(5,2) DEFAULT 0, `revenue_stability` decimal(5,2) DEFAULT 0, `retention` decimal(5,2) DEFAULT 0, `engineer_performance` decimal(5,2) DEFAULT 0, `incident_stability` decimal(5,2) DEFAULT 0, `sales_flow` decimal(5,2) DEFAULT 0, `operational_efficiency` decimal(5,2) DEFAULT 0, `shs_score` decimal(5,2) DEFAULT 0, `shs_status` varchar(20) DEFAULT '', `components_json` json DEFAULT NULL, `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, INDEX `idx_period` (`period_start`,`period_end`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; CREATE TABLE IF NOT EXISTS `blog_posts` ( `id` int UNSIGNED AUTO_INCREMENT PRIMARY KEY, `title` varchar(500) NOT NULL, `slug` varchar(500) NOT NULL UNIQUE, `content` longtext NOT NULL, `excerpt` varchar(1000) DEFAULT '', `category` enum('risk-engineering','sla-service','incident-cases','infrastructure-deep-dive','compliance-mchs','economics-security','case-studies') NOT NULL DEFAULT 'risk-engineering', `author_id` int UNSIGNED DEFAULT NULL, `status` enum('draft','published','archived') NOT NULL DEFAULT 'draft', `published_at` datetime DEFAULT NULL, `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, INDEX `idx_slug` (`slug`), INDEX `idx_category` (`category`), INDEX `idx_status` (`status`), INDEX `idx_published` (`published_at`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -- Seed: default owner (login: owner, password: AegisOne2024!) INSERT INTO `users` (`login`, `password_hash`, `role`, `full_name`, `is_active`) VALUES ('owner', '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', 'owner', 'System Owner', 1) ON DUPLICATE KEY UPDATE `id`=`id`; -- ===================================================================== -- formula_coefficients — редактируемые коэффициенты формул -- ===================================================================== CREATE TABLE IF NOT EXISTS `formula_coefficients` ( `id` int UNSIGNED AUTO_INCREMENT PRIMARY KEY, `key` varchar(100) NOT NULL UNIQUE, `value` decimal(10,4) NOT NULL DEFAULT 0, `description` varchar(500) DEFAULT '', `formula_ref` varchar(255) DEFAULT '', `is_active` tinyint(1) NOT NULL DEFAULT 1, `updated_by` int UNSIGNED DEFAULT NULL, `updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, INDEX `idx_key` (`key`), INDEX `idx_active` (`is_active`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -- Seed: коэффициенты формул (значения по умолчанию из functions.php) INSERT INTO `formula_coefficients` (`key`, `value`, `description`, `formula_ref`) VALUES -- Risk Score ('risk_score.no_archive', 25, 'Нет архива видеонаблюдения', 'calc_risk_score()'), ('risk_score.no_power_backup', 20, 'Нет резервного питания', 'calc_risk_score()'), ('risk_score.no_regulations', 15, 'Нет регламента обслуживания', 'calc_risk_score()'), ('risk_score.system_failures', 20, 'Частые сбои систем', 'calc_risk_score()'), ('risk_score.no_documentation', 10, 'Нет документации', 'calc_risk_score()'), ('risk_score.bound_low', 20, 'Граница низкого риска', 'risk_label()'), ('risk_score.bound_medium', 50, 'Граница среднего риска', 'risk_label()'), ('risk_score.bound_high', 75, 'Граница высокого риска', 'risk_label()'), -- Risk Multiplier ('risk_multiplier.low', 1.0, 'Множитель низкого риска (0-20)', 'risk_multiplier()'), ('risk_multiplier.medium', 1.3, 'Множитель среднего риска (21-50)', 'risk_multiplier()'), ('risk_multiplier.high', 1.6, 'Множитель высокого риска (51-75)', 'risk_multiplier()'), ('risk_multiplier.critical', 2.0, 'Множитель критического риска (76-100)', 'risk_multiplier()'), -- Complexity ('complexity.video_0_20', 10, 'Видеонаблюдение до 20 камер', 'calc_complexity()'), ('complexity.video_20_100', 20, 'Видеонаблюдение 20-100 камер', 'calc_complexity()'), ('complexity.video_100plus', 35, 'Видеонаблюдение 100+ камер', 'calc_complexity()'), ('complexity.access_0_5', 10, 'СКУД до 5 точек', 'calc_complexity()'), ('complexity.access_5_20', 20, 'СКУД 5-20 точек', 'calc_complexity()'), ('complexity.access_20plus', 30, 'СКУД 20+ точек', 'calc_complexity()'), ('complexity.fire_simple', 15, 'Пожарная сигнализация простая', 'calc_complexity()'), ('complexity.fire_medium', 25, 'Пожарная сигнализация средняя', 'calc_complexity()'), ('complexity.fire_complex', 40, 'Пожарная сигнализация сложная (>5000 м²)', 'calc_complexity()'), ('complexity.it', 10, 'IT-инфраструктура', 'calc_complexity()'), -- Infrastructure Load ('infra.server_none', 15, 'Нет сервера', 'calc_infrastructure_load()'), ('infra.server_weak', 10, 'Слабый сервер', 'calc_infrastructure_load()'), ('infra.network_unstable', 20, 'Нестабильная сеть', 'calc_infrastructure_load()'), ('infra.network_partial', 10, 'Частичная сеть', 'calc_infrastructure_load()'), ('infra.power_none', 20, 'Нет UPS', 'calc_infrastructure_load()'), ('infra.power_weak', 10, 'Слабый UPS', 'calc_infrastructure_load()'), -- Service History ('history.none', 30, 'Нет обслуживания', 'calc_service_history()'), ('history.irregular', 20, 'Нерегулярное обслуживание', 'calc_service_history()'), ('history.formal', 10, 'Формальный подрядчик', 'calc_service_history()'), ('history.sla', 0, 'Есть SLA', 'calc_service_history()'), -- Object Index ('object_index.risk_weight', 0.4, 'Вес Risk Score', 'calc_object_index()'), ('object_index.complexity_weight', 0.3, 'Вес Complexity', 'calc_object_index()'), ('object_index.infra_weight', 0.2, 'Вес Infra Load', 'calc_object_index()'), ('object_index.history_weight', 0.1, 'Вес Service History', 'calc_object_index()'), -- SLA Price ('sla_price.base_cost', 15000, 'Базовая стоимость инженера', 'calc_sla_price()'), ('sla_price.region_default', 1.0, 'Региональный коэффициент по умолчанию', 'calc_sla_price()'), -- Engineer Score ('engineer.score.sla_weight', 0.25, 'Вес SLA Compliance', 'calc_engineer_score()'), ('engineer.score.response_weight', 0.20, 'Вес Response Time', 'calc_engineer_score()'), ('engineer.score.resolution_weight', 0.20, 'Вес Resolution Time', 'calc_engineer_score()'), ('engineer.score.diagnosis_weight', 0.15, 'Вес Diagnosis Accuracy', 'calc_engineer_score()'), ('engineer.score.reopen_weight', 0.10, 'Вес Reopen Rate', 'calc_engineer_score()'), ('engineer.score.risk_coverage_weight', 0.10, 'Вес Risk Coverage', 'calc_engineer_score()'), ('engineer.grade.senior', 90, 'Граница Senior', 'engineer_grade()'), ('engineer.grade.strong', 80, 'Граница Strong', 'engineer_grade()'), ('engineer.grade.middle', 70, 'Граница Middle', 'engineer_grade()'), -- ECS (Engineer Control Score) ('ecs.sla_weight', 0.30, 'Вес SLA Control', 'calc_engineer_control_score()'), ('ecs.task_dist_weight', 0.25, 'Вес Task Distribution', 'calc_engineer_control_score()'), ('ecs.incident_red_weight', 0.20, 'Вес Incident Reduction', 'calc_engineer_control_score()'), ('ecs.team_perf_weight', 0.15, 'Вес Team Performance', 'calc_engineer_control_score()'), ('ecs.response_coord_weight', 0.10, 'Вес Response Coordination', 'calc_engineer_control_score()'), -- SHS (System Health Score) ('shs.sla_stability_weight', 0.22, 'Вес SLA Stability', 'calc_shs()'), ('shs.revenue_stability_weight', 0.18, 'Вес Revenue Stability', 'calc_shs()'), ('shs.retention_weight', 0.18, 'Вес Retention', 'calc_shs()'), ('shs.engineer_perf_weight', 0.15, 'Вес Engineer Performance', 'calc_shs()'), ('shs.incident_stability_weight', 0.12, 'Вес Incident Stability', 'calc_shs()'), ('shs.sales_flow_weight', 0.10, 'Вес Sales Flow', 'calc_shs()'), ('shs.operational_eff_weight', 0.05, 'Вес Operational Efficiency', 'calc_shs()'), ('shs.zone_growth', 85, 'Граница зоны Growth', 'shs_status(), shs_zone()'), ('shs.zone_stable', 70, 'Граница зоны Stable', 'shs_status(), shs_zone()'), ('shs.zone_risk', 50, 'Граница зоны Risk', 'shs_status(), shs_zone()'), ('shs.delta_warning', 5, 'Порог предупреждения ΔSHS', 'shs_delta()'), ('shs.delta_critical', 10, 'Порог критического ΔSHS', 'shs_delta()'), -- CEO SHS ('ceo_shs.mrr_weight', 0.25, 'Вес MRR Growth', 'calc_ceo_shs()'), ('ceo_shs.sla_weight', 0.20, 'Вес SLA Compliance', 'calc_ceo_shs()'), ('ceo_shs.retention_weight', 0.20, 'Вес Retention', 'calc_ceo_shs()'), ('ceo_shs.productivity_weight', 0.15, 'Вес Productivity', 'calc_ceo_shs()'), ('ceo_shs.conversion_weight', 0.10, 'Вес Conversion', 'calc_ceo_shs()'), ('ceo_shs.incident_weight', 0.10, 'Вес Incident Stability', 'calc_ceo_shs()'), -- SSI (SLA Stability Index) ('ssi.breach_severity_p1', 1.0, 'Severity P1', 'calc_breach_severity()'), ('ssi.breach_severity_p2', 0.5, 'Severity P2', 'calc_breach_severity()'), ('ssi.breach_severity_p3', 0.2, 'Severity P3', 'calc_breach_severity()'), -- ISI (Incident Stability Index) ('isi.severity_p1', 1.0, 'Severity P1', 'calc_incident_stability_index()'), ('isi.severity_p2', 0.5, 'Severity P2', 'calc_incident_stability_index()'), ('isi.severity_p3', 0.2, 'Severity P3', 'calc_incident_stability_index()'), -- Automation Rules ('rules.shs_threshold', 70, 'Порог SHS', 'check_automation_rules()'), ('rules.sla_threshold', 90, 'Порог SLA Compliance', 'check_automation_rules()'), ('rules.retention_threshold', 90, 'Порог Retention', 'check_automation_rules()'), -- Bonus ('bonus.score_90plus', 90, 'Граница премии 90+', 'calc_bonus_percent()'), ('bonus.score_80_89', 80, 'Граница премии 80-89', 'calc_bonus_percent()'), ('bonus.premium_90plus', 20, 'Премия при Score >= 90 (%)', 'calc_bonus_percent()'), ('bonus.premium_80_89', 10, 'Премия при Score 80-89 (%)', 'calc_bonus_percent()'), ('bonus.premium_below_80', 0, 'Премия при Score < 80 (%)', 'calc_bonus_percent()'), -- Retention ('retention.key_client_penalty', 0.1, 'Штраф за потерю ключевого клиента', 'calc_retention_key_client()') ON DUPLICATE KEY UPDATE `id`=`id`; -- ===================================================================== -- cases — примеры из практики (карусель на главной) -- ===================================================================== CREATE TABLE IF NOT EXISTS `cases` ( `id` int UNSIGNED AUTO_INCREMENT PRIMARY KEY, `title` varchar(500) NOT NULL, `text` text NOT NULL, `effect` text NOT NULL, `sort_order` int UNSIGNED NOT NULL DEFAULT 0, `is_active` tinyint(1) NOT NULL DEFAULT 1, `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, INDEX `idx_sort` (`sort_order`), INDEX `idx_active` (`is_active`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; INSERT INTO `cases` (`title`, `text`, `effect`, `sort_order`) VALUES ('Склад крупной торговой сети', 'Выявлено: слепые зоны в зонах разгрузки, недостаточное разрешение камер в зонах погрузки/разгрузки. Одна камера не исправна, у двух не настроена запись.', 'предотвращение убытков на сумму более 5 млн рублей в год.', 1), ('Производство пищевых продуктов', 'Неправильная настройка СКУД позволяла несанкционированный доступ в производственные помещения, создавая риск нарушения норм СанПин.', 'снижение риска порчи продукции и утечки конфиденциальной информации.', 2), ('Банковский офис', 'Недостатки в системе ОПС приводили к невозможности срабатывания или задержкам в реагировании при ЧП.', 'сокращение рисков утраты имущества и ценностей, повышение уровня безопасности.', 3), ('Торгово-развлекательный центр', 'Метод «Тайный покупатель» выявил: охрана не реагирует на срабатывание металлодетекторов, оставляет посты без присмотра. Камеры на парковке не охватывают часть машиномест.', 'снижение риска краж, повышение дисциплины службы охраны.', 4), ('Гостиница', 'СКУД не синхронизирована с системой бронирования — доступ в занятые номера. ОПС в части номеров отключена. Видеокамеры имеют мёртвые зоны.', 'устранение репутационных рисков и риска хищения личных вещей гостей.', 5), ('Логистический центр', 'Отсутствие видеоконтроля на участках приёмки и отгрузки приводило к систематическим хищениям. СКУД на въезде не фиксирует данные транспортных средств.', 'сокращение потерь товара на 15%.', 6) ON DUPLICATE KEY UPDATE `id`=`id`;