Files
angel 72b6879f4b v1.7.0: refactor max_bot to flat structure, add VCF+UserModel+NLP history context, portal pages and proxy fixes
- Refactored max_bot from nested packages to flat module structure
- Q2: Extended BotUser model (patronymic, email, org, address, vcf_raw, contact_hash, phone_verified, email_verified, last_interaction, total_conversations, total_tickets)
- Q2: VCF parser (FN, N, TEL, EMAIL, ORG, ADR), upsert on re-contact, NLP history context (_get_user_history_context -> YandexGPT)
- Q1: Broadcast preview modal with 10s confirmation timer
- Q3: CSS var(--white)->var(--bg-card), var(--text)->var(--text-primary)
- Q4: bot_settings showNotification(), editable max_bot_id
- Q5: Webhook secret passthrough via X-Max-Bot-Api-Secret
- Masking sensitive keys, dialog_cleared handler, migrate via _add_column_if_not_exists()
- Rate limit (asyncio.sleep 0.5 per 10), dead code removed, conv.intent context in contact.py
- Portal pages: bot_consent, bot_kb (edit), bot_settings, bot_test, bot_tickets, portal_settings
- Tests: 21/21 passing, added test_yandex_gpt.py, test_email_sender.py
- Deploy: deploy_full.sh, schema.sql, seed_knowledge_base.sql
2026-05-29 02:30:30 +03:00

