Initial commit
@@ -0,0 +1,21 @@
|
||||
<IfModule mod_headers.c>
|
||||
Header always set X-Content-Type-Options "nosniff"
|
||||
Header always set X-Frame-Options "SAMEORIGIN"
|
||||
</IfModule>
|
||||
|
||||
<IfModule mod_expires.c>
|
||||
ExpiresActive On
|
||||
ExpiresByType image/png "access plus 1 year"
|
||||
ExpiresByType image/jpeg "access plus 1 year"
|
||||
ExpiresByType image/svg+xml "access plus 1 year"
|
||||
ExpiresByType image/x-icon "access plus 1 year"
|
||||
ExpiresByType text/css "access plus 1 month"
|
||||
ExpiresByType text/javascript "access plus 1 month"
|
||||
ExpiresByType application/javascript "access plus 1 month"
|
||||
</IfModule>
|
||||
|
||||
<IfModule mod_deflate.c>
|
||||
AddOutputFilterByType DEFLATE text/html text/plain text/css text/javascript application/javascript image/svg+xml
|
||||
</IfModule>
|
||||
|
||||
DirectoryIndex index.php
|
||||
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 720 720"><path fill="#fff" d="M350.4,9.6C141.8,20.5,4.1,184.1,12.8,390.4c3.8,90.3,40.1,168,48.7,253.7,2.2,22.2-4.2,49.6,21.4,59.3,31.5,11.9,79.8-8.1,106.2-26.4,9-6.1,17.6-13.2,24.2-22,27.3,18.1,53.2,35.6,85.7,43.4,143.1,34.3,299.9-44.2,369.6-170.3C799.6,291.2,622.5-4.6,350.4,9.6h0ZM269.4,504c-11.3,8.8-22.2,20.8-34.7,27.7-18.1,9.7-23.7-.4-30.5-16.4-21.4-50.9-24-137.6-11.5-190.9,16.8-72.5,72.9-136.3,150-143.1,78-6.9,150.4,32.7,183.1,104.2,72.4,159.1-112.9,316.2-256.4,218.6h0Z"/></svg>
|
||||
|
After Width: | Height: | Size: 541 B |
|
After Width: | Height: | Size: 27 KiB |
|
After Width: | Height: | Size: 74 KiB |
|
After Width: | Height: | Size: 25 KiB |
|
After Width: | Height: | Size: 810 B |
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 128 KiB |
@@ -0,0 +1 @@
|
||||
{"name":"Агисван — независимый аудит безопасности","short_name":"Агисван","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#0A2A4D","background_color":"#ffffff","display":"standalone"}
|
||||
@@ -0,0 +1,481 @@
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
// ===== THEME SWITCHER =====
|
||||
var themeBtn = document.getElementById('theme-btn');
|
||||
var themeIcon = document.getElementById('theme-icon');
|
||||
var themeTooltip = document.getElementById('theme-tooltip');
|
||||
var html = document.documentElement;
|
||||
|
||||
var themes = ['system', 'dark', 'light'];
|
||||
var icons = { system: '💻', dark: '🌙', light: '☀️' };
|
||||
var labels = {
|
||||
system: 'Системная тема',
|
||||
dark: 'Тёмная тема',
|
||||
light: 'Светлая тема'
|
||||
};
|
||||
|
||||
function getSystemTheme() {
|
||||
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
|
||||
}
|
||||
|
||||
function applyTheme(mode) {
|
||||
var actual = mode === 'system' ? getSystemTheme() : mode;
|
||||
html.setAttribute('data-theme', actual);
|
||||
if (themeIcon) themeIcon.textContent = icons[mode];
|
||||
if (themeTooltip) themeTooltip.textContent = labels[mode] + ' — нажмите для смены';
|
||||
}
|
||||
|
||||
function getStoredTheme() {
|
||||
return localStorage.getItem('theme') || 'system';
|
||||
}
|
||||
|
||||
function cycleTheme() {
|
||||
var current = getStoredTheme();
|
||||
var idx = themes.indexOf(current);
|
||||
var next = themes[(idx + 1) % themes.length];
|
||||
localStorage.setItem('theme', next);
|
||||
applyTheme(next);
|
||||
}
|
||||
|
||||
// Init theme
|
||||
applyTheme(getStoredTheme());
|
||||
|
||||
// Listen for system theme changes
|
||||
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', function () {
|
||||
if (getStoredTheme() === 'system') {
|
||||
applyTheme('system');
|
||||
}
|
||||
});
|
||||
|
||||
if (themeBtn) {
|
||||
themeBtn.addEventListener('click', cycleTheme);
|
||||
}
|
||||
|
||||
// ===== YANDEX MAP THEME =====
|
||||
var mapFrame = document.getElementById('yandex-map');
|
||||
if (mapFrame) {
|
||||
var mapLon = mapFrame.getAttribute('data-lon');
|
||||
var mapLat = mapFrame.getAttribute('data-lat');
|
||||
var mapAddress = mapFrame.getAttribute('data-address') || '';
|
||||
|
||||
function updateMapTheme() {
|
||||
var theme = html.getAttribute('data-theme') || 'light';
|
||||
var params = 'll=' + mapLon + ',' + mapLat +
|
||||
'&z=16' +
|
||||
'&pt=' + mapLon + ',' + mapLat + ',pm2rdl' +
|
||||
'&text=' + encodeURIComponent(mapAddress) +
|
||||
'&theme=' + theme;
|
||||
mapFrame.src = 'https://yandex.ru/map-widget/v1/?' + params;
|
||||
}
|
||||
|
||||
updateMapTheme();
|
||||
|
||||
var mapObserver = new MutationObserver(function (mutations) {
|
||||
for (var i = 0; i < mutations.length; i++) {
|
||||
if (mutations[i].attributeName === 'data-theme') {
|
||||
updateMapTheme();
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
mapObserver.observe(html, { attributes: true });
|
||||
}
|
||||
|
||||
// ===== BURGER MENU =====
|
||||
var burger = document.getElementById('burger');
|
||||
var nav = document.querySelector('.header__nav');
|
||||
if (burger && nav) {
|
||||
burger.addEventListener('click', function () {
|
||||
nav.classList.toggle('active');
|
||||
});
|
||||
}
|
||||
|
||||
// ===== SMOOTH SCROLL =====
|
||||
document.querySelectorAll('a[href^="#"]').forEach(function (link) {
|
||||
link.addEventListener('click', function (e) {
|
||||
var id = this.getAttribute('href');
|
||||
if (id === '#') return;
|
||||
var target = document.querySelector(id);
|
||||
if (target) {
|
||||
e.preventDefault();
|
||||
var headerH = document.querySelector('.header');
|
||||
var offset = headerH ? headerH.offsetHeight : 0;
|
||||
var top = target.getBoundingClientRect().top + window.pageYOffset - offset;
|
||||
window.scrollTo({ top: top, behavior: 'smooth' });
|
||||
if (nav) nav.classList.remove('active');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// ===== PHONE MASK =====
|
||||
var phoneInput = document.getElementById('phone');
|
||||
if (phoneInput) {
|
||||
phoneInput.addEventListener('focus', function () {
|
||||
if (this.value === '') {
|
||||
this.value = '8 (___) ___-__-__';
|
||||
}
|
||||
});
|
||||
phoneInput.addEventListener('input', function () {
|
||||
var val = this.value.replace(/\D/g, '');
|
||||
var formatted = '8 (';
|
||||
if (val.length > 1) formatted += val.substring(1, 4);
|
||||
if (val.length >= 4) formatted += ') ';
|
||||
if (val.length > 4) formatted += val.substring(4, 7);
|
||||
if (val.length >= 7) formatted += '-';
|
||||
if (val.length > 7) formatted += val.substring(7, 9);
|
||||
if (val.length >= 9) formatted += '-';
|
||||
if (val.length > 9) formatted += val.substring(9, 11);
|
||||
this.value = formatted.trim();
|
||||
});
|
||||
phoneInput.addEventListener('blur', function () {
|
||||
if (this.value === '8 (___) ___-__-__' || this.value.replace(/\D/g, '').length < 11) {
|
||||
this.value = '';
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// ===== CHARACTER COUNTER =====
|
||||
var messageField = document.getElementById('message');
|
||||
var charCount = document.querySelector('.char-count');
|
||||
if (messageField && charCount) {
|
||||
messageField.addEventListener('input', function () {
|
||||
var remaining = 500 - this.value.length;
|
||||
charCount.textContent = 'Осталось: ' + remaining;
|
||||
});
|
||||
}
|
||||
|
||||
// ===== CAROUSEL =====
|
||||
var carouselEl = document.querySelector('.carousel');
|
||||
var track = document.querySelector('.carousel__track');
|
||||
var slides = track ? Array.from(track.querySelectorAll('.case')) : [];
|
||||
var prevBtn = document.querySelector('.carousel__prev');
|
||||
var nextBtn = document.querySelector('.carousel__next');
|
||||
var counterEl = document.getElementById('carousel-counter');
|
||||
|
||||
if (carouselEl && track && slides.length > 0 && prevBtn && nextBtn) {
|
||||
var realCount = slides.length;
|
||||
var isTransitioning = false;
|
||||
|
||||
// Clone first and last slide for infinite loop
|
||||
if (realCount > 1) {
|
||||
var firstClone = slides[0].cloneNode(true);
|
||||
var lastClone = slides[realCount - 1].cloneNode(true);
|
||||
firstClone.classList.add('clone');
|
||||
lastClone.classList.add('clone');
|
||||
track.insertBefore(lastClone, track.firstChild);
|
||||
track.appendChild(firstClone);
|
||||
}
|
||||
|
||||
// Re-query all slides including clones
|
||||
slides = Array.from(track.querySelectorAll('.case'));
|
||||
var totalSlides = slides.length;
|
||||
|
||||
// Start at real slide #2 (index 2 because clone of last is at index 0)
|
||||
var currentIndex = realCount > 1 ? 2 : 1;
|
||||
|
||||
var autoTimer = null;
|
||||
|
||||
function getSlideWidth() {
|
||||
return Math.round(carouselEl.clientWidth * 0.72);
|
||||
}
|
||||
|
||||
function setupSlides() {
|
||||
var w = getSlideWidth();
|
||||
for (var i = 0; i < slides.length; i++) {
|
||||
slides[i].style.width = w + 'px';
|
||||
}
|
||||
}
|
||||
|
||||
function updateActiveClass() {
|
||||
var realIdx = getRealIndex(currentIndex);
|
||||
for (var i = 0; i < slides.length; i++) {
|
||||
if (slides[i].classList.contains('clone')) {
|
||||
slides[i].classList.remove('case--active');
|
||||
} else {
|
||||
var thisRealIdx = i - 1;
|
||||
slides[i].classList.toggle('case--active', thisRealIdx === realIdx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getRealIndex(idx) {
|
||||
if (idx <= 0) return realCount - 1;
|
||||
if (idx >= realCount + 1) return 0;
|
||||
return idx - 1;
|
||||
}
|
||||
|
||||
function goToSlide(index, animate) {
|
||||
var slideW = getSlideWidth();
|
||||
var carouselW = carouselEl.clientWidth;
|
||||
var offset = (slideW * index) - (carouselW / 2) + (slideW / 2);
|
||||
if (offset < 0) offset = 0;
|
||||
|
||||
if (animate === false) {
|
||||
track.style.transition = 'none';
|
||||
} else {
|
||||
track.style.transition = 'transform 0.5s cubic-bezier(0.4, 0, 0.2, 1)';
|
||||
}
|
||||
|
||||
track.style.transform = 'translateX(-' + offset + 'px)';
|
||||
updateActiveClass();
|
||||
|
||||
if (counterEl) {
|
||||
counterEl.textContent = (getRealIndex(currentIndex) + 1) + ' / ' + realCount;
|
||||
}
|
||||
}
|
||||
|
||||
function handleTransitionEnd() {
|
||||
isTransitioning = false;
|
||||
// If we landed on a clone, jump to the real slide without animation
|
||||
if (currentIndex <= 0) {
|
||||
currentIndex = realCount;
|
||||
goToSlide(currentIndex, false);
|
||||
} else if (currentIndex >= realCount + 1) {
|
||||
currentIndex = 1;
|
||||
goToSlide(currentIndex, false);
|
||||
}
|
||||
}
|
||||
|
||||
track.addEventListener('transitionend', handleTransitionEnd);
|
||||
|
||||
function startAuto() {
|
||||
stopAuto();
|
||||
if (realCount > 1) {
|
||||
autoTimer = setInterval(function () {
|
||||
currentIndex++;
|
||||
goToSlide(currentIndex, true);
|
||||
}, 5000);
|
||||
}
|
||||
}
|
||||
|
||||
function stopAuto() {
|
||||
if (autoTimer) {
|
||||
clearInterval(autoTimer);
|
||||
autoTimer = null;
|
||||
}
|
||||
}
|
||||
|
||||
prevBtn.addEventListener('click', function () {
|
||||
if (isTransitioning) return;
|
||||
isTransitioning = true;
|
||||
stopAuto();
|
||||
currentIndex--;
|
||||
goToSlide(currentIndex, true);
|
||||
startAuto();
|
||||
});
|
||||
|
||||
nextBtn.addEventListener('click', function () {
|
||||
if (isTransitioning) return;
|
||||
isTransitioning = true;
|
||||
stopAuto();
|
||||
currentIndex++;
|
||||
goToSlide(currentIndex, true);
|
||||
startAuto();
|
||||
});
|
||||
|
||||
var resizeTimer;
|
||||
window.addEventListener('resize', function () {
|
||||
clearTimeout(resizeTimer);
|
||||
resizeTimer = setTimeout(function () {
|
||||
setupSlides();
|
||||
goToSlide(currentIndex, false);
|
||||
}, 150);
|
||||
});
|
||||
|
||||
setupSlides();
|
||||
goToSlide(currentIndex, false);
|
||||
startAuto();
|
||||
}
|
||||
|
||||
// ===== COOKIE BANNER =====
|
||||
var cookieBanner = document.getElementById('cookie-banner');
|
||||
var cookieAccept = document.getElementById('cookie-accept');
|
||||
if (cookieBanner && cookieAccept) {
|
||||
if (!localStorage.getItem('cookies_accepted')) {
|
||||
cookieBanner.classList.add('active');
|
||||
}
|
||||
cookieAccept.addEventListener('click', function () {
|
||||
localStorage.setItem('cookies_accepted', '1');
|
||||
cookieBanner.classList.remove('active');
|
||||
});
|
||||
}
|
||||
|
||||
// ===== STICKY PANEL =====
|
||||
var stickyPanel = document.getElementById('sticky-panel');
|
||||
var heroSection = document.getElementById('hero');
|
||||
var footerEl = document.querySelector('.footer');
|
||||
if (stickyPanel && heroSection) {
|
||||
var footerVisible = false;
|
||||
|
||||
if (footerEl) {
|
||||
var footerObserver = new IntersectionObserver(function (entries) {
|
||||
footerVisible = entries[0].isIntersecting;
|
||||
if (footerVisible) {
|
||||
stickyPanel.classList.remove('active');
|
||||
}
|
||||
}, { threshold: 0.1 });
|
||||
footerObserver.observe(footerEl);
|
||||
}
|
||||
|
||||
var ticking = false;
|
||||
|
||||
function updateSticky() {
|
||||
var heroBottom = heroSection.getBoundingClientRect().bottom;
|
||||
if (!footerVisible) {
|
||||
stickyPanel.classList.toggle('active', heroBottom < 0);
|
||||
}
|
||||
ticking = false;
|
||||
}
|
||||
|
||||
window.addEventListener('scroll', function () {
|
||||
if (!ticking) {
|
||||
window.requestAnimationFrame(updateSticky);
|
||||
ticking = true;
|
||||
}
|
||||
}, { passive: true });
|
||||
|
||||
updateSticky();
|
||||
}
|
||||
|
||||
// ===== FAQ ACCORDION =====
|
||||
document.querySelectorAll('.faq-question').forEach(function (btn) {
|
||||
btn.addEventListener('click', function () {
|
||||
var item = this.closest('.faq-item');
|
||||
if (!item) return;
|
||||
var isActive = item.classList.contains('active');
|
||||
document.querySelectorAll('.faq-item').forEach(function (el) {
|
||||
el.classList.remove('active');
|
||||
});
|
||||
if (!isActive) {
|
||||
item.classList.add('active');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// ===== SCROLL REVEAL ANIMATIONS =====
|
||||
var revealElements = document.querySelectorAll(
|
||||
'.problem-card, .service-card, .industry-card, .step, .case, .faq-item, .testimonial-card, .info-card, .about-card'
|
||||
);
|
||||
if (revealElements.length > 0) {
|
||||
var revealObserver = new IntersectionObserver(function (entries) {
|
||||
entries.forEach(function (entry) {
|
||||
if (entry.isIntersecting) {
|
||||
entry.target.classList.add('visible');
|
||||
revealObserver.unobserve(entry.target);
|
||||
}
|
||||
});
|
||||
}, {
|
||||
threshold: 0.1,
|
||||
rootMargin: '0px 0px -40px 0px'
|
||||
});
|
||||
|
||||
revealElements.forEach(function (el, i) {
|
||||
el.style.transitionDelay = (i % 3) * 0.08 + 's';
|
||||
revealObserver.observe(el);
|
||||
});
|
||||
}
|
||||
|
||||
// ===== FORM SUBMIT =====
|
||||
var form = document.getElementById('contact-form');
|
||||
var responseDiv = document.getElementById('form-response');
|
||||
|
||||
if (form && responseDiv) {
|
||||
// Убираем ошибку при фокусе на поле
|
||||
form.querySelectorAll('input, textarea').forEach(function (input) {
|
||||
input.addEventListener('focus', function () {
|
||||
var group = this.closest('.form-group');
|
||||
if (group) {
|
||||
group.classList.remove('form-group--error');
|
||||
var err = group.querySelector('.error-msg');
|
||||
if (err) {
|
||||
err.classList.remove('visible');
|
||||
err.textContent = '';
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
form.addEventListener('submit', async function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
// Сброс всех ошибок
|
||||
document.querySelectorAll('.form-group--error').forEach(function (el) {
|
||||
el.classList.remove('form-group--error');
|
||||
});
|
||||
document.querySelectorAll('.error-msg.visible').forEach(function (el) {
|
||||
el.classList.remove('visible');
|
||||
el.textContent = '';
|
||||
});
|
||||
|
||||
// Клиентская валидация
|
||||
var hasError = false;
|
||||
|
||||
var nameInput = document.getElementById('name');
|
||||
if (nameInput && !nameInput.value.trim()) {
|
||||
showFieldError(nameInput, 'Введите ваше имя');
|
||||
hasError = true;
|
||||
}
|
||||
|
||||
var phoneInput = document.getElementById('phone');
|
||||
if (phoneInput) {
|
||||
var digits = phoneInput.value.replace(/\D/g, '');
|
||||
if (digits.length < 11) {
|
||||
showFieldError(phoneInput, 'Введите корректный номер телефона');
|
||||
hasError = true;
|
||||
}
|
||||
}
|
||||
|
||||
var agreeInput = document.getElementById('agree');
|
||||
if (agreeInput && !agreeInput.checked) {
|
||||
var agreeGroup = agreeInput.closest('.form-group');
|
||||
if (agreeGroup) {
|
||||
agreeGroup.classList.add('form-group--error');
|
||||
var errSpan = agreeGroup.querySelector('.error-msg');
|
||||
if (errSpan) {
|
||||
errSpan.textContent = 'Необходимо согласиться с политикой обработки персональных данных';
|
||||
errSpan.classList.add('visible');
|
||||
}
|
||||
}
|
||||
hasError = true;
|
||||
}
|
||||
|
||||
if (hasError) return;
|
||||
|
||||
var formData = new FormData(form);
|
||||
formData.append('ajax', '1');
|
||||
|
||||
try {
|
||||
var res = await fetch(window.location.href, {
|
||||
method: 'POST',
|
||||
body: formData
|
||||
});
|
||||
var data = await res.json();
|
||||
|
||||
if (data.success) {
|
||||
form.style.display = 'none';
|
||||
responseDiv.innerHTML =
|
||||
'<div class="success-msg">' +
|
||||
'<div class="check-icon">' +
|
||||
'<svg viewBox="0 0 24 24"><polyline points="4 12 10 18 20 6"></polyline></svg>' +
|
||||
'</div>' +
|
||||
'<p>' + data.message + '</p>' +
|
||||
'</div>';
|
||||
} else {
|
||||
responseDiv.innerHTML = '<p style="color:var(--error); font-weight:600; text-align:center;">' + data.message + '</p>';
|
||||
}
|
||||
} catch (err) {
|
||||
responseDiv.innerHTML = '<p style="color:var(--error); font-weight:600; text-align:center;">Произошла ошибка. Попробуйте позже.</p>';
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function showFieldError(input, message) {
|
||||
var group = input.closest('.form-group');
|
||||
if (!group) return;
|
||||
group.classList.add('form-group--error');
|
||||
var errSpan = group.querySelector('.error-msg');
|
||||
if (errSpan) {
|
||||
errSpan.textContent = message;
|
||||
errSpan.classList.add('visible');
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,2 @@
|
||||
DirectoryIndex index.php
|
||||
Options -Indexes
|
||||
@@ -0,0 +1,92 @@
|
||||
<?php
|
||||
/**
|
||||
* AegisOne Engineering — Аудит безопасности
|
||||
*/
|
||||
require_once __DIR__ . '/../config.php';
|
||||
require_once __DIR__ . '/../seo.php';
|
||||
|
||||
$pageKey = 'audit';
|
||||
$canonical = '/audit/';
|
||||
$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"><strong>Факты, а не предположения!</strong><br>Объективная оценка рисков и уязвимостей систем безопасности вашего бизнеса. Аудит видеонаблюдения, СКУД и охранно-пожарных систем.</p>
|
||||
<a href="#contacts" class="btn">Заказать аудит</a>
|
||||
<p class="hero__footnote">Работаем по всей России — выезд специалиста на объект</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="services" id="services">
|
||||
<div class="container">
|
||||
<h2 class="section-title">Что мы проверяем</h2>
|
||||
<div class="services__grid">
|
||||
<?php
|
||||
$items = [
|
||||
['svg' => '<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"/>', 'title' => 'Аудит систем видеонаблюдения', 'desc' => 'Комплексная проверка состояния видеокамер, покрытия территории, качества видеозаписей и настроек хранения данных.'],
|
||||
['svg' => '<rect x="16" y="12" width="32" height="40" rx="4" fill="none" stroke="#00ADEF" stroke-width="3"/><circle cx="32" cy="32" r="6" fill="none" stroke="#00ADEF" stroke-width="3"/>', 'title' => 'Аудит систем контроля доступа', 'desc' => 'Проверка СКУД на предмет уязвимостей, правильности настроек и соответствия стандартам безопасности.'],
|
||||
['svg' => '<path d="M32 8 L8 32 L24 48 L56 24 Z" fill="none" stroke="#00ADEF" stroke-width="3"/><circle cx="32" cy="28" r="6" fill="none" stroke="#00ADEF" stroke-width="3"/>', 'title' => 'Аудит охранно-пожарных систем', 'desc' => 'Анализ состояния ОПС, проверка эффективности обнаружения угроз и своевременности реагирования.'],
|
||||
['svg' => '<polygon points="16,8 48,8 56,32 32,56 8,32" fill="none" stroke="#00ADEF" stroke-width="3"/><circle cx="32" cy="32" r="8" fill="none" stroke="#00ADEF" stroke-width="3"/>', 'title' => 'Комплексный аудит безопасности', 'desc' => 'Полный анализ всех систем безопасности на объекте с выработкой рекомендаций по повышению защищённости.'],
|
||||
];
|
||||
foreach ($items as $item): ?>
|
||||
<div class="card service-card">
|
||||
<svg class="card__icon" viewBox="0 0 64 64"><?= $item['svg'] ?></svg>
|
||||
<h3><?= $item['title'] ?></h3>
|
||||
<p><?= $item['desc'] ?></p>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="how" id="how">
|
||||
<div class="container">
|
||||
<h2 class="section-title">Как проходит аудит</h2>
|
||||
<div class="how__steps">
|
||||
<?php
|
||||
$steps = [
|
||||
['num' => '1', 'title' => 'Первичное обсуждение', 'desc' => 'Короткая встреча или созвон, чтобы понять особенности вашего объекта и ваши потребности.'],
|
||||
['num' => '2', 'title' => 'Анализ документации', 'desc' => 'Изучаем существующие проекты, планы и отчёты служб безопасности.'],
|
||||
['num' => '3', 'title' => 'Выезд на объект', 'desc' => 'Визуальный и инструментальный осмотр систем безопасности с проверкой фактической работоспособности.'],
|
||||
['num' => '4', 'title' => 'Подготовка отчёта', 'desc' => 'Детальный отчёт с выявленными уязвимостями, фотографиями и рекомендациями по устранению.'],
|
||||
['num' => '5', 'title' => 'Презентация результатов', 'desc' => 'Представляем отчёт руководству и отвечаем на все вопросы.'],
|
||||
];
|
||||
foreach ($steps as $step): ?>
|
||||
<div class="step">
|
||||
<div class="step__num"><?= $step['num'] ?></div>
|
||||
<h3><?= $step['title'] ?></h3>
|
||||
<p><?= $step['desc'] ?></p>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="faq" id="faq">
|
||||
<div class="container">
|
||||
<h2 class="section-title">Вопросы об аудите</h2>
|
||||
<div class="faq__list">
|
||||
<?php
|
||||
$faqs = [
|
||||
['q' => 'Чем ваш аудит отличается от проверки штатной службы безопасности?', 'a' => 'Штатная служба безопасности часто не замечает системных проблем — она работает «внутри» процесса. Мы смотрим независимо, как внешние аудиторы, и видим то, что стало привычным. Кроме того, мы используем метод «Тайный покупатель».'],
|
||||
['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'; ?>
|
||||
@@ -0,0 +1,2 @@
|
||||
DirectoryIndex index.php
|
||||
Options -Indexes
|
||||
@@ -0,0 +1,109 @@
|
||||
<?php
|
||||
/**
|
||||
* AegisOne Engineering — Blog AJAX API
|
||||
*
|
||||
* Возвращает HTML-фрагмент списка статей для AJAX-подгрузки.
|
||||
* Параметры: cat, page, search
|
||||
*/
|
||||
require_once __DIR__ . '/../config.php';
|
||||
require_once __DIR__ . '/../data/db-config.php';
|
||||
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
|
||||
function getDB(): PDO {
|
||||
static $pdo = null;
|
||||
if ($pdo === null) {
|
||||
if (DB_TYPE === 'pgsql') {
|
||||
$dsn = 'pgsql:host=' . DB_HOST . ';port=' . DB_PORT . ';dbname=' . DB_NAME;
|
||||
} else {
|
||||
$dsn = 'mysql:host=' . DB_HOST . ';port=' . DB_PORT . ';dbname=' . DB_NAME . ';charset=' . DB_CHARSET;
|
||||
}
|
||||
$pdo = new PDO($dsn, DB_USER, DB_PASS, [
|
||||
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
||||
PDO::ATTR_EMULATE_PREPARES => false,
|
||||
]);
|
||||
}
|
||||
return $pdo;
|
||||
}
|
||||
|
||||
$pdo = getDB();
|
||||
|
||||
$categories = [
|
||||
'audit' => 'Аудит',
|
||||
'sla' => 'SLA',
|
||||
'incident' => 'Инциденты',
|
||||
'supervision' => 'Технадзор',
|
||||
'documentation' => 'Документация',
|
||||
'risk' => 'Риск-инжиниринг',
|
||||
'cases' => 'Кейсы',
|
||||
];
|
||||
|
||||
$search = trim($_GET['search'] ?? '');
|
||||
$category = trim($_GET['cat'] ?? '');
|
||||
$page = max(1, (int)($_GET['page'] ?? 1));
|
||||
$perPage = 12;
|
||||
|
||||
$where = "status='published'";
|
||||
$params = [];
|
||||
if ($category !== '' && isset($categories[$category])) {
|
||||
$where .= " AND category=?";
|
||||
$params[] = $category;
|
||||
}
|
||||
if ($search !== '') {
|
||||
$where .= " AND (title LIKE ? OR excerpt LIKE ? OR content LIKE ?)";
|
||||
$searchTerm = '%' . $search . '%';
|
||||
$params[] = $searchTerm;
|
||||
$params[] = $searchTerm;
|
||||
$params[] = $searchTerm;
|
||||
}
|
||||
|
||||
$countStmt = $pdo->prepare("SELECT COUNT(*) FROM blog_posts WHERE $where");
|
||||
$countStmt->execute($params);
|
||||
$totalPosts = (int)$countStmt->fetchColumn();
|
||||
$totalPages = max(1, (int)ceil($totalPosts / $perPage));
|
||||
$offset = ($page - 1) * $perPage;
|
||||
|
||||
$stmt = $pdo->prepare("SELECT bp.*, u.full_name AS author_name FROM blog_posts bp LEFT JOIN users u ON u.id=bp.author_id WHERE $where ORDER BY bp.published_at DESC LIMIT $perPage OFFSET $offset");
|
||||
$stmt->execute($params);
|
||||
$posts = $stmt->fetchAll();
|
||||
|
||||
ob_start();
|
||||
|
||||
if (empty($posts)): ?>
|
||||
<div class="empty-state">
|
||||
<h2>Записей пока нет</h2>
|
||||
<p>Следите за обновлениями — мы регулярно публикуем новые статьи.</p>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="blog-grid">
|
||||
<?php foreach ($posts as $p): ?>
|
||||
<article class="blog-card">
|
||||
<div class="cat"><?= htmlspecialchars($categories[$p['category']] ?? $p['category']) ?></div>
|
||||
<h2><a href="/blog/<?= htmlspecialchars($p['slug']) ?>"><?= htmlspecialchars($p['title']) ?></a></h2>
|
||||
<?php if ($p['excerpt']): ?><p><?= htmlspecialchars($p['excerpt']) ?></p><?php endif; ?>
|
||||
<div class="meta">
|
||||
<?= $p['published_at'] ? date('d.m.Y', strtotime($p['published_at'])) : date('d.m.Y', strtotime($p['created_at'])) ?>
|
||||
<?= $p['author_name'] ? ' · ' . htmlspecialchars($p['author_name']) : '' ?>
|
||||
</div>
|
||||
</article>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php if ($totalPages > 1): ?>
|
||||
<div class="pagination">
|
||||
<?php if ($page > 1): ?>
|
||||
<a href="#" data-page="<?= $page - 1 ?>" data-cat="<?= htmlspecialchars($category) ?>" data-search="<?= htmlspecialchars($search) ?>">← Назад</a>
|
||||
<?php endif; ?>
|
||||
<?php for ($i = 1; $i <= $totalPages; $i++): ?>
|
||||
<a href="#" data-page="<?= $i ?>" data-cat="<?= htmlspecialchars($category) ?>" data-search="<?= htmlspecialchars($search) ?>" class="<?= $i === $page ? 'current' : '' ?>"><?= $i ?></a>
|
||||
<?php endfor; ?>
|
||||
<?php if ($page < $totalPages): ?>
|
||||
<a href="#" data-page="<?= $page + 1 ?>" data-cat="<?= htmlspecialchars($category) ?>" data-search="<?= htmlspecialchars($search) ?>">Вперёд →</a>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php endif;
|
||||
|
||||
$html = ob_get_clean();
|
||||
|
||||
echo json_encode(['html' => $html, 'totalPages' => $totalPages, 'currentPage' => $page, 'category' => $category], JSON_UNESCAPED_UNICODE);
|
||||
@@ -0,0 +1,349 @@
|
||||
<?php
|
||||
/**
|
||||
* AegisOne Engineering — Блог
|
||||
*
|
||||
* Два режима: список статей (/?cat=X&page=N&search=) или отдельная статья (/?slug=article-name)
|
||||
* Использует собственную вёрстку (тёмный градиентный хедер, боковая панель).
|
||||
*/
|
||||
require_once __DIR__ . '/../config.php';
|
||||
require_once __DIR__ . '/../data/db-config.php';
|
||||
|
||||
function getDB(): PDO {
|
||||
static $pdo = null;
|
||||
if ($pdo === null) {
|
||||
if (DB_TYPE === 'pgsql') {
|
||||
$dsn = 'pgsql:host=' . DB_HOST . ';port=' . DB_PORT . ';dbname=' . DB_NAME;
|
||||
} else {
|
||||
$dsn = 'mysql:host=' . DB_HOST . ';port=' . DB_PORT . ';dbname=' . DB_NAME . ';charset=' . DB_CHARSET;
|
||||
}
|
||||
$pdo = new PDO($dsn, DB_USER, DB_PASS, [
|
||||
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
||||
PDO::ATTR_EMULATE_PREPARES => false,
|
||||
]);
|
||||
}
|
||||
return $pdo;
|
||||
}
|
||||
|
||||
$pdo = getDB();
|
||||
|
||||
$categories = [
|
||||
'audit' => 'Аудит',
|
||||
'sla' => 'SLA',
|
||||
'incident' => 'Инциденты',
|
||||
'supervision' => 'Технадзор',
|
||||
'documentation' => 'Документация',
|
||||
'risk' => 'Риск-инжиниринг',
|
||||
'cases' => 'Кейсы',
|
||||
];
|
||||
|
||||
$slug = trim($_GET['slug'] ?? '');
|
||||
$search = trim($_GET['search'] ?? '');
|
||||
$category = trim($_GET['cat'] ?? '');
|
||||
$page = max(1, (int)($_GET['page'] ?? 1));
|
||||
$perPage = 12;
|
||||
|
||||
// Single post
|
||||
if ($slug !== '') {
|
||||
$stmt = $pdo->prepare("SELECT bp.*, u.full_name AS author_name FROM blog_posts bp LEFT JOIN users u ON u.id=bp.author_id WHERE bp.slug=? AND bp.status='published' LIMIT 1");
|
||||
$stmt->execute([$slug]);
|
||||
$post = $stmt->fetch();
|
||||
|
||||
$pageTitle = $post ? ($post['title'] . ' — ' . SITE_NAME) : 'Пост не найден — ' . SITE_NAME;
|
||||
$pageDesc = $post ? ($post['excerpt'] ?: mb_substr(strip_tags($post['content']), 0, 200)) : '';
|
||||
$robots = $post ? 'index, follow' : 'noindex, nofollow';
|
||||
$canonical = $post ? '/blog/' . $post['slug'] : '/blog/';
|
||||
} else {
|
||||
$pageTitle = 'Блог — ' . SITE_NAME;
|
||||
$pageDesc = 'Инженерный блог AegisOne Engineering: риск-инжиниринг, SLA, инциденты, аудит систем безопасности.';
|
||||
$robots = 'index, follow';
|
||||
$canonical = '/blog/';
|
||||
}
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title><?= $pageTitle ?></title>
|
||||
<meta name="description" content="<?= $pageDesc ?>">
|
||||
<link rel="canonical" href="https://<?= $_SERVER['HTTP_HOST'] ?><?= $canonical ?>">
|
||||
<meta name="robots" content="<?= $robots ?>">
|
||||
<link rel="icon" type="image/x-icon" href="/assets/img/favicon.ico">
|
||||
<link rel="stylesheet" href="/style.php">
|
||||
<?php if (file_exists(__DIR__ . '/../inc/analytics.php')) require __DIR__ . '/../inc/analytics.php'; ?>
|
||||
<style>
|
||||
:root { --bg-body:#0a0e1a; --bg-card:#111827; --bg-input:#1a1f2e; --text-primary:#e5e7eb; --text-secondary:#9ca3af; --text-muted:#6b7280; --border:#1f2937; --radius:10px; --font:'Open Sans',Arial,sans-serif; }
|
||||
* { margin:0; padding:0; box-sizing:border-box; }
|
||||
body { font-family:var(--font); background:var(--bg-body); color:var(--text-primary); min-height:100vh; }
|
||||
a { color:inherit; text-decoration:none; }
|
||||
.blog-header { background:linear-gradient(135deg,#0a0e1a 0%,#0d1a30 100%); padding:48px 24px; text-align:center; border-bottom:1px solid var(--border); }
|
||||
.blog-header h1 { font-size:32px; font-weight:800; margin-bottom:8px; }
|
||||
.blog-header p { color:var(--text-secondary); max-width:600px; margin:0 auto; }
|
||||
.blog-layout { max-width:1100px; margin:0 auto; padding:32px 24px; display:grid; grid-template-columns:200px 1fr; gap:32px; }
|
||||
.blog-sidebar { position:sticky; top:24px; align-self:start; }
|
||||
.blog-sidebar a { display:block; padding:6px 0; font-size:13px; color:var(--text-secondary); }
|
||||
.blog-sidebar a:hover,.blog-sidebar a.active { color:var(--accent); }
|
||||
.blog-sidebar h3 { font-size:11px; text-transform:uppercase; color:var(--text-muted); margin-bottom:8px; letter-spacing:1px; }
|
||||
.blog-grid { display:grid; gap:20px; }
|
||||
.blog-card { background:var(--bg-card); border:1px solid var(--border); border-radius:var(--radius); padding:24px; transition:border-color 0.2s; }
|
||||
.blog-card:hover { border-color:var(--accent); }
|
||||
.blog-card .cat { font-size:11px; font-weight:700; text-transform:uppercase; color:var(--accent); letter-spacing:0.5px; margin-bottom:6px; }
|
||||
.blog-card h2 { font-size:18px; font-weight:700; margin-bottom:8px; }
|
||||
.blog-card h2 a:hover { color:var(--accent); }
|
||||
.blog-card p { font-size:13px; color:var(--text-secondary); line-height:1.6; }
|
||||
.blog-card .meta { font-size:11px; color:var(--text-muted); margin-top:12px; }
|
||||
.search-form { display:flex; gap:8px; margin-bottom:20px; }
|
||||
.search-form input { flex:1; padding:8px 14px; background:var(--bg-input); border:1px solid var(--border); border-radius:6px; color:var(--text-primary); font-size:13px; font-family:var(--font); }
|
||||
.search-form input:focus { outline:none; border-color:var(--accent); }
|
||||
.search-form button { padding:8px 16px; background:var(--accent); color:#fff; border:none; border-radius:6px; cursor:pointer; }
|
||||
.blog-post { max-width:800px; margin:0 auto; padding:40px 0; }
|
||||
.blog-post h1 { font-size:28px; margin-bottom:16px; }
|
||||
.blog-meta { display:flex; gap:16px; font-size:13px; color:var(--text-muted); margin-bottom:24px; }
|
||||
.blog-category { color:var(--accent); font-weight:600; }
|
||||
.blog-content { line-height:1.8; font-size:15px; }
|
||||
.blog-content p { margin-bottom:16px; }
|
||||
.blog-share { margin:32px 0; padding:16px 0; border-top:1px solid var(--border); display:flex; gap:12px; align-items:center; font-size:13px; }
|
||||
.blog-share a { color:var(--accent); }
|
||||
.blog-nav { display:flex; justify-content:space-between; gap:16px; margin-top:24px; }
|
||||
.blog-nav a { font-size:13px; color:var(--accent); }
|
||||
.empty-state { text-align:center; padding:60px 20px; }
|
||||
.empty-state h2 { font-size:24px; margin-bottom:12px; }
|
||||
.empty-state p { color:var(--text-secondary); margin-bottom:24px; }
|
||||
.pagination { display:flex; justify-content:center; gap:8px; margin-top:32px; }
|
||||
.pagination a { padding:8px 14px; background:var(--bg-card); border:1px solid var(--border); border-radius:6px; font-size:13px; }
|
||||
.pagination a.current { background:var(--accent); color:#fff; border-color:var(--accent); }
|
||||
.filter-bar { display:flex; gap:12px; align-items:center; margin-bottom:20px; }
|
||||
.btn-secondary { background:var(--bg-card); color:var(--text-secondary); padding:6px 14px; border-radius:6px; font-size:12px; }
|
||||
.btn-secondary:hover { border-color:var(--accent); color:var(--accent); }
|
||||
.blog-footer { text-align:center; padding:24px; border-top:1px solid var(--border); margin-top:40px; }
|
||||
.blog-footer a { color:var(--text-muted); font-size:13px; }
|
||||
.blog-footer a:hover { color:var(--accent); }
|
||||
@media (max-width:768px) { .blog-layout { grid-template-columns:1fr; } .blog-sidebar { position:static; } .blog-post h1 { font-size:22px; } }
|
||||
.blog-grid.loading { opacity:0.5; pointer-events:none; }
|
||||
.blog-grid.loading::after { content:'Загрузка...'; position:absolute; top:50%; left:50%; transform:translate(-50%,-50%); color:var(--text-muted); font-size:14px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<?php if (file_exists(__DIR__ . '/../inc/analytics-body.php')) require __DIR__ . '/../inc/analytics-body.php'; ?>
|
||||
|
||||
<header class="blog-header">
|
||||
<h1>Инженерный блог AegisOne</h1>
|
||||
<p>Управление рисками, SLA, инциденты и инженерная экспертиза</p>
|
||||
<p style="margin-top:16px;"><a href="/" style="color:var(--text-muted);font-size:13px;">← На главную</a></p>
|
||||
</header>
|
||||
|
||||
<?php if ($slug !== '' && isset($post) && $post): ?>
|
||||
<!-- Single post view -->
|
||||
<main class="blog-post">
|
||||
<article>
|
||||
<h1><?= htmlspecialchars($post['title']) ?></h1>
|
||||
<div class="blog-meta">
|
||||
<span><?= date('d.m.Y', strtotime($post['published_at'])) ?></span>
|
||||
<span class="blog-category"><?= htmlspecialchars($categories[$post['category']] ?? $post['category']) ?></span>
|
||||
<?php if ($post['author_name']): ?><span><?= htmlspecialchars($post['author_name']) ?></span><?php endif; ?>
|
||||
</div>
|
||||
<div class="blog-content"><?= $post['content'] ?></div>
|
||||
</article>
|
||||
<div class="blog-share">
|
||||
<span>Поделиться:</span>
|
||||
<a href="https://t.me/share/url?url=<?= urlencode('https://' . $_SERVER['HTTP_HOST'] . '/blog/' . $post['slug']) ?>" target="_blank">Telegram</a>
|
||||
<a href="https://wa.me/?text=<?= urlencode(htmlspecialchars($post['title']) . ' — https://' . $_SERVER['HTTP_HOST'] . '/blog/' . $post['slug']) ?>" target="_blank">WhatsApp</a>
|
||||
</div>
|
||||
<div class="blog-nav">
|
||||
<?php
|
||||
$prev = $pdo->prepare("SELECT slug,title FROM blog_posts WHERE published_at<? AND status='published' ORDER BY published_at DESC LIMIT 1");
|
||||
$prev->execute([$post['published_at']]); $p = $prev->fetch();
|
||||
$next = $pdo->prepare("SELECT slug,title FROM blog_posts WHERE published_at>? AND status='published' ORDER BY published_at ASC LIMIT 1");
|
||||
$next->execute([$post['published_at']]); $n = $next->fetch();
|
||||
?>
|
||||
<?php if ($p): ?><a href="/blog/<?= $p['slug'] ?>">← <?= htmlspecialchars($p['title']) ?></a><?php endif; ?>
|
||||
<?php if ($n): ?><a href="/blog/<?= $n['slug'] ?>"><?= htmlspecialchars($n['title']) ?> →</a><?php endif; ?>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<?php elseif ($slug !== '' && (!isset($post) || !$post)): ?>
|
||||
<!-- Post not found -->
|
||||
<div class="empty-state">
|
||||
<h2>Пост не найден</h2>
|
||||
<p>Возможно, он был удалён или ещё не опубликован.</p>
|
||||
<a href="/blog/" class="btn-secondary" style="display:inline-block;padding:10px 24px;">← Все записи</a>
|
||||
</div>
|
||||
|
||||
<?php else: ?>
|
||||
<!-- Listing view -->
|
||||
<?php
|
||||
$where = "status='published'";
|
||||
$params = [];
|
||||
if ($category !== '' && isset($categories[$category])) {
|
||||
$where .= " AND category=?";
|
||||
$params[] = $category;
|
||||
}
|
||||
if ($search !== '') {
|
||||
$where .= " AND (title LIKE ? OR excerpt LIKE ? OR content LIKE ?)";
|
||||
$searchTerm = '%' . $search . '%';
|
||||
$params[] = $searchTerm;
|
||||
$params[] = $searchTerm;
|
||||
$params[] = $searchTerm;
|
||||
}
|
||||
$countStmt = $pdo->prepare("SELECT COUNT(*) FROM blog_posts WHERE $where");
|
||||
$countStmt->execute($params);
|
||||
$totalPosts = (int)$countStmt->fetchColumn();
|
||||
$totalPages = max(1, (int)ceil($totalPosts / $perPage));
|
||||
$offset = ($page - 1) * $perPage;
|
||||
|
||||
$stmt = $pdo->prepare("SELECT bp.*, u.full_name AS author_name FROM blog_posts bp LEFT JOIN users u ON u.id=bp.author_id WHERE $where ORDER BY bp.published_at DESC LIMIT $perPage OFFSET $offset");
|
||||
$stmt->execute($params);
|
||||
$posts = $stmt->fetchAll();
|
||||
?>
|
||||
<div class="blog-layout">
|
||||
<aside class="blog-sidebar">
|
||||
<h3>Категории</h3>
|
||||
<a href="#" data-cat="" class="cat-link <?= $category === '' ? 'active' : '' ?>">Все статьи</a>
|
||||
<?php foreach ($categories as $key => $label): ?>
|
||||
<a href="#" data-cat="<?= $key ?>" class="cat-link <?= $category === $key ? 'active' : '' ?>"><?= htmlspecialchars($label) ?></a>
|
||||
<?php endforeach; ?>
|
||||
<h3 style="margin-top:20px;">Поиск</h3>
|
||||
<form method="get" class="search-form" style="flex-direction:column;" id="blogSearchForm">
|
||||
<input type="text" name="search" placeholder="Поиск..." value="<?= htmlspecialchars($search) ?>" id="blogSearchInput">
|
||||
<button type="submit">Найти</button>
|
||||
</form>
|
||||
</aside>
|
||||
<main>
|
||||
<?php if ($category !== ''): ?>
|
||||
<div class="filter-bar">
|
||||
<span style="color:var(--text-muted);">Категория:</span>
|
||||
<a href="/blog/" class="btn-secondary">Все записи</a>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (empty($posts)): ?>
|
||||
<div class="empty-state">
|
||||
<h2>Записей пока нет</h2>
|
||||
<p>Следите за обновлениями — мы регулярно публикуем новые статьи.</p>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="blog-grid" id="blogGrid">
|
||||
<?php foreach ($posts as $p): ?>
|
||||
<article class="blog-card">
|
||||
<div class="cat"><?= htmlspecialchars($categories[$p['category']] ?? $p['category']) ?></div>
|
||||
<h2><a href="/blog/<?= htmlspecialchars($p['slug']) ?>"><?= htmlspecialchars($p['title']) ?></a></h2>
|
||||
<?php if ($p['excerpt']): ?><p><?= htmlspecialchars($p['excerpt']) ?></p><?php endif; ?>
|
||||
<div class="meta">
|
||||
<?= $p['published_at'] ? date('d.m.Y', strtotime($p['published_at'])) : date('d.m.Y', strtotime($p['created_at'])) ?>
|
||||
<?= $p['author_name'] ? ' · ' . htmlspecialchars($p['author_name']) : '' ?>
|
||||
</div>
|
||||
</article>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php if ($totalPages > 1): ?>
|
||||
<div class="pagination" id="blogPagination">
|
||||
<?php if ($page > 1): ?>
|
||||
<a href="#" data-page="<?= $page - 1 ?>" data-cat="<?= htmlspecialchars($category) ?>" data-search="<?= htmlspecialchars($search) ?>">← Назад</a>
|
||||
<?php endif; ?>
|
||||
<?php for ($i = 1; $i <= $totalPages; $i++): ?>
|
||||
<a href="#" data-page="<?= $i ?>" data-cat="<?= htmlspecialchars($category) ?>" data-search="<?= htmlspecialchars($search) ?>" class="<?= $i === $page ? 'current' : '' ?>"><?= $i ?></a>
|
||||
<?php endfor; ?>
|
||||
<?php if ($page < $totalPages): ?>
|
||||
<a href="#" data-page="<?= $page + 1 ?>" data-cat="<?= htmlspecialchars($category) ?>" data-search="<?= htmlspecialchars($search) ?>">Вперёд →</a>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php endif; ?>
|
||||
<?php for ($i = 1; $i <= $totalPages; $i++): ?>
|
||||
<a href="/blog/?page=<?= $i ?><?= $category ? '&cat=' . $category : '' ?><?= $search ? '&search=' . urlencode($search) : '' ?>" class="<?= $i === $page ? 'current' : '' ?>"><?= $i ?></a>
|
||||
<?php endfor; ?>
|
||||
<?php if ($page < $totalPages): ?>
|
||||
<a href="/blog/?page=<?= $page + 1 ?><?= $category ? '&cat=' . $category : '' ?><?= $search ? '&search=' . urlencode($search) : '' ?>">Вперёд →</a>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php endif; ?>
|
||||
</main>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="blog-footer">
|
||||
<a href="/">← AegisOne Engineering — главная</a>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
(function() {
|
||||
var grid = document.getElementById('blogGrid');
|
||||
var pagination = document.getElementById('blogPagination');
|
||||
var catLinks = document.querySelectorAll('.cat-link');
|
||||
var searchForm = document.getElementById('blogSearchForm');
|
||||
var searchInput = document.getElementById('blogSearchInput');
|
||||
|
||||
function loadPosts(cat, page, search) {
|
||||
if (!grid) return;
|
||||
grid.classList.add('loading');
|
||||
|
||||
var url = '/blog/api.php?cat=' + encodeURIComponent(cat) + '&page=' + page + '&search=' + encodeURIComponent(search);
|
||||
|
||||
fetch(url)
|
||||
.then(function(res) { return res.json(); })
|
||||
.then(function(data) {
|
||||
var container = grid.parentElement;
|
||||
container.innerHTML = data.html;
|
||||
|
||||
// Rebind pagination clicks
|
||||
container.querySelectorAll('.pagination a').forEach(function(a) {
|
||||
a.addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
loadPosts(this.dataset.cat || '', this.dataset.page, this.dataset.search || '');
|
||||
});
|
||||
});
|
||||
|
||||
// Update URL without reload
|
||||
var newUrl = '/blog/';
|
||||
var params = [];
|
||||
if (cat) params.push('cat=' + cat);
|
||||
if (page > 1) params.push('page=' + page);
|
||||
if (search) params.push('search=' + encodeURIComponent(search));
|
||||
if (params.length) newUrl += '?' + params.join('&');
|
||||
history.pushState(null, '', newUrl);
|
||||
|
||||
// Update active category
|
||||
catLinks.forEach(function(link) {
|
||||
link.classList.toggle('active', link.dataset.cat === cat);
|
||||
});
|
||||
|
||||
grid.classList.remove('loading');
|
||||
})
|
||||
.catch(function() {
|
||||
grid.classList.remove('loading');
|
||||
});
|
||||
}
|
||||
|
||||
// Category clicks
|
||||
catLinks.forEach(function(link) {
|
||||
link.addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
loadPosts(this.dataset.cat, 1, searchInput ? searchInput.value : '');
|
||||
});
|
||||
});
|
||||
|
||||
// Pagination clicks (initial)
|
||||
if (pagination) {
|
||||
pagination.querySelectorAll('a').forEach(function(a) {
|
||||
a.addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
loadPosts(this.dataset.cat, this.dataset.page, this.dataset.search);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Search submit
|
||||
if (searchForm) {
|
||||
searchForm.addEventListener('submit', function(e) {
|
||||
e.preventDefault();
|
||||
loadPosts('', 1, searchInput.value);
|
||||
});
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
|
||||
<?php if (file_exists(__DIR__ . '/../inc/analytics.php')) require __DIR__ . '/../inc/analytics.php'; ?>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,97 @@
|
||||
<?php
|
||||
/**
|
||||
* ============================================
|
||||
* AegisOne Engineering — Основной конфиг сайта
|
||||
* ============================================
|
||||
*
|
||||
* Все настройки проекта в одном месте:
|
||||
* контакты, ссылки, ID счётчиков, переключатели.
|
||||
*
|
||||
* Для добавления новой константы пиши:
|
||||
* define('CONST_NAME', 'значение');
|
||||
*/
|
||||
|
||||
// ============================
|
||||
// 1. ИНФОРМАЦИЯ О КОМПАНИИ
|
||||
// ============================
|
||||
// SITE_NAME — бренд, отображается в заголовках и мета-тегах
|
||||
// SITE_DOMAIN — домен без протокола (используется для канонических ссылок)
|
||||
// SITE_LEGAL_NAME — юрлицо для договоров и футера
|
||||
define('SITE_NAME', 'AegisOne Engineering');
|
||||
define('SITE_DOMAIN', 'aegisone.ru');
|
||||
define('SITE_LEGAL_NAME', 'ООО «АГИСВАН»');
|
||||
|
||||
// ============================
|
||||
// 2. ТЕЛЕФОНЫ
|
||||
// ============================
|
||||
// PHONE_MAIN — отображается в шапке и футере
|
||||
// PHONE_MAIN_LINK — только цифры, для href="tel:..."
|
||||
// PHONE_SECOND — второй номер (футер)
|
||||
// PHONE_SECOND_LINK — цифры второго номера
|
||||
define('PHONE_MAIN', '+7 (861) 203-33-30');
|
||||
define('PHONE_MAIN_LINK', '+78612033330');
|
||||
define('PHONE_SECOND', '+7 (995) 203-33-30');
|
||||
define('PHONE_SECOND_LINK', '+79952033330');
|
||||
|
||||
// ============================
|
||||
// 3. EMAIL
|
||||
// ============================
|
||||
// SITE_MAIL — публичный ящик для обращений
|
||||
// SITE_MAIL_FROM — отправитель писем с сайта (no-reply)
|
||||
// SITE_MAIL_TO — куда приходят заявки с форм
|
||||
define('SITE_MAIL', 'mail@aegisone.ru');
|
||||
define('SITE_MAIL_FROM', 'no-reply@aegisone.ru');
|
||||
define('SITE_MAIL_TO', 'mail@aegisone.ru');
|
||||
|
||||
// ============================
|
||||
// 4. АДРЕС И КАРТЫ
|
||||
// ============================
|
||||
// YANDEX_MAP_LAT / LON — координаты для карты Яндекса
|
||||
// YANDEX_MAP_ADDRESS — строка с полным адресом
|
||||
define('YANDEX_MAP_LAT', '45.076240');
|
||||
define('YANDEX_MAP_LON', '38.999864');
|
||||
define('YANDEX_MAP_ADDRESS', '350072, Россия, Краснодарский край, г. Краснодар, ул. Московская, д. 81/1, пом. 25');
|
||||
|
||||
// ============================
|
||||
// 5. МЕССЕНДЖЕРЫ
|
||||
// ============================
|
||||
// WHATSAPP_LINK — полная ссылка wa.me
|
||||
// TELEGRAM_LINK — полная ссылка t.me
|
||||
// MAX_LINK — (опционально) резервный мессенджер
|
||||
define('WHATSAPP_LINK', 'https://wa.me/79531137616');
|
||||
define('TELEGRAM_LINK', 'https://t.me/+79531137616');
|
||||
define('MAX_LINK', '');
|
||||
|
||||
// ============================
|
||||
// 6. НАСТРОЙКИ ПОЧТЫ
|
||||
// ============================
|
||||
// SITE_MAIL_SUBJECT_PREFIX — префикс темы письма из формы обратной связи
|
||||
define('SITE_MAIL_SUBJECT_PREFIX', 'Заявка с сайта');
|
||||
|
||||
// ============================
|
||||
// 7. ID СЧЁТЧИКОВ АНАЛИТИКИ
|
||||
// ============================
|
||||
// Яндекс.Метрика — номер счётчика (только цифры).
|
||||
// Если пусто ('') — счётчик не выводится.
|
||||
// Google Analytics — Measurement ID вида G-XXXXXXXXXX.
|
||||
// Если пусто ('') — счётчик не выводится.
|
||||
define('YANDEX_METRIKA_ID', '109016271');
|
||||
define('GOOGLE_ANALYTICS_ID', 'G-7XP3DZB1XJ');
|
||||
|
||||
// ============================
|
||||
// 8. НАСТРОЙКИ СЕРВИСНОЙ ЗОНЫ
|
||||
// ============================
|
||||
// SERVICE_SESSION_TTL — время жизни сессии в секундах (8 часов = 28800)
|
||||
define('SERVICE_SESSION_TTL', 28800);
|
||||
|
||||
// ============================
|
||||
// 9. ВКЛЮЧИТЬ / ВЫКЛЮЧИТЬ ФУНКЦИИ
|
||||
// ============================
|
||||
// LEAD_MAGNET_ENABLED — показывать блок "скачать чек-лист" (true/false)
|
||||
// LEAD_MAGNET_TEXT — текст магнит-предложения
|
||||
// TESTIMONIALS_ENABLED — показывать блок отзывов
|
||||
// BLOG_ENABLED — включать ссылки на блог в навигации
|
||||
define('LEAD_MAGNET_ENABLED', false);
|
||||
define('LEAD_MAGNET_TEXT', 'Оставьте заявку и получите чек-лист «5 скрытых угроз вашей безопасности»');
|
||||
define('TESTIMONIALS_ENABLED', false);
|
||||
define('BLOG_ENABLED', true);
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
/**
|
||||
* ============================================
|
||||
* AegisOne Engineering — Подключение к БД
|
||||
* ============================================
|
||||
*
|
||||
* Поддерживает MySQL и PostgreSQL.
|
||||
* Переключатель: DB_TYPE ('mysql' или 'pgsql')
|
||||
*/
|
||||
|
||||
/** Тип БД: 'mysql' или 'pgsql' */
|
||||
define('DB_TYPE', 'pgsql');
|
||||
|
||||
/** Хост БД */
|
||||
define('DB_HOST', 'localhost');
|
||||
|
||||
/** Порт БД (5432 для PostgreSQL, 3306 для MySQL) */
|
||||
define('DB_PORT', '5432');
|
||||
|
||||
/** Имя базы данных */
|
||||
define('DB_NAME', 'aegisone');
|
||||
|
||||
/** Пользователь БД */
|
||||
define('DB_USER', 'aegisone');
|
||||
|
||||
/** Пароль пользователя БД */
|
||||
define('DB_PASS', 'aegisone_pass');
|
||||
|
||||
/** Кодировка соединения */
|
||||
define('DB_CHARSET', 'utf8');
|
||||
@@ -0,0 +1,433 @@
|
||||
-- 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`;
|
||||
@@ -0,0 +1,170 @@
|
||||
-- ============================================
|
||||
-- AegisOne Engineering — Combined Migration 2026-05-16
|
||||
-- ============================================
|
||||
-- 1. Blog categories: English → Russian
|
||||
-- 2. SLA: response_time_hours, contract_number, description
|
||||
-- 3. Customers table + links to objects & contracts
|
||||
-- 4. Dynamic questionnaire items
|
||||
|
||||
-- ============================================
|
||||
-- 1. Blog ENUM update
|
||||
-- ============================================
|
||||
ALTER TABLE `blog_posts` MODIFY `category` ENUM(
|
||||
'audit', 'sla', 'incident', 'supervision',
|
||||
'documentation', 'risk', 'cases'
|
||||
) NOT NULL DEFAULT 'audit';
|
||||
|
||||
UPDATE `blog_posts` SET category = 'audit' WHERE category = 'risk-engineering';
|
||||
UPDATE `blog_posts` SET category = 'sla' WHERE category = 'sla-service';
|
||||
UPDATE `blog_posts` SET category = 'incident' WHERE category = 'incident-cases';
|
||||
UPDATE `blog_posts` SET category = 'supervision' WHERE category = 'infrastructure-deep-dive';
|
||||
UPDATE `blog_posts` SET category = 'documentation' WHERE category = 'compliance-mchs';
|
||||
UPDATE `blog_posts` SET category = 'risk' WHERE category = 'economics-security';
|
||||
UPDATE `blog_posts` SET category = 'cases' WHERE category = 'case-studies';
|
||||
|
||||
-- ============================================
|
||||
-- 2. SLA fields
|
||||
-- ============================================
|
||||
ALTER TABLE `sla_contracts`
|
||||
ADD COLUMN IF NOT EXISTS `response_time_hours` decimal(5,1) DEFAULT NULL AFTER `response_time_p3`,
|
||||
ADD COLUMN IF NOT EXISTS `contract_number` varchar(50) DEFAULT '' AFTER `id`,
|
||||
ADD COLUMN IF NOT EXISTS `description` text DEFAULT NULL AFTER `contract_number`;
|
||||
|
||||
-- ============================================
|
||||
-- 3. Customers table
|
||||
-- ============================================
|
||||
CREATE TABLE IF NOT EXISTS `customers` (
|
||||
`id` int UNSIGNED AUTO_INCREMENT PRIMARY KEY,
|
||||
`name` varchar(255) NOT NULL,
|
||||
`inn` varchar(12) DEFAULT '',
|
||||
`kpp` varchar(9) DEFAULT '',
|
||||
`legal_address` varchar(500) DEFAULT '',
|
||||
`contact_person` varchar(255) DEFAULT '',
|
||||
`contact_phone` varchar(50) DEFAULT '',
|
||||
`contact_email` varchar(255) DEFAULT '',
|
||||
`status` enum('active','inactive','prospect') NOT NULL DEFAULT 'active',
|
||||
`notes` text DEFAULT NULL,
|
||||
`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_status` (`status`),
|
||||
INDEX `idx_inn` (`inn`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- Add customer_id to objects (skip if column exists)
|
||||
SET @col_exists = (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='objects' AND COLUMN_NAME='customer_id');
|
||||
SET @sql = IF(@col_exists=0,
|
||||
'ALTER TABLE `objects` ADD COLUMN `customer_id` int UNSIGNED DEFAULT NULL AFTER `id`, ADD INDEX `idx_customer` (`customer_id`)',
|
||||
'SELECT 1'
|
||||
);
|
||||
PREPARE stmt FROM @sql;
|
||||
EXECUTE stmt;
|
||||
DEALLOCATE PREPARE stmt;
|
||||
|
||||
-- Add FK objects→customers (skip if exists)
|
||||
SET @fk_exists = (SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='objects' AND CONSTRAINT_NAME='fk_object_customer');
|
||||
SET @sql = IF(@fk_exists=0,
|
||||
'ALTER TABLE `objects` ADD CONSTRAINT `fk_object_customer` FOREIGN KEY (`customer_id`) REFERENCES `customers`(`id`) ON DELETE SET NULL ON UPDATE CASCADE',
|
||||
'SELECT 1'
|
||||
);
|
||||
PREPARE stmt FROM @sql;
|
||||
EXECUTE stmt;
|
||||
DEALLOCATE PREPARE stmt;
|
||||
|
||||
-- Add customer_id to sla_contracts (skip if column exists)
|
||||
SET @col_exists = (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='sla_contracts' AND COLUMN_NAME='customer_id');
|
||||
SET @sql = IF(@col_exists=0,
|
||||
'ALTER TABLE `sla_contracts` ADD COLUMN `customer_id` int UNSIGNED DEFAULT NULL AFTER `id`, ADD INDEX `idx_customer` (`customer_id`)',
|
||||
'SELECT 1'
|
||||
);
|
||||
PREPARE stmt FROM @sql;
|
||||
EXECUTE stmt;
|
||||
DEALLOCATE PREPARE stmt;
|
||||
|
||||
-- Add FK sla_contracts→customers (skip if exists)
|
||||
SET @fk_exists = (SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='sla_contracts' AND CONSTRAINT_NAME='fk_sla_customer');
|
||||
SET @sql = IF(@fk_exists=0,
|
||||
'ALTER TABLE `sla_contracts` ADD CONSTRAINT `fk_sla_customer` FOREIGN KEY (`customer_id`) REFERENCES `customers`(`id`) ON DELETE SET NULL ON UPDATE CASCADE',
|
||||
'SELECT 1'
|
||||
);
|
||||
PREPARE stmt FROM @sql;
|
||||
EXECUTE stmt;
|
||||
DEALLOCATE PREPARE stmt;
|
||||
|
||||
-- Migrate existing client_name from sla_contracts to customers
|
||||
INSERT IGNORE INTO `customers` (`name`, `status`, `created_at`)
|
||||
SELECT DISTINCT client_name, 'active', NOW()
|
||||
FROM `sla_contracts`
|
||||
WHERE client_name != '' AND client_name IS NOT NULL;
|
||||
|
||||
-- Link sla_contracts to customers
|
||||
UPDATE `sla_contracts` sc
|
||||
JOIN `customers` c ON c.name = sc.client_name
|
||||
SET sc.customer_id = c.id
|
||||
WHERE sc.client_name != '' AND sc.client_name IS NOT NULL AND sc.customer_id IS NULL;
|
||||
|
||||
-- ============================================
|
||||
-- 4. Dynamic questionnaire items
|
||||
-- ============================================
|
||||
CREATE TABLE IF NOT EXISTS `questionnaire_items` (
|
||||
`id` int UNSIGNED AUTO_INCREMENT PRIMARY KEY,
|
||||
`step` int UNSIGNED NOT NULL DEFAULT 1,
|
||||
`section` varchar(100) NOT NULL DEFAULT '',
|
||||
`question_key` varchar(100) NOT NULL,
|
||||
`label` varchar(255) NOT NULL,
|
||||
`type` enum('text','number','select','radio','checkbox','textarea') NOT NULL DEFAULT 'text',
|
||||
`options` text DEFAULT NULL COMMENT 'JSON array of options for select/radio',
|
||||
`required` tinyint(1) NOT NULL DEFAULT 0,
|
||||
`sort_order` int UNSIGNED NOT NULL DEFAULT 0,
|
||||
`is_active` tinyint(1) NOT NULL DEFAULT 1,
|
||||
`help_text` varchar(500) DEFAULT '',
|
||||
`created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
INDEX `idx_step` (`step`),
|
||||
INDEX `idx_key` (`question_key`),
|
||||
INDEX `idx_sort` (`sort_order`),
|
||||
UNIQUE KEY `uq_key` (`question_key`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
INSERT INTO `questionnaire_items` (`step`, `section`, `question_key`, `label`, `type`, `options`, `required`, `sort_order`, `help_text`) VALUES
|
||||
(1, 'Коммерческий профиль объекта', 'object_name', 'Название организации / объекта', 'text', NULL, 1, 1, ''),
|
||||
(1, 'Коммерческий профиль объекта', 'object_type', 'Тип объекта', 'select', '["","Гостиница","Склад","Производство","ТЦ","Офис","БЦ","Медицина","Образование","Другое"]', 0, 2, ''),
|
||||
(1, 'Коммерческий профиль объекта', 'address', 'Адрес объекта', 'text', NULL, 0, 3, ''),
|
||||
(1, 'Коммерческий профиль объекта', 'area', 'Площадь (м²)', 'number', NULL, 0, 4, ''),
|
||||
(1, 'Коммерческий профиль объекта', 'employees', 'Количество сотрудников', 'number', NULL, 0, 5, ''),
|
||||
(1, 'Коммерческий профиль объекта', 'contact_person', 'Контактное лицо', 'text', NULL, 0, 6, ''),
|
||||
(1, 'Коммерческий профиль объекта', 'contact_phone', 'Телефон', 'text', NULL, 0, 7, ''),
|
||||
(1, 'Коммерческий профиль объекта', 'region_factor', 'Региональный коэффициент', 'select', '{"1.0":"Краснодар (1.0)","1.1":"Краснодарский край (1.1)","1.3":"РФ (1.3)","1.6":"РФ удалённые (1.6)","1.8":"Москва (1.8)"}', 0, 8, ''),
|
||||
(2, 'Видеонаблюдение', 'has_video', 'Есть система видеонаблюдения?', 'radio', '{"1":"Да","0":"Нет"}', 0, 1, ''),
|
||||
(2, 'Видеонаблюдение', 'camera_count', 'Количество камер', 'number', NULL, 0, 2, ''),
|
||||
(2, 'Видеонаблюдение', 'video_type', 'Тип системы', 'select', '["","ip","analog","mixed"]', 0, 3, ''),
|
||||
(2, 'Видеонаблюдение', 'archive_depth', 'Глубина архива', 'select', '{"7":"7 дней","14":"14 дней","30":"30+ дней"}', 0, 4, ''),
|
||||
(2, 'СКУД', 'has_acs', 'Есть система СКУД?', 'radio', '{"1":"Да","0":"Нет"}', 0, 5, ''),
|
||||
(2, 'СКУД', 'access_points', 'Точек доступа', 'number', NULL, 0, 6, ''),
|
||||
(2, 'СКУД', 'acs_vendor', 'Производитель СКУД', 'text', NULL, 0, 7, ''),
|
||||
(2, 'Пожарная сигнализация', 'has_fire', 'Есть пожарная сигнализация?', 'radio', '{"1":"Да","0":"Нет"}', 0, 8, ''),
|
||||
(2, 'Пожарная сигнализация', 'fire_type', 'Сложность системы', 'select', '{"simple":"Простая","medium":"Средняя","complex":"Сложная (>5000 м²)"}', 0, 9, ''),
|
||||
(2, 'Инфраструктура', 'server_state', 'Состояние сервера', 'select', '{"ok":"Нормальный","weak":"Слабый","none":"Нет"}', 0, 10, ''),
|
||||
(2, 'Инфраструктура', 'network_state', 'Состояние сети', 'select', '{"stable":"Стабильная","partial":"Частично","unstable":"Нестабильная"}', 0, 11, ''),
|
||||
(2, 'Инфраструктура', 'power_state', 'Электропитание (UPS)', 'select', '{"ok":"Нормальное","weak":"Слабый UPS","none":"Нет UPS"}', 0, 12, ''),
|
||||
(3, 'Эксплуатационная модель', 'service_state', 'Как обслуживается объект сейчас?', 'select', '{"none":"Не обслуживается","irregular":"Нерегулярно","formal":"Формальный подрядчик","sla":"Есть SLA"}', 0, 1, ''),
|
||||
(3, 'Эксплуатационная модель', 'has_regulations', 'Есть ли регламент?', 'checkbox', NULL, 0, 2, ''),
|
||||
(3, 'Эксплуатационная модель', 'problems', 'Отметьте частые проблемы', 'checkbox', '["Не работают камеры","Пропадает архив","Зависает СКУД","Ошибки пожарки","Нет реакции подрядчика","Нет понимания состояния систем"]', 0, 3, ''),
|
||||
(3, 'Эксплуатационная модель', 'resolution_time', 'Среднее время устранения', 'select', '{"2h":"До 2 часов","24h":"До суток","days":"Несколько дней"}', 0, 4, ''),
|
||||
(3, 'Эксплуатационная модель', 'controller', 'Кто контролирует систему?', 'select', '{"engineer":"Штатный инженер","contractor":"Подрядчик","nobody":"Никто"}', 0, 5, ''),
|
||||
(4, 'Risk Assessment', 'no_archive', 'Нет архива видеонаблюдения (+25)', 'checkbox', NULL, 0, 1, ''),
|
||||
(4, 'Risk Assessment', 'no_power', 'Нет резервного питания (+20)', 'checkbox', NULL, 0, 2, ''),
|
||||
(4, 'Risk Assessment', 'no_regulations', 'Нет регламента обслуживания (+15)', 'checkbox', NULL, 0, 3, ''),
|
||||
(4, 'Risk Assessment', 'frequent_failures', 'Частые сбои систем (+20)', 'checkbox', NULL, 0, 4, ''),
|
||||
(4, 'Risk Assessment', 'no_documentation', 'Нет документации (+10)', 'checkbox', NULL, 0, 5, ''),
|
||||
(4, 'Risk Assessment', 'consequences', 'Потенциальные последствия', 'checkbox', '["loss_of_evidence","shutdown","fines","no_investigation","access_fail"]', 0, 6, ''),
|
||||
(4, 'Risk Assessment', 'confidence', 'Уровень уверенности в системе', 'select', '{"high":"Высокая","medium":"Средняя","low":"Низкая"}', 0, 7, ''),
|
||||
(5, 'Расчёт SLA', 'sla_level', 'Предпочтительный уровень обслуживания', 'select', '{"start":"Базовый (Start SLA)","business":"Стандарт (Business SLA)","enterprise":"Расширенный (Enterprise SLA)"}', 0, 1, ''),
|
||||
(5, 'Расчёт SLA', 'visit_frequency', 'Интенсивность обслуживания', 'select', '{"1":"1 выезд / мес","2":"2 выезда / мес","incident":"По инцидентам"}', 0, 2, ''),
|
||||
(5, 'Расчёт SLA', 'reaction_time', 'Требуемое время реакции', 'select', '{"24":"24 часа","4":"4 часа","2":"2 часа"}', 0, 3, ''),
|
||||
(5, 'Расчёт SLA', 'extra_247', '24/7 поддержка', 'checkbox', NULL, 0, 4, ''),
|
||||
(5, 'Расчёт SLA', 'extra_emergency', 'Аварийные выезды', 'checkbox', NULL, 0, 5, ''),
|
||||
(5, 'Расчёт SLA', 'extra_audit', 'Аудит', 'checkbox', NULL, 0, 6, ''),
|
||||
(5, 'Расчёт SLA', 'extra_docs', 'Документация', 'checkbox', NULL, 0, 7, ''),
|
||||
(5, 'Расчёт SLA', 'extra_contractors', 'Контроль подрядчиков', 'checkbox', NULL, 0, 8, '')
|
||||
ON DUPLICATE KEY UPDATE `id`=`id`;
|
||||
@@ -0,0 +1,485 @@
|
||||
Ниже — система KPI, которая превращает инженеров и техников из “выездных исполнителей” в управляемую часть инженерной SLA-модели AegisOne Engineering.
|
||||
|
||||
Главная цель системы:
|
||||
|
||||
> не “оценивать занятость”, а измерять качество эксплуатации, скорость реакции и снижение рисков объекта
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
0. ПРИНЦИП СИСТЕМЫ KPI
|
||||
|
||||
Ты НЕ измеряешь:
|
||||
|
||||
сколько выездов сделал инженер
|
||||
|
||||
сколько он “починил”
|
||||
|
||||
|
||||
Ты измеряешь:
|
||||
|
||||
1) надежность объектов
|
||||
|
||||
2) соблюдение SLA
|
||||
|
||||
3) качество диагностики
|
||||
|
||||
4) снижение повторных инцидентов
|
||||
|
||||
|
||||
---
|
||||
|
||||
1. СТРУКТУРА KPI (3 УРОВНЯ)
|
||||
|
||||
2. Операционный KPI (ежедневный)
|
||||
3. SLA KPI (контрактный)
|
||||
4. Инженерный KPI качества (экспертный)
|
||||
|
||||
|
||||
---
|
||||
|
||||
2. ОПЕРАЦИОННЫЙ KPI (Execution KPI)
|
||||
|
||||
Это “что сделал инженер”.
|
||||
|
||||
|
||||
---
|
||||
|
||||
KPI 1: Время реакции (Response Time)
|
||||
|
||||
Формула:
|
||||
|
||||
RT = (фактическое время реакции / SLA время реакции)
|
||||
|
||||
|
||||
---
|
||||
|
||||
Оценка:
|
||||
|
||||
RT Оценка
|
||||
|
||||
≤ 1.0 норма
|
||||
1.0–1.2 допустимо
|
||||
> 1.2 нарушение
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Пример:
|
||||
|
||||
SLA: 2 часа
|
||||
|
||||
факт: 3 часа
|
||||
|
||||
|
||||
RT = 3 / 2 = 1.5 → ❌ нарушение
|
||||
|
||||
|
||||
---
|
||||
|
||||
KPI 2: Время устранения (Resolution Time)
|
||||
|
||||
TTR = фактическое время устранения / нормативное время
|
||||
|
||||
|
||||
---
|
||||
|
||||
Важно:
|
||||
|
||||
Норматив зависит от типа инцидента:
|
||||
|
||||
P1 (критический) — 2–6 часов
|
||||
|
||||
P2 — до 24 часов
|
||||
|
||||
P3 — до 3 дней
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
KPI 3: Закрытие заявок в SLA
|
||||
|
||||
SLA Compliance = (заявки в SLA / все заявки) × 100%
|
||||
|
||||
|
||||
---
|
||||
|
||||
Норма:
|
||||
|
||||
≥ 95% — отлично
|
||||
|
||||
90–95% — допустимо
|
||||
|
||||
< 90% — проблема инженера
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
KPI 4: Повторные обращения (Reopen Rate)
|
||||
|
||||
RR = (повторные заявки / общее число заявок) × 100%
|
||||
|
||||
|
||||
---
|
||||
|
||||
Норма:
|
||||
|
||||
≤ 5% — хорошо
|
||||
|
||||
5–10% — средне
|
||||
|
||||
> 10% — плохая диагностика
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
3. SLA KPI (контрактный уровень)
|
||||
|
||||
|
||||
---
|
||||
|
||||
KPI 5: Выполнение SLA по объектам
|
||||
|
||||
Object SLA = (объекты без нарушений SLA / все объекты) × 100%
|
||||
|
||||
|
||||
---
|
||||
|
||||
Норма:
|
||||
|
||||
≥ 95% — стабильная сеть объектов
|
||||
|
||||
< 90% — системная проблема команды
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
KPI 6: Доступность систем (System Uptime)
|
||||
|
||||
Uptime = (время работы системы / общее время) × 100%
|
||||
|
||||
|
||||
---
|
||||
|
||||
Цель:
|
||||
|
||||
99%+ для критических объектов
|
||||
|
||||
97–99% допустимо
|
||||
|
||||
< 97% — риск SLA разрыва
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
4. ИНЖЕНЕРНЫЙ KPI (КАЧЕСТВО ЭКСПЕРТИЗЫ)
|
||||
|
||||
Это ключевой уровень, который отличает тебя от монтажников.
|
||||
|
||||
|
||||
---
|
||||
|
||||
KPI 7: Точность диагностики
|
||||
|
||||
Accuracy = (подтвержденные неисправности / выявленные) × 100%
|
||||
|
||||
|
||||
---
|
||||
|
||||
Пример:
|
||||
|
||||
выявил 10 проблем
|
||||
|
||||
9 подтвердились
|
||||
|
||||
|
||||
→ 90%
|
||||
|
||||
|
||||
---
|
||||
|
||||
Норма:
|
||||
|
||||
≥ 85% — хорошо
|
||||
|
||||
< 80% — инженер слабый
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
KPI 8: Глубина диагностики (Risk Coverage Score)
|
||||
|
||||
Оценивает, насколько инженер видит системные риски.
|
||||
|
||||
|
||||
---
|
||||
|
||||
Формула (балльная система):
|
||||
|
||||
Каждый объект оценивается по 5 зонам:
|
||||
|
||||
видео
|
||||
|
||||
СКУД
|
||||
|
||||
пожарка
|
||||
|
||||
питание
|
||||
|
||||
сеть
|
||||
|
||||
|
||||
RCS = (проверенные зоны / 5) × 100%
|
||||
|
||||
|
||||
---
|
||||
|
||||
Норма:
|
||||
|
||||
100% — стандарт AegisOne
|
||||
|
||||
< 80% — поверхностная работа
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
KPI 9: Снижение повторных инцидентов
|
||||
|
||||
IRR = ((инциденты до - инциденты после) / до) × 100%
|
||||
|
||||
|
||||
---
|
||||
|
||||
Это ключевой KPI бизнеса
|
||||
|
||||
|
||||
---
|
||||
|
||||
5. ФИНАНСОВЫЙ KPI ИНЖЕНЕРА
|
||||
|
||||
|
||||
---
|
||||
|
||||
KPI 10: Доход на инженера (Revenue per Engineer)
|
||||
|
||||
RPE = общий SLA доход / количество инженеров
|
||||
|
||||
|
||||
---
|
||||
|
||||
Норма:
|
||||
|
||||
500k – слабая загрузка
|
||||
|
||||
800k – норм
|
||||
|
||||
1.2M+ – сильная модель
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
6. ИТОГОВЫЙ ИНДЕКС ИНЖЕНЕРА (ENGINEER SCORE)
|
||||
|
||||
Это твой главный инструмент управления.
|
||||
|
||||
|
||||
---
|
||||
|
||||
Формула:
|
||||
|
||||
ES =
|
||||
(0.25 × SLA Compliance) +
|
||||
(0.20 × Response Time Score) +
|
||||
(0.20 × Resolution Time Score) +
|
||||
(0.15 × Diagnosis Accuracy) +
|
||||
(0.10 × Reopen Rate Score) +
|
||||
(0.10 × Risk Coverage Score)
|
||||
|
||||
|
||||
---
|
||||
|
||||
Интерпретация:
|
||||
|
||||
Score Уровень
|
||||
|
||||
90–100 Senior Engineer
|
||||
80–89 Strong Engineer
|
||||
70–79 Middle
|
||||
< 70 требует обучения
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
7. ДОПОЛНИТЕЛЬНЫЕ KPI (ОЧЕНЬ ВАЖНЫЕ)
|
||||
|
||||
|
||||
---
|
||||
|
||||
KPI 11: Документирование (Documentation Quality)
|
||||
|
||||
DQ = (полные отчёты / все выезды) × 100%
|
||||
|
||||
|
||||
---
|
||||
|
||||
KPI 12: Качество отчёта (Report Quality Score)
|
||||
|
||||
Оценивается по чек-листу:
|
||||
|
||||
есть ли риски
|
||||
|
||||
есть ли вывод
|
||||
|
||||
есть ли рекомендации
|
||||
|
||||
есть ли фото/фиксация
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
KPI 13: Самостоятельность инженера
|
||||
|
||||
Autonomy = (самостоятельные решения / всего решений) × 100%
|
||||
|
||||
|
||||
---
|
||||
|
||||
8. КАК ЭТО ВЫГЛЯДИТ В CRM
|
||||
|
||||
|
||||
---
|
||||
|
||||
Инженер:
|
||||
- SLA Compliance: 96%
|
||||
- RT: 1.1
|
||||
- TTR: 0.9
|
||||
- Diagnosis: 88%
|
||||
- Reopen: 3%
|
||||
- Score: 91 (Senior)
|
||||
|
||||
|
||||
---
|
||||
|
||||
9. СИСТЕМА МОТИВАЦИИ (ВАЖНО)
|
||||
|
||||
|
||||
---
|
||||
|
||||
БАЗОВАЯ ЛОГИКА:
|
||||
|
||||
фикс оклад
|
||||
|
||||
бонус за KPI
|
||||
|
||||
штрафы только за SLA нарушения
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
БОНУС:
|
||||
|
||||
Score 90+ → +20% к премии
|
||||
Score 80–89 → +10%
|
||||
Score < 80 → без бонуса
|
||||
|
||||
|
||||
---
|
||||
|
||||
10. ГЛАВНЫЙ ПРИНЦИП СИСТЕМЫ
|
||||
|
||||
Ты НЕ платишь за:
|
||||
|
||||
❌ “работу”
|
||||
❌ “выезды”
|
||||
|
||||
Ты платишь за:
|
||||
|
||||
стабильность инфраструктуры клиента
|
||||
|
||||
|
||||
---
|
||||
|
||||
11. КАК ЭТА СИСТЕМА МАСШТАБИРУЕТ БИЗНЕС
|
||||
|
||||
|
||||
---
|
||||
|
||||
1 инженер = управляемая единица SLA
|
||||
|
||||
Ты можешь:
|
||||
|
||||
добавлять инженеров
|
||||
|
||||
сравнивать эффективность
|
||||
|
||||
масштабировать регионы
|
||||
|
||||
контролировать качество без присутствия
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
12. СВЯЗЬ С ТВОЕЙ БИЗНЕС-МОДЕЛЬЮ
|
||||
|
||||
|
||||
---
|
||||
|
||||
KPI инженера
|
||||
↓
|
||||
качество SLA
|
||||
↓
|
||||
удержание клиентов
|
||||
↓
|
||||
MRR рост
|
||||
↓
|
||||
масштаб компании
|
||||
|
||||
|
||||
---
|
||||
|
||||
13. СЛЕДУЮЩИЙ УРОВЕНЬ (если продолжать систему)
|
||||
|
||||
Я могу дальше собрать:
|
||||
|
||||
систему грейдов инженеров (Junior → Lead → Chief)
|
||||
|
||||
модель расчёта зарплаты под KPI
|
||||
|
||||
автоматическую таблицу KPI в Excel/Notion
|
||||
|
||||
SLA dashboard (как у IT-компаний)
|
||||
|
||||
систему контроля качества через аудит отчётов
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
ИТОГ
|
||||
|
||||
Ты получил не “мотивацию сотрудников”.
|
||||
|
||||
Ты получил:
|
||||
|
||||
> систему управления инженерной эксплуатационной компанией через измеримые риски и SLA
|
||||
|
||||
|
||||
|
||||
Это уровень компаний, которые продают не услуги — а надежность инфраструктуры бизнеса.
|
||||
@@ -0,0 +1,520 @@
|
||||
Ты сейчас описываешь переход от “владельца инженерной фирмы” к роли:
|
||||
|
||||
операционного директора инженерной системы (Engineering Operations System Owner)
|
||||
|
||||
В такой модели ты уже не контролируешь людей напрямую — ты контролируешь поток рисков, денег, SLA и загрузки системы.
|
||||
|
||||
Я разложу это как управленческую “панель управления” (CEO Dashboard), разделив на:
|
||||
|
||||
1. критически важные метрики (must have)
|
||||
|
||||
|
||||
2. важные (should have)
|
||||
|
||||
|
||||
3. полезные (nice to have)
|
||||
|
||||
|
||||
4. формулы
|
||||
|
||||
|
||||
5. графики и визуализации
|
||||
|
||||
|
||||
6. как это связывается в одну систему управления
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
1. КРИТИЧЕСКИ ВАЖНЫЕ ПАРАМЕТРЫ (CEO CORE CONTROL LAYER)
|
||||
|
||||
Это то, без чего ты не управляешь компанией, а просто “наблюдаешь бизнес”.
|
||||
|
||||
|
||||
---
|
||||
|
||||
1.1 MRR / ARR (регулярный доход SLA)
|
||||
|
||||
Формула:
|
||||
|
||||
MRR = Σ (все SLA контракты / 12)
|
||||
ARR = MRR × 12
|
||||
|
||||
|
||||
---
|
||||
|
||||
Почему это главное:
|
||||
|
||||
Ты продаёшь не монтаж, а:
|
||||
|
||||
> стабильность объектов
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
График:
|
||||
|
||||
📈 линия роста MRR по месяцам
|
||||
📊 разбивка по типам объектов
|
||||
|
||||
|
||||
---
|
||||
|
||||
Управленческая логика:
|
||||
|
||||
если MRR растёт → система здорова
|
||||
|
||||
если нет → маркетинг/воронка сломана
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
1.2 RETENTION RATE (удержание клиентов)
|
||||
|
||||
Формула:
|
||||
|
||||
Retention = (клиенты в конце периода / клиенты в начале) × 100%
|
||||
|
||||
|
||||
---
|
||||
|
||||
Норма:
|
||||
|
||||
95–100% = отлично
|
||||
|
||||
85–95% = нормально
|
||||
|
||||
<85% = проблема в SLA
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
График:
|
||||
|
||||
📉 “утечка клиентов по месяцам”
|
||||
|
||||
|
||||
---
|
||||
|
||||
Интерпретация:
|
||||
|
||||
Если падает retention — проблема не в продажах, а в:
|
||||
|
||||
инженерах
|
||||
|
||||
SLA
|
||||
|
||||
качестве реакции
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
1.3 SLA COMPLIANCE (исполнение контрактов)
|
||||
|
||||
Формула:
|
||||
|
||||
SLA Compliance = (выполненные заявки в SLA / все заявки) × 100%
|
||||
|
||||
|
||||
---
|
||||
|
||||
Норма:
|
||||
|
||||
95–99% = система стабильна
|
||||
|
||||
<90% = начинаются разрывы контрактов
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
График:
|
||||
|
||||
📊 compliance по инженерам / регионам
|
||||
|
||||
|
||||
---
|
||||
|
||||
1.4 COST PER SLA OBJECT (стоимость обслуживания объекта)
|
||||
|
||||
Формула:
|
||||
|
||||
Cost per Object = (ФОТ + выезды + оборудование + накладные) / количество объектов
|
||||
|
||||
|
||||
---
|
||||
|
||||
Почему важно:
|
||||
|
||||
Ты должен видеть:
|
||||
|
||||
> объект приносит деньги или сжигает ресурс
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
График:
|
||||
|
||||
📊 распределение стоимости по типам объектов
|
||||
|
||||
|
||||
---
|
||||
|
||||
1.5 ENGINEER PRODUCTIVITY (производительность инженера)
|
||||
|
||||
Формула:
|
||||
|
||||
EP = SLA Revenue / количество инженеров
|
||||
|
||||
|
||||
---
|
||||
|
||||
Или глубже:
|
||||
|
||||
EP2 = (закрытые заявки × сложность) / часы работы
|
||||
|
||||
|
||||
---
|
||||
|
||||
График:
|
||||
|
||||
📊 эффективность по инженерам (ranking)
|
||||
|
||||
|
||||
---
|
||||
|
||||
2. ВАЖНЫЕ ПАРАМЕТРЫ (OPTIMIZATION LAYER)
|
||||
|
||||
Это влияет на прибыль, но не ломает систему сразу.
|
||||
|
||||
|
||||
---
|
||||
|
||||
2.1 LEAD → SLA CONVERSION RATE
|
||||
|
||||
Формула:
|
||||
|
||||
Conversion = SLA contracts / all qualified leads
|
||||
|
||||
|
||||
---
|
||||
|
||||
График:
|
||||
|
||||
📈 воронка: лиды → аудит → SLA
|
||||
|
||||
|
||||
---
|
||||
|
||||
Диагностика:
|
||||
|
||||
низкая конверсия → проблема продаж/аудита
|
||||
|
||||
высокая → система сильная
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
2.2 AVERAGE SLA CONTRACT VALUE
|
||||
|
||||
Формула:
|
||||
|
||||
ARPC = Total SLA revenue / number of contracts
|
||||
|
||||
|
||||
---
|
||||
|
||||
График:
|
||||
|
||||
📊 средний чек по объектам
|
||||
|
||||
|
||||
---
|
||||
|
||||
2.3 INCIDENT RATE (частота аварий)
|
||||
|
||||
Формула:
|
||||
|
||||
IR = incidents / objects
|
||||
|
||||
|
||||
---
|
||||
|
||||
Почему важно:
|
||||
|
||||
Показывает:
|
||||
|
||||
> реальное качество эксплуатации
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
2.4 REOPEN RATE (повторные заявки)
|
||||
|
||||
Reopen = повторные обращения / все обращения
|
||||
|
||||
|
||||
---
|
||||
|
||||
Если растёт:
|
||||
|
||||
→ инженер плохо диагностирует
|
||||
|
||||
|
||||
---
|
||||
|
||||
3. ПОЛЕЗНЫЕ ПАРАМЕТРЫ (NICE TO HAVE)
|
||||
|
||||
Это усиливает контроль, но не критично.
|
||||
|
||||
|
||||
---
|
||||
|
||||
3.1 CUSTOMER SATISFACTION (CSAT)
|
||||
|
||||
CSAT = (положительные оценки / все оценки) × 100%
|
||||
|
||||
|
||||
---
|
||||
|
||||
3.2 RESPONSE TIME DISTRIBUTION
|
||||
|
||||
Не среднее, а распределение:
|
||||
|
||||
📊 0–2 часа
|
||||
📊 2–6
|
||||
📊 6–24
|
||||
|
||||
|
||||
---
|
||||
|
||||
3.3 EQUIPMENT HEALTH INDEX
|
||||
|
||||
EHI = (исправное оборудование / общее оборудование) × 100%
|
||||
|
||||
|
||||
---
|
||||
|
||||
3.4 ENGINEER UTILIZATION RATE
|
||||
|
||||
Utilization = рабочие часы / доступные часы
|
||||
|
||||
|
||||
---
|
||||
|
||||
4. ГЛАВНЫЙ CEO-ИНДЕКС (SYSTEM HEALTH SCORE)
|
||||
|
||||
Это твоя “панель управления бизнесом”.
|
||||
|
||||
|
||||
---
|
||||
|
||||
Формула:
|
||||
|
||||
SHS =
|
||||
(0.25 × MRR growth) +
|
||||
(0.20 × SLA compliance) +
|
||||
(0.20 × retention) +
|
||||
(0.15 × engineer productivity) +
|
||||
(0.10 × conversion rate) +
|
||||
(0.10 × incident stability)
|
||||
|
||||
|
||||
---
|
||||
|
||||
Интерпретация:
|
||||
|
||||
SHS состояние
|
||||
|
||||
85–100 масштабируемый рост
|
||||
70–85 стабильный бизнес
|
||||
50–70 проблемы в системе
|
||||
<50 системный кризис
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
5. КЛЮЧЕВЫЕ ГРАФИКИ CEO (ДОСКА УПРАВЛЕНИЯ)
|
||||
|
||||
|
||||
---
|
||||
|
||||
5.1 MRR Growth Curve
|
||||
|
||||
📈 рост повторного дохода
|
||||
|
||||
|
||||
---
|
||||
|
||||
5.2 SLA Compliance Heatmap
|
||||
|
||||
🟥 красный = проблемные инженеры
|
||||
🟩 зелёный = сильные
|
||||
|
||||
|
||||
---
|
||||
|
||||
5.3 Client Retention Funnel
|
||||
|
||||
📊 где теряются клиенты
|
||||
|
||||
|
||||
---
|
||||
|
||||
5.4 Engineer Performance Ranking
|
||||
|
||||
📊 топ / низ производительности
|
||||
|
||||
|
||||
---
|
||||
|
||||
5.5 Incident Map
|
||||
|
||||
📍 какие объекты ломаются чаще
|
||||
|
||||
|
||||
---
|
||||
|
||||
5.6 Cost vs Revenue per Object
|
||||
|
||||
📊 прибыльность каждого SLA
|
||||
|
||||
|
||||
---
|
||||
|
||||
6. КРИТИЧЕСКАЯ ЛОГИКА УПРАВЛЕНИЯ
|
||||
|
||||
Ты управляешь не людьми.
|
||||
|
||||
Ты управляешь:
|
||||
|
||||
рисками → SLA → деньгами → нагрузкой инженеров
|
||||
|
||||
|
||||
---
|
||||
|
||||
7. ЧТО ТЕБЕ ОБЯЗАТЕЛЬНО ВИДЕТЬ КАЖДЫЙ ДЕНЬ
|
||||
|
||||
|
||||
---
|
||||
|
||||
DAILY CEO DASHBOARD:
|
||||
|
||||
SLA compliance
|
||||
|
||||
аварии за 24ч
|
||||
|
||||
новые SLA контракты
|
||||
|
||||
просрочки
|
||||
|
||||
перегруз инженеров
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
8. ЧТО ТЕБЕ НУЖНО ВИДЕТЬ РАЗ В НЕДЕЛЮ
|
||||
|
||||
|
||||
---
|
||||
|
||||
MRR рост
|
||||
|
||||
retention
|
||||
|
||||
эффективность инженеров
|
||||
|
||||
конверсия аудита в SLA
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
9. ЧТО СМОТРЕТЬ РАЗ В МЕСЯЦ
|
||||
|
||||
|
||||
---
|
||||
|
||||
прибыльность объектов
|
||||
|
||||
эффективность регионов
|
||||
|
||||
нагрузка команды
|
||||
|
||||
системные сбои
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
10. ГЛАВНЫЙ ПРИНЦИП
|
||||
|
||||
Ты не управляешь:
|
||||
|
||||
❌ монтажами
|
||||
❌ выездами
|
||||
❌ людьми
|
||||
|
||||
|
||||
---
|
||||
|
||||
Ты управляешь:
|
||||
|
||||
системой инженерной надежности объектов бизнеса
|
||||
|
||||
|
||||
---
|
||||
|
||||
11. ЕСЛИ СВЯЗАТЬ ВСЁ В ОДНУ МОДЕЛЬ
|
||||
|
||||
Аудит → Risk Score → SLA цена → контракт → MRR → KPI инженеров → retention → рост
|
||||
|
||||
|
||||
---
|
||||
|
||||
12. ИТОГ
|
||||
|
||||
Ты как CEO должен видеть не “что происходит”, а:
|
||||
|
||||
> где именно в системе возникает прибыль или утечка денег/риска
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
13. ЕСЛИ ДАЛЬШЕ РАЗВИВАТЬ СИСТЕМУ
|
||||
|
||||
Я могу собрать:
|
||||
|
||||
полноценный CEO-dashboard (Excel / Notion / Power BI)
|
||||
|
||||
автоматическую систему расчёта SHS
|
||||
|
||||
дашборд инженеров в реальном времени
|
||||
|
||||
модель прогнозирования MRR на 3–6 месяцев
|
||||
|
||||
систему раннего предупреждения потерь клиентов
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Если коротко:
|
||||
|
||||
ты строишь не компанию — ты строишь управляемую инженерную систему с финансовыми законами внутри неё.
|
||||
@@ -0,0 +1,488 @@
|
||||
Сейчас мы подходим к одному из самых важных этапов.
|
||||
Потому что SEO для тебя — это НЕ “трафик ради трафика”.
|
||||
|
||||
Тебе не нужны:
|
||||
|
||||
- тысячи посетителей;
|
||||
- B2C заявки;
|
||||
- мусорные лиды.
|
||||
|
||||
Тебе нужен:
|
||||
|
||||
# узкий B2B SEO с высокой экспертностью.
|
||||
|
||||
И здесь у тебя огромный шанс, потому что рынок безопасности:
|
||||
|
||||
# SEO делает ужасно.
|
||||
|
||||
Большинство сайтов:
|
||||
|
||||
- про “монтаж камер”;
|
||||
- про оборудование;
|
||||
- про бренды;
|
||||
- про “низкие цены”.
|
||||
|
||||
А ты можешь занять:
|
||||
|
||||
# нишу инженерной эксплуатации.
|
||||
|
||||
---
|
||||
|
||||
# ГЛАВНАЯ СТРАТЕГИЯ SEO
|
||||
|
||||
---
|
||||
|
||||
# НЕ ПРОДАВАТЬ:
|
||||
|
||||
- камеры;
|
||||
- оборудование;
|
||||
- монтаж.
|
||||
|
||||
---
|
||||
|
||||
# ПРОДАВАТЬ:
|
||||
|
||||
- эксплуатацию;
|
||||
- SLA;
|
||||
- аудит;
|
||||
- контроль;
|
||||
- сопровождение;
|
||||
- надежность.
|
||||
|
||||
---
|
||||
|
||||
# ТВОЯ SEO-МОДЕЛЬ
|
||||
|
||||
---
|
||||
|
||||
# УРОВЕНЬ 1
|
||||
|
||||
# КОММЕРЧЕСКИЕ СТРАНИЦЫ
|
||||
|
||||
Это:
|
||||
|
||||
# страницы услуг.
|
||||
|
||||
Они приводят клиентов.
|
||||
|
||||
---
|
||||
|
||||
# УРОВЕНЬ 2
|
||||
|
||||
# ОТРАСЛЕВЫЕ СТРАНИЦЫ
|
||||
|
||||
Это:
|
||||
|
||||
# страницы под конкретный бизнес.
|
||||
|
||||
Они повышают доверие и SEO.
|
||||
|
||||
---
|
||||
|
||||
# УРОВЕНЬ 3
|
||||
|
||||
# ЭКСПЕРТНЫЙ БЛОГ
|
||||
|
||||
Это:
|
||||
|
||||
# двигатель доверия.
|
||||
|
||||
---
|
||||
|
||||
# СТРУКТУРА САЙТА
|
||||
|
||||
Вот идеальная структура для тебя.
|
||||
|
||||
---
|
||||
|
||||
# ГЛАВНАЯ
|
||||
|
||||
## URL:
|
||||
|
||||
`/`
|
||||
|
||||
---
|
||||
|
||||
## Цель:
|
||||
|
||||
- показать позиционирование;
|
||||
- перевести из “монтажников”;
|
||||
- дать B2B доверие.
|
||||
|
||||
---
|
||||
|
||||
# РАЗДЕЛ УСЛУГ
|
||||
|
||||
---
|
||||
|
||||
## `/services/`
|
||||
|
||||
Общая страница услуг.
|
||||
|
||||
---
|
||||
|
||||
# ОСНОВНЫЕ СТРАНИЦЫ
|
||||
|
||||
---
|
||||
|
||||
## `/services/audit/`
|
||||
|
||||
# Технический аудит систем безопасности
|
||||
|
||||
---
|
||||
|
||||
## `/services/sla/`
|
||||
|
||||
# SLA сопровождение объектов
|
||||
|
||||
---
|
||||
|
||||
## `/services/maintenance/`
|
||||
|
||||
# Техническое обслуживание систем безопасности
|
||||
|
||||
---
|
||||
|
||||
## `/services/external-engineer/`
|
||||
|
||||
# Внешний инженер безопасности
|
||||
|
||||
---
|
||||
|
||||
## `/services/recovery/`
|
||||
|
||||
# Восстановление проблемных объектов
|
||||
|
||||
---
|
||||
|
||||
## `/services/fire-alarm/`
|
||||
|
||||
# Обслуживание пожарной сигнализации
|
||||
|
||||
---
|
||||
|
||||
## `/services/video-surveillance/`
|
||||
|
||||
# Эксплуатация видеонаблюдения
|
||||
|
||||
---
|
||||
|
||||
## `/services/access-control/`
|
||||
|
||||
# Обслуживание СКУД
|
||||
|
||||
---
|
||||
|
||||
# ОТРАСЛЕВЫЕ СТРАНИЦЫ
|
||||
|
||||
Это очень важно.
|
||||
|
||||
---
|
||||
|
||||
## `/industries/hotels/`
|
||||
|
||||
# Системы безопасности гостиниц
|
||||
|
||||
---
|
||||
|
||||
## `/industries/logistics/`
|
||||
|
||||
# Склады и логистика
|
||||
|
||||
---
|
||||
|
||||
## `/industries/medical/`
|
||||
|
||||
# Клиники и медцентры
|
||||
|
||||
---
|
||||
|
||||
## `/industries/commercial/`
|
||||
|
||||
# Коммерческая недвижимость
|
||||
|
||||
---
|
||||
|
||||
## `/industries/agro/`
|
||||
|
||||
# Агропредприятия
|
||||
|
||||
---
|
||||
|
||||
# БЛОГ
|
||||
|
||||
---
|
||||
|
||||
## `/blog/`
|
||||
|
||||
---
|
||||
|
||||
# КАТЕГОРИИ
|
||||
|
||||
---
|
||||
|
||||
## `/blog/video/`
|
||||
|
||||
Проблемы видеонаблюдения.
|
||||
|
||||
---
|
||||
|
||||
## `/blog/fire-alarm/`
|
||||
|
||||
Пожарная безопасность.
|
||||
|
||||
---
|
||||
|
||||
## `/blog/sla/`
|
||||
|
||||
Эксплуатация и SLA.
|
||||
|
||||
---
|
||||
|
||||
## `/blog/audit/`
|
||||
|
||||
Технический аудит.
|
||||
|
||||
---
|
||||
|
||||
# ПОЧЕМУ ЭТО ТАК ВАЖНО
|
||||
|
||||
Google и Яндекс сейчас любят:
|
||||
|
||||
- структуру;
|
||||
- экспертность;
|
||||
- тематичность;
|
||||
- глубину.
|
||||
|
||||
---
|
||||
|
||||
# ЧТО НЕЛЬЗЯ ДЕЛАТЬ
|
||||
|
||||
---
|
||||
|
||||
# НЕ ДЕЛАТЬ:
|
||||
|
||||
- 1 страницу “все услуги”;
|
||||
- короткие SEO-тексты;
|
||||
- переспам;
|
||||
- “установка камер Краснодар”.
|
||||
|
||||
Это мусорный рынок.
|
||||
|
||||
---
|
||||
|
||||
# ТВОЯ SEO-СТРАТЕГИЯ
|
||||
|
||||
---
|
||||
|
||||
# НЕ:
|
||||
|
||||
“дешевый монтаж”
|
||||
|
||||
---
|
||||
|
||||
# А:
|
||||
|
||||
# “эксплуатационные риски объектов”.
|
||||
|
||||
---
|
||||
|
||||
# ГЛАВНЫЕ SEO КЛЮЧИ
|
||||
|
||||
Вот где деньги.
|
||||
|
||||
---
|
||||
|
||||
# АУДИТ
|
||||
|
||||
- аудит систем безопасности
|
||||
- технический аудит объекта
|
||||
- аудит видеонаблюдения
|
||||
- аудит пожарной сигнализации
|
||||
- проверка систем безопасности
|
||||
|
||||
---
|
||||
|
||||
# SLA
|
||||
|
||||
- SLA обслуживание
|
||||
- сопровождение систем безопасности
|
||||
- техническое сопровождение объекта
|
||||
- эксплуатация систем безопасности
|
||||
|
||||
---
|
||||
|
||||
# ОБСЛУЖИВАНИЕ
|
||||
|
||||
- обслуживание пожарной сигнализации Краснодар
|
||||
- обслуживание видеонаблюдения Краснодар
|
||||
- обслуживание СКУД Краснодар
|
||||
|
||||
---
|
||||
|
||||
# ОТРАСЛЕВЫЕ
|
||||
|
||||
- системы безопасности гостиниц
|
||||
- обслуживание гостиниц Краснодар
|
||||
- безопасность складов Краснодар
|
||||
|
||||
---
|
||||
|
||||
# ТЕПЕРЬ ГЛАВНОЕ
|
||||
|
||||
# КАК ПИСАТЬ SEO-ТЕКСТЫ
|
||||
|
||||
---
|
||||
|
||||
# ТВОЯ ЦЕЛЬ
|
||||
|
||||
НЕ: “набить ключи”.
|
||||
|
||||
---
|
||||
|
||||
# А:
|
||||
|
||||
# показать инженерную экспертность.
|
||||
|
||||
---
|
||||
|
||||
# ПРИМЕР SEO-ТЕКСТА
|
||||
|
||||
---
|
||||
|
||||
---
|
||||
|
||||
# ТЕПЕРЬ:
|
||||
|
||||
# КОД СТРАНИЦЫ УСЛУГИ
|
||||
|
||||
Например:
|
||||
|
||||
# `/services/audit/index.php`
|
||||
|
||||
---
|
||||
|
||||
---
|
||||
|
||||
# SEO РЕКОМЕНДАЦИИ ПО ТЕХНИЧЕСКОЙ ЧАСТИ
|
||||
|
||||
---
|
||||
|
||||
# ОБЯЗАТЕЛЬНО:
|
||||
|
||||
---
|
||||
|
||||
# 1. ЧПУ URL
|
||||
|
||||
---
|
||||
|
||||
# ХОРОШО:
|
||||
|
||||
`/services/audit/`
|
||||
|
||||
---
|
||||
|
||||
# ПЛОХО:
|
||||
|
||||
`/page.php?id=123`
|
||||
|
||||
---
|
||||
|
||||
# 2. TITLE И DESCRIPTION
|
||||
|
||||
Для каждой страницы.
|
||||
|
||||
---
|
||||
|
||||
# Пример:
|
||||
|
||||
## TITLE:
|
||||
|
||||
Технический аудит систем безопасности в Краснодаре
|
||||
|
||||
---
|
||||
|
||||
## DESCRIPTION:
|
||||
|
||||
Проверка состояния систем безопасности коммерческих объектов. Аудит видеонаблюдения, СКУД и пожарной сигнализации.
|
||||
|
||||
---
|
||||
|
||||
# 3. H1 ТОЛЬКО ОДИН
|
||||
|
||||
Это важно.
|
||||
|
||||
---
|
||||
|
||||
# 4. schema.org
|
||||
|
||||
Очень желательно.
|
||||
|
||||
---
|
||||
|
||||
# 5. СКОРОСТЬ
|
||||
|
||||
Не перегружать:
|
||||
|
||||
- анимацией;
|
||||
- тяжелыми видео;
|
||||
- конструкторами.
|
||||
|
||||
---
|
||||
|
||||
# 6. GEO SEO
|
||||
|
||||
На каждой странице:
|
||||
|
||||
- Краснодар;
|
||||
- Краснодарский край.
|
||||
|
||||
---
|
||||
|
||||
# 7. ВНУТРЕННЯЯ ПЕРЕЛИНКОВКА
|
||||
|
||||
Например:
|
||||
|
||||
- из статьи → на аудит;
|
||||
- из отрасли → на SLA;
|
||||
- из кейса → на услугу.
|
||||
|
||||
---
|
||||
|
||||
# ЧТО ДАСТ РЕАЛЬНЫЙ РОСТ
|
||||
|
||||
---
|
||||
|
||||
# НЕ:
|
||||
|
||||
- покупка ссылок;
|
||||
- SEO-магия.
|
||||
|
||||
---
|
||||
|
||||
# А:
|
||||
|
||||
- экспертные статьи;
|
||||
- кейсы;
|
||||
- отраслевые страницы;
|
||||
- техническая глубина;
|
||||
- регулярность.
|
||||
|
||||
---
|
||||
|
||||
# САМОЕ ВАЖНОЕ
|
||||
|
||||
Ты должен выглядеть:
|
||||
|
||||
# не как “сайт монтажников”.
|
||||
|
||||
А как:
|
||||
|
||||
# инженерная эксплуатационная компания.
|
||||
|
||||
И это:
|
||||
|
||||
- редкость;
|
||||
- слабоконкурентная ниша;
|
||||
- высокий уровень доверия;
|
||||
- хороший B2B SEO.
|
||||
@@ -0,0 +1,795 @@
|
||||
SLA — ЭТО ОСНОВА ТВОЕГО ПЕРЕХОДА ИЗ “МОНТАЖНИКОВ” В B2B-СЕРВИС
|
||||
|
||||
Большинство компаний безопасности в Краснодарском крае:
|
||||
|
||||
“иногда приезжают”;
|
||||
|
||||
“что-то смотрят”;
|
||||
|
||||
“делают отметку”;
|
||||
|
||||
работают хаотично.
|
||||
|
||||
|
||||
SLA делает тебя:
|
||||
|
||||
инженерной сервисной компанией;
|
||||
|
||||
предсказуемым подрядчиком;
|
||||
|
||||
частью эксплуатации бизнеса клиента.
|
||||
|
||||
|
||||
Именно SLA позволяет:
|
||||
|
||||
продавать дороже;
|
||||
|
||||
получать абонентку;
|
||||
|
||||
заходить в сети;
|
||||
|
||||
работать с коммерческой недвижимостью;
|
||||
|
||||
уходить от демпинга.
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
ЧТО ТАКОЕ SLA ПРОСТЫМИ СЛОВАМИ
|
||||
|
||||
SLA (Service Level Agreement)
|
||||
|
||||
это:
|
||||
|
||||
соглашение об уровне сервиса.
|
||||
|
||||
То есть: ты заранее фиксируешь:
|
||||
|
||||
что обслуживаешь;
|
||||
|
||||
как быстро реагируешь;
|
||||
|
||||
что считается аварией;
|
||||
|
||||
что входит в обслуживание;
|
||||
|
||||
какие обязательства у сторон.
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
ПОЧЕМУ B2B ЭТО ЛЮБИТ
|
||||
|
||||
Потому что бизнес покупает:
|
||||
|
||||
предсказуемость;
|
||||
|
||||
контроль;
|
||||
|
||||
ответственность;
|
||||
|
||||
понятные сроки.
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
ТВОЯ ЦЕЛЬ
|
||||
|
||||
НЕ:
|
||||
|
||||
> “мы обслуживаем камеры”
|
||||
|
||||
|
||||
|
||||
А:
|
||||
|
||||
“мы гарантируем работоспособность критической инфраструктуры объекта”.
|
||||
|
||||
|
||||
---
|
||||
|
||||
КАК SLA ПОДНИМАЕТ ТЕБЯ НАД РЫНКОМ
|
||||
|
||||
Без SLA:
|
||||
|
||||
“звоните если что”.
|
||||
|
||||
С SLA:
|
||||
|
||||
регламенты;
|
||||
|
||||
сроки реакции;
|
||||
|
||||
журналирование;
|
||||
|
||||
прозрачность;
|
||||
|
||||
ответственность.
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
ГЛАВНАЯ ОШИБКА
|
||||
|
||||
Многие делают:
|
||||
|
||||
> “приедем в течение суток”.
|
||||
|
||||
|
||||
|
||||
Это НЕ SLA.
|
||||
|
||||
|
||||
---
|
||||
|
||||
НАСТОЯЩИЙ SLA ВКЛЮЧАЕТ
|
||||
|
||||
|
||||
---
|
||||
|
||||
1. КЛАССИФИКАЦИЮ ИНЦИДЕНТОВ
|
||||
|
||||
Например:
|
||||
|
||||
Приоритет Пример Реакция
|
||||
|
||||
P1 Критический Не работает пожарка 2 часа
|
||||
P2 Высокий Нет архива камер 4 часа
|
||||
P3 Средний Частично не работает СКУД 24 часа
|
||||
P4 Низкий Настройка доступа Планово
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
2. ВРЕМЯ РЕАКЦИИ
|
||||
|
||||
Очень важно: не “устранения”.
|
||||
|
||||
А:
|
||||
|
||||
начала работ.
|
||||
|
||||
|
||||
---
|
||||
|
||||
3. РЕГЛАМЕНТНЫЕ РАБОТЫ
|
||||
|
||||
Например:
|
||||
|
||||
ежемесячные проверки;
|
||||
|
||||
тестирование;
|
||||
|
||||
резервное копирование;
|
||||
|
||||
контроль архивов;
|
||||
|
||||
проверка питания;
|
||||
|
||||
чистка;
|
||||
|
||||
тест тревог.
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
4. ОТЧЕТНОСТЬ
|
||||
|
||||
Это критично.
|
||||
|
||||
Ты должен быть:
|
||||
|
||||
“прозрачным подрядчиком”.
|
||||
|
||||
|
||||
---
|
||||
|
||||
5. SLA ПО КАНАЛАМ СВЯЗИ
|
||||
|
||||
Например:
|
||||
|
||||
Telegram;
|
||||
|
||||
email;
|
||||
|
||||
аварийный телефон;
|
||||
|
||||
сервисный портал.
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
6. SLA ПО ДОСТУПНОСТИ
|
||||
|
||||
Вот тут начинаются большие чеки.
|
||||
|
||||
Например:
|
||||
|
||||
Система Целевая доступность
|
||||
|
||||
Пожарка 99.9%
|
||||
Видеонаблюдение 99%
|
||||
СКУД 99%
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
ТЕПЕРЬ ГЛАВНОЕ:
|
||||
|
||||
КАК ТЕБЕ ДЕЛАТЬ SLA В РЕАЛЬНОСТИ
|
||||
|
||||
Тебе НЕ нужен корпоративный монстр.
|
||||
|
||||
Тебе нужна:
|
||||
|
||||
простая инженерная система.
|
||||
|
||||
|
||||
---
|
||||
|
||||
БАЗОВАЯ МОДЕЛЬ SLA ДЛЯ ТЕБЯ
|
||||
|
||||
|
||||
---
|
||||
|
||||
START SLA
|
||||
|
||||
Для:
|
||||
|
||||
небольших объектов;
|
||||
|
||||
офисов;
|
||||
|
||||
клиник;
|
||||
|
||||
магазинов.
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Реакция:
|
||||
|
||||
до 24 часов
|
||||
|
||||
|
||||
---
|
||||
|
||||
Регламент:
|
||||
|
||||
1 раз в месяц.
|
||||
|
||||
|
||||
---
|
||||
|
||||
Что входит:
|
||||
|
||||
проверка состояния;
|
||||
|
||||
диагностика;
|
||||
|
||||
журнал;
|
||||
|
||||
рекомендации;
|
||||
|
||||
консультации.
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Стоимость:
|
||||
|
||||
25–40 тыс ₽/мес
|
||||
|
||||
Для Краснодара — нормально для качественного B2B.
|
||||
|
||||
|
||||
---
|
||||
|
||||
BUSINESS SLA
|
||||
|
||||
Твой основной продукт.
|
||||
|
||||
|
||||
---
|
||||
|
||||
Реакция:
|
||||
|
||||
критическая авария — 4 часа;
|
||||
|
||||
обычная — 24 часа.
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Регламент:
|
||||
|
||||
2–4 раза в месяц.
|
||||
|
||||
|
||||
---
|
||||
|
||||
Входит:
|
||||
|
||||
аварийные выезды;
|
||||
|
||||
удаленная диагностика;
|
||||
|
||||
контроль архива;
|
||||
|
||||
контроль питания;
|
||||
|
||||
фотоотчеты;
|
||||
|
||||
журнал;
|
||||
|
||||
рекомендации;
|
||||
|
||||
сопровождение проверок.
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Стоимость:
|
||||
|
||||
60–120 тыс ₽/мес
|
||||
|
||||
Для:
|
||||
|
||||
гостиниц;
|
||||
|
||||
складов;
|
||||
|
||||
коммерческой недвижимости.
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
ENTERPRISE SLA
|
||||
|
||||
Вот это путь к большим деньгам.
|
||||
|
||||
|
||||
---
|
||||
|
||||
Реакция:
|
||||
|
||||
2 часа
|
||||
|
||||
|
||||
---
|
||||
|
||||
Формат:
|
||||
|
||||
“внешний инженерный отдел”.
|
||||
|
||||
|
||||
---
|
||||
|
||||
Входит:
|
||||
|
||||
постоянный контроль;
|
||||
|
||||
участие в эксплуатации;
|
||||
|
||||
работа с подрядчиками;
|
||||
|
||||
аудит;
|
||||
|
||||
сопровождение модернизаций;
|
||||
|
||||
приемка;
|
||||
|
||||
развитие систем.
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Стоимость:
|
||||
|
||||
180–500 тыс ₽/мес
|
||||
|
||||
|
||||
---
|
||||
|
||||
ВАЖНО:
|
||||
|
||||
SLA НЕЛЬЗЯ ПРОДАВАТЬ КАК “ТО”
|
||||
|
||||
Иначе: ты вернешься в дешевый рынок.
|
||||
|
||||
|
||||
---
|
||||
|
||||
SLA ПРОДАЕТСЯ КАК:
|
||||
|
||||
“управление рисками объекта”.
|
||||
|
||||
|
||||
---
|
||||
|
||||
ПРИМЕР ТЕКСТА ДЛЯ САЙТА
|
||||
|
||||
|
||||
---
|
||||
|
||||
SLA-сопровождение систем безопасности
|
||||
|
||||
Мы работаем по регламентированным SLA-моделям обслуживания.
|
||||
|
||||
Это означает:
|
||||
— фиксированное время реакции;
|
||||
— контроль состояния систем;
|
||||
— прозрачную отчетность;
|
||||
— регламентные проверки;
|
||||
— ответственность за работоспособность инфраструктуры объекта.
|
||||
|
||||
SLA позволяет снизить риски простоев, исключить скрытые неисправности и обеспечить стабильную эксплуатацию систем безопасности.
|
||||
|
||||
Для каждого объекта разрабатывается индивидуальный регламент обслуживания.
|
||||
---
|
||||
|
||||
ПРИМЕР SLA ТАБЛИЦЫ ДЛЯ САЙТА
|
||||
|
||||
|
||||
---
|
||||
|
||||
Приоритет| Описание| Реакция
|
||||
P1| Полный отказ критической системы| до 2 часов
|
||||
P2| Частичная потеря функционала| до 4 часов
|
||||
P3| Некритичная неисправность| до 24 часов
|
||||
P4| Плановые работы и настройки| по графику
|
||||
---
|
||||
|
||||
ТЕПЕРЬ САМОЕ ВАЖНОЕ
|
||||
|
||||
КАК ТЕБЕ СЧИТАТЬ ЦЕНУ SLA
|
||||
|
||||
Не “от количества камер”.
|
||||
|
||||
Это ошибка рынка.
|
||||
|
||||
|
||||
---
|
||||
|
||||
ТВОЯ МОДЕЛЬ ЦЕНООБРАЗОВАНИЯ
|
||||
|
||||
Цена считается по:
|
||||
|
||||
критичности объекта;
|
||||
|
||||
количеству систем;
|
||||
|
||||
SLA;
|
||||
|
||||
расстоянию;
|
||||
|
||||
времени реакции;
|
||||
|
||||
рискам;
|
||||
|
||||
сложности эксплуатации.
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
МОДЕЛЬ ДЛЯ КРАСНОДАРСКОГО КРАЯ
|
||||
|
||||
|
||||
---
|
||||
|
||||
КРАСНОДАР
|
||||
|
||||
Можно:
|
||||
|
||||
быстрые выезды;
|
||||
|
||||
дешевле логистика.
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
СОЧИ
|
||||
|
||||
Цена должна быть:
|
||||
|
||||
выше на 30–50%.
|
||||
|
||||
Из-за:
|
||||
|
||||
логистики;
|
||||
|
||||
сезонности;
|
||||
|
||||
срочности.
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
УДАЛЕННЫЕ РАЙОНЫ
|
||||
|
||||
Нужно:
|
||||
|
||||
отдельное SLA.
|
||||
|
||||
|
||||
---
|
||||
|
||||
Например:
|
||||
|
||||
Базовая реакция:
|
||||
|
||||
24 часа.
|
||||
|
||||
Срочный выезд:
|
||||
|
||||
дополнительная ставка.
|
||||
|
||||
|
||||
---
|
||||
|
||||
КАК СЧИТАТЬ SLA
|
||||
|
||||
Вот модель.
|
||||
|
||||
|
||||
---
|
||||
|
||||
БАЗА
|
||||
|
||||
Например:
|
||||
|
||||
35 000 ₽
|
||||
|
||||
|
||||
---
|
||||
|
||||
ПЛЮС:
|
||||
|
||||
Параметр Доплата
|
||||
|
||||
24/7 доступность +20%
|
||||
SLA 2 часа +35%
|
||||
Удаленный район +15–40%
|
||||
Несколько объектов индивидуально
|
||||
Высокая критичность +25%
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
ПРИМЕР
|
||||
|
||||
Гостиница:
|
||||
|
||||
64 камеры;
|
||||
|
||||
СКУД;
|
||||
|
||||
пожарка;
|
||||
|
||||
архив;
|
||||
|
||||
Краснодар.
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
SLA:
|
||||
|
||||
4 часа.
|
||||
|
||||
|
||||
---
|
||||
|
||||
Цена:
|
||||
|
||||
85–120 тыс ₽/мес
|
||||
|
||||
И это нормальный рынок для качественного сервиса.
|
||||
|
||||
|
||||
---
|
||||
|
||||
ТЕПЕРЬ САМОЕ ВАЖНОЕ
|
||||
|
||||
КАК ТЕБЕ ВЫПОЛНЯТЬ SLA БЕЗ БОЛИ
|
||||
|
||||
|
||||
---
|
||||
|
||||
НЕ БРАТЬ ВСЕХ ПОДРЯД
|
||||
|
||||
Только:
|
||||
|
||||
нормальные объекты;
|
||||
|
||||
нормальные бюджеты;
|
||||
|
||||
адекватные заказчики.
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
НЕ ПРОДАВАТЬ “ДЕШЕВО”
|
||||
|
||||
Иначе SLA развалится.
|
||||
|
||||
|
||||
---
|
||||
|
||||
ОБЯЗАТЕЛЬНО:
|
||||
|
||||
журнал заявок;
|
||||
|
||||
регламент;
|
||||
|
||||
чек-листы;
|
||||
|
||||
фотофиксация;
|
||||
|
||||
история обслуживания.
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
ТЕХНИЧЕСКИ ТЕБЕ НУЖНО
|
||||
|
||||
|
||||
---
|
||||
|
||||
1. HELP DESK
|
||||
|
||||
Минимум:
|
||||
|
||||
Telegram;
|
||||
|
||||
1С;
|
||||
|
||||
Google Sheets.
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Лучше:
|
||||
|
||||
GLPI;
|
||||
|
||||
Zammad;
|
||||
|
||||
Jira Service Desk.
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
2. БАЗА ОБЪЕКТОВ
|
||||
|
||||
Для каждого:
|
||||
|
||||
схемы;
|
||||
|
||||
пароли;
|
||||
|
||||
оборудование;
|
||||
|
||||
IP;
|
||||
|
||||
контакты;
|
||||
|
||||
история.
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
3. ЧЕК-ЛИСТЫ
|
||||
|
||||
Например:
|
||||
|
||||
Видеонаблюдение:
|
||||
|
||||
запись;
|
||||
|
||||
архив;
|
||||
|
||||
питание;
|
||||
|
||||
доступ;
|
||||
|
||||
фокус;
|
||||
|
||||
время.
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
4. SLA-ДОКУМЕНТ
|
||||
|
||||
Это обязательно.
|
||||
|
||||
|
||||
---
|
||||
|
||||
ПРИМЕР СТРУКТУРЫ SLA ДОГОВОРА
|
||||
|
||||
|
||||
---
|
||||
|
||||
1. Предмет SLA
|
||||
|
||||
Исполнитель обеспечивает техническое сопровождение
|
||||
и контроль работоспособности систем безопасности объекта.
|
||||
|
||||
2. Время реакции
|
||||
|
||||
P1 — до 2 часов
|
||||
P2 — до 4 часов
|
||||
P3 — до 24 часов
|
||||
|
||||
3. Регламентные работы
|
||||
|
||||
— диагностика
|
||||
— тестирование
|
||||
— проверка журналов
|
||||
— контроль архива
|
||||
— проверка питания
|
||||
|
||||
4. Отчетность
|
||||
|
||||
По результатам работ предоставляется отчет.
|
||||
|
||||
5. Ограничения SLA
|
||||
|
||||
SLA не распространяется на:
|
||||
— физическое повреждение оборудования
|
||||
— аварии электропитания
|
||||
— действия третьих лиц
|
||||
— форс-мажор
|
||||
---
|
||||
|
||||
ИТОГ
|
||||
|
||||
SLA — это:
|
||||
|
||||
не “дополнение”.
|
||||
|
||||
Это:
|
||||
|
||||
фундамент твоего нового бизнеса.
|
||||
|
||||
Именно SLA:
|
||||
|
||||
выводит тебя из монтажников;
|
||||
|
||||
делает recurring revenue;
|
||||
|
||||
дает стабильность;
|
||||
|
||||
повышает чек;
|
||||
|
||||
позволяет масштабироваться.
|
||||
|
||||
|
||||
И это идеально совпадает с твоим профилем инженера и системного человека.
|
||||
@@ -0,0 +1,934 @@
|
||||
Хорошо, это важный шаг — ты фактически выбираешь архитектуру бренда (brand architecture), а не просто название. От этого зависит:
|
||||
|
||||
как тебя воспринимают (монтажники vs инженерная компания),
|
||||
|
||||
как ты продаёшь SLA,
|
||||
|
||||
насколько легко масштабируешься по РФ.
|
||||
|
||||
|
||||
Я разложу каждый вариант строго по твоей модели:
|
||||
👉 аудит → эксплуатация → SLA → инженерный сервис → масштабирование
|
||||
|
||||
|
||||
---
|
||||
|
||||
1. AegisOne Engineering
|
||||
|
||||
Суть позиционирования:
|
||||
|
||||
инженерная компания полного цикла
|
||||
|
||||
|
||||
---
|
||||
|
||||
Как воспринимается рынком:
|
||||
|
||||
“серьёзная инженерная организация”
|
||||
|
||||
ближе к проектированию / эксплуатации
|
||||
|
||||
высокий уровень доверия B2B
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Сильные стороны:
|
||||
|
||||
подходит под SLA и аудит
|
||||
|
||||
звучит “дорого и системно”
|
||||
|
||||
легко масштабируется на РФ
|
||||
|
||||
не привязан к монтажу
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Слабые стороны:
|
||||
|
||||
не сразу понятно “сервис”
|
||||
|
||||
нужно объяснение через сайт/контент
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Лучше всего подходит для:
|
||||
|
||||
✔ SLA обслуживание
|
||||
✔ аудит объектов
|
||||
✔ эксплуатация систем безопасности
|
||||
✔ B2B рынок (гостиницы, склады, УК)
|
||||
|
||||
|
||||
---
|
||||
|
||||
Итог:
|
||||
|
||||
> ❗ ЛУЧШИЙ ОСНОВНОЙ БРЕНД (ядро компании)
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
2. AegisOne Service
|
||||
|
||||
Суть:
|
||||
|
||||
сервисная эксплуатационная компания
|
||||
|
||||
|
||||
---
|
||||
|
||||
Восприятие:
|
||||
|
||||
обслуживание
|
||||
|
||||
ремонт
|
||||
|
||||
“сервисники”
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Сильные стороны:
|
||||
|
||||
понятный вход для клиентов
|
||||
|
||||
хорошо продаёт обслуживание
|
||||
|
||||
легко объяснить
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Слабые стороны:
|
||||
|
||||
слишком “сервис/ремонт”
|
||||
|
||||
занижает статус инженера
|
||||
|
||||
хуже для крупных B2B объектов
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Лучше для:
|
||||
|
||||
✔ абонентское обслуживание
|
||||
✔ выездной сервис
|
||||
✔ мелкие и средние клиенты
|
||||
✔ поддержка SLA как продукт
|
||||
|
||||
|
||||
---
|
||||
|
||||
Итог:
|
||||
|
||||
> ⚠ можно как подразделение, но не основной бренд
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
3. AegisOne Security Engineering
|
||||
|
||||
Суть:
|
||||
|
||||
инженерия безопасности (очень сильный B2B бренд)
|
||||
|
||||
|
||||
---
|
||||
|
||||
Восприятие:
|
||||
|
||||
высокий уровень экспертизы
|
||||
|
||||
ближе к проектированию и системной безопасности
|
||||
|
||||
звучит “международно”
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Сильные стороны:
|
||||
|
||||
максимальная экспертность
|
||||
|
||||
идеально под аудит и SLA
|
||||
|
||||
хорошо для РФ + будущего выхода за регион
|
||||
|
||||
не “монтажники”
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Слабые стороны:
|
||||
|
||||
длинное название
|
||||
|
||||
чуть тяжеловесно в маркетинге
|
||||
|
||||
требует сокращений (AegisOne SE)
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Лучше для:
|
||||
|
||||
✔ аудит
|
||||
✔ техническая экспертиза
|
||||
✔ корпоративные объекты
|
||||
✔ крупные B2B сделки
|
||||
✔ федеральное масштабирование
|
||||
|
||||
|
||||
---
|
||||
|
||||
Итог:
|
||||
|
||||
> ⭐ ЛУЧШИЙ ДЛЯ ЭКСПЕРТНОСТИ И PREMIUM B2B
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
4. AegisOne Facility Security
|
||||
|
||||
Суть:
|
||||
|
||||
безопасность объектов (facility management)
|
||||
|
||||
|
||||
---
|
||||
|
||||
Восприятие:
|
||||
|
||||
управление объектами
|
||||
|
||||
эксплуатация зданий
|
||||
|
||||
FM-компании уровня “facility management”
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Сильные стороны:
|
||||
|
||||
очень сильный корпоративный сегмент
|
||||
|
||||
подходит для УК, ТЦ, гостиниц
|
||||
|
||||
легко встраивается в FM-рынок
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Слабые стороны:
|
||||
|
||||
менее технический фокус
|
||||
|
||||
может размывать “инженерность”
|
||||
|
||||
ближе к управлению недвижимостью
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Лучше для:
|
||||
|
||||
✔ управляющие компании
|
||||
✔ гостиничные сети
|
||||
✔ торговые центры
|
||||
✔ facility management подрядчики
|
||||
|
||||
|
||||
---
|
||||
|
||||
Итог:
|
||||
|
||||
> ⚠ хорошо как направление, но не ядро
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
5. AegisOne TechService
|
||||
|
||||
Суть:
|
||||
|
||||
техсервис / техническое обслуживание
|
||||
|
||||
|
||||
---
|
||||
|
||||
Восприятие:
|
||||
|
||||
ремонтная служба
|
||||
|
||||
IT/техподдержка стиль
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Сильные стороны:
|
||||
|
||||
простое и понятное
|
||||
|
||||
легко продаётся “в лоб”
|
||||
|
||||
подходит для мелких объектов
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Слабые стороны:
|
||||
|
||||
дешёвое восприятие
|
||||
|
||||
не тянет премиум SLA
|
||||
|
||||
теряет инженерный статус
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Лучше для:
|
||||
|
||||
✔ массовое обслуживание
|
||||
✔ низкий чек рынок
|
||||
✔ быстрые заявки
|
||||
✔ простые сервисные работы
|
||||
|
||||
|
||||
---
|
||||
|
||||
Итог:
|
||||
|
||||
> ❌ не подходит под твою стратегию роста
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
6. РЕКОМЕНТИРУЕМАЯ СТРУКТУРА БРЕНДА (ОПТИМАЛЬНАЯ)
|
||||
|
||||
Вот как это должно выглядеть в системе:
|
||||
|
||||
|
||||
---
|
||||
|
||||
🧠 ГЛАВНЫЙ БРЕНД (основа)
|
||||
|
||||
AegisOne Engineering
|
||||
|
||||
👉 ядро:
|
||||
|
||||
SLA
|
||||
|
||||
аудит
|
||||
|
||||
эксплуатация
|
||||
|
||||
инженерный контроль
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
🔧 СЕРВИСНОЕ ПОДРАЗДЕЛЕНИЕ
|
||||
|
||||
AegisOne Service
|
||||
|
||||
👉 внутри:
|
||||
|
||||
выезды
|
||||
|
||||
ремонт
|
||||
|
||||
поддержка
|
||||
|
||||
реакция по SLA
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
🧪 ЭКСПЕРТНЫЙ КОНТУР
|
||||
|
||||
AegisOne Security Engineering
|
||||
|
||||
👉 используется для:
|
||||
|
||||
сайта экспертного уровня
|
||||
|
||||
презентаций
|
||||
|
||||
коммерческих предложений
|
||||
|
||||
крупных B2B переговоров
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
🏢 ФУТУРОЛОГИЧЕСКИЙ КОНТУР (масштаб)
|
||||
|
||||
AegisOne Facility Security
|
||||
|
||||
👉 когда выйдешь в:
|
||||
|
||||
УК
|
||||
|
||||
сети отелей
|
||||
|
||||
FM-контракты
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
⚙️ ТЕХПОДДЕРЖКА (НЕ ОСНОВНАЯ)
|
||||
|
||||
AegisOne TechService
|
||||
|
||||
👉 можно использовать как:
|
||||
|
||||
внутренний бренд
|
||||
|
||||
дешёвый сегмент (если вдруг нужен)
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
7. ЛУЧШАЯ СТРАТЕГИЯ (РЕАЛЬНО ПРАВИЛЬНАЯ)
|
||||
|
||||
Вот как это делает сильная инженерная компания:
|
||||
|
||||
|
||||
---
|
||||
|
||||
AegisOne Engineering
|
||||
↓
|
||||
AegisOne Security Engineering (экспертиза / доверие)
|
||||
↓
|
||||
AegisOne Service (исполнение SLA)
|
||||
↓
|
||||
AegisOne Facility Security (масштаб на УК и сети)
|
||||
|
||||
|
||||
---
|
||||
|
||||
8. ВАЖНОЕ РЕШЕНИЕ ДЛЯ ТЕБЯ
|
||||
|
||||
Если брать твою стратегию:
|
||||
|
||||
уход от монтажа
|
||||
|
||||
переход в SLA
|
||||
|
||||
рост до 2–3 млн+
|
||||
|
||||
B2B рынок
|
||||
|
||||
экспертность
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
ТОП-1 выбор:
|
||||
|
||||
✔ AegisOne Engineering
|
||||
|
||||
|
||||
---
|
||||
|
||||
ТОП-2 усиление:
|
||||
|
||||
✔ AegisOne Security Engineering
|
||||
|
||||
|
||||
---
|
||||
|
||||
НЕ РЕКОМЕНДУЮ КАК ОСНОВУ:
|
||||
|
||||
Service (снижает статус)
|
||||
|
||||
TechService (дешевит бренд)
|
||||
|
||||
Facility Security (узкая ниша на будущее)
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
9. ЕСЛИ ХОЧЕШЬ ДАЛЬШЕ УСИЛИТЬ БРЕНД
|
||||
|
||||
Я могу собрать тебе следующий уровень:
|
||||
|
||||
нейминг архитектуры сайта (как разложить домены/страницы)
|
||||
|
||||
логотип-систему (как должен выглядеть бренд инженерной компании)
|
||||
|
||||
упаковку КП под каждый бренд
|
||||
|
||||
позиционирование для тендеров
|
||||
|
||||
“как выглядеть как федеральный подрядчик при локальном бизнесе”
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Если коротко:
|
||||
|
||||
> тебе нужен не набор названий, а система уровней доверия
|
||||
|
||||
|
||||
|
||||
И из всех вариантов:
|
||||
|
||||
AegisOne Engineering — фундамент бизнеса.
|
||||
|
||||
---
|
||||
|
||||
Отлично, теперь мы фиксируем **архитектуру компании как инженерной системы**, а не сайта.
|
||||
|
||||
Ты строишь не “фирму услуг”, а:
|
||||
|
||||
# AegisOne Engineering — операционную систему эксплуатации объектов
|
||||
|
||||
Ниже даю тебе:
|
||||
|
||||
1. структуру компании (как она “разложена в голове клиента”)
|
||||
2. все разделы сайта / системы
|
||||
3. документы (шаблоны, которые продают SLA сами)
|
||||
4. сценарии взаимодействия с клиентом
|
||||
5. стандарты (как ты выглядишь как федеральный подрядчик)
|
||||
|
||||
---
|
||||
|
||||
# 1. СТРУКТУРА AEGISONE ENGINEERING
|
||||
|
||||
## 🧠 ЯДРО КОМПАНИИ
|
||||
|
||||
# AegisOne Engineering
|
||||
|
||||
> Инженерная компания по эксплуатации и контролю систем безопасности объектов
|
||||
|
||||
---
|
||||
|
||||
## ФУНКЦИОНАЛЬНЫЕ БЛОКИ
|
||||
|
||||
```text
|
||||
1. Engineering Audit (аудит и диагностика)
|
||||
2. SLA Operations (эксплуатация)
|
||||
3. Incident Response (аварийные работы)
|
||||
4. Technical Supervision (контроль подрядчиков)
|
||||
5. Documentation & Compliance (документация)
|
||||
6. Risk Engineering (анализ рисков)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# 2. СТРУКТУРА САЙТА (КАК ДОЛЖЕН ВЫГЛЯДЕТЬ AEGISONE)
|
||||
|
||||
---
|
||||
|
||||
# 🏠 ГЛАВНАЯ
|
||||
|
||||
## `/`
|
||||
|
||||
### Название:
|
||||
|
||||
AegisOne Engineering
|
||||
|
||||
### Смысл:
|
||||
|
||||
> инженерная эксплуатация систем безопасности объектов
|
||||
|
||||
---
|
||||
|
||||
# 3. РАЗДЕЛЫ САЙТА
|
||||
|
||||
---
|
||||
|
||||
# 3.1 ENGINEERING AUDIT
|
||||
|
||||
## `/engineering-audit/`
|
||||
|
||||
### Описание:
|
||||
|
||||
```text
|
||||
Технический аудит систем безопасности с оценкой рисков эксплуатации.
|
||||
|
||||
Проверка:
|
||||
- видеонаблюдения
|
||||
- СКУД
|
||||
- пожарной сигнализации
|
||||
- инфраструктуры объекта
|
||||
|
||||
Результат:
|
||||
инженерное заключение и карта рисков объекта
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Подразделы:
|
||||
|
||||
- `/engineering-audit/video-surveillance`
|
||||
- `/engineering-audit/access-control`
|
||||
- `/engineering-audit/fire-alarm`
|
||||
- `/engineering-audit/risk-report`
|
||||
|
||||
---
|
||||
|
||||
# 3.2 SLA OPERATIONS
|
||||
|
||||
## `/sla-operations/`
|
||||
|
||||
### Описание:
|
||||
|
||||
```text
|
||||
Постоянное техническое сопровождение объектов с регламентами и SLA.
|
||||
|
||||
Мы обеспечиваем:
|
||||
- стабильную работу систем
|
||||
- контроль состояния оборудования
|
||||
- аварийное реагирование
|
||||
- регулярные проверки
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Подразделы:
|
||||
|
||||
- `/sla-operations/start`
|
||||
- `/sla-operations/business`
|
||||
- `/sla-operations/enterprise`
|
||||
- `/sla-operations/sla-regulations`
|
||||
|
||||
---
|
||||
|
||||
# 3.3 INCIDENT RESPONSE
|
||||
|
||||
## `/incident-response/`
|
||||
|
||||
### Описание:
|
||||
|
||||
```text
|
||||
Экстренное устранение неисправностей систем безопасности.
|
||||
|
||||
Сценарии:
|
||||
- отказ видеонаблюдения
|
||||
- потеря архива
|
||||
- сбой СКУД
|
||||
- проблемы пожарной сигнализации
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Подразделы:
|
||||
|
||||
- `/incident-response/critical`
|
||||
- `/incident-response/emergency-call`
|
||||
- `/incident-response/post-incident-report`
|
||||
|
||||
---
|
||||
|
||||
# 3.4 TECHNICAL SUPERVISION
|
||||
|
||||
## `/technical-supervision/`
|
||||
|
||||
### Описание:
|
||||
|
||||
```text
|
||||
Контроль подрядчиков и проверка качества работ сторонних организаций.
|
||||
|
||||
Мы выступаем как независимый инженерный контроль объекта.
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Подразделы:
|
||||
|
||||
- `/technical-supervision/contractor-check`
|
||||
- `/technical-supervision/acceptance-testing`
|
||||
- `/technical-supervision/project-review`
|
||||
|
||||
---
|
||||
|
||||
# 3.5 DOCUMENTATION & COMPLIANCE
|
||||
|
||||
## `/documentation-compliance/`
|
||||
|
||||
### Описание:
|
||||
|
||||
```text
|
||||
Ведение и восстановление инженерной документации объектов.
|
||||
|
||||
Системы:
|
||||
- схемы
|
||||
- журналы
|
||||
- паспорта оборудования
|
||||
- регламенты эксплуатации
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Подразделы:
|
||||
|
||||
- `/documentation-compliance/passport`
|
||||
- `/documentation-compliance/regulations`
|
||||
- `/documentation-compliance/reporting`
|
||||
|
||||
---
|
||||
|
||||
# 3.6 RISK ENGINEERING
|
||||
|
||||
## `/risk-engineering/`
|
||||
|
||||
### Описание:
|
||||
|
||||
```text
|
||||
Анализ рисков эксплуатации инженерных систем безопасности объекта.
|
||||
|
||||
Мы оцениваем не оборудование, а последствия его отказа.
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Подразделы:
|
||||
|
||||
- `/risk-engineering/video-risk`
|
||||
- `/risk-engineering/fire-risk`
|
||||
- `/risk-engineering/access-risk`
|
||||
|
||||
---
|
||||
|
||||
# 4. ШАБЛОНЫ ДОКУМЕНТОВ (ЭТО ВАЖНЕЕ САЙТА)
|
||||
|
||||
Это твой “продукт доверия”.
|
||||
|
||||
---
|
||||
|
||||
# 4.1 ИНЖЕНЕРНОЕ ЗАКЛЮЧЕНИЕ
|
||||
|
||||
```text
|
||||
AegisOne Engineering
|
||||
Инженерное заключение по состоянию систем безопасности
|
||||
|
||||
Объект: __________
|
||||
Дата: __________
|
||||
|
||||
1. Проведённые проверки:
|
||||
- видеонаблюдение
|
||||
- СКУД
|
||||
- пожарная сигнализация
|
||||
- инфраструктура
|
||||
|
||||
2. Выявленные отклонения:
|
||||
- __________
|
||||
- __________
|
||||
|
||||
3. Критические риски:
|
||||
- __________
|
||||
|
||||
4. Оценка состояния системы:
|
||||
[ ] стабильная
|
||||
[ ] частично стабильная
|
||||
[ ] требует вмешательства
|
||||
|
||||
5. Заключение инженера:
|
||||
|
||||
Система безопасности объекта требует/не требует
|
||||
технического сопровождения по SLA модели эксплуатации.
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# 4.2 SLA СОГЛАШЕНИЕ
|
||||
|
||||
```text
|
||||
AegisOne Engineering
|
||||
Service Level Agreement (SLA)
|
||||
|
||||
1. Объект обслуживания
|
||||
2. Перечень систем
|
||||
3. Время реакции:
|
||||
P1 — 2 часа
|
||||
P2 — 4 часа
|
||||
P3 — 24 часа
|
||||
|
||||
4. Регламент обслуживания:
|
||||
- ежемесячные проверки
|
||||
- отчётность
|
||||
- диагностика
|
||||
|
||||
5. Зоны ответственности:
|
||||
- заказчик
|
||||
- инженерная компания
|
||||
|
||||
6. Исключения:
|
||||
- повреждение третьими лицами
|
||||
- форс-мажор
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# 4.3 АКТ ТЕХНИЧЕСКОГО АУДИТА
|
||||
|
||||
```text
|
||||
Проверено:
|
||||
- видеонаблюдение
|
||||
- СКУД
|
||||
- пожарная система
|
||||
|
||||
Результаты:
|
||||
- __________
|
||||
|
||||
Рекомендации:
|
||||
- критические
|
||||
- важные
|
||||
- плановые
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# 4.4 ПАСПОРТ ОБЪЕКТА
|
||||
|
||||
```text
|
||||
AegisOne Engineering
|
||||
Паспорт инженерных систем объекта
|
||||
|
||||
Содержит:
|
||||
- схема систем
|
||||
- оборудование
|
||||
- IP-адреса
|
||||
- точки отказа
|
||||
- история обслуживания
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# 4.5 ОТЧЁТ ПО ИНЦИДЕНТУ
|
||||
|
||||
```text
|
||||
Описание инцидента:
|
||||
Время реакции:
|
||||
Причина:
|
||||
Последствия:
|
||||
Устранение:
|
||||
Рекомендации:
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# 5. СЦЕНАРИИ ВЗАИМОДЕЙСТВИЯ
|
||||
|
||||
---
|
||||
|
||||
## СЦЕНАРИЙ 1 — ВХОД
|
||||
|
||||
```text
|
||||
Контакт → мини-диагностика → аудит → отчет → SLA
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## СЦЕНАРИЙ 2 — АВАРИЯ
|
||||
|
||||
```text
|
||||
Инцидент → выезд → устранение → отчет → предложение SLA
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## СЦЕНАРИЙ 3 — ПАРТНЁРСКИЙ ВХОД
|
||||
|
||||
```text
|
||||
Партнёр → объект → аудит → сопровождение
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## СЦЕНАРИЙ 4 — ТЕНДЕР / КОММЕРЧЕСКИЙ ВХОД
|
||||
|
||||
```text
|
||||
Запрос → аудит → КП → SLA контракт
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# 6. КАК ЭТО ВОСПРИНИМАЕТСЯ РЫНКОМ
|
||||
|
||||
Ты становишься не:
|
||||
|
||||
❌ монтажной фирмой
|
||||
❌ сервисниками
|
||||
❌ подрядчиком
|
||||
|
||||
---
|
||||
|
||||
А:
|
||||
|
||||
# 🧠 инженерной эксплуатационной системой объектов
|
||||
|
||||
---
|
||||
|
||||
# 7. ГЛАВНЫЙ ЭФФЕКТ ЭТОЙ УПАКОВКИ
|
||||
|
||||
## Клиент думает:
|
||||
|
||||
> “Это не монтажники. Это те, кто контролирует безопасность объекта как систему.”
|
||||
|
||||
---
|
||||
|
||||
# 8. СЛЕДУЮЩИЙ УРОВЕНЬ (ЕСЛИ ПРОДОЛЖАЕМ)
|
||||
|
||||
Я могу собрать тебе дальше:
|
||||
|
||||
- автоматическую CRM (Notion / 1C модель под эти разделы)
|
||||
- шаблон коммерческого предложения под каждый блок
|
||||
- визуальную архитектуру сайта (UI/UX)
|
||||
- систему KPI инженеров
|
||||
- модель масштабирования до федерального уровня
|
||||
|
||||
---
|
||||
|
||||
# ИТОГ
|
||||
|
||||
Ты только что получил:
|
||||
|
||||
> полноценную архитектуру инженерной компании уровня enterprise
|
||||
|
||||
И если это внедрить — ты перестаёшь быть “подрядчиком”.
|
||||
|
||||
Ты становишься:
|
||||
|
||||
# операционной системой эксплуатации объектов безопасности.
|
||||
@@ -0,0 +1,459 @@
|
||||
Отлично, теперь мы фиксируем архитектуру компании как инженерной системы, а не сайта.
|
||||
|
||||
Ты строишь не “фирму услуг”, а:
|
||||
|
||||
AegisOne Engineering — операционную систему эксплуатации объектов
|
||||
|
||||
Ниже даю тебе:
|
||||
|
||||
1. структуру компании (как она “разложена в голове клиента”)
|
||||
|
||||
|
||||
2. все разделы сайта / системы
|
||||
|
||||
|
||||
3. документы (шаблоны, которые продают SLA сами)
|
||||
|
||||
|
||||
4. сценарии взаимодействия с клиентом
|
||||
|
||||
|
||||
5. стандарты (как ты выглядишь как федеральный подрядчик)
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
1. СТРУКТУРА AEGISONE ENGINEERING
|
||||
|
||||
🧠 ЯДРО КОМПАНИИ
|
||||
|
||||
AegisOne Engineering
|
||||
|
||||
> Инженерная компания по эксплуатации и контролю систем безопасности объектов
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
ФУНКЦИОНАЛЬНЫЕ БЛОКИ
|
||||
|
||||
1. Engineering Audit (аудит и диагностика)
|
||||
2. SLA Operations (эксплуатация)
|
||||
3. Incident Response (аварийные работы)
|
||||
4. Technical Supervision (контроль подрядчиков)
|
||||
5. Documentation & Compliance (документация)
|
||||
6. Risk Engineering (анализ рисков)
|
||||
|
||||
|
||||
---
|
||||
|
||||
2. СТРУКТУРА САЙТА (КАК ДОЛЖЕН ВЫГЛЯДЕТЬ AEGISONE)
|
||||
|
||||
|
||||
---
|
||||
|
||||
🏠 ГЛАВНАЯ
|
||||
|
||||
/
|
||||
|
||||
Название:
|
||||
|
||||
AegisOne Engineering
|
||||
|
||||
Смысл:
|
||||
|
||||
> инженерная эксплуатация систем безопасности объектов
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
3. РАЗДЕЛЫ САЙТА
|
||||
|
||||
|
||||
---
|
||||
|
||||
3.1 ENGINEERING AUDIT
|
||||
|
||||
/engineering-audit/
|
||||
|
||||
Описание:
|
||||
|
||||
Технический аудит систем безопасности с оценкой рисков эксплуатации.
|
||||
|
||||
Проверка:
|
||||
- видеонаблюдения
|
||||
- СКУД
|
||||
- пожарной сигнализации
|
||||
- инфраструктуры объекта
|
||||
|
||||
Результат:
|
||||
инженерное заключение и карта рисков объекта
|
||||
|
||||
|
||||
---
|
||||
|
||||
Подразделы:
|
||||
|
||||
/engineering-audit/video-surveillance
|
||||
|
||||
/engineering-audit/access-control
|
||||
|
||||
/engineering-audit/fire-alarm
|
||||
|
||||
/engineering-audit/risk-report
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
3.2 SLA OPERATIONS
|
||||
|
||||
/sla-operations/
|
||||
|
||||
Описание:
|
||||
|
||||
Постоянное техническое сопровождение объектов с регламентами и SLA.
|
||||
|
||||
Мы обеспечиваем:
|
||||
- стабильную работу систем
|
||||
- контроль состояния оборудования
|
||||
- аварийное реагирование
|
||||
- регулярные проверки
|
||||
|
||||
|
||||
---
|
||||
|
||||
Подразделы:
|
||||
|
||||
/sla-operations/start
|
||||
|
||||
/sla-operations/business
|
||||
|
||||
/sla-operations/enterprise
|
||||
|
||||
/sla-operations/sla-regulations
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
3.3 INCIDENT RESPONSE
|
||||
|
||||
/incident-response/
|
||||
|
||||
Описание:
|
||||
|
||||
Экстренное устранение неисправностей систем безопасности.
|
||||
|
||||
Сценарии:
|
||||
- отказ видеонаблюдения
|
||||
- потеря архива
|
||||
- сбой СКУД
|
||||
- проблемы пожарной сигнализации
|
||||
|
||||
|
||||
---
|
||||
|
||||
Подразделы:
|
||||
|
||||
/incident-response/critical
|
||||
|
||||
/incident-response/emergency-call
|
||||
|
||||
/incident-response/post-incident-report
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
3.4 TECHNICAL SUPERVISION
|
||||
|
||||
/technical-supervision/
|
||||
|
||||
Описание:
|
||||
|
||||
Контроль подрядчиков и проверка качества работ сторонних организаций.
|
||||
|
||||
Мы выступаем как независимый инженерный контроль объекта.
|
||||
|
||||
|
||||
---
|
||||
|
||||
Подразделы:
|
||||
|
||||
/technical-supervision/contractor-check
|
||||
|
||||
/technical-supervision/acceptance-testing
|
||||
|
||||
/technical-supervision/project-review
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
3.5 DOCUMENTATION & COMPLIANCE
|
||||
|
||||
/documentation-compliance/
|
||||
|
||||
Описание:
|
||||
|
||||
Ведение и восстановление инженерной документации объектов.
|
||||
|
||||
Системы:
|
||||
- схемы
|
||||
- журналы
|
||||
- паспорта оборудования
|
||||
- регламенты эксплуатации
|
||||
|
||||
|
||||
---
|
||||
|
||||
Подразделы:
|
||||
|
||||
/documentation-compliance/passport
|
||||
|
||||
/documentation-compliance/regulations
|
||||
|
||||
/documentation-compliance/reporting
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
3.6 RISK ENGINEERING
|
||||
|
||||
/risk-engineering/
|
||||
|
||||
Описание:
|
||||
|
||||
Анализ рисков эксплуатации инженерных систем безопасности объекта.
|
||||
|
||||
Мы оцениваем не оборудование, а последствия его отказа.
|
||||
|
||||
|
||||
---
|
||||
|
||||
Подразделы:
|
||||
|
||||
/risk-engineering/video-risk
|
||||
|
||||
/risk-engineering/fire-risk
|
||||
|
||||
/risk-engineering/access-risk
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
4. ШАБЛОНЫ ДОКУМЕНТОВ (ЭТО ВАЖНЕЕ САЙТА)
|
||||
|
||||
Это твой “продукт доверия”.
|
||||
|
||||
|
||||
---
|
||||
|
||||
4.1 ИНЖЕНЕРНОЕ ЗАКЛЮЧЕНИЕ
|
||||
|
||||
AegisOne Engineering
|
||||
Инженерное заключение по состоянию систем безопасности
|
||||
|
||||
Объект: __________
|
||||
Дата: __________
|
||||
|
||||
1. Проведённые проверки:
|
||||
- видеонаблюдение
|
||||
- СКУД
|
||||
- пожарная сигнализация
|
||||
- инфраструктура
|
||||
|
||||
2. Выявленные отклонения:
|
||||
- __________
|
||||
- __________
|
||||
|
||||
3. Критические риски:
|
||||
- __________
|
||||
|
||||
4. Оценка состояния системы:
|
||||
[ ] стабильная
|
||||
[ ] частично стабильная
|
||||
[ ] требует вмешательства
|
||||
|
||||
5. Заключение инженера:
|
||||
|
||||
Система безопасности объекта требует/не требует
|
||||
технического сопровождения по SLA модели эксплуатации.
|
||||
|
||||
|
||||
---
|
||||
|
||||
4.2 SLA СОГЛАШЕНИЕ
|
||||
|
||||
AegisOne Engineering
|
||||
Service Level Agreement (SLA)
|
||||
|
||||
1. Объект обслуживания
|
||||
2. Перечень систем
|
||||
3. Время реакции:
|
||||
P1 — 2 часа
|
||||
P2 — 4 часа
|
||||
P3 — 24 часа
|
||||
|
||||
4. Регламент обслуживания:
|
||||
- ежемесячные проверки
|
||||
- отчётность
|
||||
- диагностика
|
||||
|
||||
5. Зоны ответственности:
|
||||
- заказчик
|
||||
- инженерная компания
|
||||
|
||||
6. Исключения:
|
||||
- повреждение третьими лицами
|
||||
- форс-мажор
|
||||
|
||||
|
||||
---
|
||||
|
||||
4.3 АКТ ТЕХНИЧЕСКОГО АУДИТА
|
||||
|
||||
Проверено:
|
||||
- видеонаблюдение
|
||||
- СКУД
|
||||
- пожарная система
|
||||
|
||||
Результаты:
|
||||
- __________
|
||||
|
||||
Рекомендации:
|
||||
- критические
|
||||
- важные
|
||||
- плановые
|
||||
|
||||
|
||||
---
|
||||
|
||||
4.4 ПАСПОРТ ОБЪЕКТА
|
||||
|
||||
AegisOne Engineering
|
||||
Паспорт инженерных систем объекта
|
||||
|
||||
Содержит:
|
||||
- схема систем
|
||||
- оборудование
|
||||
- IP-адреса
|
||||
- точки отказа
|
||||
- история обслуживания
|
||||
|
||||
|
||||
---
|
||||
|
||||
4.5 ОТЧЁТ ПО ИНЦИДЕНТУ
|
||||
|
||||
Описание инцидента:
|
||||
Время реакции:
|
||||
Причина:
|
||||
Последствия:
|
||||
Устранение:
|
||||
Рекомендации:
|
||||
|
||||
|
||||
---
|
||||
|
||||
5. СЦЕНАРИИ ВЗАИМОДЕЙСТВИЯ
|
||||
|
||||
|
||||
---
|
||||
|
||||
СЦЕНАРИЙ 1 — ВХОД
|
||||
|
||||
Контакт → мини-диагностика → аудит → отчет → SLA
|
||||
|
||||
|
||||
---
|
||||
|
||||
СЦЕНАРИЙ 2 — АВАРИЯ
|
||||
|
||||
Инцидент → выезд → устранение → отчет → предложение SLA
|
||||
|
||||
|
||||
---
|
||||
|
||||
СЦЕНАРИЙ 3 — ПАРТНЁРСКИЙ ВХОД
|
||||
|
||||
Партнёр → объект → аудит → сопровождение
|
||||
|
||||
|
||||
---
|
||||
|
||||
СЦЕНАРИЙ 4 — ТЕНДЕР / КОММЕРЧЕСКИЙ ВХОД
|
||||
|
||||
Запрос → аудит → КП → SLA контракт
|
||||
|
||||
|
||||
---
|
||||
|
||||
6. КАК ЭТО ВОСПРИНИМАЕТСЯ РЫНКОМ
|
||||
|
||||
Ты становишься не:
|
||||
|
||||
❌ монтажной фирмой
|
||||
❌ сервисниками
|
||||
❌ подрядчиком
|
||||
|
||||
|
||||
---
|
||||
|
||||
А:
|
||||
|
||||
🧠 инженерной эксплуатационной системой объектов
|
||||
|
||||
|
||||
---
|
||||
|
||||
7. ГЛАВНЫЙ ЭФФЕКТ ЭТОЙ УПАКОВКИ
|
||||
|
||||
Клиент думает:
|
||||
|
||||
> “Это не монтажники. Это те, кто контролирует безопасность объекта как систему.”
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
8. СЛЕДУЮЩИЙ УРОВЕНЬ (ЕСЛИ ПРОДОЛЖАЕМ)
|
||||
|
||||
Я могу собрать тебе дальше:
|
||||
|
||||
автоматическую CRM (Notion / 1C модель под эти разделы)
|
||||
|
||||
шаблон коммерческого предложения под каждый блок
|
||||
|
||||
визуальную архитектуру сайта (UI/UX)
|
||||
|
||||
систему KPI инженеров
|
||||
|
||||
модель масштабирования до федерального уровня
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
ИТОГ
|
||||
|
||||
Ты только что получил:
|
||||
|
||||
> полноценную архитектуру инженерной компании уровня enterprise
|
||||
|
||||
|
||||
|
||||
И если это внедрить — ты перестаёшь быть “подрядчиком”.
|
||||
|
||||
Ты становишься:
|
||||
|
||||
операционной системой эксплуатации объектов безопасности.
|
||||
@@ -0,0 +1,543 @@
|
||||
Хороший вопрос — блог в твоей нише (системы безопасности + SLA + B2B + обслуживание) это не “контент-маркетинг”, а:
|
||||
|
||||
> инструмент продажи доверия, SLA и инженерной компетентности
|
||||
|
||||
|
||||
|
||||
Если блог сделан правильно, он заменяет:
|
||||
|
||||
отдел продаж (частично)
|
||||
|
||||
коммерческие предложения (частично)
|
||||
|
||||
презентации
|
||||
|
||||
кейсы
|
||||
|
||||
и даже тендерные обоснования
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
1. ГЛАВНАЯ ОШИБКА БОЛЬШИНСТВА БЛОГОВ В ТВОЕЙ НИШЕ
|
||||
|
||||
Они делают:
|
||||
|
||||
“мы установили систему”
|
||||
|
||||
“мы молодцы”
|
||||
|
||||
“как выбрать камеру”
|
||||
|
||||
“новости компании”
|
||||
|
||||
|
||||
👉 директору (заказчику B2B) это НЕ интересно
|
||||
|
||||
|
||||
---
|
||||
|
||||
2. ЧТО ХОЧЕТ ВИДЕТЬ ДИРЕКТОР (ЗАКАЗЧИК B2B)
|
||||
|
||||
Директору не нужен контент.
|
||||
|
||||
Ему нужно:
|
||||
|
||||
1. Снижение риска
|
||||
|
||||
“у меня не сломается объект”
|
||||
|
||||
“меня не оштрафуют”
|
||||
|
||||
“у меня будет доказательная база”
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
2. Управляемость
|
||||
|
||||
SLA
|
||||
|
||||
контроль
|
||||
|
||||
прозрачность
|
||||
|
||||
ответственность
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
3. Деньги и потери
|
||||
|
||||
сколько стоит простой
|
||||
|
||||
сколько стоит отказ системы
|
||||
|
||||
где риски потерь
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
4. Компетентность подрядчика
|
||||
|
||||
понимает ли подрядчик реальные риски
|
||||
|
||||
умеет ли он управлять системой, а не “чинить камеры”
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
3. КАК ДОЛЖЕН БЫТЬ УСТРОЕН БЛОГ (АРХИТЕКТУРА)
|
||||
|
||||
BLOG AEGISONE
|
||||
|
||||
1. Risk Engineering (риски объектов)
|
||||
2. SLA & Service (обслуживание)
|
||||
3. Incident Cases (разбор аварий)
|
||||
4. Infrastructure Deep Dive (техническая экспертиза)
|
||||
5. Compliance / MCHS / Audit (регуляторика)
|
||||
6. Economics of Security (экономика потерь)
|
||||
7. Case Studies (реальные объекты)
|
||||
|
||||
|
||||
---
|
||||
|
||||
4. КАТЕГОРИИ БЛОГА (ПОЛНАЯ СТРУКТУРА)
|
||||
|
||||
|
||||
---
|
||||
|
||||
4.1 RISK ENGINEERING (САМАЯ ВАЖНАЯ)
|
||||
|
||||
Суть:
|
||||
|
||||
Показывает директору:
|
||||
|
||||
> где он уже теряет деньги, даже если всё “работает”
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Примеры статей:
|
||||
|
||||
“Почему 70% объектов теряют видеодоказательства и не знают об этом”
|
||||
|
||||
“Что происходит, когда SLA пожарной системы формальный”
|
||||
|
||||
“7 скрытых точек отказа в СКУД”
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Формат:
|
||||
|
||||
риск
|
||||
|
||||
последствия
|
||||
|
||||
реальные сценарии
|
||||
|
||||
стоимость потерь
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Почему это продаёт:
|
||||
|
||||
👉 вызывает страх + осознание потерь
|
||||
|
||||
|
||||
---
|
||||
|
||||
4.2 SLA & SERVICE (ТВОЯ ДЕНЕЖНАЯ КАТЕГОРИЯ)
|
||||
|
||||
Суть:
|
||||
|
||||
объясняет, почему SLA = бизнес-стабильность
|
||||
|
||||
|
||||
---
|
||||
|
||||
Примеры:
|
||||
|
||||
“Почему обслуживание пожарной сигнализации — это не обслуживание, а юридическая ответственность”
|
||||
|
||||
“Как SLA снижает риск остановки бизнеса”
|
||||
|
||||
“Почему разовые выезды не работают”
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Формат:
|
||||
|
||||
объяснение SLA
|
||||
|
||||
цифры
|
||||
|
||||
последствия без SLA
|
||||
|
||||
кейсы
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
4.3 INCIDENT CASES (СИЛЬНЕЙШИЙ ДОВЕРИТЕЛЬНЫЙ БЛОК)
|
||||
|
||||
Суть:
|
||||
|
||||
реальные аварии
|
||||
|
||||
|
||||
---
|
||||
|
||||
Примеры:
|
||||
|
||||
“Как один отказ СКУД остановил склад на 14 часов”
|
||||
|
||||
“Пожарная система без регламента: разбор инцидента”
|
||||
|
||||
“Почему не работал архив видеонаблюдения 3 месяца”
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Структура:
|
||||
|
||||
1. Что случилось
|
||||
2. Почему это произошло
|
||||
3. Какие были последствия
|
||||
4. Как это выявили
|
||||
5. Как исправили
|
||||
6. Как избежать
|
||||
|
||||
|
||||
---
|
||||
|
||||
Это:
|
||||
|
||||
👉 главный доверительный инструмент
|
||||
|
||||
|
||||
---
|
||||
|
||||
4.4 INFRASTRUCTURE DEEP DIVE
|
||||
|
||||
Суть:
|
||||
|
||||
показывает инженерную глубину
|
||||
|
||||
|
||||
---
|
||||
|
||||
Примеры:
|
||||
|
||||
“Как устроена современная система видеонаблюдения на объекте 10 000 м²”
|
||||
|
||||
“Почему сеть — это главный риск безопасности”
|
||||
|
||||
“UPS как критический элемент безопасности”
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
4.5 COMPLIANCE / MCHS
|
||||
|
||||
Суть:
|
||||
|
||||
работа с нормативкой
|
||||
|
||||
|
||||
---
|
||||
|
||||
Примеры:
|
||||
|
||||
“Что проверяет МЧС в 2026 году”
|
||||
|
||||
“Типовые ошибки объектов при проверках”
|
||||
|
||||
“Почему формальное ТО приводит к штрафам”
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
4.6 ECONOMICS OF SECURITY
|
||||
|
||||
Суть:
|
||||
|
||||
деньги, потери, риск
|
||||
|
||||
|
||||
---
|
||||
|
||||
Примеры:
|
||||
|
||||
“Сколько стоит 1 час простоя склада”
|
||||
|
||||
“Стоимость потери видеодоказательства”
|
||||
|
||||
“Почему дешёвый подрядчик обходится дороже”
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
4.7 CASE STUDIES (ОСНОВА ПРОДАЖ)
|
||||
|
||||
Суть:
|
||||
|
||||
твои реальные объекты
|
||||
|
||||
|
||||
---
|
||||
|
||||
Формат:
|
||||
|
||||
объект
|
||||
|
||||
проблемы
|
||||
|
||||
что сделали
|
||||
|
||||
результат
|
||||
|
||||
SLA модель
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
5. КАК ДОЛЖЕН ВЫГЛЯДЕТЬ БЛОГ (UI/UX)
|
||||
|
||||
|
||||
---
|
||||
|
||||
5.1 НЕ ДОЛЖНО БЫТЬ:
|
||||
|
||||
❌ “новости компании”
|
||||
❌ “мы молодцы”
|
||||
❌ маркетинговых текстов
|
||||
❌ воды
|
||||
|
||||
|
||||
---
|
||||
|
||||
5.2 ДОЛЖНО БЫТЬ:
|
||||
|
||||
Главная страница блога:
|
||||
|
||||
“инженерные риски”
|
||||
|
||||
“разбор инцидентов”
|
||||
|
||||
“стоимость отказов”
|
||||
|
||||
“кейсы объектов”
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
5.3 Визуально:
|
||||
|
||||
строгий технический стиль
|
||||
|
||||
таблицы
|
||||
|
||||
схемы
|
||||
|
||||
диаграммы
|
||||
|
||||
риск-блоки
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
6. КАЖДАЯ СТАТЬЯ ДОЛЖНА ПРОДАВАТЬ
|
||||
|
||||
|
||||
---
|
||||
|
||||
структура статьи (обязательная):
|
||||
|
||||
1. Проблема
|
||||
2. Реальный сценарий
|
||||
3. Что происходит технически
|
||||
4. Риски
|
||||
5. Финансовые последствия
|
||||
6. Как решается
|
||||
7. Как это делает AegisOne
|
||||
|
||||
|
||||
---
|
||||
|
||||
7. ПРИМЕР “ПРОДАЮЩЕЙ” СТАТЬИ
|
||||
|
||||
|
||||
---
|
||||
|
||||
Заголовок:
|
||||
|
||||
> “Почему 80% систем видеонаблюдения не дают доказательств в момент инцидента”
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Внутри:
|
||||
|
||||
потеря архива
|
||||
|
||||
сбои HDD
|
||||
|
||||
неправильная настройка
|
||||
|
||||
отсутствие контроля
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Финал:
|
||||
|
||||
> “в AegisOne это решается через SLA мониторинг и инженерный контроль”
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
8. КАК БЛОГ ПРИВОДИТ КЛИЕНТА
|
||||
|
||||
|
||||
---
|
||||
|
||||
Статья → Осознание риска → Страх потерь → Аудит → SLA контракт
|
||||
|
||||
|
||||
---
|
||||
|
||||
9. ГЛАВНАЯ ЛОГИКА БЛОГА
|
||||
|
||||
Ты не пишешь статьи.
|
||||
|
||||
Ты создаёшь:
|
||||
|
||||
> систему формирования потребности в SLA
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
10. ЧТО ДЕЛАЕТ БЛОГ СИЛЬНЫМ (КРИТИЧНО)
|
||||
|
||||
|
||||
---
|
||||
|
||||
1. РЕАЛЬНЫЕ ЦИФРЫ
|
||||
|
||||
потери
|
||||
|
||||
простои
|
||||
|
||||
риски
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
2. РЕАЛЬНЫЕ ИНЦИДЕНТЫ
|
||||
|
||||
аварии
|
||||
|
||||
сбои
|
||||
|
||||
последствия
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
3. ИНЖЕНЕРНАЯ ГЛУБИНА
|
||||
|
||||
схемы
|
||||
|
||||
логика систем
|
||||
|
||||
причины отказов
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
4. ЭКОНОМИКА
|
||||
|
||||
сколько стоит ошибка
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
11. ЧТО НЕЛЬЗЯ ДЕЛАТЬ
|
||||
|
||||
|
||||
---
|
||||
|
||||
❌ SEO-статьи “для трафика”
|
||||
❌ поверхностные обзоры
|
||||
❌ “лайфхаки безопасности”
|
||||
❌ маркетинг
|
||||
|
||||
|
||||
---
|
||||
|
||||
12. ИТОГ
|
||||
|
||||
Правильный блог в твоей модели — это:
|
||||
|
||||
> “система инженерного страха + доверия + экспертизы”
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
13. ЕСЛИ РАЗВИВАТЬ ДАЛЬШЕ
|
||||
|
||||
Я могу дальше собрать:
|
||||
|
||||
30 готовых статей под твой блог (с заголовками + структурами)
|
||||
|
||||
SEO-структуру под Краснодарский край
|
||||
|
||||
Telegram-воронку из блога
|
||||
|
||||
автоматическое превращение статей в заявки на аудит
|
||||
|
||||
систему “контент → SHS влияние”
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Если коротко:
|
||||
|
||||
👉 блог в твоей модели — это не контент
|
||||
👉 это “машина продажи SLA через понимание риска”
|
||||
@@ -0,0 +1,445 @@
|
||||
Ок, здесь мы уже собираем не “маркетинг”, а полноценную B2B-машину:
|
||||
|
||||
# вход → доверие → аудит → SLA → долгий повторяющийся доход
|
||||
|
||||
Ты как раз в нише, где деньги делаются не на разовых монтажах, а на:
|
||||
|
||||
> эксплуатации + рисках + ответственности
|
||||
|
||||
---
|
||||
|
||||
# ЧАСТЬ 1. ПЕРВАЯ ВОРОНКА КЛИЕНТОВ (КРАСНОДАРСКИЙ КРАЙ)
|
||||
|
||||
---
|
||||
|
||||
# 0. ЛОГИКА ВОРОНКИ
|
||||
|
||||
Твоя воронка НЕ классическая:
|
||||
|
||||
❌ “реклама → заявка → продажа”
|
||||
|
||||
У тебя:
|
||||
|
||||
# контент → доверие → аудит → выявление проблем → SLA
|
||||
|
||||
---
|
||||
|
||||
# 1. ВХОД В ВОРОНКУ (ТОЧКИ ПРИКОСНОВЕНИЯ)
|
||||
|
||||
## 1.1. Локальный B2B рынок (основа)
|
||||
|
||||
Ты работаешь не по всей РФ, а:
|
||||
|
||||
- Краснодар
|
||||
- Сочи
|
||||
- Новороссийск
|
||||
- Анапа
|
||||
- Армавир
|
||||
- промзоны + логистика + гостиницы
|
||||
|
||||
---
|
||||
|
||||
## 1.2. Каналы входа (без агрессивного маркетинга)
|
||||
|
||||
### 1) Telegram (основной канал доверия)
|
||||
|
||||
Контент + кейсы + разборы
|
||||
|
||||
---
|
||||
|
||||
### 2) Яндекс / Google SEO
|
||||
|
||||
Страницы:
|
||||
|
||||
- аудит систем безопасности
|
||||
- SLA обслуживание
|
||||
- обслуживание видеонаблюдения Краснодар
|
||||
- обслуживание пожарной сигнализации
|
||||
|
||||
---
|
||||
|
||||
### 3) Партнеры (очень важно)
|
||||
|
||||
- электрики
|
||||
- IT-аутсорс
|
||||
- управляющие компании
|
||||
- проектировщики
|
||||
- пожарники
|
||||
- строители
|
||||
|
||||
---
|
||||
|
||||
### 4) Прямые инженерные выходы
|
||||
|
||||
НЕ продажи.
|
||||
|
||||
Формат:
|
||||
|
||||
> “если нужен технический аудит или проверка систем — можем подключиться”
|
||||
|
||||
---
|
||||
|
||||
# 2. ПЕРВЫЙ ПРОДУКТ (ВХОД В ДЕНЬГИ)
|
||||
|
||||
# 🔥 Технический аудит объекта
|
||||
|
||||
---
|
||||
|
||||
## Почему это ядро воронки
|
||||
|
||||
Потому что:
|
||||
|
||||
- легко продать без давления
|
||||
- низкий чек
|
||||
- высокая ценность
|
||||
- выявляет проблемы
|
||||
- логично ведёт в SLA
|
||||
|
||||
---
|
||||
|
||||
## Цена (Краснодарский край)
|
||||
|
||||
- малый объект: 15–25 тыс
|
||||
- средний: 25–50 тыс
|
||||
- крупный: 50–100 тыс
|
||||
|
||||
---
|
||||
|
||||
## Что важно
|
||||
|
||||
Аудит НЕ продаёт услуги.
|
||||
|
||||
Он:
|
||||
|
||||
# показывает проблемы → создаёт необходимость SLA
|
||||
|
||||
---
|
||||
|
||||
# 3. ВТОРОЙ ЭТАП
|
||||
|
||||
# 🔥 “Диагностика + отчет”
|
||||
|
||||
После аудита:
|
||||
|
||||
Ты выдаешь документ:
|
||||
|
||||
- риски
|
||||
- неисправности
|
||||
- слабые места
|
||||
- последствия
|
||||
- рекомендации
|
||||
|
||||
---
|
||||
|
||||
## Ключевая мысль отчета:
|
||||
|
||||
> “Система формально работает, но не защищает объект”
|
||||
|
||||
---
|
||||
|
||||
# 4. ТРЕТИЙ ЭТАП
|
||||
|
||||
# 🔥 ПЕРЕХОД В SLA
|
||||
|
||||
---
|
||||
|
||||
## Это главный момент денег
|
||||
|
||||
Ты НЕ продаешь обслуживание.
|
||||
|
||||
Ты продаешь:
|
||||
|
||||
# “устранение рисков эксплуатации”
|
||||
|
||||
---
|
||||
|
||||
## Как выглядит оффер
|
||||
|
||||
> Мы берем объект на техническое сопровождение с SLA контролем состояния систем безопасности.
|
||||
|
||||
---
|
||||
|
||||
## Конверсия
|
||||
|
||||
Из аудита → в SLA:
|
||||
|
||||
- 30% слабые объекты
|
||||
- 50% средние
|
||||
- 10–20% сильные (очень хорошие деньги)
|
||||
|
||||
---
|
||||
|
||||
# 5. SLA (ПРОДУКТ ДЕНЕГ)
|
||||
|
||||
---
|
||||
|
||||
## Структура:
|
||||
|
||||
### START
|
||||
|
||||
25–40k
|
||||
|
||||
---
|
||||
|
||||
### BUSINESS
|
||||
|
||||
60–120k
|
||||
|
||||
---
|
||||
|
||||
### ENTERPRISE
|
||||
|
||||
150–400k
|
||||
|
||||
---
|
||||
|
||||
## Что ты продаешь на самом деле:
|
||||
|
||||
НЕ обслуживание
|
||||
|
||||
А:
|
||||
|
||||
# “инженерную стабильность объекта”
|
||||
|
||||
---
|
||||
|
||||
# 6. ПОЛНАЯ ВОРОНКА В ВИДЕ СХЕМЫ
|
||||
|
||||
```
|
||||
Контент / SEO / партнеры
|
||||
↓
|
||||
Лид (запрос)
|
||||
↓
|
||||
Мини-аудит (или первичная диагностика)
|
||||
↓
|
||||
Полный технический аудит
|
||||
↓
|
||||
Отчет с рисками
|
||||
↓
|
||||
SLA предложение
|
||||
↓
|
||||
Долгосрочный контракт
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# ЧАСТЬ 2. МОДЕЛЬ РОСТА ДО 2–3 МЛН ₽/МЕС RECURRENT
|
||||
|
||||
---
|
||||
|
||||
# 1. КЛЮЧЕВОЕ ПРАВИЛО
|
||||
|
||||
Ты не масштабируешь монтаж.
|
||||
|
||||
Ты масштабируешь:
|
||||
|
||||
# количество объектов на SLA
|
||||
|
||||
---
|
||||
|
||||
# 2. МАТЕМАТИКА МОДЕЛИ
|
||||
|
||||
---
|
||||
|
||||
## Вариант реалистичный (Краснодар → край → РФ)
|
||||
|
||||
### Средний чек SLA:
|
||||
|
||||
80 000 ₽
|
||||
|
||||
---
|
||||
|
||||
## Тебе нужно:
|
||||
|
||||
### 25–35 объектов
|
||||
|
||||
---
|
||||
|
||||
## Доход:
|
||||
|
||||
```
|
||||
30 объектов × 80 000 ₽ = 2 400 000 ₽/мес
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# 3. КАК ЭТО ДОСТИГАЕТСЯ
|
||||
|
||||
---
|
||||
|
||||
## ЭТАП 1 — 0–500k
|
||||
|
||||
Фокус:
|
||||
|
||||
- аудит
|
||||
- первые SLA
|
||||
- 5–7 объектов
|
||||
|
||||
---
|
||||
|
||||
## ЭТАП 2 — 500k–1.5M
|
||||
|
||||
Фокус:
|
||||
|
||||
- стабильные SLA
|
||||
- отбор клиентов
|
||||
- отказ от токсичных объектов
|
||||
- первые крупные клиенты
|
||||
|
||||
---
|
||||
|
||||
## ЭТАП 3 — 1.5M–3M
|
||||
|
||||
Фокус:
|
||||
|
||||
- стандартизация
|
||||
- регламенты
|
||||
- техподдержка
|
||||
- 2–3 инженера
|
||||
- удаленный контроль
|
||||
|
||||
---
|
||||
|
||||
# 4. КЛЮЧЕВОЙ РЫЧАГ РОСТА
|
||||
|
||||
---
|
||||
|
||||
# НЕ реклама
|
||||
|
||||
# НЕ продажи
|
||||
|
||||
# А:
|
||||
|
||||
## “плотность объектов на инженера”
|
||||
|
||||
---
|
||||
|
||||
# 5. СИСТЕМА РОСТА
|
||||
|
||||
---
|
||||
|
||||
## 1 инженер = 8–12 объектов
|
||||
|
||||
---
|
||||
|
||||
## значит:
|
||||
|
||||
|Кол-во инженеров|Доход|
|
||||
|---|---|
|
||||
|1|0.8–1.2M|
|
||||
|2|1.6–2.4M|
|
||||
|3|2.4–3.6M|
|
||||
|
||||
---
|
||||
|
||||
# 6. ГЛАВНЫЕ РЫЧАГИ МАСШТАБА
|
||||
|
||||
---
|
||||
|
||||
## 1. Аудит как продукт входа
|
||||
|
||||
(дешево / легко / продается сам)
|
||||
|
||||
---
|
||||
|
||||
## 2. SLA как подписка
|
||||
|
||||
(деньги каждый месяц)
|
||||
|
||||
---
|
||||
|
||||
## 3. Контент как доверие
|
||||
|
||||
(заменяет рекламу)
|
||||
|
||||
---
|
||||
|
||||
## 4. Партнерки
|
||||
|
||||
(дают теплые объекты)
|
||||
|
||||
---
|
||||
|
||||
## 5. Отказ от дешевых клиентов
|
||||
|
||||
(самый важный фактор)
|
||||
|
||||
---
|
||||
|
||||
# 7. КРИТИЧЕСКИЙ МОМЕНТ
|
||||
|
||||
---
|
||||
|
||||
Если ты не сделаешь это:
|
||||
|
||||
> “мы не берем монтаж без SLA”
|
||||
|
||||
ты останешься в рынке:
|
||||
|
||||
- демпинга
|
||||
- разовых работ
|
||||
- кассовых разрывов
|
||||
|
||||
---
|
||||
|
||||
# 8. ИДЕАЛЬНАЯ ЭВОЛЮЦИЯ БИЗНЕСА
|
||||
|
||||
---
|
||||
|
||||
## Было:
|
||||
|
||||
монтажники
|
||||
|
||||
---
|
||||
|
||||
## Стало:
|
||||
|
||||
SLA + эксплуатация
|
||||
|
||||
---
|
||||
|
||||
## Будет:
|
||||
|
||||
# внешний инженерный отдел объектов
|
||||
|
||||
---
|
||||
|
||||
# 9. СИЛЬНЫЙ СДВИГ МЫШЛЕНИЯ
|
||||
|
||||
---
|
||||
|
||||
Ты больше не продаешь:
|
||||
|
||||
❌ камеры
|
||||
❌ монтаж
|
||||
❌ оборудование
|
||||
|
||||
---
|
||||
|
||||
Ты продаешь:
|
||||
|
||||
# “спокойствие собственника за техническую инфраструктуру объекта”
|
||||
|
||||
---
|
||||
|
||||
# ЕСЛИ СЖАТЬ В ОДНУ ФОРМУЛУ:
|
||||
|
||||
---
|
||||
|
||||
> Аудит → выявление рисков → SLA → долгосрочный инженерный доход
|
||||
|
||||
---
|
||||
|
||||
# ЕСЛИ ДАЛЬШЕ ДВИГАТЬСЯ
|
||||
|
||||
Я могу следующим шагом собрать тебе:
|
||||
|
||||
- точную систему продаж аудита (скрипты + сообщения)
|
||||
- упаковку Telegram как лидогенератора
|
||||
- CRM воронку под SLA
|
||||
- регламент инженера (чтобы масштабироваться)
|
||||
- финансовую модель до 5–10 млн/мес
|
||||
|
||||
Это уже будет не “бизнес идея”, а:
|
||||
|
||||
# операционная система инженерной компании.
|
||||
@@ -0,0 +1,397 @@
|
||||
Отлично, это уже уровень, где бизнес начинает “дышать сам”:
|
||||
Telegram → доверие → аудит → SLA → регулярный доход.
|
||||
|
||||
Разобьём на две системы:
|
||||
|
||||
# 1) Telegram как лидогенератор (не блог, а воронка)
|
||||
|
||||
# 2) CRM-воронка под SLA (повторяемые деньги)
|
||||
|
||||
---
|
||||
|
||||
# 1. TELEGRAM КАК ЛИДОГЕНЕРАТОР (ИНЖЕНЕРНАЯ МОДЕЛЬ)
|
||||
|
||||
---
|
||||
|
||||
## 1.1. Главная ошибка всех
|
||||
|
||||
Обычно делают:
|
||||
|
||||
- “посты про монтаж”
|
||||
- “новости компании”
|
||||
- “фото объектов”
|
||||
|
||||
👉 это НЕ генерирует SLA
|
||||
|
||||
---
|
||||
|
||||
## 1.2. Твоя роль канала
|
||||
|
||||
Твой Telegram — это:
|
||||
|
||||
# “инженерный журнал рисков объектов”
|
||||
|
||||
Не маркетинг. Не реклама. Не блог.
|
||||
|
||||
---
|
||||
|
||||
## 1.3. Главная цель Telegram
|
||||
|
||||
Не подписки.
|
||||
|
||||
А:
|
||||
|
||||
> заявки на аудит
|
||||
|
||||
---
|
||||
|
||||
# 2. СТРУКТУРА TELEGRAM-КАНАЛА
|
||||
|
||||
---
|
||||
|
||||
## 2.1. Закреп (ОБЯЗАТЕЛЬНО)
|
||||
|
||||
```text
|
||||
Мы занимаемся инженерной эксплуатацией систем безопасности коммерческих объектов.
|
||||
|
||||
Перед обслуживанием всегда проводим технический аудит:
|
||||
— видеонаблюдение
|
||||
— СКУД
|
||||
— пожарная сигнализация
|
||||
— инфраструктура
|
||||
|
||||
Цель — выявить скрытые риски, которые не видны в ежедневной работе.
|
||||
|
||||
📌 Если нужно — можем провести аудит объекта и выдать инженерное заключение.
|
||||
|
||||
Написать: @your_contact
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2.2. 3 типа контента (ВСЕГДА)
|
||||
|
||||
---
|
||||
|
||||
### 1) РИСКИ (60%)
|
||||
|
||||
👉 основа роста
|
||||
|
||||
Примеры:
|
||||
|
||||
- “Почему архив видеонаблюдения исчезает незаметно”
|
||||
- “Почему пожарка работает, но не защищает”
|
||||
- “3 скрытые ошибки СКУД”
|
||||
|
||||
---
|
||||
|
||||
### 2) КЕЙСЫ (25%)
|
||||
|
||||
👉 доверие
|
||||
|
||||
Примеры:
|
||||
|
||||
- “Аудит склада: 12 критических ошибок”
|
||||
- “Гостиница без резервного питания”
|
||||
|
||||
---
|
||||
|
||||
### 3) ЭКСПЕРТИЗА (15%)
|
||||
|
||||
👉 статус
|
||||
|
||||
Примеры:
|
||||
|
||||
- “Как должен выглядеть нормальный SLA”
|
||||
- “Что проверяет инженер, а не монтажник”
|
||||
|
||||
---
|
||||
|
||||
# 2.3. ФОРМАТ ПОСТОВ (СТАНДАРТ)
|
||||
|
||||
```text
|
||||
1. Проблема
|
||||
2. Инженерное объяснение
|
||||
3. Последствия для бизнеса
|
||||
4. Спокойный вывод
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Пример готового поста
|
||||
|
||||
```text
|
||||
Большинство объектов уверены, что видеонаблюдение работает корректно.
|
||||
|
||||
На практике часто есть скрытая проблема — архив.
|
||||
|
||||
Камеры могут показывать картинку, но запись:
|
||||
— не сохраняется полностью
|
||||
— перезаписывается раньше срока
|
||||
— теряет часть каналов
|
||||
— сбоит из-за питания или дисков
|
||||
|
||||
Это не видно в ежедневной работе.
|
||||
|
||||
Проблема проявляется только после инцидента.
|
||||
|
||||
По сути, система существует, но не выполняет свою функцию хранения доказательной базы.
|
||||
|
||||
Именно поэтому видеонаблюдение нужно рассматривать как систему эксплуатации, а не просто установленное оборудование.
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# 2.4. CTA (ОЧЕНЬ ВАЖНО)
|
||||
|
||||
Каждый 3–4 пост:
|
||||
|
||||
```text
|
||||
Если нужно — можем провести технический аудит объекта и проверить состояние систем безопасности.
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# 2.5. ЛИД-МАГНИТ (ОЧЕНЬ СИЛЬНЫЙ РЫЧАГ)
|
||||
|
||||
---
|
||||
|
||||
## PDF:
|
||||
|
||||
# “Чек-лист скрытых рисков систем безопасности”
|
||||
|
||||
или
|
||||
|
||||
# “10 ошибок эксплуатации объектов”
|
||||
|
||||
---
|
||||
|
||||
## Telegram пост:
|
||||
|
||||
```text
|
||||
Мы собрали чек-лист из 10 критических ошибок, которые встречаются на большинстве объектов.
|
||||
|
||||
Если хотите — отправим бесплатно.
|
||||
```
|
||||
|
||||
👉 это даёт первые контакты без давления
|
||||
|
||||
---
|
||||
|
||||
# 3. TELEGRAM → ВОРОНКА
|
||||
|
||||
```text
|
||||
Контент
|
||||
↓
|
||||
Интерес
|
||||
↓
|
||||
Чек-лист / диалог
|
||||
↓
|
||||
Диагностика (мини-аудит)
|
||||
↓
|
||||
Полный аудит
|
||||
↓
|
||||
SLA
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# 4. CRM-ВОРОНКА ПОД SLA
|
||||
|
||||
Теперь самое важное.
|
||||
|
||||
Ты не продаёшь “услуги”. Ты ведёшь объекты по состояниям.
|
||||
|
||||
---
|
||||
|
||||
# 4.1. СТРУКТУРА CRM (СТАДИИ)
|
||||
|
||||
---
|
||||
|
||||
## 1. ЛИД
|
||||
|
||||
Источник:
|
||||
|
||||
- Telegram
|
||||
- сайт
|
||||
- партнер
|
||||
- холодный контакт
|
||||
|
||||
---
|
||||
|
||||
## 2. ПЕРВИЧНЫЙ КОНТАКТ
|
||||
|
||||
- написал / ответил
|
||||
- уточнение объекта
|
||||
|
||||
---
|
||||
|
||||
## 3. КВАЛИФИКАЦИЯ
|
||||
|
||||
Вопросы:
|
||||
|
||||
- тип объекта
|
||||
- системы
|
||||
- есть ли подрядчик
|
||||
- проблемы
|
||||
|
||||
---
|
||||
|
||||
## 4. ДИАГНОСТИКА (мини-аудит)
|
||||
|
||||
- быстрый осмотр
|
||||
- удаленно или выезд
|
||||
- выявление боли
|
||||
|
||||
---
|
||||
|
||||
## 5. ПОЛНЫЙ АУДИТ
|
||||
|
||||
- инженерный выезд
|
||||
- отчет
|
||||
- риски
|
||||
|
||||
---
|
||||
|
||||
## 6. ПРЕДЛОЖЕНИЕ SLA
|
||||
|
||||
- тариф
|
||||
- регламент
|
||||
- реакция
|
||||
|
||||
---
|
||||
|
||||
## 7. ПЕРЕГОВОРЫ
|
||||
|
||||
- согласование цены
|
||||
- условия
|
||||
|
||||
---
|
||||
|
||||
## 8. ДОГОВОР SLA
|
||||
|
||||
- подписан
|
||||
- объект активен
|
||||
|
||||
---
|
||||
|
||||
## 9. АКТИВНЫЙ SLA
|
||||
|
||||
- обслуживание
|
||||
- отчёты
|
||||
|
||||
---
|
||||
|
||||
## 10. РАСШИРЕНИЕ
|
||||
|
||||
- новые объекты
|
||||
- доп. системы
|
||||
|
||||
---
|
||||
|
||||
# 4.2. ВИЗУАЛЬНАЯ CRM-СХЕМА
|
||||
|
||||
```text
|
||||
ЛИД
|
||||
↓
|
||||
КОНТАКТ
|
||||
↓
|
||||
КВАЛИФИКАЦИЯ
|
||||
↓
|
||||
МИНИ-ДИАГНОСТИКА
|
||||
↓
|
||||
АУДИТ
|
||||
↓
|
||||
SLA ОФФЕР
|
||||
↓
|
||||
ДОГОВОР
|
||||
↓
|
||||
ОБСЛУЖИВАНИЕ
|
||||
↓
|
||||
РАСШИРЕНИЕ
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# 5. ПРОСТАЯ CRM В ТАБЛИЦЕ (СТАРТ)
|
||||
|
||||
Если без софта:
|
||||
|
||||
|Клиент|Объект|Статус|Проблема|Этап|Потенциал|
|
||||
|---|---|---|---|---|---|
|
||||
|X|гостиница|аудит|нет архива|прогрев|80k/мес|
|
||||
|
||||
---
|
||||
|
||||
# 6. КЛЮЧЕВОЙ ПРИНЦИП CRM
|
||||
|
||||
Ты не ведёшь “продажи”.
|
||||
|
||||
Ты ведёшь:
|
||||
|
||||
# инженерные объекты
|
||||
|
||||
---
|
||||
|
||||
# 7. МЕТРИКА УСПЕХА (ВАЖНО)
|
||||
|
||||
Не:
|
||||
|
||||
- подписчики
|
||||
- заявки
|
||||
|
||||
А:
|
||||
|
||||
## 1 объект = SLA контракт
|
||||
|
||||
---
|
||||
|
||||
# 8. РОЛЬ TELEGRAM В МОДЕЛИ ДЕНЕГ
|
||||
|
||||
```text
|
||||
Telegram = генератор доверия
|
||||
Аудит = генератор денег входа
|
||||
SLA = генератор повторного дохода
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# 9. СИСТЕМА РОСТА (СВЯЗКА ВСЕГО)
|
||||
|
||||
```text
|
||||
Контент (Telegram)
|
||||
↓
|
||||
Диалог
|
||||
↓
|
||||
Аудит
|
||||
↓
|
||||
SLA контракт
|
||||
↓
|
||||
Постоянный доход
|
||||
↓
|
||||
Масштаб через инженеров
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# 10. СЛЕДУЮЩИЙ УРОВЕНЬ (если хочешь усилить систему)
|
||||
|
||||
Я могу дальше собрать тебе:
|
||||
|
||||
### 1. Полную CRM в Notion / 1C структуру под SLA
|
||||
|
||||
### 2. Скрипт “закрытия в SLA после аудита”
|
||||
|
||||
### 3. Таблицу квалификации клиента (кого брать/кого нет)
|
||||
|
||||
### 4. Финмодель роста до 3 млн+
|
||||
|
||||
### 5. Регламент инженера (чтобы масштабировать команду)
|
||||
|
||||
---
|
||||
|
||||
Если коротко: ты сейчас строишь не маркетинг, а:
|
||||
|
||||
> инженерную подписочную сервисную компанию
|
||||
|
||||
И Telegram + CRM — это её нервная система.
|
||||
@@ -0,0 +1,537 @@
|
||||
Ниже — полноценная модель **“Дашборд инженера (тимлид / руководитель техников)”** для AegisOne Engineering.
|
||||
|
||||
Это ключевой слой между:
|
||||
|
||||
- техник → (исполнение)
|
||||
- директор → (управление системой)
|
||||
|
||||
Инженер тут не “старший техник”, а:
|
||||
|
||||
> операционный контроллер SLA, качества и рисков на объектах
|
||||
|
||||
---
|
||||
|
||||
# 1. РОЛЬ ИНЖЕНЕРА В СИСТЕМЕ
|
||||
|
||||
## 1.1 Основная функция
|
||||
|
||||
```text
|
||||
Инженер = управление качеством исполнения SLA + распределение нагрузки + контроль рисков объектов
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 1.2 Он НЕ делает:
|
||||
|
||||
- не чинит оборудование (это техник)
|
||||
- не продаёт SLA (это коммерция)
|
||||
- не ведёт бухгалтерию
|
||||
|
||||
---
|
||||
|
||||
## 1.3 Он ДЕЛАЕТ:
|
||||
|
||||
- распределяет заявки
|
||||
- контролирует SLA
|
||||
- проверяет качество работ
|
||||
- снижает инциденты
|
||||
- управляет техниками
|
||||
- влияет на SHS
|
||||
|
||||
---
|
||||
|
||||
# 2. АРХИТЕКТУРА DASHBOARD ИНЖЕНЕРА
|
||||
|
||||
```text
|
||||
CEO DASHBOARD
|
||||
↓
|
||||
ENGINEER DASHBOARD
|
||||
↓
|
||||
TECHNICIAN DASHBOARD
|
||||
↓
|
||||
OBJECT SYSTEMS
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# 3. DASHBOARD ИНЖЕНЕРА (REAL-TIME)
|
||||
|
||||
## 3.1 Главные блоки интерфейса
|
||||
|
||||
### Блок 1 — SLA контроль региона
|
||||
|
||||
- SLA compliance (%)
|
||||
- просроченные заявки
|
||||
- риск нарушения SLA
|
||||
- критические объекты
|
||||
|
||||
---
|
||||
|
||||
### Блок 2 — команда техников
|
||||
|
||||
- загрузка каждого техника
|
||||
- эффективность
|
||||
- ошибки / reopen rate
|
||||
- скорость реакции
|
||||
|
||||
---
|
||||
|
||||
### Блок 3 — инциденты
|
||||
|
||||
- P1 / P2 / P3
|
||||
- открытые критические
|
||||
- повторяющиеся аварии
|
||||
|
||||
---
|
||||
|
||||
### Блок 4 — объекты
|
||||
|
||||
- риск-уровень (Risk Score)
|
||||
- SHS влияние объекта
|
||||
- проблемные системы
|
||||
|
||||
---
|
||||
|
||||
### Блок 5 — KPI инженера
|
||||
|
||||
- качество управления SLA
|
||||
- распределение нагрузки
|
||||
- снижение инцидентов
|
||||
- эффективность команды
|
||||
|
||||
---
|
||||
|
||||
# 4. PHP АРХИТЕКТУРА
|
||||
|
||||
---
|
||||
|
||||
## 4.1 API инженера
|
||||
|
||||
```php
|
||||
<?php
|
||||
header('Content-Type: application/json');
|
||||
|
||||
$pdo = new PDO("mysql:host=localhost;dbname=aegisone","user","pass");
|
||||
|
||||
$data = $pdo->query("
|
||||
SELECT
|
||||
e.id,
|
||||
e.name,
|
||||
|
||||
AVG(t.sla_compliance) as sla,
|
||||
COUNT(i.id) as incidents,
|
||||
AVG(t.response_time) as response_time
|
||||
|
||||
FROM engineers e
|
||||
LEFT JOIN tasks t ON t.engineer_id = e.id
|
||||
LEFT JOIN incidents i ON i.engineer_id = e.id
|
||||
|
||||
GROUP BY e.id
|
||||
")->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
echo json_encode($data);
|
||||
?>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4.2 SHS ENGINEER IMPACT API
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
header('Content-Type: application/json');
|
||||
|
||||
$pdo = new PDO("mysql:host=localhost;dbname=aegisone","user","pass");
|
||||
|
||||
$k = $pdo->query("
|
||||
SELECT
|
||||
AVG(sla_compliance) as sla,
|
||||
AVG(response_time) as rt,
|
||||
AVG(reopen_rate) as rr
|
||||
FROM tasks
|
||||
")->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
/* Engineer Impact on SHS */
|
||||
$EIS =
|
||||
(0.5 * $k['sla']) +
|
||||
(0.3 * (1 - $k['rr'])) +
|
||||
(0.2 * (1 - $k['rt']/10));
|
||||
|
||||
echo json_encode([
|
||||
"ENGINEER_IMPACT_SCORE" => round($EIS * 100, 2)
|
||||
]);
|
||||
?>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# 5. ФОРМУЛЫ ИНЖЕНЕРА (КРИТИЧЕСКИЕ KPI)
|
||||
|
||||
---
|
||||
|
||||
## 5.1 ENGINEER CONTROL SCORE (ECS)
|
||||
|
||||
```text
|
||||
ECS =
|
||||
(0.30 × SLA Compliance Control)
|
||||
+ (0.25 × Task Distribution Efficiency)
|
||||
+ (0.20 × Incident Reduction Rate)
|
||||
+ (0.15 × Team Performance Score)
|
||||
+ (0.10 × Response Coordination Speed)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5.2 SLA CONTROL INDEX
|
||||
|
||||
```text
|
||||
SCI = closed_tasks_in_SLA / total_tasks
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5.3 TEAM LOAD BALANCE
|
||||
|
||||
```text
|
||||
TLB = std_dev(tasks_per_engineer)
|
||||
```
|
||||
|
||||
👉 чем меньше → тем лучше распределение
|
||||
|
||||
---
|
||||
|
||||
## 5.4 INCIDENT REDUCTION RATE
|
||||
|
||||
```text
|
||||
IRR = (incidents_previous - incidents_current) / incidents_previous
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5.5 ESCALATION RATE
|
||||
|
||||
```text
|
||||
ER = escalated_tasks / total_tasks
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# 6. DASHBOARD (HTML + JS)
|
||||
|
||||
---
|
||||
|
||||
## 6.1 HTML
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Engineer Control Panel</title>
|
||||
|
||||
<style>
|
||||
body { background:#0f172a; color:white; font-family:Arial; }
|
||||
|
||||
.grid {
|
||||
display:grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap:15px;
|
||||
padding:20px;
|
||||
}
|
||||
|
||||
.card {
|
||||
background:#1e293b;
|
||||
padding:15px;
|
||||
border-radius:12px;
|
||||
}
|
||||
|
||||
.big { font-size:28px; font-weight:bold; }
|
||||
.green { color:#22c55e; }
|
||||
.yellow { color:#facc15; }
|
||||
.red { color:#ef4444; }
|
||||
</style>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<h2 style="padding:20px;">Engineer Live Dashboard</h2>
|
||||
|
||||
<div class="grid">
|
||||
|
||||
<div class="card">
|
||||
<div>SLA Control</div>
|
||||
<div id="sla" class="big">--</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div>Engineer Impact (SHS)</div>
|
||||
<div id="shs" class="big">--</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div>Incidents</div>
|
||||
<div id="inc" class="big">--</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div id="team"></div>
|
||||
|
||||
<script src="engineer.js"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6.2 JS realtime
|
||||
|
||||
```javascript
|
||||
async function loadEngineer(){
|
||||
|
||||
const res = await fetch('/api/engineer.php');
|
||||
const data = await res.json();
|
||||
|
||||
let sla = 0;
|
||||
let inc = 0;
|
||||
|
||||
let html = "";
|
||||
|
||||
data.forEach(e => {
|
||||
|
||||
sla += parseFloat(e.sla);
|
||||
inc += parseInt(e.incidents);
|
||||
|
||||
let color =
|
||||
e.sla > 0.9 ? "green" :
|
||||
e.sla > 0.75 ? "yellow" : "red";
|
||||
|
||||
html += `
|
||||
<div class="card">
|
||||
<h3>${e.name}</h3>
|
||||
|
||||
<p>SLA: <b class="${color}">
|
||||
${(e.sla * 100).toFixed(1)}%
|
||||
</b></p>
|
||||
|
||||
<p>Incidents: ${e.incidents}</p>
|
||||
<p>Response: ${e.response_time}</p>
|
||||
</div>
|
||||
`;
|
||||
});
|
||||
|
||||
document.getElementById("team").innerHTML = html;
|
||||
|
||||
document.getElementById("sla").innerText =
|
||||
((sla / data.length) * 100).toFixed(1) + "%";
|
||||
|
||||
document.getElementById("inc").innerText = inc;
|
||||
|
||||
let shs = (sla / data.length) * 100 - inc * 0.5;
|
||||
|
||||
document.getElementById("shs").innerText =
|
||||
shs.toFixed(1);
|
||||
}
|
||||
|
||||
setInterval(loadEngineer, 15000);
|
||||
loadEngineer();
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# 7. ДОКУМЕНТЫ ИНЖЕНЕРА (ОБЯЗАТЕЛЬНЫЕ)
|
||||
|
||||
---
|
||||
|
||||
## 7.1 РЕГЛАМЕНТ ИНЖЕНЕРА
|
||||
|
||||
```text
|
||||
AegisOne Engineering
|
||||
Engineer Operational Standard
|
||||
|
||||
1. Назначение
|
||||
Инженер отвечает за выполнение SLA и контроль качества работ техников.
|
||||
|
||||
---
|
||||
|
||||
2. Обязанности
|
||||
|
||||
- распределение заявок
|
||||
- контроль SLA выполнения
|
||||
- контроль качества диагностики
|
||||
- управление инцидентами
|
||||
- предотвращение повторных аварий
|
||||
|
||||
---
|
||||
|
||||
3. Запрещено
|
||||
|
||||
- закрывать задачи без проверки
|
||||
- игнорировать SLA нарушения
|
||||
- делегировать без фиксации
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7.2 ESCALATION MATRIX
|
||||
|
||||
```text
|
||||
P1 → инженер → директор (немедленно)
|
||||
P2 → инженер → инженер контроль
|
||||
P3 → техник
|
||||
|
||||
Если SLA риск > 80%:
|
||||
→ обязательная эскалация
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7.3 ЧЕК-ЛИСТ ИНЖЕНЕРА
|
||||
|
||||
```text
|
||||
AegisOne Engineering
|
||||
Engineer Control Checklist
|
||||
|
||||
[ ] Все заявки распределены
|
||||
[ ] SLA риск оценён
|
||||
[ ] Техники назначены
|
||||
[ ] P1 инциденты закрыты
|
||||
[ ] Повторные аварии проанализированы
|
||||
[ ] Отчёты проверены
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7.4 ОТЧЁТ ИНЖЕНЕРА
|
||||
|
||||
```text
|
||||
Engineer Report
|
||||
|
||||
Период:
|
||||
Инженер:
|
||||
|
||||
---
|
||||
|
||||
1. SLA состояние:
|
||||
-
|
||||
|
||||
2. Проблемные объекты:
|
||||
-
|
||||
|
||||
3. Инциденты:
|
||||
-
|
||||
|
||||
4. Перегруз команды:
|
||||
-
|
||||
|
||||
5. Принятые меры:
|
||||
-
|
||||
|
||||
6. Риски:
|
||||
-
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# 8. ЧТО ИНЖЕНЕР ДОЛЖЕН ИМЕТЬ В СИСТЕМЕ
|
||||
|
||||
---
|
||||
|
||||
## ОБЯЗАТЕЛЬНО:
|
||||
|
||||
- SLA статус всех объектов
|
||||
- список техников
|
||||
- инциденты P1–P3
|
||||
- риск объектов
|
||||
- SHS влияние
|
||||
|
||||
---
|
||||
|
||||
## РЕКОМЕНДУЕМО:
|
||||
|
||||
- история объектов
|
||||
- схемы систем
|
||||
- фото оборудования
|
||||
- прошлые ремонты
|
||||
- нагрузка по часам
|
||||
|
||||
---
|
||||
|
||||
# 9. ЧТО ЕМУ НЕЛЬЗЯ ДАВАТЬ
|
||||
|
||||
---
|
||||
|
||||
## КАТЕГОРИЧЕСКИ НЕ НУЖНО:
|
||||
|
||||
- прямые продажи
|
||||
- финансовые данные прибыли
|
||||
- доступ к CRM сделкам
|
||||
- доступ к договорам без SLA слоя
|
||||
- административные функции директора
|
||||
|
||||
---
|
||||
|
||||
# 10. РИСКИ СИСТЕМЫ
|
||||
|
||||
---
|
||||
|
||||
## РИСК 1 — инженер превращается в диспетчера
|
||||
|
||||
👉 решение:
|
||||
|
||||
- оставить KPI, а не “ручное управление”
|
||||
|
||||
---
|
||||
|
||||
## РИСК 2 — перегруз инженера
|
||||
|
||||
👉 решение:
|
||||
|
||||
- TLB (load balance)
|
||||
|
||||
---
|
||||
|
||||
## РИСК 3 — потеря SLA контроля
|
||||
|
||||
👉 решение:
|
||||
|
||||
- SHS alert system
|
||||
|
||||
---
|
||||
|
||||
# 11. ГЛАВНАЯ ЛОГИКА
|
||||
|
||||
```text
|
||||
Техник → выполняет
|
||||
Инженер → управляет качеством
|
||||
Директор → управляет системой
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# 12. ИТОГ
|
||||
|
||||
Ты получаешь:
|
||||
|
||||
> управляемый слой контроля SLA между исполнением и бизнесом
|
||||
|
||||
---
|
||||
|
||||
# 13. ЕСЛИ РАЗВИВАТЬ ДАЛЬШЕ
|
||||
|
||||
Я могу собрать:
|
||||
|
||||
- автораспределение заявок (AI dispatch)
|
||||
- прогноз поломок объектов
|
||||
- система “умного SLA риска”
|
||||
- мобильный кабинет инженера
|
||||
- интеграция с Telegram уведомлениями
|
||||
|
||||
---
|
||||
|
||||
Если коротко:
|
||||
|
||||
👉 это уже не “дашборд”
|
||||
👉 это уровень операционной системы инженерного бизнеса (mini-SAP под твою нишу)
|
||||
@@ -0,0 +1,424 @@
|
||||
Ниже — полноценная система **“Дашборд техника в реальном времени” + пакет документов и инструкций**, который превращает техника не в “исполнителя заявок”, а в **узел управляемой SLA-системы**.
|
||||
|
||||
Я разделю на 3 уровня:
|
||||
|
||||
1. Дашборд техника (web / PHP система)
|
||||
2. Документы и регламенты (полные тексты)
|
||||
3. Шаблоны (акты, чек-листы, отчёты)
|
||||
|
||||
---
|
||||
|
||||
# 1. DASHBOARD ТЕХНИКА (REAL-TIME)
|
||||
|
||||
## 1.1 Логика системы
|
||||
|
||||
```text
|
||||
Заявка → Назначение → Выезд → Диагностика → Исполнение → Закрытие → SLA фиксация → SHS влияние
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 1.2 Что должен видеть техник (главное)
|
||||
|
||||
### Блок 1 — текущая нагрузка
|
||||
|
||||
- активные заявки
|
||||
- срочность (P1–P3)
|
||||
- дедлайн SLA
|
||||
- расстояние до объекта
|
||||
- статус выполнения
|
||||
|
||||
---
|
||||
|
||||
### Блок 2 — SLA контроль
|
||||
|
||||
- осталось времени до нарушения SLA
|
||||
- критичность заявки
|
||||
- штрафной риск
|
||||
|
||||
---
|
||||
|
||||
### Блок 3 — оборудование объекта
|
||||
|
||||
- камеры / СКУД / пожарка
|
||||
- история неисправностей
|
||||
- последние ремонты
|
||||
|
||||
---
|
||||
|
||||
### Блок 4 — чек-лист работ
|
||||
|
||||
- пошаговый регламент
|
||||
- обязательные проверки
|
||||
- фотофиксация
|
||||
|
||||
---
|
||||
|
||||
### Блок 5 — результат
|
||||
|
||||
- закрытие заявки
|
||||
- причина
|
||||
- подтверждение клиента
|
||||
- влияние на KPI
|
||||
|
||||
---
|
||||
|
||||
# 2. PHP ДАШБОРД ТЕХНИКА (ГОТОВЫЙ ШАБЛОН)
|
||||
|
||||
---
|
||||
|
||||
## 2.1 API задач техника
|
||||
|
||||
```php
|
||||
<?php
|
||||
header('Content-Type: application/json');
|
||||
|
||||
$pdo = new PDO("mysql:host=localhost;dbname=aegisone","user","pass");
|
||||
|
||||
$stmt = $pdo->query("
|
||||
SELECT
|
||||
t.id,
|
||||
t.title,
|
||||
t.priority,
|
||||
t.status,
|
||||
t.deadline,
|
||||
t.address,
|
||||
t.system_type,
|
||||
t.sla_remaining_hours
|
||||
FROM tasks t
|
||||
WHERE t.status != 'closed'
|
||||
ORDER BY t.priority DESC, t.deadline ASC
|
||||
");
|
||||
|
||||
echo json_encode($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||
?>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2.2 FRONTEND (ТЕХНИК DASHBOARD)
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Technician Panel - AegisOne</title>
|
||||
|
||||
<style>
|
||||
body { background:#0f172a; color:white; font-family:Arial; }
|
||||
.card { background:#1e293b; padding:15px; margin:10px; border-radius:10px; }
|
||||
.grid { display:grid; grid-template-columns: repeat(2, 1fr); gap:10px; }
|
||||
.red { color:#ef4444; }
|
||||
.yellow { color:#facc15; }
|
||||
.green { color:#22c55e; }
|
||||
</style>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<h2 style="padding:10px;">Technician Live Dashboard</h2>
|
||||
|
||||
<div id="tasks"></div>
|
||||
|
||||
<script src="tech.js"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2.3 JS realtime обновление
|
||||
|
||||
```javascript
|
||||
async function loadTasks(){
|
||||
const res = await fetch('/api/tech_tasks.php');
|
||||
const data = await res.json();
|
||||
|
||||
let html = "";
|
||||
|
||||
data.forEach(t => {
|
||||
|
||||
let color =
|
||||
t.sla_remaining_hours < 2 ? "red" :
|
||||
t.sla_remaining_hours < 6 ? "yellow" : "green";
|
||||
|
||||
html += `
|
||||
<div class="card">
|
||||
<h3>${t.title}</h3>
|
||||
|
||||
<p><b>Priority:</b> ${t.priority}</p>
|
||||
<p><b>Address:</b> ${t.address}</p>
|
||||
<p><b>System:</b> ${t.system_type}</p>
|
||||
|
||||
<p><b>SLA:</b>
|
||||
<span class="${color}">
|
||||
${t.sla_remaining_hours}h left
|
||||
</span>
|
||||
</p>
|
||||
|
||||
<button onclick="startTask(${t.id})">Start</button>
|
||||
<button onclick="closeTask(${t.id})">Close</button>
|
||||
</div>
|
||||
`;
|
||||
});
|
||||
|
||||
document.getElementById("tasks").innerHTML = html;
|
||||
}
|
||||
|
||||
setInterval(loadTasks, 10000);
|
||||
loadTasks();
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# 3. ДОКУМЕНТЫ ДЛЯ ТЕХНИКА (ОБЯЗАТЕЛЬНЫЕ)
|
||||
|
||||
---
|
||||
|
||||
# 3.1 РЕГЛАМЕНТ РАБОТЫ ТЕХНИКА
|
||||
|
||||
```text
|
||||
AegisOne Engineering
|
||||
Регламент работы инженера-техника
|
||||
|
||||
1. Общие положения
|
||||
|
||||
Техник обязан выполнять работы строго по SLA и чек-листу объекта.
|
||||
Любое отклонение фиксируется в системе.
|
||||
|
||||
---
|
||||
|
||||
2. Прибытие на объект
|
||||
|
||||
- зарегистрировать прибытие в системе
|
||||
- подтвердить время начала работ
|
||||
- сделать фото объекта до начала работ
|
||||
|
||||
---
|
||||
|
||||
3. Диагностика
|
||||
|
||||
- проверить систему по чек-листу
|
||||
- зафиксировать неисправности
|
||||
- определить причину (если возможно)
|
||||
|
||||
---
|
||||
|
||||
4. Выполнение работ
|
||||
|
||||
- устранить неисправность
|
||||
- не изменять конфигурацию без согласования
|
||||
- использовать только разрешённые материалы
|
||||
|
||||
---
|
||||
|
||||
5. Завершение работ
|
||||
|
||||
- тестирование системы
|
||||
- фото после выполнения
|
||||
- подтверждение работоспособности
|
||||
|
||||
---
|
||||
|
||||
6. Закрытие заявки
|
||||
|
||||
- заполнить отчет
|
||||
- указать причину неисправности
|
||||
- получить подтверждение клиента (если возможно)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# 3.2 ЧЕК-ЛИСТ ВЫЕЗДА
|
||||
|
||||
```text
|
||||
AegisOne Engineering
|
||||
Checklist Technician Visit
|
||||
|
||||
[ ] Прибытие на объект зафиксировано
|
||||
[ ] Фото “до”
|
||||
[ ] Проверка питания системы
|
||||
[ ] Проверка камер / датчиков
|
||||
[ ] Проверка СКУД
|
||||
[ ] Проверка пожарной панели
|
||||
[ ] Локализация неисправности
|
||||
[ ] Устранение проблемы
|
||||
[ ] Тестирование системы
|
||||
[ ] Фото “после”
|
||||
[ ] Закрытие заявки
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# 3.3 СТАНДАРТ ДИАГНОСТИКИ
|
||||
|
||||
```text
|
||||
AegisOne Engineering
|
||||
Diagnostic Standard
|
||||
|
||||
1. Неисправность фиксируется только после проверки:
|
||||
- питания
|
||||
- сети
|
||||
- оборудования
|
||||
- конфигурации
|
||||
|
||||
2. Причина должна быть классифицирована:
|
||||
|
||||
- Hardware
|
||||
- Software
|
||||
- Network
|
||||
- Human error
|
||||
- External factor
|
||||
|
||||
3. Запрещено:
|
||||
- закрывать заявку без причины
|
||||
- менять систему без фиксации
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# 3.4 ОТЧЁТ ТЕХНИКА (ШАБЛОН)
|
||||
|
||||
```text
|
||||
AegisOne Engineering
|
||||
Technician Report
|
||||
|
||||
Объект:
|
||||
Дата:
|
||||
Техник:
|
||||
|
||||
---
|
||||
|
||||
1. Выполненные работы:
|
||||
-
|
||||
|
||||
2. Выявленные проблемы:
|
||||
-
|
||||
|
||||
3. Причина неисправности:
|
||||
(Hardware / Software / Network / Other)
|
||||
|
||||
4. Что было сделано:
|
||||
-
|
||||
|
||||
5. Результат:
|
||||
[ ] Исправлено
|
||||
[ ] Частично исправлено
|
||||
[ ] Требует повторного выезда
|
||||
|
||||
6. Фото до/после:
|
||||
(вложение)
|
||||
|
||||
7. Комментарий:
|
||||
-
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# 4. ОБЯЗАТЕЛЬНЫЕ ДАННЫЕ ТЕХНИКА В СИСТЕМЕ
|
||||
|
||||
---
|
||||
|
||||
## 4.1 Минимум данных
|
||||
|
||||
- текущие заявки
|
||||
- SLA таймер
|
||||
- адрес объекта
|
||||
- тип системы
|
||||
- приоритет
|
||||
|
||||
---
|
||||
|
||||
## 4.2 Рекомендуемые данные
|
||||
|
||||
- история объекта
|
||||
- прошлые неисправности
|
||||
- схема оборудования
|
||||
- контакт ответственного
|
||||
- тип неисправности по базе
|
||||
|
||||
---
|
||||
|
||||
# 5. КЛЮЧЕВАЯ ЛОГИКА СИСТЕМЫ
|
||||
|
||||
```text
|
||||
Техник не “чинит оборудование”
|
||||
|
||||
Техник:
|
||||
→ закрывает SLA
|
||||
→ влияет на SHS
|
||||
→ формирует retention
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# 6. КОНТРОЛЬ РИСКОВ
|
||||
|
||||
---
|
||||
|
||||
## РИСК 1 — “закрытие без факта”
|
||||
|
||||
👉 решение:
|
||||
|
||||
- фотофиксация обязательна
|
||||
|
||||
---
|
||||
|
||||
## РИСК 2 — “ложное устранение”
|
||||
|
||||
👉 решение:
|
||||
|
||||
- reopen rate KPI
|
||||
|
||||
---
|
||||
|
||||
## РИСК 3 — перегруз техника
|
||||
|
||||
👉 решение:
|
||||
|
||||
- utilization tracking
|
||||
|
||||
---
|
||||
|
||||
## РИСК 4 — нарушение SLA
|
||||
|
||||
👉 решение:
|
||||
|
||||
- live SLA countdown
|
||||
|
||||
---
|
||||
|
||||
# 7. ИТОГОВАЯ МОДЕЛЬ
|
||||
|
||||
```text
|
||||
CRM → SLA → TASK → TECH DASHBOARD → EXECUTION → KPI → SHS
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# 8. СУТЬ СИСТЕМЫ
|
||||
|
||||
Ты создаёшь не “работу техника”:
|
||||
|
||||
> ты создаёшь управляемый процесс физической эксплуатации инфраструктуры бизнеса
|
||||
|
||||
---
|
||||
|
||||
# 9. ЕСЛИ ДАЛЬШЕ РАЗВИВАТЬ
|
||||
|
||||
Можно собрать:
|
||||
|
||||
- мобильное приложение техника (PWA)
|
||||
- GPS контроль выездов
|
||||
- автоакты выполненных работ
|
||||
- голосовые отчёты
|
||||
- AI диагностику неисправностей
|
||||
- автоматическое распределение заявок
|
||||
|
||||
---
|
||||
|
||||
Если хочешь следующий шаг:
|
||||
|
||||
👉 я могу объединить дашборд техника + инженера + CEO в одну единую систему управления AegisOne (как ERP уровня SAP, но для твоей ниши)
|
||||
@@ -0,0 +1,574 @@
|
||||
Ниже — система, которая делает тебя не “компанией по безопасности”, а:
|
||||
|
||||
доказательным инженерным экспертом
|
||||
|
||||
Это ключевой переход.
|
||||
Потому что рынок верит не словам, а:
|
||||
|
||||
> измерениям, проверкам и воспроизводимым результатам
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
0. ЧТО ТАКОЕ “ДОКАЗАТЕЛЬНАЯ ЭКСПЕРТИЗА”
|
||||
|
||||
Это подход, где каждое твоё утверждение:
|
||||
|
||||
проверяется тестом
|
||||
|
||||
фиксируется
|
||||
|
||||
документируется
|
||||
|
||||
повторяется на любом объекте
|
||||
|
||||
подтверждается результатом
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
1. ГЛАВНАЯ ИДЕЯ СИСТЕМЫ
|
||||
|
||||
Ты перестаёшь говорить:
|
||||
|
||||
❌ “у вас плохое обслуживание”
|
||||
❌ “система работает неправильно”
|
||||
|
||||
Ты начинаешь говорить:
|
||||
|
||||
✔ “мы провели тест №X”
|
||||
✔ “результат измерен”
|
||||
✔ “отклонение от нормы”
|
||||
✔ “риск подтверждён”
|
||||
|
||||
|
||||
---
|
||||
|
||||
2. СТРУКТУРА СИСТЕМЫ ДОКАЗАТЕЛЬНОСТИ
|
||||
|
||||
3. Тест (что проверяем)
|
||||
4. Методика (как проверяем)
|
||||
5. Норма (как должно быть)
|
||||
6. Фактический результат
|
||||
7. Отклонение
|
||||
8. Риск для бизнеса
|
||||
9. Вывод инженера
|
||||
|
||||
|
||||
---
|
||||
|
||||
3. БАЗОВЫЕ ТЕСТЫ (ЯДРО ТВОЕЙ ЭКСПЕРТИЗЫ)
|
||||
|
||||
|
||||
---
|
||||
|
||||
ТЕСТ №1 — РЕАЛЬНОСТЬ АРХИВА ВИДЕОНАБЛЮДЕНИЯ
|
||||
|
||||
|
||||
---
|
||||
|
||||
🔧 Методика
|
||||
|
||||
Выборочно проверяется запись с камер за последние:
|
||||
- 1 день
|
||||
- 7 дней
|
||||
- 14 дней
|
||||
- 30 дней
|
||||
|
||||
Проверяется:
|
||||
- наличие записи
|
||||
- непрерывность
|
||||
- пропуски
|
||||
- доступность воспроизведения
|
||||
|
||||
|
||||
---
|
||||
|
||||
📏 Норма
|
||||
|
||||
запись 100% камер
|
||||
|
||||
непрерывность без пропусков
|
||||
|
||||
доступность архива согласно заявленному сроку
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
📉 Частая реальность
|
||||
|
||||
часть камер не пишет
|
||||
|
||||
архив “дыры”
|
||||
|
||||
перезапись раньше срока
|
||||
|
||||
сбои HDD
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
⚠️ Риск
|
||||
|
||||
> Потеря доказательной базы при инциденте
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
🧠 Заключение от тебя
|
||||
|
||||
> “На объекте система видеонаблюдения формально функционирует, но не гарантирует сохранность событийного архива.”
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
ТЕСТ №2 — СИНХРОНИЗАЦИЯ ВРЕМЕНИ
|
||||
|
||||
|
||||
---
|
||||
|
||||
Методика
|
||||
|
||||
Сравнение времени:
|
||||
- на камерах
|
||||
- на регистраторе
|
||||
- на сервере СКУД
|
||||
- фактическое время события
|
||||
|
||||
|
||||
---
|
||||
|
||||
Норма
|
||||
|
||||
отклонение ≤ 1–2 секунды
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Часто
|
||||
|
||||
разрыв 2–15 минут
|
||||
|
||||
разные часовые зоны
|
||||
|
||||
нет NTP синхронизации
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Риск
|
||||
|
||||
> невозможность юридически доказать момент события
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Вывод
|
||||
|
||||
> “Система не обеспечивает юридически корректную фиксацию времени событий.”
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
ТЕСТ №3 — РЕЗЕРВНОЕ ПИТАНИЕ
|
||||
|
||||
|
||||
---
|
||||
|
||||
Методика
|
||||
|
||||
Проверка:
|
||||
- UPS
|
||||
- время автономной работы
|
||||
- отключение питания
|
||||
- поведение систем
|
||||
|
||||
|
||||
---
|
||||
|
||||
Норма
|
||||
|
||||
15–60 минут автономии минимум
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Часто
|
||||
|
||||
UPS “для галочки”
|
||||
|
||||
не держит нагрузку
|
||||
|
||||
отсутствует тестирование
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Риск
|
||||
|
||||
> полная остановка системы при отключении электричества
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Вывод
|
||||
|
||||
> “Инфраструктура объекта не защищена от отключения электропитания.”
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
ТЕСТ №4 — ПОЛНОТА КАМЕРНОГО ПОКРЫТИЯ
|
||||
|
||||
|
||||
---
|
||||
|
||||
Методика
|
||||
|
||||
Проверка зон:
|
||||
- входы
|
||||
- кассы
|
||||
- периметр
|
||||
- слепые зоны
|
||||
|
||||
|
||||
---
|
||||
|
||||
Норма
|
||||
|
||||
отсутствие “мертвых зон”
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Часто
|
||||
|
||||
перекрытия нет
|
||||
|
||||
камеры направлены неправильно
|
||||
|
||||
часть зон не контролируется
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Риск
|
||||
|
||||
> невозможность фиксации инцидентов
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Вывод
|
||||
|
||||
> “Фактическое покрытие объекта не соответствует заявленной системе безопасности.”
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
ТЕСТ №5 — ЖУРНАЛ СОБЫТИЙ СКУД
|
||||
|
||||
|
||||
---
|
||||
|
||||
Методика
|
||||
|
||||
Проверка:
|
||||
- записи проходов
|
||||
- корректность пользователей
|
||||
- история событий
|
||||
|
||||
|
||||
---
|
||||
|
||||
Норма
|
||||
|
||||
полный лог всех проходов
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Часто
|
||||
|
||||
потери логов
|
||||
|
||||
сбои базы
|
||||
|
||||
отключённый журнал
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Риск
|
||||
|
||||
> невозможность отследить перемещения персонала
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Вывод
|
||||
|
||||
> “СКУД не выполняет функцию контроля доступа в полном объёме.”
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
ТЕСТ №6 — СОСТОЯНИЕ ПИТАНИЯ СИСТЕМ
|
||||
|
||||
|
||||
---
|
||||
|
||||
Методика
|
||||
|
||||
Проверка:
|
||||
- напряжения
|
||||
- нагрузки
|
||||
- перегрева
|
||||
- стабильности питания оборудования
|
||||
|
||||
|
||||
---
|
||||
|
||||
Часто
|
||||
|
||||
перегрузка линий
|
||||
|
||||
дешёвые блоки питания
|
||||
|
||||
нестабильное напряжение
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Риск
|
||||
|
||||
> деградация оборудования и внезапные отказы
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Вывод
|
||||
|
||||
> “Система имеет скрытую деградацию по питанию.”
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
ТЕСТ №7 — СОСТОЯНИЕ ХРАНЕНИЯ ДАННЫХ
|
||||
|
||||
|
||||
---
|
||||
|
||||
Методика
|
||||
|
||||
Проверка:
|
||||
- HDD/SSD
|
||||
- заполнение
|
||||
- циклы перезаписи
|
||||
- ошибки записи
|
||||
|
||||
|
||||
---
|
||||
|
||||
Часто
|
||||
|
||||
диски в деградации
|
||||
|
||||
нет мониторинга
|
||||
|
||||
потеря данных без уведомлений
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Риск
|
||||
|
||||
> потеря архива без внешних признаков
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Вывод
|
||||
|
||||
> “Система хранения не контролируется и не мониторится.”
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
4. КАК ТЫ ПРЕЗЕНТУЕШЬ ЭТО КЛИЕНТУ
|
||||
|
||||
|
||||
---
|
||||
|
||||
НЕ так:
|
||||
|
||||
❌ “у вас проблемы”
|
||||
|
||||
|
||||
---
|
||||
|
||||
А так:
|
||||
|
||||
✔ “мы провели тест №3 и зафиксировали отклонение”
|
||||
|
||||
|
||||
---
|
||||
|
||||
5. ШАБЛОН ТВОЕГО ЭКСПЕРТНОГО ЗАКЛЮЧЕНИЯ
|
||||
|
||||
ИНЖЕНЕРНОЕ ЗАКЛЮЧЕНИЕ
|
||||
|
||||
Объект: ________
|
||||
|
||||
Проведены тесты:
|
||||
- архив видеонаблюдения
|
||||
- синхронизация времени
|
||||
- резервное питание
|
||||
- СКУД
|
||||
- хранение данных
|
||||
|
||||
Выявленные отклонения:
|
||||
|
||||
1. ________
|
||||
2. ________
|
||||
3. ________
|
||||
|
||||
Риски:
|
||||
|
||||
- ________
|
||||
- ________
|
||||
|
||||
Заключение инженера:
|
||||
|
||||
Система безопасности объекта требует технического сопровождения
|
||||
для обеспечения стабильной эксплуатации и снижения рисков отказов.
|
||||
|
||||
|
||||
---
|
||||
|
||||
6. СИЛА ЭТОЙ СИСТЕМЫ
|
||||
|
||||
Ты становишься:
|
||||
|
||||
не монтажником
|
||||
|
||||
не продавцом услуг
|
||||
|
||||
не подрядчиком
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
А ЧЕМ?
|
||||
|
||||
инженером, который доказывает состояние объекта
|
||||
|
||||
|
||||
---
|
||||
|
||||
7. ПОЧЕМУ ЭТО ПРОДАЁТ SLA
|
||||
|
||||
Потому что клиент видит:
|
||||
|
||||
факты
|
||||
|
||||
отклонения
|
||||
|
||||
риски
|
||||
|
||||
|
||||
И сам приходит к выводу:
|
||||
|
||||
> “это нужно сопровождать постоянно”
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
8. КАК ЭТО МАСШТАБИРУЕТСЯ
|
||||
|
||||
Ты можешь:
|
||||
|
||||
обучить инженеров тестам
|
||||
|
||||
стандартизировать отчёты
|
||||
|
||||
превратить это в продукт аудита
|
||||
|
||||
автоматизировать CRM
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
9. СЛЕДУЮЩИЙ УРОВЕНЬ (если продолжим)
|
||||
|
||||
Я могу дальше собрать:
|
||||
|
||||
автоматический шаблон отчёта (PDF + PHP генерация)
|
||||
|
||||
систему балльной оценки объекта (risk scoring)
|
||||
|
||||
SLA-переход на основе результатов тестов
|
||||
|
||||
“паспорт объекта безопасности”
|
||||
|
||||
стандарты для инженеров в команде
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Если коротко:
|
||||
|
||||
> ты превращаешь “услуги безопасности” в инженерную измеряемую систему контроля риска
|
||||
|
||||
|
||||
|
||||
И это уже не рынок монтажников.
|
||||
Это рынок эксплуатационных инженеров уровня enterprise.
|
||||
@@ -0,0 +1,589 @@
|
||||
Ниже — уже не просто “текст КП”, а фундамент твоей новой модели бизнеса.
|
||||
|
||||
Я делаю это в формате:
|
||||
|
||||
инженерного B2B;
|
||||
|
||||
без “маркетингового мусора”;
|
||||
|
||||
с акцентом на доверие, SLA и эксплуатацию.
|
||||
|
||||
|
||||
Это можно:
|
||||
|
||||
сразу использовать;
|
||||
|
||||
конвертировать в PDF;
|
||||
|
||||
вставить на сайт;
|
||||
|
||||
генерировать автоматически через CRM.
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
1. ПОЛНОЦЕННЫЙ ШАБЛОН КП (.md)
|
||||
|
||||
# КОММЕРЧЕСКОЕ ПРЕДЛОЖЕНИЕ
|
||||
## Техническое сопровождение систем безопасности
|
||||
|
||||
---
|
||||
|
||||
# AEGISONE ENGINEERING
|
||||
### Эксплуатация и сопровождение систем безопасности коммерческих объектов
|
||||
|
||||
---
|
||||
|
||||
## Контакты
|
||||
|
||||
Телефон: +7 (XXX) XXX-XX-XX
|
||||
Email: info@aegisone.ru
|
||||
Сайт: https://aegisone.ru
|
||||
|
||||
---
|
||||
|
||||
# О компании
|
||||
|
||||
AEGISONE ENGINEERING — инженерная сервисная компания,
|
||||
специализирующаяся на техническом сопровождении
|
||||
и эксплуатации систем безопасности коммерческих объектов.
|
||||
|
||||
Мы обеспечиваем:
|
||||
- стабильную работу систем;
|
||||
- контроль инфраструктуры;
|
||||
- регламентное обслуживание;
|
||||
- SLA и контроль сроков реакции;
|
||||
- технический аудит;
|
||||
- сопровождение эксплуатации объектов.
|
||||
|
||||
---
|
||||
|
||||
# Какие проблемы мы решаем
|
||||
|
||||
Большинство неисправностей систем безопасности
|
||||
выявляются только после возникновения проблем:
|
||||
|
||||
- отсутствует архив видеонаблюдения;
|
||||
- системы работают нестабильно;
|
||||
- часть оборудования неисправна;
|
||||
- отсутствует документация;
|
||||
- неисправности копятся месяцами;
|
||||
- подрядчики не несут ответственности;
|
||||
- проверки выявляют критические нарушения.
|
||||
|
||||
Это приводит:
|
||||
- к рискам простоев;
|
||||
- потере контроля;
|
||||
- проблемам при проверках;
|
||||
- финансовым потерям.
|
||||
|
||||
---
|
||||
|
||||
# Решение
|
||||
|
||||
Мы берем на себя техническое сопровождение
|
||||
и контроль работоспособности систем безопасности объекта.
|
||||
|
||||
В рамках сопровождения обеспечиваем:
|
||||
|
||||
- регламентное обслуживание;
|
||||
- диагностику;
|
||||
- контроль состояния оборудования;
|
||||
- аварийное реагирование;
|
||||
- сопровождение эксплуатации;
|
||||
- фотоотчетность;
|
||||
- рекомендации по модернизации;
|
||||
- технический контроль подрядчиков.
|
||||
|
||||
---
|
||||
|
||||
# Состав услуг
|
||||
|
||||
| Услуга | Описание |
|
||||
|---|---|
|
||||
| Регламентные проверки | Контроль состояния систем |
|
||||
| Диагностика | Поиск неисправностей |
|
||||
| Контроль архива | Проверка записи и хранения |
|
||||
| Проверка питания | Бесперебойность работы |
|
||||
| Аварийные выезды | Реагирование по SLA |
|
||||
| Фотоотчетность | Подтверждение работ |
|
||||
| Ведение журналов | История обслуживания |
|
||||
| Консультации | Поддержка эксплуатации |
|
||||
|
||||
---
|
||||
|
||||
# SLA
|
||||
|
||||
| Приоритет | Описание | Время реакции |
|
||||
|---|---|---|
|
||||
| P1 | Полный отказ критической системы | до 2 часов |
|
||||
| P2 | Частичная потеря функционала | до 4 часов |
|
||||
| P3 | Некритичная неисправность | до 24 часов |
|
||||
| P4 | Плановые работы | по графику |
|
||||
|
||||
---
|
||||
|
||||
# Почему выбирают нас
|
||||
|
||||
- более 20 лет инженерного опыта;
|
||||
- лицензия МЧС;
|
||||
- работа по SLA и регламентам;
|
||||
- опыт эксплуатации коммерческих объектов;
|
||||
- прозрачная отчетность;
|
||||
- несем ответственность за результат;
|
||||
- не работаем по принципу «сделали и забыли».
|
||||
|
||||
---
|
||||
|
||||
# Тарифы
|
||||
|
||||
## START
|
||||
Для небольших объектов.
|
||||
|
||||
Включает:
|
||||
- ежемесячный регламент;
|
||||
- диагностику;
|
||||
- удаленную поддержку;
|
||||
- отчетность.
|
||||
|
||||
Стоимость:
|
||||
от 25 000 ₽ / месяц
|
||||
|
||||
---
|
||||
|
||||
## BUSINESS
|
||||
Для коммерческих объектов.
|
||||
|
||||
Включает:
|
||||
- SLA;
|
||||
- аварийные выезды;
|
||||
- контроль архива;
|
||||
- сопровождение проверок;
|
||||
- фотоотчетность.
|
||||
|
||||
Стоимость:
|
||||
от 60 000 ₽ / месяц
|
||||
|
||||
---
|
||||
|
||||
## ENTERPRISE
|
||||
Формат внешнего инженерного отдела.
|
||||
|
||||
Включает:
|
||||
- постоянное сопровождение;
|
||||
- участие в эксплуатации;
|
||||
- контроль подрядчиков;
|
||||
- развитие инфраструктуры;
|
||||
- аудит объектов.
|
||||
|
||||
Стоимость:
|
||||
индивидуально
|
||||
|
||||
---
|
||||
|
||||
# Этапы работы
|
||||
|
||||
1. Предварительная консультация
|
||||
2. Технический аудит объекта
|
||||
3. Подготовка отчета и рекомендаций
|
||||
4. Формирование SLA и регламентов
|
||||
5. Постановка объекта на сопровождение
|
||||
6. Регулярное обслуживание и отчетность
|
||||
|
||||
---
|
||||
|
||||
# Технический аудит
|
||||
|
||||
Перед постановкой объекта на сопровождение
|
||||
рекомендуем проведение технического аудита.
|
||||
|
||||
Аудит позволяет:
|
||||
- выявить скрытые проблемы;
|
||||
- оценить состояние систем;
|
||||
- определить риски;
|
||||
- подготовить рекомендации.
|
||||
|
||||
---
|
||||
|
||||
# Контакты
|
||||
|
||||
AEGISONE ENGINEERING
|
||||
|
||||
Телефон:
|
||||
+7 (XXX) XXX-XX-XX
|
||||
|
||||
Email:
|
||||
info@aegisone.ru
|
||||
|
||||
Сайт:
|
||||
https://aegisone.ru
|
||||
---
|
||||
|
||||
2. СТРУКТУРА ПЕРВОГО АУДИТА
|
||||
|
||||
Вот здесь начинается твоя реальная экспертная модель.
|
||||
|
||||
ЦЕЛЬ АУДИТА
|
||||
|
||||
НЕ:
|
||||
|
||||
“найти поломку”.
|
||||
|
||||
|
||||
А:
|
||||
|
||||
показать уровень инженерной зрелости объекта.
|
||||
|
||||
|
||||
---
|
||||
|
||||
ЧТО ДОЛЖЕН ДАВАТЬ АУДИТ
|
||||
|
||||
После него клиент должен понять:
|
||||
|
||||
где риски;
|
||||
|
||||
что не работает;
|
||||
|
||||
что может привести к проблемам;
|
||||
|
||||
насколько объект управляем;
|
||||
|
||||
почему нужен SLA.
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
ИДЕАЛЬНАЯ СТРУКТУРА АУДИТА
|
||||
|
||||
|
||||
---
|
||||
|
||||
ЭТАП 1
|
||||
|
||||
ВВОДНАЯ ИНФОРМАЦИЯ
|
||||
|
||||
|
||||
---
|
||||
|
||||
Собираем:
|
||||
|
||||
тип объекта;
|
||||
|
||||
площадь;
|
||||
|
||||
количество систем;
|
||||
|
||||
ответственные лица;
|
||||
|
||||
история проблем;
|
||||
|
||||
подрядчики;
|
||||
|
||||
наличие документации.
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
ЭТАП 2
|
||||
|
||||
ВИЗУАЛЬНЫЙ ОСМОТР
|
||||
|
||||
|
||||
---
|
||||
|
||||
Проверяем:
|
||||
|
||||
шкафы;
|
||||
|
||||
коммутацию;
|
||||
|
||||
маркировку;
|
||||
|
||||
кабельные трассы;
|
||||
|
||||
питание;
|
||||
|
||||
серверные;
|
||||
|
||||
доступ к оборудованию.
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
ЭТАП 3
|
||||
|
||||
ПРОВЕРКА РАБОТОСПОСОБНОСТИ
|
||||
|
||||
|
||||
---
|
||||
|
||||
Видеонаблюдение:
|
||||
|
||||
запись;
|
||||
|
||||
архив;
|
||||
|
||||
синхронизация времени;
|
||||
|
||||
качество изображения;
|
||||
|
||||
доступность камер;
|
||||
|
||||
питание.
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
СКУД:
|
||||
|
||||
проходы;
|
||||
|
||||
журналы;
|
||||
|
||||
права доступа;
|
||||
|
||||
аварийное открытие;
|
||||
|
||||
контроллеры.
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Пожарка:
|
||||
|
||||
индикация;
|
||||
|
||||
ошибки;
|
||||
|
||||
оповещение;
|
||||
|
||||
связь;
|
||||
|
||||
резервное питание.
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
ЭТАП 4
|
||||
|
||||
ПРОВЕРКА ДОКУМЕНТАЦИИ
|
||||
|
||||
|
||||
---
|
||||
|
||||
Проверяем:
|
||||
|
||||
схемы;
|
||||
|
||||
пароли;
|
||||
|
||||
IP;
|
||||
|
||||
журналы;
|
||||
|
||||
проекты;
|
||||
|
||||
исполнительную документацию.
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
ЭТАП 5
|
||||
|
||||
ОЦЕНКА РИСКОВ
|
||||
|
||||
Это важнейшая часть.
|
||||
|
||||
|
||||
---
|
||||
|
||||
Например:
|
||||
|
||||
Риск Последствие
|
||||
|
||||
Не пишется архив Потеря доказательств
|
||||
Нет резервного питания Полный отказ
|
||||
Нет документации Долгое восстановление
|
||||
Ошибки пожарки Риски проверок
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
ЭТАП 6
|
||||
|
||||
РЕКОМЕНДАЦИИ
|
||||
|
||||
|
||||
---
|
||||
|
||||
Разделяем:
|
||||
|
||||
Критические
|
||||
|
||||
Исправить срочно.
|
||||
|
||||
|
||||
---
|
||||
|
||||
Важные
|
||||
|
||||
В течение 30 дней.
|
||||
|
||||
|
||||
---
|
||||
|
||||
Плановые
|
||||
|
||||
При модернизации.
|
||||
|
||||
|
||||
---
|
||||
|
||||
ЭТАП 7
|
||||
|
||||
ПРЕДЛОЖЕНИЕ SLA
|
||||
|
||||
Вот тут ты переводишь аудит:
|
||||
|
||||
в абонентское сопровождение.
|
||||
|
||||
|
||||
---
|
||||
|
||||
3. ЧЕК-ЛИСТ АУДИТА
|
||||
|
||||
Это уже реальный инструмент продаж.
|
||||
|
||||
|
||||
---
|
||||
|
||||
# ЧЕК-ЛИСТ ТЕХНИЧЕСКОГО АУДИТА
|
||||
|
||||
## Общая информация
|
||||
|
||||
- [ ] Тип объекта
|
||||
- [ ] Адрес
|
||||
- [ ] Ответственное лицо
|
||||
- [ ] Количество систем
|
||||
- [ ] Наличие документации
|
||||
- [ ] Наличие подрядчиков
|
||||
|
||||
---
|
||||
|
||||
# Видеонаблюдение
|
||||
|
||||
## Сервер / регистратор
|
||||
|
||||
- [ ] Проверка записи
|
||||
- [ ] Проверка архива
|
||||
- [ ] Проверка HDD
|
||||
- [ ] Проверка времени
|
||||
- [ ] Проверка сети
|
||||
- [ ] Проверка питания
|
||||
|
||||
## Камеры
|
||||
|
||||
- [ ] Наличие сигнала
|
||||
- [ ] Качество изображения
|
||||
- [ ] Наличие загрязнений
|
||||
- [ ] Корректность обзора
|
||||
- [ ] Наличие ИК подсветки
|
||||
|
||||
---
|
||||
|
||||
# СКУД
|
||||
|
||||
- [ ] Проверка контроллеров
|
||||
- [ ] Проверка считывателей
|
||||
- [ ] Проверка журналов
|
||||
- [ ] Проверка доступа
|
||||
- [ ] Проверка аварийного открытия
|
||||
- [ ] Проверка резервного питания
|
||||
|
||||
---
|
||||
|
||||
# Пожарная сигнализация
|
||||
|
||||
- [ ] Проверка панели
|
||||
- [ ] Проверка ошибок
|
||||
- [ ] Проверка шлейфов
|
||||
- [ ] Проверка оповещения
|
||||
- [ ] Проверка резервного питания
|
||||
- [ ] Проверка журналов событий
|
||||
|
||||
---
|
||||
|
||||
# Сетевая инфраструктура
|
||||
|
||||
- [ ] Проверка коммутаторов
|
||||
- [ ] Проверка UPS
|
||||
- [ ] Проверка кабельной инфраструктуры
|
||||
- [ ] Проверка интернет-каналов
|
||||
- [ ] Проверка температурного режима
|
||||
|
||||
---
|
||||
|
||||
# Документация
|
||||
|
||||
- [ ] Схемы
|
||||
- [ ] IP-адресация
|
||||
- [ ] Пароли
|
||||
- [ ] Журналы обслуживания
|
||||
- [ ] Исполнительная документация
|
||||
|
||||
---
|
||||
|
||||
# Риски
|
||||
|
||||
- [ ] Отсутствие записи
|
||||
- [ ] Отказ резервного питания
|
||||
- [ ] Отсутствие документации
|
||||
- [ ] Ошибки оборудования
|
||||
- [ ] Нестабильность сети
|
||||
|
||||
---
|
||||
|
||||
# Рекомендации
|
||||
|
||||
## Критические:
|
||||
_________________________________
|
||||
|
||||
## Важные:
|
||||
_________________________________
|
||||
|
||||
## Плановые:
|
||||
_________________________________
|
||||
---
|
||||
|
||||
САМОЕ ВАЖНОЕ
|
||||
|
||||
Вот что тебе нужно понять стратегически.
|
||||
|
||||
АУДИТ — ЭТО НЕ “ДОП. УСЛУГА”.
|
||||
|
||||
Это:
|
||||
|
||||
твоя система продаж.
|
||||
|
||||
Потому что:
|
||||
|
||||
не надо “впаривать”;
|
||||
|
||||
ты показываешь реальность;
|
||||
|
||||
ты становишься экспертом;
|
||||
|
||||
клиент сам понимает необходимость SLA.
|
||||
|
||||
|
||||
И это идеально подходит под твою модель инженерного B2B.
|
||||
@@ -0,0 +1,503 @@
|
||||
Хорошо. Здесь ты фактически строишь не “контент”, а:
|
||||
|
||||
инженерную медийную репутацию компании
|
||||
|
||||
Это важно различать.
|
||||
|
||||
Контент в твоей нише выполняет 3 функции:
|
||||
|
||||
1. формирует доверие у B2B (директора, УК, собственники)
|
||||
|
||||
|
||||
2. объясняет, почему эксплуатация важнее монтажа
|
||||
|
||||
|
||||
3. подводит к SLA и аудитам (деньгам)
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
0. СТРАТЕГИЯ ЭКСПЕРТНОСТИ (ОСНОВА)
|
||||
|
||||
Твоя роль в контенте:
|
||||
|
||||
> “Спокойный инженер, который объясняет, где у бизнеса скрытые риски в системах безопасности”
|
||||
|
||||
|
||||
|
||||
НЕ:
|
||||
|
||||
продавец
|
||||
|
||||
маркетолог
|
||||
|
||||
“лиды”
|
||||
|
||||
“акции”
|
||||
|
||||
|
||||
А:
|
||||
|
||||
диагност
|
||||
|
||||
эксплуатационный инженер
|
||||
|
||||
человек, который видит риски до аварии
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
1. КОНТЕНТ-СТОЛПЫ (PILLARS)
|
||||
|
||||
У тебя должно быть 5 контент-направлений:
|
||||
|
||||
|
||||
---
|
||||
|
||||
1. Эксплуатационные проблемы (самый важный)
|
||||
|
||||
👉 “Что ломается в реальности”
|
||||
|
||||
Примеры:
|
||||
|
||||
камеры не пишут архив
|
||||
|
||||
пожарка работает “на бумаге”
|
||||
|
||||
СКУД пропускает ошибки
|
||||
|
||||
нет резервного питания
|
||||
|
||||
подрядчики исчезают
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
2. Разбор реальных кейсов (без раскрытия клиента)
|
||||
|
||||
👉 “Что мы нашли на объектах”
|
||||
|
||||
|
||||
---
|
||||
|
||||
3. Ошибки монтажа и эксплуатации
|
||||
|
||||
👉 “Почему дешево = дорого”
|
||||
|
||||
|
||||
---
|
||||
|
||||
4. Инженерные разборы систем
|
||||
|
||||
👉 “как это должно работать правильно”
|
||||
|
||||
|
||||
---
|
||||
|
||||
5. Управление рисками (B2B язык)
|
||||
|
||||
👉 “что теряет бизнес”
|
||||
|
||||
|
||||
---
|
||||
|
||||
2. ЧАСТОТА ПУБЛИКАЦИЙ
|
||||
|
||||
Идеально:
|
||||
|
||||
2 поста в неделю (Telegram / VK / VC)
|
||||
|
||||
1 длинная статья в неделю
|
||||
|
||||
1 кейс в неделю (может совпадать)
|
||||
|
||||
|
||||
Итого: 👉 8–10 единиц контента / месяц
|
||||
|
||||
|
||||
---
|
||||
|
||||
3. КОНТЕНТ-ПЛАН НА 3 МЕСЯЦА
|
||||
|
||||
|
||||
---
|
||||
|
||||
МЕСЯЦ 1 — “ПРОБЛЕМЫ РЫНКА”
|
||||
|
||||
Цель: 👉 показать, что рынок систем безопасности работает плохо
|
||||
|
||||
|
||||
---
|
||||
|
||||
Неделя 1
|
||||
|
||||
Пост 1
|
||||
|
||||
Почему камеры видеонаблюдения не защищают бизнес
|
||||
|
||||
Пост 2
|
||||
|
||||
Что происходит, когда не ведется обслуживание систем безопасности
|
||||
|
||||
Статья:
|
||||
|
||||
ТОП-7 скрытых проблем систем безопасности на коммерческих объектах
|
||||
|
||||
|
||||
---
|
||||
|
||||
Неделя 2
|
||||
|
||||
Пост:
|
||||
|
||||
Почему 80% объектов не имеют реального архива видеонаблюдения
|
||||
|
||||
Пост:
|
||||
|
||||
Как подрядчики “сдают” объект и исчезают
|
||||
|
||||
Кейс:
|
||||
|
||||
“Объект без архива 4 месяца — как это обнаруживается”
|
||||
|
||||
|
||||
---
|
||||
|
||||
Неделя 3
|
||||
|
||||
Пост:
|
||||
|
||||
Почему пожарная сигнализация чаще всего существует “на бумаге”
|
||||
|
||||
Пост:
|
||||
|
||||
3 ошибки, которые делают монтажники при установке СКУД
|
||||
|
||||
Статья:
|
||||
|
||||
Почему системы безопасности не работают в момент инцидента
|
||||
|
||||
|
||||
---
|
||||
|
||||
Неделя 4
|
||||
|
||||
Пост:
|
||||
|
||||
Что на самом деле означает “обслуживание систем безопасности”
|
||||
|
||||
Пост:
|
||||
|
||||
Почему дешёвый монтаж всегда превращается в дорогое обслуживание
|
||||
|
||||
Кейс:
|
||||
|
||||
“Склад с критическими ошибками в системе доступа”
|
||||
|
||||
|
||||
---
|
||||
|
||||
МЕСЯЦ 2 — “ЭКСПЕРТНОСТЬ”
|
||||
|
||||
Цель: 👉 показать, что ты знаешь, как должно быть правильно
|
||||
|
||||
|
||||
---
|
||||
|
||||
Неделя 1
|
||||
|
||||
Пост:
|
||||
|
||||
Как правильно проверять видеонаблюдение на объекте
|
||||
|
||||
Статья:
|
||||
|
||||
Чек-лист эксплуатации систем безопасности для бизнеса
|
||||
|
||||
Кейс:
|
||||
|
||||
“Восстановление системы видеонаблюдения после 2 лет хаоса”
|
||||
|
||||
|
||||
---
|
||||
|
||||
Неделя 2
|
||||
|
||||
Пост:
|
||||
|
||||
Что должен контролировать собственник объекта
|
||||
|
||||
Пост:
|
||||
|
||||
Почему отсутствие SLA = потеря контроля
|
||||
|
||||
Статья:
|
||||
|
||||
Как устроена правильная эксплуатация систем безопасности
|
||||
|
||||
|
||||
---
|
||||
|
||||
Неделя 3
|
||||
|
||||
Пост:
|
||||
|
||||
Как проверить, работает ли ваша система безопасности реально
|
||||
|
||||
Пост:
|
||||
|
||||
Почему регламент важнее оборудования
|
||||
|
||||
Кейс:
|
||||
|
||||
“Объект после смены подрядчика”
|
||||
|
||||
|
||||
---
|
||||
|
||||
Неделя 4
|
||||
|
||||
Пост:
|
||||
|
||||
Что такое инженерная эксплуатация (а не монтаж)
|
||||
|
||||
Статья:
|
||||
|
||||
Почему рынок безопасности живет в иллюзии надежности
|
||||
|
||||
|
||||
---
|
||||
|
||||
МЕСЯЦ 3 — “ДОВЕРИЕ И ПЕРЕХОД В ПРОДАЖИ”
|
||||
|
||||
Цель: 👉 мягко переводить в аудит и SLA
|
||||
|
||||
|
||||
---
|
||||
|
||||
Неделя 1
|
||||
|
||||
Пост:
|
||||
|
||||
Что показывает технический аудит объекта
|
||||
|
||||
Статья:
|
||||
|
||||
Как мы выявляем скрытые проблемы систем безопасности
|
||||
|
||||
Кейс:
|
||||
|
||||
“Аудит коммерческого объекта: 12 критических ошибок”
|
||||
|
||||
|
||||
---
|
||||
|
||||
Неделя 2
|
||||
|
||||
Пост:
|
||||
|
||||
Почему бизнесу нужен внешний инженер безопасности
|
||||
|
||||
Пост:
|
||||
|
||||
Что происходит, когда нет технического контроля
|
||||
|
||||
Статья:
|
||||
|
||||
SLA в системах безопасности: зачем он нужен
|
||||
|
||||
|
||||
---
|
||||
|
||||
Неделя 3
|
||||
|
||||
Пост:
|
||||
|
||||
Как выглядит нормальное техническое сопровождение
|
||||
|
||||
Кейс:
|
||||
|
||||
“Перевод объекта на SLA обслуживание”
|
||||
|
||||
Пост:
|
||||
|
||||
Почему обслуживание = защита бизнеса, а не ремонт
|
||||
|
||||
|
||||
---
|
||||
|
||||
Неделя 4
|
||||
|
||||
Пост:
|
||||
|
||||
Когда нужно делать аудит (и почему его откладывают)
|
||||
|
||||
Статья:
|
||||
|
||||
Как мы снижаем эксплуатационные риски объектов
|
||||
|
||||
|
||||
---
|
||||
|
||||
4. ФОРМАТ КОНТЕНТА (ВАЖНО)
|
||||
|
||||
Каждый пост должен иметь структуру:
|
||||
|
||||
|
||||
---
|
||||
|
||||
1. Проблема
|
||||
|
||||
2. Реальный инженерный разбор
|
||||
|
||||
3. Последствия для бизнеса
|
||||
|
||||
4. Вывод (очень спокойный)
|
||||
|
||||
|
||||
---
|
||||
|
||||
5. ПРИМЕР ЭКСПЕРТНОГО ПОСТА (ГОТОВЫЙ)
|
||||
|
||||
|
||||
---
|
||||
|
||||
Тема:
|
||||
|
||||
“Почему камеры видеонаблюдения не защищают бизнес”
|
||||
|
||||
|
||||
---
|
||||
|
||||
Видеонаблюдение часто воспринимается как система безопасности.
|
||||
|
||||
На практике это не всегда так.
|
||||
|
||||
Основная проблема заключается не в оборудовании, а в эксплуатации.
|
||||
|
||||
На большинстве объектов мы наблюдаем типовые ситуации:
|
||||
|
||||
— часть камер не записывает архив;
|
||||
— запись есть, но не сохраняется нужный период;
|
||||
— часть каналов отключена;
|
||||
— время на устройствах не синхронизировано;
|
||||
— отсутствует резервирование питания;
|
||||
— система не тестируется регулярно.
|
||||
|
||||
В результате при инциденте система формально есть, но фактически не выполняет свою функцию.
|
||||
|
||||
Бизнес узнаёт об этом только постфактум.
|
||||
|
||||
Правильная эксплуатация видеонаблюдения — это не установка оборудования, а регулярный контроль:
|
||||
|
||||
— состояния записи;
|
||||
— целостности архива;
|
||||
— доступности камер;
|
||||
— корректности времени;
|
||||
— работоспособности хранения.
|
||||
|
||||
Без этого система превращается в формальность.
|
||||
|
||||
Именно поэтому в инженерной эксплуатации видеонаблюдение рассматривается как сервис, а не как установленное оборудование.
|
||||
---
|
||||
|
||||
6. КОД ДЛЯ КОНТЕНТ-СТРАНИЦЫ (PHP БЛОГ)
|
||||
|
||||
|
||||
---
|
||||
|
||||
<?php include '../header.php'; ?>
|
||||
|
||||
<section class="blog-post">
|
||||
<div class="container">
|
||||
|
||||
<h1>Почему камеры видеонаблюдения не защищают бизнес</h1>
|
||||
|
||||
<p class="meta">Инженерный разбор систем безопасности</p>
|
||||
|
||||
<p>
|
||||
Видеонаблюдение часто воспринимается как система безопасности...
|
||||
</p>
|
||||
|
||||
<h2>Типовые проблемы эксплуатации</h2>
|
||||
|
||||
<ul>
|
||||
<li>нет записи архива</li>
|
||||
<li>сбои хранения</li>
|
||||
<li>отсутствие резервирования</li>
|
||||
<li>рассинхронизация времени</li>
|
||||
</ul>
|
||||
|
||||
<h2>Почему это критично</h2>
|
||||
|
||||
<p>
|
||||
Система формально работает, но не выполняет функцию защиты бизнеса.
|
||||
</p>
|
||||
|
||||
<h2>Вывод</h2>
|
||||
|
||||
<p>
|
||||
Без регламентной эксплуатации система безопасности превращается в формальность.
|
||||
</p>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<?php include '../footer.php'; ?>
|
||||
|
||||
|
||||
---
|
||||
|
||||
7. ГЛАВНЫЙ ПРИНЦИП ВСЕГО КОНТЕНТА
|
||||
|
||||
Ты должен повторять одну мысль:
|
||||
|
||||
> “Без эксплуатации система безопасности не существует”
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
8. ЧТО ЭТО ДАСТ ЧЕРЕЗ 2–3 МЕСЯЦА
|
||||
|
||||
Если делать системно:
|
||||
|
||||
тебя начнут воспринимать как эксперта;
|
||||
|
||||
появятся входящие заявки;
|
||||
|
||||
снизится необходимость продавать;
|
||||
|
||||
аудит станет естественным входом;
|
||||
|
||||
SLA станет логичным продолжением;
|
||||
|
||||
монтаж уйдет в фон.
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
9. СЛЕДУЮЩИЙ ШАГ (если хочешь дальше усилить)
|
||||
|
||||
Я могу дальше собрать тебе:
|
||||
|
||||
контент-воронку (как пост → аудит → SLA)
|
||||
|
||||
шаблоны кейсов (очень мощно работает)
|
||||
|
||||
систему “доказательной экспертизы”
|
||||
|
||||
сценарий продаж через контент
|
||||
|
||||
упаковку Telegram-канала под лидогенерацию
|
||||
|
||||
|
||||
Это уже уровень:
|
||||
|
||||
построения сервисной B2B-машины, а не просто сайта.
|
||||
@@ -0,0 +1,673 @@
|
||||
Вот здесь начинается настоящий B2B.
|
||||
И это как раз твоя сильная сторона.
|
||||
|
||||
Потому что:
|
||||
|
||||
# тебе НЕ нужен агрессивный маркетинг.
|
||||
|
||||
Ты не:
|
||||
|
||||
- франшиза,
|
||||
- массовый монтажник,
|
||||
- “льем лиды”.
|
||||
|
||||
Твой рынок:
|
||||
|
||||
# доверительный инженерный B2B.
|
||||
|
||||
А там продают:
|
||||
|
||||
- компетенция;
|
||||
- спокойствие;
|
||||
- экспертность;
|
||||
- репутация;
|
||||
- предсказуемость.
|
||||
|
||||
---
|
||||
|
||||
# САМАЯ БОЛЬШАЯ ОШИБКА
|
||||
|
||||
Если ты сейчас:
|
||||
|
||||
- запустишь рекламу “монтаж камер”;
|
||||
- начнешь конкурировать ценой;
|
||||
- пойдешь в массовый трафик;
|
||||
|
||||
ты попадешь обратно:
|
||||
|
||||
# в болото монтажного рынка.
|
||||
|
||||
---
|
||||
|
||||
# ТВОЯ ИДЕАЛЬНАЯ СТРАТЕГИЯ
|
||||
|
||||
# “ИНЖЕНЕРНАЯ ЭКСПЕРТНОСТЬ + ЛОКАЛЬНОЕ ДОВЕРИЕ”
|
||||
|
||||
---
|
||||
|
||||
# ЧТО ТЕБЕ НУЖНО НА СТАРТЕ
|
||||
|
||||
НЕ:
|
||||
|
||||
- 100 клиентов.
|
||||
|
||||
А:
|
||||
|
||||
# 3–5 правильных объектов.
|
||||
|
||||
Это принципиально.
|
||||
|
||||
---
|
||||
|
||||
# ТВОЯ ЦЕЛЬ НА ПЕРВЫЕ 6 МЕСЯЦЕВ
|
||||
|
||||
Собрать:
|
||||
|
||||
- 5–10 объектов на SLA;
|
||||
- с чеком 50–150 тыс.
|
||||
|
||||
Это уже:
|
||||
|
||||
# 500 тыс – 1.5 млн recurring revenue.
|
||||
|
||||
И это достижимо без рекламы.
|
||||
|
||||
---
|
||||
|
||||
# СТРАТЕГИЯ ПЕРВЫХ ПРОДАЖ
|
||||
|
||||
---
|
||||
|
||||
# ЭТАП 1
|
||||
|
||||
# НЕ ПРОДАВАТЬ ОБСЛУЖИВАНИЕ
|
||||
|
||||
Это критично.
|
||||
|
||||
Потому что: “ТО” воспринимается как:
|
||||
|
||||
- обязаловка;
|
||||
- минималка;
|
||||
- формальность.
|
||||
|
||||
---
|
||||
|
||||
# ПРОДАВАТЬ НУЖНО:
|
||||
|
||||
# АУДИТ И СНИЖЕНИЕ РИСКОВ.
|
||||
|
||||
---
|
||||
|
||||
# ТВОЙ ИДЕАЛЬНЫЙ ВХОД
|
||||
|
||||
НЕ:
|
||||
|
||||
> “давайте мы вас обслужим”.
|
||||
|
||||
А:
|
||||
|
||||
# “давайте проверим текущее состояние систем”.
|
||||
|
||||
---
|
||||
|
||||
# ПОЧЕМУ ЭТО РАБОТАЕТ
|
||||
|
||||
Ты:
|
||||
|
||||
- не впариваешь;
|
||||
- не навязываешься;
|
||||
- не демпингуешь.
|
||||
|
||||
Ты:
|
||||
|
||||
# инженер-эксперт.
|
||||
|
||||
---
|
||||
|
||||
# ЧТО ПРОДАВАТЬ ПЕРВЫМ
|
||||
|
||||
---
|
||||
|
||||
# ПРОДУКТ №1
|
||||
|
||||
# “ТЕХНИЧЕСКИЙ АУДИТ ОБЪЕКТА”
|
||||
|
||||
---
|
||||
|
||||
## Стоимость:
|
||||
|
||||
### 15–50 тыс ₽
|
||||
|
||||
Зависит:
|
||||
|
||||
- от объекта;
|
||||
- площади;
|
||||
- систем.
|
||||
|
||||
---
|
||||
|
||||
# ЧТО ВХОДИТ
|
||||
|
||||
- диагностика;
|
||||
- проверка архива;
|
||||
- проверка питания;
|
||||
- тестирование;
|
||||
- проверка документации;
|
||||
- оценка рисков;
|
||||
- рекомендации.
|
||||
|
||||
---
|
||||
|
||||
# РЕЗУЛЬТАТ:
|
||||
|
||||
PDF-отчет.
|
||||
|
||||
---
|
||||
|
||||
# ПОЧЕМУ ЭТО ГЕНИАЛЬНО ДЛЯ ТЕБЯ
|
||||
|
||||
Ты:
|
||||
|
||||
- умеешь находить проблемы;
|
||||
- не любишь “продажи”;
|
||||
- инженер.
|
||||
|
||||
То есть:
|
||||
|
||||
# это идеальная модель продаж под тебя.
|
||||
|
||||
---
|
||||
|
||||
# ЭТАП 2
|
||||
|
||||
# ПРОДАЖА SLA
|
||||
|
||||
После аудита.
|
||||
|
||||
---
|
||||
|
||||
# СХЕМА
|
||||
|
||||
## Ты показываешь:
|
||||
|
||||
### Сейчас:
|
||||
|
||||
- риски;
|
||||
- неисправности;
|
||||
- слабые места.
|
||||
|
||||
---
|
||||
|
||||
## Потом:
|
||||
|
||||
> “Чтобы это не накапливалось — нужен регламент эксплуатации.”
|
||||
|
||||
---
|
||||
|
||||
# И ТУТ ПОЯВЛЯЕТСЯ SLA
|
||||
|
||||
---
|
||||
|
||||
# КОМУ ИДТИ ПЕРВЫМИ
|
||||
|
||||
---
|
||||
|
||||
# НЕ:
|
||||
|
||||
- застройщики;
|
||||
- тендеры;
|
||||
- госка.
|
||||
|
||||
Это болото.
|
||||
|
||||
---
|
||||
|
||||
# ИДЕАЛЬНЫЕ ПЕРВЫЕ КЛИЕНТЫ
|
||||
|
||||
---
|
||||
|
||||
# 1. ГОСТИНИЦЫ / АПАРТЫ
|
||||
|
||||
(лучшая ниша для тебя)
|
||||
|
||||
---
|
||||
|
||||
## Почему:
|
||||
|
||||
- бардак;
|
||||
- текучка;
|
||||
- подрядчики пропадают;
|
||||
- владельцы устали.
|
||||
|
||||
---
|
||||
|
||||
# 2. НЕБОЛЬШИЕ СКЛАДЫ
|
||||
|
||||
Очень хорошая ниша.
|
||||
|
||||
---
|
||||
|
||||
# 3. КОММЕРЧЕСКИЕ УК
|
||||
|
||||
Золото.
|
||||
|
||||
---
|
||||
|
||||
# 4. ЧАСТНЫЕ КЛИНИКИ
|
||||
|
||||
Отличная ниша.
|
||||
|
||||
---
|
||||
|
||||
# 5. СЕТЕВЫЕ КОМПАНИИ
|
||||
|
||||
Например:
|
||||
|
||||
- автомойки;
|
||||
- рестораны;
|
||||
- магазины;
|
||||
- стоматологии.
|
||||
|
||||
---
|
||||
|
||||
# КАК ИСКАТЬ КЛИЕНТОВ БЕЗ РЕКЛАМЫ
|
||||
|
||||
Вот тут твой рынок.
|
||||
|
||||
---
|
||||
|
||||
# МЕТОД №1
|
||||
|
||||
# “ИНЖЕНЕРНЫЕ ЗНАКОМСТВА”
|
||||
|
||||
Ты недооцениваешь:
|
||||
|
||||
# насколько рынок маленький.
|
||||
|
||||
---
|
||||
|
||||
# ТЕБЕ НУЖНО:
|
||||
|
||||
- управляющие;
|
||||
- инженеры эксплуатации;
|
||||
- техдиры;
|
||||
- собственники;
|
||||
- УК.
|
||||
|
||||
---
|
||||
|
||||
# НЕ ПРОДАВАТЬ
|
||||
|
||||
А:
|
||||
|
||||
# знакомиться.
|
||||
|
||||
---
|
||||
|
||||
# ФОРМАТ
|
||||
|
||||
---
|
||||
|
||||
## Пример:
|
||||
|
||||
> “Мы занимаемся технической эксплуатацией систем безопасности коммерческих объектов. Если будет нужна диагностика или помощь — обращайтесь.”
|
||||
|
||||
---
|
||||
|
||||
# ВСЕ.
|
||||
|
||||
Никаких:
|
||||
|
||||
- впариваний;
|
||||
- “акций”;
|
||||
- скидок.
|
||||
|
||||
---
|
||||
|
||||
# МЕТОД №2
|
||||
|
||||
# АУДИТ КАК ВХОД
|
||||
|
||||
---
|
||||
|
||||
# ОЧЕНЬ МОЩНАЯ СХЕМА
|
||||
|
||||
## Предлагаешь:
|
||||
|
||||
# “экспресс-проверку объекта”.
|
||||
|
||||
---
|
||||
|
||||
## Например:
|
||||
|
||||
- проверка архива;
|
||||
- отказоустойчивость;
|
||||
- питание;
|
||||
- документация.
|
||||
|
||||
---
|
||||
|
||||
# ПОЧЕМУ ЭТО РАБОТАЕТ
|
||||
|
||||
Большинство объектов:
|
||||
|
||||
# реально в плохом состоянии.
|
||||
|
||||
---
|
||||
|
||||
# МЕТОД №3
|
||||
|
||||
# LINKEDIN / TELEGRAM / VC / ДЗЕН
|
||||
|
||||
Это твоя золотая жила.
|
||||
|
||||
---
|
||||
|
||||
# ПОЧЕМУ
|
||||
|
||||
Рынок безопасности:
|
||||
|
||||
# чудовищно слаб по экспертности.
|
||||
|
||||
---
|
||||
|
||||
# А ТЫ:
|
||||
|
||||
- умеешь говорить по делу;
|
||||
- инженер;
|
||||
- системный.
|
||||
|
||||
---
|
||||
|
||||
# ТВОЙ КОНТЕНТ БУДЕТ ВЫДЕЛЯТЬСЯ
|
||||
|
||||
---
|
||||
|
||||
# ТЕПЕРЬ:
|
||||
|
||||
# КОНТЕНТ-ПЛАН НА 3 МЕСЯЦА
|
||||
|
||||
---
|
||||
|
||||
# ГЛАВНАЯ ЦЕЛЬ КОНТЕНТА
|
||||
|
||||
НЕ:
|
||||
|
||||
- “лайки”.
|
||||
|
||||
А:
|
||||
|
||||
# доверие B2B.
|
||||
|
||||
---
|
||||
|
||||
# ТВОЯ РОЛЬ В КОНТЕНТЕ
|
||||
|
||||
НЕ: “маркетолог”.
|
||||
|
||||
А:
|
||||
|
||||
# “спокойный инженер-эксперт”.
|
||||
|
||||
---
|
||||
|
||||
# СТИЛЬ КОНТЕНТА
|
||||
|
||||
---
|
||||
|
||||
# НЕ:
|
||||
|
||||
- хайп;
|
||||
- кликбейт;
|
||||
- “ТОП-5 камер”.
|
||||
|
||||
---
|
||||
|
||||
# А:
|
||||
|
||||
- реальные проблемы;
|
||||
- эксплуатация;
|
||||
- ошибки;
|
||||
- риски;
|
||||
- практика.
|
||||
|
||||
---
|
||||
|
||||
# КАНАЛЫ
|
||||
|
||||
---
|
||||
|
||||
# ОБЯЗАТЕЛЬНО:
|
||||
|
||||
- Telegram;
|
||||
- сайт/блог;
|
||||
- Яндекс Бизнес;
|
||||
- VC.ru;
|
||||
- Дзен.
|
||||
|
||||
---
|
||||
|
||||
# МОЖНО:
|
||||
|
||||
- YouTube Shorts;
|
||||
- Rutube.
|
||||
|
||||
---
|
||||
|
||||
# ГЛАВНОЕ:
|
||||
|
||||
# не количество.
|
||||
|
||||
А:
|
||||
|
||||
# экспертность.
|
||||
|
||||
---
|
||||
|
||||
# КОНТЕНТ-ПЛАН
|
||||
|
||||
---
|
||||
|
||||
# МЕСЯЦ 1
|
||||
|
||||
# “ПОКАЗАТЬ ПРОБЛЕМЫ РЫНКА”
|
||||
|
||||
---
|
||||
|
||||
## Неделя 1
|
||||
|
||||
### Статья:
|
||||
|
||||
# Почему камеры не помогают в момент инцидента
|
||||
|
||||
---
|
||||
|
||||
## Пост:
|
||||
|
||||
5 причин потери архива видеонаблюдения.
|
||||
|
||||
---
|
||||
|
||||
## Короткое видео:
|
||||
|
||||
“Почему регистратор — не гарантия записи.”
|
||||
|
||||
---
|
||||
|
||||
## Кейс:
|
||||
|
||||
“На объекте архив не записывался 4 месяца.”
|
||||
|
||||
---
|
||||
|
||||
# Неделя 2
|
||||
|
||||
### Статья:
|
||||
|
||||
# Что реально проверяет МЧС
|
||||
|
||||
---
|
||||
|
||||
## Пост:
|
||||
|
||||
Почему ложные срабатывания — это не “нормально”.
|
||||
|
||||
---
|
||||
|
||||
## Видео:
|
||||
|
||||
3 ошибки обслуживания пожарки.
|
||||
|
||||
---
|
||||
|
||||
# Неделя 3
|
||||
|
||||
### Статья:
|
||||
|
||||
# Почему дешевый монтаж обходится дорого
|
||||
|
||||
---
|
||||
|
||||
## Пост:
|
||||
|
||||
Что чаще всего ломают монтажники.
|
||||
|
||||
---
|
||||
|
||||
## Фото-кейс:
|
||||
|
||||
“Как выглядит отсутствие эксплуатации через 2 года.”
|
||||
|
||||
---
|
||||
|
||||
# Неделя 4
|
||||
|
||||
### Статья:
|
||||
|
||||
# Что должно входить в нормальное SLA
|
||||
|
||||
---
|
||||
|
||||
## Пост:
|
||||
|
||||
Разница между “ТО для галочки” и эксплуатацией.
|
||||
|
||||
---
|
||||
|
||||
## Видео:
|
||||
|
||||
“Почему подрядчики исчезают после монтажа.”
|
||||
|
||||
---
|
||||
|
||||
# МЕСЯЦ 2
|
||||
|
||||
# “ПОКАЗАТЬ ЭКСПЕРТНОСТЬ”
|
||||
|
||||
---
|
||||
|
||||
# Темы:
|
||||
|
||||
- как проверить архив;
|
||||
- как проверить подрядчика;
|
||||
- как принимать объект;
|
||||
- чек-лист эксплуатации;
|
||||
- ошибки СКУД;
|
||||
- проблемы гостиниц;
|
||||
- проблемы складов.
|
||||
|
||||
---
|
||||
|
||||
# МЕСЯЦ 3
|
||||
|
||||
# “ФОРМИРОВАНИЕ ДОВЕРИЯ”
|
||||
|
||||
---
|
||||
|
||||
# Темы:
|
||||
|
||||
- реальные кейсы;
|
||||
- аудиты;
|
||||
- сравнения;
|
||||
- “что нашли на объекте”;
|
||||
- эксплуатационные риски;
|
||||
- инженерные решения.
|
||||
|
||||
---
|
||||
|
||||
# КАК ЧАСТО ПУБЛИКОВАТЬ
|
||||
|
||||
---
|
||||
|
||||
# ИДЕАЛЬНО:
|
||||
|
||||
## 2–3 поста в неделю.
|
||||
|
||||
---
|
||||
|
||||
# НЕ НУЖНО:
|
||||
|
||||
- каждый день;
|
||||
- “активность ради активности”.
|
||||
|
||||
---
|
||||
|
||||
# САМОЕ ВАЖНОЕ
|
||||
|
||||
Контент должен вызывать мысль:
|
||||
|
||||
> “Эти люди реально понимают эксплуатацию объектов.”
|
||||
|
||||
---
|
||||
|
||||
# ЧТО ДАСТ РЕЗУЛЬТАТ БЫСТРЕЕ ВСЕГО
|
||||
|
||||
---
|
||||
|
||||
# 1. АУДИТЫ
|
||||
|
||||
---
|
||||
|
||||
# 2. КЕЙСЫ
|
||||
|
||||
---
|
||||
|
||||
# 3. РАЗБОРЫ ОШИБОК
|
||||
|
||||
---
|
||||
|
||||
# 4. УЗКАЯ НИША
|
||||
|
||||
Например:
|
||||
|
||||
- гостиницы;
|
||||
- склады.
|
||||
|
||||
---
|
||||
|
||||
# 5. ЛИЧНЫЙ БРЕНД ИНЖЕНЕРА
|
||||
|
||||
Вот это критично.
|
||||
|
||||
---
|
||||
|
||||
# ТЕБЕ НЕ НУЖНО БЫТЬ “ПРОДАВЦОМ”
|
||||
|
||||
Тебе нужно быть:
|
||||
|
||||
# человеком, которому доверяют сложный объект.
|
||||
|
||||
---
|
||||
|
||||
# ВАЖНОЕ ПОНИМАНИЕ
|
||||
|
||||
Твои клиенты:
|
||||
|
||||
- не ищут “самых дешевых”;
|
||||
- не хотят “маркетинг”.
|
||||
|
||||
Они хотят:
|
||||
|
||||
# “нормального ответственного подрядчика”.
|
||||
|
||||
И рынок сейчас чудовищно голоден на таких людей.
|
||||
@@ -0,0 +1,340 @@
|
||||
Ниже — тебе не “скрипты продаж”, а инженерная система входа в аудит, адаптированная под Краснодарский край и B2B-реальность (УК, гостиницы, склады, собственники).
|
||||
|
||||
Главная идея:
|
||||
|
||||
> Ты не продаёшь аудит. Ты предлагаешь проверку рисков объекта.
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
1. ПСИХОЛОГИЯ ПРОДАЖ АУДИТА (ВАЖНО)
|
||||
|
||||
Что продаёт аудит на самом деле:
|
||||
|
||||
снижение рисков проверок (МЧС, внутренние, страховые)
|
||||
|
||||
уверенность, что система реально работает
|
||||
|
||||
снятие ответственности с менеджера/собственника
|
||||
|
||||
“независимое мнение инженера”
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Что НЕ работает:
|
||||
|
||||
“проверим камеры”
|
||||
|
||||
“сделаем диагностику”
|
||||
|
||||
“обслуживание дешевле”
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Рабочая позиция:
|
||||
|
||||
> “Мы делаем техническую проверку систем безопасности объекта с выдачей инженерного заключения по рискам эксплуатации.”
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
2. ВХОД В ПРОДАЖУ (3 КАНАЛА)
|
||||
|
||||
|
||||
---
|
||||
|
||||
2.1 Холодный вход (самый важный в регионе)
|
||||
|
||||
Кому пишем:
|
||||
|
||||
гостиницы
|
||||
|
||||
апарт-отели
|
||||
|
||||
склады
|
||||
|
||||
УК
|
||||
|
||||
коммерческая недвижимость
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
2.2 Тёплый вход (через знакомства)
|
||||
|
||||
электрики
|
||||
|
||||
IT
|
||||
|
||||
строители
|
||||
|
||||
подрядчики
|
||||
|
||||
проектировщики
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
2.3 Вход через контент
|
||||
|
||||
Telegram / статьи / кейсы
|
||||
|
||||
|
||||
---
|
||||
|
||||
3. СТРУКТУРА ПРОДАЖИ АУДИТА
|
||||
|
||||
|
||||
---
|
||||
|
||||
1. Контакт
|
||||
2. Короткое позиционирование
|
||||
3. Выявление боли
|
||||
4. Предложение аудита
|
||||
5. Подтверждение логики
|
||||
6. Назначение выезда
|
||||
|
||||
|
||||
---
|
||||
|
||||
4. ХОЛОДНЫЙ СКРИПТ (ТЕКСТ + WA / TG)
|
||||
|
||||
Вариант 1 — максимально инженерный (основной)
|
||||
|
||||
Добрый день.
|
||||
|
||||
Мы занимаемся техническим сопровождением систем безопасности коммерческих объектов в Краснодарском крае.
|
||||
|
||||
Перед тем как брать объекты на обслуживание, обычно делаем технический аудит:
|
||||
— проверка видеонаблюдения (архив, запись, питание)
|
||||
— проверка СКУД
|
||||
— проверка пожарной сигнализации
|
||||
— оценка рисков эксплуатации
|
||||
|
||||
По практике, на большинстве объектов выявляются скрытые проблемы, которые не видны в ежедневной работе.
|
||||
|
||||
Если у вас есть задача понять текущее состояние систем — можем провести аудит и дать инженерное заключение по рискам.
|
||||
|
||||
Подскажите, у вас сейчас системы на обслуживании или “как есть работают”?
|
||||
|
||||
|
||||
---
|
||||
|
||||
Почему это работает:
|
||||
|
||||
нет продажи
|
||||
|
||||
есть диагностика
|
||||
|
||||
есть статус эксперта
|
||||
|
||||
есть вопрос (диалог)
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
5. ВТОРОЙ СООБЩЕНИЕ (если отвечают “работает/есть подрядчик”)
|
||||
|
||||
Понял.
|
||||
|
||||
В таких случаях чаще всего проблема не в “работает/не работает”, а в том, что:
|
||||
— архив не проверяется регулярно
|
||||
— резервирование не тестируется
|
||||
— часть оборудования работает нестабильно
|
||||
— нет объективного контроля состояния
|
||||
|
||||
А это всплывает обычно в момент инцидента или проверки.
|
||||
|
||||
Мы как раз делаем аудит, который показывает такие скрытые вещи до проблем.
|
||||
|
||||
Если интересно — можем сделать экспресс-проверку объекта с коротким отчётом по рискам.
|
||||
|
||||
|
||||
---
|
||||
|
||||
6. КОНВЕРСИЯ В АУДИТ (КЛЮЧЕВОЙ МОМЕНТ)
|
||||
|
||||
Можем сделать так:
|
||||
|
||||
— выезд инженера
|
||||
— проверка всех систем
|
||||
— фиксация состояния
|
||||
— короткий инженерный отчёт
|
||||
— список рисков и рекомендаций
|
||||
|
||||
Обычно это занимает 1–2 дня в зависимости от объекта.
|
||||
|
||||
По стоимости — от 15 до 50 тыс, зависит от объёма систем.
|
||||
|
||||
Если удобно — могу уточнить объект и сказать точнее по формату.
|
||||
|
||||
|
||||
---
|
||||
|
||||
7. СКРИПТ ДЛЯ ГОЛОСА (ЕСЛИ ЗВОНЯТ)
|
||||
|
||||
структура:
|
||||
|
||||
1. Позиционирование (10–15 сек)
|
||||
|
||||
Мы занимаемся техническим сопровождением систем безопасности коммерческих объектов.
|
||||
Перед обслуживанием всегда делаем аудит состояния систем.
|
||||
|
||||
|
||||
---
|
||||
|
||||
2. Боль
|
||||
|
||||
На большинстве объектов, которые мы смотрим, есть скрытые проблемы — архив, питание, доступ, пожарка.
|
||||
Обычно это не видно в ежедневной работе.
|
||||
|
||||
|
||||
---
|
||||
|
||||
3. Переход
|
||||
|
||||
Поэтому предлагаем сначала сделать техническую проверку объекта и дать инженерное заключение.
|
||||
|
||||
|
||||
---
|
||||
|
||||
4. Закрытие
|
||||
|
||||
Если вам актуально — можем согласовать выезд инженера и формат проверки.
|
||||
|
||||
|
||||
---
|
||||
|
||||
8. ОБРАБОТКА ВОЗРАЖЕНИЙ
|
||||
|
||||
|
||||
---
|
||||
|
||||
❌ “У нас уже есть подрядчик”
|
||||
|
||||
Понял.
|
||||
|
||||
Аудит как раз часто показывает, что объект обслуживается формально, но без проверки ключевых параметров:
|
||||
архив, резервирование, ошибки, питание.
|
||||
|
||||
Мы не конкурируем с подрядчиком — мы даём независимую оценку состояния систем.
|
||||
|
||||
|
||||
---
|
||||
|
||||
❌ “Дорого”
|
||||
|
||||
Аудит не про “сделать дешевле”.
|
||||
|
||||
Это проверка рисков, которые могут стоить дороже:
|
||||
— потеря архива
|
||||
— отказ системы
|
||||
— проблемы при проверках
|
||||
|
||||
Поэтому стоимость зависит от масштаба объекта, но обычно это разовая диагностика, а не постоянные расходы.
|
||||
|
||||
|
||||
---
|
||||
|
||||
❌ “Нам не нужно”
|
||||
|
||||
Понял.
|
||||
|
||||
На практике аудит нужен не всегда “сейчас”, а когда появляются сомнения в стабильности систем или перед проверками.
|
||||
|
||||
Если актуализируется — можем подключиться.
|
||||
|
||||
|
||||
---
|
||||
|
||||
9. СИСТЕМА ДОГРЕВА (ЕСЛИ НЕ КУПИЛИ СРАЗУ)
|
||||
|
||||
Через 3–5 дней:
|
||||
|
||||
Добрый день.
|
||||
|
||||
Подскажите, актуально ли сейчас техническое обследование систем безопасности?
|
||||
|
||||
По опыту, на объектах часто всплывают вопросы по архиву и резервированию, которые лучше проверить заранее, чем в момент инцидента.
|
||||
|
||||
|
||||
---
|
||||
|
||||
10. МИКРО-CRM ЛОГИКА (ВАЖНО)
|
||||
|
||||
Каждый контакт делишь на:
|
||||
|
||||
не ответил
|
||||
|
||||
думает
|
||||
|
||||
есть подрядчик
|
||||
|
||||
отказ
|
||||
|
||||
сделал аудит
|
||||
|
||||
ушёл в SLA
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
11. КЛЮЧЕВОЙ МЕХАНИЗМ ПРОДАЖ
|
||||
|
||||
Твоя система должна работать так:
|
||||
|
||||
контакт → инженерная диагностика → выявление рисков → логичный переход в SLA
|
||||
|
||||
|
||||
---
|
||||
|
||||
12. ПОЧЕМУ ЭТО РАБОТАЕТ ИМЕННО В КРАСНОДАРСКОМ КРАЕ
|
||||
|
||||
Рынок региона:
|
||||
|
||||
много частных объектов
|
||||
|
||||
слабая эксплуатация систем
|
||||
|
||||
подрядчики “формальные”
|
||||
|
||||
мало инженерных компаний уровня SLA
|
||||
|
||||
|
||||
👉 значит: ты не конкурируешь по цене — ты создаёшь новый тип услуги
|
||||
|
||||
|
||||
---
|
||||
|
||||
13. ЕСЛИ ДАЛЬШЕ УСИЛИВАТЬ СИСТЕМУ
|
||||
|
||||
Следующий уровень, который я могу тебе собрать:
|
||||
|
||||
скрипт “закрытия в SLA после аудита”
|
||||
|
||||
таблица квалификации клиента (кого брать/кого нет)
|
||||
|
||||
CRM-воронка под SLA (по стадиям)
|
||||
|
||||
шаблон отчёта аудита (который продаёт сам себя)
|
||||
|
||||
шаблон договора SLA (который не торгуется)
|
||||
|
||||
|
||||
И это уже будет не продажи.
|
||||
|
||||
Это будет:
|
||||
|
||||
инженерная коммерческая система повторяемого дохода.
|
||||
@@ -0,0 +1,556 @@
|
||||
Сейчас мы выходим на ключевой этап.
|
||||
Потому что:
|
||||
|
||||
УТП — это не “красивый текст”.
|
||||
|
||||
Это:
|
||||
|
||||
твоя позиция на рынке.
|
||||
|
||||
Именно здесь определяется:
|
||||
|
||||
будешь ли ты конкурировать ценой;
|
||||
|
||||
попадешь ли в “монтажников”;
|
||||
|
||||
или станешь инженерным B2B подрядчиком.
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
ГЛАВНАЯ ОШИБКА РЫНКА
|
||||
|
||||
Все пишут:
|
||||
|
||||
“качественный монтаж”;
|
||||
|
||||
“20 лет опыта”;
|
||||
|
||||
“индивидуальный подход”.
|
||||
|
||||
|
||||
Это не УТП.
|
||||
|
||||
Это информационный шум.
|
||||
|
||||
|
||||
---
|
||||
|
||||
ТВОЕ РЕАЛЬНОЕ ПРЕИМУЩЕСТВО
|
||||
|
||||
Ты НЕ:
|
||||
|
||||
продавец оборудования;
|
||||
|
||||
бригада монтажников;
|
||||
|
||||
дешевый подрядчик.
|
||||
|
||||
|
||||
Ты:
|
||||
|
||||
инженерная сервисная компания.
|
||||
|
||||
И продавать нужно:
|
||||
|
||||
ответственность;
|
||||
|
||||
стабильность;
|
||||
|
||||
контроль;
|
||||
|
||||
снижение рисков;
|
||||
|
||||
эксплуатацию;
|
||||
|
||||
прозрачность.
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
ТВОЕ ОСНОВНОЕ УТП
|
||||
|
||||
Вот сильная база.
|
||||
|
||||
|
||||
---
|
||||
|
||||
AEGISONE — инженерное сопровождение систем безопасности коммерческих объектов.
|
||||
|
||||
Мы не просто устанавливаем оборудование.
|
||||
Мы берем на себя ответственность за стабильную работу систем безопасности объекта.
|
||||
|
||||
Работаем с коммерческой недвижимостью, гостиницами, складами, производствами и сетевыми объектами.
|
||||
|
||||
Обеспечиваем:
|
||||
— регламентное обслуживание;
|
||||
— SLA и контроль сроков реакции;
|
||||
— технический аудит;
|
||||
— восстановление проблемных объектов;
|
||||
— сопровождение эксплуатации;
|
||||
— прозрачную отчетность и контроль инфраструктуры.
|
||||
|
||||
Если система безопасности нужна не «для галочки», а для реальной работы объекта — мы подходим.
|
||||
---
|
||||
|
||||
ПОЧЕМУ ЭТО СИЛЬНО
|
||||
|
||||
Тут нет:
|
||||
|
||||
“лучших цен”;
|
||||
|
||||
“монтажа под ключ”;
|
||||
|
||||
“любых работ”.
|
||||
|
||||
|
||||
Это:
|
||||
|
||||
позиция эксперта.
|
||||
|
||||
|
||||
---
|
||||
|
||||
ДОПОЛНИТЕЛЬНЫЕ УТП ДЛЯ РАЗНЫХ СЕГМЕНТОВ
|
||||
|
||||
|
||||
---
|
||||
|
||||
ДЛЯ ГОСТИНИЦ
|
||||
|
||||
Обеспечиваем стабильную работу систем безопасности гостиниц и апарт-отелей без постоянного контроля со стороны управляющего.
|
||||
|
||||
Берем на себя техническое сопровождение:
|
||||
— видеонаблюдения;
|
||||
— СКУД;
|
||||
— пожарной сигнализации;
|
||||
— сетевой инфраструктуры.
|
||||
|
||||
Работаем по SLA и регламентам.
|
||||
---
|
||||
|
||||
ДЛЯ СКЛАДОВ И ЛОГИСТИКИ
|
||||
|
||||
Снижаем риски потери архива, отказов систем и простоев инфраструктуры складских объектов.
|
||||
|
||||
Контролируем работоспособность:
|
||||
— видеонаблюдения;
|
||||
— контроля доступа;
|
||||
— периметра;
|
||||
— сетевой инфраструктуры.
|
||||
|
||||
Обеспечиваем регламентное обслуживание и аварийное реагирование.
|
||||
---
|
||||
|
||||
ТЕПЕРЬ САМОЕ ВАЖНОЕ
|
||||
|
||||
СТРУКТУРА КОММЕРЧЕСКОГО ПРЕДЛОЖЕНИЯ
|
||||
|
||||
Большинство КП на рынке — мусор.
|
||||
|
||||
Там:
|
||||
|
||||
список оборудования;
|
||||
|
||||
цены;
|
||||
|
||||
таблицы;
|
||||
|
||||
“надежные решения”.
|
||||
|
||||
|
||||
B2B это НЕ читает.
|
||||
|
||||
|
||||
---
|
||||
|
||||
ТВОЕ КП ДОЛЖНО ПРОДАВАТЬ:
|
||||
|
||||
СПОКОЙСТВИЕ И КОНТРОЛЬ.
|
||||
|
||||
|
||||
---
|
||||
|
||||
ИДЕАЛЬНАЯ СТРУКТУРА КП ДЛЯ ТЕБЯ
|
||||
|
||||
|
||||
---
|
||||
|
||||
1. ТИТУЛЬНАЯ СТРАНИЦА
|
||||
|
||||
|
||||
---
|
||||
|
||||
Заголовок:
|
||||
|
||||
Коммерческое предложение
|
||||
|
||||
по техническому сопровождению систем безопасности
|
||||
|
||||
|
||||
---
|
||||
|
||||
Подзаголовок:
|
||||
|
||||
Для:
|
||||
|
||||
гостиницы;
|
||||
|
||||
склада;
|
||||
|
||||
коммерческого объекта;
|
||||
|
||||
производства.
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Внизу:
|
||||
|
||||
логотип;
|
||||
|
||||
контакты;
|
||||
|
||||
дата.
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
2. КРАТКО О ПРОБЛЕМЕ
|
||||
|
||||
Это критически важно.
|
||||
|
||||
|
||||
---
|
||||
|
||||
Пример:
|
||||
|
||||
|
||||
---
|
||||
|
||||
Большинство неисправностей систем безопасности выявляются только после возникновения проблем:
|
||||
— отсутствует архив видеонаблюдения;
|
||||
— часть оборудования не функционирует;
|
||||
— отсутствует документация;
|
||||
— подрядчики не несут ответственности;
|
||||
— неисправности накапливаются месяцами.
|
||||
|
||||
Это приводит к рискам простоев, потере контроля и проблемам при проверках.
|
||||
|
||||
Для снижения этих рисков необходимо регулярное техническое сопровождение и контроль состояния инфраструктуры объекта.
|
||||
---
|
||||
|
||||
ПОЧЕМУ ЭТО СИЛЬНО
|
||||
|
||||
Ты:
|
||||
|
||||
не “продаешь услуги”;
|
||||
|
||||
а показываешь проблему бизнеса.
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
3. ЧТО ТЫ ПРЕДЛАГАЕШЬ
|
||||
|
||||
|
||||
---
|
||||
|
||||
Заголовок:
|
||||
|
||||
Решение
|
||||
|
||||
|
||||
---
|
||||
|
||||
Пример:
|
||||
|
||||
|
||||
---
|
||||
|
||||
AEGISONE обеспечивает техническое сопровождение и контроль работоспособности систем безопасности объекта.
|
||||
|
||||
Мы берем на себя:
|
||||
— регламентное обслуживание;
|
||||
— диагностику;
|
||||
— аварийное реагирование;
|
||||
— технический контроль;
|
||||
— сопровождение эксплуатации;
|
||||
— контроль подрядчиков;
|
||||
— отчетность и рекомендации.
|
||||
---
|
||||
|
||||
4. ЧТО ВХОДИТ В ОБСЛУЖИВАНИЕ
|
||||
|
||||
Вот здесь уже конкретика.
|
||||
|
||||
|
||||
---
|
||||
|
||||
Пример структуры:
|
||||
|
||||
Услуга Описание
|
||||
|
||||
Регламентные проверки Проверка состояния оборудования
|
||||
Контроль архива Проверка записи и хранения
|
||||
Аварийные выезды Реагирование по SLA
|
||||
Диагностика Поиск неисправностей
|
||||
Отчетность Фото и рекомендации
|
||||
Поддержка Консультации персонала
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
5. SLA
|
||||
|
||||
Очень важно.
|
||||
|
||||
|
||||
---
|
||||
|
||||
Пример:
|
||||
|
||||
Приоритет Время реакции
|
||||
|
||||
Критическая авария до 2 часов
|
||||
Частичный отказ до 4 часов
|
||||
Плановая заявка до 24 часов
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
6. ПОЧЕМУ ИМЕННО ВЫ
|
||||
|
||||
Вот тут нельзя писать банальности.
|
||||
|
||||
|
||||
---
|
||||
|
||||
ПРАВИЛЬНО:
|
||||
|
||||
|
||||
---
|
||||
|
||||
Почему заказчики работают с нами:
|
||||
|
||||
— более 20 лет инженерного опыта;
|
||||
— лицензия МЧС;
|
||||
— работа по регламентам и SLA;
|
||||
— прозрачная отчетность;
|
||||
— опыт эксплуатации сложных объектов;
|
||||
— несем ответственность за результат;
|
||||
— не работаем по принципу «сделали и забыли».
|
||||
---
|
||||
|
||||
7. СТОИМОСТЬ
|
||||
|
||||
Очень важный блок.
|
||||
|
||||
|
||||
---
|
||||
|
||||
НЕ ДЕЛАЙ:
|
||||
|
||||
“от 5000 ₽”.
|
||||
|
||||
|
||||
---
|
||||
|
||||
ПРАВИЛЬНО:
|
||||
|
||||
Тариф Формат Стоимость
|
||||
|
||||
START Небольшие объекты от 25 000 ₽
|
||||
BUSINESS Коммерческие объекты от 60 000 ₽
|
||||
ENTERPRISE Внешний инженерный отдел индивидуально
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
8. ЭТАПЫ РАБОТЫ
|
||||
|
||||
Это резко повышает доверие.
|
||||
|
||||
|
||||
---
|
||||
|
||||
Пример:
|
||||
|
||||
1. Технический аудит объекта
|
||||
|
||||
|
||||
2. Формирование регламентов
|
||||
|
||||
|
||||
3. Подписание SLA
|
||||
|
||||
|
||||
4. Постановка объекта на сопровождение
|
||||
|
||||
|
||||
5. Регулярное обслуживание и отчетность
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
9. CTA
|
||||
|
||||
Очень важно.
|
||||
|
||||
|
||||
---
|
||||
|
||||
НЕ:
|
||||
|
||||
“оставьте заявку”.
|
||||
|
||||
|
||||
---
|
||||
|
||||
ПРАВИЛЬНО:
|
||||
|
||||
Предлагаем провести технический аудит объекта и подготовить рекомендации по снижению эксплуатационных рисков.
|
||||
|
||||
|
||||
---
|
||||
|
||||
КАК ДОЛЖНО ВЫГЛЯДЕТЬ КП ВИЗУАЛЬНО
|
||||
|
||||
|
||||
---
|
||||
|
||||
НЕ:
|
||||
|
||||
“цветастая реклама”;
|
||||
|
||||
“маркетинговый шум”.
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
А:
|
||||
|
||||
спокойный инженерный документ.
|
||||
|
||||
|
||||
---
|
||||
|
||||
ЦВЕТА
|
||||
|
||||
темно-синий;
|
||||
|
||||
графит;
|
||||
|
||||
белый;
|
||||
|
||||
серый.
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
СТИЛЬ
|
||||
|
||||
Как:
|
||||
|
||||
техническая компания;
|
||||
|
||||
инженерный аудит;
|
||||
|
||||
эксплуатация объектов.
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
САМОЕ ВАЖНОЕ
|
||||
|
||||
Твое КП должно вызывать мысль:
|
||||
|
||||
> “Эти люди понимают, как работает объект.”
|
||||
|
||||
|
||||
|
||||
А не:
|
||||
|
||||
> “Очередные монтажники.”
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
И ТУТ КЛЮЧЕВОЙ МОМЕНТ
|
||||
|
||||
Ты не должен пытаться понравиться всем.
|
||||
|
||||
Тебе нужны:
|
||||
|
||||
нормальные объекты;
|
||||
|
||||
нормальные бюджеты;
|
||||
|
||||
нормальные заказчики.
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
ТВОЯ СТРАТЕГИЯ
|
||||
|
||||
Не:
|
||||
|
||||
“много дешевых клиентов”.
|
||||
|
||||
А:
|
||||
|
||||
“мало, но качественных объектов на абонентке”.
|
||||
|
||||
Это огромная разница в бизнес-модели.
|
||||
|
||||
|
||||
---
|
||||
|
||||
Следующий логичный этап:
|
||||
|
||||
1. Сделать полноценный шаблон КП (PDF-структуру).
|
||||
|
||||
|
||||
2. Прописать тарифы глубже.
|
||||
|
||||
|
||||
3. Сделать SLA-документ.
|
||||
|
||||
|
||||
4. Подготовить скрипт инженерной продажи.
|
||||
|
||||
|
||||
5. Сделать структуру первого аудита.
|
||||
|
||||
|
||||
6. Составить чек-листы.
|
||||
|
||||
|
||||
7. Построить первую воронку клиентов в Краснодарском крае.
|
||||
|
||||
|
||||
8. Подготовить SEO-структуру сайта.
|
||||
|
||||
|
||||
9. Разработать контент-план для выхода в экспертность.
|
||||
|
||||
|
||||
10. Построить модель роста до 1–3 млн/мес recurring revenue.
|
||||
|
||||
|
||||
@@ -0,0 +1,458 @@
|
||||
Ниже — единая цифровая операционная модель AegisOne Engineering в формате .md.
|
||||
|
||||
Это не просто документация — это “скелет системы”, который можно отдать разработчику, внедрить в Notion/Bitrix/1C/веб-CRM или развернуть как внутренний продукт.
|
||||
|
||||
|
||||
---
|
||||
|
||||
# AegisOne Engineering
|
||||
## Unified Digital Operating System (UDOS)
|
||||
|
||||
---
|
||||
|
||||
# 0. СУТЬ СИСТЕМЫ
|
||||
|
||||
AegisOne UDOS — это единая цифровая система управления инженерной эксплуатацией объектов безопасности.
|
||||
|
||||
Она объединяет:
|
||||
|
||||
- CRM (клиенты и сделки)
|
||||
- SLA (контракты и обслуживание)
|
||||
- KPI инженеров (исполнение)
|
||||
- SHS (здоровье бизнеса)
|
||||
- Финансовую модель
|
||||
- Операционный дашборд
|
||||
|
||||
---
|
||||
|
||||
# 1. АРХИТЕКТУРА СИСТЕМЫ
|
||||
|
||||
┌──────────────────────┐
|
||||
│ LEADS / CRM │
|
||||
└─────────┬────────────┘
|
||||
↓
|
||||
┌──────────────────────┐
|
||||
│ AUDIT SYSTEM │
|
||||
└─────────┬────────────┘
|
||||
↓
|
||||
┌──────────────────────┐
|
||||
│ SLA CONTRACTS │
|
||||
└─────────┬────────────┘
|
||||
↓
|
||||
┌─────────────────────────────────────────┐
|
||||
│ OPERATIONS (ENGINEERS) │
|
||||
└─────────┬───────────────┬──────────────┘
|
||||
↓ ↓
|
||||
┌──────────────┐ ┌─────────────────────┐
|
||||
│ KPI ENGINEERS │ │ INCIDENT SYSTEM │
|
||||
└──────┬───────┘ └─────────┬───────────┘
|
||||
↓ ↓
|
||||
┌─────────────────────────────────────────┐
|
||||
│ SHS ENGINE │
|
||||
└──────────────┬──────────────────────────┘
|
||||
↓
|
||||
┌─────────────────────────────────────────┐
|
||||
│ CEO DASHBOARD │
|
||||
└─────────────────────────────────────────┘
|
||||
|
||||
---
|
||||
|
||||
# 2. CRM СИСТЕМА
|
||||
|
||||
## 2.1 Структура клиента
|
||||
|
||||
```json
|
||||
Client {
|
||||
id,
|
||||
company_name,
|
||||
object_type,
|
||||
location,
|
||||
contact_person,
|
||||
decision_maker,
|
||||
number_of_objects,
|
||||
systems: {
|
||||
video: int,
|
||||
access_control: int,
|
||||
fire_alarm: bool,
|
||||
it_infrastructure: bool
|
||||
},
|
||||
current_provider,
|
||||
pain_points[],
|
||||
budget_level,
|
||||
status: [lead, qualified, audit, offer, sla, lost]
|
||||
}
|
||||
|
||||
|
||||
---
|
||||
|
||||
2.2 Воронка CRM
|
||||
|
||||
Lead
|
||||
↓
|
||||
Qualification
|
||||
↓
|
||||
Technical Audit
|
||||
↓
|
||||
Risk Report
|
||||
↓
|
||||
SLA Offer
|
||||
↓
|
||||
Contract
|
||||
↓
|
||||
Active SLA
|
||||
|
||||
|
||||
---
|
||||
|
||||
3. AUDIT SYSTEM (ИНЖЕНЕРНЫЙ ВХОД)
|
||||
|
||||
3.1 Формирование Risk Score
|
||||
|
||||
Risk Score =
|
||||
missing_archive (25)
|
||||
+ no_power_backup (20)
|
||||
+ no_regulations (15)
|
||||
+ system_failures (20)
|
||||
+ no_documentation (10)
|
||||
|
||||
|
||||
---
|
||||
|
||||
3.2 Output аудита
|
||||
|
||||
Audit Report:
|
||||
- Risk Score
|
||||
- System condition
|
||||
- Critical vulnerabilities
|
||||
- SLA recommendation
|
||||
- Cost estimation
|
||||
|
||||
|
||||
---
|
||||
|
||||
4. SLA СИСТЕМА
|
||||
|
||||
4.1 Формула стоимости
|
||||
|
||||
SLA Price =
|
||||
Base Cost × Object Index × Region Factor × Risk Multiplier
|
||||
|
||||
|
||||
---
|
||||
|
||||
4.2 Object Index
|
||||
|
||||
Object Index =
|
||||
(Risk × 0.4)
|
||||
+ (Complexity × 0.3)
|
||||
+ (Infrastructure × 0.2)
|
||||
+ (Service History × 0.1)
|
||||
|
||||
|
||||
---
|
||||
|
||||
4.3 SLA уровни
|
||||
|
||||
Class Index Description
|
||||
|
||||
A 0–30 simple SLA
|
||||
B 31–60 standard SLA
|
||||
C 61–90 complex SLA
|
||||
D 90+ enterprise SLA
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
4.4 SLA метрики
|
||||
|
||||
Response Time
|
||||
|
||||
Resolution Time
|
||||
|
||||
Uptime %
|
||||
|
||||
Incident Rate
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
5. KPI СИСТЕМА ИНЖЕНЕРОВ
|
||||
|
||||
5.1 Engineer Score
|
||||
|
||||
ES =
|
||||
(0.25 × SLA Compliance)
|
||||
+ (0.20 × Response Time Score)
|
||||
+ (0.20 × Resolution Time Score)
|
||||
+ (0.15 × Diagnosis Accuracy)
|
||||
+ (0.10 × Reopen Rate Score)
|
||||
+ (0.10 × Documentation Quality)
|
||||
|
||||
|
||||
---
|
||||
|
||||
5.2 KPI метрики
|
||||
|
||||
SLA Compliance
|
||||
|
||||
closed_in_SLA / total_requests
|
||||
|
||||
Reopen Rate
|
||||
|
||||
reopened_requests / total_requests
|
||||
|
||||
Diagnosis Accuracy
|
||||
|
||||
confirmed_faults / found_faults
|
||||
|
||||
Utilization
|
||||
|
||||
working_hours / available_hours
|
||||
|
||||
|
||||
---
|
||||
|
||||
5.3 Грейды инженеров
|
||||
|
||||
Score Level
|
||||
|
||||
90–100 Senior
|
||||
80–89 Strong
|
||||
70–79 Middle
|
||||
<70 Junior
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
6. SHS (SYSTEM HEALTH SCORE)
|
||||
|
||||
6.1 Формула SHS
|
||||
|
||||
SHS =
|
||||
(0.22 × SLA Stability)
|
||||
+ (0.18 × Revenue Stability)
|
||||
+ (0.18 × Retention)
|
||||
+ (0.15 × Engineer Performance)
|
||||
+ (0.12 × Incident Stability)
|
||||
+ (0.10 × Sales Flow)
|
||||
+ (0.05 × Operational Efficiency)
|
||||
|
||||
|
||||
---
|
||||
|
||||
6.2 Интерпретация
|
||||
|
||||
SHS Status
|
||||
|
||||
85–100 Growth
|
||||
70–85 Stable
|
||||
50–70 Risk
|
||||
<50 Crisis
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
6.3 Alert System
|
||||
|
||||
SHS ↓ 5% weekly → Warning
|
||||
|
||||
SHS ↓ 10% → Critical
|
||||
|
||||
Retention drop → Immediate audit trigger
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
7. INCIDENT SYSTEM
|
||||
|
||||
7.1 Incident Classification
|
||||
|
||||
Level Description
|
||||
|
||||
P1 critical system failure
|
||||
P2 partial failure
|
||||
P3 minor issue
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
7.2 Incident Rate
|
||||
|
||||
IR = incidents / number_of_objects
|
||||
|
||||
|
||||
---
|
||||
|
||||
7.3 SLA breach tracking
|
||||
|
||||
breach_rate = failed_SLA_cases / total_cases
|
||||
|
||||
|
||||
---
|
||||
|
||||
8. FINANCIAL LAYER
|
||||
|
||||
8.1 MRR
|
||||
|
||||
MRR = Σ SLA contracts / 12
|
||||
|
||||
|
||||
---
|
||||
|
||||
8.2 Revenue per Engineer
|
||||
|
||||
RPE = SLA Revenue / number_of_engineers
|
||||
|
||||
|
||||
---
|
||||
|
||||
8.3 Cost per Object
|
||||
|
||||
CPO = total_operational_cost / number_of_objects
|
||||
|
||||
|
||||
---
|
||||
|
||||
9. CEO DASHBOARD
|
||||
|
||||
9.1 Main indicators
|
||||
|
||||
SHS (system health)
|
||||
|
||||
MRR (monthly recurring revenue)
|
||||
|
||||
SLA Compliance
|
||||
|
||||
Retention
|
||||
|
||||
Incident Rate
|
||||
|
||||
Engineer Score Avg
|
||||
|
||||
Sales Conversion
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
9.2 Dashboard visualization blocks
|
||||
|
||||
1. SHS Line Chart
|
||||
|
||||
trend over time
|
||||
|
||||
|
||||
2. SLA Heatmap
|
||||
|
||||
engineers vs performance
|
||||
|
||||
|
||||
3. MRR Growth Curve
|
||||
|
||||
monthly recurring revenue
|
||||
|
||||
|
||||
4. Client Retention Funnel
|
||||
|
||||
drop-off points
|
||||
|
||||
|
||||
5. Incident Map
|
||||
|
||||
problematic objects
|
||||
|
||||
|
||||
6. Engineer Ranking Table
|
||||
|
||||
top/bottom performers
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
10. AUTOMATION RULES
|
||||
|
||||
10.1 If SHS drops
|
||||
|
||||
IF SHS < 70:
|
||||
reduce new sales
|
||||
trigger audit cycle
|
||||
reassign engineers
|
||||
|
||||
|
||||
---
|
||||
|
||||
10.2 If SLA compliance drops
|
||||
|
||||
IF SLA < 90%:
|
||||
freeze non-critical projects
|
||||
increase inspection frequency
|
||||
|
||||
|
||||
---
|
||||
|
||||
10.3 If retention drops
|
||||
|
||||
IF retention < 90%:
|
||||
mandatory client audit
|
||||
review engineer assignments
|
||||
|
||||
|
||||
---
|
||||
|
||||
11. SYSTEM BEHAVIOR MODEL
|
||||
|
||||
DATA → KPI → SHS → DECISION → ACTION → FEEDBACK LOOP
|
||||
|
||||
|
||||
---
|
||||
|
||||
12. STRATEGIC PRINCIPLE
|
||||
|
||||
AegisOne Engineering is not a service company.
|
||||
|
||||
It is:
|
||||
|
||||
> an operating system for managing engineering risk in physical infrastructure.
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
13. END STATE MODEL
|
||||
|
||||
The system evolves into:
|
||||
|
||||
predictive SLA risk detection
|
||||
|
||||
automated pricing
|
||||
|
||||
engineer auto-allocation
|
||||
|
||||
client churn prediction
|
||||
|
||||
MRR forecasting
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
END OF SYSTEM
|
||||
|
||||
---
|
||||
|
||||
Если хочешь следующий уровень, я могу собрать тебе:
|
||||
|
||||
1) визуальный UI дашборда (как он должен выглядеть как продукт)
|
||||
2) структуру базы данных (SQL / 1C / Bitrix schema)
|
||||
3) алгоритм “предикта потери клиента за 14 дней”
|
||||
4) или автоматический генератор КП + SLA из этой системы
|
||||
|
||||
Это уже уровень **enterprise SaaS, а не просто инженерной компании**.
|
||||
@@ -0,0 +1,629 @@
|
||||
Ниже — как должна работать автоматическая система SHS (System Health Score) в твоей модели AegisOne Engineering.
|
||||
|
||||
Это уже не “аналитика бизнеса”, а:
|
||||
|
||||
> инженерная система раннего предупреждения о деградации компании
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
0. ЧТО ТАКОЕ SHS (СУТЬ СИСТЕМЫ)
|
||||
|
||||
SHS — это единый индекс здоровья бизнеса (0–100), который показывает:
|
||||
|
||||
насколько стабильно работает SLA-модель
|
||||
|
||||
где теряются деньги
|
||||
|
||||
где растут риски разрыва контрактов
|
||||
|
||||
где перегружается команда
|
||||
|
||||
где падает качество эксплуатации
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
1. ЛОГИКА СИСТЕМЫ SHS
|
||||
|
||||
Данные (CRM + SLA + инженеры)
|
||||
↓
|
||||
Нормализация метрик
|
||||
↓
|
||||
Взвешивание показателей
|
||||
↓
|
||||
Расчёт SHS
|
||||
↓
|
||||
Детектирование отклонений
|
||||
↓
|
||||
Сигналы риска (alerts)
|
||||
|
||||
|
||||
---
|
||||
|
||||
2. ФИНАЛЬНАЯ ФОРМУЛА SHS
|
||||
|
||||
SHS =
|
||||
(0.22 × SLA Stability Index) +
|
||||
(0.18 × Revenue Stability Index) +
|
||||
(0.18 × Retention Index) +
|
||||
(0.15 × Engineering Performance Index) +
|
||||
(0.12 × Incident Stability Index) +
|
||||
(0.10 × Sales Flow Index) +
|
||||
(0.05 × Operational Efficiency Index)
|
||||
|
||||
|
||||
---
|
||||
|
||||
3. РАСШИФРОВКА ВСЕХ КОМПОНЕНТОВ
|
||||
|
||||
|
||||
---
|
||||
|
||||
3.1 SLA STABILITY INDEX (критический)
|
||||
|
||||
Смысл:
|
||||
|
||||
Насколько система выполняет SLA без сбоев.
|
||||
|
||||
|
||||
---
|
||||
|
||||
Формула:
|
||||
|
||||
SSI = SLA_compliance × (1 - SLA_breach_severity)
|
||||
|
||||
|
||||
---
|
||||
|
||||
Где:
|
||||
|
||||
SLA_compliance = выполненные заявки / все заявки
|
||||
|
||||
SLA_breach_severity = тяжесть нарушений (0–1)
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Пример:
|
||||
|
||||
compliance = 0.96
|
||||
|
||||
нарушения = 0.1
|
||||
|
||||
|
||||
→ SSI = 0.864
|
||||
|
||||
|
||||
---
|
||||
|
||||
Риски:
|
||||
|
||||
падение ниже 0.85 = начинается утечка клиентов
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
3.2 REVENUE STABILITY INDEX
|
||||
|
||||
Смысл:
|
||||
|
||||
Стабильность денежного потока SLA
|
||||
|
||||
|
||||
---
|
||||
|
||||
Формула:
|
||||
|
||||
RSI = 1 - (σ(MRR) / mean(MRR))
|
||||
|
||||
|
||||
---
|
||||
|
||||
Интерпретация:
|
||||
|
||||
чем меньше колебания → тем выше индекс
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Риски:
|
||||
|
||||
RSI < 0.7 → нестабильная финансовая модель
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
3.3 RETENTION INDEX (очень критично)
|
||||
|
||||
Формула:
|
||||
|
||||
RI = retained_clients / total_clients
|
||||
|
||||
|
||||
---
|
||||
|
||||
Дополнение:
|
||||
|
||||
штраф за уход крупных клиентов:
|
||||
|
||||
RI_adjusted = RI - (lost_key_clients × 0.1)
|
||||
|
||||
|
||||
---
|
||||
|
||||
Риски:
|
||||
|
||||
падение ниже 0.9 = системная проблема SLA
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
3.4 ENGINEERING PERFORMANCE INDEX
|
||||
|
||||
Смысл:
|
||||
|
||||
качество работы инженеров
|
||||
|
||||
|
||||
---
|
||||
|
||||
Формула:
|
||||
|
||||
EPI =
|
||||
(0.3 × SLA compliance engineers) +
|
||||
(0.25 × diagnosis accuracy) +
|
||||
(0.2 × reopen rate inverse) +
|
||||
(0.15 × response time score) +
|
||||
(0.1 × documentation quality)
|
||||
|
||||
|
||||
---
|
||||
|
||||
Важный момент:
|
||||
|
||||
это единственный KPI, который напрямую влияет на:
|
||||
|
||||
> удержание клиентов
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Риски:
|
||||
|
||||
EPI < 0.75 → будущие потери клиентов через 1–2 месяца
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
3.5 INCIDENT STABILITY INDEX
|
||||
|
||||
Смысл:
|
||||
|
||||
насколько система “ломается”
|
||||
|
||||
|
||||
---
|
||||
|
||||
Формула:
|
||||
|
||||
ISI = 1 - (incidents / objects × severity_weight)
|
||||
|
||||
|
||||
---
|
||||
|
||||
Где severity_weight:
|
||||
|
||||
критический = 1.0
|
||||
|
||||
средний = 0.5
|
||||
|
||||
низкий = 0.2
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Риски:
|
||||
|
||||
рост ISI вниз = деградация инфраструктуры
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
3.6 SALES FLOW INDEX
|
||||
|
||||
Смысл:
|
||||
|
||||
здоровье входящего потока денег
|
||||
|
||||
|
||||
---
|
||||
|
||||
Формула:
|
||||
|
||||
SFI = (audits → SLA conversion rate) × lead quality
|
||||
|
||||
|
||||
---
|
||||
|
||||
Пример:
|
||||
|
||||
конверсия 0.35
|
||||
|
||||
качество лидов 0.8
|
||||
|
||||
|
||||
→ SFI = 0.28
|
||||
|
||||
|
||||
---
|
||||
|
||||
Риски:
|
||||
|
||||
SFI < 0.25 → нет роста MRR
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
3.7 OPERATIONAL EFFICIENCY INDEX
|
||||
|
||||
Смысл:
|
||||
|
||||
насколько эффективно работает компания внутри
|
||||
|
||||
|
||||
---
|
||||
|
||||
Формула:
|
||||
|
||||
OEI = revenue / (engineer_hours × cost)
|
||||
|
||||
|
||||
---
|
||||
|
||||
Риски:
|
||||
|
||||
падение → перегруз команды
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
4. ИНТЕРПРЕТАЦИЯ SHS
|
||||
|
||||
|
||||
---
|
||||
|
||||
SHS Состояние системы
|
||||
|
||||
85–100 масштабируемый рост
|
||||
70–85 стабильная работа
|
||||
50–70 скрытые проблемы
|
||||
<50 системный кризис
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
5. ГЛАВНАЯ СИЛА SHS — НЕ ЧИСЛО, А ДИНАМИКА
|
||||
|
||||
|
||||
---
|
||||
|
||||
ВАЖНО:
|
||||
|
||||
Ты смотришь не на значение, а на:
|
||||
|
||||
Δ SHS (изменение)
|
||||
|
||||
ΔSHS = SHS_today - SHS_last_week
|
||||
|
||||
|
||||
---
|
||||
|
||||
Критично:
|
||||
|
||||
падение > 5 пунктов за неделю → тревога
|
||||
|
||||
падение > 10 → кризис
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
6. СИСТЕМА АВТОМАТИЧЕСКИХ СИГНАЛОВ
|
||||
|
||||
|
||||
---
|
||||
|
||||
GREEN ZONE:
|
||||
|
||||
SHS > 80
|
||||
|
||||
нет действий
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
YELLOW ZONE:
|
||||
|
||||
SHS 65–80
|
||||
|
||||
|
||||
👉 действия:
|
||||
|
||||
проверить инженеров
|
||||
|
||||
проверить SLA просадки
|
||||
|
||||
проверить загрузку
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
RED ZONE:
|
||||
|
||||
SHS < 65
|
||||
|
||||
|
||||
👉 действия:
|
||||
|
||||
аудит клиентов
|
||||
|
||||
пересмотр инженеров
|
||||
|
||||
срочный анализ SLA нарушений
|
||||
|
||||
заморозка новых продаж
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
7. КОГДА ПОЯВЛЯЮТСЯ РИСКИ
|
||||
|
||||
|
||||
---
|
||||
|
||||
РИСК №1 — падение EPI
|
||||
|
||||
Причина:
|
||||
|
||||
инженеры начали “делать быстро, но плохо”
|
||||
|
||||
Симптом:
|
||||
|
||||
рост повторных заявок
|
||||
|
||||
жалобы клиентов через 2–3 недели
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
РИСК №2 — рост INCIDENT RATE
|
||||
|
||||
Причина:
|
||||
|
||||
старое оборудование
|
||||
|
||||
плохая эксплуатация
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
РИСК №3 — падение RETENTION
|
||||
|
||||
Самый опасный
|
||||
|
||||
👉 означает:
|
||||
|
||||
> клиент уже не верит системе
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
РИСК №4 — нестабильный SFI
|
||||
|
||||
Причина:
|
||||
|
||||
слабый маркетинг
|
||||
|
||||
неправильный аудит
|
||||
|
||||
некачественные лиды
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
РИСК №5 — падение OEI
|
||||
|
||||
Причина:
|
||||
|
||||
перегруз инженеров
|
||||
|
||||
хаотичные выезды
|
||||
|
||||
нет стандартизации
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
8. КАК ИСПРАВЛЯТЬ РИСКИ
|
||||
|
||||
|
||||
---
|
||||
|
||||
ЕСЛИ ПАДАЕТ SHS:
|
||||
|
||||
|
||||
---
|
||||
|
||||
ШАГ 1 — локализация
|
||||
|
||||
разбить SHS на компоненты:
|
||||
|
||||
где падение?
|
||||
|
||||
SLA?
|
||||
|
||||
инженеры?
|
||||
|
||||
продажи?
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
ШАГ 2 — точечное вмешательство
|
||||
|
||||
проблема действие
|
||||
|
||||
EPI падает обучение инженеров + чек-листы
|
||||
retention падает аудит объектов
|
||||
SLA падает перераспределение нагрузки
|
||||
SFI падает фильтрация лидов
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
ШАГ 3 — стабилизация
|
||||
|
||||
ограничить новые продажи
|
||||
|
||||
усилить контроль SLA
|
||||
|
||||
снизить нагрузку
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
9. ВАЖНОЕ ПРАВИЛО СИСТЕМЫ
|
||||
|
||||
|
||||
---
|
||||
|
||||
> нельзя “растить бизнес”, если SHS падает
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
10. ВИЗУАЛИЗАЦИЯ SHS (CEO DASHBOARD)
|
||||
|
||||
|
||||
---
|
||||
|
||||
1. SHS LINE
|
||||
|
||||
📈 динамика здоровья компании
|
||||
|
||||
|
||||
---
|
||||
|
||||
2. STACKED INDEX CHART
|
||||
|
||||
SLA
|
||||
|
||||
Revenue
|
||||
|
||||
Engineers
|
||||
|
||||
Retention
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
3. ALERT MAP
|
||||
|
||||
🟥 проблемные зоны
|
||||
|
||||
|
||||
---
|
||||
|
||||
4. ENGINEER IMPACT MAP
|
||||
|
||||
📍 какой инженер влияет на SHS
|
||||
|
||||
|
||||
---
|
||||
|
||||
11. ГЛАВНЫЙ СМЫСЛ SHS
|
||||
|
||||
|
||||
---
|
||||
|
||||
Ты больше не управляешь:
|
||||
|
||||
❌ людьми
|
||||
❌ объектами
|
||||
❌ заявками
|
||||
|
||||
|
||||
---
|
||||
|
||||
Ты управляешь:
|
||||
|
||||
системой стабильности инженерного бизнеса
|
||||
|
||||
|
||||
---
|
||||
|
||||
12. ЕСЛИ ДАЛЬШЕ РАЗВИВАТЬ
|
||||
|
||||
Я могу собрать:
|
||||
|
||||
автоматический SHS калькулятор (Excel / 1C / web)
|
||||
|
||||
real-time dashboard
|
||||
|
||||
систему предиктивных предупреждений (падение SHS за 7–14 дней)
|
||||
|
||||
интеграцию SHS в KPI инженеров
|
||||
|
||||
систему автоматического “замедления продаж” при риске
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
ИТОГ
|
||||
|
||||
SHS — это не метрика.
|
||||
|
||||
> это “нервная система” твоей компании, которая заранее показывает, где бизнес начнёт терять деньги или клиентов
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Если хочешь дальше, следующий логичный шаг:
|
||||
|
||||
сделать тебе полноценную цифровую модель AegisOne (дашборд + CRM + SHS + SLA + KPI инженеров в одной системе)
|
||||
@@ -0,0 +1,2 @@
|
||||
DirectoryIndex index.php
|
||||
Options -Indexes
|
||||
@@ -0,0 +1,88 @@
|
||||
<?php
|
||||
/**
|
||||
* AegisOne Engineering — Документация и соответствие нормативам
|
||||
*/
|
||||
require_once __DIR__ . '/../config.php';
|
||||
require_once __DIR__ . '/../seo.php';
|
||||
|
||||
$pageKey = 'documentation';
|
||||
$canonical = '/documentation/';
|
||||
$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">Разработка, экспертиза и сопровождение проектной документации систем безопасности. Аудит соответствия требованиям регуляторов.</p>
|
||||
<a href="#contacts" class="btn">Заказать документацию</a>
|
||||
<p class="hero__footnote">Работаем по всей России</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="services">
|
||||
<div class="container">
|
||||
<h2 class="section-title">Наши услуги в области документации</h2>
|
||||
<div class="services__grid">
|
||||
<?php
|
||||
$items = [
|
||||
['svg' => '<rect x="16" y="8" width="32" height="48" rx="4" fill="none" stroke="#00ADEF" stroke-width="3"/><line x1="22" y1="18" x2="42" y2="18" stroke="#00ADEF" stroke-width="3"/><line x1="22" y1="28" x2="42" y2="28" stroke="#00ADEF" stroke-width="3"/><line x1="22" y1="38" x2="34" y2="38" stroke="#00ADEF" stroke-width="3"/>', 'title' => 'Проектная документация', 'desc' => 'Разработка разделов проектной документации для систем видеонаблюдения, СКУД, ОПС, периметральной защиты.'],
|
||||
['svg' => '<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"/>', 'title' => 'Экспертиза документации', 'desc' => 'Аудит существующей документации на полноту, соответствие нормативам и актуальность.'],
|
||||
['svg' => '<rect x="12" y="12" width="40" height="40" rx="4" fill="none" stroke="#00ADEF" stroke-width="3"/><polygon points="22,32 30,40 44,24" fill="none" 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' => 'Подготовка документов к проверкам надзорных органов, представительство интересов, устранение замечаний.'],
|
||||
];
|
||||
foreach ($items as $item): ?>
|
||||
<div class="card service-card">
|
||||
<svg class="card__icon" viewBox="0 0 64 64"><?= $item['svg'] ?></svg>
|
||||
<h3><?= $item['title'] ?></h3>
|
||||
<p><?= $item['desc'] ?></p>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="about">
|
||||
<div class="container">
|
||||
<h2 class="section-title">Почему это важно</h2>
|
||||
<div class="info-cards">
|
||||
<div class="info-card">
|
||||
<h3>Риск штрафов и предписаний</h3>
|
||||
<p>Отсутствие или неактуальность документации — одна из частых причин штрафов надзорных органов. Корректно оформленная документация — доказательство соответствия систем всем требованиям.</p>
|
||||
</div>
|
||||
<div class="info-card">
|
||||
<h3>Полный порядок в документах</h3>
|
||||
<p>Мы помогаем привести документацию в порядок: от разработки «с нуля» до экспертизы существующих томов. Все документы разрабатываются в соответствии с актуальными ГОСТ, СП и ведомственными нормативами.</p>
|
||||
</div>
|
||||
<div class="info-card">
|
||||
<h3>Опыт прохождения проверок</h3>
|
||||
<p>Наши специалисты имеют опыт прохождения проверок МЧС, Росгвардии, Ростехнадзора. Мы знаем, на что обращают внимание инспекторы, и подготовим вас к проверке.</p>
|
||||
</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' => 'Зависит от типа объекта. В общем случае: проектная документация (стадия П и Р), исполнительная документация, акты скрытых работ, паспорта и сертификаты на оборудование, акты приёмки.'],
|
||||
['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'; ?>
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
/**
|
||||
* AegisOne Engineering — <noscript> счётчиков аналитики
|
||||
*
|
||||
* Должен подключаться сразу после <body>.
|
||||
* Содержит только <noscript> — валидный HTML только в <body>.
|
||||
*
|
||||
* Подключать: <?php if (file_exists(__DIR__ . '/analytics-body.php')) require __DIR__ . '/analytics-body.php'; ?>
|
||||
*/
|
||||
|
||||
$ymId = defined('YANDEX_METRIKA_ID') ? YANDEX_METRIKA_ID : '';
|
||||
$gaId = defined('GOOGLE_ANALYTICS_ID') ? GOOGLE_ANALYTICS_ID : '';
|
||||
?>
|
||||
|
||||
<?php if ($ymId !== ''): ?>
|
||||
<noscript><div><img src="https://mc.yandex.ru/watch/<?= $ymId ?>" style="position:absolute; left:-9999px;" alt="" /></div></noscript>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($gaId !== ''): ?>
|
||||
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=<?= $gaId ?>" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
|
||||
<?php endif; ?>
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
/**
|
||||
* ============================================
|
||||
* AegisOne Engineering — Счётчики аналитики
|
||||
* ============================================
|
||||
*
|
||||
* Подключается в <head> всех страниц: выводит JS-счётчики.
|
||||
* Подключается в inc/analytics-body.php после <body>: выводит <noscript>.
|
||||
*
|
||||
* Яндекс.Метрика: YANDEX_METRIKA_ID (только цифры)
|
||||
* Google Analytics: GOOGLE_ANALYTICS_ID (G-XXXXXXXXXX)
|
||||
*/
|
||||
|
||||
$ymId = defined('YANDEX_METRIKA_ID') ? YANDEX_METRIKA_ID : '';
|
||||
$gaId = defined('GOOGLE_ANALYTICS_ID') ? GOOGLE_ANALYTICS_ID : '';
|
||||
?>
|
||||
|
||||
<?php if ($ymId !== ''): ?>
|
||||
<!-- Yandex.Metrika counter -->
|
||||
<script type="text/javascript">
|
||||
(function(m,e,t,r,i,k,a){m[i]=m[i]||function(){(m[i].a=m[i].a||[]).push(arguments)};
|
||||
m[i].l=1*new Date();
|
||||
for (var j = 0; j < document.scripts.length; j++) {if (document.scripts[j].src === r) { return; }}
|
||||
k=e.createElement(t),a=e.getElementsByTagName(t)[0],k.async=1,k.src=r,a.parentNode.insertBefore(k,a)
|
||||
})(window, document,'script','https://mc.yandex.ru/metrika/tag.js?id=<?= $ymId ?>', 'ym');
|
||||
ym(<?= $ymId ?>, 'init', {ssr:true, webvisor:true, trackHash:true, clickmap:true, ecommerce:"dataLayer", accurateTrackBounce:true, trackLinks:true});
|
||||
</script>
|
||||
<!-- /Yandex.Metrika counter -->
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($gaId !== ''): ?>
|
||||
<!-- Google Analytics -->
|
||||
<script async src="https://www.googletagmanager.com/gtag/js?id=<?= $gaId ?>"></script>
|
||||
<script>
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag(){dataLayer.push(arguments);}
|
||||
gtag('js', new Date());
|
||||
gtag('config', '<?= $gaId ?>');
|
||||
</script>
|
||||
<!-- /Google Analytics -->
|
||||
<?php endif; ?>
|
||||
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
/**
|
||||
* AegisOne Engineering — Общий блок контактной формы + карта
|
||||
*
|
||||
* Подключается на всех публичных страницах перед футером.
|
||||
* Переменные (опционально):
|
||||
* $contactTitle — заголовок секции (по умолч. «Свяжитесь с нами»)
|
||||
*/
|
||||
$serviceTitles = [
|
||||
'main' => 'Консультация',
|
||||
'audit' => 'Аудит безопасности',
|
||||
'sla' => 'Сервисное обслуживание (SLA)',
|
||||
'incident' => 'Реагирование на инциденты',
|
||||
'supervision' => 'Технический надзор',
|
||||
'documentation' => 'Документация',
|
||||
'risk' => 'Риск-инжиниринг',
|
||||
'blog' => 'Блог',
|
||||
];
|
||||
$serviceTitle = $serviceTitles[$pageKey] ?? '';
|
||||
?>
|
||||
<section class="contacts" id="contacts">
|
||||
<div class="container">
|
||||
<h2 class="section-title"><?= $contactTitle ?? 'Свяжитесь с нами' ?></h2>
|
||||
<div class="contacts__row">
|
||||
<div class="contacts__form" id="form-block">
|
||||
<?php if (defined('LEAD_MAGNET_ENABLED') && LEAD_MAGNET_ENABLED): ?>
|
||||
<div class="lead-magnet"><?= LEAD_MAGNET_TEXT ?></div>
|
||||
<?php endif; ?>
|
||||
<form id="contact-form">
|
||||
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
|
||||
<input type="hidden" name="service" value="<?= $serviceTitle ?? '' ?>">
|
||||
<div class="form-group">
|
||||
<label for="name">Имя *</label>
|
||||
<input type="text" id="name" name="name" maxlength="25" required>
|
||||
<span class="error-msg"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="phone">Телефон *</label>
|
||||
<input type="tel" id="phone" name="phone" required>
|
||||
<span class="error-msg"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="message">Сообщение</label>
|
||||
<textarea id="message" name="message" maxlength="500" placeholder="Не обязательно"></textarea>
|
||||
<span class="char-count">Осталось: 500</span>
|
||||
<span class="error-msg"></span>
|
||||
</div>
|
||||
<div class="form-group form-group--checkbox">
|
||||
<input type="checkbox" id="agree" name="agree" required>
|
||||
<label for="agree">Ознакомлен и согласен с <a href="/politica.php">политикой обработки персональных данных</a> *</label>
|
||||
<span class="error-msg"></span>
|
||||
</div>
|
||||
<button type="submit" class="btn">Отправить</button>
|
||||
</form>
|
||||
<div id="form-response" class="form-response"></div>
|
||||
</div>
|
||||
<div class="contacts__map">
|
||||
<iframe id="yandex-map" data-lon="<?=YANDEX_MAP_LON?>" data-lat="<?=YANDEX_MAP_LAT?>" data-address="<?=htmlspecialchars(YANDEX_MAP_ADDRESS)?>" width="100%" height="400" allowfullscreen title="Местоположение <?=htmlspecialchars(SITE_NAME)?>"></iframe>
|
||||
<p class="map-address"><strong>Адрес <?=SITE_NAME?>:</strong> <?= YANDEX_MAP_ADDRESS ?></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
/**
|
||||
* AegisOne Engineering — Общий шаблон футера для публичных страниц
|
||||
*
|
||||
* Подключается в конце страницы, после всего контента.
|
||||
* Выводит: sticky-панель → footer → скрипты → </body></html>
|
||||
*
|
||||
* Дополнительно (опционально):
|
||||
* $btnText — текст кнопки в sticky-панели (по умолчанию «Оставить заявку»)
|
||||
*/
|
||||
?>
|
||||
<div class="sticky-panel" id="sticky-panel">
|
||||
<div class="sticky-panel__inner">
|
||||
<a href="tel:+<?= PHONE_MAIN_LINK ?>">
|
||||
<svg class="sticky-icon" viewBox="0 0 24 24"><path d="M6.62 10.79c1.44 2.83 3.76 5.14 6.59 6.59l2.2-2.2c.27-.27.67-.36 1.02-.24 1.12.37 2.33.57 3.57.57.55 0 1 .45 1 1V20c0 .55-.45 1-1 1-9.39 0-17-7.61-17-17 0-.55.45-1 1-1h3.5c.55 0 1 .45 1 1 0 1.25.2 2.45.57 3.57.11.35.03.74-.25 1.02l-2.2 2.2z"/></svg>
|
||||
<span><?= PHONE_MAIN ?></span>
|
||||
</a>
|
||||
<a href="<?= WHATSAPP_LINK ?>" target="_blank" aria-label="WhatsApp">
|
||||
<svg class="sticky-icon" viewBox="0 0 32 32"><path d="M16 0C7.16 0 0 7.16 0 16c0 2.8.72 5.44 2.08 7.76L0 32l8.4-2.08C10.24 31.2 13.04 32 16 32c8.84 0 16-7.16 16-16S24.84 0 16 0zm0 29.2c-2.36 0-4.64-.64-6.6-1.84l-.48-.28-5 1.28 1.32-4.84-.32-.52C3.56 20.8 2.8 18.48 2.8 16 2.8 8.72 8.72 2.8 16 2.8S29.2 8.72 29.2 16 23.28 29.2 16 29.2zm7.24-8.44c-.36-.2-2.12-1.04-2.44-1.16-.32-.12-.56-.2-.8.2-.24.4-.92 1.16-1.12 1.4-.2.24-.4.28-.76.08-.36-.2-1.52-.56-2.88-1.76-1.08-.96-1.8-2.16-2-2.52-.2-.36-.04-.56.16-.76.16-.16.36-.44.56-.64.2-.2.24-.36.4-.6.16-.24.08-.44-.04-.64-.12-.2-.8-1.96-1.12-2.68-.28-.72-.56-.6-.8-.6-.2 0-.44-.04-.68-.04s-.6.08-.92.44c-.32.36-1.2 1.16-1.2 2.84s1.24 3.28 1.4 3.52c.16.24 2.44 3.76 5.92 5.28 2.92 1.28 2.92.84 3.44.8.52-.04 2.12-.88 2.4-1.72.28-.84.28-1.56.2-1.72-.08-.16-.32-.24-.68-.4z"/></svg>
|
||||
</a>
|
||||
<a href="<?= TELEGRAM_LINK ?>" target="_blank" aria-label="Telegram">
|
||||
<svg class="sticky-icon" viewBox="0 0 32 32"><path d="M16 0C7.16 0 0 7.16 0 16s7.16 16 16 16 16-7.16 16-16S24.84 0 16 0zm7.84 11.04l-2.88 13.56c-.2 1-.84 1.24-1.68.76l-4.64-3.44-2.24 2.16c-.24.24-.44.44-.92.44l.32-4.76 8.64-7.8c.36-.32-.08-.48-.56-.16l-10.68 6.72-4.6-1.44c-1-.32-1-1 .2-1.48l18-6.96c.84-.32 1.56.2 1.28 1.44z"/></svg>
|
||||
</a>
|
||||
<?php if (defined('MAX_LINK') && MAX_LINK): ?>
|
||||
<a href="<?= MAX_LINK ?>" target="_blank" aria-label="Макс">
|
||||
<img src="/assets/img/Max_logo.svg" alt="Макс" class="sticky-icon">
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
<a href="#contacts" class="btn"><?= $btnText ?? 'Оставить заявку' ?></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<footer class="footer">
|
||||
<div class="container footer__inner">
|
||||
<div class="footer__col">
|
||||
<h4>Контакты</h4>
|
||||
<a href="tel:+<?= PHONE_MAIN_LINK ?>"><?= PHONE_MAIN ?></a>
|
||||
<a href="tel:+<?= PHONE_SECOND_LINK ?>"><?= PHONE_SECOND ?></a>
|
||||
<a href="mailto:<?= SITE_MAIL ?>"><?= SITE_MAIL ?></a>
|
||||
<p style="margin-top:10px; font-size:0.85rem; opacity:0.7;"><?= YANDEX_MAP_ADDRESS ?></p>
|
||||
</div>
|
||||
<div class="footer__col">
|
||||
<h4>Услуги</h4>
|
||||
<a href="/audit/">Аудит безопасности</a>
|
||||
<a href="/sla/">Сервисное обслуживание (SLA)</a>
|
||||
<a href="/incident/">Реагирование на инциденты</a>
|
||||
<a href="/supervision/">Технический надзор</a>
|
||||
<a href="/documentation/">Документация и соответствие нормативам</a>
|
||||
<a href="/risk/">Риск-инжиниринг</a>
|
||||
</div>
|
||||
<div class="footer__col">
|
||||
<h4>Мы в соцсетях</h4>
|
||||
<div class="footer__social">
|
||||
<a href="<?= TELEGRAM_LINK ?>" target="_blank" aria-label="Telegram">
|
||||
<svg viewBox="0 0 32 32"><path d="M16 0C7.16 0 0 7.16 0 16s7.16 16 16 16 16-7.16 16-16S24.84 0 16 0zm7.84 11.04l-2.88 13.56c-.2 1-.84 1.24-1.68.76l-4.64-3.44-2.24 2.16c-.24.24-.44.44-.92.44l.32-4.76 8.64-7.8c.36-.32-.08-.48-.56-.16l-10.68 6.72-4.6-1.44c-1-.32-1-1 .2-1.48l18-6.96c.84-.32 1.56.2 1.28 1.44z" fill="#fff"/></svg>
|
||||
</a>
|
||||
<a href="<?= WHATSAPP_LINK ?>" target="_blank" aria-label="WhatsApp">
|
||||
<svg viewBox="0 0 32 32"><path d="M16 0C7.16 0 0 7.16 0 16c0 2.8.72 5.44 2.08 7.76L0 32l8.4-2.08C10.24 31.2 13.04 32 16 32c8.84 0 16-7.16 16-16S24.84 0 16 0zm0 29.2c-2.36 0-4.64-.64-6.6-1.84l-.48-.28-5 1.28 1.32-4.84-.32-.52C3.56 20.8 2.8 18.48 2.8 16 2.8 8.72 8.72 2.8 16 2.8S29.2 8.72 29.2 16 23.28 29.2 16 29.2zm7.24-8.44c-.36-.2-2.12-1.04-2.44-1.16-.32-.12-.56-.2-.8.2-.24.4-.92 1.16-1.12 1.4-.2.24-.4.28-.76.08-.36-.2-1.52-.56-2.88-1.76-1.08-.96-1.8-2.16-2-2.52-.2-.36-.04-.56.16-.76.16-.16.36-.44.56-.64.2-.2.24-.36.4-.6.16-.24.08-.44-.04-.64-.12-.2-.8-1.96-1.12-2.68-.28-.72-.56-.6-.8-.6-.2 0-.44-.04-.68-.04s-.6.08-.92.44c-.32.36-1.2 1.16-1.2 2.84s1.24 3.28 1.4 3.52c.16.24 2.44 3.76 5.92 5.28 2.92 1.28 2.92.84 3.44.8.52-.04 2.12-.88 2.4-1.72.28-.84.28-1.56.2-1.72-.08-.16-.32-.24-.68-.4z" fill="#fff"/></svg>
|
||||
</a>
|
||||
<?php if (defined('MAX_LINK') && MAX_LINK): ?>
|
||||
<a href="<?= MAX_LINK ?>" target="_blank" aria-label="Макс">
|
||||
<img src="/assets/img/Max_logo.svg" alt="Макс" class="footer-social-icon">
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<p style="margin-top:12px; font-size:0.85rem;"><strong>Работаем по всей России</strong></p>
|
||||
</div>
|
||||
<div class="footer__bottom">
|
||||
<a href="/politica.php" style="color:var(--accent); display:inline-block; margin-bottom:8px;">Политика конфиденциальности</a><br>
|
||||
© <?= date('Y') ?> <?= SITE_LEGAL_NAME ?>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script src="/assets/js/main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
session_start();
|
||||
|
||||
if (empty($_SESSION['csrf_token'])) {
|
||||
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
|
||||
}
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['ajax'])) {
|
||||
header('Content-Type: application/json');
|
||||
$response = ['success' => false, 'message' => ''];
|
||||
|
||||
$csrf_token = $_POST['csrf_token'] ?? '';
|
||||
if (!hash_equals($_SESSION['csrf_token'], $csrf_token)) {
|
||||
$response['message'] = 'Ошибка безопасности. Обновите страницу и попробуйте снова.';
|
||||
echo json_encode($response);
|
||||
exit;
|
||||
}
|
||||
|
||||
$ip = $_SERVER['REMOTE_ADDR'];
|
||||
$rateKey = 'rate_' . md5($ip);
|
||||
$now = time();
|
||||
$rateData = $_SESSION[$rateKey] ?? ['count' => 0, 'first' => $now];
|
||||
if ($now - $rateData['first'] > 60) {
|
||||
$rateData = ['count' => 0, 'first' => $now];
|
||||
}
|
||||
$rateData['count']++;
|
||||
$_SESSION[$rateKey] = $rateData;
|
||||
if ($rateData['count'] > 3) {
|
||||
$response['message'] = 'Слишком много запросов. Попробуйте через минуту.';
|
||||
echo json_encode($response);
|
||||
exit;
|
||||
}
|
||||
|
||||
$name = trim($_POST['name'] ?? '');
|
||||
$phone = trim($_POST['phone'] ?? '');
|
||||
$message = trim($_POST['message'] ?? '');
|
||||
$agree = isset($_POST['agree']);
|
||||
|
||||
if (!preg_match('/^[a-zA-Zа-яА-Я\s]{1,25}$/u', $name)) {
|
||||
$response['message'] = 'Имя должно содержать только буквы и пробелы, до 25 символов.';
|
||||
echo json_encode($response);
|
||||
exit;
|
||||
}
|
||||
if (!preg_match('/^8\s\(\d{3}\)\s\d{3}-\d{2}-\d{2}$/', $phone)) {
|
||||
$response['message'] = 'Введите корректный номер телефона.';
|
||||
echo json_encode($response);
|
||||
exit;
|
||||
}
|
||||
if ($message !== '' && !preg_match('/^.{1,500}$/u', $message)) {
|
||||
$response['message'] = 'Сообщение не должно превышать 500 символов.';
|
||||
echo json_encode($response);
|
||||
exit;
|
||||
}
|
||||
if (!$agree) {
|
||||
$response['message'] = 'Необходимо согласиться с обработкой данных.';
|
||||
echo json_encode($response);
|
||||
exit;
|
||||
}
|
||||
|
||||
$dateTime = date('d.m.Y H:i:s');
|
||||
$serviceTitle = trim($_POST['service'] ?? '');
|
||||
$subject = SITE_MAIL_SUBJECT_PREFIX;
|
||||
if ($serviceTitle !== '') {
|
||||
$subject .= ' (' . $serviceTitle . ')';
|
||||
}
|
||||
$subject .= ' — ' . $dateTime;
|
||||
|
||||
$body = "Услуга: " . ($serviceTitle !== '' ? $serviceTitle : 'Главная страница') . "\n";
|
||||
$body .= "Имя: " . strip_tags($name) . "\n";
|
||||
$body .= "Телефон: " . strip_tags($phone) . "\n";
|
||||
$body .= "Сообщение: " . strip_tags($message) . "\n";
|
||||
$body .= "Согласие на обработку данных: Да\n";
|
||||
$body .= "Страница: " . ($_SERVER['HTTP_REFERER'] ?? 'неизвестно') . "\n";
|
||||
|
||||
$headers = "From: " . SITE_MAIL_FROM . "\r\n";
|
||||
$headers .= "Reply-To: " . SITE_MAIL_FROM . "\r\n";
|
||||
$headers .= "Content-Type: text/plain; charset=UTF-8\r\n";
|
||||
|
||||
$mailSent = mail(SITE_MAIL_TO, $subject, $body, $headers);
|
||||
|
||||
if ($mailSent) {
|
||||
$response['success'] = true;
|
||||
$response['message'] = 'Спасибо! Ваша заявка отправлена. Мы свяжемся с вами в ближайшее время.';
|
||||
} else {
|
||||
$response['message'] = 'Ошибка при отправке. Пожалуйста, попробуйте ещё раз.';
|
||||
}
|
||||
echo json_encode($response);
|
||||
exit;
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
<?php
|
||||
/**
|
||||
* AegisOne Engineering — Общий шаблон <head> и <header> для публичных страниц
|
||||
*
|
||||
* Подключается после установки переменных:
|
||||
* $pageKey — ключ из массива $SEO
|
||||
* $canonical — канонический URL (с ведущим слешем, напр. /audit/)
|
||||
*
|
||||
* Дополнительно (опционально):
|
||||
* $robots — значение <meta name="robots"> (по умолчанию не выводится)
|
||||
*
|
||||
* Стек:
|
||||
* config.php → seo.php → form-handler.php → header.php → контент → footer.php
|
||||
*/
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title><?= $SEO[$pageKey]['title'] ?></title>
|
||||
<meta name="description" content="<?= $SEO[$pageKey]['description'] ?>">
|
||||
<meta name="keywords" content="<?= $SEO[$pageKey]['keywords'] ?>">
|
||||
<link rel="canonical" href="https://<?= $_SERVER['HTTP_HOST'] ?><?= $canonical ?? '/' ?>">
|
||||
<?php if (!empty($robots)): ?>
|
||||
<meta name="robots" content="<?= $robots ?>">
|
||||
<?php endif; ?>
|
||||
<link rel="icon" type="image/x-icon" href="/assets/img/favicon.ico">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/assets/img/favicon-16x16.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/assets/img/favicon-32x32.png">
|
||||
<link rel="apple-touch-icon" href="/assets/img/apple-touch-icon.png">
|
||||
<link rel="manifest" href="/site.webmanifest">
|
||||
<meta name="msapplication-TileImage" content="/assets/img/android-chrome-192x192.png">
|
||||
<link rel="stylesheet" href="/style.php">
|
||||
<script>
|
||||
(function(){
|
||||
var t=localStorage.getItem('theme')||'system';
|
||||
var d=t==='system'?(window.matchMedia('(prefers-color-scheme: dark)').matches?'dark':'light'):t;
|
||||
document.documentElement.setAttribute('data-theme',d);
|
||||
})();
|
||||
</script>
|
||||
<?php if (file_exists(__DIR__ . '/analytics.php')) require __DIR__ . '/analytics.php'; ?>
|
||||
<script type="application/ld+json">
|
||||
{
|
||||
"@context": "https://schema.org",
|
||||
"@type": "Organization",
|
||||
"name": "<?= SITE_LEGAL_NAME ?>",
|
||||
"description": "Инженерные решения для безопасности бизнеса",
|
||||
"url": "https://<?= SITE_DOMAIN ?>",
|
||||
"logo": "https://<?= SITE_DOMAIN ?>/logo.php",
|
||||
"telephone": "<?= PHONE_MAIN ?>",
|
||||
"email": "<?= SITE_MAIL ?>",
|
||||
"contactPoint": {
|
||||
"@type": "ContactPoint",
|
||||
"telephone": "<?= PHONE_MAIN ?>",
|
||||
"contactType": "sales",
|
||||
"availableLanguage": ["Russian"]
|
||||
},
|
||||
"address": {
|
||||
"@type": "PostalAddress",
|
||||
"addressLocality": "Краснодар",
|
||||
"addressRegion": "Краснодарский край",
|
||||
"postalCode": "350072",
|
||||
"streetAddress": "ул. Московская, д. 81/1, пом. 25"
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<?php if (file_exists(__DIR__ . '/analytics-body.php')) require __DIR__ . '/analytics-body.php'; ?>
|
||||
<div class="cookie-banner" id="cookie-banner">
|
||||
<div class="container cookie-banner__inner">
|
||||
<p>Мы используем cookie-файлы. Продолжая использовать сайт, вы соглашаетесь с <a href="/politica.php">политикой обработки персональных данных</a>.</p>
|
||||
<button class="btn" id="cookie-accept">Принять</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<header class="header">
|
||||
<div class="container header__inner">
|
||||
<div class="header__logo">
|
||||
<a href="/"><img src="/logo.php" alt="<?= SITE_NAME ?>"></a>
|
||||
</div>
|
||||
<nav class="header__nav">
|
||||
<ul class="header__menu">
|
||||
<?php if ($pageKey === 'main'): ?>
|
||||
<li><a href="#problems">Проблемы</a></li>
|
||||
<li><a href="#services">Услуги</a></li>
|
||||
<li><a href="#about">О нас</a></li>
|
||||
<li><a href="#cases">Кейсы</a></li>
|
||||
<li><a href="#faq">Вопросы</a></li>
|
||||
<li><a href="#contacts">Контакты</a></li>
|
||||
<?php else: ?>
|
||||
<li><a href="/#services">Услуги</a></li>
|
||||
<li><a href="/#about">О нас</a></li>
|
||||
<li><a href="/#cases">Кейсы</a></li>
|
||||
<li><a href="/blog/">Блог</a></li>
|
||||
<li><a href="#faq">Вопросы</a></li>
|
||||
<li><a href="#contacts">Контакты</a></li>
|
||||
<?php endif; ?>
|
||||
</ul>
|
||||
</nav>
|
||||
<div class="header__phone">
|
||||
<a href="tel:+<?= PHONE_MAIN_LINK ?>"><?= PHONE_MAIN ?></a>
|
||||
</div>
|
||||
<div class="theme-switcher" id="theme-switcher" title="Сменить тему оформления">
|
||||
<button class="theme-switcher__btn" id="theme-btn" aria-label="Переключить тему">
|
||||
<span class="theme-switcher__icon" id="theme-icon"></span>
|
||||
</button>
|
||||
<div class="theme-switcher__tooltip" id="theme-tooltip"></div>
|
||||
</div>
|
||||
<button class="burger" id="burger">
|
||||
<span></span><span></span><span></span>
|
||||
</button>
|
||||
</div>
|
||||
</header>
|
||||
@@ -0,0 +1,2 @@
|
||||
DirectoryIndex index.php
|
||||
Options -Indexes
|
||||
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
/**
|
||||
* AegisOne Engineering — Реагирование на инциденты
|
||||
*/
|
||||
require_once __DIR__ . '/../config.php';
|
||||
require_once __DIR__ . '/../seo.php';
|
||||
|
||||
$pageKey = 'incident';
|
||||
$canonical = '/incident/';
|
||||
$btnText = 'Оставить заявку';
|
||||
$contactTitle = 'Связаться с нами';
|
||||
require_once __DIR__ . '/../inc/form-handler.php';
|
||||
require __DIR__ . '/../inc/header.php';
|
||||
?>
|
||||
<style>
|
||||
.incident-flow { display:grid; grid-template-columns:repeat(auto-fit,minmax(220px,1fr)); gap:20px; margin-top:40px; }
|
||||
.incident-flow__step { text-align:center; padding:30px 20px; background:var(--bg-card); border:1px solid var(--border); border-radius:12px; box-shadow:var(--shadow-sm); transition:transform var(--transition),box-shadow var(--transition),background var(--transition); }
|
||||
.incident-flow__step:hover { transform:translateY(-3px); box-shadow:var(--shadow-md); }
|
||||
.incident-flow__step .step__num { margin:0 auto 15px; }
|
||||
</style>
|
||||
|
||||
<section class="hero" id="hero">
|
||||
<div class="container">
|
||||
<h1 class="hero__title"><?= $SEO[$pageKey]['h1'] ?></h1>
|
||||
<p class="hero__subtitle">Круглосуточный мониторинг и оперативное реагирование на инциденты. Минимизируем последствия, расследуем причины, предотвращаем повторение.</p>
|
||||
<a href="#contacts" class="btn">Оставить заявку</a>
|
||||
<p class="hero__footnote">Работаем по всей России</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="services">
|
||||
<div class="container">
|
||||
<h2 class="section-title">Наши возможности</h2>
|
||||
<div class="services__grid">
|
||||
<?php
|
||||
$items = [
|
||||
['svg' => '<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"/>', 'title' => 'Мониторинг 24/7', 'desc' => 'Непрерывный контроль систем безопасности, оперативное выявление нештатных ситуаций и оповещение ответственных лиц.'],
|
||||
['svg' => '<rect x="12" y="12" width="40" height="40" rx="4" fill="none" stroke="#00ADEF" stroke-width="3"/><polygon points="22,28 30,36 44,20" fill="none" stroke="#00ADEF" stroke-width="3"/>', 'title' => 'Расследование инцидентов', 'desc' => 'Экспертный анализ произошедшего: сбор данных, восстановление хронологии, выявление причин и виновных.'],
|
||||
['svg' => '<path d="M48 24 L56 32 L48 40" fill="none" stroke="#00ADEF" stroke-width="3"/><path d="M16 24 L8 32 L16 40" fill="none" stroke="#00ADEF" stroke-width="3"/><line x1="28" y1="20" x2="36" y2="44" stroke="#00ADEF" stroke-width="3"/>', 'title' => 'Устранение последствий', 'desc' => 'Оперативное восстановление работоспособности систем, закрытие уязвимостей, корректировка настроек.'],
|
||||
['svg' => '<polygon points="32,8 48,28 44,52 20,52 16,28" fill="none" stroke="#00ADEF" stroke-width="3"/><circle cx="32" cy="34" r="6" fill="none" stroke="#00ADEF" stroke-width="3"/>', 'title' => 'Предиктивная аналитика', 'desc' => 'Анализ данных для прогнозирования потенциальных инцидентов и предотвращения их до возникновения.'],
|
||||
];
|
||||
foreach ($items as $item): ?>
|
||||
<div class="card service-card">
|
||||
<svg class="card__icon" viewBox="0 0 64 64"><?= $item['svg'] ?></svg>
|
||||
<h3><?= $item['title'] ?></h3>
|
||||
<p><?= $item['desc'] ?></p>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="about">
|
||||
<div class="container">
|
||||
<h2 class="section-title">Процесс реагирования</h2>
|
||||
<div class="incident-flow">
|
||||
<?php
|
||||
$steps = [
|
||||
['num' => '1', 'title' => 'Обнаружение', 'desc' => 'Система мониторинга фиксирует отклонение или вы сообщаете об инциденте.'],
|
||||
['num' => '2', 'title' => 'Выезд', 'desc' => 'Дежурный инженер выезжает на объект в гарантированные сроки.'],
|
||||
['num' => '3', 'title' => 'Локализация', 'desc' => 'Оперативное устранение угрозы и восстановление штатного режима.'],
|
||||
['num' => '4', 'title' => 'Расследование', 'desc' => 'Детальный разбор причин, подготовка отчёта, рекомендации.'],
|
||||
];
|
||||
foreach ($steps as $step): ?>
|
||||
<div class="incident-flow__step">
|
||||
<div class="step__num"><?= $step['num'] ?></div>
|
||||
<h3><?= $step['title'] ?></h3>
|
||||
<p><?= $step['desc'] ?></p>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</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: от 4 до 24 часов. Для экстренных ситуаций возможен срочный выезд.'],
|
||||
['q' => 'Вы работаете только с системами безопасности?', 'a' => 'Да, мы специализируемся на инцидентах, связанных с видеонаблюдением, СКУД, ОПС и периметральной защитой.'],
|
||||
['q' => 'Нужен ли договор на обслуживание?', 'a' => 'Для регулярного мониторинга — да, заключается SLA-контракт. Разовый выезд возможен без договора, по заявке.'],
|
||||
];
|
||||
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'; ?>
|
||||
@@ -0,0 +1,201 @@
|
||||
<?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=1 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'; ?>
|
||||
@@ -0,0 +1,4 @@
|
||||
<?php
|
||||
header('Content-Type: image/png');
|
||||
header('Cache-Control: public, max-age=86400');
|
||||
readfile(__DIR__ . '/assets/img/logo.png');
|
||||
@@ -0,0 +1,126 @@
|
||||
<?php
|
||||
/**
|
||||
* AegisOne Engineering — Политика конфиденциальности
|
||||
*
|
||||
* Страница-заглушка с noindex, не содержит аналитику и форму.
|
||||
*/
|
||||
require_once __DIR__ . '/config.php';
|
||||
|
||||
$pageKey = 'main';
|
||||
$canonical = '/politica.php';
|
||||
$robots = 'noindex, nofollow';
|
||||
require __DIR__ . '/inc/header.php';
|
||||
?>
|
||||
<style>
|
||||
.policy { padding:60px 0; }
|
||||
.policy__nav { background:var(--light-bg); padding:30px; border-radius:12px; margin-bottom:50px; box-shadow:0 5px 15px rgba(0,0,0,0.05); }
|
||||
.policy__nav h2 { font-size:1.2rem; color:var(--primary); margin-bottom:15px; }
|
||||
.policy__nav ul { list-style:none; display:flex; flex-direction:column; gap:10px; }
|
||||
.policy__nav a { color:var(--accent); text-decoration:none; font-weight:600; transition:color 0.3s; }
|
||||
.policy__nav a:hover { color:#0095cc; }
|
||||
.policy__section { background:var(--white); padding:40px; border-radius:12px; box-shadow:0 5px 15px rgba(0,0,0,0.05); margin-bottom:40px; }
|
||||
.policy__section h2 { color:var(--primary); font-size:1.8rem; margin-bottom:25px; padding-bottom:10px; border-bottom:3px solid var(--accent); }
|
||||
.policy__section h3 { color:var(--primary); font-size:1.2rem; margin:20px 0 10px; }
|
||||
.policy__section p { margin-bottom:12px; line-height:1.7; }
|
||||
.policy__section ul { margin:10px 0 15px 25px; line-height:1.7; }
|
||||
.policy__back { display:flex; justify-content:center; margin-bottom:40px; }
|
||||
@media (max-width:768px) { .policy__section { padding:25px; } .policy__section h2 { font-size:1.4rem; } }
|
||||
</style>
|
||||
|
||||
<section class="policy">
|
||||
<div class="container">
|
||||
<div class="policy__back">
|
||||
<a href="javascript:history.back()" class="btn">← Вернуться назад</a>
|
||||
</div>
|
||||
|
||||
<div class="policy__nav">
|
||||
<h2>Содержание</h2>
|
||||
<ul>
|
||||
<li><a href="#privacy">Политика конфиденциальности</a></li>
|
||||
<li><a href="#advertising">Политика рекламной рассылки</a></li>
|
||||
<li><a href="#agreement">Соглашение на обработку персональных данных</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div id="privacy" class="policy__section">
|
||||
<h2>Политика конфиденциальности</h2>
|
||||
<h3>1. Общие положения</h3>
|
||||
<p>Настоящая политика обработки персональных данных составлена в соответствии с требованиями Федерального закона от 27.07.2006. № 152-ФЗ «О персональных данных» (далее — Закон о персональных данных) и определяет порядок обработки персональных данных и меры по обеспечению безопасности персональных данных, предпринимаемые <?= SITE_LEGAL_NAME ?> (далее — Оператор).</p>
|
||||
<p>1.1. Оператор ставит своей важнейшей целью и условием осуществления своей деятельности соблюдение прав и свобод человека и гражданина при обработке его персональных данных, в том числе защиты прав на неприкосновенность частной жизни, личную и семейную тайну.</p>
|
||||
<p>1.2. Настоящая политика Оператора в отношении обработки персональных данных (далее — Политика) применяется ко всей информации, которую Оператор может получить о посетителях веб-сайта https://<?= SITE_DOMAIN ?>.</p>
|
||||
<h3>2. Основные понятия, используемые в Политике</h3>
|
||||
<p>2.1. Автоматизированная обработка персональных данных — обработка персональных данных с помощью средств вычислительной техники.</p>
|
||||
<p>2.2. Блокирование персональных данных — временное прекращение обработки персональных данных (за исключением случаев, если обработка необходима для уточнения персональных данных).</p>
|
||||
<p>2.3. Веб-сайт — совокупность графических и информационных материалов, а также программ для ЭВМ и баз данных, обеспечивающих их доступность в сети интернет по сетевому адресу https://<?= SITE_DOMAIN ?>.</p>
|
||||
<p>2.4. Информационная система персональных данных — совокупность содержащихся в базах данных персональных данных и обеспечивающих их обработку информационных технологий и технических средств.</p>
|
||||
<p>2.5. Обезличивание персональных данных — действия, в результате которых невозможно определить без использования дополнительной информации принадлежность персональных данных конкретному Пользователю или иному субъекту персональных данных.</p>
|
||||
<p>2.6. Обработка персональных данных — любое действие (операция) или совокупность действий (операций), совершаемых с использованием средств автоматизации или без использования таких средств с персональными данными, включая сбор, запись, систематизацию, накопление, хранение, уточнение (обновление, изменение), извлечение, использование, передачу (распространение, предоставление, доступ), обезличивание, блокирование, удаление, уничтожение персональных данных.</p>
|
||||
<p>2.7. Оператор — государственный орган, муниципальный орган, юридическое или физическое лицо, самостоятельно или совместно с другими лицами организующие и/или осуществляющие обработку персональных данных, а также определяющие цели обработки персональных данных, состав персональных данных, подлежащих обработке, действия (операции), совершаемые с персональными данными.</p>
|
||||
<p>2.8. Персональные данные — любая информация, относящаяся прямо или косвенно к определенному или определяемому Пользователю веб-сайта https://<?= SITE_DOMAIN ?>.</p>
|
||||
<p>2.9. Персональные данные, разрешенные субъектом персональных данных для распространения, — персональные данные, доступ неограниченного круга лиц к которым предоставлен субъектом персональных данных путем дачи согласия на обработку персональных данных, разрешенных субъектом персональных данных для распространения в порядке, предусмотренном Законом о персональных данных (далее — персональные данные, разрешенные для распространения).</p>
|
||||
<p>2.10. Пользователь — любой посетитель веб-сайта https://<?= SITE_DOMAIN ?>.</p>
|
||||
<p>2.11. Предоставление персональных данных — действия, направленные на раскрытие персональных данных определенному лицу или определенному кругу лиц.</p>
|
||||
<p>2.12. Распространение персональных данных — любые действия, направленные на раскрытие персональных данных неопределенному кругу лиц (передача персональных данных) или на ознакомление с персональными данными неограниченного круга лиц, в том числе обнародование персональных данных в средствах массовой информации, размещение в информационно-телекоммуникационных сетях или предоставление доступа к персональным данным каким-либо иным способом.</p>
|
||||
<p>2.13. Трансграничная передача персональных данных — передача персональных данных на территорию иностранного государства органу власти иностранного государства, иностранному физическому или иностранному юридическому лицу.</p>
|
||||
<p>2.14. Уничтожение персональных данных — любые действия, в результате которых персональные данные уничтожаются безвозвратно с невозможностью дальнейшего восстановления содержания персональных данных в информационной системе персональных данных и/или уничтожаются материальные носители персональных данных.</p>
|
||||
<h3>3. Основные права и обязанности Оператора</h3>
|
||||
<p>3.1. Оператор имеет право: получать от субъекта персональных данных достоверные информацию и/или документы, содержащие персональные данные; в случае отзыва субъектом персональных данных согласия на обработку персональных данных, а также, направления обращения с требованием о прекращении обработки персональных данных, Оператор вправе продолжить обработку персональных данных без согласия субъекта персональных данных при наличии оснований, указанных в Законе о персональных данных; самостоятельно определять состав и перечень мер, необходимых и достаточных для обеспечения выполнения обязанностей, предусмотренных Законом о персональных данных и принятыми в соответствии с ним нормативными правовыми актами, если иное не предусмотрено Законом о персональных данных или другими федеральными законами.</p>
|
||||
<p>3.2. Оператор обязан: предоставлять субъекту персональных данных по его просьбе информацию, касающуюся обработки его персональных данных; организовывать обработку персональных данных в порядке, установленном действующим законодательством РФ; отвечать на обращения и запросы субъектов персональных данных и их законных представителей в соответствии с требованиями Закона о персональных данных; сообщать в уполномоченный орган по защите прав субъектов персональных данных по запросу этого органа необходимую информацию в течение 10 дней с даты получения такого запроса; публиковать или иным образом обеспечивать неограниченный доступ к настоящей Политике в отношении обработки персональных данных; принимать правовые, организационные и технические меры для защиты персональных данных от неправомерного или случайного доступа к ним, уничтожения, изменения, блокирования, копирования, предоставления, распространения персональных данных, а также от иных неправомерных действий в отношении персональных данных; прекратить передачу (распространение, предоставление, доступ) персональных данных, прекратить обработку и уничтожить персональные данные в порядке и случаях, предусмотренных Законом о персональных данных; исполнять иные обязанности, предусмотренные Законом о персональных данных.</p>
|
||||
<h3>4. Основные права и обязанности субъектов персональных данных</h3>
|
||||
<p>4.1. Субъекты персональных данных имеют право: получать информацию, касающуюся обработки его персональных данных; требовать от оператора уточнения его персональных данных, их блокирования или уничтожения в случае, если персональные данные являются неполными, устаревшими, неточными, незаконно полученными или не являются необходимыми для заявленной цели обработки; выдвигать условие предварительного согласия при обработке персональных данных в целях продвижения на рынке товаров, работ и услуг; на отзыв согласия на обработку персональных данных, а также, на направление требования о прекращении обработки персональных данных; обжаловать в уполномоченный орган по защите прав субъектов персональных данных или в судебном порядке неправомерные действия или бездействие Оператора при обработке его персональных данных; на осуществление иных прав, предусмотренных законодательством РФ.</p>
|
||||
<p>4.2. Субъекты персональных данных обязаны: предоставлять Оператору достоверные данные о себе; сообщать Оператору об уточнении (обновлении, изменении) своих персональных данных.</p>
|
||||
<p>4.3. Лица, передавшие Оператору недостоверные сведения о себе, либо сведения о другом субъекте персональных данных без согласия последнего, несут ответственность в соответствии с законодательством РФ.</p>
|
||||
<h3>5. Принципы обработки персональных данных</h3>
|
||||
<p>5.1. Обработка персональных данных осуществляется на законной и справедливой основе. 5.2. Обработка персональных данных ограничивается достижением конкретных, заранее определенных и законных целей. 5.3. Не допускается объединение баз данных, содержащих персональные данные, обработка которых осуществляется в целях, несовместимых между собой. 5.4. Обработке подлежат только персональные данные, которые отвечают целям их обработки. 5.5. Содержание и объем обрабатываемых персональных данных соответствуют заявленным целям обработки. 5.6. При обработке персональных данных обеспечивается точность персональных данных, их достаточность, а в необходимых случаях и актуальность по отношению к целям обработки персональных данных. 5.7. Хранение персональных данных осуществляется в форме, позволяющей определить субъекта персональных данных, не дольше, чем этого требуют цели обработки персональных данных.</p>
|
||||
<h3>6. Цели обработки персональных данных</h3>
|
||||
<p><strong>Цель обработки:</strong> информирование Пользователя посредством отправки электронных писем.</p>
|
||||
<p><strong>Персональные данные:</strong> фамилия, имя, отчество; электронный адрес; номера телефонов.</p>
|
||||
<p><strong>Правовые основания:</strong> уставные (учредительные) документы Оператора; договоры, заключаемые между оператором и субъектом персональных данных.</p>
|
||||
<p><strong>Виды обработки:</strong> сбор, запись, систематизация, накопление, хранение, уничтожение и обезличивание персональных данных; отправка информационных писем на адрес электронной почты.</p>
|
||||
<h3>7. Условия обработки персональных данных</h3>
|
||||
<p>7.1. Обработка персональных данных осуществляется с согласия субъекта персональных данных на обработку его персональных данных. 7.2. Обработка персональных данных необходима для достижения целей, предусмотренных международным договором Российской Федерации или законом. 7.3. Обработка персональных данных необходима для осуществления правосудия, исполнения судебного акта. 7.4. Обработка персональных данных необходима для исполнения договора. 7.5. Обработка персональных данных необходима для осуществления прав и законных интересов оператора или третьих лиц. 7.6. Осуществляется обработка персональных данных, доступ неограниченного круга лиц к которым предоставлен субъектом персональных данных. 7.7. Осуществляется обработка персональных данных, подлежащих опубликованию или обязательному раскрытию в соответствии с федеральным законом.</p>
|
||||
<h3>8. Порядок сбора, хранения, передачи и других видов обработки персональных данных</h3>
|
||||
<p>Безопасность персональных данных, которые обрабатываются Оператором, обеспечивается путем реализации правовых, организационных и технических мер, необходимых для выполнения в полном объеме требований действующего законодательства в области защиты персональных данных.</p>
|
||||
<p>8.1. Оператор обеспечивает сохранность персональных данных и принимает все возможные меры, исключающие доступ к персональным данным неуполномоченных лиц.</p>
|
||||
<p>8.2. Персональные данные Пользователя никогда, ни при каких условиях не будут переданы третьим лицам, за исключением случаев, связанных с исполнением действующего законодательства либо в случае, если субъектом персональных данных дано согласие Оператору на передачу данных третьему лицу для исполнения обязательств по гражданско-правовому договору.</p>
|
||||
<p>8.3. В случае выявления неточностей в персональных данных, Пользователь может актуализировать их самостоятельно, путем направления Оператору уведомление на адрес электронной почты Оператора <?= SITE_MAIL ?> с пометкой «Актуализация персональных данных».</p>
|
||||
<p>8.4. Срок обработки персональных данных определяется достижением целей, для которых были собраны персональные данные, если иной срок не предусмотрен договором или действующим законодательством. Пользователь может в любой момент отозвать свое согласие на обработку персональных данных, направив Оператору уведомление посредством электронной почты на электронный адрес Оператора <?= SITE_MAIL ?> с пометкой «Отзыв согласия на обработку персональных данных».</p>
|
||||
<p>8.5. Вся информация, которая собирается сторонними сервисами, в том числе платежными системами, средствами связи и другими поставщиками услуг, хранится и обрабатывается указанными лицами (Операторами) в соответствии с их Пользовательским соглашением и Политикой конфиденциальности.</p>
|
||||
<p>8.6-8.9. Оператор при обработке персональных данных обеспечивает конфиденциальность персональных данных, осуществляет хранение в форме, позволяющей определить субъекта персональных данных, не дольше, чем этого требуют цели обработки.</p>
|
||||
<h3>9. Перечень действий, производимых Оператором с полученными персональными данными</h3>
|
||||
<p>9.1. Оператор осуществляет сбор, запись, систематизацию, накопление, хранение, уточнение (обновление, изменение), извлечение, использование, передачу (распространение, предоставление, доступ), обезличивание, блокирование, удаление и уничтожение персональных данных. 9.2. Оператор осуществляет автоматизированную обработку персональных данных с получением и/или передачей полученной информации по информационно-телекоммуникационным сетям или без таковой.</p>
|
||||
<h3>10. Трансграничная передача персональных данных</h3>
|
||||
<p>10.1. Оператор до начала осуществления деятельности по трансграничной передаче персональных данных обязан уведомить уполномоченный орган по защите прав субъектов персональных данных о своем намерении осуществлять трансграничную передачу персональных данных. 10.2. Оператор до подачи вышеуказанного уведомления, обязан получить от органов власти иностранного государства, иностранных физических лиц, иностранных юридических лиц, которым планируется трансграничная передача персональных данных, соответствующие сведения.</p>
|
||||
<h3>11. Конфиденциальность персональных данных</h3>
|
||||
<p>Оператор и иные лица, получившие доступ к персональным данным, обязаны не раскрывать третьим лицам и не распространять персональные данные без согласия субъекта персональных данных, если иное не предусмотрено федеральным законом.</p>
|
||||
<h3>12. Заключительные положения</h3>
|
||||
<p>12.1. Пользователь может получить любые разъяснения по интересующим вопросам, касающимся обработки его персональных данных, обратившись к Оператору с помощью электронной почты <?= SITE_MAIL ?>.</p>
|
||||
<p>12.2. В данном документе будут отражены любые изменения политики обработки персональных данных Оператором. Политика действует бессрочно до замены ее новой версией.</p>
|
||||
<p>12.3. Актуальная версия Политики в свободном доступе расположена в сети Интернет по адресу https://<?= SITE_DOMAIN ?>/politica.</p>
|
||||
</div>
|
||||
|
||||
<div id="advertising" class="policy__section">
|
||||
<h2>Политика рекламной рассылки</h2>
|
||||
<p>1. Политика рассылки уведомлений и информации рекламного характера (далее – Политика информационной рассылки) принимается <?= SITE_LEGAL_NAME ?>, ОГРН 1252300036240, ИНН/КПП 2311381465/231101001, место нахождения <?= YANDEX_MAP_ADDRESS ?>, в дальнейшем именуемым «Администрация Сайта», для информирования любого лица, использующего сайт, размещенный в сети интернет по адресу: https://<?= SITE_DOMAIN ?> (далее – Сайт), в дальнейшем именуемого «Пользователь», о реализуемой Администрацией Сайта политики в отношении осуществления ею рассылки различного рода уведомлений и сообщений рекламного характера в отношении Пользователя.</p>
|
||||
<p>2. Администрация Сайта уважает право каждого Пользователя получать только такие сообщения, на получение которых он выразил свое согласие.</p>
|
||||
<p>3. Администрация Сайта осуществляет рассылку сообщений исключительно на добровольной основе, а также прилагает все усилия для того, чтобы взаимодействие между Пользователем и Сайтом было максимально удобным и доверительным.</p>
|
||||
<p>4. Администрация Сайта с большим вниманием относится к проблеме не запрошенных рекламных сообщений, носящих массовый характер (Далее – Спам). Администрацией Сайта приняты следующие меры для борьбы со Спамом: получение от Пользователя предварительного согласия на осуществление рассылки сообщений; включение в текст каждого сообщения достоверных идентификационных сведений об Администрации Сайта; предоставление Пользователю возможности отказаться от рассылки сообщений.</p>
|
||||
<p>5. Настоящая Политика информационной рассылки носит исключительно информационный характер и ни при каких условиях не является публичной офертой.</p>
|
||||
<p>6. Все термины, используемые в настоящей Политике информационной рассылки, толкуются в соответствии с Пользовательским соглашением, размещенным и доступным на Сайте.</p>
|
||||
</div>
|
||||
|
||||
<div id="agreement" class="policy__section">
|
||||
<h2>Соглашение на обработку персональных данных</h2>
|
||||
<p>Настоящим в соответствии с Федеральным законом № 152-ФЗ «О персональных данных» от 27.07.2006 года Вы подтверждаете свое согласие на обработку компанией <?= SITE_LEGAL_NAME ?> персональных данных: сбор, систематизацию, накопление, хранение, уточнение (обновление, изменение), использование, передачу исключительно в целях продажи программного обеспечения на Ваше имя, как это описано ниже, блокирование, обезличивание, уничтожение.</p>
|
||||
<p><?= SITE_LEGAL_NAME ?> гарантирует конфиденциальность получаемой информации. Обработка персональных данных осуществляется в целях эффективного исполнения заказов, договоров и иных обязательств, принятых компанией <?= SITE_LEGAL_NAME ?> в качестве обязательных к исполнению.</p>
|
||||
<p>В случае необходимости предоставления Ваших персональных данных правообладателю, дистрибьютору или реселлеру программного обеспечения в целях регистрации программного обеспечения на ваше имя, вы даёте согласие на передачу ваших персональных данных.</p>
|
||||
<p>Настоящее согласие распространяется на следующие Ваши персональные данные: фамилия, имя и отчество, адрес электронной почты, почтовый адрес доставки заказов, контактный телефон, платёжные реквизиты.</p>
|
||||
<p>Срок действия согласия является неограниченным. Вы можете в любой момент отозвать настоящее согласие, направив письменное уведомления на адрес: <?= YANDEX_MAP_ADDRESS ?>, с пометкой «Отзыв согласия на обработку персональных данных».</p>
|
||||
<p>Обращаем ваше внимание, что отзыв согласия на обработку персональных данных влечёт за собой удаление Вашей учётной записи, при наличии таковой, с Интернет-сайта (www.<?= SITE_DOMAIN ?>), а также уничтожение записей, содержащих ваши персональные данные, в системах обработки персональных данных компании <?= SITE_LEGAL_NAME ?>.</p>
|
||||
<p>Гарантирую, что представленная мной информация является полной, точной и достоверной, а также что при представлении информации не нарушаются действующее законодательство Российской Федерации, законные права и интересы третьих лиц. Вся представленная информация заполнена мною в отношении себя лично.</p>
|
||||
<p>Настоящее согласие действует в течение всего периода хранения персональных данных, если иное не предусмотрено законодательством Российской Федерации.</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<?php require __DIR__ . '/inc/footer.php'; ?>
|
||||
@@ -0,0 +1,5 @@
|
||||
DATABASE_URL=postgresql+asyncpg://aegisone:aegisone_pass@localhost:5432/aegisone
|
||||
SECRET_KEY=change-me-to-random-string
|
||||
SESSION_TTL=3600
|
||||
APP_ENV=development
|
||||
LOG_LEVEL=debug
|
||||
@@ -0,0 +1,19 @@
|
||||
FROM python:3.12-slim
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
gcc \
|
||||
libpq-dev \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
COPY requirements.txt .
|
||||
RUN pip install --no-cache-dir -r requirements.txt
|
||||
|
||||
COPY . .
|
||||
|
||||
RUN mkdir -p /app/docs /app/permissions /app/uploads
|
||||
|
||||
EXPOSE 8000
|
||||
|
||||
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000", "--workers", "4"]
|
||||
@@ -0,0 +1,92 @@
|
||||
import time
|
||||
import secrets
|
||||
from datetime import datetime
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy import select, func
|
||||
from passlib.context import CryptContext
|
||||
from app.models.models import User, LoginAttempt, AuditLog
|
||||
|
||||
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
|
||||
|
||||
BRUTE_FORCE_WINDOW = 180
|
||||
BRUTE_FORCE_MAX_ATTEMPTS = 3
|
||||
|
||||
|
||||
def hash_password(password: str) -> str:
|
||||
return pwd_context.hash(password)
|
||||
|
||||
|
||||
def verify_password(password: str, hashed: str) -> bool:
|
||||
return pwd_context.verify(password, hashed)
|
||||
|
||||
|
||||
def generate_csrf_token() -> str:
|
||||
return secrets.token_hex(32)
|
||||
|
||||
|
||||
async def brute_force_check(db: AsyncSession, login: str, ip_address: str) -> bool:
|
||||
cutoff = datetime.utcnow().timestamp() - BRUTE_FORCE_WINDOW
|
||||
result = await db.execute(
|
||||
select(func.count(LoginAttempt.id))
|
||||
.where(
|
||||
(LoginAttempt.login == login) | (LoginAttempt.ip_address == ip_address),
|
||||
LoginAttempt.attempt_time > datetime.fromtimestamp(cutoff),
|
||||
)
|
||||
)
|
||||
count = result.scalar() or 0
|
||||
return count >= BRUTE_FORCE_MAX_ATTEMPTS
|
||||
|
||||
|
||||
async def record_attempt(db: AsyncSession, login: str, ip_address: str):
|
||||
attempt = LoginAttempt(login=login, ip_address=ip_address)
|
||||
db.add(attempt)
|
||||
await db.flush()
|
||||
|
||||
|
||||
async def clear_attempts(db: AsyncSession, login: str, ip_address: str):
|
||||
from sqlalchemy import delete
|
||||
await db.execute(
|
||||
delete(LoginAttempt).where(
|
||||
(LoginAttempt.login == login) | (LoginAttempt.ip_address == ip_address)
|
||||
)
|
||||
)
|
||||
await db.flush()
|
||||
|
||||
|
||||
async def authenticate(db: AsyncSession, login: str, password: str, ip_address: str) -> dict:
|
||||
if await brute_force_check(db, login, ip_address):
|
||||
return {"success": False, "error": "Превышен лимит попыток. Подождите 3 минуты."}
|
||||
|
||||
result = await db.execute(
|
||||
select(User).where(User.login == login).limit(1)
|
||||
)
|
||||
user = result.scalar_one_or_none()
|
||||
|
||||
if not user or not verify_password(password, user.password_hash):
|
||||
await record_attempt(db, login, ip_address)
|
||||
return {"success": False, "error": "Неверный логин или пароль."}
|
||||
|
||||
if not user.is_active:
|
||||
return {"success": False, "error": "Учётная запись заблокирована."}
|
||||
|
||||
await clear_attempts(db, login, ip_address)
|
||||
await audit_log(db, user.id, "login", "Вход в систему", ip_address)
|
||||
|
||||
return {
|
||||
"success": True,
|
||||
"user": {
|
||||
"id": user.id,
|
||||
"login": user.login,
|
||||
"role": user.role,
|
||||
"full_name": user.full_name,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
async def audit_log(db: AsyncSession, user_id: int | None, action: str, details: str, ip_address: str):
|
||||
try:
|
||||
log = AuditLog(user_id=user_id, action=action, details=details, ip_address=ip_address)
|
||||
db.add(log)
|
||||
await db.flush()
|
||||
except Exception:
|
||||
pass
|
||||
@@ -0,0 +1,499 @@
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy import select
|
||||
from app.models.models import FormulaCoefficient
|
||||
from functools import lru_cache
|
||||
import math
|
||||
|
||||
_coeff_cache: dict[str, float] = {}
|
||||
|
||||
|
||||
async def get_coefficient(db: AsyncSession, key: str, default: float = 0.0) -> float:
|
||||
global _coeff_cache
|
||||
if not _coeff_cache:
|
||||
result = await db.execute(
|
||||
select(FormulaCoefficient.key, FormulaCoefficient.value)
|
||||
.where(FormulaCoefficient.is_active == True)
|
||||
)
|
||||
_coeff_cache = {row.key: float(row.value) for row in result.all()}
|
||||
return _coeff_cache.get(key, default)
|
||||
|
||||
|
||||
async def reload_coefficients(db: AsyncSession):
|
||||
global _coeff_cache
|
||||
_coeff_cache = {}
|
||||
await get_coefficient(db, "dummy")
|
||||
|
||||
|
||||
def fmt_money(amount: float) -> str:
|
||||
return f"{amount:,.0f}".replace(",", " ") + " ₽"
|
||||
|
||||
|
||||
def fmt_percent(value: float) -> str:
|
||||
return f"{value:.1f}%"
|
||||
|
||||
|
||||
def fmt_hours(hours: float) -> str:
|
||||
return f"{hours:.1f} ч"
|
||||
|
||||
|
||||
def badge_class(status: str, badge_type: str = "default") -> str:
|
||||
mapping = {
|
||||
"P1": "badge-critical", "P2": "badge-high", "P3": "badge-medium", "P4": "badge-low",
|
||||
"open": "badge-open", "in_progress": "badge-progress", "completed": "badge-done", "cancelled": "badge-cancelled",
|
||||
"active": "badge-active", "inactive": "badge-inactive", "draft": "badge-draft", "final": "badge-done",
|
||||
"Risk": "badge-risk", "Crisis": "badge-crisis", "Stable": "badge-stable", "Growth": "badge-growth",
|
||||
}
|
||||
return mapping.get(status, "badge-default")
|
||||
|
||||
|
||||
async def calc_risk_score(db: AsyncSession, no_archive: bool, no_power_backup: bool, no_regulations: bool, system_failures: bool, no_documentation: bool) -> float:
|
||||
return (
|
||||
(await get_coefficient(db, "risk_score.no_archive", 25) if no_archive else 0)
|
||||
+ (await get_coefficient(db, "risk_score.no_power_backup", 20) if no_power_backup else 0)
|
||||
+ (await get_coefficient(db, "risk_score.no_regulations", 15) if no_regulations else 0)
|
||||
+ (await get_coefficient(db, "risk_score.system_failures", 20) if system_failures else 0)
|
||||
+ (await get_coefficient(db, "risk_score.no_documentation", 10) if no_documentation else 0)
|
||||
)
|
||||
|
||||
|
||||
async def risk_label(db: AsyncSession, score: float) -> str:
|
||||
if score <= await get_coefficient(db, "risk_score.bound_low", 20):
|
||||
return "Низкий"
|
||||
if score <= await get_coefficient(db, "risk_score.bound_medium", 50):
|
||||
return "Средний"
|
||||
if score <= await get_coefficient(db, "risk_score.bound_high", 75):
|
||||
return "Высокий"
|
||||
return "Критический"
|
||||
|
||||
|
||||
async def risk_multiplier(db: AsyncSession, score: float) -> float:
|
||||
if score <= await get_coefficient(db, "risk_score.bound_low", 20):
|
||||
return await get_coefficient(db, "risk_multiplier.low", 1.0)
|
||||
if score <= await get_coefficient(db, "risk_score.bound_medium", 50):
|
||||
return await get_coefficient(db, "risk_multiplier.medium", 1.3)
|
||||
if score <= await get_coefficient(db, "risk_score.bound_high", 75):
|
||||
return await get_coefficient(db, "risk_multiplier.high", 1.6)
|
||||
return await get_coefficient(db, "risk_multiplier.critical", 2.0)
|
||||
|
||||
|
||||
async def calc_complexity(db: AsyncSession, cameras: int, access_points: int, fire_type: str, has_it: bool) -> float:
|
||||
if cameras <= 20:
|
||||
video = await get_coefficient(db, "complexity.video_0_20", 10)
|
||||
elif cameras <= 100:
|
||||
video = await get_coefficient(db, "complexity.video_20_100", 20)
|
||||
else:
|
||||
video = await get_coefficient(db, "complexity.video_100plus", 35)
|
||||
|
||||
if access_points <= 5:
|
||||
access = await get_coefficient(db, "complexity.access_0_5", 10)
|
||||
elif access_points <= 20:
|
||||
access = await get_coefficient(db, "complexity.access_5_20", 20)
|
||||
else:
|
||||
access = await get_coefficient(db, "complexity.access_20plus", 30)
|
||||
|
||||
if fire_type == "simple":
|
||||
fire = await get_coefficient(db, "complexity.fire_simple", 15)
|
||||
elif fire_type == "medium":
|
||||
fire = await get_coefficient(db, "complexity.fire_medium", 25)
|
||||
elif fire_type == "complex":
|
||||
fire = await get_coefficient(db, "complexity.fire_complex", 40)
|
||||
else:
|
||||
fire = 0
|
||||
|
||||
it = await get_coefficient(db, "complexity.it", 10) if has_it else 0
|
||||
return video + access + fire + it
|
||||
|
||||
|
||||
def complexity_label(score: float) -> str:
|
||||
if score <= 30:
|
||||
return "Простой"
|
||||
if score <= 70:
|
||||
return "Средний"
|
||||
if score <= 120:
|
||||
return "Сложный"
|
||||
return "Enterprise"
|
||||
|
||||
|
||||
async def calc_infrastructure_load(db: AsyncSession, server_state: str, network_state: str, power_state: str) -> float:
|
||||
if server_state == "none":
|
||||
server = await get_coefficient(db, "infra.server_none", 15)
|
||||
elif server_state == "weak":
|
||||
server = await get_coefficient(db, "infra.server_weak", 10)
|
||||
else:
|
||||
server = 0
|
||||
|
||||
if network_state == "unstable":
|
||||
network = await get_coefficient(db, "infra.network_unstable", 20)
|
||||
elif network_state == "partial":
|
||||
network = await get_coefficient(db, "infra.network_partial", 10)
|
||||
else:
|
||||
network = 0
|
||||
|
||||
if power_state == "none":
|
||||
power = await get_coefficient(db, "infra.power_none", 20)
|
||||
elif power_state == "weak":
|
||||
power = await get_coefficient(db, "infra.power_weak", 10)
|
||||
else:
|
||||
power = 0
|
||||
|
||||
return server + network + power
|
||||
|
||||
|
||||
async def calc_service_history(db: AsyncSession, service_state: str) -> float:
|
||||
mapping = {
|
||||
"none": "history.none",
|
||||
"irregular": "history.irregular",
|
||||
"formal": "history.formal",
|
||||
"sla": "history.sla",
|
||||
}
|
||||
key = mapping.get(service_state, "history.none")
|
||||
return await get_coefficient(db, key, 30)
|
||||
|
||||
|
||||
async def calc_object_index(db: AsyncSession, risk: float, complexity: float, infra: float, history: float) -> float:
|
||||
return round(
|
||||
risk * await get_coefficient(db, "object_index.risk_weight", 0.4)
|
||||
+ complexity * await get_coefficient(db, "object_index.complexity_weight", 0.3)
|
||||
+ infra * await get_coefficient(db, "object_index.infra_weight", 0.2)
|
||||
+ history * await get_coefficient(db, "object_index.history_weight", 0.1),
|
||||
2,
|
||||
)
|
||||
|
||||
|
||||
def object_class(index: float) -> str:
|
||||
if index <= 30:
|
||||
return "A"
|
||||
if index <= 60:
|
||||
return "B"
|
||||
if index <= 90:
|
||||
return "C"
|
||||
return "D"
|
||||
|
||||
|
||||
def object_class_label(index: float) -> str:
|
||||
cls = object_class(index)
|
||||
labels = {
|
||||
"A": "Лёгкий SLA",
|
||||
"B": "Стандарт SLA",
|
||||
"C": "Сложный SLA",
|
||||
"D": "Enterprise / Высокий риск",
|
||||
}
|
||||
return labels.get(cls, "")
|
||||
|
||||
|
||||
def calc_sla_price(base_cost: float, object_index: float, region_factor: float, risk_mult: float) -> float:
|
||||
return round(base_cost * object_index * region_factor * risk_mult, 2)
|
||||
|
||||
|
||||
async def calc_engineer_score(db: AsyncSession, sla_compliance: float, response_time_score: float, resolution_time_score: float, diagnosis_accuracy: float, reopen_rate_score: float, risk_coverage_score: float) -> float:
|
||||
return round(
|
||||
(await get_coefficient(db, "engineer.score.sla_weight", 0.25) * sla_compliance)
|
||||
+ (await get_coefficient(db, "engineer.score.response_weight", 0.20) * response_time_score)
|
||||
+ (await get_coefficient(db, "engineer.score.resolution_weight", 0.20) * resolution_time_score)
|
||||
+ (await get_coefficient(db, "engineer.score.diagnosis_weight", 0.15) * diagnosis_accuracy)
|
||||
+ (await get_coefficient(db, "engineer.score.reopen_weight", 0.10) * reopen_rate_score)
|
||||
+ (await get_coefficient(db, "engineer.score.risk_coverage_weight", 0.10) * risk_coverage_score),
|
||||
2,
|
||||
)
|
||||
|
||||
|
||||
async def engineer_grade(db: AsyncSession, score: float) -> str:
|
||||
if score >= await get_coefficient(db, "engineer.grade.senior", 90):
|
||||
return "Senior"
|
||||
if score >= await get_coefficient(db, "engineer.grade.strong", 80):
|
||||
return "Strong"
|
||||
if score >= await get_coefficient(db, "engineer.grade.middle", 70):
|
||||
return "Middle"
|
||||
return "Junior"
|
||||
|
||||
|
||||
async def calc_engineer_control_score(db: AsyncSession, sla_control: float, task_dist: float, incident_red: float, team_perf: float, response_coord: float) -> float:
|
||||
return round(
|
||||
(await get_coefficient(db, "ecs.sla_weight", 0.30) * sla_control)
|
||||
+ (await get_coefficient(db, "ecs.task_dist_weight", 0.25) * task_dist)
|
||||
+ (await get_coefficient(db, "ecs.incident_red_weight", 0.20) * incident_red)
|
||||
+ (await get_coefficient(db, "ecs.team_perf_weight", 0.15) * team_perf)
|
||||
+ (await get_coefficient(db, "ecs.response_coord_weight", 0.10) * response_coord),
|
||||
2,
|
||||
)
|
||||
|
||||
|
||||
async def calc_shs(db: AsyncSession, sla_stability: float, revenue_stability: float, retention: float, engineer_performance: float, incident_stability: float, sales_flow: float, operational_efficiency: float) -> float:
|
||||
return round(
|
||||
(await get_coefficient(db, "shs.sla_stability_weight", 0.22) * sla_stability)
|
||||
+ (await get_coefficient(db, "shs.revenue_stability_weight", 0.18) * revenue_stability)
|
||||
+ (await get_coefficient(db, "shs.retention_weight", 0.18) * retention)
|
||||
+ (await get_coefficient(db, "shs.engineer_perf_weight", 0.15) * engineer_performance)
|
||||
+ (await get_coefficient(db, "shs.incident_stability_weight", 0.12) * incident_stability)
|
||||
+ (await get_coefficient(db, "shs.sales_flow_weight", 0.10) * sales_flow)
|
||||
+ (await get_coefficient(db, "shs.operational_eff_weight", 0.05) * operational_efficiency),
|
||||
2,
|
||||
)
|
||||
|
||||
|
||||
async def calc_ceo_shs(db: AsyncSession, mrr_growth: float, sla_compliance: float, retention: float, productivity: float, conversion: float, incident_stability: float) -> float:
|
||||
return round(
|
||||
(await get_coefficient(db, "ceo_shs.mrr_weight", 0.25) * mrr_growth)
|
||||
+ (await get_coefficient(db, "ceo_shs.sla_weight", 0.20) * sla_compliance)
|
||||
+ (await get_coefficient(db, "ceo_shs.retention_weight", 0.20) * retention)
|
||||
+ (await get_coefficient(db, "ceo_shs.productivity_weight", 0.15) * productivity)
|
||||
+ (await get_coefficient(db, "ceo_shs.conversion_weight", 0.10) * conversion)
|
||||
+ (await get_coefficient(db, "ceo_shs.incident_weight", 0.10) * incident_stability),
|
||||
2,
|
||||
)
|
||||
|
||||
|
||||
async def shs_status(db: AsyncSession, score: float) -> str:
|
||||
if score >= await get_coefficient(db, "shs.zone_growth", 85):
|
||||
return "Growth"
|
||||
if score >= await get_coefficient(db, "shs.zone_stable", 70):
|
||||
return "Stable"
|
||||
if score >= await get_coefficient(db, "shs.zone_risk", 50):
|
||||
return "Risk"
|
||||
return "Crisis"
|
||||
|
||||
|
||||
async def shs_zone(db: AsyncSession, score: float) -> dict:
|
||||
if score >= await get_coefficient(db, "shs.zone_growth", 85):
|
||||
return {"zone": "green", "label": "Growth", "action": ""}
|
||||
if score >= await get_coefficient(db, "shs.zone_stable", 70):
|
||||
return {"zone": "yellow", "label": "Stable", "action": "Мониторинг"}
|
||||
if score >= await get_coefficient(db, "shs.zone_risk", 50):
|
||||
return {"zone": "yellow", "label": "Risk", "action": "Снизить продажи, запустить аудит цикла, пересмотреть назначения"}
|
||||
return {"zone": "red", "label": "Crisis", "action": "Немедленный аудит, приостановка новых продаж, пересмотр команды"}
|
||||
|
||||
|
||||
async def shs_delta(db: AsyncSession, current_score: float, previous_score: float | None) -> dict | None:
|
||||
if previous_score is None:
|
||||
return None
|
||||
delta = current_score - previous_score
|
||||
threshold_warn = await get_coefficient(db, "shs.delta_warning", 5)
|
||||
threshold_crit = await get_coefficient(db, "shs.delta_critical", 10)
|
||||
if delta <= -threshold_crit:
|
||||
return {"delta": round(delta, 1), "level": "critical", "message": f"SHS упал более чем на {threshold_crit} пунктов — кризис"}
|
||||
if delta <= -threshold_warn:
|
||||
return {"delta": round(delta, 1), "level": "warning", "message": f"SHS упал более чем на {threshold_warn} пунктов — требуется внимание"}
|
||||
return {"delta": round(delta, 1), "level": "ok", "message": ""}
|
||||
|
||||
|
||||
async def calc_sla_stability_index(db: AsyncSession, sla_compliance: float, breach_severity_weighted: float) -> float:
|
||||
ssi = sla_compliance * (1 - breach_severity_weighted)
|
||||
return round(max(0, min(100, ssi)), 2)
|
||||
|
||||
|
||||
async def calc_breach_severity(db: AsyncSession, breaches_p1: int, breaches_p2: int, breaches_p3: int) -> float:
|
||||
total = breaches_p1 + breaches_p2 + breaches_p3
|
||||
if total == 0:
|
||||
return 0
|
||||
weighted = (
|
||||
breaches_p1 * await get_coefficient(db, "ssi.breach_severity_p1", 1.0)
|
||||
+ breaches_p2 * await get_coefficient(db, "ssi.breach_severity_p2", 0.5)
|
||||
+ breaches_p3 * await get_coefficient(db, "ssi.breach_severity_p3", 0.2)
|
||||
)
|
||||
return min(1, weighted / total)
|
||||
|
||||
|
||||
def calc_revenue_stability_index(mrr_history: list[float]) -> float:
|
||||
count = len(mrr_history)
|
||||
if count < 2:
|
||||
return 100
|
||||
mean = sum(mrr_history) / count
|
||||
if mean <= 0:
|
||||
return 100
|
||||
variance = sum((mrr - mean) ** 2 for mrr in mrr_history) / count
|
||||
std_dev = math.sqrt(variance)
|
||||
cv = std_dev / mean
|
||||
return round(max(0, min(100, 100 * (1 - cv))), 2)
|
||||
|
||||
|
||||
def calc_sales_flow_index(audits: int, sla_contracts: int, lead_quality: float = 1.0) -> float:
|
||||
if audits <= 0:
|
||||
return 0
|
||||
conversion = sla_contracts / audits
|
||||
return round(min(100, conversion * 100 * lead_quality), 2)
|
||||
|
||||
|
||||
def calc_operational_efficiency_index(revenue: float, engineer_hours: float, cost_per_hour: float) -> float:
|
||||
total = engineer_hours * cost_per_hour
|
||||
if total <= 0:
|
||||
return 100
|
||||
return round(min(100, (revenue / total) * 100), 2)
|
||||
|
||||
|
||||
async def calc_incident_stability_index(db: AsyncSession, incidents_p1: int, incidents_p2: int, incidents_p3: int, object_count: int) -> float:
|
||||
if object_count <= 0:
|
||||
return 100
|
||||
weighted = (
|
||||
incidents_p1 * await get_coefficient(db, "isi.severity_p1", 1.0)
|
||||
+ incidents_p2 * await get_coefficient(db, "isi.severity_p2", 0.5)
|
||||
+ incidents_p3 * await get_coefficient(db, "isi.severity_p3", 0.2)
|
||||
)
|
||||
rate = weighted / object_count
|
||||
return round(max(0, min(100, 100 - (rate * 20))), 2)
|
||||
|
||||
|
||||
async def check_automation_rules(db: AsyncSession, shs: float | None, sla_compliance: float | None, retention: float | None) -> list[dict]:
|
||||
alerts = []
|
||||
if shs is not None and shs < await get_coefficient(db, "rules.shs_threshold", 70):
|
||||
alerts.append({
|
||||
"rule": "SHS",
|
||||
"severity": "critical",
|
||||
"message": f"SHS ниже {await get_coefficient(db, 'rules.shs_threshold', 70)} — снизить продажи, запустить аудит, пересмотреть назначения инженеров.",
|
||||
})
|
||||
if sla_compliance is not None and sla_compliance < await get_coefficient(db, "rules.sla_threshold", 90):
|
||||
alerts.append({
|
||||
"rule": "SLA",
|
||||
"severity": "warning",
|
||||
"message": f"SLA Compliance ниже {await get_coefficient(db, 'rules.sla_threshold', 90)}% — заморозить неприоритетные проекты, увеличить частоту проверок.",
|
||||
})
|
||||
if retention is not None and retention < await get_coefficient(db, "rules.retention_threshold", 90):
|
||||
alerts.append({
|
||||
"rule": "Retention",
|
||||
"severity": "critical",
|
||||
"message": f"Удержание клиентов ниже {await get_coefficient(db, 'rules.retention_threshold', 90)}% — обязательный аудит клиентов, пересмотр назначений инженеров.",
|
||||
})
|
||||
return alerts
|
||||
|
||||
|
||||
def calc_sla_compliance(closed_in_sla: int, total: int) -> float:
|
||||
if total <= 0:
|
||||
return 100
|
||||
return round((closed_in_sla / total) * 100, 2)
|
||||
|
||||
|
||||
def calc_reopen_rate(reopened: int, total: int) -> float:
|
||||
if total <= 0:
|
||||
return 0
|
||||
return round((reopened / total) * 100, 2)
|
||||
|
||||
|
||||
def calc_diagnosis_accuracy(confirmed: int, found: int) -> float:
|
||||
if found <= 0:
|
||||
return 100
|
||||
return round((confirmed / found) * 100, 2)
|
||||
|
||||
|
||||
def calc_response_time_score(actual_hours: float, sla_hours: float) -> float:
|
||||
if sla_hours <= 0:
|
||||
return 100
|
||||
ratio = actual_hours / sla_hours
|
||||
if ratio <= 1.0:
|
||||
return 100
|
||||
if ratio <= 1.2:
|
||||
return 80
|
||||
return max(0, 100 - (ratio - 1.2) * 50)
|
||||
|
||||
|
||||
def calc_resolution_time_score(actual_hours: float, norm_hours: float) -> float:
|
||||
if norm_hours <= 0:
|
||||
return 100
|
||||
ratio = actual_hours / norm_hours
|
||||
if ratio <= 1.0:
|
||||
return 100
|
||||
if ratio <= 1.5:
|
||||
return 70
|
||||
return max(0, 100 - (ratio - 1.5) * 40)
|
||||
|
||||
|
||||
def calc_risk_coverage(checked_zones: int, total_zones: int = 5) -> float:
|
||||
if total_zones <= 0:
|
||||
return 0
|
||||
return round((checked_zones / total_zones) * 100, 2)
|
||||
|
||||
|
||||
def calc_documentation_quality(full_reports: int, total_visits: int) -> float:
|
||||
if total_visits <= 0:
|
||||
return 100
|
||||
return round((full_reports / total_visits) * 100, 2)
|
||||
|
||||
|
||||
def calc_tlb(tasks_per_engineer: list[float]) -> float:
|
||||
count = len(tasks_per_engineer)
|
||||
if count < 2:
|
||||
return 0
|
||||
mean = sum(tasks_per_engineer) / count
|
||||
variance = sum((t - mean) ** 2 for t in tasks_per_engineer) / count
|
||||
return round(math.sqrt(variance), 2)
|
||||
|
||||
|
||||
def calc_mrr(total_sla_annual: float) -> float:
|
||||
return round(total_sla_annual / 12, 2)
|
||||
|
||||
|
||||
def calc_rpe(sla_revenue: float, engineer_count: int) -> float:
|
||||
if engineer_count <= 0:
|
||||
return 0
|
||||
return round(sla_revenue / engineer_count, 2)
|
||||
|
||||
|
||||
def calc_cpo(total_cost: float, object_count: int) -> float:
|
||||
if object_count <= 0:
|
||||
return 0
|
||||
return round(total_cost / object_count, 2)
|
||||
|
||||
|
||||
def calc_arpc(total_revenue: float, client_count: int) -> float:
|
||||
if client_count <= 0:
|
||||
return 0
|
||||
return round(total_revenue / client_count, 2)
|
||||
|
||||
|
||||
def calc_utilization(working_hours: int, available_hours: int) -> float:
|
||||
if available_hours <= 0:
|
||||
return 0
|
||||
return round((working_hours / available_hours) * 100, 2)
|
||||
|
||||
|
||||
def calc_autonomy(independent: int, total: int) -> float:
|
||||
if total <= 0:
|
||||
return 100
|
||||
return round((independent / total) * 100, 2)
|
||||
|
||||
|
||||
def calc_escalation_rate(escalated: int, total: int) -> float:
|
||||
if total <= 0:
|
||||
return 0
|
||||
return round((escalated / total) * 100, 2)
|
||||
|
||||
|
||||
def calc_uptime(uptime_hours: float, total_hours: float) -> float:
|
||||
if total_hours <= 0:
|
||||
return 100
|
||||
return round((uptime_hours / total_hours) * 100, 2)
|
||||
|
||||
|
||||
def calc_retention(active_clients: int, total_clients: int) -> float:
|
||||
if total_clients <= 0:
|
||||
return 100
|
||||
return round((active_clients / total_clients) * 100, 2)
|
||||
|
||||
|
||||
async def calc_retention_key_client(db: AsyncSession, base_retention: float, lost_key_clients: int) -> float:
|
||||
penalty = lost_key_clients * await get_coefficient(db, "retention.key_client_penalty", 0.1)
|
||||
return round(max(0, base_retention - penalty * 100), 2)
|
||||
|
||||
|
||||
def calc_csat(positive: int, total: int) -> float:
|
||||
if total <= 0:
|
||||
return 100
|
||||
return round((positive / total) * 100, 2)
|
||||
|
||||
|
||||
def calc_incident_rate(incidents: int, object_count: int) -> float:
|
||||
if object_count <= 0:
|
||||
return 0
|
||||
return round(incidents / object_count, 2)
|
||||
|
||||
|
||||
def calc_incident_reduction(previous: int, current: int) -> float:
|
||||
if previous <= 0:
|
||||
return 0
|
||||
return round(((previous - current) / previous) * 100, 2)
|
||||
|
||||
|
||||
async def calc_bonus_percent(db: AsyncSession, engineer_score: float) -> float:
|
||||
if engineer_score >= await get_coefficient(db, "bonus.score_90plus", 90):
|
||||
return await get_coefficient(db, "bonus.premium_90plus", 20)
|
||||
if engineer_score >= await get_coefficient(db, "bonus.score_80_89", 80):
|
||||
return await get_coefficient(db, "bonus.premium_80_89", 10)
|
||||
return await get_coefficient(db, "bonus.premium_below_80", 0)
|
||||
@@ -0,0 +1,24 @@
|
||||
import os
|
||||
from pathlib import Path
|
||||
from pydantic_settings import BaseSettings
|
||||
from functools import lru_cache
|
||||
|
||||
|
||||
class Settings(BaseSettings):
|
||||
DATABASE_URL: str = "postgresql+asyncpg://aegisone:aegisone_pass@localhost:5432/aegisone"
|
||||
SECRET_KEY: str = "change-me-to-random-string"
|
||||
SESSION_TTL: int = 3600
|
||||
APP_ENV: str = "development"
|
||||
LOG_LEVEL: str = "debug"
|
||||
DOCS_DIR: str = str(Path(__file__).parent.parent.parent / "docs")
|
||||
PERMISSIONS_DIR: str = str(Path(__file__).parent.parent.parent / "permissions")
|
||||
UPLOADS_DIR: str = str(Path(__file__).parent.parent.parent / "uploads")
|
||||
|
||||
class Config:
|
||||
env_file = ".env"
|
||||
env_file_encoding = "utf-8"
|
||||
|
||||
|
||||
@lru_cache()
|
||||
def get_settings() -> Settings:
|
||||
return Settings()
|
||||
@@ -0,0 +1,24 @@
|
||||
from sqlalchemy.ext.asyncio import create_async_engine, async_sessionmaker, AsyncSession
|
||||
from app.config import get_settings
|
||||
|
||||
settings = get_settings()
|
||||
|
||||
engine = create_async_engine(
|
||||
settings.DATABASE_URL,
|
||||
echo=settings.APP_ENV == "development",
|
||||
pool_pre_ping=True,
|
||||
pool_size=10,
|
||||
max_overflow=20,
|
||||
)
|
||||
|
||||
async_session = async_sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)
|
||||
|
||||
|
||||
async def get_db() -> AsyncSession:
|
||||
async with async_session() as session:
|
||||
try:
|
||||
yield session
|
||||
await session.commit()
|
||||
except Exception:
|
||||
await session.rollback()
|
||||
raise
|
||||
@@ -0,0 +1,187 @@
|
||||
import os
|
||||
from contextlib import asynccontextmanager
|
||||
from fastapi import FastAPI, Request, Depends
|
||||
from fastapi.responses import HTMLResponse, RedirectResponse, JSONResponse
|
||||
from fastapi.staticfiles import StaticFiles
|
||||
from fastapi.templating import Jinja2Templates
|
||||
from starlette.middleware.sessions import SessionMiddleware
|
||||
from starlette.middleware.base import BaseHTTPMiddleware
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from app.config import get_settings
|
||||
from app.database import get_db, async_session
|
||||
from app.auth import audit_log
|
||||
from app.services.docs_permissions import discover_docs
|
||||
|
||||
settings = get_settings()
|
||||
|
||||
|
||||
@asynccontextmanager
|
||||
async def lifespan(app: FastAPI):
|
||||
async with async_session() as db:
|
||||
from app.calculations.engine import reload_coefficients
|
||||
await reload_coefficients(db)
|
||||
discover_docs()
|
||||
yield
|
||||
|
||||
|
||||
app = FastAPI(title="AegisOne Service Portal", lifespan=lifespan)
|
||||
|
||||
app.add_middleware(SessionMiddleware, secret_key=settings.SECRET_KEY, max_age=settings.SESSION_TTL)
|
||||
|
||||
templates = Jinja2Templates(directory="app/templates")
|
||||
templates.env.globals["SITE_NAME"] = "AegisOne Engineering"
|
||||
|
||||
|
||||
class RoleGuardMiddleware(BaseHTTPMiddleware):
|
||||
async def dispatch(self, request: Request, call_next):
|
||||
path = request.url.path
|
||||
if path.startswith("/service/") and not any(
|
||||
path.startswith(p) for p in ["/service/login", "/service/static", "/service/api/"]
|
||||
):
|
||||
user = request.session.get("user")
|
||||
if not user:
|
||||
return RedirectResponse(url="/service/login", status_code=302)
|
||||
response = await call_next(request)
|
||||
return response
|
||||
|
||||
|
||||
app.add_middleware(RoleGuardMiddleware)
|
||||
|
||||
|
||||
def get_current_user(request: Request) -> dict | None:
|
||||
return request.session.get("user")
|
||||
|
||||
|
||||
def require_role(*roles: str):
|
||||
def dependency(request: Request, user: dict = Depends(get_current_user)):
|
||||
if not user:
|
||||
return RedirectResponse(url="/service/login", status_code=302)
|
||||
if roles and user["role"] not in roles:
|
||||
return HTMLResponse(content="Доступ запрещён", status_code=403)
|
||||
return user
|
||||
return dependency
|
||||
|
||||
|
||||
@app.get("/service/login")
|
||||
async def login_page(request: Request, db: AsyncSession = Depends(get_db)):
|
||||
if request.session.get("user"):
|
||||
return RedirectResponse(url="/service/dashboard", status_code=302)
|
||||
return templates.TemplateResponse("login.html", {"request": request, "error": ""})
|
||||
|
||||
|
||||
@app.post("/service/login")
|
||||
async def login_submit(request: Request, db: AsyncSession = Depends(get_db)):
|
||||
form = await request.form()
|
||||
login = form.get("login", "").strip()
|
||||
password = form.get("password", "")
|
||||
if not login or not password:
|
||||
return templates.TemplateResponse("login.html", {"request": request, "error": "Заполните все поля."})
|
||||
|
||||
from app.auth import authenticate
|
||||
ip = request.client.host if request.client else ""
|
||||
result = await authenticate(db, login, password, ip)
|
||||
|
||||
if result["success"]:
|
||||
request.session["user"] = result["user"]
|
||||
request.session["csrf_token"] = __import__("secrets").token_hex(32)
|
||||
redirect = request.query_params.get("redirect", "/service/dashboard")
|
||||
return RedirectResponse(url=redirect, status_code=302)
|
||||
return templates.TemplateResponse("login.html", {"request": request, "error": result["error"]})
|
||||
|
||||
|
||||
@app.get("/service/logout")
|
||||
async def logout(request: Request, db: AsyncSession = Depends(get_db)):
|
||||
user = request.session.get("user")
|
||||
if user:
|
||||
await audit_log(db, user["id"], "logout", "Выход из системы", request.client.host if request.client else "")
|
||||
request.session.clear()
|
||||
return RedirectResponse(url="/service/login", status_code=302)
|
||||
|
||||
|
||||
@app.get("/service/dashboard")
|
||||
async def dashboard(request: Request, db: AsyncSession = Depends(get_db), user: dict = Depends(get_current_user)):
|
||||
from sqlalchemy import select, func
|
||||
from app.models.models import Object, Task, Incident, SLAContract, SHSRecord
|
||||
|
||||
stats = {}
|
||||
result = await db.execute(select(func.count(Object.id)).where(Object.status == "active"))
|
||||
stats["objects"] = result.scalar() or 0
|
||||
|
||||
result = await db.execute(select(func.count(Task.id)).where(Task.status.in_(["open", "in_progress"])))
|
||||
stats["tasks"] = result.scalar() or 0
|
||||
|
||||
result = await db.execute(select(func.count(Incident.id)).where(Incident.status.in_(["open", "in_progress"])))
|
||||
stats["incidents"] = result.scalar() or 0
|
||||
|
||||
result = await db.execute(select(func.count(SLAContract.id)).where(SLAContract.status == "active"))
|
||||
stats["sla_count"] = result.scalar() or 0
|
||||
|
||||
result = await db.execute(select(SHSRecord.shs_score, SHSRecord.shs_status).order_by(SHSRecord.id.desc()).limit(1))
|
||||
shs_row = result.first()
|
||||
stats["shs"] = {"shs_score": shs_row[0], "shs_status": shs_row[1]} if shs_row else None
|
||||
|
||||
if user["role"] in ("engineer", "technician"):
|
||||
result = await db.execute(
|
||||
select(func.count(Task.id)).where(
|
||||
Task.assigned_to == user["id"],
|
||||
Task.status.in_(["open", "in_progress"]),
|
||||
)
|
||||
)
|
||||
stats["my_tasks"] = result.scalar() or 0
|
||||
|
||||
result = await db.execute(
|
||||
select(func.count(Task.id), func.sum(Task.sla_compliant.cast(int)))
|
||||
.where(Task.closed_at.isnot(None))
|
||||
)
|
||||
row = result.first()
|
||||
total = row[0] or 0
|
||||
compliant = row[1] or 0
|
||||
stats["sla_compliance"] = round((compliant / total) * 100, 1) if total > 0 else 0
|
||||
|
||||
shs_alert = None
|
||||
if stats["shs"] and stats["shs"]["shs_score"] < 70:
|
||||
shs_alert = f"SHS ниже 70 ({stats['shs']['shs_score']}) — {stats['shs']['shs_status']}"
|
||||
|
||||
now = __import__("datetime").datetime.now().strftime("%d.%m.%Y %H:%M")
|
||||
return templates.TemplateResponse("dashboard.html", {
|
||||
"request": request, "stats": stats, "shs_alert": shs_alert, "now": now, "user": user,
|
||||
})
|
||||
|
||||
|
||||
@app.get("/service/api/shs")
|
||||
async def api_shs(db: AsyncSession = Depends(get_db)):
|
||||
from sqlalchemy import select
|
||||
from app.models.models import SHSRecord
|
||||
result = await db.execute(select(SHSRecord).order_by(SHSRecord.id.desc()).limit(1))
|
||||
record = result.scalar_one_or_none()
|
||||
if not record:
|
||||
return JSONResponse({"error": "No data"})
|
||||
return JSONResponse({
|
||||
"shs_score": float(record.shs_score),
|
||||
"shs_status": record.shs_status,
|
||||
"period_start": record.period_start.isoformat(),
|
||||
"period_end": record.period_end.isoformat(),
|
||||
})
|
||||
|
||||
|
||||
@app.get("/service/api/tasks")
|
||||
async def api_tasks(db: AsyncSession = Depends(get_db), user: dict = Depends(get_current_user)):
|
||||
from sqlalchemy import select
|
||||
from app.models.models import Task
|
||||
query = select(Task).where(Task.status.in_(["open", "in_progress"]))
|
||||
if user["role"] == "technician":
|
||||
query = query.where(Task.assigned_to == user["id"])
|
||||
result = await db.execute(query.order_by(Task.created_at.desc()))
|
||||
tasks = result.scalars().all()
|
||||
return JSONResponse([
|
||||
{
|
||||
"id": t.id, "title": t.title, "priority": t.priority,
|
||||
"status": t.status, "object_id": t.object_id,
|
||||
}
|
||||
for t in tasks
|
||||
])
|
||||
|
||||
|
||||
@app.get("/health")
|
||||
async def health():
|
||||
return {"status": "ok"}
|
||||
@@ -0,0 +1,465 @@
|
||||
from datetime import datetime
|
||||
from sqlalchemy import (
|
||||
Column, Integer, String, Boolean, Text, DateTime, Numeric, Date, BigInteger, SmallInteger, JSON, ForeignKey, CheckConstraint
|
||||
)
|
||||
from sqlalchemy.orm import relationship, declarative_base
|
||||
|
||||
Base = declarative_base()
|
||||
|
||||
|
||||
class User(Base):
|
||||
__tablename__ = "users"
|
||||
|
||||
id = Column(Integer, primary_key=True, autoincrement=True)
|
||||
login = Column(String(50), unique=True, nullable=False)
|
||||
password_hash = Column(String(255), nullable=False)
|
||||
role = Column(String(20), nullable=False, default="technician")
|
||||
full_name = Column(String(255), nullable=False)
|
||||
phone = Column(String(50), default="")
|
||||
email = Column(String(255), default="")
|
||||
is_active = Column(Boolean, nullable=False, default=True)
|
||||
created_at = Column(DateTime, nullable=False, server_default="NOW()")
|
||||
updated_at = Column(DateTime, nullable=False, server_default="NOW()", onupdate="NOW()")
|
||||
|
||||
__table_args__ = (
|
||||
CheckConstraint("role IN ('owner','engineer','technician')", name="ck_users_role"),
|
||||
)
|
||||
|
||||
objects_created = relationship("Object", foreign_keys="Object.created_by", back_populates="creator")
|
||||
tasks_created = relationship("Task", foreign_keys="Task.created_by", back_populates="creator")
|
||||
tasks_assigned = relationship("Task", foreign_keys="Task.assigned_to", back_populates="assignee")
|
||||
|
||||
|
||||
class LoginAttempt(Base):
|
||||
__tablename__ = "login_attempts"
|
||||
|
||||
id = Column(Integer, primary_key=True, autoincrement=True)
|
||||
ip_address = Column(String(45), nullable=False)
|
||||
login = Column(String(50), nullable=False, default="")
|
||||
attempt_time = Column(DateTime, nullable=False, server_default="NOW()")
|
||||
|
||||
|
||||
class AuditLog(Base):
|
||||
__tablename__ = "audit_log"
|
||||
|
||||
id = Column(BigInteger, primary_key=True, autoincrement=True)
|
||||
user_id = Column(Integer, ForeignKey("users.id", ondelete="SET NULL"))
|
||||
action = Column(String(255), nullable=False)
|
||||
details = Column(Text)
|
||||
ip_address = Column(String(45), default="")
|
||||
created_at = Column(DateTime, nullable=False, server_default="NOW()")
|
||||
|
||||
|
||||
class Customer(Base):
|
||||
__tablename__ = "customers"
|
||||
|
||||
id = Column(Integer, primary_key=True, autoincrement=True)
|
||||
name = Column(String(255), nullable=False)
|
||||
inn = Column(String(12), default="")
|
||||
kpp = Column(String(9), default="")
|
||||
legal_address = Column(String(500), default="")
|
||||
contact_person = Column(String(255), default="")
|
||||
contact_phone = Column(String(50), default="")
|
||||
contact_email = Column(String(255), default="")
|
||||
status = Column(String(20), nullable=False, default="active")
|
||||
notes = Column(Text)
|
||||
created_by = Column(Integer, ForeignKey("users.id", ondelete="SET NULL"))
|
||||
created_at = Column(DateTime, nullable=False, server_default="NOW()")
|
||||
updated_at = Column(DateTime, nullable=False, server_default="NOW()", onupdate="NOW()")
|
||||
|
||||
__table_args__ = (
|
||||
CheckConstraint("status IN ('active','inactive','prospect')", name="ck_customers_status"),
|
||||
)
|
||||
|
||||
objects = relationship("Object", back_populates="customer")
|
||||
sla_contracts = relationship("SLAContract", back_populates="customer")
|
||||
|
||||
|
||||
class Object(Base):
|
||||
__tablename__ = "objects"
|
||||
|
||||
id = Column(Integer, primary_key=True, autoincrement=True)
|
||||
customer_id = Column(Integer, ForeignKey("customers.id", ondelete="SET NULL"))
|
||||
name = Column(String(255), nullable=False)
|
||||
address = Column(String(500), default="")
|
||||
object_type = Column(String(100), default="")
|
||||
area_sqm = Column(Numeric(10, 2), default=0)
|
||||
employees_count = Column(Integer, default=0)
|
||||
contact_person = Column(String(255), default="")
|
||||
contact_phone = Column(String(50), default="")
|
||||
status = Column(String(20), nullable=False, default="active")
|
||||
notes = Column(Text)
|
||||
risk_score = Column(Numeric(5, 2), default=0)
|
||||
complexity_index = Column(Numeric(5, 2), default=0)
|
||||
infrastructure_load = Column(Numeric(5, 2), default=0)
|
||||
service_history = Column(Numeric(5, 2), default=0)
|
||||
object_index = Column(Numeric(5, 2), default=0)
|
||||
sla_price_monthly = Column(Numeric(12, 2), default=0)
|
||||
region_factor = Column(Numeric(3, 2), default=1.00)
|
||||
created_by = Column(Integer, ForeignKey("users.id", ondelete="SET NULL"))
|
||||
created_at = Column(DateTime, nullable=False, server_default="NOW()")
|
||||
updated_at = Column(DateTime, nullable=False, server_default="NOW()", onupdate="NOW()")
|
||||
|
||||
__table_args__ = (
|
||||
CheckConstraint("status IN ('active','inactive','audit','prospective')", name="ck_objects_status"),
|
||||
)
|
||||
|
||||
customer = relationship("Customer", back_populates="objects")
|
||||
creator = relationship("User", foreign_keys=[created_by], back_populates="objects_created")
|
||||
assignments = relationship("ObjectAssignment", back_populates="object")
|
||||
tasks = relationship("Task", back_populates="object")
|
||||
reports = relationship("Report", back_populates="object")
|
||||
incidents = relationship("Incident", back_populates="object")
|
||||
sla_contracts = relationship("SLAContract", back_populates="object")
|
||||
passports = relationship("ObjectPassport", back_populates="object")
|
||||
|
||||
|
||||
class ObjectAssignment(Base):
|
||||
__tablename__ = "object_assignments"
|
||||
|
||||
id = Column(Integer, primary_key=True, autoincrement=True)
|
||||
object_id = Column(Integer, ForeignKey("objects.id", ondelete="CASCADE"), nullable=False)
|
||||
user_id = Column(Integer, ForeignKey("users.id", ondelete="CASCADE"), nullable=False)
|
||||
role = Column(String(20), nullable=False)
|
||||
assigned_at = Column(DateTime, nullable=False, server_default="NOW()")
|
||||
unassigned_at = Column(DateTime)
|
||||
|
||||
__table_args__ = (
|
||||
CheckConstraint("role IN ('engineer','technician')", name="ck_assignments_role"),
|
||||
)
|
||||
|
||||
object = relationship("Object", back_populates="assignments")
|
||||
user = relationship("User")
|
||||
|
||||
|
||||
class Task(Base):
|
||||
__tablename__ = "tasks"
|
||||
|
||||
id = Column(Integer, primary_key=True, autoincrement=True)
|
||||
object_id = Column(Integer, ForeignKey("objects.id", ondelete="CASCADE"), nullable=False)
|
||||
assigned_to = Column(Integer, ForeignKey("users.id", ondelete="SET NULL"))
|
||||
created_by = Column(Integer, ForeignKey("users.id", ondelete="SET NULL"))
|
||||
title = Column(String(500), nullable=False)
|
||||
description = Column(Text)
|
||||
priority = Column(String(4), nullable=False, default="P3")
|
||||
status = Column(String(20), nullable=False, default="open")
|
||||
deadline = Column(DateTime)
|
||||
sla_remaining_hours = Column(Numeric(6, 1), default=0)
|
||||
response_time_minutes = Column(Integer, default=0)
|
||||
resolution_time_minutes = Column(Integer, default=0)
|
||||
sla_compliant = Column(Boolean)
|
||||
checklist_data = Column(JSON)
|
||||
result_notes = Column(Text)
|
||||
closed_at = Column(DateTime)
|
||||
created_at = Column(DateTime, nullable=False, server_default="NOW()")
|
||||
updated_at = Column(DateTime, nullable=False, server_default="NOW()", onupdate="NOW()")
|
||||
|
||||
__table_args__ = (
|
||||
CheckConstraint("priority IN ('P1','P2','P3','P4')", name="ck_tasks_priority"),
|
||||
CheckConstraint("status IN ('open','in_progress','completed','cancelled')", name="ck_tasks_status"),
|
||||
)
|
||||
|
||||
object = relationship("Object", back_populates="tasks")
|
||||
creator = relationship("User", foreign_keys=[created_by], back_populates="tasks_created")
|
||||
assignee = relationship("User", foreign_keys=[assigned_to], back_populates="tasks_assigned")
|
||||
comments = relationship("TaskComment", back_populates="task")
|
||||
photos = relationship("TaskPhoto", back_populates="task")
|
||||
|
||||
|
||||
class TaskComment(Base):
|
||||
__tablename__ = "task_comments"
|
||||
|
||||
id = Column(Integer, primary_key=True, autoincrement=True)
|
||||
task_id = Column(Integer, ForeignKey("tasks.id", ondelete="CASCADE"), nullable=False)
|
||||
user_id = Column(Integer, ForeignKey("users.id", ondelete="SET NULL"))
|
||||
comment = Column(Text, nullable=False)
|
||||
created_at = Column(DateTime, nullable=False, server_default="NOW()")
|
||||
|
||||
task = relationship("Task", back_populates="comments")
|
||||
user = relationship("User")
|
||||
|
||||
|
||||
class TaskPhoto(Base):
|
||||
__tablename__ = "task_photos"
|
||||
|
||||
id = Column(Integer, primary_key=True, autoincrement=True)
|
||||
task_id = Column(Integer, ForeignKey("tasks.id", ondelete="SET NULL"))
|
||||
report_id = Column(Integer, ForeignKey("reports.id", ondelete="SET NULL"))
|
||||
file_path = Column(String(500), nullable=False)
|
||||
description = Column(String(500), default="")
|
||||
type = Column(String(20), default="other")
|
||||
uploaded_by = Column(Integer, ForeignKey("users.id", ondelete="SET NULL"))
|
||||
created_at = Column(DateTime, nullable=False, server_default="NOW()")
|
||||
|
||||
__table_args__ = (
|
||||
CheckConstraint("type IN ('before','after','evidence','other')", name="ck_photos_type"),
|
||||
)
|
||||
|
||||
task = relationship("Task", back_populates="photos")
|
||||
uploader = relationship("User")
|
||||
|
||||
|
||||
class Report(Base):
|
||||
__tablename__ = "reports"
|
||||
|
||||
id = Column(Integer, primary_key=True, autoincrement=True)
|
||||
object_id = Column(Integer, ForeignKey("objects.id", ondelete="CASCADE"), nullable=False)
|
||||
created_by = Column(Integer, ForeignKey("users.id", ondelete="SET NULL"))
|
||||
report_type = Column(String(20), nullable=False, default="service")
|
||||
title = Column(String(500), default="")
|
||||
description = Column(Text)
|
||||
findings = Column(Text)
|
||||
recommendations = Column(Text)
|
||||
work_done = Column(Text)
|
||||
cause_classification = Column(String(100))
|
||||
result_status = Column(String(20), default="ok")
|
||||
status = Column(String(20), nullable=False, default="draft")
|
||||
client_confirmed = Column(Boolean, default=False)
|
||||
created_at = Column(DateTime, nullable=False, server_default="NOW()")
|
||||
updated_at = Column(DateTime, nullable=False, server_default="NOW()", onupdate="NOW()")
|
||||
|
||||
__table_args__ = (
|
||||
CheckConstraint("report_type IN ('inspection','service','emergency','audit','monthly')", name="ck_reports_type"),
|
||||
CheckConstraint("result_status IN ('fixed','partial','revisit','ok')", name="ck_reports_result"),
|
||||
CheckConstraint("status IN ('draft','final','cancelled')", name="ck_reports_status"),
|
||||
)
|
||||
|
||||
object = relationship("Object", back_populates="reports")
|
||||
creator = relationship("User")
|
||||
|
||||
|
||||
class QuestionnaireSession(Base):
|
||||
__tablename__ = "questionnaire_sessions"
|
||||
|
||||
id = Column(Integer, primary_key=True, autoincrement=True)
|
||||
object_id = Column(Integer, ForeignKey("objects.id", ondelete="SET NULL"))
|
||||
client_name = Column(String(255), default="")
|
||||
created_by = Column(Integer, ForeignKey("users.id", ondelete="SET NULL"))
|
||||
status = Column(String(20), nullable=False, default="draft")
|
||||
current_step = Column(SmallInteger, nullable=False, default=1)
|
||||
risk_score = Column(Numeric(5, 2), default=0)
|
||||
complexity_index = Column(Numeric(5, 2), default=0)
|
||||
infrastructure_load = Column(Numeric(5, 2), default=0)
|
||||
service_history = Column(Numeric(5, 2), default=0)
|
||||
object_index = Column(Numeric(5, 2), default=0)
|
||||
sla_price_monthly = Column(Numeric(12, 2), default=0)
|
||||
created_at = Column(DateTime, nullable=False, server_default="NOW()")
|
||||
updated_at = Column(DateTime, nullable=False, server_default="NOW()", onupdate="NOW()")
|
||||
|
||||
__table_args__ = (
|
||||
CheckConstraint("status IN ('draft','completed','cancelled')", name="ck_qsessions_status"),
|
||||
)
|
||||
|
||||
answers = relationship("QuestionnaireAnswer", back_populates="session")
|
||||
passport = relationship("ObjectPassport", back_populates="session")
|
||||
|
||||
|
||||
class QuestionnaireAnswer(Base):
|
||||
__tablename__ = "questionnaire_answers"
|
||||
|
||||
id = Column(Integer, primary_key=True, autoincrement=True)
|
||||
session_id = Column(Integer, ForeignKey("questionnaire_sessions.id", ondelete="CASCADE"), nullable=False)
|
||||
step = Column(SmallInteger, nullable=False)
|
||||
question_key = Column(String(100), nullable=False)
|
||||
answer_value = Column(Text)
|
||||
created_at = Column(DateTime, nullable=False, server_default="NOW()")
|
||||
|
||||
session = relationship("QuestionnaireSession", back_populates="answers")
|
||||
|
||||
|
||||
class QuestionnaireItem(Base):
|
||||
__tablename__ = "questionnaire_items"
|
||||
|
||||
id = Column(Integer, primary_key=True, autoincrement=True)
|
||||
step = Column(Integer, nullable=False, default=1)
|
||||
section = Column(String(100), nullable=False, default="")
|
||||
question_key = Column(String(100), unique=True, nullable=False)
|
||||
label = Column(String(255), nullable=False)
|
||||
type = Column(String(20), nullable=False, default="text")
|
||||
options = Column(JSON)
|
||||
required = Column(Boolean, nullable=False, default=False)
|
||||
sort_order = Column(Integer, nullable=False, default=0)
|
||||
is_active = Column(Boolean, nullable=False, default=True)
|
||||
help_text = Column(String(500), default="")
|
||||
created_at = Column(DateTime, nullable=False, server_default="NOW()")
|
||||
updated_at = Column(DateTime, nullable=False, server_default="NOW()", onupdate="NOW()")
|
||||
|
||||
__table_args__ = (
|
||||
CheckConstraint("type IN ('text','number','select','radio','checkbox','textarea')", name="ck_qitems_type"),
|
||||
)
|
||||
|
||||
|
||||
class ObjectPassport(Base):
|
||||
__tablename__ = "object_passports"
|
||||
|
||||
id = Column(Integer, primary_key=True, autoincrement=True)
|
||||
session_id = Column(Integer, ForeignKey("questionnaire_sessions.id", ondelete="SET NULL"))
|
||||
object_id = Column(Integer, ForeignKey("objects.id", ondelete="SET NULL"))
|
||||
object_index = Column(Numeric(5, 2), default=0)
|
||||
risk_score = Column(Numeric(5, 2), default=0)
|
||||
complexity_index = Column(Numeric(5, 2), default=0)
|
||||
sla_price_monthly = Column(Numeric(12, 2), default=0)
|
||||
passport_data = Column(JSON)
|
||||
created_by = Column(Integer, ForeignKey("users.id", ondelete="SET NULL"))
|
||||
created_at = Column(DateTime, nullable=False, server_default="NOW()")
|
||||
|
||||
session = relationship("QuestionnaireSession", back_populates="passport")
|
||||
object = relationship("Object", back_populates="passports")
|
||||
creator = relationship("User")
|
||||
|
||||
|
||||
class SLAContract(Base):
|
||||
__tablename__ = "sla_contracts"
|
||||
|
||||
id = Column(Integer, primary_key=True, autoincrement=True)
|
||||
customer_id = Column(Integer, ForeignKey("customers.id", ondelete="SET NULL"))
|
||||
object_id = Column(Integer, ForeignKey("objects.id", ondelete="CASCADE"), nullable=False)
|
||||
contract_number = Column(String(50), default="")
|
||||
client_name = Column(String(255), default="")
|
||||
description = Column(Text)
|
||||
start_date = Column(Date, nullable=False)
|
||||
end_date = Column(Date)
|
||||
sla_price_monthly = Column(Numeric(12, 2), nullable=False, default=0)
|
||||
penalty_rate = Column(Numeric(5, 2), default=0)
|
||||
response_time_p1 = Column(Integer, default=4)
|
||||
response_time_p2 = Column(Integer, default=8)
|
||||
response_time_p3 = Column(Integer, default=24)
|
||||
response_time_hours = Column(Numeric(5, 1))
|
||||
service_level = Column(String(20), nullable=False, default="business")
|
||||
status = Column(String(20), nullable=False, default="negotiation")
|
||||
created_by = Column(Integer, ForeignKey("users.id", ondelete="SET NULL"))
|
||||
created_at = Column(DateTime, nullable=False, server_default="NOW()")
|
||||
updated_at = Column(DateTime, nullable=False, server_default="NOW()", onupdate="NOW()")
|
||||
|
||||
__table_args__ = (
|
||||
CheckConstraint("service_level IN ('start','business','enterprise')", name="ck_sla_level"),
|
||||
CheckConstraint("status IN ('active','expired','cancelled','negotiation')", name="ck_sla_status"),
|
||||
)
|
||||
|
||||
customer = relationship("Customer", back_populates="sla_contracts")
|
||||
object = relationship("Object", back_populates="sla_contracts")
|
||||
creator = relationship("User")
|
||||
|
||||
|
||||
class Incident(Base):
|
||||
__tablename__ = "incidents"
|
||||
|
||||
id = Column(Integer, primary_key=True, autoincrement=True)
|
||||
object_id = Column(Integer, ForeignKey("objects.id", ondelete="CASCADE"), nullable=False)
|
||||
reported_by = Column(Integer, ForeignKey("users.id", ondelete="SET NULL"))
|
||||
assigned_to = Column(Integer, ForeignKey("users.id", ondelete="SET NULL"))
|
||||
title = Column(String(500), nullable=False)
|
||||
description = Column(Text)
|
||||
severity = Column(String(4), nullable=False, default="P3")
|
||||
status = Column(String(20), nullable=False, default="open")
|
||||
resolution = Column(Text)
|
||||
cause = Column(String(500), default="")
|
||||
resolution_time_minutes = Column(Integer, default=0)
|
||||
sla_breached = Column(Boolean, default=False)
|
||||
resolved_at = Column(DateTime)
|
||||
created_at = Column(DateTime, nullable=False, server_default="NOW()")
|
||||
updated_at = Column(DateTime, nullable=False, server_default="NOW()", onupdate="NOW()")
|
||||
|
||||
__table_args__ = (
|
||||
CheckConstraint("severity IN ('P1','P2','P3')", name="ck_incidents_severity"),
|
||||
CheckConstraint("status IN ('open','in_progress','resolved','closed')", name="ck_incidents_status"),
|
||||
)
|
||||
|
||||
object = relationship("Object", back_populates="incidents")
|
||||
reporter = relationship("User", foreign_keys=[reported_by])
|
||||
assignee = relationship("User", foreign_keys=[assigned_to])
|
||||
|
||||
|
||||
class EngineerKPI(Base):
|
||||
__tablename__ = "engineer_kpi"
|
||||
|
||||
id = Column(Integer, primary_key=True, autoincrement=True)
|
||||
engineer_id = Column(Integer, ForeignKey("users.id", ondelete="CASCADE"), nullable=False)
|
||||
period_start = Column(Date, nullable=False)
|
||||
period_end = Column(Date, nullable=False)
|
||||
sla_compliance = Column(Numeric(5, 2), default=0)
|
||||
response_time_score = Column(Numeric(5, 2), default=0)
|
||||
resolution_time_score = Column(Numeric(5, 2), default=0)
|
||||
diagnosis_accuracy = Column(Numeric(5, 2), default=0)
|
||||
reopen_rate = Column(Numeric(5, 2), default=0)
|
||||
risk_coverage_score = Column(Numeric(5, 2), default=0)
|
||||
documentation_quality = Column(Numeric(5, 2), default=0)
|
||||
engineer_score = Column(Numeric(5, 2), default=0)
|
||||
grade = Column(String(20), default="")
|
||||
components_json = Column(JSON)
|
||||
created_at = Column(DateTime, nullable=False, server_default="NOW()")
|
||||
|
||||
engineer = relationship("User")
|
||||
|
||||
|
||||
class SHSRecord(Base):
|
||||
__tablename__ = "shs_records"
|
||||
|
||||
id = Column(Integer, primary_key=True, autoincrement=True)
|
||||
recorded_by = Column(Integer, ForeignKey("users.id", ondelete="SET NULL"))
|
||||
period_start = Column(Date, nullable=False)
|
||||
period_end = Column(Date, nullable=False)
|
||||
sla_stability = Column(Numeric(5, 2), default=0)
|
||||
revenue_stability = Column(Numeric(5, 2), default=0)
|
||||
retention = Column(Numeric(5, 2), default=0)
|
||||
engineer_performance = Column(Numeric(5, 2), default=0)
|
||||
incident_stability = Column(Numeric(5, 2), default=0)
|
||||
sales_flow = Column(Numeric(5, 2), default=0)
|
||||
operational_efficiency = Column(Numeric(5, 2), default=0)
|
||||
shs_score = Column(Numeric(5, 2), default=0)
|
||||
shs_status = Column(String(20), default="")
|
||||
components_json = Column(JSON)
|
||||
created_at = Column(DateTime, nullable=False, server_default="NOW()")
|
||||
|
||||
recorder = relationship("User")
|
||||
|
||||
|
||||
class BlogPost(Base):
|
||||
__tablename__ = "blog_posts"
|
||||
|
||||
id = Column(Integer, primary_key=True, autoincrement=True)
|
||||
title = Column(String(500), nullable=False)
|
||||
slug = Column(String(500), unique=True, nullable=False)
|
||||
content = Column(Text, nullable=False)
|
||||
excerpt = Column(String(1000), default="")
|
||||
category = Column(String(50), nullable=False, default="audit")
|
||||
author_id = Column(Integer, ForeignKey("users.id", ondelete="SET NULL"))
|
||||
status = Column(String(20), nullable=False, default="draft")
|
||||
published_at = Column(DateTime)
|
||||
created_at = Column(DateTime, nullable=False, server_default="NOW()")
|
||||
updated_at = Column(DateTime, nullable=False, server_default="NOW()", onupdate="NOW()")
|
||||
|
||||
__table_args__ = (
|
||||
CheckConstraint("category IN ('audit','sla','incident','supervision','documentation','risk','cases')", name="ck_blog_category"),
|
||||
CheckConstraint("status IN ('draft','published','archived')", name="ck_blog_status"),
|
||||
)
|
||||
|
||||
author = relationship("User")
|
||||
|
||||
|
||||
class FormulaCoefficient(Base):
|
||||
__tablename__ = "formula_coefficients"
|
||||
|
||||
id = Column(Integer, primary_key=True, autoincrement=True)
|
||||
key = Column(String(100), unique=True, nullable=False)
|
||||
value = Column(Numeric(10, 4), nullable=False, default=0)
|
||||
description = Column(String(500), default="")
|
||||
formula_ref = Column(String(255), default="")
|
||||
is_active = Column(Boolean, nullable=False, default=True)
|
||||
updated_by = Column(Integer, ForeignKey("users.id", ondelete="SET NULL"))
|
||||
updated_at = Column(DateTime, nullable=False, server_default="NOW()", onupdate="NOW()")
|
||||
|
||||
updater = relationship("User")
|
||||
|
||||
|
||||
class Case(Base):
|
||||
__tablename__ = "cases"
|
||||
|
||||
id = Column(Integer, primary_key=True, autoincrement=True)
|
||||
title = Column(String(500), nullable=False)
|
||||
text = Column(Text, nullable=False)
|
||||
effect = Column(Text, nullable=False)
|
||||
sort_order = Column(Integer, nullable=False, default=0)
|
||||
is_active = Column(Boolean, nullable=False, default=True)
|
||||
created_at = Column(DateTime, nullable=False, server_default="NOW()")
|
||||
updated_at = Column(DateTime, nullable=False, server_default="NOW()", onupdate="NOW()")
|
||||
@@ -0,0 +1,65 @@
|
||||
import os
|
||||
import json
|
||||
from pathlib import Path
|
||||
from app.config import get_settings
|
||||
|
||||
settings = get_settings()
|
||||
PERMISSIONS_FILE = os.path.join(settings.PERMISSIONS_DIR, "docs_permissions.json")
|
||||
|
||||
|
||||
def load_permissions() -> dict:
|
||||
if os.path.exists(PERMISSIONS_FILE):
|
||||
with open(PERMISSIONS_FILE, "r", encoding="utf-8") as f:
|
||||
return json.load(f)
|
||||
return {}
|
||||
|
||||
|
||||
def save_permissions(perms: dict):
|
||||
os.makedirs(settings.PERMISSIONS_DIR, exist_ok=True)
|
||||
with open(PERMISSIONS_FILE, "w", encoding="utf-8") as f:
|
||||
json.dump(perms, f, indent=2, ensure_ascii=False)
|
||||
|
||||
|
||||
def discover_docs() -> dict:
|
||||
docs_dir = settings.DOCS_DIR
|
||||
if not os.path.exists(docs_dir):
|
||||
return {}
|
||||
perms = load_permissions()
|
||||
existing_slugs = set(perms.keys())
|
||||
for filename in os.listdir(docs_dir):
|
||||
if filename.endswith(".md"):
|
||||
slug = Path(filename).stem
|
||||
if slug not in existing_slugs:
|
||||
title = slug.replace("-", " ").title()
|
||||
perms[slug] = {
|
||||
"title": title,
|
||||
"filename": filename,
|
||||
"sort_order": len(perms),
|
||||
"permissions": {
|
||||
"engineer": {"view": False, "edit": False, "cancel": False}
|
||||
},
|
||||
}
|
||||
save_permissions(perms)
|
||||
return perms
|
||||
|
||||
|
||||
def get_allowed_docs(role: str) -> list[dict]:
|
||||
perms = discover_docs()
|
||||
if role == "owner":
|
||||
return sorted(perms.values(), key=lambda x: x.get("sort_order", 0))
|
||||
if role == "engineer":
|
||||
return [
|
||||
doc for doc in perms.values()
|
||||
if doc.get("permissions", {}).get("engineer", {}).get("view", False)
|
||||
]
|
||||
return []
|
||||
|
||||
|
||||
def can_access_doc(role: str, slug: str, action: str = "view") -> bool:
|
||||
if role == "owner":
|
||||
return True
|
||||
if role == "engineer":
|
||||
perms = load_permissions()
|
||||
doc = perms.get(slug, {})
|
||||
return doc.get("permissions", {}).get("engineer", {}).get(action, False)
|
||||
return False
|
||||
@@ -0,0 +1,16 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="robots" content="noindex, nofollow">
|
||||
<title>{% block title %}Service Portal — AegisOne Engineering{% endblock %}</title>
|
||||
<link rel="stylesheet" href="/service-style.php">
|
||||
<link rel="icon" type="image/x-icon" href="/assets/img/favicon.ico">
|
||||
{% block extra_head %}{% endblock %}
|
||||
</head>
|
||||
<body class="{% block body_class %}{% endblock %}">
|
||||
{% block content %}{% endblock %}
|
||||
{% block extra_scripts %}{% endblock %}
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,126 @@
|
||||
{% extends "base.html" %}
|
||||
{% block body_class %}dashboard-page{% endblock %}
|
||||
{% block content %}
|
||||
<button class="sidebar-toggle" onclick="document.querySelector('.sidebar').classList.toggle('open')">☰</button>
|
||||
<div class="layout">
|
||||
<aside class="sidebar">
|
||||
<div class="sidebar-header">
|
||||
<div class="logo">Aegis<span>One</span></div>
|
||||
<div style="font-size:10px;color:var(--text-muted);">Service Portal</div>
|
||||
</div>
|
||||
<nav class="sidebar-nav">
|
||||
<div class="sidebar-section">Панель</div>
|
||||
<a href="/service/dashboard" class="active">Дашборд</a>
|
||||
{% if user.role == 'owner' %}
|
||||
<div class="sidebar-section">Управление</div>
|
||||
<a href="/service/users">Сотрудники</a>
|
||||
<a href="/service/customers">Клиенты</a>
|
||||
<a href="/service/objects">Объекты</a>
|
||||
<a href="/service/assignments">Назначения</a>
|
||||
<a href="/service/sla">SLA контракты</a>
|
||||
<a href="/service/ceo">CEO дашборд</a>
|
||||
<a href="/service/coefficients">Коэффициенты</a>
|
||||
{% elif user.role == 'engineer' %}
|
||||
<div class="sidebar-section">Управление</div>
|
||||
<a href="/service/customers">Клиенты</a>
|
||||
<a href="/service/objects">Объекты</a>
|
||||
<a href="/service/sla">SLA контракты</a>
|
||||
{% endif %}
|
||||
<div class="sidebar-section">Работа</div>
|
||||
{% if user.role in ['engineer', 'technician'] %}
|
||||
<a href="/service/tasks">Задачи</a>
|
||||
<a href="/service/reports">Отчёты</a>
|
||||
<a href="/service/incidents">Инциденты</a>
|
||||
{% endif %}
|
||||
{% if user.role in ['owner', 'engineer'] %}
|
||||
<a href="/service/questionnaire">Опросник</a>
|
||||
{% endif %}
|
||||
{% if user.role == 'owner' %}
|
||||
<a href="/service/questionnaire-config">Настройка опросника</a>
|
||||
{% endif %}
|
||||
{% if user.role in ['owner', 'engineer'] %}
|
||||
<a href="/service/passports">Паспорта объектов</a>
|
||||
{% endif %}
|
||||
{% if user.role == 'technician' %}
|
||||
<a href="/service/checklist">Чек-лист</a>
|
||||
{% endif %}
|
||||
<div class="sidebar-section">Блог</div>
|
||||
{% if user.role == 'owner' %}
|
||||
<a href="/service/blog">Управление блогом</a>
|
||||
{% endif %}
|
||||
<a href="/blog/">Публичный блог</a>
|
||||
<div class="sidebar-section">Контент</div>
|
||||
{% if user.role == 'owner' %}
|
||||
<a href="/service/cases">Примеры из практики</a>
|
||||
{% endif %}
|
||||
<div class="sidebar-section">Документация</div>
|
||||
{% if user.role in ['owner', 'engineer'] %}
|
||||
<a href="/service/docs">Просмотр документации</a>
|
||||
{% endif %}
|
||||
{% if user.role == 'owner' %}
|
||||
<a href="/service/docs-manage">Управление документами</a>
|
||||
{% endif %}
|
||||
</nav>
|
||||
<div class="sidebar-footer">
|
||||
<div class="user-name">{{ user.full_name }}</div>
|
||||
<div class="user-role">{{ {'owner': 'Владелец', 'engineer': 'Инженер', 'technician': 'Техник'}[user.role] }}</div>
|
||||
<a href="/service/logout" style="display:inline-block;margin-top:6px;font-size:12px;">Выйти</a>
|
||||
</div>
|
||||
</aside>
|
||||
<main class="main">
|
||||
<div class="main-header">
|
||||
<div>
|
||||
<h1>Дашборд</h1>
|
||||
<div class="breadcrumb"><a href="/service/dashboard">Главная</a></div>
|
||||
</div>
|
||||
<div class="actions">
|
||||
<span style="font-size:12px;color:var(--text-muted);">{{ now }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if shs_alert %}
|
||||
<div class="shs-alert critical">⚠ {{ shs_alert }}</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="card-grid">
|
||||
<a href="/service/objects" class="card card-link">
|
||||
<div class="card-label">Активные объекты</div>
|
||||
<div class="card-value value-accent">{{ stats.objects }}</div>
|
||||
</a>
|
||||
<a href="/service/tasks" class="card card-link">
|
||||
<div class="card-label">Активные задачи</div>
|
||||
<div class="card-value {% if stats.tasks > 0 %}value-yellow{% else %}value-green{% endif %}">{{ stats.tasks }}</div>
|
||||
</a>
|
||||
<a href="/service/incidents" class="card card-link">
|
||||
<div class="card-label">Открытые инциденты</div>
|
||||
<div class="card-value {% if stats.incidents > 0 %}value-red{% else %}value-green{% endif %}">{{ stats.incidents }}</div>
|
||||
</a>
|
||||
<a href="/service/sla" class="card card-link">
|
||||
<div class="card-label">SLA контракты</div>
|
||||
<div class="card-value value-info">{{ stats.sla_count }}</div>
|
||||
</a>
|
||||
<a href="/service/sla" class="card card-link">
|
||||
<div class="card-label">SLA Compliance</div>
|
||||
<div class="card-value {% if stats.sla_compliance >= 90 %}value-green{% elif stats.sla_compliance >= 70 %}value-yellow{% else %}value-red{% endif %}">{{ stats.sla_compliance }}%</div>
|
||||
</a>
|
||||
{% if stats.shs %}
|
||||
<a href="/service/ceo" class="card card-link">
|
||||
<div class="card-label">SHS (System Health)</div>
|
||||
<div class="card-value {% if stats.shs.shs_status in ['Growth', 'Stable'] %}value-green{% else %}value-red{% endif %}">{{ stats.shs.shs_score }}</div>
|
||||
<div class="card-label"><span class="badge badge-{{ stats.shs.shs_status|lower }}">{{ stats.shs.shs_status }}</span></div>
|
||||
</a>
|
||||
{% endif %}
|
||||
{% if stats.my_tasks is defined %}
|
||||
<a href="/service/tasks" class="card card-link">
|
||||
<div class="card-label">Мои задачи</div>
|
||||
<div class="card-value">{{ stats.my_tasks }}</div>
|
||||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
<style>
|
||||
.card-link { text-decoration:none; color:inherit; display:block; transition:transform 0.2s, box-shadow 0.2s; }
|
||||
.card-link:hover { transform:translateY(-2px); box-shadow:var(--shadow); cursor:pointer; }
|
||||
</style>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,28 @@
|
||||
{% extends "base.html" %}
|
||||
{% block body_class %}login-page{% endblock %}
|
||||
{% block content %}
|
||||
<div class="login-box">
|
||||
<div class="login-brand">
|
||||
<img src="/logo.php" alt="AegisOne" class="login-brand__img">
|
||||
<div class="login-brand__title">AegisOne Engineering</div>
|
||||
<div class="login-brand__subtitle">Service Portal</div>
|
||||
</div>
|
||||
<div class="login-divider"></div>
|
||||
<h1>Вход в сервисный портал</h1>
|
||||
{% if error %}
|
||||
<div class="alert alert-error">{{ error }}</div>
|
||||
{% endif %}
|
||||
<form method="post">
|
||||
<div class="form-group">
|
||||
<label for="login">Логин</label>
|
||||
<input type="text" id="login" name="login" placeholder="Введите логин" required autocomplete="username" autofocus>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="password">Пароль</label>
|
||||
<input type="password" id="password" name="password" placeholder="Введите пароль" required autocomplete="current-password">
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary btn-block">Войти</button>
|
||||
</form>
|
||||
<p class="login-box__footnote">* Сервисный портал для сотрудников AegisOne Engineering</p>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,53 @@
|
||||
version: "3.8"
|
||||
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:16-alpine
|
||||
container_name: aegisone-postgres
|
||||
environment:
|
||||
POSTGRES_DB: aegisone
|
||||
POSTGRES_USER: aegisone
|
||||
POSTGRES_PASSWORD: aegisone_pass
|
||||
volumes:
|
||||
- pgdata:/var/lib/postgresql/data
|
||||
- ./sql/schema_postgresql.sql:/docker-entrypoint-initdb.d/01_schema.sql
|
||||
- ./sql/seed_data.sql:/docker-entrypoint-initdb.d/02_seed.sql
|
||||
ports:
|
||||
- "5432:5432"
|
||||
networks:
|
||||
- aegisone-net
|
||||
restart: unless-stopped
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U aegisone"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
|
||||
app:
|
||||
build: .
|
||||
container_name: aegisone-app
|
||||
environment:
|
||||
DATABASE_URL: postgresql+asyncpg://aegisone:aegisone_pass@postgres:5432/aegisone
|
||||
SECRET_KEY: ${SECRET_KEY:-change-me-to-random-string}
|
||||
SESSION_TTL: 3600
|
||||
APP_ENV: production
|
||||
LOG_LEVEL: info
|
||||
depends_on:
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
ports:
|
||||
- "8000:8000"
|
||||
volumes:
|
||||
- ./docs:/app/docs
|
||||
- ./permissions:/app/permissions
|
||||
- ./uploads:/app/uploads
|
||||
networks:
|
||||
- aegisone-net
|
||||
restart: unless-stopped
|
||||
|
||||
volumes:
|
||||
pgdata:
|
||||
|
||||
networks:
|
||||
aegisone-net:
|
||||
driver: bridge
|
||||
@@ -0,0 +1,14 @@
|
||||
fastapi==0.115.6
|
||||
uvicorn[standard]==0.34.0
|
||||
sqlalchemy[asyncio]==2.0.36
|
||||
asyncpg==0.30.0
|
||||
alembic==1.14.0
|
||||
python-multipart==0.0.18
|
||||
jinja2==3.1.4
|
||||
passlib[bcrypt]==1.7.4
|
||||
python-dotenv==1.0.1
|
||||
itsdangerous==2.2.0
|
||||
aiohttp==3.11.11
|
||||
markdown==3.7
|
||||
pydantic==2.10.3
|
||||
pydantic-settings==2.7.0
|
||||
@@ -0,0 +1,180 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
MySQL → PostgreSQL Data Migration Script
|
||||
Reads from MySQL, transforms data, writes to PostgreSQL.
|
||||
Handles ENUM→VARCHAR, TINYINT→BOOLEAN, JSON→JSONB, AUTO_INCREMENT→SERIAL.
|
||||
"""
|
||||
|
||||
import mysql.connector
|
||||
import asyncpg
|
||||
import asyncio
|
||||
import json
|
||||
import os
|
||||
from dotenv import load_dotenv
|
||||
|
||||
load_dotenv()
|
||||
|
||||
MYSQL_CONFIG = {
|
||||
"host": os.getenv("MYSQL_HOST", "localhost"),
|
||||
"port": int(os.getenv("MYSQL_PORT", "3306")),
|
||||
"user": os.getenv("MYSQL_USER", "root"),
|
||||
"password": os.getenv("MYSQL_PASSWORD", ""),
|
||||
"database": os.getenv("MYSQL_DATABASE", "aegisone"),
|
||||
}
|
||||
|
||||
PG_DSN = os.getenv("PG_DSN", "postgresql://aegisone:aegisone_pass@localhost:5432/aegisone")
|
||||
|
||||
TABLES = [
|
||||
"users", "customers", "objects", "object_assignments",
|
||||
"tasks", "task_comments", "task_photos", "reports",
|
||||
"questionnaire_sessions", "questionnaire_answers", "questionnaire_items",
|
||||
"object_passports", "sla_contracts", "incidents",
|
||||
"engineer_kpi", "shs_records", "blog_posts",
|
||||
"formula_coefficients", "cases", "login_attempts", "audit_log",
|
||||
]
|
||||
|
||||
ENUM_MAP = {
|
||||
"users.role": {"owner": "owner", "engineer": "engineer", "technician": "technician"},
|
||||
"objects.status": {"active": "active", "inactive": "inactive", "audit": "audit", "prospective": "prospective"},
|
||||
"tasks.priority": {"P1": "P1", "P2": "P2", "P3": "P3", "P4": "P4"},
|
||||
"tasks.status": {"open": "open", "in_progress": "in_progress", "completed": "completed", "cancelled": "cancelled"},
|
||||
"reports.report_type": {"inspection": "inspection", "service": "service", "emergency": "emergency", "audit": "audit", "monthly": "monthly"},
|
||||
"reports.result_status": {"fixed": "fixed", "partial": "partial", "revisit": "revisit", "ok": "ok"},
|
||||
"reports.status": {"draft": "draft", "final": "final", "cancelled": "cancelled"},
|
||||
"questionnaire_sessions.status": {"draft": "draft", "completed": "completed", "cancelled": "cancelled"},
|
||||
"questionnaire_items.type": {"text": "text", "number": "number", "select": "select", "radio": "radio", "checkbox": "checkbox", "textarea": "textarea"},
|
||||
"sla_contracts.service_level": {"start": "start", "business": "business", "enterprise": "enterprise"},
|
||||
"sla_contracts.status": {"active": "active", "expired": "expired", "cancelled": "cancelled", "negotiation": "negotiation"},
|
||||
"incidents.severity": {"P1": "P1", "P2": "P2", "P3": "P3"},
|
||||
"incidents.status": {"open": "open", "in_progress": "in_progress", "resolved": "resolved", "closed": "closed"},
|
||||
"blog_posts.category": {"audit": "audit", "sla": "sla", "incident": "incident", "supervision": "supervision", "documentation": "documentation", "risk": "risk", "cases": "cases"},
|
||||
"blog_posts.status": {"draft": "draft", "published": "published", "archived": "archived"},
|
||||
"object_assignments.role": {"engineer": "engineer", "technician": "technician"},
|
||||
"customers.status": {"active": "active", "inactive": "inactive", "prospect": "prospect"},
|
||||
"task_photos.type": {"before": "before", "after": "after", "evidence": "evidence", "other": "other"},
|
||||
}
|
||||
|
||||
BOOL_COLUMNS = {
|
||||
"users": ["is_active"],
|
||||
"tasks": ["sla_compliant"],
|
||||
"reports": ["client_confirmed"],
|
||||
"questionnaire_items": ["required", "is_active"],
|
||||
"object_passports": [],
|
||||
"sla_contracts": [],
|
||||
"incidents": ["sla_breached"],
|
||||
"engineer_kpi": [],
|
||||
"shs_records": [],
|
||||
"blog_posts": [],
|
||||
"formula_coefficients": ["is_active"],
|
||||
"cases": ["is_active"],
|
||||
"customers": [],
|
||||
"objects": [],
|
||||
"object_assignments": [],
|
||||
"task_comments": [],
|
||||
"task_photos": [],
|
||||
"questionnaire_sessions": [],
|
||||
"questionnaire_answers": [],
|
||||
"login_attempts": [],
|
||||
"audit_log": [],
|
||||
}
|
||||
|
||||
SKIP_COLUMNS = {
|
||||
"users": [],
|
||||
"customers": [],
|
||||
"objects": [],
|
||||
"object_assignments": [],
|
||||
"tasks": [],
|
||||
"task_comments": [],
|
||||
"task_photos": [],
|
||||
"reports": [],
|
||||
"questionnaire_sessions": [],
|
||||
"questionnaire_answers": [],
|
||||
"questionnaire_items": [],
|
||||
"object_passports": [],
|
||||
"sla_contracts": [],
|
||||
"incidents": [],
|
||||
"engineer_kpi": [],
|
||||
"shs_records": [],
|
||||
"blog_posts": [],
|
||||
"formula_coefficients": [],
|
||||
"cases": [],
|
||||
"login_attempts": [],
|
||||
"audit_log": [],
|
||||
}
|
||||
|
||||
|
||||
def transform_row(table: str, row: dict) -> dict:
|
||||
result = {}
|
||||
for key, value in row.items():
|
||||
if key in SKIP_COLUMNS.get(table, []):
|
||||
continue
|
||||
if value is None:
|
||||
result[key] = None
|
||||
continue
|
||||
enum_key = f"{table}.{key}"
|
||||
if enum_key in ENUM_MAP:
|
||||
result[key] = ENUM_MAP[enum_key].get(value, value)
|
||||
elif table in BOOL_COLUMNS and key in BOOL_COLUMNS[table]:
|
||||
result[key] = bool(value)
|
||||
elif isinstance(value, (bytes, bytearray)):
|
||||
result[key] = value.decode("utf-8")
|
||||
elif isinstance(value, dict) or isinstance(value, list):
|
||||
result[key] = json.dumps(value, ensure_ascii=False)
|
||||
else:
|
||||
result[key] = value
|
||||
return result
|
||||
|
||||
|
||||
async def migrate_table(mysql_conn, pg_conn, table: str):
|
||||
cursor = mysql_conn.cursor(dictionary=True)
|
||||
cursor.execute(f"SELECT * FROM {table}")
|
||||
rows = cursor.fetchall()
|
||||
|
||||
if not rows:
|
||||
print(f" {table}: нет данных")
|
||||
return
|
||||
|
||||
columns = list(rows[0].keys())
|
||||
placeholders = ", ".join([f"${i+1}" for i in range(len(columns))])
|
||||
col_names = ", ".join(columns)
|
||||
|
||||
inserted = 0
|
||||
errors = 0
|
||||
for row in rows:
|
||||
try:
|
||||
transformed = transform_row(table, row)
|
||||
values = [transformed.get(c) for c in columns]
|
||||
await pg_conn.execute(
|
||||
f"INSERT INTO {table} ({col_names}) VALUES ({placeholders}) ON CONFLICT DO NOTHING",
|
||||
*values,
|
||||
)
|
||||
inserted += 1
|
||||
except Exception as e:
|
||||
errors += 1
|
||||
print(f" Ошибка в {table}: {e}")
|
||||
|
||||
print(f" {table}: {inserted} записей, {errors} ошибок")
|
||||
|
||||
|
||||
async def main():
|
||||
print("Подключение к MySQL...")
|
||||
mysql_conn = mysql.connector.connect(**MYSQL_CONFIG)
|
||||
|
||||
print("Подключение к PostgreSQL...")
|
||||
pg_conn = await asyncpg.connect(PG_DSN)
|
||||
|
||||
total_tables = len(TABLES)
|
||||
for i, table in enumerate(TABLES, 1):
|
||||
print(f"[{i}/{total_tables}] Миграция {table}...")
|
||||
try:
|
||||
await migrate_table(mysql_conn, pg_conn, table)
|
||||
except Exception as e:
|
||||
print(f" Ошибка миграции {table}: {e}")
|
||||
|
||||
await pg_conn.close()
|
||||
mysql_conn.close()
|
||||
print("\nМиграция завершена.")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
@@ -0,0 +1,401 @@
|
||||
-- AegisOne Engineering — PostgreSQL Schema
|
||||
-- Adapted from MySQL for Python/FastAPI migration
|
||||
|
||||
-- Users
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
id SERIAL PRIMARY KEY,
|
||||
login VARCHAR(50) NOT NULL UNIQUE,
|
||||
password_hash VARCHAR(255) NOT NULL,
|
||||
role VARCHAR(20) NOT NULL DEFAULT 'technician' CHECK (role IN ('owner','engineer','technician')),
|
||||
full_name VARCHAR(255) NOT NULL,
|
||||
phone VARCHAR(50) DEFAULT '',
|
||||
email VARCHAR(255) DEFAULT '',
|
||||
is_active BOOLEAN NOT NULL DEFAULT TRUE,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE INDEX idx_users_role ON users(role);
|
||||
CREATE INDEX idx_users_active ON users(is_active);
|
||||
|
||||
-- Login attempts
|
||||
CREATE TABLE IF NOT EXISTS login_attempts (
|
||||
id SERIAL PRIMARY KEY,
|
||||
ip_address VARCHAR(45) NOT NULL,
|
||||
login VARCHAR(50) NOT NULL DEFAULT '',
|
||||
attempt_time TIMESTAMP NOT NULL DEFAULT NOW()
|
||||
);
|
||||
CREATE INDEX idx_login_attempts_ip ON login_attempts(ip_address);
|
||||
CREATE INDEX idx_login_attempts_time ON login_attempts(attempt_time);
|
||||
|
||||
-- Audit log
|
||||
CREATE TABLE IF NOT EXISTS audit_log (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
user_id INTEGER REFERENCES users(id) ON DELETE SET NULL,
|
||||
action VARCHAR(255) NOT NULL,
|
||||
details TEXT,
|
||||
ip_address VARCHAR(45) DEFAULT '',
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW()
|
||||
);
|
||||
CREATE INDEX idx_audit_user ON audit_log(user_id);
|
||||
CREATE INDEX idx_audit_action ON audit_log(action);
|
||||
CREATE INDEX idx_audit_created ON audit_log(created_at);
|
||||
|
||||
-- Customers
|
||||
CREATE TABLE IF NOT EXISTS customers (
|
||||
id SERIAL PRIMARY KEY,
|
||||
name VARCHAR(255) NOT NULL,
|
||||
inn VARCHAR(12) DEFAULT '',
|
||||
kpp VARCHAR(9) DEFAULT '',
|
||||
legal_address VARCHAR(500) DEFAULT '',
|
||||
contact_person VARCHAR(255) DEFAULT '',
|
||||
contact_phone VARCHAR(50) DEFAULT '',
|
||||
contact_email VARCHAR(255) DEFAULT '',
|
||||
status VARCHAR(20) NOT NULL DEFAULT 'active' CHECK (status IN ('active','inactive','prospect')),
|
||||
notes TEXT,
|
||||
created_by INTEGER REFERENCES users(id) ON DELETE SET NULL,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
|
||||
);
|
||||
CREATE INDEX idx_customers_status ON customers(status);
|
||||
CREATE INDEX idx_customers_inn ON customers(inn);
|
||||
|
||||
-- Objects
|
||||
CREATE TABLE IF NOT EXISTS objects (
|
||||
id SERIAL PRIMARY KEY,
|
||||
customer_id INTEGER REFERENCES customers(id) ON DELETE SET NULL,
|
||||
name VARCHAR(255) NOT NULL,
|
||||
address VARCHAR(500) DEFAULT '',
|
||||
object_type VARCHAR(100) DEFAULT '',
|
||||
area_sqm NUMERIC(10,2) DEFAULT 0,
|
||||
employees_count INTEGER DEFAULT 0,
|
||||
contact_person VARCHAR(255) DEFAULT '',
|
||||
contact_phone VARCHAR(50) DEFAULT '',
|
||||
status VARCHAR(20) NOT NULL DEFAULT 'active' CHECK (status IN ('active','inactive','audit','prospective')),
|
||||
notes TEXT,
|
||||
risk_score NUMERIC(5,2) DEFAULT 0,
|
||||
complexity_index NUMERIC(5,2) DEFAULT 0,
|
||||
infrastructure_load NUMERIC(5,2) DEFAULT 0,
|
||||
service_history NUMERIC(5,2) DEFAULT 0,
|
||||
object_index NUMERIC(5,2) DEFAULT 0,
|
||||
sla_price_monthly NUMERIC(12,2) DEFAULT 0,
|
||||
region_factor NUMERIC(3,2) DEFAULT 1.00,
|
||||
created_by INTEGER REFERENCES users(id) ON DELETE SET NULL,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
|
||||
);
|
||||
CREATE INDEX idx_objects_status ON objects(status);
|
||||
CREATE INDEX idx_objects_customer ON objects(customer_id);
|
||||
|
||||
-- Object assignments
|
||||
CREATE TABLE IF NOT EXISTS object_assignments (
|
||||
id SERIAL PRIMARY KEY,
|
||||
object_id INTEGER NOT NULL REFERENCES objects(id) ON DELETE CASCADE,
|
||||
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
role VARCHAR(20) NOT NULL CHECK (role IN ('engineer','technician')),
|
||||
assigned_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
unassigned_at TIMESTAMP DEFAULT NULL
|
||||
);
|
||||
CREATE INDEX idx_assignments_object ON object_assignments(object_id);
|
||||
CREATE INDEX idx_assignments_user ON object_assignments(user_id);
|
||||
|
||||
-- Tasks
|
||||
CREATE TABLE IF NOT EXISTS tasks (
|
||||
id SERIAL PRIMARY KEY,
|
||||
object_id INTEGER NOT NULL REFERENCES objects(id) ON DELETE CASCADE,
|
||||
assigned_to INTEGER REFERENCES users(id) ON DELETE SET NULL,
|
||||
created_by INTEGER REFERENCES users(id) ON DELETE SET NULL,
|
||||
title VARCHAR(500) NOT NULL,
|
||||
description TEXT,
|
||||
priority VARCHAR(4) NOT NULL DEFAULT 'P3' CHECK (priority IN ('P1','P2','P3','P4')),
|
||||
status VARCHAR(20) NOT NULL DEFAULT 'open' CHECK (status IN ('open','in_progress','completed','cancelled')),
|
||||
deadline TIMESTAMP,
|
||||
sla_remaining_hours NUMERIC(6,1) DEFAULT 0,
|
||||
response_time_minutes INTEGER DEFAULT 0,
|
||||
resolution_time_minutes INTEGER DEFAULT 0,
|
||||
sla_compliant BOOLEAN,
|
||||
checklist_data JSONB,
|
||||
result_notes TEXT,
|
||||
closed_at TIMESTAMP,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
|
||||
);
|
||||
CREATE INDEX idx_tasks_object ON tasks(object_id);
|
||||
CREATE INDEX idx_tasks_assigned ON tasks(assigned_to);
|
||||
CREATE INDEX idx_tasks_status ON tasks(status);
|
||||
CREATE INDEX idx_tasks_priority ON tasks(priority);
|
||||
|
||||
-- Task comments
|
||||
CREATE TABLE IF NOT EXISTS task_comments (
|
||||
id SERIAL PRIMARY KEY,
|
||||
task_id INTEGER NOT NULL REFERENCES tasks(id) ON DELETE CASCADE,
|
||||
user_id INTEGER REFERENCES users(id) ON DELETE SET NULL,
|
||||
comment TEXT NOT NULL,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW()
|
||||
);
|
||||
CREATE INDEX idx_comments_task ON task_comments(task_id);
|
||||
|
||||
-- Task photos
|
||||
CREATE TABLE IF NOT EXISTS task_photos (
|
||||
id SERIAL PRIMARY KEY,
|
||||
task_id INTEGER REFERENCES tasks(id) ON DELETE SET NULL,
|
||||
report_id INTEGER REFERENCES reports(id) ON DELETE SET NULL,
|
||||
file_path VARCHAR(500) NOT NULL,
|
||||
description VARCHAR(500) DEFAULT '',
|
||||
type VARCHAR(20) DEFAULT 'other' CHECK (type IN ('before','after','evidence','other')),
|
||||
uploaded_by INTEGER REFERENCES users(id) ON DELETE SET NULL,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW()
|
||||
);
|
||||
CREATE INDEX idx_photos_task ON task_photos(task_id);
|
||||
|
||||
-- Reports (created after task_photos for FK reference)
|
||||
CREATE TABLE IF NOT EXISTS reports (
|
||||
id SERIAL PRIMARY KEY,
|
||||
object_id INTEGER NOT NULL REFERENCES objects(id) ON DELETE CASCADE,
|
||||
created_by INTEGER REFERENCES users(id) ON DELETE SET NULL,
|
||||
report_type VARCHAR(20) NOT NULL DEFAULT 'service' CHECK (report_type IN ('inspection','service','emergency','audit','monthly')),
|
||||
title VARCHAR(500) DEFAULT '',
|
||||
description TEXT,
|
||||
findings TEXT,
|
||||
recommendations TEXT,
|
||||
work_done TEXT,
|
||||
cause_classification VARCHAR(100),
|
||||
result_status VARCHAR(20) DEFAULT 'ok' CHECK (result_status IN ('fixed','partial','revisit','ok')),
|
||||
status VARCHAR(20) NOT NULL DEFAULT 'draft' CHECK (status IN ('draft','final','cancelled')),
|
||||
client_confirmed BOOLEAN DEFAULT FALSE,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
|
||||
);
|
||||
CREATE INDEX idx_reports_object ON reports(object_id);
|
||||
CREATE INDEX idx_reports_author ON reports(created_by);
|
||||
|
||||
-- Add FK for task_photos.report_id after reports table exists
|
||||
-- (handled in application-level migration)
|
||||
|
||||
-- Questionnaire sessions
|
||||
CREATE TABLE IF NOT EXISTS questionnaire_sessions (
|
||||
id SERIAL PRIMARY KEY,
|
||||
object_id INTEGER REFERENCES objects(id) ON DELETE SET NULL,
|
||||
client_name VARCHAR(255) DEFAULT '',
|
||||
created_by INTEGER REFERENCES users(id) ON DELETE SET NULL,
|
||||
status VARCHAR(20) NOT NULL DEFAULT 'draft' CHECK (status IN ('draft','completed','cancelled')),
|
||||
current_step SMALLINT NOT NULL DEFAULT 1,
|
||||
risk_score NUMERIC(5,2) DEFAULT 0,
|
||||
complexity_index NUMERIC(5,2) DEFAULT 0,
|
||||
infrastructure_load NUMERIC(5,2) DEFAULT 0,
|
||||
service_history NUMERIC(5,2) DEFAULT 0,
|
||||
object_index NUMERIC(5,2) DEFAULT 0,
|
||||
sla_price_monthly NUMERIC(12,2) DEFAULT 0,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
|
||||
);
|
||||
CREATE INDEX idx_qsessions_object ON questionnaire_sessions(object_id);
|
||||
CREATE INDEX idx_qsessions_author ON questionnaire_sessions(created_by);
|
||||
|
||||
-- Questionnaire answers
|
||||
CREATE TABLE IF NOT EXISTS questionnaire_answers (
|
||||
id SERIAL PRIMARY KEY,
|
||||
session_id INTEGER NOT NULL REFERENCES questionnaire_sessions(id) ON DELETE CASCADE,
|
||||
step SMALLINT NOT NULL,
|
||||
question_key VARCHAR(100) NOT NULL,
|
||||
answer_value TEXT,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW()
|
||||
);
|
||||
CREATE INDEX idx_qanswers_session ON questionnaire_answers(session_id);
|
||||
CREATE INDEX idx_qanswers_step ON questionnaire_answers(step);
|
||||
|
||||
-- Questionnaire items
|
||||
CREATE TABLE IF NOT EXISTS questionnaire_items (
|
||||
id SERIAL PRIMARY KEY,
|
||||
step INTEGER NOT NULL DEFAULT 1,
|
||||
section VARCHAR(100) NOT NULL DEFAULT '',
|
||||
question_key VARCHAR(100) NOT NULL UNIQUE,
|
||||
label VARCHAR(255) NOT NULL,
|
||||
type VARCHAR(20) NOT NULL DEFAULT 'text' CHECK (type IN ('text','number','select','radio','checkbox','textarea')),
|
||||
options JSONB,
|
||||
required BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
sort_order INTEGER NOT NULL DEFAULT 0,
|
||||
is_active BOOLEAN NOT NULL DEFAULT TRUE,
|
||||
help_text VARCHAR(500) DEFAULT '',
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
|
||||
);
|
||||
CREATE INDEX idx_qitems_step ON questionnaire_items(step);
|
||||
CREATE INDEX idx_qitems_key ON questionnaire_items(question_key);
|
||||
CREATE INDEX idx_qitems_sort ON questionnaire_items(sort_order);
|
||||
|
||||
-- Object passports
|
||||
CREATE TABLE IF NOT EXISTS object_passports (
|
||||
id SERIAL PRIMARY KEY,
|
||||
session_id INTEGER REFERENCES questionnaire_sessions(id) ON DELETE SET NULL,
|
||||
object_id INTEGER REFERENCES objects(id) ON DELETE SET NULL,
|
||||
object_index NUMERIC(5,2) DEFAULT 0,
|
||||
risk_score NUMERIC(5,2) DEFAULT 0,
|
||||
complexity_index NUMERIC(5,2) DEFAULT 0,
|
||||
sla_price_monthly NUMERIC(12,2) DEFAULT 0,
|
||||
passport_data JSONB,
|
||||
created_by INTEGER REFERENCES users(id) ON DELETE SET NULL,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW()
|
||||
);
|
||||
CREATE INDEX idx_passports_object ON object_passports(object_id);
|
||||
CREATE INDEX idx_passports_session ON object_passports(session_id);
|
||||
|
||||
-- SLA contracts
|
||||
CREATE TABLE IF NOT EXISTS sla_contracts (
|
||||
id SERIAL PRIMARY KEY,
|
||||
customer_id INTEGER REFERENCES customers(id) ON DELETE SET NULL,
|
||||
object_id INTEGER NOT NULL REFERENCES objects(id) ON DELETE CASCADE,
|
||||
contract_number VARCHAR(50) DEFAULT '',
|
||||
client_name VARCHAR(255) DEFAULT '',
|
||||
description TEXT,
|
||||
start_date DATE NOT NULL,
|
||||
end_date DATE,
|
||||
sla_price_monthly NUMERIC(12,2) NOT NULL DEFAULT 0,
|
||||
penalty_rate NUMERIC(5,2) DEFAULT 0,
|
||||
response_time_p1 INTEGER DEFAULT 4,
|
||||
response_time_p2 INTEGER DEFAULT 8,
|
||||
response_time_p3 INTEGER DEFAULT 24,
|
||||
response_time_hours NUMERIC(5,1),
|
||||
service_level VARCHAR(20) NOT NULL DEFAULT 'business' CHECK (service_level IN ('start','business','enterprise')),
|
||||
status VARCHAR(20) NOT NULL DEFAULT 'negotiation' CHECK (status IN ('active','expired','cancelled','negotiation')),
|
||||
created_by INTEGER REFERENCES users(id) ON DELETE SET NULL,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
|
||||
);
|
||||
CREATE INDEX idx_sla_object ON sla_contracts(object_id);
|
||||
CREATE INDEX idx_sla_status ON sla_contracts(status);
|
||||
CREATE INDEX idx_sla_customer ON sla_contracts(customer_id);
|
||||
|
||||
-- Incidents
|
||||
CREATE TABLE IF NOT EXISTS incidents (
|
||||
id SERIAL PRIMARY KEY,
|
||||
object_id INTEGER NOT NULL REFERENCES objects(id) ON DELETE CASCADE,
|
||||
reported_by INTEGER REFERENCES users(id) ON DELETE SET NULL,
|
||||
assigned_to INTEGER REFERENCES users(id) ON DELETE SET NULL,
|
||||
title VARCHAR(500) NOT NULL,
|
||||
description TEXT,
|
||||
severity VARCHAR(4) NOT NULL DEFAULT 'P3' CHECK (severity IN ('P1','P2','P3')),
|
||||
status VARCHAR(20) NOT NULL DEFAULT 'open' CHECK (status IN ('open','in_progress','resolved','closed')),
|
||||
resolution TEXT,
|
||||
cause VARCHAR(500) DEFAULT '',
|
||||
resolution_time_minutes INTEGER DEFAULT 0,
|
||||
sla_breached BOOLEAN DEFAULT FALSE,
|
||||
resolved_at TIMESTAMP,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
|
||||
);
|
||||
CREATE INDEX idx_incidents_object ON incidents(object_id);
|
||||
CREATE INDEX idx_incidents_severity ON incidents(severity);
|
||||
CREATE INDEX idx_incidents_status ON incidents(status);
|
||||
CREATE INDEX idx_incidents_assigned ON incidents(assigned_to);
|
||||
|
||||
-- Engineer KPI
|
||||
CREATE TABLE IF NOT EXISTS engineer_kpi (
|
||||
id SERIAL PRIMARY KEY,
|
||||
engineer_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
period_start DATE NOT NULL,
|
||||
period_end DATE NOT NULL,
|
||||
sla_compliance NUMERIC(5,2) DEFAULT 0,
|
||||
response_time_score NUMERIC(5,2) DEFAULT 0,
|
||||
resolution_time_score NUMERIC(5,2) DEFAULT 0,
|
||||
diagnosis_accuracy NUMERIC(5,2) DEFAULT 0,
|
||||
reopen_rate NUMERIC(5,2) DEFAULT 0,
|
||||
risk_coverage_score NUMERIC(5,2) DEFAULT 0,
|
||||
documentation_quality NUMERIC(5,2) DEFAULT 0,
|
||||
engineer_score NUMERIC(5,2) DEFAULT 0,
|
||||
grade VARCHAR(20) DEFAULT '',
|
||||
components_json JSONB,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW()
|
||||
);
|
||||
CREATE INDEX idx_kpi_engineer ON engineer_kpi(engineer_id);
|
||||
CREATE INDEX idx_kpi_period ON engineer_kpi(period_start, period_end);
|
||||
|
||||
-- SHS records
|
||||
CREATE TABLE IF NOT EXISTS shs_records (
|
||||
id SERIAL PRIMARY KEY,
|
||||
recorded_by INTEGER REFERENCES users(id) ON DELETE SET NULL,
|
||||
period_start DATE NOT NULL,
|
||||
period_end DATE NOT NULL,
|
||||
sla_stability NUMERIC(5,2) DEFAULT 0,
|
||||
revenue_stability NUMERIC(5,2) DEFAULT 0,
|
||||
retention NUMERIC(5,2) DEFAULT 0,
|
||||
engineer_performance NUMERIC(5,2) DEFAULT 0,
|
||||
incident_stability NUMERIC(5,2) DEFAULT 0,
|
||||
sales_flow NUMERIC(5,2) DEFAULT 0,
|
||||
operational_efficiency NUMERIC(5,2) DEFAULT 0,
|
||||
shs_score NUMERIC(5,2) DEFAULT 0,
|
||||
shs_status VARCHAR(20) DEFAULT '',
|
||||
components_json JSONB,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW()
|
||||
);
|
||||
CREATE INDEX idx_shs_period ON shs_records(period_start, period_end);
|
||||
|
||||
-- Blog posts
|
||||
CREATE TABLE IF NOT EXISTS blog_posts (
|
||||
id SERIAL PRIMARY KEY,
|
||||
title VARCHAR(500) NOT NULL,
|
||||
slug VARCHAR(500) NOT NULL UNIQUE,
|
||||
content TEXT NOT NULL,
|
||||
excerpt VARCHAR(1000) DEFAULT '',
|
||||
category VARCHAR(50) NOT NULL DEFAULT 'audit' CHECK (category IN ('audit','sla','incident','supervision','documentation','risk','cases')),
|
||||
author_id INTEGER REFERENCES users(id) ON DELETE SET NULL,
|
||||
status VARCHAR(20) NOT NULL DEFAULT 'draft' CHECK (status IN ('draft','published','archived')),
|
||||
published_at TIMESTAMP,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
|
||||
);
|
||||
CREATE INDEX idx_blog_slug ON blog_posts(slug);
|
||||
CREATE INDEX idx_blog_category ON blog_posts(category);
|
||||
CREATE INDEX idx_blog_status ON blog_posts(status);
|
||||
CREATE INDEX idx_blog_published ON blog_posts(published_at);
|
||||
|
||||
-- Formula coefficients
|
||||
CREATE TABLE IF NOT EXISTS formula_coefficients (
|
||||
id SERIAL PRIMARY KEY,
|
||||
key VARCHAR(100) NOT NULL UNIQUE,
|
||||
value NUMERIC(10,4) NOT NULL DEFAULT 0,
|
||||
description VARCHAR(500) DEFAULT '',
|
||||
formula_ref VARCHAR(255) DEFAULT '',
|
||||
is_active BOOLEAN NOT NULL DEFAULT TRUE,
|
||||
updated_by INTEGER REFERENCES users(id) ON DELETE SET NULL,
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
|
||||
);
|
||||
CREATE INDEX idx_coeff_key ON formula_coefficients(key);
|
||||
CREATE INDEX idx_coeff_active ON formula_coefficients(is_active);
|
||||
|
||||
-- Cases
|
||||
CREATE TABLE IF NOT EXISTS cases (
|
||||
id SERIAL PRIMARY KEY,
|
||||
title VARCHAR(500) NOT NULL,
|
||||
text TEXT NOT NULL,
|
||||
effect TEXT NOT NULL,
|
||||
sort_order INTEGER NOT NULL DEFAULT 0,
|
||||
is_active BOOLEAN NOT NULL DEFAULT TRUE,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
|
||||
);
|
||||
CREATE INDEX idx_cases_sort ON cases(sort_order);
|
||||
CREATE INDEX idx_cases_active ON cases(is_active);
|
||||
|
||||
-- Updated_at trigger function
|
||||
CREATE OR REPLACE FUNCTION update_updated_at_column()
|
||||
RETURNS TRIGGER AS $$
|
||||
BEGIN
|
||||
NEW.updated_at = NOW();
|
||||
RETURN NEW;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
-- Apply triggers
|
||||
CREATE TRIGGER update_users_updated_at BEFORE UPDATE ON users FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
||||
CREATE TRIGGER update_customers_updated_at BEFORE UPDATE ON customers FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
||||
CREATE TRIGGER update_objects_updated_at BEFORE UPDATE ON objects FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
||||
CREATE TRIGGER update_tasks_updated_at BEFORE UPDATE ON tasks FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
||||
CREATE TRIGGER update_reports_updated_at BEFORE UPDATE ON reports FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
||||
CREATE TRIGGER update_qsessions_updated_at BEFORE UPDATE ON questionnaire_sessions FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
||||
CREATE TRIGGER update_qitems_updated_at BEFORE UPDATE ON questionnaire_items FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
||||
CREATE TRIGGER update_sla_updated_at BEFORE UPDATE ON sla_contracts FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
||||
CREATE TRIGGER update_incidents_updated_at BEFORE UPDATE ON incidents FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
||||
CREATE TRIGGER update_blog_updated_at BEFORE UPDATE ON blog_posts FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
||||
CREATE TRIGGER update_cases_updated_at BEFORE UPDATE ON cases FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
||||
CREATE TRIGGER update_coeff_updated_at BEFORE UPDATE ON formula_coefficients FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
||||
@@ -0,0 +1,149 @@
|
||||
-- Seed data for PostgreSQL
|
||||
|
||||
-- Default owner (password: AegisOne2024!)
|
||||
INSERT INTO users (login, password_hash, role, full_name, is_active)
|
||||
VALUES ('owner', '$2b$12$LJ3m4ys3Lk8KqJqKqKqKqO5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', 'owner', 'System Owner', TRUE)
|
||||
ON CONFLICT (login) DO NOTHING;
|
||||
|
||||
-- Formula coefficients
|
||||
INSERT INTO formula_coefficients (key, value, description, formula_ref) VALUES
|
||||
('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.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.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()'),
|
||||
('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()'),
|
||||
('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.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.base_cost', 15000, 'Базовая стоимость инженера', 'calc_sla_price()'),
|
||||
('sla_price.region_default', 1.0, 'Региональный коэффициент по умолчанию', 'calc_sla_price()'),
|
||||
('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.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.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.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.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.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()'),
|
||||
('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.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.key_client_penalty', 0.1, 'Штраф за потерю ключевого клиента', 'calc_retention_key_client()')
|
||||
ON CONFLICT (key) DO NOTHING;
|
||||
|
||||
-- Cases
|
||||
INSERT INTO cases (title, text, effect, sort_order) VALUES
|
||||
('Склад крупной торговой сети', 'Выявлено: слепые зоны в зонах разгрузки, недостаточное разрешение камер в зонах погрузки/разгрузки. Одна камера не исправна, у двух не настроена запись.', 'предотвращение убытков на сумму более 5 млн рублей в год.', 1),
|
||||
('Производство пищевых продуктов', 'Неправильная настройка СКУД позволяла несанкционированный доступ в производственные помещения, создавая риск нарушения норм СанПин.', 'снижение риска порчи продукции и утечки конфиденциальной информации.', 2),
|
||||
('Банковский офис', 'Недостатки в системе ОПС приводили к невозможности срабатывания или задержкам в реагировании при ЧП.', 'сокращение рисков утраты имущества и ценностей, повышение уровня безопасности.', 3),
|
||||
('Торгово-развлекательный центр', 'Метод «Тайный покупатель» выявил: охрана не реагирует на срабатывание металлодетекторов, оставляет посты без присмотра. Камеры на парковке не охватывают часть машиномест.', 'снижение риска краж, повышение дисциплины службы охраны.', 4),
|
||||
('Гостиница', 'СКУД не синхронизирована с системой бронирования — доступ в занятые номера. ОПС в части номеров отключена. Видеокамеры имеют мёртвые зоны.', 'устранение репутационных рисков и риска хищения личных вещей гостей.', 5),
|
||||
('Логистический центр', 'Отсутствие видеоконтроля на участках приёмки и отгрузки приводило к систематическим хищениям. СКУД на въезде не фиксирует данные транспортных средств.', 'сокращение потерь товара на 15%.', 6)
|
||||
ON CONFLICT DO NOTHING;
|
||||
|
||||
-- Questionnaire items
|
||||
INSERT INTO questionnaire_items (step, section, question_key, label, type, options, required, sort_order, help_text) VALUES
|
||||
(1, 'Коммерческий профиль объекта', 'object_name', 'Название организации / объекта', 'text', NULL, TRUE, 1, ''),
|
||||
(1, 'Коммерческий профиль объекта', 'object_type', 'Тип объекта', 'select', '["","Гостиница","Склад","Производство","ТЦ","Офис","БЦ","Медицина","Образование","Другое"]', FALSE, 2, ''),
|
||||
(1, 'Коммерческий профиль объекта', 'address', 'Адрес объекта', 'text', NULL, FALSE, 3, ''),
|
||||
(1, 'Коммерческий профиль объекта', 'area', 'Площадь (м²)', 'number', NULL, FALSE, 4, ''),
|
||||
(1, 'Коммерческий профиль объекта', 'employees', 'Количество сотрудников', 'number', NULL, FALSE, 5, ''),
|
||||
(1, 'Коммерческий профиль объекта', 'contact_person', 'Контактное лицо', 'text', NULL, FALSE, 6, ''),
|
||||
(1, 'Коммерческий профиль объекта', 'contact_phone', 'Телефон', 'text', NULL, FALSE, 7, ''),
|
||||
(1, 'Коммерческий профиль объекта', 'region_factor', 'Региональный коэффициент', 'select', '{"1.0":"Краснодар (1.0)","1.1":"Краснодарский край (1.1)","1.3":"РФ (1.3)","1.6":"РФ удалённые (1.6)","1.8":"Москва (1.8)"}', FALSE, 8, ''),
|
||||
(2, 'Видеонаблюдение', 'has_video', 'Есть система видеонаблюдения?', 'radio', '{"1":"Да","0":"Нет"}', FALSE, 1, ''),
|
||||
(2, 'Видеонаблюдение', 'camera_count', 'Количество камер', 'number', NULL, FALSE, 2, ''),
|
||||
(2, 'Видеонаблюдение', 'video_type', 'Тип системы', 'select', '["","ip","analog","mixed"]', FALSE, 3, ''),
|
||||
(2, 'Видеонаблюдение', 'archive_depth', 'Глубина архива', 'select', '{"7":"7 дней","14":"14 дней","30":"30+ дней"}', FALSE, 4, ''),
|
||||
(2, 'СКУД', 'has_acs', 'Есть система СКУД?', 'radio', '{"1":"Да","0":"Нет"}', FALSE, 5, ''),
|
||||
(2, 'СКУД', 'access_points', 'Точек доступа', 'number', NULL, FALSE, 6, ''),
|
||||
(2, 'СКУД', 'acs_vendor', 'Производитель СКУД', 'text', NULL, FALSE, 7, ''),
|
||||
(2, 'Пожарная сигнализация', 'has_fire', 'Есть пожарная сигнализация?', 'radio', '{"1":"Да","0":"Нет"}', FALSE, 8, ''),
|
||||
(2, 'Пожарная сигнализация', 'fire_type', 'Сложность системы', 'select', '{"simple":"Простая","medium":"Средняя","complex":"Сложная (>5000 м²)"}', FALSE, 9, ''),
|
||||
(2, 'Инфраструктура', 'server_state', 'Состояние сервера', 'select', '{"ok":"Нормальный","weak":"Слабый","none":"Нет"}', FALSE, 10, ''),
|
||||
(2, 'Инфраструктура', 'network_state', 'Состояние сети', 'select', '{"stable":"Стабильная","partial":"Частично","unstable":"Нестабильная"}', FALSE, 11, ''),
|
||||
(2, 'Инфраструктура', 'power_state', 'Электропитание (UPS)', 'select', '{"ok":"Нормальное","weak":"Слабый UPS","none":"Нет UPS"}', FALSE, 12, ''),
|
||||
(3, 'Эксплуатационная модель', 'service_state', 'Как обслуживается объект сейчас?', 'select', '{"none":"Не обслуживается","irregular":"Нерегулярно","formal":"Формальный подрядчик","sla":"Есть SLA"}', FALSE, 1, ''),
|
||||
(3, 'Эксплуатационная модель', 'has_regulations', 'Есть ли регламент?', 'checkbox', NULL, FALSE, 2, ''),
|
||||
(3, 'Эксплуатационная модель', 'problems', 'Отметьте частые проблемы', 'checkbox', '["Не работают камеры","Пропадает архив","Зависает СКУД","Ошибки пожарки","Нет реакции подрядчика","Нет понимания состояния систем"]', FALSE, 3, ''),
|
||||
(3, 'Эксплуатационная модель', 'resolution_time', 'Среднее время устранения', 'select', '{"2h":"До 2 часов","24h":"До суток","days":"Несколько дней"}', FALSE, 4, ''),
|
||||
(3, 'Эксплуатационная модель', 'controller', 'Кто контролирует систему?', 'select', '{"engineer":"Штатный инженер","contractor":"Подрядчик","nobody":"Никто"}', FALSE, 5, ''),
|
||||
(4, 'Risk Assessment', 'no_archive', 'Нет архива видеонаблюдения (+25)', 'checkbox', NULL, FALSE, 1, ''),
|
||||
(4, 'Risk Assessment', 'no_power', 'Нет резервного питания (+20)', 'checkbox', NULL, FALSE, 2, ''),
|
||||
(4, 'Risk Assessment', 'no_regulations', 'Нет регламента обслуживания (+15)', 'checkbox', NULL, FALSE, 3, ''),
|
||||
(4, 'Risk Assessment', 'frequent_failures', 'Частые сбои систем (+20)', 'checkbox', NULL, FALSE, 4, ''),
|
||||
(4, 'Risk Assessment', 'no_documentation', 'Нет документации (+10)', 'checkbox', NULL, FALSE, 5, ''),
|
||||
(4, 'Risk Assessment', 'consequences', 'Потенциальные последствия', 'checkbox', '["loss_of_evidence","shutdown","fines","no_investigation","access_fail"]', FALSE, 6, ''),
|
||||
(4, 'Risk Assessment', 'confidence', 'Уровень уверенности в системе', 'select', '{"high":"Высокая","medium":"Средняя","low":"Низкая"}', FALSE, 7, ''),
|
||||
(5, 'Расчёт SLA', 'sla_level', 'Предпочтительный уровень обслуживания', 'select', '{"start":"Базовый (Start SLA)","business":"Стандарт (Business SLA)","enterprise":"Расширенный (Enterprise SLA)"}', FALSE, 1, ''),
|
||||
(5, 'Расчёт SLA', 'visit_frequency', 'Интенсивность обслуживания', 'select', '{"1":"1 выезд / мес","2":"2 выезда / мес","incident":"По инцидентам"}', FALSE, 2, ''),
|
||||
(5, 'Расчёт SLA', 'reaction_time', 'Требуемое время реакции', 'select', '{"24":"24 часа","4":"4 часа","2":"2 часа"}', FALSE, 3, ''),
|
||||
(5, 'Расчёт SLA', 'extra_247', '24/7 поддержка', 'checkbox', NULL, FALSE, 4, ''),
|
||||
(5, 'Расчёт SLA', 'extra_emergency', 'Аварийные выезды', 'checkbox', NULL, FALSE, 5, ''),
|
||||
(5, 'Расчёт SLA', 'extra_audit', 'Аудит', 'checkbox', NULL, FALSE, 6, ''),
|
||||
(5, 'Расчёт SLA', 'extra_docs', 'Документация', 'checkbox', NULL, FALSE, 7, ''),
|
||||
(5, 'Расчёт SLA', 'extra_contractors', 'Контроль подрядчиков', 'checkbox', NULL, FALSE, 8, '')
|
||||
ON CONFLICT (question_key) DO NOTHING;
|
||||
@@ -0,0 +1,2 @@
|
||||
DirectoryIndex index.php
|
||||
Options -Indexes
|
||||
@@ -0,0 +1,88 @@
|
||||
<?php
|
||||
/**
|
||||
* AegisOne Engineering — Риск-инжиниринг
|
||||
*/
|
||||
require_once __DIR__ . '/../config.php';
|
||||
require_once __DIR__ . '/../seo.php';
|
||||
|
||||
$pageKey = 'risk';
|
||||
$canonical = '/risk/';
|
||||
$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">Системный подход к управлению рисками безопасности: оценка, анализ, стратегия. Защита бизнеса от финансовых и репутационных потерь.</p>
|
||||
<a href="#contacts" class="btn">Заказать риск-инжиниринг</a>
|
||||
<p class="hero__footnote">Работаем по всей России</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="services">
|
||||
<div class="container">
|
||||
<h2 class="section-title">Направления риск-инжиниринга</h2>
|
||||
<div class="services__grid">
|
||||
<?php
|
||||
$items = [
|
||||
['svg' => '<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"/>', 'title' => 'Оценка рисков', 'desc' => 'Идентификация и количественная оценка рисков безопасности. Матрица рисков, приоритеты, экономическое обоснование мер защиты.'],
|
||||
['svg' => '<circle cx="32" cy="32" r="24" fill="none" stroke="#00ADEF" stroke-width="3"/><rect x="28" y="18" width="8" height="20" rx="2" fill="#00ADEF"/><rect x="28" y="42" width="8" height="4" rx="1" fill="#00ADEF"/>', 'title' => 'Непрерывность бизнеса', 'desc' => 'Разработка планов непрерывности бизнеса (BCP) и восстановления после инцидентов (DRP). Минимизация простоев.'],
|
||||
['svg' => '<path d="M8 40 Q20 16 32 32 Q44 48 56 24" fill="none" stroke="#00ADEF" stroke-width="3"/><circle cx="32" cy="32" r="4" fill="#00ADEF"/>', 'title' => 'Стратегия безопасности', 'desc' => 'Разработка концепции и архитектуры безопасности объекта с учётом бизнес-задач, угроз и бюджета.'],
|
||||
['svg' => '<rect x="12" y="12" width="40" height="40" rx="4" fill="none" stroke="#00ADEF" stroke-width="3"/><polygon points="22,34 30,42 44,24" fill="none" stroke="#00ADEF" stroke-width="3"/>', 'title' => 'Экономика безопасности', 'desc' => 'Расчёт экономической эффективности инвестиций в безопасность (ROI). Обоснование бюджета для руководства.'],
|
||||
];
|
||||
foreach ($items as $item): ?>
|
||||
<div class="card service-card">
|
||||
<svg class="card__icon" viewBox="0 0 64 64"><?= $item['svg'] ?></svg>
|
||||
<h3><?= $item['title'] ?></h3>
|
||||
<p><?= $item['desc'] ?></p>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="about">
|
||||
<div class="container">
|
||||
<h2 class="section-title">Методология</h2>
|
||||
<div class="info-cards">
|
||||
<div class="info-card">
|
||||
<h3>Прикладной инструмент</h3>
|
||||
<p>Риск-инжиниринг — не абстрактная теория, а прикладной инструмент управления. Мы используем проверенные методики: анализ угроз и уязвимостей (TVA), оценку критичности активов, построение матрицы рисков.</p>
|
||||
</div>
|
||||
<div class="info-card">
|
||||
<h3>Инструмент для решений</h3>
|
||||
<p>Результат — понятный документ с ранжированными рисками, экономическими обоснованиями и дорожной картой внедрения мер защиты. Вы получаете не просто отчёт, а инструмент для принятия управленческих решений.</p>
|
||||
</div>
|
||||
<div class="info-card">
|
||||
<h3>Для кого это</h3>
|
||||
<p>Для собственников бизнеса, директоров по безопасности, риск-менеджеров, которые хотят перевести безопасность из затратной статьи в управляемый бизнес-процесс.</p>
|
||||
</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' => 'Аудит оценивает текущее состояние систем. Риск-инжиниринг смотрит шире: анализирует бизнес-процессы, угрозы, сценарии и предлагает стратегию защиты с экономическим обоснованием.'],
|
||||
['q' => 'Как измерить эффективность мер безопасности?', 'a' => 'Мы используем показатель ROI безопасности: сравниваем стоимость риска «до» и «после» внедрения мер. Вы видите конкретные цифры и сроки окупаемости.'],
|
||||
['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'; ?>
|
||||
@@ -0,0 +1,13 @@
|
||||
User-agent: *
|
||||
Allow: /
|
||||
|
||||
# Закрываем служебные разделы от индексации
|
||||
Disallow: /service/
|
||||
Disallow: /config.php
|
||||
Disallow: /seo.php
|
||||
Disallow: /inc/
|
||||
Disallow: /data/
|
||||
Disallow: /inc-form-handler.php
|
||||
Disallow: /inc/analytics.php
|
||||
|
||||
Sitemap: https://aegisone.ru/sitemap.xml
|
||||
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
/**
|
||||
* ============================================
|
||||
* AegisOne Engineering — SEO-метаданные страниц
|
||||
* ============================================
|
||||
*
|
||||
* Массив $SEO содержит title, description, h1 и keywords
|
||||
* для каждой страницы сайта. Ключ массива = pageKey.
|
||||
*
|
||||
* Формат:
|
||||
* 'page-key' => [
|
||||
* 'title' => '...', // <title> (макс. 60 символов для Google)
|
||||
* 'description' => '...', // <meta name="description"> (макс. 160 символов)
|
||||
* 'h1' => '...', // Заголовок <h1> на странице
|
||||
* 'keywords' => '...', // <meta name="keywords"> (через запятую)
|
||||
* ],
|
||||
*/
|
||||
|
||||
$SEO = [
|
||||
|
||||
// ============================================
|
||||
// Главная страница
|
||||
// ============================================
|
||||
'main' => [
|
||||
'title' => 'AegisOne Engineering — инженерные решения для безопасности бизнеса | Краснодар',
|
||||
'description' => 'Аудит, сервисное обслуживание (SLA), технический надзор, реагирование на инциденты и документация систем безопасности в Краснодаре и ЮФО. Снижаем риски, обеспечиваем стабильность.',
|
||||
'h1' => 'Инженерные решения для безопасности вашего бизнеса',
|
||||
'keywords' => 'безопасность бизнеса, аудит безопасности, SLA сервисное обслуживание, технический надзор, incident response, документация систем безопасности, Краснодар, ЮФО',
|
||||
],
|
||||
|
||||
// ============================================
|
||||
// Аудит безопасности
|
||||
// ============================================
|
||||
'audit' => [
|
||||
'title' => 'Независимый аудит безопасности в Краснодаре | Заказать аудит систем безопасности | AegisOne',
|
||||
'description' => 'Профессиональный независимый аудит систем безопасности в Краснодаре. Аудит видеонаблюдения, СКУД, охранно-пожарных систем. Объективная оценка рисков и уязвимостей для вашего бизнеса.',
|
||||
'h1' => 'Независимый аудит безопасности<br>Краснодар и ЮФО',
|
||||
'keywords' => 'аудит безопасности, независимый аудит, аудит систем безопасности, аудит видеонаблюдения, аудит СКУД, аудит охранно-пожарной сигнализации, заказать аудит, Краснодар',
|
||||
],
|
||||
|
||||
// ============================================
|
||||
// Сервисное обслуживание (SLA)
|
||||
// ============================================
|
||||
'sla' => [
|
||||
'title' => 'Сервисное обслуживание систем безопасности (SLA) | AegisOne Краснодар',
|
||||
'description' => 'Сервисное обслуживание систем безопасности с гарантированным уровнем (SLA). Регулярное ТО, круглосуточный мониторинг, быстрое реагирование. Работаем в Краснодаре и ЮФО.',
|
||||
'h1' => 'Сервисное обслуживание систем безопасности (SLA)',
|
||||
'keywords' => 'сервисное обслуживание систем безопасности, SLA, ТО систем безопасности, обслуживание видеонаблюдения, обслуживание СКУД, Краснодар',
|
||||
],
|
||||
|
||||
// ============================================
|
||||
// Incident Response
|
||||
// ============================================
|
||||
'incident' => [
|
||||
'title' => 'Реагирование на инциденты безопасности | AegisOne Краснодар',
|
||||
'description' => 'Профессиональное реагирование на инциденты безопасности: круглосуточный мониторинг, расследование, устранение последствий. Защитите свой бизнес в Краснодаре и ЮФО.',
|
||||
'h1' => 'Реагирование на инциденты безопасности',
|
||||
'keywords' => 'incident response, реагирование на инциденты, расследование инцидентов, кибербезопасность, Краснодар',
|
||||
],
|
||||
|
||||
// ============================================
|
||||
// Технический надзор
|
||||
// ============================================
|
||||
'supervision' => [
|
||||
'title' => 'Технический надзор за монтажом систем безопасности | AegisOne Краснодар',
|
||||
'description' => 'Технический надзор за строительством и монтажом систем безопасности. Контроль качества, соответствия проекту и нормативам. Краснодар и ЮФО.',
|
||||
'h1' => 'Технический надзор за монтажом систем безопасности',
|
||||
'keywords' => 'технический надзор, строительный контроль, монтаж систем безопасности, надзор за монтажом, Краснодар',
|
||||
],
|
||||
|
||||
// ============================================
|
||||
// Документация и compliance
|
||||
// ============================================
|
||||
'documentation' => [
|
||||
'title' => 'Документация и соответствие нормативам систем безопасности | AegisOne Краснодар',
|
||||
'description' => 'Разработка и экспертиза проектной документации систем безопасности. Аудит соответствия нормативам. Помощь в прохождении проверок. Краснодар и ЮФО.',
|
||||
'h1' => 'Документация и соответствие нормативам систем безопасности',
|
||||
'keywords' => 'документация систем безопасности, соответствие нормативам, проектная документация, нормы безопасности, разрешительная документация, Краснодар',
|
||||
],
|
||||
|
||||
// ============================================
|
||||
// Риск-инжиниринг
|
||||
// ============================================
|
||||
'risk' => [
|
||||
'title' => 'Риск-инжиниринг систем безопасности | AegisOne Краснодар',
|
||||
'description' => 'Оценка рисков, планирование непрерывности бизнеса, разработка стратегии безопасности для вашего бизнеса. Краснодар и ЮФО.',
|
||||
'h1' => 'Риск-инжиниринг систем безопасности',
|
||||
'keywords' => 'риск-инжиниринг, оценка рисков, управление рисками, непрерывность бизнеса, стратегия безопасности, Краснодар',
|
||||
],
|
||||
];
|
||||
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
/**
|
||||
* AegisOne Engineering — PHP-обработчик CSS для сервисной зоны (дашборд)
|
||||
*
|
||||
* Использование: <link rel="stylesheet" href="/service-style.php">
|
||||
*/
|
||||
header('Content-Type: text/css; charset=UTF-8');
|
||||
header('Cache-Control: public, max-age=86400');
|
||||
header('Vary: Accept-Encoding');
|
||||
readfile(__DIR__ . '/service/assets/css/service.css');
|
||||
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
|
||||
require_once __DIR__ . '/../inc/auth.php';
|
||||
$session = auth_require('owner', 'engineer');
|
||||
|
||||
$pdo = getDB();
|
||||
|
||||
$stmt = $pdo->query("SELECT * FROM shs_records ORDER BY id DESC LIMIT 1");
|
||||
$shs = $stmt->fetch();
|
||||
|
||||
echo json_encode($shs ?: ['error' => 'Нет данных']);
|
||||
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
|
||||
require_once __DIR__ . '/../inc/auth.php';
|
||||
$session = auth_require('engineer', 'technician');
|
||||
|
||||
$pdo = getDB();
|
||||
$userId = $session['user_id'];
|
||||
$role = $session['user_role'];
|
||||
|
||||
$sql = "SELECT t.*, o.name as object_name, o.address FROM tasks t JOIN objects o ON o.id=t.object_id WHERE t.status IN ('open','in_progress')";
|
||||
$params = [];
|
||||
|
||||
if ($role === 'technician') {
|
||||
$sql .= " AND t.assigned_to = ?";
|
||||
$params[] = $userId;
|
||||
}
|
||||
|
||||
$sql .= " ORDER BY FIELD(t.priority,'P1','P2','P3','P4'), t.deadline ASC";
|
||||
|
||||
$stmt = $pdo->prepare($sql);
|
||||
$stmt->execute($params);
|
||||
echo json_encode($stmt->fetchAll());
|
||||
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
|
||||
require_once __DIR__ . '/../inc/auth.php';
|
||||
auth_session_start();
|
||||
|
||||
if (empty($_SESSION['user_id'])) {
|
||||
http_response_code(401);
|
||||
echo json_encode(['error' => 'Не авторизован']);
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] !== 'POST' || empty($_FILES['photo'])) {
|
||||
http_response_code(400);
|
||||
echo json_encode(['error' => 'Нет файла']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$taskId = (int)($_POST['task_id'] ?? 0);
|
||||
$reportId = (int)($_POST['report_id'] ?? 0);
|
||||
$type = $_POST['type'] ?? 'other';
|
||||
$desc = trim($_POST['description'] ?? '');
|
||||
|
||||
$uploadDir = __DIR__ . '/../uploads/';
|
||||
if (!is_dir($uploadDir)) {
|
||||
mkdir($uploadDir, 0755, true);
|
||||
}
|
||||
|
||||
$file = $_FILES['photo'];
|
||||
$ext = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
|
||||
$allowed = ['jpg','jpeg','png','gif','webp','heic'];
|
||||
|
||||
if (!in_array($ext, $allowed)) {
|
||||
http_response_code(400);
|
||||
echo json_encode(['error' => 'Недопустимый формат. Разрешены: ' . implode(', ', $allowed)]);
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($file['size'] > 20 * 1024 * 1024) {
|
||||
http_response_code(400);
|
||||
echo json_encode(['error' => 'Файл больше 20MB']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$fileName = uniqid('photo_') . '.' . $ext;
|
||||
$destPath = $uploadDir . $fileName;
|
||||
|
||||
if (!move_uploaded_file($file['tmp_name'], $destPath)) {
|
||||
http_response_code(500);
|
||||
echo json_encode(['error' => 'Ошибка сохранения файла']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$dbPath = '/service/uploads/' . $fileName;
|
||||
|
||||
try {
|
||||
$pdo = getDB();
|
||||
$stmt = $pdo->prepare("INSERT INTO task_photos (task_id, report_id, file_path, description, type, uploaded_by) VALUES (?,?,?,?,?,?)");
|
||||
$stmt->execute([$taskId ?: null, $reportId ?: null, $dbPath, $desc, $type, $_SESSION['user_id']]);
|
||||
echo json_encode(['success' => true, 'path' => $dbPath, 'id' => $pdo->lastInsertId()]);
|
||||
} catch (\Throwable $e) {
|
||||
http_response_code(500);
|
||||
echo json_encode(['error' => 'Ошибка БД: ' . $e->getMessage()]);
|
||||
}
|
||||
@@ -0,0 +1,896 @@
|
||||
@charset "UTF-8";
|
||||
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&family=Montserrat:wght@600;700;800&display=swap');
|
||||
|
||||
:root {
|
||||
--bg-body: #0a0e1a;
|
||||
--bg-card: #131a2e;
|
||||
--bg-card-hover: #1a2340;
|
||||
--bg-sidebar: #0d1322;
|
||||
--bg-input: #1a2340;
|
||||
--border: #1e2a4a;
|
||||
--border-focus: #00ADEF;
|
||||
--text-primary: #e8edf5;
|
||||
--text-secondary: #8899bb;
|
||||
--text-muted: #556688;
|
||||
--accent: #00ADEF;
|
||||
--accent-hover: #33c4f5;
|
||||
--accent-dim: rgba(0, 173, 239, 0.15);
|
||||
--success: #22c55e;
|
||||
--warning: #f59e0b;
|
||||
--danger: #ef4444;
|
||||
--info: #6366f1;
|
||||
--font: 'Inter', 'Segoe UI', sans-serif;
|
||||
--radius: 10px;
|
||||
--shadow: 0 2px 12px rgba(0,0,0,0.3);
|
||||
}
|
||||
|
||||
/* ---------- SCROLLBARS ---------- */
|
||||
::-webkit-scrollbar { width: 6px; height: 6px; }
|
||||
::-webkit-scrollbar-track { background: rgba(255,255,255,0.03); border-radius: 3px; }
|
||||
::-webkit-scrollbar-thumb { background: rgba(0,173,239,0.3); border-radius: 3px; transition: background 0.2s; }
|
||||
::-webkit-scrollbar-thumb:hover { background: rgba(0,173,239,0.5); }
|
||||
* { scrollbar-width: thin; scrollbar-color: rgba(0,173,239,0.3) rgba(255,255,255,0.03); }
|
||||
|
||||
* { margin:0; padding:0; box-sizing:border-box; }
|
||||
|
||||
html, body {
|
||||
font-family: var(--font);
|
||||
background: var(--bg-body);
|
||||
color: var(--text-primary);
|
||||
font-size: 14px;
|
||||
line-height: 1.5;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
a { color: var(--accent); text-decoration:none; }
|
||||
a:hover { color: var(--accent-hover); }
|
||||
img { max-width:100%; height:auto; }
|
||||
|
||||
/* ---------- LOGIN PAGE ---------- */
|
||||
.login-page {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-height: 100vh;
|
||||
background: linear-gradient(135deg, #0a0e1a 0%, #0d1a30 50%, #0a0e1a 100%);
|
||||
}
|
||||
|
||||
.login-box {
|
||||
background: var(--bg-card);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: var(--radius);
|
||||
padding: 36px 32px;
|
||||
width: 100%;
|
||||
max-width: 400px;
|
||||
box-shadow: var(--shadow);
|
||||
}
|
||||
|
||||
.login-brand {
|
||||
text-align: center;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.login-brand__img {
|
||||
display: block;
|
||||
height: 56px;
|
||||
margin: 0 auto 16px;
|
||||
}
|
||||
|
||||
.login-brand__title {
|
||||
font-family: 'Montserrat', sans-serif;
|
||||
font-weight: 800;
|
||||
font-size: 24px;
|
||||
color: var(--text-primary);
|
||||
letter-spacing: -0.02em;
|
||||
line-height: 1.1;
|
||||
}
|
||||
|
||||
.login-brand__subtitle {
|
||||
font-family: 'Inter', sans-serif;
|
||||
font-weight: 500;
|
||||
font-size: 10px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.2em;
|
||||
color: var(--accent);
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.login-divider {
|
||||
border: none;
|
||||
border-top: 1px solid var(--border);
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.login-box h1 {
|
||||
font-size: 20px;
|
||||
font-weight: 700;
|
||||
margin-bottom: 24px;
|
||||
color: var(--text-primary);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.login-box__footnote {
|
||||
margin-top: 24px;
|
||||
font-size: 11px;
|
||||
color: var(--text-muted);
|
||||
text-align: center;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.form-group {
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
|
||||
.form-group label {
|
||||
display: block;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
color: var(--text-secondary);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5px;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.form-group input,
|
||||
.form-group select,
|
||||
.form-group textarea {
|
||||
width: 100%;
|
||||
padding: 10px 14px;
|
||||
background: var(--bg-input);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 6px;
|
||||
color: var(--text-primary);
|
||||
font-family: var(--font);
|
||||
font-size: 14px;
|
||||
transition: border 0.2s;
|
||||
}
|
||||
|
||||
.form-group input:focus,
|
||||
.form-group select:focus,
|
||||
.form-group textarea:focus {
|
||||
outline: none;
|
||||
border-color: var(--border-focus);
|
||||
box-shadow: 0 0 0 3px var(--accent-dim);
|
||||
}
|
||||
|
||||
.form-group textarea {
|
||||
min-height: 80px;
|
||||
resize: vertical;
|
||||
}
|
||||
|
||||
.btn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
padding: 10px 20px;
|
||||
border: none;
|
||||
border-radius: 6px;
|
||||
font-family: var(--font);
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background: var(--accent);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
background: var(--accent-hover);
|
||||
}
|
||||
|
||||
.btn-secondary {
|
||||
background: var(--bg-input);
|
||||
color: var(--text-primary);
|
||||
border: 1px solid var(--border);
|
||||
}
|
||||
|
||||
.btn-secondary:hover {
|
||||
border-color: var(--accent);
|
||||
}
|
||||
|
||||
.btn-success {
|
||||
background: var(--success);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.btn-danger {
|
||||
background: var(--danger);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.btn-warning {
|
||||
background: var(--warning);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.btn-sm {
|
||||
padding: 5px 12px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.btn-block {
|
||||
width: 100%;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.alert {
|
||||
padding: 12px 16px;
|
||||
border-radius: 6px;
|
||||
font-size: 13px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.alert-error {
|
||||
background: rgba(239, 68, 68, 0.15);
|
||||
color: var(--danger);
|
||||
border: 1px solid rgba(239, 68, 68, 0.3);
|
||||
}
|
||||
|
||||
.alert-success {
|
||||
background: rgba(34, 197, 94, 0.15);
|
||||
color: var(--success);
|
||||
border: 1px solid rgba(34, 197, 94, 0.3);
|
||||
}
|
||||
|
||||
.alert-warning {
|
||||
background: rgba(245, 158, 11, 0.15);
|
||||
color: var(--warning);
|
||||
border: 1px solid rgba(245, 158, 11, 0.3);
|
||||
}
|
||||
|
||||
.alert-info {
|
||||
background: rgba(99, 102, 241, 0.15);
|
||||
color: var(--info);
|
||||
border: 1px solid rgba(99, 102, 241, 0.3);
|
||||
}
|
||||
|
||||
/* ---------- LAYOUT ---------- */
|
||||
.layout {
|
||||
display: flex;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
width: 240px;
|
||||
background: var(--bg-sidebar);
|
||||
border-right: 1px solid var(--border);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 100vh;
|
||||
z-index: 100;
|
||||
transition: transform 0.3s;
|
||||
}
|
||||
|
||||
.sidebar-header {
|
||||
padding: 20px;
|
||||
border-bottom: 1px solid var(--border);
|
||||
}
|
||||
|
||||
.sidebar-header .logo {
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.sidebar-header .logo span {
|
||||
color: var(--accent);
|
||||
}
|
||||
|
||||
.sidebar-nav {
|
||||
flex: 1;
|
||||
padding: 12px 0;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.sidebar-nav a {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding: 10px 20px;
|
||||
color: var(--text-secondary);
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.sidebar-nav a:hover,
|
||||
.sidebar-nav a.active {
|
||||
color: var(--text-primary);
|
||||
background: var(--accent-dim);
|
||||
}
|
||||
|
||||
.sidebar-nav a.active {
|
||||
border-right: 3px solid var(--accent);
|
||||
}
|
||||
|
||||
.sidebar-section {
|
||||
padding: 8px 20px 4px;
|
||||
font-size: 10px;
|
||||
font-weight: 700;
|
||||
color: var(--text-muted);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
|
||||
.sidebar-footer {
|
||||
padding: 16px 20px;
|
||||
border-top: 1px solid var(--border);
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.sidebar-footer .user-name {
|
||||
color: var(--text-primary);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.sidebar-footer .user-role {
|
||||
color: var(--text-muted);
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.sidebar-toggle {
|
||||
display: none;
|
||||
position: fixed;
|
||||
top: 12px;
|
||||
left: 12px;
|
||||
z-index: 101;
|
||||
background: var(--bg-card);
|
||||
border: 1px solid var(--border);
|
||||
color: var(--text-primary);
|
||||
padding: 8px 12px;
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.main {
|
||||
flex: 1;
|
||||
margin-left: 240px;
|
||||
padding: 24px;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.main-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.main-header h1 {
|
||||
font-size: 24px;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.main-header .breadcrumb {
|
||||
font-size: 12px;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
|
||||
.main-header .breadcrumb a {
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
.main-header .breadcrumb a:hover {
|
||||
color: var(--accent);
|
||||
}
|
||||
|
||||
/* ---------- CARDS ---------- */
|
||||
.card {
|
||||
background: var(--bg-card);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: var(--radius);
|
||||
padding: 20px;
|
||||
margin-bottom: 16px;
|
||||
transition: box-shadow 0.2s;
|
||||
}
|
||||
|
||||
.card:hover {
|
||||
box-shadow: var(--shadow);
|
||||
}
|
||||
|
||||
.card-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
|
||||
.card-header h2,
|
||||
.card-header h3 {
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.card-value {
|
||||
font-size: 28px;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.card-label {
|
||||
font-size: 12px;
|
||||
color: var(--text-secondary);
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.card-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
|
||||
gap: 16px;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
/* ---------- KPI VALUES ---------- */
|
||||
.value-green { color: var(--success); }
|
||||
.value-yellow { color: var(--warning); }
|
||||
.value-red { color: var(--danger); }
|
||||
.value-accent { color: var(--accent); }
|
||||
.value-info { color: var(--info); }
|
||||
|
||||
/* ---------- TABLES ---------- */
|
||||
.table-wrap {
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
table th {
|
||||
text-align: left;
|
||||
padding: 10px 12px;
|
||||
font-size: 11px;
|
||||
font-weight: 700;
|
||||
color: var(--text-muted);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5px;
|
||||
border-bottom: 1px solid var(--border);
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
table td {
|
||||
padding: 10px 12px;
|
||||
font-size: 13px;
|
||||
border-bottom: 1px solid var(--border);
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
table tr:hover td {
|
||||
background: rgba(0, 173, 239, 0.03);
|
||||
}
|
||||
|
||||
table .actions {
|
||||
white-space: nowrap;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
table .actions a,
|
||||
table .actions button {
|
||||
margin-left: 6px;
|
||||
}
|
||||
|
||||
/* ---------- BADGES ---------- */
|
||||
.badge {
|
||||
display: inline-block;
|
||||
padding: 2px 8px;
|
||||
border-radius: 4px;
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.badge-critical { background: rgba(239,68,68,0.2); color: var(--danger); }
|
||||
.badge-high { background: rgba(245,158,11,0.2); color: var(--warning); }
|
||||
.badge-medium { background: rgba(99,102,241,0.2); color: var(--info); }
|
||||
.badge-low { background: rgba(136,153,187,0.2); color: var(--text-secondary); }
|
||||
.badge-open { background: rgba(99,102,241,0.2); color: var(--info); }
|
||||
.badge-progress { background: rgba(245,158,11,0.2); color: var(--warning); }
|
||||
.badge-done { background: rgba(34,197,94,0.2); color: var(--success); }
|
||||
.badge-cancelled { background: rgba(239,68,68,0.2); color: var(--danger); }
|
||||
.badge-active { background: rgba(34,197,94,0.2); color: var(--success); }
|
||||
.badge-inactive { background: rgba(136,153,187,0.2); color: var(--text-secondary); }
|
||||
.badge-draft { background: rgba(136,153,187,0.2); color: var(--text-secondary); }
|
||||
.badge-risk { background: rgba(245,158,11,0.2); color: var(--warning); }
|
||||
.badge-crisis { background: rgba(239,68,68,0.2); color: var(--danger); }
|
||||
.badge-stable { background: rgba(99,102,241,0.2); color: var(--info); }
|
||||
.badge-growth { background: rgba(34,197,94,0.2); color: var(--success); }
|
||||
.badge-default { background: rgba(136,153,187,0.2); color: var(--text-secondary); }
|
||||
|
||||
/* ---------- MODAL ---------- */
|
||||
.modal-overlay {
|
||||
position: fixed;
|
||||
top: 0; left: 0; right: 0; bottom: 0;
|
||||
background: rgba(0,0,0,0.6);
|
||||
display: none;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 200;
|
||||
}
|
||||
|
||||
.modal-overlay.open {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.modal {
|
||||
background: var(--bg-card);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: var(--radius);
|
||||
padding: 28px;
|
||||
width: 100%;
|
||||
max-width: 540px;
|
||||
max-height: 80vh;
|
||||
overflow-y: auto;
|
||||
box-shadow: 0 8px 40px rgba(0,0,0,0.5);
|
||||
}
|
||||
|
||||
.modal h2 {
|
||||
font-size: 18px;
|
||||
font-weight: 700;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.modal-close {
|
||||
float: right;
|
||||
background: none;
|
||||
border: none;
|
||||
color: var(--text-muted);
|
||||
font-size: 20px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* ---------- TABS ---------- */
|
||||
.tabs {
|
||||
display: flex;
|
||||
border-bottom: 1px solid var(--border);
|
||||
margin-bottom: 20px;
|
||||
gap: 0;
|
||||
}
|
||||
|
||||
.tabs a {
|
||||
padding: 10px 20px;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
color: var(--text-secondary);
|
||||
border-bottom: 2px solid transparent;
|
||||
margin-bottom: -1px;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.tabs a:hover,
|
||||
.tabs a.active {
|
||||
color: var(--accent);
|
||||
border-bottom-color: var(--accent);
|
||||
}
|
||||
|
||||
/* ---------- PAGINATION ---------- */
|
||||
.pagination {
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
justify-content: center;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.pagination a,
|
||||
.pagination span {
|
||||
padding: 6px 12px;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 4px;
|
||||
color: var(--text-secondary);
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.pagination a:hover {
|
||||
border-color: var(--accent);
|
||||
color: var(--accent);
|
||||
}
|
||||
|
||||
.pagination .current {
|
||||
background: var(--accent);
|
||||
color: #fff;
|
||||
border-color: var(--accent);
|
||||
}
|
||||
|
||||
/* ---------- SEARCH ---------- */
|
||||
.search-box {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.search-box input {
|
||||
flex: 1;
|
||||
padding: 8px 14px;
|
||||
background: var(--bg-input);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 6px;
|
||||
color: var(--text-primary);
|
||||
font-family: var(--font);
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.search-box input:focus {
|
||||
outline: none;
|
||||
border-color: var(--border-focus);
|
||||
}
|
||||
|
||||
/* ---------- PROGRESS ---------- */
|
||||
.progress-bar {
|
||||
height: 6px;
|
||||
background: rgba(255,255,255,0.08);
|
||||
border-radius: 3px;
|
||||
overflow: hidden;
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.progress-fill {
|
||||
height: 100%;
|
||||
border-radius: 3px;
|
||||
transition: width 0.4s;
|
||||
}
|
||||
|
||||
/* ---------- FORM INLINE ---------- */
|
||||
.form-row {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
|
||||
gap: 14px;
|
||||
}
|
||||
|
||||
.form-check {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.form-check input[type="checkbox"],
|
||||
.form-check input[type="radio"] {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
/* ---------- FILTER BAR ---------- */
|
||||
.filter-bar {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
flex-wrap: wrap;
|
||||
margin-bottom: 16px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.filter-bar select,
|
||||
.filter-bar input {
|
||||
padding: 6px 10px;
|
||||
background: var(--bg-input);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 6px;
|
||||
color: var(--text-primary);
|
||||
font-family: var(--font);
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
/* ---------- QUESTIONNAIRE ---------- */
|
||||
.questionnaire-step {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.questionnaire-step.active {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.step-indicators {
|
||||
display: flex;
|
||||
gap: 0;
|
||||
margin-bottom: 28px;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.step-dot {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
padding: 8px 14px;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
color: var(--text-muted);
|
||||
border-bottom: 2px solid var(--border);
|
||||
white-space: nowrap;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.step-dot.completed {
|
||||
color: var(--success);
|
||||
border-bottom-color: var(--success);
|
||||
}
|
||||
|
||||
.step-dot.active {
|
||||
color: var(--accent);
|
||||
border-bottom-color: var(--accent);
|
||||
}
|
||||
|
||||
/* ---------- SHS ALERT ---------- */
|
||||
.shs-alert {
|
||||
padding: 12px 16px;
|
||||
border-radius: 6px;
|
||||
margin-bottom: 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.shs-alert.warning {
|
||||
background: rgba(245,158,11,0.15);
|
||||
color: var(--warning);
|
||||
border: 1px solid rgba(245,158,11,0.3);
|
||||
}
|
||||
|
||||
.shs-alert.critical {
|
||||
background: rgba(239,68,68,0.15);
|
||||
color: var(--danger);
|
||||
border: 1px solid rgba(239,68,68,0.3);
|
||||
}
|
||||
|
||||
/* ---------- RESPONSIVE ---------- */
|
||||
@media (max-width: 768px) {
|
||||
.sidebar {
|
||||
transform: translateX(-100%);
|
||||
}
|
||||
.sidebar.open {
|
||||
transform: translateX(0);
|
||||
}
|
||||
.sidebar-toggle {
|
||||
display: block;
|
||||
}
|
||||
.main {
|
||||
margin-left: 0;
|
||||
padding: 16px;
|
||||
padding-top: 56px;
|
||||
}
|
||||
.card-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
.form-row {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
.login-box {
|
||||
margin: 16px;
|
||||
padding: 24px;
|
||||
}
|
||||
.tabs {
|
||||
overflow-x: auto;
|
||||
}
|
||||
.step-indicators {
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
/* ---------- PRINT ---------- */
|
||||
@media print {
|
||||
.sidebar, .sidebar-toggle, .main-header .actions { display: none; }
|
||||
.main { margin-left: 0; }
|
||||
.card { break-inside: avoid; }
|
||||
}
|
||||
|
||||
/* ---------- TOAST ---------- */
|
||||
.toast-container {
|
||||
position: fixed;
|
||||
top: 20px;
|
||||
right: 20px;
|
||||
z-index: 999;
|
||||
}
|
||||
|
||||
.toast {
|
||||
padding: 12px 20px;
|
||||
border-radius: 6px;
|
||||
margin-bottom: 8px;
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
box-shadow: 0 4px 20px rgba(0,0,0,0.4);
|
||||
animation: slideIn 0.3s ease;
|
||||
}
|
||||
|
||||
.toast-success { background: var(--success); color: #fff; }
|
||||
.toast-error { background: var(--danger); color: #fff; }
|
||||
.toast-warning { background: var(--warning); color: #fff; }
|
||||
.toast-info { background: var(--info); color: #fff; }
|
||||
|
||||
@keyframes slideIn {
|
||||
from { transform: translateX(100%); opacity: 0; }
|
||||
to { transform: translateX(0); opacity: 1; }
|
||||
}
|
||||
|
||||
/* ---------- TOOLTIPS ---------- */
|
||||
[data-tooltip] {
|
||||
position: relative;
|
||||
}
|
||||
[data-tooltip]::after {
|
||||
content: attr(data-tooltip);
|
||||
position: absolute;
|
||||
bottom: calc(100% + 8px);
|
||||
left: 50%;
|
||||
transform: translateX(-50%) translateY(4px);
|
||||
background: #1a1a2e;
|
||||
color: #e8edf5;
|
||||
padding: 6px 10px;
|
||||
border-radius: 6px;
|
||||
font-size: 11px;
|
||||
font-weight: 500;
|
||||
white-space: nowrap;
|
||||
pointer-events: none;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
transition: opacity 0.2s, transform 0.2s, visibility 0.2s;
|
||||
z-index: 1000;
|
||||
box-shadow: 0 2px 8px rgba(0,0,0,0.3);
|
||||
}
|
||||
[data-tooltip]::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: calc(100% + 2px);
|
||||
left: 50%;
|
||||
transform: translateX(-50%) translateY(4px);
|
||||
border: 5px solid transparent;
|
||||
border-top-color: #1a1a2e;
|
||||
pointer-events: none;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
transition: opacity 0.2s, transform 0.2s, visibility 0.2s;
|
||||
z-index: 1000;
|
||||
}
|
||||
[data-tooltip]:hover::after,
|
||||
[data-tooltip]:hover::before {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
transform: translateX(-50%) translateY(0);
|
||||
}
|
||||
|
||||
/* ---------- EMPTY STATE ---------- */
|
||||
.empty-state {
|
||||
text-align: center;
|
||||
padding: 48px 20px;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
|
||||
.empty-state svg {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
margin-bottom: 16px;
|
||||
opacity: 0.4;
|
||||
}
|
||||
|
||||
.empty-state h3 {
|
||||
font-size: 16px;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.empty-state p {
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
/* ---------- LOADING ---------- */
|
||||
.loading {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 40px;
|
||||
}
|
||||
|
||||
.spinner {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border: 3px solid var(--border);
|
||||
border-top-color: var(--accent);
|
||||
border-radius: 50%;
|
||||
animation: spin 0.8s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
to { transform: rotate(360deg); }
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/inc/auth.php';
|
||||
$session = auth_require();
|
||||
$role = $session['user_role'];
|
||||
$pdo = getDB();
|
||||
|
||||
// Common stats
|
||||
$stats = [];
|
||||
|
||||
// Total objects
|
||||
$stmt = $pdo->query("SELECT COUNT(*) FROM objects WHERE status='active'");
|
||||
$stats['objects'] = $stmt->fetchColumn();
|
||||
|
||||
// Active tasks
|
||||
$stmt = $pdo->query("SELECT COUNT(*) FROM tasks WHERE status IN ('open','in_progress')");
|
||||
$stats['tasks'] = $stmt->fetchColumn();
|
||||
|
||||
// Open incidents
|
||||
$stmt = $pdo->query("SELECT COUNT(*) FROM incidents WHERE status IN ('open','in_progress')");
|
||||
$stats['incidents'] = $stmt->fetchColumn();
|
||||
|
||||
// Active SLA contracts
|
||||
$stmt = $pdo->query("SELECT COUNT(*) FROM sla_contracts WHERE status='active'");
|
||||
$stats['sla_count'] = $stmt->fetchColumn();
|
||||
|
||||
// Latest SHS
|
||||
$stmt = $pdo->query("SELECT shs_score, shs_status FROM shs_records ORDER BY id DESC LIMIT 1");
|
||||
$stats['shs'] = $stmt->fetch();
|
||||
|
||||
// Engineer-specific: tasks assigned to me
|
||||
if ($role === 'engineer' || $role === 'technician') {
|
||||
$stmt = $pdo->prepare("SELECT COUNT(*) FROM tasks WHERE assigned_to = ? AND status IN ('open','in_progress')");
|
||||
$stmt->execute([$session['user_id']]);
|
||||
$stats['my_tasks'] = $stmt->fetchColumn();
|
||||
}
|
||||
|
||||
// SLA compliance (overall)
|
||||
$stmt = $pdo->query("SELECT COUNT(*) as total, SUM(CASE WHEN sla_compliant=TRUE THEN 1 ELSE 0 END) as compliant FROM tasks WHERE closed_at IS NOT NULL");
|
||||
$slaData = $stmt->fetch();
|
||||
$stats['sla_compliance'] = $slaData['total'] > 0 ? round(($slaData['compliant'] / $slaData['total']) * 100, 1) : 0;
|
||||
|
||||
$shsAlert = null;
|
||||
if ($stats['shs'] && $stats['shs']['shs_score'] < 70) {
|
||||
$shsAlert = 'SHS ниже 70 (' . $stats['shs']['shs_score'] . ') — ' . $stats['shs']['shs_status'];
|
||||
}
|
||||
|
||||
require __DIR__ . '/inc/header.php';
|
||||
?>
|
||||
|
||||
<div class="main-header">
|
||||
<div>
|
||||
<h1>Дашборд</h1>
|
||||
<div class="breadcrumb"><a href="/service/dashboard.php">Главная</a></div>
|
||||
</div>
|
||||
<div class="actions">
|
||||
<span style="font-size:12px;color:var(--text-muted);"><?= date('d.m.Y H:i') ?></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php if ($shsAlert): ?>
|
||||
<div class="shs-alert critical">⚠ <?= htmlspecialchars($shsAlert) ?></div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="card-grid">
|
||||
<a href="/service/pages/owner/objects.php" class="card card-link">
|
||||
<div class="card-label">Активные объекты</div>
|
||||
<div class="card-value value-accent"><?= $stats['objects'] ?></div>
|
||||
</a>
|
||||
<a href="/service/pages/engineer/tasks.php" class="card card-link">
|
||||
<div class="card-label">Активные задачи</div>
|
||||
<div class="card-value <?= $stats['tasks'] > 0 ? 'value-yellow' : 'value-green' ?>"><?= $stats['tasks'] ?></div>
|
||||
</a>
|
||||
<a href="/service/pages/engineer/incidents.php" class="card card-link">
|
||||
<div class="card-label">Открытые инциденты</div>
|
||||
<div class="card-value <?= $stats['incidents'] > 0 ? 'value-red' : 'value-green' ?>"><?= $stats['incidents'] ?></div>
|
||||
</a>
|
||||
<a href="/service/pages/owner/sla.php" class="card card-link">
|
||||
<div class="card-label">SLA контракты</div>
|
||||
<div class="card-value value-info"><?= $stats['sla_count'] ?></div>
|
||||
</a>
|
||||
<a href="/service/pages/owner/sla.php" class="card card-link">
|
||||
<div class="card-label">SLA Compliance</div>
|
||||
<div class="card-value <?= $stats['sla_compliance'] >= 90 ? 'value-green' : ($stats['sla_compliance'] >= 70 ? 'value-yellow' : 'value-red') ?>"><?= $stats['sla_compliance'] ?>%</div>
|
||||
</a>
|
||||
<?php if ($stats['shs']): ?>
|
||||
<a href="/service/pages/owner/ceo.php" class="card card-link">
|
||||
<div class="card-label">SHS (System Health)</div>
|
||||
<div class="card-value <?= $stats['shs']['shs_status'] === 'Growth' || $stats['shs']['shs_status'] === 'Stable' ? 'value-green' : 'value-red' ?>"><?= $stats['shs']['shs_score'] ?></div>
|
||||
<div class="card-label"><span class="badge badge-<?= strtolower($stats['shs']['shs_status']) ?>"><?= $stats['shs']['shs_status'] ?></span></div>
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($stats['my_tasks'])): ?>
|
||||
<a href="/service/pages/engineer/tasks.php" class="card card-link">
|
||||
<div class="card-label">Мои задачи</div>
|
||||
<div class="card-value"><?= $stats['my_tasks'] ?></div>
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
require __DIR__ . '/inc/footer.php';
|
||||
?>
|
||||
<style>
|
||||
.card-link { text-decoration:none; color:inherit; display:block; transition:transform 0.2s, box-shadow 0.2s; }
|
||||
.card-link:hover { transform:translateY(-2px); box-shadow:var(--shadow); cursor:pointer; }
|
||||
</style>
|
||||
@@ -0,0 +1,836 @@
|
||||
# AegisOne Engineering — План миграции инфраструктуры и переписывания сервисной части
|
||||
|
||||
> **Статус:** План утверждён, готов к реализации
|
||||
> **Дата:** 2026-05-17
|
||||
> **Команда:** Владелец + AI-ассистент
|
||||
> **Примечание:** Если при реализации возникнут вопросы — лучше уточнить, чем переделывать потом.
|
||||
|
||||
---
|
||||
|
||||
## 1. Текущее состояние
|
||||
|
||||
### 1.1. Публичная часть (aegisone.ru)
|
||||
- **Технологии:** PHP 7.4, MySQL, inline CSS/JS
|
||||
- **Хостинг:** Shared-хостинг (проблемы: HTTP 302-редирект, блокировка `/assets/`, отключённый `RewriteEngine`, PHP 7.4 тупик)
|
||||
- **Страницы:** Главная, услуги, блог, контакты, форма обратной связи
|
||||
- **SEO:** `robots.txt`, `sitemap.xml`, канонические URL
|
||||
- **Решение:** **Не трогать.** Перенести на VPS как есть в Docker-контейнер.
|
||||
|
||||
### 1.2. Сервисная часть (service.aegisone.ru)
|
||||
- **Технологии:** PHP 7.4, MySQL, inline CSS/JS
|
||||
- **Функционал:** Админ-панель (управление пользователями, объектами, SLA, опросниками, блогом, документами), расчёты (Risk Score, Object Index, SLA price), паспорта объектов
|
||||
- **Проблемы:** PHP 7.4 ограничивает развитие, нет автоматизации отчётов, нет интеграций
|
||||
- **Решение:** **Полностью переписать на Python/FastAPI + Jinja2**
|
||||
|
||||
### 1.3. Инфраструктура
|
||||
- **VPS:** Уже есть, на нём один проект (FastAPI + Uvicorn + Celery + Nginx + PostgreSQL + Redis + Alembic)
|
||||
- **Хостинг:** Платный, планируется отказ
|
||||
- **Git:** Нет централизованного сервера, работа на локальной машине
|
||||
- **SSL:** От регистратора домена (статический, неудобно для мультидомена)
|
||||
- **Домены:** `aegisone.ru` (публичная часть), планируется `service.aegisone.ru` (админка)
|
||||
|
||||
---
|
||||
|
||||
## 2. Целевая архитектура
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────────┐
|
||||
│ VPS │
|
||||
│ │
|
||||
│ ┌───────────────────────────────────────────────────────────────┐ │
|
||||
│ │ Nginx (reverse proxy + SSL) │ │
|
||||
│ │ порт 80/443, Let's Encrypt │ │
|
||||
│ │ │ │
|
||||
│ │ aegisone.ru ──────────────► php-fpm container (порт 9000) │ │
|
||||
│ │ service.aegisone.ru ─────► fastapi container (порт 8000) │ │
|
||||
│ │ other-project.ru ────────► project2 container (порт 8001) │ │
|
||||
│ │ git.aegisone.ru ─────────► gitea container (порт 3000) │ │
|
||||
│ └───────────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐ │
|
||||
│ │ AegisOne PHP │ │ AegisOne Python │ │ Other Project │ │
|
||||
│ │ (публичная) │ │ (админка) │ │ (FastAPI) │ │
|
||||
│ │ │ │ │ │ │ │
|
||||
│ │ • Главная │ │ • Аутентификация│ │ • ... │ │
|
||||
│ │ • Услуги │ │ • Пользователи │ │ │ │
|
||||
│ │ • Блог │ │ • Объекты │ │ │ │
|
||||
│ │ • Контакты │ │ • Клиенты │ │ │ │
|
||||
│ │ • FAQ │ │ • SLA │ │ │ │
|
||||
│ │ • Карусель │ │ • Опросники │ │ │ │
|
||||
│ │ • Форма │ │ • Расчёты │ │ │ │
|
||||
│ │ │ │ • Отчёты (PDF) │ │ │ │
|
||||
│ │ │ │ • Документы │ │ │ │
|
||||
│ │ │ │ • Yandex Disk │ │ │ │
|
||||
│ └────────┬─────────┘ └────────┬─────────┘ └────────┬─────────┘ │
|
||||
│ │ │ │ │
|
||||
│ └──────────┬──────────┘ │ │
|
||||
│ │ │ │
|
||||
│ ┌──────────▼──────────┐ ┌─────────▼────────┐ │
|
||||
│ │ PostgreSQL │ │ PostgreSQL │ │
|
||||
│ │ (AegisOne БД) │ │ (Project 2 БД) │ │
|
||||
│ │ │ │ │ │
|
||||
│ │ • users │ │ • ... │ │
|
||||
│ │ • customers │ │ │ │
|
||||
│ │ • objects │ │ │ │
|
||||
│ │ • sla_contracts │ │ │ │
|
||||
│ │ • questionnaire_* │ │ │ │
|
||||
│ │ • blog_posts │ │ │ │
|
||||
│ │ • cases │ │ │ │
|
||||
│ │ • documents │ │ │ │
|
||||
│ │ • photos │ │ │ │
|
||||
│ │ • audit_log │ │ │ │
|
||||
│ └─────────────────────┘ └──────────────────┘ │
|
||||
│ │ │
|
||||
│ ┌──────────▼──────────┐ │
|
||||
│ │ Redis │ (кэш, Celery broker) │
|
||||
│ └─────────────────────┘ │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────────┐ │
|
||||
│ │ Celery Workers (Python) │ │
|
||||
│ │ │ │
|
||||
│ │ • Генерация отчётов (PDF, Excel) │ │
|
||||
│ │ • Загрузка фото на Yandex Disk │ │
|
||||
│ │ • Интеграция с 1С (по мере необходимости) │ │
|
||||
│ │ • Фоновые расчёты, уведомления │ │
|
||||
│ └─────────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌──────────────────┐ ┌──────────────────┐ │
|
||||
│ │ Gitea │ │ Certbot │ │
|
||||
│ │ (Git-сервер) │ │ (Let's Encrypt) │ │
|
||||
│ │ │ │ │ │
|
||||
│ │ • aegisone-php │ │ • aegisone.ru │ │
|
||||
│ │ • aegisone-py │ │ • service.aeg.. │ │
|
||||
│ │ • project2 │ │ • other.ru │ │
|
||||
│ │ • CI/CD Actions │ │ • автообновление│ │
|
||||
│ └──────────────────┘ └──────────────────┘ │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────────┐ │
|
||||
│ │ Yandex Disk API (облачное хранилище) │ │
|
||||
│ │ │ │
|
||||
│ │ /AegisOne/ │ │
|
||||
│ │ ├── objects/{object_id}/ │ │
|
||||
│ │ │ ├── photos/{photo_id}.jpg │ │
|
||||
│ │ │ └── documents/{doc_id}/ │ │
|
||||
│ │ │ ├── {photo_id}.jpg │ │
|
||||
│ │ │ └── report_{doc_id}.pdf │ │
|
||||
│ │ └── ... │ │
|
||||
│ │ │ │
|
||||
│ │ В PostgreSQL хранятся: file_id, file_url, привязка к объекту│ │
|
||||
│ └─────────────────────────────────────────────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Технологический стек
|
||||
|
||||
### 3.1. Публичная часть (без изменений)
|
||||
| Компонент | Технология | Примечание |
|
||||
|---|---|---|
|
||||
| Язык | PHP 7.4 | Не обновлять, не трогать |
|
||||
| БД | MySQL | Мигрировать на PostgreSQL позже (опционально) |
|
||||
| Веб-сервер | Nginx + PHP-FPM | В Docker-контейнере |
|
||||
| CSS/JS | Inline | Без изменений |
|
||||
|
||||
### 3.2. Сервисная часть (Python)
|
||||
| Компонент | Технология | Примечание |
|
||||
|---|---|---|
|
||||
| Язык | Python 3.11+ | |
|
||||
| Фреймворк | FastAPI | REST API + серверный рендеринг |
|
||||
| Шаблоны | Jinja2 | Серверный рендеринг, как сейчас PHP |
|
||||
| Веб-сервер | Uvicorn | ASGI-сервер |
|
||||
| ORM | SQLAlchemy 2.0 + Alembic | Миграции БД |
|
||||
| БД | PostgreSQL 15+ | Единая БД для всех проектов |
|
||||
| Аутентификация | JWT (python-jose) | Токены для API и сессий |
|
||||
| Фоновые задачи | Celery + Redis | Отчёты, загрузка файлов, интеграции |
|
||||
| Генерация отчётов | WeasyPrint (PDF), openpyxl (Excel) | |
|
||||
| Yandex Disk | yandex-disk SDK / REST API | OAuth 2.0 |
|
||||
| Валидация | Pydantic | Схемы данных |
|
||||
|
||||
### 3.3. Инфраструктура
|
||||
| Компонент | Технология | Примечание |
|
||||
|---|---|---|
|
||||
| Контейнеризация | Docker + Docker Compose | |
|
||||
| Reverse proxy | Nginx | Маршрутизация по доменам |
|
||||
| SSL | Let's Encrypt + Certbot | Автообновление |
|
||||
| Git-сервер | Gitea | Лёгкий, встроенный CI/CD |
|
||||
| CI/CD | Gitea Actions | Автоматический деплой |
|
||||
| Мониторинг | (опционально) Uptime Kuma | |
|
||||
|
||||
### 3.4. Мобильные приложения (будущее)
|
||||
| Компонент | Технология | Примечание |
|
||||
|---|---|---|
|
||||
| Фреймворк | Flutter | |
|
||||
| API | FastAPI REST endpoints | Те же, что для веб-админки |
|
||||
| Аутентификация | JWT | |
|
||||
|
||||
---
|
||||
|
||||
## 4. Почему Jinja2, а не SPA
|
||||
|
||||
### 4.1. Сравнение
|
||||
|
||||
| Критерий | Jinja2 (SSR) | SPA (React/Vue) |
|
||||
|---|---|---|
|
||||
| Серверная нагрузка | Рендерит HTML на сервере | Отдаёт статику + JSON API |
|
||||
| Масштабирование | Горизонтальное: Nginx → N FastAPI инстансов | CDN для статики + Nginx → API |
|
||||
| Сложность разработки | Один стек, один деплой | Два стека, два деплоя, CORS |
|
||||
| Скорость разработки | Быстро | Медленнее |
|
||||
| Команда | 1-2 Python-разработчика | Python + JS/TS разработчики |
|
||||
| SEO | Не нужен (админка закрыта) | Не нужен |
|
||||
| Мобильные приложения | API тот же — Flutter подключается | API тот же — Flutter подключается |
|
||||
| Поддержка | Проще | Сложнее (два кодовых базы) |
|
||||
|
||||
### 4.2. Масштабирование Jinja2 по России
|
||||
|
||||
При росте нагрузки:
|
||||
1. **Вертикальное:** Увеличить ресурсы VPS (CPU, RAM)
|
||||
2. **Горизонтальное:** Несколько инстансов FastAPI за Nginx (load balancing)
|
||||
3. **Кэширование:** Redis для кэширования тяжёлых запросов
|
||||
4. **CDN:** Для статики (CSS, JS, изображения) — Cloudflare или аналог
|
||||
|
||||
Jinja2 **не является узким местом**. Узким местом будет БД или внешние API (Yandex Disk, 1С).
|
||||
|
||||
### 4.3. Вердикт
|
||||
|
||||
**Jinja2 — правильный выбор.** Для B2B-админки SPA — это оверинжиниринг. Jinja2 даёт:
|
||||
- Быструю разработку
|
||||
- Простую поддержку
|
||||
- Легкое масштабирование
|
||||
- Единую кодовую базу
|
||||
- Готовность к мобильным приложениям (тот же API)
|
||||
|
||||
---
|
||||
|
||||
## 5. Этапы реализации
|
||||
|
||||
### Этап 1: Docker-фундамент на VPS (1-2 недели)
|
||||
|
||||
**Цель:** Подготовить VPS для мультипроектной работы с Docker.
|
||||
|
||||
#### 1.1. Установка Docker и Docker Compose
|
||||
```bash
|
||||
# На VPS (Ubuntu/Debian)
|
||||
apt update && apt upgrade -y
|
||||
curl -fsSL https://get.docker.com | sh
|
||||
systemctl enable --now docker
|
||||
curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
|
||||
chmod +x /usr/local/bin/docker-compose
|
||||
```
|
||||
|
||||
#### 1.2. Базовая структура директорий на VPS
|
||||
```
|
||||
/opt/
|
||||
├── nginx-proxy/ # Nginx reverse proxy + Certbot
|
||||
│ ├── docker-compose.yml
|
||||
│ ├── nginx.conf
|
||||
│ └── certs/ # Let's Encrypt сертификаты
|
||||
├── gitea/ # Git-сервер
|
||||
│ ├── docker-compose.yml
|
||||
│ └── data/ # Данные Gitea
|
||||
├── aegisone-php/ # Публичная часть (PHP)
|
||||
│ ├── docker-compose.yml
|
||||
│ └── src/ # Исходный код (git clone)
|
||||
├── aegisone-py/ # Сервисная часть (Python)
|
||||
│ ├── docker-compose.yml
|
||||
│ ├── app/ # FastAPI приложение
|
||||
│ ├── migrations/ # Alembic миграции
|
||||
│ └── requirements.txt
|
||||
└── project2/ # Существующий проект
|
||||
└── docker-compose.yml
|
||||
```
|
||||
|
||||
#### 1.3. Nginx reverse proxy + Certbot
|
||||
- Один Nginx-контейнер на портах 80/443
|
||||
- Маршрутизация по `server_name`:
|
||||
- `aegisone.ru` → `aegisone-php:80`
|
||||
- `service.aegisone.ru` → `aegisone-py:8000`
|
||||
- `git.aegisone.ru` → `gitea:3000`
|
||||
- `other-project.ru` → `project2:8000`
|
||||
- Certbot в отдельном контейнере или встроенный (nginx-proxy + acme-companion)
|
||||
|
||||
#### 1.4. Gitea (Git-сервер)
|
||||
- Docker-образ `gitea/gitea:latest`
|
||||
- Порт 3000 → `git.aegisone.ru`
|
||||
- PostgreSQL для данных Gitea
|
||||
- Встроенный CI/CD (Gitea Actions)
|
||||
- Репозитории:
|
||||
- `aegisone-php` (публичная часть, перенос с текущего хостинга)
|
||||
- `aegisone-py` (новая сервисная часть)
|
||||
- `project2` (существующий проект)
|
||||
- `infra` (конфигурации Docker, Nginx, CI/CD)
|
||||
|
||||
#### 1.5. Обёртка существующего проекта в Docker
|
||||
- Создать `docker-compose.yml` для project2
|
||||
- Протестировать работоспособность
|
||||
- Настроить домен `other-project.ru`
|
||||
|
||||
**Критерий завершения этапа:**
|
||||
- [ ] Docker + Docker Compose установлены
|
||||
- [ ] Nginx reverse proxy работает, маршрутизирует по доменам
|
||||
- [ ] Certbot выдаёт SSL-сертификаты (Let's Encrypt)
|
||||
- [ ] Gitea запущен на `git.aegisone.ru`
|
||||
- [ ] Существующий проект работает в Docker
|
||||
- [ ] Все домены доступны по HTTPS
|
||||
|
||||
---
|
||||
|
||||
### Этап 2: Перенос AegisOne на VPS (1 неделя)
|
||||
|
||||
**Цель:** Перенести публичную часть с хостинга на VPS, отключить хостинг.
|
||||
|
||||
#### 2.1. Docker-контейнер для PHP
|
||||
```yaml
|
||||
# /opt/aegisone-php/docker-compose.yml
|
||||
services:
|
||||
nginx:
|
||||
image: nginx:alpine
|
||||
ports:
|
||||
- "9080:80" # Внутренний порт, внешний через reverse proxy
|
||||
volumes:
|
||||
- ./src:/var/www/html
|
||||
- ./nginx.conf:/etc/nginx/conf.d/default.conf
|
||||
depends_on:
|
||||
- php
|
||||
|
||||
php:
|
||||
image: php:7.4-fpm
|
||||
volumes:
|
||||
- ./src:/var/www/html
|
||||
environment:
|
||||
- DB_HOST=mysql
|
||||
- DB_NAME=aegisone
|
||||
- DB_USER=aegisone
|
||||
- DB_PASS=<password>
|
||||
|
||||
mysql:
|
||||
image: mysql:5.7
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: <root_password>
|
||||
MYSQL_DATABASE: aegisone
|
||||
MYSQL_USER: aegisone
|
||||
MYSQL_PASSWORD: <password>
|
||||
volumes:
|
||||
- mysql_data:/var/lib/mysql
|
||||
|
||||
volumes:
|
||||
mysql_data:
|
||||
```
|
||||
|
||||
#### 2.2. Перенос файлов
|
||||
- Скачать все файлы с хостинга (FTP/SFTP)
|
||||
- Загрузить в `/opt/aegisone-php/src/`
|
||||
- Настроить `config.php` для нового окружения (DB_HOST=mysql)
|
||||
|
||||
#### 2.3. Миграция БД
|
||||
- Экспорт MySQL с хостинга: `mysqldump -u user -p db_name > backup.sql`
|
||||
- Импорт в Docker MySQL: `docker exec -i aegisone-php-mysql mysql -u aegisone -p aegisone < backup.sql`
|
||||
- Проверить работоспособность
|
||||
|
||||
#### 2.4. Настройка домена
|
||||
- DNS: `aegisone.ru` → IP VPS
|
||||
- Nginx reverse proxy: `server_name aegisone.ru` → `aegisone-php:9080`
|
||||
- SSL: Certbot для `aegisone.ru`
|
||||
|
||||
#### 2.5. Тестирование и отключение хостинга
|
||||
- Проверить все страницы: главная, услуги, блог, контакты, форма
|
||||
- Проверить карусель, FAQ, тему (светлая/тёмная)
|
||||
- Проверить Яндекс.Карту с переключением темы
|
||||
- После подтверждения — отключить хостинг
|
||||
|
||||
**Критерий завершения этапа:**
|
||||
- [ ] Публичная часть работает на VPS
|
||||
- [ ] Все страницы загружаются корректно
|
||||
- [ ] Форма обратной связи работает
|
||||
- [ ] Яндекс.Карта переключает тему
|
||||
- [ ] Домен `aegisone.ru` указывает на VPS
|
||||
- [ ] Хостинг отключён
|
||||
|
||||
---
|
||||
|
||||
### Этап 3: Python-админка (FastAPI + Jinja2) (3-5 недель)
|
||||
|
||||
**Цель:** Полностью переписать сервисную часть на Python.
|
||||
|
||||
#### 3.1. Структура проекта
|
||||
```
|
||||
aegisone-py/
|
||||
├── docker-compose.yml
|
||||
├── Dockerfile
|
||||
├── requirements.txt
|
||||
├── alembic.ini
|
||||
├── migrations/ # Alembic миграции
|
||||
├── app/
|
||||
│ ├── __init__.py
|
||||
│ ├── main.py # FastAPI приложение
|
||||
│ ├── config.py # Настройки (env vars)
|
||||
│ ├── database.py # SQLAlchemy engine, session
|
||||
│ ├── models/ # SQLAlchemy модели
|
||||
│ │ ├── __init__.py
|
||||
│ │ ├── user.py
|
||||
│ │ ├── customer.py
|
||||
│ │ ├── object.py
|
||||
│ │ ├── sla.py
|
||||
│ │ ├── questionnaire.py
|
||||
│ │ ├── blog.py
|
||||
│ │ ├── case.py
|
||||
│ │ ├── document.py
|
||||
│ │ ├── photo.py
|
||||
│ │ └── audit_log.py
|
||||
│ ├── schemas/ # Pydantic схемы
|
||||
│ │ ├── __init__.py
|
||||
│ │ ├── user.py
|
||||
│ │ ├── customer.py
|
||||
│ │ └── ...
|
||||
│ ├── api/ # API endpoints
|
||||
│ │ ├── __init__.py
|
||||
│ │ ├── auth.py # Логин, JWT
|
||||
│ │ ├── users.py
|
||||
│ │ ├── customers.py
|
||||
│ │ ├── objects.py
|
||||
│ │ ├── sla.py
|
||||
│ │ ├── questionnaire.py
|
||||
│ │ ├── blog.py
|
||||
│ │ ├── cases.py
|
||||
│ │ ├── documents.py
|
||||
│ │ └── reports.py
|
||||
│ ├── templates/ # Jinja2 шаблоны
|
||||
│ │ ├── base.html # Базовый шаблон
|
||||
│ │ ├── login.html
|
||||
│ │ ├── dashboard.html
|
||||
│ │ ├── users/
|
||||
│ │ ├── customers/
|
||||
│ │ ├── objects/
|
||||
│ │ ├── sla/
|
||||
│ │ ├── questionnaire/
|
||||
│ │ ├── blog/
|
||||
│ │ ├── documents/
|
||||
│ │ └── reports/
|
||||
│ ├── static/ # CSS, JS, изображения
|
||||
│ │ ├── css/
|
||||
│ │ │ ├── service.css # Стили админки
|
||||
│ │ │ └── ...
|
||||
│ │ ├── js/
|
||||
│ │ │ ├── main.js
|
||||
│ │ │ └── ...
|
||||
│ │ └── img/
|
||||
│ ├── services/ # Бизнес-логика
|
||||
│ │ ├── __init__.py
|
||||
│ │ ├── auth_service.py
|
||||
│ │ ├── calc_service.py # Расчёты (Risk Score, Object Index, SLA)
|
||||
│ │ ├── report_service.py # Генерация отчётов
|
||||
│ │ ├── yandex_disk_service.py # Интеграция с Yandex Disk
|
||||
│ │ └── ...
|
||||
│ ├── tasks/ # Celery задачи
|
||||
│ │ ├── __init__.py
|
||||
│ │ ├── reports.py
|
||||
│ │ ├── yandex_disk.py
|
||||
│ │ └── ...
|
||||
│ └── utils/ # Утилиты
|
||||
│ ├── __init__.py
|
||||
│ ├── password.py
|
||||
│ └── ...
|
||||
└── tests/ # Тесты (опционально)
|
||||
```
|
||||
|
||||
#### 3.2. Миграция данных из MySQL в PostgreSQL
|
||||
- Создать Alembic миграции для всех таблиц
|
||||
- Написать скрипт миграции данных:
|
||||
- `users` → `users`
|
||||
- `customers` → `customers`
|
||||
- `objects` → `objects`
|
||||
- `sla_contracts` → `sla_contracts`
|
||||
- `questionnaire_sessions`, `questionnaire_answers`, `questionnaire_items` → аналогично
|
||||
- `blog_posts` → `blog_posts`
|
||||
- `cases` → `cases`
|
||||
- `audit_log` → `audit_log`
|
||||
- Протестировать миграцию на копии БД
|
||||
|
||||
#### 3.3. Аутентификация
|
||||
- JWT-токены (python-jose)
|
||||
- Логин/пароль (bcrypt)
|
||||
- Роли: `owner`, `engineer`, `technician`
|
||||
- Сессии через cookies (для Jinja2) + JWT (для API)
|
||||
- CSRF-защита для форм
|
||||
|
||||
#### 3.4. CRUD-модули (по порядку приоритета)
|
||||
|
||||
**3.4.1. Пользователи (`/service/users/`)**
|
||||
- Список, создание, редактирование, удаление
|
||||
- Роль `owner` нельзя удалить, нельзя изменить роль
|
||||
- Блокировка/разблокировка
|
||||
- Аудит действий
|
||||
|
||||
**3.4.2. Клиенты (`/service/customers/`)**
|
||||
- Список, создание, редактирование, удаление
|
||||
- ИНН, КПП, юридический адрес, контакты
|
||||
- Связь с объектами и SLA
|
||||
|
||||
**3.4.3. Объекты (`/service/objects/`)**
|
||||
- Список, создание, редактирование, удаление
|
||||
- Привязка к клиенту
|
||||
- Тип, адрес, площадь, сотрудники
|
||||
- Risk Score, Complexity Index, Object Index (авторасчёт)
|
||||
- SLA price (авторасчёт)
|
||||
|
||||
**3.4.4. SLA контракты (`/service/sla/`)**
|
||||
- Список, создание, редактирование, удаление
|
||||
- Привязка к клиенту и объекту
|
||||
- Тарифы: Базовый, Оптимальный, Максимальный
|
||||
- Время реакции, периодичность ТО
|
||||
- Статус: active, expired, cancelled, negotiation
|
||||
|
||||
**3.4.5. Опросник (`/service/questionnaire/`)**
|
||||
- Создание новой сессии
|
||||
- 5 шагов: Коммерческий, Технический, Эксплуатация, Риски, Расчёт SLA
|
||||
- Вопросы из БД (`questionnaire_items`)
|
||||
- Сохранение ответов
|
||||
- Авторасчёт: Risk Score, Complexity Index, Infrastructure Load, Service History, Object Index, SLA Price
|
||||
- Формирование паспорта объекта
|
||||
|
||||
**3.4.6. Блог (`/service/blog/`)**
|
||||
- Список, создание, редактирование, удаление
|
||||
- Категории: audit, sla, incident, supervision, documentation, risk, cases
|
||||
- HTML-редактор (toolbar)
|
||||
- Автогенерация slug из заголовка
|
||||
- Статус: draft, published
|
||||
|
||||
**3.4.7. Примеры из практики (`/service/cases/`)**
|
||||
- Список, создание, редактирование, удаление
|
||||
- Заголовок, текст, эффект
|
||||
- Сортировка, активность
|
||||
|
||||
**3.4.8. Документы (`/service/documents/`)**
|
||||
- Список документов (из `service/docs/*.md`)
|
||||
- Ручная сортировка
|
||||
- Переименование
|
||||
- Гранулярные права: view, edit, cancel (по ролям)
|
||||
- JSON-хранилище прав (`docs_permissions.json`)
|
||||
|
||||
#### 3.5. Расчёты (перенос из PHP)
|
||||
- `calc_risk_score()` — Risk Score
|
||||
- `calc_complexity()` — Complexity Index
|
||||
- `calc_infrastructure_load()` — Infrastructure Load
|
||||
- `calc_service_history()` — Service History
|
||||
- `calc_object_index()` — Object Index
|
||||
- `calc_sla_price()` — SLA Price
|
||||
- `risk_multiplier()` — множитель риска
|
||||
- `risk_label()` — текстовая метка риска
|
||||
- `object_class()` — класс объекта
|
||||
- `fmt_money()` — форматирование денег
|
||||
|
||||
Все функции переписать на Python, покрыть тестами.
|
||||
|
||||
#### 3.6. Дашборд (`/service/dashboard/`)
|
||||
- Метрики: количество объектов, активных SLA, открытых задач
|
||||
- Графики (Chart.js или аналог)
|
||||
- Быстрые действия
|
||||
- Последние активности (audit_log)
|
||||
|
||||
#### 3.7. Фронтенд (Jinja2)
|
||||
- Базовый шаблон (`base.html`) с:
|
||||
- Боковой панелью (sidebar) с навигацией
|
||||
- Верхней панелью (header) с пользователем и переключателем темы
|
||||
- Основным контентом
|
||||
- Темы: system → dark → light (localStorage, как сейчас)
|
||||
- Кастомные скроллбары
|
||||
- Тултипы на кнопках
|
||||
- Модальные окна (создание/редактирование)
|
||||
- Таблицы с поиском и пагинацией
|
||||
- Адаптивность (мобильная версия)
|
||||
|
||||
**Критерий завершения этапа:**
|
||||
- [ ] Все CRUD-модули работают
|
||||
- [ ] Расчёты корректны (сравнить с PHP-версией)
|
||||
- [ ] Миграция данных завершена
|
||||
- [ ] Фронтенд полностью функционален
|
||||
- [ ] Темы переключаются
|
||||
- [ ] Мобильная версия работает
|
||||
- [ ] `service.aegisone.ru` доступен по HTTPS
|
||||
|
||||
---
|
||||
|
||||
### Этап 4: Интеграции (2-3 недели)
|
||||
|
||||
**Цель:** Добавить генерацию отчётов, интеграцию с Yandex Disk, фоновые задачи.
|
||||
|
||||
#### 4.1. Yandex Disk API
|
||||
- Регистрация приложения в Yandex OAuth
|
||||
- Получение OAuth-токена
|
||||
- SDK: `yandex-disk` или REST API через `requests`
|
||||
- Структура папок:
|
||||
```
|
||||
/AegisOne/
|
||||
├── objects/{object_id}/
|
||||
│ ├── photos/
|
||||
│ │ └── {photo_id}.jpg
|
||||
│ └── documents/{doc_id}/
|
||||
│ ├── {photo_id}.jpg
|
||||
│ └── report_{doc_id}.pdf
|
||||
└── ...
|
||||
```
|
||||
- Эндпоинты:
|
||||
- `POST /api/documents/{id}/upload-photo` — загрузка фото
|
||||
- `GET /api/documents/{id}/photos` — список фото
|
||||
- `DELETE /api/photos/{id}` — удаление фото
|
||||
- В БД: таблица `photos` (id, document_id, object_id, yandex_file_id, yandex_file_url, uploaded_at, uploaded_by)
|
||||
|
||||
#### 4.2. Генерация отчётов
|
||||
- **PDF:** WeasyPrint (HTML → PDF)
|
||||
- Шаблон паспорта объекта
|
||||
- Шаблон отчёта по аудиту
|
||||
- Шаблон SLA-контракта
|
||||
- **Excel:** openpyxl
|
||||
- Экспорт списка объектов
|
||||
- Экспорт SLA-контрактов
|
||||
- Экспорт отчётов по KPI
|
||||
- Фоновая генерация через Celery (для тяжёлых отчётов)
|
||||
|
||||
#### 4.3. Celery (фоновые задачи)
|
||||
- Broker: Redis
|
||||
- Задачи:
|
||||
- Генерация PDF-отчётов
|
||||
- Загрузка фото на Yandex Disk
|
||||
- Отправка уведомлений (email, Telegram)
|
||||
- Интеграция с 1С (по мере необходимости)
|
||||
- Мониторинг: Flower (веб-интерфейс для Celery)
|
||||
|
||||
#### 4.4. Интеграция с 1С (опционально, по мере необходимости)
|
||||
- REST API 1С или OData
|
||||
- Синхронизация: клиенты, объекты, договоры
|
||||
- Фоновая задача Celery
|
||||
|
||||
**Критерий завершения этапа:**
|
||||
- [ ] Yandex Disk API интегрирован
|
||||
- [ ] Фото загружаются и привязываются к документам
|
||||
- [ ] PDF-отчёты генерируются
|
||||
- [ ] Excel-экспорт работает
|
||||
- [ ] Celery запущен, задачи выполняются
|
||||
- [ ] (Опционально) Интеграция с 1С настроена
|
||||
|
||||
---
|
||||
|
||||
### Этап 5: CI/CD и автоматизация деплоя (1 неделя)
|
||||
|
||||
**Цель:** Настроить автоматический деплой при push в Git.
|
||||
|
||||
#### 5.1. Gitea Actions (CI/CD)
|
||||
- Встроенный CI/CD в Gitea (совместим с GitHub Actions)
|
||||
- Workflow для `aegisone-py`:
|
||||
```yaml
|
||||
name: Deploy AegisOne Python
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Build and push Docker image
|
||||
run: |
|
||||
docker build -t registry.git.aegisone.ru/aegisone-py:latest .
|
||||
docker push registry.git.aegisone.ru/aegisone-py:latest
|
||||
|
||||
- name: Deploy to VPS
|
||||
run: |
|
||||
ssh user@vps "cd /opt/aegisone-py && docker compose pull && docker compose up -d"
|
||||
```
|
||||
|
||||
#### 5.2. Структура репозиториев в Gitea
|
||||
```
|
||||
git.aegisone.ru/
|
||||
├── aegisone/aegisone-php # Публичная часть (PHP)
|
||||
├── aegisone/aegisone-py # Сервисная часть (Python)
|
||||
├── aegisone/infra # Docker, Nginx, CI/CD конфиги
|
||||
└── aegisone/project2 # Существующий проект
|
||||
```
|
||||
|
||||
#### 5.3. Автоматический деплой
|
||||
- Push в `main` → Gitea Actions → сборка Docker-образа → деплой на VPS
|
||||
- Rollback: `docker compose down && docker compose up -d` с предыдущим образом
|
||||
- Миграции БД: Alembic `upgrade head` автоматически при деплое
|
||||
|
||||
#### 5.4. Локальная разработка
|
||||
- `docker-compose.dev.yml` для локальной разработки
|
||||
- Hot-reload для Python (uvicorn --reload)
|
||||
- Локальная БД (PostgreSQL в Docker)
|
||||
- Синхронизация с VPS: `git push` → автоматический деплой
|
||||
|
||||
**Критерий завершения этапа:**
|
||||
- [ ] Gitea Actions настроены для всех проектов
|
||||
- [ ] Push в `main` → автоматический деплой
|
||||
- [ ] Rollback работает
|
||||
- [ ] Миграции БД применяются автоматически
|
||||
- [ ] Локальная разработка через Docker
|
||||
|
||||
---
|
||||
|
||||
## 6. Миграция данных: MySQL → PostgreSQL
|
||||
|
||||
### 6.1. Таблицы для миграции
|
||||
|
||||
| MySQL таблица | PostgreSQL таблица | Примечание |
|
||||
|---|---|---|
|
||||
| `users` | `users` | Без изменений |
|
||||
| `login_attempts` | `login_attempts` | Без изменений |
|
||||
| `audit_log` | `audit_log` | Без изменений |
|
||||
| `objects` | `objects` | + `customer_id` FK |
|
||||
| `object_assignments` | `object_assignments` | Без изменений |
|
||||
| `tasks` | `tasks` | Без изменений |
|
||||
| `task_comments` | `task_comments` | Без изменений |
|
||||
| `customers` | `customers` | Новая таблица |
|
||||
| `sla_contracts` | `sla_contracts` | + `customer_id` FK, `contract_number`, `description`, `response_time_hours` |
|
||||
| `incidents` | `incidents` | Без изменений |
|
||||
| `engineer_kpi` | `engineer_kpi` | Без изменений |
|
||||
| `questionnaire_sessions` | `questionnaire_sessions` | Без изменений |
|
||||
| `questionnaire_answers` | `questionnaire_answers` | Без изменений |
|
||||
| `questionnaire_items` | `questionnaire_items` | Новая таблица |
|
||||
| `object_passports` | `object_passports` | Без изменений |
|
||||
| `blog_posts` | `blog_posts` | ENUM категории изменён |
|
||||
| `cases` | `cases` | Без изменений |
|
||||
|
||||
### 6.2. Скрипт миграции
|
||||
```python
|
||||
# scripts/migrate_mysql_to_postgres.py
|
||||
import mysql.connector
|
||||
import psycopg2
|
||||
from psycopg2.extras import execute_batch
|
||||
|
||||
# Подключение к MySQL
|
||||
mysql_conn = mysql.connector.connect(host='...', user='...', password='...', database='...')
|
||||
mysql_cursor = mysql_conn.cursor(dictionary=True)
|
||||
|
||||
# Подключение к PostgreSQL
|
||||
pg_conn = psycopg2.connect(host='...', user='...', password='...', database='...')
|
||||
pg_cursor = pg_conn.cursor()
|
||||
|
||||
# Миграция каждой таблицы
|
||||
tables = ['users', 'customers', 'objects', 'sla_contracts', ...]
|
||||
for table in tables:
|
||||
mysql_cursor.execute(f"SELECT * FROM {table}")
|
||||
rows = mysql_cursor.fetchall()
|
||||
|
||||
if rows:
|
||||
columns = rows[0].keys()
|
||||
placeholders = ', '.join(['%s'] * len(columns))
|
||||
cols = ', '.join(columns)
|
||||
execute_batch(
|
||||
pg_cursor,
|
||||
f"INSERT INTO {table} ({cols}) VALUES ({placeholders}) ON CONFLICT DO NOTHING",
|
||||
[tuple(row[col] for col in columns) for row in rows]
|
||||
)
|
||||
|
||||
pg_conn.commit()
|
||||
```
|
||||
|
||||
### 6.3. Проверка миграции
|
||||
- Сравнить количество записей в MySQL и PostgreSQL
|
||||
- Проверить FK-связи
|
||||
- Протестировать CRUD-операции на PostgreSQL
|
||||
- Откат: сохранить бэкап MySQL до миграции
|
||||
|
||||
---
|
||||
|
||||
## 7. Безопасность
|
||||
|
||||
### 7.1. Аутентификация и авторизация
|
||||
- JWT-токены с expiration (1 час)
|
||||
- Refresh tokens (7 дней)
|
||||
- Роли: `owner`, `engineer`, `technician`
|
||||
- Гранулярные права для документов (view, edit, cancel)
|
||||
- CSRF-защита для форм
|
||||
|
||||
### 7.2. Защита данных
|
||||
- Пароли: bcrypt (cost factor 12)
|
||||
- HTTPS для всех доменов (Let's Encrypt)
|
||||
- Firewall: только порты 80, 443, 22 (SSH)
|
||||
- Docker: изоляция контейнеров, нет root в контейнерах
|
||||
- БД: нет внешнего доступа, только из Docker-сети
|
||||
|
||||
### 7.3. Бэкапы
|
||||
- PostgreSQL: `pg_dump` ежедневно (cron)
|
||||
- Yandex Disk: файлы уже в облаке
|
||||
- Gitea: бэкап репозиториев (tar)
|
||||
- Хранение бэкапов: отдельный диск или облако
|
||||
|
||||
### 7.4. Мониторинг
|
||||
- (Опционально) Uptime Kuma для мониторинга доступности
|
||||
- Логи: Docker logs + ротация
|
||||
- Алерты: email/Telegram при ошибках
|
||||
|
||||
---
|
||||
|
||||
## 8. Риски и митигация
|
||||
|
||||
| Риск | Вероятность | Влияние | Митигация |
|
||||
|---|---|---|---|
|
||||
| Ошибка миграции данных | Средняя | Высокое | Тестирование на копии, бэкап MySQL |
|
||||
| Простои при деплое | Низкая | Среднее | Zero-downtime деплой (docker compose up -d) |
|
||||
| Проблемы с SSL | Низкая | Среднее | Certbot автообновление, мониторинг |
|
||||
| Yandex Disk API лимиты | Низкая | Низкое | Кэширование, retry logic |
|
||||
| Нехватка ресурсов VPS | Средняя | Высокое | Мониторинг CPU/RAM, масштабирование |
|
||||
| Ошибки в расчётах | Средняя | Высокое | Тесты, сравнение с PHP-версией |
|
||||
|
||||
---
|
||||
|
||||
## 9. Оценки времени
|
||||
|
||||
| Этап | Описание | Оценка |
|
||||
|---|---|---|
|
||||
| Этап 1 | Docker-фундамент | 1-2 недели |
|
||||
| Этап 2 | Перенос AegisOne на VPS | 1 неделя |
|
||||
| Этап 3 | Python-админка | 3-5 недель |
|
||||
| Этап 4 | Интеграции | 2-3 недели |
|
||||
| Этап 5 | CI/CD | 1 неделя |
|
||||
| **Итого** | | **8-12 недель** |
|
||||
|
||||
---
|
||||
|
||||
## 10. Контрольные точки
|
||||
|
||||
| Точка | Описание | Критерий успеха |
|
||||
|---|---|---|
|
||||
| КП1 | Docker-фундамент готов | Все сервисы запущены, домены работают по HTTPS |
|
||||
| КП2 | Публичная часть на VPS | aegisone.ru работает, хостинг отключён |
|
||||
| КП3 | Python-админка MVP | CRUD для пользователей, объектов, SLA работает |
|
||||
| КП4 | Python-админка полная | Все модули, расчёты, миграция данных завершены |
|
||||
| КП5 | Интеграции | Yandex Disk, отчёты, Celery работают |
|
||||
| КП6 | CI/CD | Автоматический деплой при push |
|
||||
|
||||
---
|
||||
|
||||
## 11. Открытые вопросы (уточнить перед реализацией)
|
||||
|
||||
> **Важно:** Если при реализации возникнут вопросы — лучше уточнить, чем переделывать потом.
|
||||
|
||||
1. **Миграция данных:** Переносим все данные из MySQL в PostgreSQL или начинаем с чистой БД? (Рекомендация: мигрировать)
|
||||
2. **Домен для админки:** `service.aegisone.ru` или `app.aegisone.ru`? (Рекомендация: `service.aegisone.ru`)
|
||||
3. **Yandex Disk OAuth:** Использовать токен приложения или OAuth с авторизацией пользователя? (Рекомендация: токен приложения для простоты)
|
||||
4. **Генерация отчётов:** Какие именно отчёты нужны в первую очередь? (Паспорт объекта, отчёт по аудиту, SLA-контракт?)
|
||||
5. **Интеграция с 1С:** Какая версия 1С? Какой метод интеграции (REST API, OData, файловый обмен)?
|
||||
6. **Мониторинг:** Нужен ли Uptime Kuma или другой мониторинг? (Рекомендация: да, для продакшена)
|
||||
7. **Бэкапы:** Где хранить бэкапы PostgreSQL? (Отдельный диск на VPS, облако, другой сервер?)
|
||||
8. **Тестирование:** Покрывать ли код тестами? (Рекомендация: да, хотя бы критические расчёты)
|
||||
9. **Документация:** Вести ли документацию по API? (Рекомендация: да, через FastAPI автоматическую /docs)
|
||||
10. **Логирование:** Какой уровень логирования? Куда писать логи? (Рекомендация: INFO в stdout, Docker logs)
|
||||
|
||||
---
|
||||
|
||||
## 12. Следующие шаги
|
||||
|
||||
1. **Утвердить план** — ответить на открытые вопросы (раздел 11)
|
||||
2. **Начать Этап 1** — Docker-фундамент на VPS
|
||||
3. **Параллельно** — создать репозитории в Gitea, настроить CI/CD skeleton
|
||||
4. **После Этапа 1** — приступить к Этапу 2 (перенос PHP)
|
||||
5. **После Этапа 2** — приступить к Этапу 3 (Python-админка)
|
||||
|
||||
---
|
||||
|
||||
**Документ создан:** 2026-05-17
|
||||
**Версия:** 1.0
|
||||
**Автор:** AI-ассистент + Владелец
|
||||
**Статус:** Готов к реализации после утверждения
|
||||
@@ -0,0 +1,485 @@
|
||||
Ниже — система KPI, которая превращает инженеров и техников из “выездных исполнителей” в управляемую часть инженерной SLA-модели AegisOne Engineering.
|
||||
|
||||
Главная цель системы:
|
||||
|
||||
> не “оценивать занятость”, а измерять качество эксплуатации, скорость реакции и снижение рисков объекта
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
0. ПРИНЦИП СИСТЕМЫ KPI
|
||||
|
||||
Ты НЕ измеряешь:
|
||||
|
||||
сколько выездов сделал инженер
|
||||
|
||||
сколько он “починил”
|
||||
|
||||
|
||||
Ты измеряешь:
|
||||
|
||||
1) надежность объектов
|
||||
|
||||
2) соблюдение SLA
|
||||
|
||||
3) качество диагностики
|
||||
|
||||
4) снижение повторных инцидентов
|
||||
|
||||
|
||||
---
|
||||
|
||||
1. СТРУКТУРА KPI (3 УРОВНЯ)
|
||||
|
||||
2. Операционный KPI (ежедневный)
|
||||
3. SLA KPI (контрактный)
|
||||
4. Инженерный KPI качества (экспертный)
|
||||
|
||||
|
||||
---
|
||||
|
||||
2. ОПЕРАЦИОННЫЙ KPI (Execution KPI)
|
||||
|
||||
Это “что сделал инженер”.
|
||||
|
||||
|
||||
---
|
||||
|
||||
KPI 1: Время реакции (Response Time)
|
||||
|
||||
Формула:
|
||||
|
||||
RT = (фактическое время реакции / SLA время реакции)
|
||||
|
||||
|
||||
---
|
||||
|
||||
Оценка:
|
||||
|
||||
RT Оценка
|
||||
|
||||
≤ 1.0 норма
|
||||
1.0–1.2 допустимо
|
||||
> 1.2 нарушение
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Пример:
|
||||
|
||||
SLA: 2 часа
|
||||
|
||||
факт: 3 часа
|
||||
|
||||
|
||||
RT = 3 / 2 = 1.5 → ❌ нарушение
|
||||
|
||||
|
||||
---
|
||||
|
||||
KPI 2: Время устранения (Resolution Time)
|
||||
|
||||
TTR = фактическое время устранения / нормативное время
|
||||
|
||||
|
||||
---
|
||||
|
||||
Важно:
|
||||
|
||||
Норматив зависит от типа инцидента:
|
||||
|
||||
P1 (критический) — 2–6 часов
|
||||
|
||||
P2 — до 24 часов
|
||||
|
||||
P3 — до 3 дней
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
KPI 3: Закрытие заявок в SLA
|
||||
|
||||
SLA Compliance = (заявки в SLA / все заявки) × 100%
|
||||
|
||||
|
||||
---
|
||||
|
||||
Норма:
|
||||
|
||||
≥ 95% — отлично
|
||||
|
||||
90–95% — допустимо
|
||||
|
||||
< 90% — проблема инженера
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
KPI 4: Повторные обращения (Reopen Rate)
|
||||
|
||||
RR = (повторные заявки / общее число заявок) × 100%
|
||||
|
||||
|
||||
---
|
||||
|
||||
Норма:
|
||||
|
||||
≤ 5% — хорошо
|
||||
|
||||
5–10% — средне
|
||||
|
||||
> 10% — плохая диагностика
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
3. SLA KPI (контрактный уровень)
|
||||
|
||||
|
||||
---
|
||||
|
||||
KPI 5: Выполнение SLA по объектам
|
||||
|
||||
Object SLA = (объекты без нарушений SLA / все объекты) × 100%
|
||||
|
||||
|
||||
---
|
||||
|
||||
Норма:
|
||||
|
||||
≥ 95% — стабильная сеть объектов
|
||||
|
||||
< 90% — системная проблема команды
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
KPI 6: Доступность систем (System Uptime)
|
||||
|
||||
Uptime = (время работы системы / общее время) × 100%
|
||||
|
||||
|
||||
---
|
||||
|
||||
Цель:
|
||||
|
||||
99%+ для критических объектов
|
||||
|
||||
97–99% допустимо
|
||||
|
||||
< 97% — риск SLA разрыва
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
4. ИНЖЕНЕРНЫЙ KPI (КАЧЕСТВО ЭКСПЕРТИЗЫ)
|
||||
|
||||
Это ключевой уровень, который отличает тебя от монтажников.
|
||||
|
||||
|
||||
---
|
||||
|
||||
KPI 7: Точность диагностики
|
||||
|
||||
Accuracy = (подтвержденные неисправности / выявленные) × 100%
|
||||
|
||||
|
||||
---
|
||||
|
||||
Пример:
|
||||
|
||||
выявил 10 проблем
|
||||
|
||||
9 подтвердились
|
||||
|
||||
|
||||
→ 90%
|
||||
|
||||
|
||||
---
|
||||
|
||||
Норма:
|
||||
|
||||
≥ 85% — хорошо
|
||||
|
||||
< 80% — инженер слабый
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
KPI 8: Глубина диагностики (Risk Coverage Score)
|
||||
|
||||
Оценивает, насколько инженер видит системные риски.
|
||||
|
||||
|
||||
---
|
||||
|
||||
Формула (балльная система):
|
||||
|
||||
Каждый объект оценивается по 5 зонам:
|
||||
|
||||
видео
|
||||
|
||||
СКУД
|
||||
|
||||
пожарка
|
||||
|
||||
питание
|
||||
|
||||
сеть
|
||||
|
||||
|
||||
RCS = (проверенные зоны / 5) × 100%
|
||||
|
||||
|
||||
---
|
||||
|
||||
Норма:
|
||||
|
||||
100% — стандарт AegisOne
|
||||
|
||||
< 80% — поверхностная работа
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
KPI 9: Снижение повторных инцидентов
|
||||
|
||||
IRR = ((инциденты до - инциденты после) / до) × 100%
|
||||
|
||||
|
||||
---
|
||||
|
||||
Это ключевой KPI бизнеса
|
||||
|
||||
|
||||
---
|
||||
|
||||
5. ФИНАНСОВЫЙ KPI ИНЖЕНЕРА
|
||||
|
||||
|
||||
---
|
||||
|
||||
KPI 10: Доход на инженера (Revenue per Engineer)
|
||||
|
||||
RPE = общий SLA доход / количество инженеров
|
||||
|
||||
|
||||
---
|
||||
|
||||
Норма:
|
||||
|
||||
500k – слабая загрузка
|
||||
|
||||
800k – норм
|
||||
|
||||
1.2M+ – сильная модель
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
6. ИТОГОВЫЙ ИНДЕКС ИНЖЕНЕРА (ENGINEER SCORE)
|
||||
|
||||
Это твой главный инструмент управления.
|
||||
|
||||
|
||||
---
|
||||
|
||||
Формула:
|
||||
|
||||
ES =
|
||||
(0.25 × SLA Compliance) +
|
||||
(0.20 × Response Time Score) +
|
||||
(0.20 × Resolution Time Score) +
|
||||
(0.15 × Diagnosis Accuracy) +
|
||||
(0.10 × Reopen Rate Score) +
|
||||
(0.10 × Risk Coverage Score)
|
||||
|
||||
|
||||
---
|
||||
|
||||
Интерпретация:
|
||||
|
||||
Score Уровень
|
||||
|
||||
90–100 Senior Engineer
|
||||
80–89 Strong Engineer
|
||||
70–79 Middle
|
||||
< 70 требует обучения
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
7. ДОПОЛНИТЕЛЬНЫЕ KPI (ОЧЕНЬ ВАЖНЫЕ)
|
||||
|
||||
|
||||
---
|
||||
|
||||
KPI 11: Документирование (Documentation Quality)
|
||||
|
||||
DQ = (полные отчёты / все выезды) × 100%
|
||||
|
||||
|
||||
---
|
||||
|
||||
KPI 12: Качество отчёта (Report Quality Score)
|
||||
|
||||
Оценивается по чек-листу:
|
||||
|
||||
есть ли риски
|
||||
|
||||
есть ли вывод
|
||||
|
||||
есть ли рекомендации
|
||||
|
||||
есть ли фото/фиксация
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
KPI 13: Самостоятельность инженера
|
||||
|
||||
Autonomy = (самостоятельные решения / всего решений) × 100%
|
||||
|
||||
|
||||
---
|
||||
|
||||
8. КАК ЭТО ВЫГЛЯДИТ В CRM
|
||||
|
||||
|
||||
---
|
||||
|
||||
Инженер:
|
||||
- SLA Compliance: 96%
|
||||
- RT: 1.1
|
||||
- TTR: 0.9
|
||||
- Diagnosis: 88%
|
||||
- Reopen: 3%
|
||||
- Score: 91 (Senior)
|
||||
|
||||
|
||||
---
|
||||
|
||||
9. СИСТЕМА МОТИВАЦИИ (ВАЖНО)
|
||||
|
||||
|
||||
---
|
||||
|
||||
БАЗОВАЯ ЛОГИКА:
|
||||
|
||||
фикс оклад
|
||||
|
||||
бонус за KPI
|
||||
|
||||
штрафы только за SLA нарушения
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
БОНУС:
|
||||
|
||||
Score 90+ → +20% к премии
|
||||
Score 80–89 → +10%
|
||||
Score < 80 → без бонуса
|
||||
|
||||
|
||||
---
|
||||
|
||||
10. ГЛАВНЫЙ ПРИНЦИП СИСТЕМЫ
|
||||
|
||||
Ты НЕ платишь за:
|
||||
|
||||
❌ “работу”
|
||||
❌ “выезды”
|
||||
|
||||
Ты платишь за:
|
||||
|
||||
стабильность инфраструктуры клиента
|
||||
|
||||
|
||||
---
|
||||
|
||||
11. КАК ЭТА СИСТЕМА МАСШТАБИРУЕТ БИЗНЕС
|
||||
|
||||
|
||||
---
|
||||
|
||||
1 инженер = управляемая единица SLA
|
||||
|
||||
Ты можешь:
|
||||
|
||||
добавлять инженеров
|
||||
|
||||
сравнивать эффективность
|
||||
|
||||
масштабировать регионы
|
||||
|
||||
контролировать качество без присутствия
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
12. СВЯЗЬ С ТВОЕЙ БИЗНЕС-МОДЕЛЬЮ
|
||||
|
||||
|
||||
---
|
||||
|
||||
KPI инженера
|
||||
↓
|
||||
качество SLA
|
||||
↓
|
||||
удержание клиентов
|
||||
↓
|
||||
MRR рост
|
||||
↓
|
||||
масштаб компании
|
||||
|
||||
|
||||
---
|
||||
|
||||
13. СЛЕДУЮЩИЙ УРОВЕНЬ (если продолжать систему)
|
||||
|
||||
Я могу дальше собрать:
|
||||
|
||||
систему грейдов инженеров (Junior → Lead → Chief)
|
||||
|
||||
модель расчёта зарплаты под KPI
|
||||
|
||||
автоматическую таблицу KPI в Excel/Notion
|
||||
|
||||
SLA dashboard (как у IT-компаний)
|
||||
|
||||
систему контроля качества через аудит отчётов
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
ИТОГ
|
||||
|
||||
Ты получил не “мотивацию сотрудников”.
|
||||
|
||||
Ты получил:
|
||||
|
||||
> систему управления инженерной эксплуатационной компанией через измеримые риски и SLA
|
||||
|
||||
|
||||
|
||||
Это уровень компаний, которые продают не услуги — а надежность инфраструктуры бизнеса.
|
||||
@@ -0,0 +1,520 @@
|
||||
Ты сейчас описываешь переход от “владельца инженерной фирмы” к роли:
|
||||
|
||||
операционного директора инженерной системы (Engineering Operations System Owner)
|
||||
|
||||
В такой модели ты уже не контролируешь людей напрямую — ты контролируешь поток рисков, денег, SLA и загрузки системы.
|
||||
|
||||
Я разложу это как управленческую “панель управления” (CEO Dashboard), разделив на:
|
||||
|
||||
1. критически важные метрики (must have)
|
||||
|
||||
|
||||
2. важные (should have)
|
||||
|
||||
|
||||
3. полезные (nice to have)
|
||||
|
||||
|
||||
4. формулы
|
||||
|
||||
|
||||
5. графики и визуализации
|
||||
|
||||
|
||||
6. как это связывается в одну систему управления
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
1. КРИТИЧЕСКИ ВАЖНЫЕ ПАРАМЕТРЫ (CEO CORE CONTROL LAYER)
|
||||
|
||||
Это то, без чего ты не управляешь компанией, а просто “наблюдаешь бизнес”.
|
||||
|
||||
|
||||
---
|
||||
|
||||
1.1 MRR / ARR (регулярный доход SLA)
|
||||
|
||||
Формула:
|
||||
|
||||
MRR = Σ (все SLA контракты / 12)
|
||||
ARR = MRR × 12
|
||||
|
||||
|
||||
---
|
||||
|
||||
Почему это главное:
|
||||
|
||||
Ты продаёшь не монтаж, а:
|
||||
|
||||
> стабильность объектов
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
График:
|
||||
|
||||
📈 линия роста MRR по месяцам
|
||||
📊 разбивка по типам объектов
|
||||
|
||||
|
||||
---
|
||||
|
||||
Управленческая логика:
|
||||
|
||||
если MRR растёт → система здорова
|
||||
|
||||
если нет → маркетинг/воронка сломана
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
1.2 RETENTION RATE (удержание клиентов)
|
||||
|
||||
Формула:
|
||||
|
||||
Retention = (клиенты в конце периода / клиенты в начале) × 100%
|
||||
|
||||
|
||||
---
|
||||
|
||||
Норма:
|
||||
|
||||
95–100% = отлично
|
||||
|
||||
85–95% = нормально
|
||||
|
||||
<85% = проблема в SLA
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
График:
|
||||
|
||||
📉 “утечка клиентов по месяцам”
|
||||
|
||||
|
||||
---
|
||||
|
||||
Интерпретация:
|
||||
|
||||
Если падает retention — проблема не в продажах, а в:
|
||||
|
||||
инженерах
|
||||
|
||||
SLA
|
||||
|
||||
качестве реакции
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
1.3 SLA COMPLIANCE (исполнение контрактов)
|
||||
|
||||
Формула:
|
||||
|
||||
SLA Compliance = (выполненные заявки в SLA / все заявки) × 100%
|
||||
|
||||
|
||||
---
|
||||
|
||||
Норма:
|
||||
|
||||
95–99% = система стабильна
|
||||
|
||||
<90% = начинаются разрывы контрактов
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
График:
|
||||
|
||||
📊 compliance по инженерам / регионам
|
||||
|
||||
|
||||
---
|
||||
|
||||
1.4 COST PER SLA OBJECT (стоимость обслуживания объекта)
|
||||
|
||||
Формула:
|
||||
|
||||
Cost per Object = (ФОТ + выезды + оборудование + накладные) / количество объектов
|
||||
|
||||
|
||||
---
|
||||
|
||||
Почему важно:
|
||||
|
||||
Ты должен видеть:
|
||||
|
||||
> объект приносит деньги или сжигает ресурс
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
График:
|
||||
|
||||
📊 распределение стоимости по типам объектов
|
||||
|
||||
|
||||
---
|
||||
|
||||
1.5 ENGINEER PRODUCTIVITY (производительность инженера)
|
||||
|
||||
Формула:
|
||||
|
||||
EP = SLA Revenue / количество инженеров
|
||||
|
||||
|
||||
---
|
||||
|
||||
Или глубже:
|
||||
|
||||
EP2 = (закрытые заявки × сложность) / часы работы
|
||||
|
||||
|
||||
---
|
||||
|
||||
График:
|
||||
|
||||
📊 эффективность по инженерам (ranking)
|
||||
|
||||
|
||||
---
|
||||
|
||||
2. ВАЖНЫЕ ПАРАМЕТРЫ (OPTIMIZATION LAYER)
|
||||
|
||||
Это влияет на прибыль, но не ломает систему сразу.
|
||||
|
||||
|
||||
---
|
||||
|
||||
2.1 LEAD → SLA CONVERSION RATE
|
||||
|
||||
Формула:
|
||||
|
||||
Conversion = SLA contracts / all qualified leads
|
||||
|
||||
|
||||
---
|
||||
|
||||
График:
|
||||
|
||||
📈 воронка: лиды → аудит → SLA
|
||||
|
||||
|
||||
---
|
||||
|
||||
Диагностика:
|
||||
|
||||
низкая конверсия → проблема продаж/аудита
|
||||
|
||||
высокая → система сильная
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
2.2 AVERAGE SLA CONTRACT VALUE
|
||||
|
||||
Формула:
|
||||
|
||||
ARPC = Total SLA revenue / number of contracts
|
||||
|
||||
|
||||
---
|
||||
|
||||
График:
|
||||
|
||||
📊 средний чек по объектам
|
||||
|
||||
|
||||
---
|
||||
|
||||
2.3 INCIDENT RATE (частота аварий)
|
||||
|
||||
Формула:
|
||||
|
||||
IR = incidents / objects
|
||||
|
||||
|
||||
---
|
||||
|
||||
Почему важно:
|
||||
|
||||
Показывает:
|
||||
|
||||
> реальное качество эксплуатации
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
2.4 REOPEN RATE (повторные заявки)
|
||||
|
||||
Reopen = повторные обращения / все обращения
|
||||
|
||||
|
||||
---
|
||||
|
||||
Если растёт:
|
||||
|
||||
→ инженер плохо диагностирует
|
||||
|
||||
|
||||
---
|
||||
|
||||
3. ПОЛЕЗНЫЕ ПАРАМЕТРЫ (NICE TO HAVE)
|
||||
|
||||
Это усиливает контроль, но не критично.
|
||||
|
||||
|
||||
---
|
||||
|
||||
3.1 CUSTOMER SATISFACTION (CSAT)
|
||||
|
||||
CSAT = (положительные оценки / все оценки) × 100%
|
||||
|
||||
|
||||
---
|
||||
|
||||
3.2 RESPONSE TIME DISTRIBUTION
|
||||
|
||||
Не среднее, а распределение:
|
||||
|
||||
📊 0–2 часа
|
||||
📊 2–6
|
||||
📊 6–24
|
||||
|
||||
|
||||
---
|
||||
|
||||
3.3 EQUIPMENT HEALTH INDEX
|
||||
|
||||
EHI = (исправное оборудование / общее оборудование) × 100%
|
||||
|
||||
|
||||
---
|
||||
|
||||
3.4 ENGINEER UTILIZATION RATE
|
||||
|
||||
Utilization = рабочие часы / доступные часы
|
||||
|
||||
|
||||
---
|
||||
|
||||
4. ГЛАВНЫЙ CEO-ИНДЕКС (SYSTEM HEALTH SCORE)
|
||||
|
||||
Это твоя “панель управления бизнесом”.
|
||||
|
||||
|
||||
---
|
||||
|
||||
Формула:
|
||||
|
||||
SHS =
|
||||
(0.25 × MRR growth) +
|
||||
(0.20 × SLA compliance) +
|
||||
(0.20 × retention) +
|
||||
(0.15 × engineer productivity) +
|
||||
(0.10 × conversion rate) +
|
||||
(0.10 × incident stability)
|
||||
|
||||
|
||||
---
|
||||
|
||||
Интерпретация:
|
||||
|
||||
SHS состояние
|
||||
|
||||
85–100 масштабируемый рост
|
||||
70–85 стабильный бизнес
|
||||
50–70 проблемы в системе
|
||||
<50 системный кризис
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
5. КЛЮЧЕВЫЕ ГРАФИКИ CEO (ДОСКА УПРАВЛЕНИЯ)
|
||||
|
||||
|
||||
---
|
||||
|
||||
5.1 MRR Growth Curve
|
||||
|
||||
📈 рост повторного дохода
|
||||
|
||||
|
||||
---
|
||||
|
||||
5.2 SLA Compliance Heatmap
|
||||
|
||||
🟥 красный = проблемные инженеры
|
||||
🟩 зелёный = сильные
|
||||
|
||||
|
||||
---
|
||||
|
||||
5.3 Client Retention Funnel
|
||||
|
||||
📊 где теряются клиенты
|
||||
|
||||
|
||||
---
|
||||
|
||||
5.4 Engineer Performance Ranking
|
||||
|
||||
📊 топ / низ производительности
|
||||
|
||||
|
||||
---
|
||||
|
||||
5.5 Incident Map
|
||||
|
||||
📍 какие объекты ломаются чаще
|
||||
|
||||
|
||||
---
|
||||
|
||||
5.6 Cost vs Revenue per Object
|
||||
|
||||
📊 прибыльность каждого SLA
|
||||
|
||||
|
||||
---
|
||||
|
||||
6. КРИТИЧЕСКАЯ ЛОГИКА УПРАВЛЕНИЯ
|
||||
|
||||
Ты управляешь не людьми.
|
||||
|
||||
Ты управляешь:
|
||||
|
||||
рисками → SLA → деньгами → нагрузкой инженеров
|
||||
|
||||
|
||||
---
|
||||
|
||||
7. ЧТО ТЕБЕ ОБЯЗАТЕЛЬНО ВИДЕТЬ КАЖДЫЙ ДЕНЬ
|
||||
|
||||
|
||||
---
|
||||
|
||||
DAILY CEO DASHBOARD:
|
||||
|
||||
SLA compliance
|
||||
|
||||
аварии за 24ч
|
||||
|
||||
новые SLA контракты
|
||||
|
||||
просрочки
|
||||
|
||||
перегруз инженеров
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
8. ЧТО ТЕБЕ НУЖНО ВИДЕТЬ РАЗ В НЕДЕЛЮ
|
||||
|
||||
|
||||
---
|
||||
|
||||
MRR рост
|
||||
|
||||
retention
|
||||
|
||||
эффективность инженеров
|
||||
|
||||
конверсия аудита в SLA
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
9. ЧТО СМОТРЕТЬ РАЗ В МЕСЯЦ
|
||||
|
||||
|
||||
---
|
||||
|
||||
прибыльность объектов
|
||||
|
||||
эффективность регионов
|
||||
|
||||
нагрузка команды
|
||||
|
||||
системные сбои
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
10. ГЛАВНЫЙ ПРИНЦИП
|
||||
|
||||
Ты не управляешь:
|
||||
|
||||
❌ монтажами
|
||||
❌ выездами
|
||||
❌ людьми
|
||||
|
||||
|
||||
---
|
||||
|
||||
Ты управляешь:
|
||||
|
||||
системой инженерной надежности объектов бизнеса
|
||||
|
||||
|
||||
---
|
||||
|
||||
11. ЕСЛИ СВЯЗАТЬ ВСЁ В ОДНУ МОДЕЛЬ
|
||||
|
||||
Аудит → Risk Score → SLA цена → контракт → MRR → KPI инженеров → retention → рост
|
||||
|
||||
|
||||
---
|
||||
|
||||
12. ИТОГ
|
||||
|
||||
Ты как CEO должен видеть не “что происходит”, а:
|
||||
|
||||
> где именно в системе возникает прибыль или утечка денег/риска
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
13. ЕСЛИ ДАЛЬШЕ РАЗВИВАТЬ СИСТЕМУ
|
||||
|
||||
Я могу собрать:
|
||||
|
||||
полноценный CEO-dashboard (Excel / Notion / Power BI)
|
||||
|
||||
автоматическую систему расчёта SHS
|
||||
|
||||
дашборд инженеров в реальном времени
|
||||
|
||||
модель прогнозирования MRR на 3–6 месяцев
|
||||
|
||||
систему раннего предупреждения потерь клиентов
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Если коротко:
|
||||
|
||||
ты строишь не компанию — ты строишь управляемую инженерную систему с финансовыми законами внутри неё.
|
||||
@@ -0,0 +1,488 @@
|
||||
Сейчас мы подходим к одному из самых важных этапов.
|
||||
Потому что SEO для тебя — это НЕ “трафик ради трафика”.
|
||||
|
||||
Тебе не нужны:
|
||||
|
||||
- тысячи посетителей;
|
||||
- B2C заявки;
|
||||
- мусорные лиды.
|
||||
|
||||
Тебе нужен:
|
||||
|
||||
# узкий B2B SEO с высокой экспертностью.
|
||||
|
||||
И здесь у тебя огромный шанс, потому что рынок безопасности:
|
||||
|
||||
# SEO делает ужасно.
|
||||
|
||||
Большинство сайтов:
|
||||
|
||||
- про “монтаж камер”;
|
||||
- про оборудование;
|
||||
- про бренды;
|
||||
- про “низкие цены”.
|
||||
|
||||
А ты можешь занять:
|
||||
|
||||
# нишу инженерной эксплуатации.
|
||||
|
||||
---
|
||||
|
||||
# ГЛАВНАЯ СТРАТЕГИЯ SEO
|
||||
|
||||
---
|
||||
|
||||
# НЕ ПРОДАВАТЬ:
|
||||
|
||||
- камеры;
|
||||
- оборудование;
|
||||
- монтаж.
|
||||
|
||||
---
|
||||
|
||||
# ПРОДАВАТЬ:
|
||||
|
||||
- эксплуатацию;
|
||||
- SLA;
|
||||
- аудит;
|
||||
- контроль;
|
||||
- сопровождение;
|
||||
- надежность.
|
||||
|
||||
---
|
||||
|
||||
# ТВОЯ SEO-МОДЕЛЬ
|
||||
|
||||
---
|
||||
|
||||
# УРОВЕНЬ 1
|
||||
|
||||
# КОММЕРЧЕСКИЕ СТРАНИЦЫ
|
||||
|
||||
Это:
|
||||
|
||||
# страницы услуг.
|
||||
|
||||
Они приводят клиентов.
|
||||
|
||||
---
|
||||
|
||||
# УРОВЕНЬ 2
|
||||
|
||||
# ОТРАСЛЕВЫЕ СТРАНИЦЫ
|
||||
|
||||
Это:
|
||||
|
||||
# страницы под конкретный бизнес.
|
||||
|
||||
Они повышают доверие и SEO.
|
||||
|
||||
---
|
||||
|
||||
# УРОВЕНЬ 3
|
||||
|
||||
# ЭКСПЕРТНЫЙ БЛОГ
|
||||
|
||||
Это:
|
||||
|
||||
# двигатель доверия.
|
||||
|
||||
---
|
||||
|
||||
# СТРУКТУРА САЙТА
|
||||
|
||||
Вот идеальная структура для тебя.
|
||||
|
||||
---
|
||||
|
||||
# ГЛАВНАЯ
|
||||
|
||||
## URL:
|
||||
|
||||
`/`
|
||||
|
||||
---
|
||||
|
||||
## Цель:
|
||||
|
||||
- показать позиционирование;
|
||||
- перевести из “монтажников”;
|
||||
- дать B2B доверие.
|
||||
|
||||
---
|
||||
|
||||
# РАЗДЕЛ УСЛУГ
|
||||
|
||||
---
|
||||
|
||||
## `/services/`
|
||||
|
||||
Общая страница услуг.
|
||||
|
||||
---
|
||||
|
||||
# ОСНОВНЫЕ СТРАНИЦЫ
|
||||
|
||||
---
|
||||
|
||||
## `/services/audit/`
|
||||
|
||||
# Технический аудит систем безопасности
|
||||
|
||||
---
|
||||
|
||||
## `/services/sla/`
|
||||
|
||||
# SLA сопровождение объектов
|
||||
|
||||
---
|
||||
|
||||
## `/services/maintenance/`
|
||||
|
||||
# Техническое обслуживание систем безопасности
|
||||
|
||||
---
|
||||
|
||||
## `/services/external-engineer/`
|
||||
|
||||
# Внешний инженер безопасности
|
||||
|
||||
---
|
||||
|
||||
## `/services/recovery/`
|
||||
|
||||
# Восстановление проблемных объектов
|
||||
|
||||
---
|
||||
|
||||
## `/services/fire-alarm/`
|
||||
|
||||
# Обслуживание пожарной сигнализации
|
||||
|
||||
---
|
||||
|
||||
## `/services/video-surveillance/`
|
||||
|
||||
# Эксплуатация видеонаблюдения
|
||||
|
||||
---
|
||||
|
||||
## `/services/access-control/`
|
||||
|
||||
# Обслуживание СКУД
|
||||
|
||||
---
|
||||
|
||||
# ОТРАСЛЕВЫЕ СТРАНИЦЫ
|
||||
|
||||
Это очень важно.
|
||||
|
||||
---
|
||||
|
||||
## `/industries/hotels/`
|
||||
|
||||
# Системы безопасности гостиниц
|
||||
|
||||
---
|
||||
|
||||
## `/industries/logistics/`
|
||||
|
||||
# Склады и логистика
|
||||
|
||||
---
|
||||
|
||||
## `/industries/medical/`
|
||||
|
||||
# Клиники и медцентры
|
||||
|
||||
---
|
||||
|
||||
## `/industries/commercial/`
|
||||
|
||||
# Коммерческая недвижимость
|
||||
|
||||
---
|
||||
|
||||
## `/industries/agro/`
|
||||
|
||||
# Агропредприятия
|
||||
|
||||
---
|
||||
|
||||
# БЛОГ
|
||||
|
||||
---
|
||||
|
||||
## `/blog/`
|
||||
|
||||
---
|
||||
|
||||
# КАТЕГОРИИ
|
||||
|
||||
---
|
||||
|
||||
## `/blog/video/`
|
||||
|
||||
Проблемы видеонаблюдения.
|
||||
|
||||
---
|
||||
|
||||
## `/blog/fire-alarm/`
|
||||
|
||||
Пожарная безопасность.
|
||||
|
||||
---
|
||||
|
||||
## `/blog/sla/`
|
||||
|
||||
Эксплуатация и SLA.
|
||||
|
||||
---
|
||||
|
||||
## `/blog/audit/`
|
||||
|
||||
Технический аудит.
|
||||
|
||||
---
|
||||
|
||||
# ПОЧЕМУ ЭТО ТАК ВАЖНО
|
||||
|
||||
Google и Яндекс сейчас любят:
|
||||
|
||||
- структуру;
|
||||
- экспертность;
|
||||
- тематичность;
|
||||
- глубину.
|
||||
|
||||
---
|
||||
|
||||
# ЧТО НЕЛЬЗЯ ДЕЛАТЬ
|
||||
|
||||
---
|
||||
|
||||
# НЕ ДЕЛАТЬ:
|
||||
|
||||
- 1 страницу “все услуги”;
|
||||
- короткие SEO-тексты;
|
||||
- переспам;
|
||||
- “установка камер Краснодар”.
|
||||
|
||||
Это мусорный рынок.
|
||||
|
||||
---
|
||||
|
||||
# ТВОЯ SEO-СТРАТЕГИЯ
|
||||
|
||||
---
|
||||
|
||||
# НЕ:
|
||||
|
||||
“дешевый монтаж”
|
||||
|
||||
---
|
||||
|
||||
# А:
|
||||
|
||||
# “эксплуатационные риски объектов”.
|
||||
|
||||
---
|
||||
|
||||
# ГЛАВНЫЕ SEO КЛЮЧИ
|
||||
|
||||
Вот где деньги.
|
||||
|
||||
---
|
||||
|
||||
# АУДИТ
|
||||
|
||||
- аудит систем безопасности
|
||||
- технический аудит объекта
|
||||
- аудит видеонаблюдения
|
||||
- аудит пожарной сигнализации
|
||||
- проверка систем безопасности
|
||||
|
||||
---
|
||||
|
||||
# SLA
|
||||
|
||||
- SLA обслуживание
|
||||
- сопровождение систем безопасности
|
||||
- техническое сопровождение объекта
|
||||
- эксплуатация систем безопасности
|
||||
|
||||
---
|
||||
|
||||
# ОБСЛУЖИВАНИЕ
|
||||
|
||||
- обслуживание пожарной сигнализации Краснодар
|
||||
- обслуживание видеонаблюдения Краснодар
|
||||
- обслуживание СКУД Краснодар
|
||||
|
||||
---
|
||||
|
||||
# ОТРАСЛЕВЫЕ
|
||||
|
||||
- системы безопасности гостиниц
|
||||
- обслуживание гостиниц Краснодар
|
||||
- безопасность складов Краснодар
|
||||
|
||||
---
|
||||
|
||||
# ТЕПЕРЬ ГЛАВНОЕ
|
||||
|
||||
# КАК ПИСАТЬ SEO-ТЕКСТЫ
|
||||
|
||||
---
|
||||
|
||||
# ТВОЯ ЦЕЛЬ
|
||||
|
||||
НЕ: “набить ключи”.
|
||||
|
||||
---
|
||||
|
||||
# А:
|
||||
|
||||
# показать инженерную экспертность.
|
||||
|
||||
---
|
||||
|
||||
# ПРИМЕР SEO-ТЕКСТА
|
||||
|
||||
---
|
||||
|
||||
---
|
||||
|
||||
# ТЕПЕРЬ:
|
||||
|
||||
# КОД СТРАНИЦЫ УСЛУГИ
|
||||
|
||||
Например:
|
||||
|
||||
# `/services/audit/index.php`
|
||||
|
||||
---
|
||||
|
||||
---
|
||||
|
||||
# SEO РЕКОМЕНДАЦИИ ПО ТЕХНИЧЕСКОЙ ЧАСТИ
|
||||
|
||||
---
|
||||
|
||||
# ОБЯЗАТЕЛЬНО:
|
||||
|
||||
---
|
||||
|
||||
# 1. ЧПУ URL
|
||||
|
||||
---
|
||||
|
||||
# ХОРОШО:
|
||||
|
||||
`/services/audit/`
|
||||
|
||||
---
|
||||
|
||||
# ПЛОХО:
|
||||
|
||||
`/page.php?id=123`
|
||||
|
||||
---
|
||||
|
||||
# 2. TITLE И DESCRIPTION
|
||||
|
||||
Для каждой страницы.
|
||||
|
||||
---
|
||||
|
||||
# Пример:
|
||||
|
||||
## TITLE:
|
||||
|
||||
Технический аудит систем безопасности в Краснодаре
|
||||
|
||||
---
|
||||
|
||||
## DESCRIPTION:
|
||||
|
||||
Проверка состояния систем безопасности коммерческих объектов. Аудит видеонаблюдения, СКУД и пожарной сигнализации.
|
||||
|
||||
---
|
||||
|
||||
# 3. H1 ТОЛЬКО ОДИН
|
||||
|
||||
Это важно.
|
||||
|
||||
---
|
||||
|
||||
# 4. schema.org
|
||||
|
||||
Очень желательно.
|
||||
|
||||
---
|
||||
|
||||
# 5. СКОРОСТЬ
|
||||
|
||||
Не перегружать:
|
||||
|
||||
- анимацией;
|
||||
- тяжелыми видео;
|
||||
- конструкторами.
|
||||
|
||||
---
|
||||
|
||||
# 6. GEO SEO
|
||||
|
||||
На каждой странице:
|
||||
|
||||
- Краснодар;
|
||||
- Краснодарский край.
|
||||
|
||||
---
|
||||
|
||||
# 7. ВНУТРЕННЯЯ ПЕРЕЛИНКОВКА
|
||||
|
||||
Например:
|
||||
|
||||
- из статьи → на аудит;
|
||||
- из отрасли → на SLA;
|
||||
- из кейса → на услугу.
|
||||
|
||||
---
|
||||
|
||||
# ЧТО ДАСТ РЕАЛЬНЫЙ РОСТ
|
||||
|
||||
---
|
||||
|
||||
# НЕ:
|
||||
|
||||
- покупка ссылок;
|
||||
- SEO-магия.
|
||||
|
||||
---
|
||||
|
||||
# А:
|
||||
|
||||
- экспертные статьи;
|
||||
- кейсы;
|
||||
- отраслевые страницы;
|
||||
- техническая глубина;
|
||||
- регулярность.
|
||||
|
||||
---
|
||||
|
||||
# САМОЕ ВАЖНОЕ
|
||||
|
||||
Ты должен выглядеть:
|
||||
|
||||
# не как “сайт монтажников”.
|
||||
|
||||
А как:
|
||||
|
||||
# инженерная эксплуатационная компания.
|
||||
|
||||
И это:
|
||||
|
||||
- редкость;
|
||||
- слабоконкурентная ниша;
|
||||
- высокий уровень доверия;
|
||||
- хороший B2B SEO.
|
||||
@@ -0,0 +1,795 @@
|
||||
SLA — ЭТО ОСНОВА ТВОЕГО ПЕРЕХОДА ИЗ “МОНТАЖНИКОВ” В B2B-СЕРВИС
|
||||
|
||||
Большинство компаний безопасности в Краснодарском крае:
|
||||
|
||||
“иногда приезжают”;
|
||||
|
||||
“что-то смотрят”;
|
||||
|
||||
“делают отметку”;
|
||||
|
||||
работают хаотично.
|
||||
|
||||
|
||||
SLA делает тебя:
|
||||
|
||||
инженерной сервисной компанией;
|
||||
|
||||
предсказуемым подрядчиком;
|
||||
|
||||
частью эксплуатации бизнеса клиента.
|
||||
|
||||
|
||||
Именно SLA позволяет:
|
||||
|
||||
продавать дороже;
|
||||
|
||||
получать абонентку;
|
||||
|
||||
заходить в сети;
|
||||
|
||||
работать с коммерческой недвижимостью;
|
||||
|
||||
уходить от демпинга.
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
ЧТО ТАКОЕ SLA ПРОСТЫМИ СЛОВАМИ
|
||||
|
||||
SLA (Service Level Agreement)
|
||||
|
||||
это:
|
||||
|
||||
соглашение об уровне сервиса.
|
||||
|
||||
То есть: ты заранее фиксируешь:
|
||||
|
||||
что обслуживаешь;
|
||||
|
||||
как быстро реагируешь;
|
||||
|
||||
что считается аварией;
|
||||
|
||||
что входит в обслуживание;
|
||||
|
||||
какие обязательства у сторон.
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
ПОЧЕМУ B2B ЭТО ЛЮБИТ
|
||||
|
||||
Потому что бизнес покупает:
|
||||
|
||||
предсказуемость;
|
||||
|
||||
контроль;
|
||||
|
||||
ответственность;
|
||||
|
||||
понятные сроки.
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
ТВОЯ ЦЕЛЬ
|
||||
|
||||
НЕ:
|
||||
|
||||
> “мы обслуживаем камеры”
|
||||
|
||||
|
||||
|
||||
А:
|
||||
|
||||
“мы гарантируем работоспособность критической инфраструктуры объекта”.
|
||||
|
||||
|
||||
---
|
||||
|
||||
КАК SLA ПОДНИМАЕТ ТЕБЯ НАД РЫНКОМ
|
||||
|
||||
Без SLA:
|
||||
|
||||
“звоните если что”.
|
||||
|
||||
С SLA:
|
||||
|
||||
регламенты;
|
||||
|
||||
сроки реакции;
|
||||
|
||||
журналирование;
|
||||
|
||||
прозрачность;
|
||||
|
||||
ответственность.
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
ГЛАВНАЯ ОШИБКА
|
||||
|
||||
Многие делают:
|
||||
|
||||
> “приедем в течение суток”.
|
||||
|
||||
|
||||
|
||||
Это НЕ SLA.
|
||||
|
||||
|
||||
---
|
||||
|
||||
НАСТОЯЩИЙ SLA ВКЛЮЧАЕТ
|
||||
|
||||
|
||||
---
|
||||
|
||||
1. КЛАССИФИКАЦИЮ ИНЦИДЕНТОВ
|
||||
|
||||
Например:
|
||||
|
||||
Приоритет Пример Реакция
|
||||
|
||||
P1 Критический Не работает пожарка 2 часа
|
||||
P2 Высокий Нет архива камер 4 часа
|
||||
P3 Средний Частично не работает СКУД 24 часа
|
||||
P4 Низкий Настройка доступа Планово
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
2. ВРЕМЯ РЕАКЦИИ
|
||||
|
||||
Очень важно: не “устранения”.
|
||||
|
||||
А:
|
||||
|
||||
начала работ.
|
||||
|
||||
|
||||
---
|
||||
|
||||
3. РЕГЛАМЕНТНЫЕ РАБОТЫ
|
||||
|
||||
Например:
|
||||
|
||||
ежемесячные проверки;
|
||||
|
||||
тестирование;
|
||||
|
||||
резервное копирование;
|
||||
|
||||
контроль архивов;
|
||||
|
||||
проверка питания;
|
||||
|
||||
чистка;
|
||||
|
||||
тест тревог.
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
4. ОТЧЕТНОСТЬ
|
||||
|
||||
Это критично.
|
||||
|
||||
Ты должен быть:
|
||||
|
||||
“прозрачным подрядчиком”.
|
||||
|
||||
|
||||
---
|
||||
|
||||
5. SLA ПО КАНАЛАМ СВЯЗИ
|
||||
|
||||
Например:
|
||||
|
||||
Telegram;
|
||||
|
||||
email;
|
||||
|
||||
аварийный телефон;
|
||||
|
||||
сервисный портал.
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
6. SLA ПО ДОСТУПНОСТИ
|
||||
|
||||
Вот тут начинаются большие чеки.
|
||||
|
||||
Например:
|
||||
|
||||
Система Целевая доступность
|
||||
|
||||
Пожарка 99.9%
|
||||
Видеонаблюдение 99%
|
||||
СКУД 99%
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
ТЕПЕРЬ ГЛАВНОЕ:
|
||||
|
||||
КАК ТЕБЕ ДЕЛАТЬ SLA В РЕАЛЬНОСТИ
|
||||
|
||||
Тебе НЕ нужен корпоративный монстр.
|
||||
|
||||
Тебе нужна:
|
||||
|
||||
простая инженерная система.
|
||||
|
||||
|
||||
---
|
||||
|
||||
БАЗОВАЯ МОДЕЛЬ SLA ДЛЯ ТЕБЯ
|
||||
|
||||
|
||||
---
|
||||
|
||||
START SLA
|
||||
|
||||
Для:
|
||||
|
||||
небольших объектов;
|
||||
|
||||
офисов;
|
||||
|
||||
клиник;
|
||||
|
||||
магазинов.
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Реакция:
|
||||
|
||||
до 24 часов
|
||||
|
||||
|
||||
---
|
||||
|
||||
Регламент:
|
||||
|
||||
1 раз в месяц.
|
||||
|
||||
|
||||
---
|
||||
|
||||
Что входит:
|
||||
|
||||
проверка состояния;
|
||||
|
||||
диагностика;
|
||||
|
||||
журнал;
|
||||
|
||||
рекомендации;
|
||||
|
||||
консультации.
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Стоимость:
|
||||
|
||||
25–40 тыс ₽/мес
|
||||
|
||||
Для Краснодара — нормально для качественного B2B.
|
||||
|
||||
|
||||
---
|
||||
|
||||
BUSINESS SLA
|
||||
|
||||
Твой основной продукт.
|
||||
|
||||
|
||||
---
|
||||
|
||||
Реакция:
|
||||
|
||||
критическая авария — 4 часа;
|
||||
|
||||
обычная — 24 часа.
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Регламент:
|
||||
|
||||
2–4 раза в месяц.
|
||||
|
||||
|
||||
---
|
||||
|
||||
Входит:
|
||||
|
||||
аварийные выезды;
|
||||
|
||||
удаленная диагностика;
|
||||
|
||||
контроль архива;
|
||||
|
||||
контроль питания;
|
||||
|
||||
фотоотчеты;
|
||||
|
||||
журнал;
|
||||
|
||||
рекомендации;
|
||||
|
||||
сопровождение проверок.
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Стоимость:
|
||||
|
||||
60–120 тыс ₽/мес
|
||||
|
||||
Для:
|
||||
|
||||
гостиниц;
|
||||
|
||||
складов;
|
||||
|
||||
коммерческой недвижимости.
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
ENTERPRISE SLA
|
||||
|
||||
Вот это путь к большим деньгам.
|
||||
|
||||
|
||||
---
|
||||
|
||||
Реакция:
|
||||
|
||||
2 часа
|
||||
|
||||
|
||||
---
|
||||
|
||||
Формат:
|
||||
|
||||
“внешний инженерный отдел”.
|
||||
|
||||
|
||||
---
|
||||
|
||||
Входит:
|
||||
|
||||
постоянный контроль;
|
||||
|
||||
участие в эксплуатации;
|
||||
|
||||
работа с подрядчиками;
|
||||
|
||||
аудит;
|
||||
|
||||
сопровождение модернизаций;
|
||||
|
||||
приемка;
|
||||
|
||||
развитие систем.
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Стоимость:
|
||||
|
||||
180–500 тыс ₽/мес
|
||||
|
||||
|
||||
---
|
||||
|
||||
ВАЖНО:
|
||||
|
||||
SLA НЕЛЬЗЯ ПРОДАВАТЬ КАК “ТО”
|
||||
|
||||
Иначе: ты вернешься в дешевый рынок.
|
||||
|
||||
|
||||
---
|
||||
|
||||
SLA ПРОДАЕТСЯ КАК:
|
||||
|
||||
“управление рисками объекта”.
|
||||
|
||||
|
||||
---
|
||||
|
||||
ПРИМЕР ТЕКСТА ДЛЯ САЙТА
|
||||
|
||||
|
||||
---
|
||||
|
||||
SLA-сопровождение систем безопасности
|
||||
|
||||
Мы работаем по регламентированным SLA-моделям обслуживания.
|
||||
|
||||
Это означает:
|
||||
— фиксированное время реакции;
|
||||
— контроль состояния систем;
|
||||
— прозрачную отчетность;
|
||||
— регламентные проверки;
|
||||
— ответственность за работоспособность инфраструктуры объекта.
|
||||
|
||||
SLA позволяет снизить риски простоев, исключить скрытые неисправности и обеспечить стабильную эксплуатацию систем безопасности.
|
||||
|
||||
Для каждого объекта разрабатывается индивидуальный регламент обслуживания.
|
||||
---
|
||||
|
||||
ПРИМЕР SLA ТАБЛИЦЫ ДЛЯ САЙТА
|
||||
|
||||
|
||||
---
|
||||
|
||||
Приоритет| Описание| Реакция
|
||||
P1| Полный отказ критической системы| до 2 часов
|
||||
P2| Частичная потеря функционала| до 4 часов
|
||||
P3| Некритичная неисправность| до 24 часов
|
||||
P4| Плановые работы и настройки| по графику
|
||||
---
|
||||
|
||||
ТЕПЕРЬ САМОЕ ВАЖНОЕ
|
||||
|
||||
КАК ТЕБЕ СЧИТАТЬ ЦЕНУ SLA
|
||||
|
||||
Не “от количества камер”.
|
||||
|
||||
Это ошибка рынка.
|
||||
|
||||
|
||||
---
|
||||
|
||||
ТВОЯ МОДЕЛЬ ЦЕНООБРАЗОВАНИЯ
|
||||
|
||||
Цена считается по:
|
||||
|
||||
критичности объекта;
|
||||
|
||||
количеству систем;
|
||||
|
||||
SLA;
|
||||
|
||||
расстоянию;
|
||||
|
||||
времени реакции;
|
||||
|
||||
рискам;
|
||||
|
||||
сложности эксплуатации.
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
МОДЕЛЬ ДЛЯ КРАСНОДАРСКОГО КРАЯ
|
||||
|
||||
|
||||
---
|
||||
|
||||
КРАСНОДАР
|
||||
|
||||
Можно:
|
||||
|
||||
быстрые выезды;
|
||||
|
||||
дешевле логистика.
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
СОЧИ
|
||||
|
||||
Цена должна быть:
|
||||
|
||||
выше на 30–50%.
|
||||
|
||||
Из-за:
|
||||
|
||||
логистики;
|
||||
|
||||
сезонности;
|
||||
|
||||
срочности.
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
УДАЛЕННЫЕ РАЙОНЫ
|
||||
|
||||
Нужно:
|
||||
|
||||
отдельное SLA.
|
||||
|
||||
|
||||
---
|
||||
|
||||
Например:
|
||||
|
||||
Базовая реакция:
|
||||
|
||||
24 часа.
|
||||
|
||||
Срочный выезд:
|
||||
|
||||
дополнительная ставка.
|
||||
|
||||
|
||||
---
|
||||
|
||||
КАК СЧИТАТЬ SLA
|
||||
|
||||
Вот модель.
|
||||
|
||||
|
||||
---
|
||||
|
||||
БАЗА
|
||||
|
||||
Например:
|
||||
|
||||
35 000 ₽
|
||||
|
||||
|
||||
---
|
||||
|
||||
ПЛЮС:
|
||||
|
||||
Параметр Доплата
|
||||
|
||||
24/7 доступность +20%
|
||||
SLA 2 часа +35%
|
||||
Удаленный район +15–40%
|
||||
Несколько объектов индивидуально
|
||||
Высокая критичность +25%
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
ПРИМЕР
|
||||
|
||||
Гостиница:
|
||||
|
||||
64 камеры;
|
||||
|
||||
СКУД;
|
||||
|
||||
пожарка;
|
||||
|
||||
архив;
|
||||
|
||||
Краснодар.
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
SLA:
|
||||
|
||||
4 часа.
|
||||
|
||||
|
||||
---
|
||||
|
||||
Цена:
|
||||
|
||||
85–120 тыс ₽/мес
|
||||
|
||||
И это нормальный рынок для качественного сервиса.
|
||||
|
||||
|
||||
---
|
||||
|
||||
ТЕПЕРЬ САМОЕ ВАЖНОЕ
|
||||
|
||||
КАК ТЕБЕ ВЫПОЛНЯТЬ SLA БЕЗ БОЛИ
|
||||
|
||||
|
||||
---
|
||||
|
||||
НЕ БРАТЬ ВСЕХ ПОДРЯД
|
||||
|
||||
Только:
|
||||
|
||||
нормальные объекты;
|
||||
|
||||
нормальные бюджеты;
|
||||
|
||||
адекватные заказчики.
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
НЕ ПРОДАВАТЬ “ДЕШЕВО”
|
||||
|
||||
Иначе SLA развалится.
|
||||
|
||||
|
||||
---
|
||||
|
||||
ОБЯЗАТЕЛЬНО:
|
||||
|
||||
журнал заявок;
|
||||
|
||||
регламент;
|
||||
|
||||
чек-листы;
|
||||
|
||||
фотофиксация;
|
||||
|
||||
история обслуживания.
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
ТЕХНИЧЕСКИ ТЕБЕ НУЖНО
|
||||
|
||||
|
||||
---
|
||||
|
||||
1. HELP DESK
|
||||
|
||||
Минимум:
|
||||
|
||||
Telegram;
|
||||
|
||||
1С;
|
||||
|
||||
Google Sheets.
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Лучше:
|
||||
|
||||
GLPI;
|
||||
|
||||
Zammad;
|
||||
|
||||
Jira Service Desk.
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
2. БАЗА ОБЪЕКТОВ
|
||||
|
||||
Для каждого:
|
||||
|
||||
схемы;
|
||||
|
||||
пароли;
|
||||
|
||||
оборудование;
|
||||
|
||||
IP;
|
||||
|
||||
контакты;
|
||||
|
||||
история.
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
3. ЧЕК-ЛИСТЫ
|
||||
|
||||
Например:
|
||||
|
||||
Видеонаблюдение:
|
||||
|
||||
запись;
|
||||
|
||||
архив;
|
||||
|
||||
питание;
|
||||
|
||||
доступ;
|
||||
|
||||
фокус;
|
||||
|
||||
время.
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
4. SLA-ДОКУМЕНТ
|
||||
|
||||
Это обязательно.
|
||||
|
||||
|
||||
---
|
||||
|
||||
ПРИМЕР СТРУКТУРЫ SLA ДОГОВОРА
|
||||
|
||||
|
||||
---
|
||||
|
||||
1. Предмет SLA
|
||||
|
||||
Исполнитель обеспечивает техническое сопровождение
|
||||
и контроль работоспособности систем безопасности объекта.
|
||||
|
||||
2. Время реакции
|
||||
|
||||
P1 — до 2 часов
|
||||
P2 — до 4 часов
|
||||
P3 — до 24 часов
|
||||
|
||||
3. Регламентные работы
|
||||
|
||||
— диагностика
|
||||
— тестирование
|
||||
— проверка журналов
|
||||
— контроль архива
|
||||
— проверка питания
|
||||
|
||||
4. Отчетность
|
||||
|
||||
По результатам работ предоставляется отчет.
|
||||
|
||||
5. Ограничения SLA
|
||||
|
||||
SLA не распространяется на:
|
||||
— физическое повреждение оборудования
|
||||
— аварии электропитания
|
||||
— действия третьих лиц
|
||||
— форс-мажор
|
||||
---
|
||||
|
||||
ИТОГ
|
||||
|
||||
SLA — это:
|
||||
|
||||
не “дополнение”.
|
||||
|
||||
Это:
|
||||
|
||||
фундамент твоего нового бизнеса.
|
||||
|
||||
Именно SLA:
|
||||
|
||||
выводит тебя из монтажников;
|
||||
|
||||
делает recurring revenue;
|
||||
|
||||
дает стабильность;
|
||||
|
||||
повышает чек;
|
||||
|
||||
позволяет масштабироваться.
|
||||
|
||||
|
||||
И это идеально совпадает с твоим профилем инженера и системного человека.
|
||||
@@ -0,0 +1,69 @@
|
||||
# SQL-запросы для администрирования
|
||||
|
||||
## Как выполнить
|
||||
|
||||
1. Войдите в phpMyAdmin на хостинге
|
||||
2. Выберите базу данных `j30663893_engineering`
|
||||
3. Перейдите на вкладку «SQL»
|
||||
4. Вставьте запрос и нажмите «Вперёд»
|
||||
|
||||
## Смена пароля владельца
|
||||
|
||||
```sql
|
||||
UPDATE users
|
||||
SET password_hash = '$2y$10$e0MYzXyjpJS7k0ggKtqjGOcMFU.h9S1sGqf3qJ6qJ6qJ6qJ6qJ6qO'
|
||||
WHERE login = 'ваш_логин';
|
||||
```
|
||||
|
||||
**Важно:** Замените хеш на реальный. Для генерации хеша используйте PHP:
|
||||
|
||||
```php
|
||||
<?php echo password_hash('новый_пароль', PASSWORD_DEFAULT); ?>
|
||||
```
|
||||
|
||||
Создайте файл `hash.php` в корне сайта с этим кодом, откройте в браузере, скопируйте хеш, удалите файл.
|
||||
|
||||
## Разблокировка пользователя
|
||||
|
||||
```sql
|
||||
DELETE FROM login_attempts WHERE login = 'логин_пользователя';
|
||||
```
|
||||
|
||||
## Активация всех кейсов на главной
|
||||
|
||||
```sql
|
||||
UPDATE cases SET is_active = 1;
|
||||
```
|
||||
|
||||
## Просмотр всех пользователей
|
||||
|
||||
```sql
|
||||
SELECT id, login, role, full_name, is_active, created_at FROM users;
|
||||
```
|
||||
|
||||
## Просмотр активных SLA контрактов
|
||||
|
||||
```sql
|
||||
SELECT sc.id, sc.contract_number, o.name as object, sc.client_name,
|
||||
sc.sla_price_monthly, sc.start_date, sc.end_date, sc.status
|
||||
FROM sla_contracts sc
|
||||
JOIN objects o ON o.id = sc.object_id
|
||||
WHERE sc.status = 'active'
|
||||
ORDER BY sc.start_date DESC;
|
||||
```
|
||||
|
||||
## Сброс опросника (удаление черновиков)
|
||||
|
||||
```sql
|
||||
DELETE qs, qa
|
||||
FROM questionnaire_sessions qs
|
||||
LEFT JOIN questionnaire_answers qa ON qa.session_id = qs.id
|
||||
WHERE qs.status != 'completed';
|
||||
```
|
||||
|
||||
## Просмотр документов и прав
|
||||
|
||||
```sql
|
||||
-- Файлы в базе не хранятся. Проверьте папку service/docs/ на хостинге.
|
||||
-- Права хранятся в service/permissions/docs_permissions.json
|
||||
```
|
||||
@@ -0,0 +1,934 @@
|
||||
Хорошо, это важный шаг — ты фактически выбираешь архитектуру бренда (brand architecture), а не просто название. От этого зависит:
|
||||
|
||||
как тебя воспринимают (монтажники vs инженерная компания),
|
||||
|
||||
как ты продаёшь SLA,
|
||||
|
||||
насколько легко масштабируешься по РФ.
|
||||
|
||||
|
||||
Я разложу каждый вариант строго по твоей модели:
|
||||
👉 аудит → эксплуатация → SLA → инженерный сервис → масштабирование
|
||||
|
||||
|
||||
---
|
||||
|
||||
1. AegisOne Engineering
|
||||
|
||||
Суть позиционирования:
|
||||
|
||||
инженерная компания полного цикла
|
||||
|
||||
|
||||
---
|
||||
|
||||
Как воспринимается рынком:
|
||||
|
||||
“серьёзная инженерная организация”
|
||||
|
||||
ближе к проектированию / эксплуатации
|
||||
|
||||
высокий уровень доверия B2B
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Сильные стороны:
|
||||
|
||||
подходит под SLA и аудит
|
||||
|
||||
звучит “дорого и системно”
|
||||
|
||||
легко масштабируется на РФ
|
||||
|
||||
не привязан к монтажу
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Слабые стороны:
|
||||
|
||||
не сразу понятно “сервис”
|
||||
|
||||
нужно объяснение через сайт/контент
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Лучше всего подходит для:
|
||||
|
||||
✔ SLA обслуживание
|
||||
✔ аудит объектов
|
||||
✔ эксплуатация систем безопасности
|
||||
✔ B2B рынок (гостиницы, склады, УК)
|
||||
|
||||
|
||||
---
|
||||
|
||||
Итог:
|
||||
|
||||
> ❗ ЛУЧШИЙ ОСНОВНОЙ БРЕНД (ядро компании)
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
2. AegisOne Service
|
||||
|
||||
Суть:
|
||||
|
||||
сервисная эксплуатационная компания
|
||||
|
||||
|
||||
---
|
||||
|
||||
Восприятие:
|
||||
|
||||
обслуживание
|
||||
|
||||
ремонт
|
||||
|
||||
“сервисники”
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Сильные стороны:
|
||||
|
||||
понятный вход для клиентов
|
||||
|
||||
хорошо продаёт обслуживание
|
||||
|
||||
легко объяснить
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Слабые стороны:
|
||||
|
||||
слишком “сервис/ремонт”
|
||||
|
||||
занижает статус инженера
|
||||
|
||||
хуже для крупных B2B объектов
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Лучше для:
|
||||
|
||||
✔ абонентское обслуживание
|
||||
✔ выездной сервис
|
||||
✔ мелкие и средние клиенты
|
||||
✔ поддержка SLA как продукт
|
||||
|
||||
|
||||
---
|
||||
|
||||
Итог:
|
||||
|
||||
> ⚠ можно как подразделение, но не основной бренд
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
3. AegisOne Security Engineering
|
||||
|
||||
Суть:
|
||||
|
||||
инженерия безопасности (очень сильный B2B бренд)
|
||||
|
||||
|
||||
---
|
||||
|
||||
Восприятие:
|
||||
|
||||
высокий уровень экспертизы
|
||||
|
||||
ближе к проектированию и системной безопасности
|
||||
|
||||
звучит “международно”
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Сильные стороны:
|
||||
|
||||
максимальная экспертность
|
||||
|
||||
идеально под аудит и SLA
|
||||
|
||||
хорошо для РФ + будущего выхода за регион
|
||||
|
||||
не “монтажники”
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Слабые стороны:
|
||||
|
||||
длинное название
|
||||
|
||||
чуть тяжеловесно в маркетинге
|
||||
|
||||
требует сокращений (AegisOne SE)
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Лучше для:
|
||||
|
||||
✔ аудит
|
||||
✔ техническая экспертиза
|
||||
✔ корпоративные объекты
|
||||
✔ крупные B2B сделки
|
||||
✔ федеральное масштабирование
|
||||
|
||||
|
||||
---
|
||||
|
||||
Итог:
|
||||
|
||||
> ⭐ ЛУЧШИЙ ДЛЯ ЭКСПЕРТНОСТИ И PREMIUM B2B
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
4. AegisOne Facility Security
|
||||
|
||||
Суть:
|
||||
|
||||
безопасность объектов (facility management)
|
||||
|
||||
|
||||
---
|
||||
|
||||
Восприятие:
|
||||
|
||||
управление объектами
|
||||
|
||||
эксплуатация зданий
|
||||
|
||||
FM-компании уровня “facility management”
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Сильные стороны:
|
||||
|
||||
очень сильный корпоративный сегмент
|
||||
|
||||
подходит для УК, ТЦ, гостиниц
|
||||
|
||||
легко встраивается в FM-рынок
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Слабые стороны:
|
||||
|
||||
менее технический фокус
|
||||
|
||||
может размывать “инженерность”
|
||||
|
||||
ближе к управлению недвижимостью
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Лучше для:
|
||||
|
||||
✔ управляющие компании
|
||||
✔ гостиничные сети
|
||||
✔ торговые центры
|
||||
✔ facility management подрядчики
|
||||
|
||||
|
||||
---
|
||||
|
||||
Итог:
|
||||
|
||||
> ⚠ хорошо как направление, но не ядро
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
5. AegisOne TechService
|
||||
|
||||
Суть:
|
||||
|
||||
техсервис / техническое обслуживание
|
||||
|
||||
|
||||
---
|
||||
|
||||
Восприятие:
|
||||
|
||||
ремонтная служба
|
||||
|
||||
IT/техподдержка стиль
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Сильные стороны:
|
||||
|
||||
простое и понятное
|
||||
|
||||
легко продаётся “в лоб”
|
||||
|
||||
подходит для мелких объектов
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Слабые стороны:
|
||||
|
||||
дешёвое восприятие
|
||||
|
||||
не тянет премиум SLA
|
||||
|
||||
теряет инженерный статус
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Лучше для:
|
||||
|
||||
✔ массовое обслуживание
|
||||
✔ низкий чек рынок
|
||||
✔ быстрые заявки
|
||||
✔ простые сервисные работы
|
||||
|
||||
|
||||
---
|
||||
|
||||
Итог:
|
||||
|
||||
> ❌ не подходит под твою стратегию роста
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
6. РЕКОМЕНТИРУЕМАЯ СТРУКТУРА БРЕНДА (ОПТИМАЛЬНАЯ)
|
||||
|
||||
Вот как это должно выглядеть в системе:
|
||||
|
||||
|
||||
---
|
||||
|
||||
🧠 ГЛАВНЫЙ БРЕНД (основа)
|
||||
|
||||
AegisOne Engineering
|
||||
|
||||
👉 ядро:
|
||||
|
||||
SLA
|
||||
|
||||
аудит
|
||||
|
||||
эксплуатация
|
||||
|
||||
инженерный контроль
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
🔧 СЕРВИСНОЕ ПОДРАЗДЕЛЕНИЕ
|
||||
|
||||
AegisOne Service
|
||||
|
||||
👉 внутри:
|
||||
|
||||
выезды
|
||||
|
||||
ремонт
|
||||
|
||||
поддержка
|
||||
|
||||
реакция по SLA
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
🧪 ЭКСПЕРТНЫЙ КОНТУР
|
||||
|
||||
AegisOne Security Engineering
|
||||
|
||||
👉 используется для:
|
||||
|
||||
сайта экспертного уровня
|
||||
|
||||
презентаций
|
||||
|
||||
коммерческих предложений
|
||||
|
||||
крупных B2B переговоров
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
🏢 ФУТУРОЛОГИЧЕСКИЙ КОНТУР (масштаб)
|
||||
|
||||
AegisOne Facility Security
|
||||
|
||||
👉 когда выйдешь в:
|
||||
|
||||
УК
|
||||
|
||||
сети отелей
|
||||
|
||||
FM-контракты
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
⚙️ ТЕХПОДДЕРЖКА (НЕ ОСНОВНАЯ)
|
||||
|
||||
AegisOne TechService
|
||||
|
||||
👉 можно использовать как:
|
||||
|
||||
внутренний бренд
|
||||
|
||||
дешёвый сегмент (если вдруг нужен)
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
7. ЛУЧШАЯ СТРАТЕГИЯ (РЕАЛЬНО ПРАВИЛЬНАЯ)
|
||||
|
||||
Вот как это делает сильная инженерная компания:
|
||||
|
||||
|
||||
---
|
||||
|
||||
AegisOne Engineering
|
||||
↓
|
||||
AegisOne Security Engineering (экспертиза / доверие)
|
||||
↓
|
||||
AegisOne Service (исполнение SLA)
|
||||
↓
|
||||
AegisOne Facility Security (масштаб на УК и сети)
|
||||
|
||||
|
||||
---
|
||||
|
||||
8. ВАЖНОЕ РЕШЕНИЕ ДЛЯ ТЕБЯ
|
||||
|
||||
Если брать твою стратегию:
|
||||
|
||||
уход от монтажа
|
||||
|
||||
переход в SLA
|
||||
|
||||
рост до 2–3 млн+
|
||||
|
||||
B2B рынок
|
||||
|
||||
экспертность
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
ТОП-1 выбор:
|
||||
|
||||
✔ AegisOne Engineering
|
||||
|
||||
|
||||
---
|
||||
|
||||
ТОП-2 усиление:
|
||||
|
||||
✔ AegisOne Security Engineering
|
||||
|
||||
|
||||
---
|
||||
|
||||
НЕ РЕКОМЕНДУЮ КАК ОСНОВУ:
|
||||
|
||||
Service (снижает статус)
|
||||
|
||||
TechService (дешевит бренд)
|
||||
|
||||
Facility Security (узкая ниша на будущее)
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
9. ЕСЛИ ХОЧЕШЬ ДАЛЬШЕ УСИЛИТЬ БРЕНД
|
||||
|
||||
Я могу собрать тебе следующий уровень:
|
||||
|
||||
нейминг архитектуры сайта (как разложить домены/страницы)
|
||||
|
||||
логотип-систему (как должен выглядеть бренд инженерной компании)
|
||||
|
||||
упаковку КП под каждый бренд
|
||||
|
||||
позиционирование для тендеров
|
||||
|
||||
“как выглядеть как федеральный подрядчик при локальном бизнесе”
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Если коротко:
|
||||
|
||||
> тебе нужен не набор названий, а система уровней доверия
|
||||
|
||||
|
||||
|
||||
И из всех вариантов:
|
||||
|
||||
AegisOne Engineering — фундамент бизнеса.
|
||||
|
||||
---
|
||||
|
||||
Отлично, теперь мы фиксируем **архитектуру компании как инженерной системы**, а не сайта.
|
||||
|
||||
Ты строишь не “фирму услуг”, а:
|
||||
|
||||
# AegisOne Engineering — операционную систему эксплуатации объектов
|
||||
|
||||
Ниже даю тебе:
|
||||
|
||||
1. структуру компании (как она “разложена в голове клиента”)
|
||||
2. все разделы сайта / системы
|
||||
3. документы (шаблоны, которые продают SLA сами)
|
||||
4. сценарии взаимодействия с клиентом
|
||||
5. стандарты (как ты выглядишь как федеральный подрядчик)
|
||||
|
||||
---
|
||||
|
||||
# 1. СТРУКТУРА AEGISONE ENGINEERING
|
||||
|
||||
## 🧠 ЯДРО КОМПАНИИ
|
||||
|
||||
# AegisOne Engineering
|
||||
|
||||
> Инженерная компания по эксплуатации и контролю систем безопасности объектов
|
||||
|
||||
---
|
||||
|
||||
## ФУНКЦИОНАЛЬНЫЕ БЛОКИ
|
||||
|
||||
```text
|
||||
1. Engineering Audit (аудит и диагностика)
|
||||
2. SLA Operations (эксплуатация)
|
||||
3. Incident Response (аварийные работы)
|
||||
4. Technical Supervision (контроль подрядчиков)
|
||||
5. Documentation & Compliance (документация)
|
||||
6. Risk Engineering (анализ рисков)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# 2. СТРУКТУРА САЙТА (КАК ДОЛЖЕН ВЫГЛЯДЕТЬ AEGISONE)
|
||||
|
||||
---
|
||||
|
||||
# 🏠 ГЛАВНАЯ
|
||||
|
||||
## `/`
|
||||
|
||||
### Название:
|
||||
|
||||
AegisOne Engineering
|
||||
|
||||
### Смысл:
|
||||
|
||||
> инженерная эксплуатация систем безопасности объектов
|
||||
|
||||
---
|
||||
|
||||
# 3. РАЗДЕЛЫ САЙТА
|
||||
|
||||
---
|
||||
|
||||
# 3.1 ENGINEERING AUDIT
|
||||
|
||||
## `/engineering-audit/`
|
||||
|
||||
### Описание:
|
||||
|
||||
```text
|
||||
Технический аудит систем безопасности с оценкой рисков эксплуатации.
|
||||
|
||||
Проверка:
|
||||
- видеонаблюдения
|
||||
- СКУД
|
||||
- пожарной сигнализации
|
||||
- инфраструктуры объекта
|
||||
|
||||
Результат:
|
||||
инженерное заключение и карта рисков объекта
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Подразделы:
|
||||
|
||||
- `/engineering-audit/video-surveillance`
|
||||
- `/engineering-audit/access-control`
|
||||
- `/engineering-audit/fire-alarm`
|
||||
- `/engineering-audit/risk-report`
|
||||
|
||||
---
|
||||
|
||||
# 3.2 SLA OPERATIONS
|
||||
|
||||
## `/sla-operations/`
|
||||
|
||||
### Описание:
|
||||
|
||||
```text
|
||||
Постоянное техническое сопровождение объектов с регламентами и SLA.
|
||||
|
||||
Мы обеспечиваем:
|
||||
- стабильную работу систем
|
||||
- контроль состояния оборудования
|
||||
- аварийное реагирование
|
||||
- регулярные проверки
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Подразделы:
|
||||
|
||||
- `/sla-operations/start`
|
||||
- `/sla-operations/business`
|
||||
- `/sla-operations/enterprise`
|
||||
- `/sla-operations/sla-regulations`
|
||||
|
||||
---
|
||||
|
||||
# 3.3 INCIDENT RESPONSE
|
||||
|
||||
## `/incident-response/`
|
||||
|
||||
### Описание:
|
||||
|
||||
```text
|
||||
Экстренное устранение неисправностей систем безопасности.
|
||||
|
||||
Сценарии:
|
||||
- отказ видеонаблюдения
|
||||
- потеря архива
|
||||
- сбой СКУД
|
||||
- проблемы пожарной сигнализации
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Подразделы:
|
||||
|
||||
- `/incident-response/critical`
|
||||
- `/incident-response/emergency-call`
|
||||
- `/incident-response/post-incident-report`
|
||||
|
||||
---
|
||||
|
||||
# 3.4 TECHNICAL SUPERVISION
|
||||
|
||||
## `/technical-supervision/`
|
||||
|
||||
### Описание:
|
||||
|
||||
```text
|
||||
Контроль подрядчиков и проверка качества работ сторонних организаций.
|
||||
|
||||
Мы выступаем как независимый инженерный контроль объекта.
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Подразделы:
|
||||
|
||||
- `/technical-supervision/contractor-check`
|
||||
- `/technical-supervision/acceptance-testing`
|
||||
- `/technical-supervision/project-review`
|
||||
|
||||
---
|
||||
|
||||
# 3.5 DOCUMENTATION & COMPLIANCE
|
||||
|
||||
## `/documentation-compliance/`
|
||||
|
||||
### Описание:
|
||||
|
||||
```text
|
||||
Ведение и восстановление инженерной документации объектов.
|
||||
|
||||
Системы:
|
||||
- схемы
|
||||
- журналы
|
||||
- паспорта оборудования
|
||||
- регламенты эксплуатации
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Подразделы:
|
||||
|
||||
- `/documentation-compliance/passport`
|
||||
- `/documentation-compliance/regulations`
|
||||
- `/documentation-compliance/reporting`
|
||||
|
||||
---
|
||||
|
||||
# 3.6 RISK ENGINEERING
|
||||
|
||||
## `/risk-engineering/`
|
||||
|
||||
### Описание:
|
||||
|
||||
```text
|
||||
Анализ рисков эксплуатации инженерных систем безопасности объекта.
|
||||
|
||||
Мы оцениваем не оборудование, а последствия его отказа.
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Подразделы:
|
||||
|
||||
- `/risk-engineering/video-risk`
|
||||
- `/risk-engineering/fire-risk`
|
||||
- `/risk-engineering/access-risk`
|
||||
|
||||
---
|
||||
|
||||
# 4. ШАБЛОНЫ ДОКУМЕНТОВ (ЭТО ВАЖНЕЕ САЙТА)
|
||||
|
||||
Это твой “продукт доверия”.
|
||||
|
||||
---
|
||||
|
||||
# 4.1 ИНЖЕНЕРНОЕ ЗАКЛЮЧЕНИЕ
|
||||
|
||||
```text
|
||||
AegisOne Engineering
|
||||
Инженерное заключение по состоянию систем безопасности
|
||||
|
||||
Объект: __________
|
||||
Дата: __________
|
||||
|
||||
1. Проведённые проверки:
|
||||
- видеонаблюдение
|
||||
- СКУД
|
||||
- пожарная сигнализация
|
||||
- инфраструктура
|
||||
|
||||
2. Выявленные отклонения:
|
||||
- __________
|
||||
- __________
|
||||
|
||||
3. Критические риски:
|
||||
- __________
|
||||
|
||||
4. Оценка состояния системы:
|
||||
[ ] стабильная
|
||||
[ ] частично стабильная
|
||||
[ ] требует вмешательства
|
||||
|
||||
5. Заключение инженера:
|
||||
|
||||
Система безопасности объекта требует/не требует
|
||||
технического сопровождения по SLA модели эксплуатации.
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# 4.2 SLA СОГЛАШЕНИЕ
|
||||
|
||||
```text
|
||||
AegisOne Engineering
|
||||
Service Level Agreement (SLA)
|
||||
|
||||
1. Объект обслуживания
|
||||
2. Перечень систем
|
||||
3. Время реакции:
|
||||
P1 — 2 часа
|
||||
P2 — 4 часа
|
||||
P3 — 24 часа
|
||||
|
||||
4. Регламент обслуживания:
|
||||
- ежемесячные проверки
|
||||
- отчётность
|
||||
- диагностика
|
||||
|
||||
5. Зоны ответственности:
|
||||
- заказчик
|
||||
- инженерная компания
|
||||
|
||||
6. Исключения:
|
||||
- повреждение третьими лицами
|
||||
- форс-мажор
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# 4.3 АКТ ТЕХНИЧЕСКОГО АУДИТА
|
||||
|
||||
```text
|
||||
Проверено:
|
||||
- видеонаблюдение
|
||||
- СКУД
|
||||
- пожарная система
|
||||
|
||||
Результаты:
|
||||
- __________
|
||||
|
||||
Рекомендации:
|
||||
- критические
|
||||
- важные
|
||||
- плановые
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# 4.4 ПАСПОРТ ОБЪЕКТА
|
||||
|
||||
```text
|
||||
AegisOne Engineering
|
||||
Паспорт инженерных систем объекта
|
||||
|
||||
Содержит:
|
||||
- схема систем
|
||||
- оборудование
|
||||
- IP-адреса
|
||||
- точки отказа
|
||||
- история обслуживания
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# 4.5 ОТЧЁТ ПО ИНЦИДЕНТУ
|
||||
|
||||
```text
|
||||
Описание инцидента:
|
||||
Время реакции:
|
||||
Причина:
|
||||
Последствия:
|
||||
Устранение:
|
||||
Рекомендации:
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# 5. СЦЕНАРИИ ВЗАИМОДЕЙСТВИЯ
|
||||
|
||||
---
|
||||
|
||||
## СЦЕНАРИЙ 1 — ВХОД
|
||||
|
||||
```text
|
||||
Контакт → мини-диагностика → аудит → отчет → SLA
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## СЦЕНАРИЙ 2 — АВАРИЯ
|
||||
|
||||
```text
|
||||
Инцидент → выезд → устранение → отчет → предложение SLA
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## СЦЕНАРИЙ 3 — ПАРТНЁРСКИЙ ВХОД
|
||||
|
||||
```text
|
||||
Партнёр → объект → аудит → сопровождение
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## СЦЕНАРИЙ 4 — ТЕНДЕР / КОММЕРЧЕСКИЙ ВХОД
|
||||
|
||||
```text
|
||||
Запрос → аудит → КП → SLA контракт
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# 6. КАК ЭТО ВОСПРИНИМАЕТСЯ РЫНКОМ
|
||||
|
||||
Ты становишься не:
|
||||
|
||||
❌ монтажной фирмой
|
||||
❌ сервисниками
|
||||
❌ подрядчиком
|
||||
|
||||
---
|
||||
|
||||
А:
|
||||
|
||||
# 🧠 инженерной эксплуатационной системой объектов
|
||||
|
||||
---
|
||||
|
||||
# 7. ГЛАВНЫЙ ЭФФЕКТ ЭТОЙ УПАКОВКИ
|
||||
|
||||
## Клиент думает:
|
||||
|
||||
> “Это не монтажники. Это те, кто контролирует безопасность объекта как систему.”
|
||||
|
||||
---
|
||||
|
||||
# 8. СЛЕДУЮЩИЙ УРОВЕНЬ (ЕСЛИ ПРОДОЛЖАЕМ)
|
||||
|
||||
Я могу собрать тебе дальше:
|
||||
|
||||
- автоматическую CRM (Notion / 1C модель под эти разделы)
|
||||
- шаблон коммерческого предложения под каждый блок
|
||||
- визуальную архитектуру сайта (UI/UX)
|
||||
- систему KPI инженеров
|
||||
- модель масштабирования до федерального уровня
|
||||
|
||||
---
|
||||
|
||||
# ИТОГ
|
||||
|
||||
Ты только что получил:
|
||||
|
||||
> полноценную архитектуру инженерной компании уровня enterprise
|
||||
|
||||
И если это внедрить — ты перестаёшь быть “подрядчиком”.
|
||||
|
||||
Ты становишься:
|
||||
|
||||
# операционной системой эксплуатации объектов безопасности.
|
||||
@@ -0,0 +1,459 @@
|
||||
Отлично, теперь мы фиксируем архитектуру компании как инженерной системы, а не сайта.
|
||||
|
||||
Ты строишь не “фирму услуг”, а:
|
||||
|
||||
AegisOne Engineering — операционную систему эксплуатации объектов
|
||||
|
||||
Ниже даю тебе:
|
||||
|
||||
1. структуру компании (как она “разложена в голове клиента”)
|
||||
|
||||
|
||||
2. все разделы сайта / системы
|
||||
|
||||
|
||||
3. документы (шаблоны, которые продают SLA сами)
|
||||
|
||||
|
||||
4. сценарии взаимодействия с клиентом
|
||||
|
||||
|
||||
5. стандарты (как ты выглядишь как федеральный подрядчик)
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
1. СТРУКТУРА AEGISONE ENGINEERING
|
||||
|
||||
🧠 ЯДРО КОМПАНИИ
|
||||
|
||||
AegisOne Engineering
|
||||
|
||||
> Инженерная компания по эксплуатации и контролю систем безопасности объектов
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
ФУНКЦИОНАЛЬНЫЕ БЛОКИ
|
||||
|
||||
1. Engineering Audit (аудит и диагностика)
|
||||
2. SLA Operations (эксплуатация)
|
||||
3. Incident Response (аварийные работы)
|
||||
4. Technical Supervision (контроль подрядчиков)
|
||||
5. Documentation & Compliance (документация)
|
||||
6. Risk Engineering (анализ рисков)
|
||||
|
||||
|
||||
---
|
||||
|
||||
2. СТРУКТУРА САЙТА (КАК ДОЛЖЕН ВЫГЛЯДЕТЬ AEGISONE)
|
||||
|
||||
|
||||
---
|
||||
|
||||
🏠 ГЛАВНАЯ
|
||||
|
||||
/
|
||||
|
||||
Название:
|
||||
|
||||
AegisOne Engineering
|
||||
|
||||
Смысл:
|
||||
|
||||
> инженерная эксплуатация систем безопасности объектов
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
3. РАЗДЕЛЫ САЙТА
|
||||
|
||||
|
||||
---
|
||||
|
||||
3.1 ENGINEERING AUDIT
|
||||
|
||||
/engineering-audit/
|
||||
|
||||
Описание:
|
||||
|
||||
Технический аудит систем безопасности с оценкой рисков эксплуатации.
|
||||
|
||||
Проверка:
|
||||
- видеонаблюдения
|
||||
- СКУД
|
||||
- пожарной сигнализации
|
||||
- инфраструктуры объекта
|
||||
|
||||
Результат:
|
||||
инженерное заключение и карта рисков объекта
|
||||
|
||||
|
||||
---
|
||||
|
||||
Подразделы:
|
||||
|
||||
/engineering-audit/video-surveillance
|
||||
|
||||
/engineering-audit/access-control
|
||||
|
||||
/engineering-audit/fire-alarm
|
||||
|
||||
/engineering-audit/risk-report
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
3.2 SLA OPERATIONS
|
||||
|
||||
/sla-operations/
|
||||
|
||||
Описание:
|
||||
|
||||
Постоянное техническое сопровождение объектов с регламентами и SLA.
|
||||
|
||||
Мы обеспечиваем:
|
||||
- стабильную работу систем
|
||||
- контроль состояния оборудования
|
||||
- аварийное реагирование
|
||||
- регулярные проверки
|
||||
|
||||
|
||||
---
|
||||
|
||||
Подразделы:
|
||||
|
||||
/sla-operations/start
|
||||
|
||||
/sla-operations/business
|
||||
|
||||
/sla-operations/enterprise
|
||||
|
||||
/sla-operations/sla-regulations
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
3.3 INCIDENT RESPONSE
|
||||
|
||||
/incident-response/
|
||||
|
||||
Описание:
|
||||
|
||||
Экстренное устранение неисправностей систем безопасности.
|
||||
|
||||
Сценарии:
|
||||
- отказ видеонаблюдения
|
||||
- потеря архива
|
||||
- сбой СКУД
|
||||
- проблемы пожарной сигнализации
|
||||
|
||||
|
||||
---
|
||||
|
||||
Подразделы:
|
||||
|
||||
/incident-response/critical
|
||||
|
||||
/incident-response/emergency-call
|
||||
|
||||
/incident-response/post-incident-report
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
3.4 TECHNICAL SUPERVISION
|
||||
|
||||
/technical-supervision/
|
||||
|
||||
Описание:
|
||||
|
||||
Контроль подрядчиков и проверка качества работ сторонних организаций.
|
||||
|
||||
Мы выступаем как независимый инженерный контроль объекта.
|
||||
|
||||
|
||||
---
|
||||
|
||||
Подразделы:
|
||||
|
||||
/technical-supervision/contractor-check
|
||||
|
||||
/technical-supervision/acceptance-testing
|
||||
|
||||
/technical-supervision/project-review
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
3.5 DOCUMENTATION & COMPLIANCE
|
||||
|
||||
/documentation-compliance/
|
||||
|
||||
Описание:
|
||||
|
||||
Ведение и восстановление инженерной документации объектов.
|
||||
|
||||
Системы:
|
||||
- схемы
|
||||
- журналы
|
||||
- паспорта оборудования
|
||||
- регламенты эксплуатации
|
||||
|
||||
|
||||
---
|
||||
|
||||
Подразделы:
|
||||
|
||||
/documentation-compliance/passport
|
||||
|
||||
/documentation-compliance/regulations
|
||||
|
||||
/documentation-compliance/reporting
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
3.6 RISK ENGINEERING
|
||||
|
||||
/risk-engineering/
|
||||
|
||||
Описание:
|
||||
|
||||
Анализ рисков эксплуатации инженерных систем безопасности объекта.
|
||||
|
||||
Мы оцениваем не оборудование, а последствия его отказа.
|
||||
|
||||
|
||||
---
|
||||
|
||||
Подразделы:
|
||||
|
||||
/risk-engineering/video-risk
|
||||
|
||||
/risk-engineering/fire-risk
|
||||
|
||||
/risk-engineering/access-risk
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
4. ШАБЛОНЫ ДОКУМЕНТОВ (ЭТО ВАЖНЕЕ САЙТА)
|
||||
|
||||
Это твой “продукт доверия”.
|
||||
|
||||
|
||||
---
|
||||
|
||||
4.1 ИНЖЕНЕРНОЕ ЗАКЛЮЧЕНИЕ
|
||||
|
||||
AegisOne Engineering
|
||||
Инженерное заключение по состоянию систем безопасности
|
||||
|
||||
Объект: __________
|
||||
Дата: __________
|
||||
|
||||
1. Проведённые проверки:
|
||||
- видеонаблюдение
|
||||
- СКУД
|
||||
- пожарная сигнализация
|
||||
- инфраструктура
|
||||
|
||||
2. Выявленные отклонения:
|
||||
- __________
|
||||
- __________
|
||||
|
||||
3. Критические риски:
|
||||
- __________
|
||||
|
||||
4. Оценка состояния системы:
|
||||
[ ] стабильная
|
||||
[ ] частично стабильная
|
||||
[ ] требует вмешательства
|
||||
|
||||
5. Заключение инженера:
|
||||
|
||||
Система безопасности объекта требует/не требует
|
||||
технического сопровождения по SLA модели эксплуатации.
|
||||
|
||||
|
||||
---
|
||||
|
||||
4.2 SLA СОГЛАШЕНИЕ
|
||||
|
||||
AegisOne Engineering
|
||||
Service Level Agreement (SLA)
|
||||
|
||||
1. Объект обслуживания
|
||||
2. Перечень систем
|
||||
3. Время реакции:
|
||||
P1 — 2 часа
|
||||
P2 — 4 часа
|
||||
P3 — 24 часа
|
||||
|
||||
4. Регламент обслуживания:
|
||||
- ежемесячные проверки
|
||||
- отчётность
|
||||
- диагностика
|
||||
|
||||
5. Зоны ответственности:
|
||||
- заказчик
|
||||
- инженерная компания
|
||||
|
||||
6. Исключения:
|
||||
- повреждение третьими лицами
|
||||
- форс-мажор
|
||||
|
||||
|
||||
---
|
||||
|
||||
4.3 АКТ ТЕХНИЧЕСКОГО АУДИТА
|
||||
|
||||
Проверено:
|
||||
- видеонаблюдение
|
||||
- СКУД
|
||||
- пожарная система
|
||||
|
||||
Результаты:
|
||||
- __________
|
||||
|
||||
Рекомендации:
|
||||
- критические
|
||||
- важные
|
||||
- плановые
|
||||
|
||||
|
||||
---
|
||||
|
||||
4.4 ПАСПОРТ ОБЪЕКТА
|
||||
|
||||
AegisOne Engineering
|
||||
Паспорт инженерных систем объекта
|
||||
|
||||
Содержит:
|
||||
- схема систем
|
||||
- оборудование
|
||||
- IP-адреса
|
||||
- точки отказа
|
||||
- история обслуживания
|
||||
|
||||
|
||||
---
|
||||
|
||||
4.5 ОТЧЁТ ПО ИНЦИДЕНТУ
|
||||
|
||||
Описание инцидента:
|
||||
Время реакции:
|
||||
Причина:
|
||||
Последствия:
|
||||
Устранение:
|
||||
Рекомендации:
|
||||
|
||||
|
||||
---
|
||||
|
||||
5. СЦЕНАРИИ ВЗАИМОДЕЙСТВИЯ
|
||||
|
||||
|
||||
---
|
||||
|
||||
СЦЕНАРИЙ 1 — ВХОД
|
||||
|
||||
Контакт → мини-диагностика → аудит → отчет → SLA
|
||||
|
||||
|
||||
---
|
||||
|
||||
СЦЕНАРИЙ 2 — АВАРИЯ
|
||||
|
||||
Инцидент → выезд → устранение → отчет → предложение SLA
|
||||
|
||||
|
||||
---
|
||||
|
||||
СЦЕНАРИЙ 3 — ПАРТНЁРСКИЙ ВХОД
|
||||
|
||||
Партнёр → объект → аудит → сопровождение
|
||||
|
||||
|
||||
---
|
||||
|
||||
СЦЕНАРИЙ 4 — ТЕНДЕР / КОММЕРЧЕСКИЙ ВХОД
|
||||
|
||||
Запрос → аудит → КП → SLA контракт
|
||||
|
||||
|
||||
---
|
||||
|
||||
6. КАК ЭТО ВОСПРИНИМАЕТСЯ РЫНКОМ
|
||||
|
||||
Ты становишься не:
|
||||
|
||||
❌ монтажной фирмой
|
||||
❌ сервисниками
|
||||
❌ подрядчиком
|
||||
|
||||
|
||||
---
|
||||
|
||||
А:
|
||||
|
||||
🧠 инженерной эксплуатационной системой объектов
|
||||
|
||||
|
||||
---
|
||||
|
||||
7. ГЛАВНЫЙ ЭФФЕКТ ЭТОЙ УПАКОВКИ
|
||||
|
||||
Клиент думает:
|
||||
|
||||
> “Это не монтажники. Это те, кто контролирует безопасность объекта как систему.”
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
8. СЛЕДУЮЩИЙ УРОВЕНЬ (ЕСЛИ ПРОДОЛЖАЕМ)
|
||||
|
||||
Я могу собрать тебе дальше:
|
||||
|
||||
автоматическую CRM (Notion / 1C модель под эти разделы)
|
||||
|
||||
шаблон коммерческого предложения под каждый блок
|
||||
|
||||
визуальную архитектуру сайта (UI/UX)
|
||||
|
||||
систему KPI инженеров
|
||||
|
||||
модель масштабирования до федерального уровня
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
ИТОГ
|
||||
|
||||
Ты только что получил:
|
||||
|
||||
> полноценную архитектуру инженерной компании уровня enterprise
|
||||
|
||||
|
||||
|
||||
И если это внедрить — ты перестаёшь быть “подрядчиком”.
|
||||
|
||||
Ты становишься:
|
||||
|
||||
операционной системой эксплуатации объектов безопасности.
|
||||
@@ -0,0 +1,543 @@
|
||||
Хороший вопрос — блог в твоей нише (системы безопасности + SLA + B2B + обслуживание) это не “контент-маркетинг”, а:
|
||||
|
||||
> инструмент продажи доверия, SLA и инженерной компетентности
|
||||
|
||||
|
||||
|
||||
Если блог сделан правильно, он заменяет:
|
||||
|
||||
отдел продаж (частично)
|
||||
|
||||
коммерческие предложения (частично)
|
||||
|
||||
презентации
|
||||
|
||||
кейсы
|
||||
|
||||
и даже тендерные обоснования
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
1. ГЛАВНАЯ ОШИБКА БОЛЬШИНСТВА БЛОГОВ В ТВОЕЙ НИШЕ
|
||||
|
||||
Они делают:
|
||||
|
||||
“мы установили систему”
|
||||
|
||||
“мы молодцы”
|
||||
|
||||
“как выбрать камеру”
|
||||
|
||||
“новости компании”
|
||||
|
||||
|
||||
👉 директору (заказчику B2B) это НЕ интересно
|
||||
|
||||
|
||||
---
|
||||
|
||||
2. ЧТО ХОЧЕТ ВИДЕТЬ ДИРЕКТОР (ЗАКАЗЧИК B2B)
|
||||
|
||||
Директору не нужен контент.
|
||||
|
||||
Ему нужно:
|
||||
|
||||
1. Снижение риска
|
||||
|
||||
“у меня не сломается объект”
|
||||
|
||||
“меня не оштрафуют”
|
||||
|
||||
“у меня будет доказательная база”
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
2. Управляемость
|
||||
|
||||
SLA
|
||||
|
||||
контроль
|
||||
|
||||
прозрачность
|
||||
|
||||
ответственность
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
3. Деньги и потери
|
||||
|
||||
сколько стоит простой
|
||||
|
||||
сколько стоит отказ системы
|
||||
|
||||
где риски потерь
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
4. Компетентность подрядчика
|
||||
|
||||
понимает ли подрядчик реальные риски
|
||||
|
||||
умеет ли он управлять системой, а не “чинить камеры”
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
3. КАК ДОЛЖЕН БЫТЬ УСТРОЕН БЛОГ (АРХИТЕКТУРА)
|
||||
|
||||
BLOG AEGISONE
|
||||
|
||||
1. Risk Engineering (риски объектов)
|
||||
2. SLA & Service (обслуживание)
|
||||
3. Incident Cases (разбор аварий)
|
||||
4. Infrastructure Deep Dive (техническая экспертиза)
|
||||
5. Compliance / MCHS / Audit (регуляторика)
|
||||
6. Economics of Security (экономика потерь)
|
||||
7. Case Studies (реальные объекты)
|
||||
|
||||
|
||||
---
|
||||
|
||||
4. КАТЕГОРИИ БЛОГА (ПОЛНАЯ СТРУКТУРА)
|
||||
|
||||
|
||||
---
|
||||
|
||||
4.1 RISK ENGINEERING (САМАЯ ВАЖНАЯ)
|
||||
|
||||
Суть:
|
||||
|
||||
Показывает директору:
|
||||
|
||||
> где он уже теряет деньги, даже если всё “работает”
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Примеры статей:
|
||||
|
||||
“Почему 70% объектов теряют видеодоказательства и не знают об этом”
|
||||
|
||||
“Что происходит, когда SLA пожарной системы формальный”
|
||||
|
||||
“7 скрытых точек отказа в СКУД”
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Формат:
|
||||
|
||||
риск
|
||||
|
||||
последствия
|
||||
|
||||
реальные сценарии
|
||||
|
||||
стоимость потерь
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Почему это продаёт:
|
||||
|
||||
👉 вызывает страх + осознание потерь
|
||||
|
||||
|
||||
---
|
||||
|
||||
4.2 SLA & SERVICE (ТВОЯ ДЕНЕЖНАЯ КАТЕГОРИЯ)
|
||||
|
||||
Суть:
|
||||
|
||||
объясняет, почему SLA = бизнес-стабильность
|
||||
|
||||
|
||||
---
|
||||
|
||||
Примеры:
|
||||
|
||||
“Почему обслуживание пожарной сигнализации — это не обслуживание, а юридическая ответственность”
|
||||
|
||||
“Как SLA снижает риск остановки бизнеса”
|
||||
|
||||
“Почему разовые выезды не работают”
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Формат:
|
||||
|
||||
объяснение SLA
|
||||
|
||||
цифры
|
||||
|
||||
последствия без SLA
|
||||
|
||||
кейсы
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
4.3 INCIDENT CASES (СИЛЬНЕЙШИЙ ДОВЕРИТЕЛЬНЫЙ БЛОК)
|
||||
|
||||
Суть:
|
||||
|
||||
реальные аварии
|
||||
|
||||
|
||||
---
|
||||
|
||||
Примеры:
|
||||
|
||||
“Как один отказ СКУД остановил склад на 14 часов”
|
||||
|
||||
“Пожарная система без регламента: разбор инцидента”
|
||||
|
||||
“Почему не работал архив видеонаблюдения 3 месяца”
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Структура:
|
||||
|
||||
1. Что случилось
|
||||
2. Почему это произошло
|
||||
3. Какие были последствия
|
||||
4. Как это выявили
|
||||
5. Как исправили
|
||||
6. Как избежать
|
||||
|
||||
|
||||
---
|
||||
|
||||
Это:
|
||||
|
||||
👉 главный доверительный инструмент
|
||||
|
||||
|
||||
---
|
||||
|
||||
4.4 INFRASTRUCTURE DEEP DIVE
|
||||
|
||||
Суть:
|
||||
|
||||
показывает инженерную глубину
|
||||
|
||||
|
||||
---
|
||||
|
||||
Примеры:
|
||||
|
||||
“Как устроена современная система видеонаблюдения на объекте 10 000 м²”
|
||||
|
||||
“Почему сеть — это главный риск безопасности”
|
||||
|
||||
“UPS как критический элемент безопасности”
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
4.5 COMPLIANCE / MCHS
|
||||
|
||||
Суть:
|
||||
|
||||
работа с нормативкой
|
||||
|
||||
|
||||
---
|
||||
|
||||
Примеры:
|
||||
|
||||
“Что проверяет МЧС в 2026 году”
|
||||
|
||||
“Типовые ошибки объектов при проверках”
|
||||
|
||||
“Почему формальное ТО приводит к штрафам”
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
4.6 ECONOMICS OF SECURITY
|
||||
|
||||
Суть:
|
||||
|
||||
деньги, потери, риск
|
||||
|
||||
|
||||
---
|
||||
|
||||
Примеры:
|
||||
|
||||
“Сколько стоит 1 час простоя склада”
|
||||
|
||||
“Стоимость потери видеодоказательства”
|
||||
|
||||
“Почему дешёвый подрядчик обходится дороже”
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
4.7 CASE STUDIES (ОСНОВА ПРОДАЖ)
|
||||
|
||||
Суть:
|
||||
|
||||
твои реальные объекты
|
||||
|
||||
|
||||
---
|
||||
|
||||
Формат:
|
||||
|
||||
объект
|
||||
|
||||
проблемы
|
||||
|
||||
что сделали
|
||||
|
||||
результат
|
||||
|
||||
SLA модель
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
5. КАК ДОЛЖЕН ВЫГЛЯДЕТЬ БЛОГ (UI/UX)
|
||||
|
||||
|
||||
---
|
||||
|
||||
5.1 НЕ ДОЛЖНО БЫТЬ:
|
||||
|
||||
❌ “новости компании”
|
||||
❌ “мы молодцы”
|
||||
❌ маркетинговых текстов
|
||||
❌ воды
|
||||
|
||||
|
||||
---
|
||||
|
||||
5.2 ДОЛЖНО БЫТЬ:
|
||||
|
||||
Главная страница блога:
|
||||
|
||||
“инженерные риски”
|
||||
|
||||
“разбор инцидентов”
|
||||
|
||||
“стоимость отказов”
|
||||
|
||||
“кейсы объектов”
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
5.3 Визуально:
|
||||
|
||||
строгий технический стиль
|
||||
|
||||
таблицы
|
||||
|
||||
схемы
|
||||
|
||||
диаграммы
|
||||
|
||||
риск-блоки
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
6. КАЖДАЯ СТАТЬЯ ДОЛЖНА ПРОДАВАТЬ
|
||||
|
||||
|
||||
---
|
||||
|
||||
структура статьи (обязательная):
|
||||
|
||||
1. Проблема
|
||||
2. Реальный сценарий
|
||||
3. Что происходит технически
|
||||
4. Риски
|
||||
5. Финансовые последствия
|
||||
6. Как решается
|
||||
7. Как это делает AegisOne
|
||||
|
||||
|
||||
---
|
||||
|
||||
7. ПРИМЕР “ПРОДАЮЩЕЙ” СТАТЬИ
|
||||
|
||||
|
||||
---
|
||||
|
||||
Заголовок:
|
||||
|
||||
> “Почему 80% систем видеонаблюдения не дают доказательств в момент инцидента”
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Внутри:
|
||||
|
||||
потеря архива
|
||||
|
||||
сбои HDD
|
||||
|
||||
неправильная настройка
|
||||
|
||||
отсутствие контроля
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Финал:
|
||||
|
||||
> “в AegisOne это решается через SLA мониторинг и инженерный контроль”
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
8. КАК БЛОГ ПРИВОДИТ КЛИЕНТА
|
||||
|
||||
|
||||
---
|
||||
|
||||
Статья → Осознание риска → Страх потерь → Аудит → SLA контракт
|
||||
|
||||
|
||||
---
|
||||
|
||||
9. ГЛАВНАЯ ЛОГИКА БЛОГА
|
||||
|
||||
Ты не пишешь статьи.
|
||||
|
||||
Ты создаёшь:
|
||||
|
||||
> систему формирования потребности в SLA
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
10. ЧТО ДЕЛАЕТ БЛОГ СИЛЬНЫМ (КРИТИЧНО)
|
||||
|
||||
|
||||
---
|
||||
|
||||
1. РЕАЛЬНЫЕ ЦИФРЫ
|
||||
|
||||
потери
|
||||
|
||||
простои
|
||||
|
||||
риски
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
2. РЕАЛЬНЫЕ ИНЦИДЕНТЫ
|
||||
|
||||
аварии
|
||||
|
||||
сбои
|
||||
|
||||
последствия
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
3. ИНЖЕНЕРНАЯ ГЛУБИНА
|
||||
|
||||
схемы
|
||||
|
||||
логика систем
|
||||
|
||||
причины отказов
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
4. ЭКОНОМИКА
|
||||
|
||||
сколько стоит ошибка
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
11. ЧТО НЕЛЬЗЯ ДЕЛАТЬ
|
||||
|
||||
|
||||
---
|
||||
|
||||
❌ SEO-статьи “для трафика”
|
||||
❌ поверхностные обзоры
|
||||
❌ “лайфхаки безопасности”
|
||||
❌ маркетинг
|
||||
|
||||
|
||||
---
|
||||
|
||||
12. ИТОГ
|
||||
|
||||
Правильный блог в твоей модели — это:
|
||||
|
||||
> “система инженерного страха + доверия + экспертизы”
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
13. ЕСЛИ РАЗВИВАТЬ ДАЛЬШЕ
|
||||
|
||||
Я могу дальше собрать:
|
||||
|
||||
30 готовых статей под твой блог (с заголовками + структурами)
|
||||
|
||||
SEO-структуру под Краснодарский край
|
||||
|
||||
Telegram-воронку из блога
|
||||
|
||||
автоматическое превращение статей в заявки на аудит
|
||||
|
||||
систему “контент → SHS влияние”
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Если коротко:
|
||||
|
||||
👉 блог в твоей модели — это не контент
|
||||
👉 это “машина продажи SLA через понимание риска”
|
||||
@@ -0,0 +1,445 @@
|
||||
Ок, здесь мы уже собираем не “маркетинг”, а полноценную B2B-машину:
|
||||
|
||||
# вход → доверие → аудит → SLA → долгий повторяющийся доход
|
||||
|
||||
Ты как раз в нише, где деньги делаются не на разовых монтажах, а на:
|
||||
|
||||
> эксплуатации + рисках + ответственности
|
||||
|
||||
---
|
||||
|
||||
# ЧАСТЬ 1. ПЕРВАЯ ВОРОНКА КЛИЕНТОВ (КРАСНОДАРСКИЙ КРАЙ)
|
||||
|
||||
---
|
||||
|
||||
# 0. ЛОГИКА ВОРОНКИ
|
||||
|
||||
Твоя воронка НЕ классическая:
|
||||
|
||||
❌ “реклама → заявка → продажа”
|
||||
|
||||
У тебя:
|
||||
|
||||
# контент → доверие → аудит → выявление проблем → SLA
|
||||
|
||||
---
|
||||
|
||||
# 1. ВХОД В ВОРОНКУ (ТОЧКИ ПРИКОСНОВЕНИЯ)
|
||||
|
||||
## 1.1. Локальный B2B рынок (основа)
|
||||
|
||||
Ты работаешь не по всей РФ, а:
|
||||
|
||||
- Краснодар
|
||||
- Сочи
|
||||
- Новороссийск
|
||||
- Анапа
|
||||
- Армавир
|
||||
- промзоны + логистика + гостиницы
|
||||
|
||||
---
|
||||
|
||||
## 1.2. Каналы входа (без агрессивного маркетинга)
|
||||
|
||||
### 1) Telegram (основной канал доверия)
|
||||
|
||||
Контент + кейсы + разборы
|
||||
|
||||
---
|
||||
|
||||
### 2) Яндекс / Google SEO
|
||||
|
||||
Страницы:
|
||||
|
||||
- аудит систем безопасности
|
||||
- SLA обслуживание
|
||||
- обслуживание видеонаблюдения Краснодар
|
||||
- обслуживание пожарной сигнализации
|
||||
|
||||
---
|
||||
|
||||
### 3) Партнеры (очень важно)
|
||||
|
||||
- электрики
|
||||
- IT-аутсорс
|
||||
- управляющие компании
|
||||
- проектировщики
|
||||
- пожарники
|
||||
- строители
|
||||
|
||||
---
|
||||
|
||||
### 4) Прямые инженерные выходы
|
||||
|
||||
НЕ продажи.
|
||||
|
||||
Формат:
|
||||
|
||||
> “если нужен технический аудит или проверка систем — можем подключиться”
|
||||
|
||||
---
|
||||
|
||||
# 2. ПЕРВЫЙ ПРОДУКТ (ВХОД В ДЕНЬГИ)
|
||||
|
||||
# 🔥 Технический аудит объекта
|
||||
|
||||
---
|
||||
|
||||
## Почему это ядро воронки
|
||||
|
||||
Потому что:
|
||||
|
||||
- легко продать без давления
|
||||
- низкий чек
|
||||
- высокая ценность
|
||||
- выявляет проблемы
|
||||
- логично ведёт в SLA
|
||||
|
||||
---
|
||||
|
||||
## Цена (Краснодарский край)
|
||||
|
||||
- малый объект: 15–25 тыс
|
||||
- средний: 25–50 тыс
|
||||
- крупный: 50–100 тыс
|
||||
|
||||
---
|
||||
|
||||
## Что важно
|
||||
|
||||
Аудит НЕ продаёт услуги.
|
||||
|
||||
Он:
|
||||
|
||||
# показывает проблемы → создаёт необходимость SLA
|
||||
|
||||
---
|
||||
|
||||
# 3. ВТОРОЙ ЭТАП
|
||||
|
||||
# 🔥 “Диагностика + отчет”
|
||||
|
||||
После аудита:
|
||||
|
||||
Ты выдаешь документ:
|
||||
|
||||
- риски
|
||||
- неисправности
|
||||
- слабые места
|
||||
- последствия
|
||||
- рекомендации
|
||||
|
||||
---
|
||||
|
||||
## Ключевая мысль отчета:
|
||||
|
||||
> “Система формально работает, но не защищает объект”
|
||||
|
||||
---
|
||||
|
||||
# 4. ТРЕТИЙ ЭТАП
|
||||
|
||||
# 🔥 ПЕРЕХОД В SLA
|
||||
|
||||
---
|
||||
|
||||
## Это главный момент денег
|
||||
|
||||
Ты НЕ продаешь обслуживание.
|
||||
|
||||
Ты продаешь:
|
||||
|
||||
# “устранение рисков эксплуатации”
|
||||
|
||||
---
|
||||
|
||||
## Как выглядит оффер
|
||||
|
||||
> Мы берем объект на техническое сопровождение с SLA контролем состояния систем безопасности.
|
||||
|
||||
---
|
||||
|
||||
## Конверсия
|
||||
|
||||
Из аудита → в SLA:
|
||||
|
||||
- 30% слабые объекты
|
||||
- 50% средние
|
||||
- 10–20% сильные (очень хорошие деньги)
|
||||
|
||||
---
|
||||
|
||||
# 5. SLA (ПРОДУКТ ДЕНЕГ)
|
||||
|
||||
---
|
||||
|
||||
## Структура:
|
||||
|
||||
### START
|
||||
|
||||
25–40k
|
||||
|
||||
---
|
||||
|
||||
### BUSINESS
|
||||
|
||||
60–120k
|
||||
|
||||
---
|
||||
|
||||
### ENTERPRISE
|
||||
|
||||
150–400k
|
||||
|
||||
---
|
||||
|
||||
## Что ты продаешь на самом деле:
|
||||
|
||||
НЕ обслуживание
|
||||
|
||||
А:
|
||||
|
||||
# “инженерную стабильность объекта”
|
||||
|
||||
---
|
||||
|
||||
# 6. ПОЛНАЯ ВОРОНКА В ВИДЕ СХЕМЫ
|
||||
|
||||
```
|
||||
Контент / SEO / партнеры
|
||||
↓
|
||||
Лид (запрос)
|
||||
↓
|
||||
Мини-аудит (или первичная диагностика)
|
||||
↓
|
||||
Полный технический аудит
|
||||
↓
|
||||
Отчет с рисками
|
||||
↓
|
||||
SLA предложение
|
||||
↓
|
||||
Долгосрочный контракт
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# ЧАСТЬ 2. МОДЕЛЬ РОСТА ДО 2–3 МЛН ₽/МЕС RECURRENT
|
||||
|
||||
---
|
||||
|
||||
# 1. КЛЮЧЕВОЕ ПРАВИЛО
|
||||
|
||||
Ты не масштабируешь монтаж.
|
||||
|
||||
Ты масштабируешь:
|
||||
|
||||
# количество объектов на SLA
|
||||
|
||||
---
|
||||
|
||||
# 2. МАТЕМАТИКА МОДЕЛИ
|
||||
|
||||
---
|
||||
|
||||
## Вариант реалистичный (Краснодар → край → РФ)
|
||||
|
||||
### Средний чек SLA:
|
||||
|
||||
80 000 ₽
|
||||
|
||||
---
|
||||
|
||||
## Тебе нужно:
|
||||
|
||||
### 25–35 объектов
|
||||
|
||||
---
|
||||
|
||||
## Доход:
|
||||
|
||||
```
|
||||
30 объектов × 80 000 ₽ = 2 400 000 ₽/мес
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# 3. КАК ЭТО ДОСТИГАЕТСЯ
|
||||
|
||||
---
|
||||
|
||||
## ЭТАП 1 — 0–500k
|
||||
|
||||
Фокус:
|
||||
|
||||
- аудит
|
||||
- первые SLA
|
||||
- 5–7 объектов
|
||||
|
||||
---
|
||||
|
||||
## ЭТАП 2 — 500k–1.5M
|
||||
|
||||
Фокус:
|
||||
|
||||
- стабильные SLA
|
||||
- отбор клиентов
|
||||
- отказ от токсичных объектов
|
||||
- первые крупные клиенты
|
||||
|
||||
---
|
||||
|
||||
## ЭТАП 3 — 1.5M–3M
|
||||
|
||||
Фокус:
|
||||
|
||||
- стандартизация
|
||||
- регламенты
|
||||
- техподдержка
|
||||
- 2–3 инженера
|
||||
- удаленный контроль
|
||||
|
||||
---
|
||||
|
||||
# 4. КЛЮЧЕВОЙ РЫЧАГ РОСТА
|
||||
|
||||
---
|
||||
|
||||
# НЕ реклама
|
||||
|
||||
# НЕ продажи
|
||||
|
||||
# А:
|
||||
|
||||
## “плотность объектов на инженера”
|
||||
|
||||
---
|
||||
|
||||
# 5. СИСТЕМА РОСТА
|
||||
|
||||
---
|
||||
|
||||
## 1 инженер = 8–12 объектов
|
||||
|
||||
---
|
||||
|
||||
## значит:
|
||||
|
||||
|Кол-во инженеров|Доход|
|
||||
|---|---|
|
||||
|1|0.8–1.2M|
|
||||
|2|1.6–2.4M|
|
||||
|3|2.4–3.6M|
|
||||
|
||||
---
|
||||
|
||||
# 6. ГЛАВНЫЕ РЫЧАГИ МАСШТАБА
|
||||
|
||||
---
|
||||
|
||||
## 1. Аудит как продукт входа
|
||||
|
||||
(дешево / легко / продается сам)
|
||||
|
||||
---
|
||||
|
||||
## 2. SLA как подписка
|
||||
|
||||
(деньги каждый месяц)
|
||||
|
||||
---
|
||||
|
||||
## 3. Контент как доверие
|
||||
|
||||
(заменяет рекламу)
|
||||
|
||||
---
|
||||
|
||||
## 4. Партнерки
|
||||
|
||||
(дают теплые объекты)
|
||||
|
||||
---
|
||||
|
||||
## 5. Отказ от дешевых клиентов
|
||||
|
||||
(самый важный фактор)
|
||||
|
||||
---
|
||||
|
||||
# 7. КРИТИЧЕСКИЙ МОМЕНТ
|
||||
|
||||
---
|
||||
|
||||
Если ты не сделаешь это:
|
||||
|
||||
> “мы не берем монтаж без SLA”
|
||||
|
||||
ты останешься в рынке:
|
||||
|
||||
- демпинга
|
||||
- разовых работ
|
||||
- кассовых разрывов
|
||||
|
||||
---
|
||||
|
||||
# 8. ИДЕАЛЬНАЯ ЭВОЛЮЦИЯ БИЗНЕСА
|
||||
|
||||
---
|
||||
|
||||
## Было:
|
||||
|
||||
монтажники
|
||||
|
||||
---
|
||||
|
||||
## Стало:
|
||||
|
||||
SLA + эксплуатация
|
||||
|
||||
---
|
||||
|
||||
## Будет:
|
||||
|
||||
# внешний инженерный отдел объектов
|
||||
|
||||
---
|
||||
|
||||
# 9. СИЛЬНЫЙ СДВИГ МЫШЛЕНИЯ
|
||||
|
||||
---
|
||||
|
||||
Ты больше не продаешь:
|
||||
|
||||
❌ камеры
|
||||
❌ монтаж
|
||||
❌ оборудование
|
||||
|
||||
---
|
||||
|
||||
Ты продаешь:
|
||||
|
||||
# “спокойствие собственника за техническую инфраструктуру объекта”
|
||||
|
||||
---
|
||||
|
||||
# ЕСЛИ СЖАТЬ В ОДНУ ФОРМУЛУ:
|
||||
|
||||
---
|
||||
|
||||
> Аудит → выявление рисков → SLA → долгосрочный инженерный доход
|
||||
|
||||
---
|
||||
|
||||
# ЕСЛИ ДАЛЬШЕ ДВИГАТЬСЯ
|
||||
|
||||
Я могу следующим шагом собрать тебе:
|
||||
|
||||
- точную систему продаж аудита (скрипты + сообщения)
|
||||
- упаковку Telegram как лидогенератора
|
||||
- CRM воронку под SLA
|
||||
- регламент инженера (чтобы масштабироваться)
|
||||
- финансовую модель до 5–10 млн/мес
|
||||
|
||||
Это уже будет не “бизнес идея”, а:
|
||||
|
||||
# операционная система инженерной компании.
|
||||