202 lines
20 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
/**
* AegisOne Engineering — Главная страница
*
* Стек: config → seo → form-handler → header → контент → contact-form → footer
*/
require_once __DIR__ . '/config.php';
require_once __DIR__ . '/seo.php';
require_once __DIR__ . '/data/db-config.php';
$pageKey = 'main';
$canonical = '/';
$btnText = 'Заказать консультацию';
$contactTitle = 'Свяжитесь с нами';
require_once __DIR__ . '/inc/form-handler.php';
require __DIR__ . '/inc/header.php';
?>
<section class="hero" id="hero">
<div class="container">
<h1 class="hero__title"><?= $SEO[$pageKey]['h1'] ?></h1>
<p class="hero__subtitle">Аудит, сервисное обслуживание и технический надзор систем безопасности.<br>Снижаем риски, обеспечиваем стабильность, подтверждаем соответствие нормативам.</p>
<a href="#contacts" class="btn">Заказать консультацию</a>
<p class="hero__footnote">Работаем по всей России — с выездом нашего специалиста на ваш объект</p>
</div>
</section>
<section class="problems" id="problems">
<div class="container">
<h2 class="section-title">Проблемы, которые мы решаем</h2>
<div class="problems__grid">
<?php
$problems = [
['svg' => '<circle cx="32" cy="32" r="24" fill="none" stroke="#00ADEF" stroke-width="3"/><line x1="32" y1="22" x2="32" y2="36" stroke="#00ADEF" stroke-width="3"/><circle cx="32" cy="42" r="2" fill="#00ADEF"/>',
'title' => 'Системы не работают как надо',
'desc' => 'Камеры не охватывают ключевые зоны, СКУД имеет уязвимости, а ОПС может не сработать в критический момент. Вы платите за безопасность, но не получаете её.'],
['svg' => '<rect x="12" y="16" width="40" height="32" rx="4" fill="none" stroke="#00ADEF" stroke-width="3"/><line x1="22" y1="12" x2="22" y2="20" stroke="#00ADEF" stroke-width="3"/><line x1="42" y1="12" x2="42" y2="20" stroke="#00ADEF" stroke-width="3"/>',
'title' => 'Нет единого стандарта',
'desc' => 'Разрозненные системы от разных подрядчиков, отсутствие регламентов и непрозрачность работы службы безопасности — хаус, который несёт скрытые риски.'],
['svg' => '<path d="M32 8 L56 48 L8 48 Z" fill="none" stroke="#00ADEF" stroke-width="3"/><circle cx="32" cy="28" r="4" fill="none" stroke="#00ADEF" stroke-width="3"/><line x1="32" y1="32" x2="32" y2="40" stroke="#00ADEF" stroke-width="3"/>',
'title' => 'Риски штрафов и санкций',
'desc' => 'Надзорные органы ужесточают требования. Несоответствие нормативам грозит штрафами, приостановкой деятельности и репутационными потерями.'],
['svg' => '<circle cx="32" cy="32" r="24" fill="none" stroke="#00ADEF" stroke-width="3"/><polyline points="20,34 28,42 44,24" fill="none" stroke="#00ADEF" stroke-width="3"/>',
'title' => 'Штатная служба не видит проблем',
'desc' => '«Замыленный глаз» собственной охраны пропускает системные нарушения. Метод «Тайный покупатель» вскрывает то, что скрыто от внутреннего контроля.'],
['svg' => '<path d="M16 48 L32 16 L48 48 Z" fill="none" stroke="#00ADEF" stroke-width="3"/><line x1="32" y1="28" x2="32" y2="38" stroke="#00ADEF" stroke-width="3"/><circle cx="32" cy="44" r="2" fill="#00ADEF"/>',
'title' => 'Реагирование постфактум',
'desc' => 'Инциденты происходят, а реагирование запаздывает. Нет системы раннего обнаружения и чёткого плана действий при нарушении безопасности.'],
['svg' => '<rect x="12" y="12" width="40" height="40" rx="4" fill="none" stroke="#00ADEF" stroke-width="3"/><line x1="32" y1="12" x2="32" y2="52" stroke="#00ADEF" stroke-width="3"/><line x1="12" y1="32" x2="52" y2="32" stroke="#00ADEF" stroke-width="3"/>',
'title' => 'Документация не в порядке',
'desc' => 'Проектная и исполнительная документация отсутствует или не соответствует реальности. Это блокирует проверки и создаёт риски при страховых случаях.'],
];
foreach ($problems as $p): ?>
<div class="problem-card">
<div class="problem-card__icon"><svg viewBox="0 0 64 64"><?= $p['svg'] ?></svg></div>
<h3><?= $p['title'] ?></h3>
<p><?= $p['desc'] ?></p>
</div>
<?php endforeach; ?>
</div>
</div>
</section>
<section class="services" id="services">
<div class="container">
<h2 class="section-title">Наши услуги</h2>
<div class="services__grid">
<a href="/audit/" class="card service-card">
<svg class="card__icon" viewBox="0 0 64 64"><circle cx="32" cy="32" r="24" fill="none" stroke="#00ADEF" stroke-width="3"/><polygon points="40,20 28,32 40,44" fill="none" stroke="#00ADEF" stroke-width="3"/></svg>
<h3>Независимый аудит безопасности</h3>
<p>Объективная оценка состояния систем видеонаблюдения, СКУД и ОПС. Выявление уязвимостей и скрытых рисков с детальным отчётом.</p>
<span class="service-card__more">Подробнее →</span>
</a>
<a href="/sla/" class="card service-card">
<svg class="card__icon" viewBox="0 0 64 64"><path d="M32 8 L56 24 L56 40 L32 56 L8 40 L8 24 Z" fill="none" stroke="#00ADEF" stroke-width="3"/><circle cx="32" cy="32" r="8" fill="none" stroke="#00ADEF" stroke-width="3"/></svg>
<h3>Сервисное обслуживание (SLA)</h3>
<p>Регулярное техническое обслуживание с гарантированным уровнем сервиса. KPI, время реакции, профилактика отказов.</p>
<span class="service-card__more">Подробнее →</span>
</a>
<a href="/incident/" class="card service-card">
<svg class="card__icon" viewBox="0 0 64 64"><circle cx="32" cy="32" r="24" fill="none" stroke="#00ADEF" stroke-width="3"/><line x1="32" y1="18" x2="32" y2="36" stroke="#00ADEF" stroke-width="3"/><circle cx="32" cy="42" r="2" fill="#00ADEF"/></svg>
<h3>Реагирование на инциденты</h3>
<p>Круглосуточный мониторинг, оперативное реагирование на инциденты, расследование и устранение последствий.</p>
<span class="service-card__more">Подробнее →</span>
</a>
<a href="/supervision/" class="card service-card">
<svg class="card__icon" viewBox="0 0 64 64"><rect x="12" y="16" width="40" height="32" rx="4" fill="none" stroke="#00ADEF" stroke-width="3"/><polygon points="22,32 30,40 44,24" fill="none" stroke="#00ADEF" stroke-width="3"/></svg>
<h3>Технический надзор</h3>
<p>Контроль качества монтажа и пусконаладки систем безопасности. Соответствие проекту, нормативам и срокам.</p>
<span class="service-card__more">Подробнее →</span>
</a>
<a href="/documentation/" class="card service-card">
<svg class="card__icon" viewBox="0 0 64 64"><rect x="16" y="8" width="32" height="48" rx="4" fill="none" stroke="#00ADEF" stroke-width="3"/><line x1="22" y1="20" x2="42" y2="20" stroke="#00ADEF" stroke-width="3"/><line x1="22" y1="30" x2="42" y2="30" stroke="#00ADEF" stroke-width="3"/><line x1="22" y1="40" x2="34" y2="40" stroke="#00ADEF" stroke-width="3"/></svg>
<h3>Документация и соответствие нормативам</h3>
<p>Разработка проектной документации, аудит соответствия нормативам, помощь в прохождении проверок.</p>
<span class="service-card__more">Подробнее →</span>
</a>
<a href="/risk/" class="card service-card">
<svg class="card__icon" viewBox="0 0 64 64"><polygon points="32,8 48,28 44,52 20,52 16,28" fill="none" stroke="#00ADEF" stroke-width="3"/><circle cx="32" cy="30" r="6" fill="none" stroke="#00ADEF" stroke-width="3"/><line x1="32" y1="36" x2="32" y2="46" stroke="#00ADEF" stroke-width="3"/></svg>
<h3>Риск-инжиниринг</h3>
<p>Оценка и управление рисками безопасности, планирование непрерывности бизнеса, разработка стратегии защиты.</p>
<span class="service-card__more">Подробнее →</span>
</a>
</div>
</div>
</section>
<section class="industries" id="industries">
<div class="container">
<h2 class="section-title">Отрасли, в которых мы работаем</h2>
<div class="industries__grid">
<?php
$industries = [
['svg' => '<rect x="12" y="20" width="40" height="36" rx="4" fill="none" stroke="#00ADEF" stroke-width="3"/><line x1="32" y1="20" x2="32" y2="8" stroke="#00ADEF" stroke-width="3"/><rect x="24" y="36" width="16" height="12" rx="2" fill="none" stroke="#00ADEF" stroke-width="3"/>', 'title' => 'Торговые центры и ритейл'],
['svg' => '<rect x="8" y="20" width="48" height="32" rx="4" fill="none" stroke="#00ADEF" stroke-width="3"/><rect x="20" y="28" width="24" height="16" rx="2" fill="none" stroke="#00ADEF" stroke-width="3"/><line x1="8" y1="36" x2="20" y2="36" stroke="#00ADEF" stroke-width="3"/><line x1="44" y1="36" x2="56" y2="36" stroke="#00ADEF" stroke-width="3"/>', 'title' => 'Складские комплексы и логистика'],
['svg' => '<rect x="10" y="16" width="44" height="36" rx="4" fill="none" stroke="#00ADEF" stroke-width="3"/><circle cx="32" cy="34" r="8" fill="none" stroke="#00ADEF" stroke-width="3"/><line x1="32" y1="14" x2="32" y2="26" stroke="#00ADEF" stroke-width="3"/><line x1="32" y1="42" x2="32" y2="52" stroke="#00ADEF" stroke-width="3"/>', 'title' => 'Производственные предприятия'],
['svg' => '<rect x="14" y="16" width="36" height="36" rx="4" fill="none" stroke="#00ADEF" stroke-width="3"/><rect x="22" y="24" width="20" height="8" rx="2" fill="none" stroke="#00ADEF" stroke-width="3"/><line x1="32" y1="16" x2="32" y2="8" stroke="#00ADEF" stroke-width="3"/>', 'title' => 'Бизнес-центры и офисы'],
['svg' => '<rect x="12" y="20" width="40" height="32" rx="4" fill="none" stroke="#00ADEF" stroke-width="3"/><rect x="20" y="28" width="24" height="12" rx="2" fill="none" stroke="#00ADEF" stroke-width="3"/><circle cx="20" cy="44" r="4" fill="none" stroke="#00ADEF" stroke-width="3"/><circle cx="44" cy="44" r="4" fill="none" stroke="#00ADEF" stroke-width="3"/>', 'title' => 'Гостиницы и рестораны'],
['svg' => '<rect x="12" y="12" width="40" height="40" rx="8" fill="none" stroke="#00ADEF" stroke-width="3"/><circle cx="32" cy="24" r="6" fill="none" stroke="#00ADEF" stroke-width="3"/><path d="M22 48 Q32 38 42 48" fill="none" stroke="#00ADEF" stroke-width="3"/>', 'title' => 'Финансовые организации'],
];
foreach ($industries as $ind): ?>
<div class="industry-card">
<svg viewBox="0 0 64 64"><?= $ind['svg'] ?></svg>
<h3><?= $ind['title'] ?></h3>
</div>
<?php endforeach; ?>
</div>
</div>
</section>
<section class="about" id="about">
<div class="container">
<h2 class="section-title">О компании</h2>
<div class="about-card">
<p>Более 20 лет помогаем бизнесу <strong>Краснодара, Краснодарского края и Южного федерального округа</strong> обеспечивать реальную безопасность объектов. Мы предоставляем независимые аудиты, сервисное обслуживание и технический надзор для предприятий любого масштаба.</p>
<p><strong>Наша миссия</strong> — давать руководителям объективную картину состояния их систем безопасности, выявляя скрытые угрозы и экономя ресурсы. Мы не продаём оборудование — мы продаём спокойствие и стабильность.</p>
<p>Мы работаем на стыке инженерии и управления рисками: от аудита и SLA до реагирования на инциденты и риск-инжиниринга. Каждый наш проект начинается с диагностики и заканчивается измеримым результатом — снижением рисков, повышением надёжности и соответствием нормативам.</p>
<p>Для объективной оценки реального уровня безопасности мы используем метод <strong>«Тайный покупатель»</strong> — это позволяет выявить несоответствие между формальными инструкциями и фактическими действиями персонала.</p>
</div>
</div>
</section>
<section class="cases" id="cases">
<div class="container">
<h2 class="section-title">Примеры из практики</h2>
</div>
<div class="carousel" id="cases-carousel">
<div class="carousel__track">
<?php
try {
if (DB_TYPE === 'pgsql') {
$dsn_cases = 'pgsql:host=' . DB_HOST . ';port=' . DB_PORT . ';dbname=' . DB_NAME;
} else {
$dsn_cases = 'mysql:host=' . DB_HOST . ';port=' . DB_PORT . ';dbname=' . DB_NAME . ';charset=' . DB_CHARSET;
}
$pdo_cases = new PDO($dsn_cases, DB_USER, DB_PASS, [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC]);
$stmt_cases = $pdo_cases->query("SELECT title, text, effect FROM cases WHERE is_active ORDER BY sort_order ASC, id ASC");
$cases = $stmt_cases->fetchAll();
} catch (\Throwable $e) {
$cases = [];
}
foreach ($cases as $c): ?>
<div class="case">
<h3><?= htmlspecialchars($c['title']) ?></h3>
<p><?= htmlspecialchars($c['text']) ?></p>
<p><strong>Эффект:</strong> <?= htmlspecialchars($c['effect']) ?></p>
</div>
<?php endforeach; ?>
</div>
<button class="carousel__prev"></button>
<button class="carousel__next"></button>
<div class="carousel__counter" id="carousel-counter"></div>
</div>
</div>
</section>
<section class="faq" id="faq">
<div class="container">
<h2 class="section-title">Часто задаваемые вопросы</h2>
<div class="faq__list">
<?php
$faqs = [
['q' => 'С чего начать взаимодействие с вашей компанией?', 'a' => 'Оптимальный путь: бесплатная первичная консультация, на которой мы понимаем ваши задачи и специфику объекта. Далее предлагаем наиболее подходящий формат работы — от разового аудита до комплексного SLA.'],
['q' => 'Вы продаёте оборудование или монтажные работы?', 'a' => 'Мы работаем с системами безопасности «под ключ», но в рамках независимых услуг выступаем исключительно как эксперты. Наша задача — объективно оценить ситуацию и обеспечить работоспособность, а не продать оборудование.'],
['q' => 'Какие гарантии вы даёте?', 'a' => 'Для SLA-контрактов гарантируем время реакции, периодичность ТО и KPI, прописанные в договоре. Для аудита — полноту и объективность отчёта. Все наши специалисты имеют профильное образование и опыт от 10 лет.'],
['q' => 'Сколько стоит аудит?', 'a' => 'Стоимость зависит от объекта: площади, количества систем, удалённости. Называем цену после предварительного обсуждения — это бесплатно и ни к чему не обязывает.'],
['q' => 'Работаете ли вы за пределами Краснодара?', 'a' => 'Да. Основной регион — Краснодарский край и ЮФО. Также реализуем проекты по всей России с выездом специалистов на объект.'],
['q' => 'Как выезд на объект влияет на его работу?', 'a' => 'Мы не останавливаем производственные и бизнес-процессы. Осмотр проводится в рабочее время без вмешательства в работу сотрудников.'],
];
foreach ($faqs as $faq): ?>
<div class="faq-item">
<button class="faq-question"><?= $faq['q'] ?></button>
<div class="faq-answer"><?= $faq['a'] ?></div>
</div>
<?php endforeach; ?>
</div>
</div>
</section>
<?php require __DIR__ . '/inc/contact-form.php'; ?>
<?php require __DIR__ . '/inc/footer.php'; ?>