let db;
function init(database) {
db = database;
return initDatabase();
}
function initDatabase() {
return new Promise((resolve, reject) => {
db.serialize(() => {
db.run(`CREATE TABLE IF NOT EXISTS leads (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
phone TEXT NOT NULL,
message TEXT,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
)`);
db.run(`CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
login TEXT NOT NULL UNIQUE,
password_hash TEXT NOT NULL,
full_name TEXT,
role TEXT NOT NULL DEFAULT 'admin',
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
)`);
db.run(`CREATE TABLE IF NOT EXISTS hero_settings (
id INTEGER PRIMARY KEY AUTOINCREMENT,
key TEXT UNIQUE NOT NULL,
value TEXT
)`);
db.run(`CREATE TABLE IF NOT EXISTS hero_stats (
id INTEGER PRIMARY KEY AUTOINCREMENT,
label TEXT NOT NULL,
value TEXT NOT NULL,
is_dynamic INTEGER DEFAULT 0,
sort_order INTEGER DEFAULT 0
)`);
db.run(`CREATE TABLE IF NOT EXISTS about_settings (
id INTEGER PRIMARY KEY AUTOINCREMENT,
key TEXT UNIQUE NOT NULL,
value TEXT
)`);
db.run(`CREATE TABLE IF NOT EXISTS about_features (
id INTEGER PRIMARY KEY AUTOINCREMENT,
svg_icon TEXT,
title TEXT NOT NULL,
description TEXT,
sort_order INTEGER DEFAULT 0
)`);
db.run(`CREATE TABLE IF NOT EXISTS services (
id INTEGER PRIMARY KEY AUTOINCREMENT,
svg_icon TEXT,
title TEXT NOT NULL,
description TEXT,
items TEXT DEFAULT '[]',
is_large INTEGER DEFAULT 0,
sort_order INTEGER DEFAULT 0,
is_active INTEGER DEFAULT 1
)`);
db.run(`CREATE TABLE IF NOT EXISTS work_schemes (
id INTEGER PRIMARY KEY AUTOINCREMENT,
svg_icon TEXT,
title TEXT NOT NULL,
description TEXT,
items TEXT DEFAULT '[]',
sort_order INTEGER DEFAULT 0,
is_active INTEGER DEFAULT 1
)`);
db.run(`CREATE TABLE IF NOT EXISTS process_steps (
id INTEGER PRIMARY KEY AUTOINCREMENT,
step_number INTEGER NOT NULL,
title TEXT NOT NULL,
description TEXT,
sort_order INTEGER DEFAULT 0
)`);
db.run(`CREATE TABLE IF NOT EXISTS equipment (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
brand TEXT,
image_path TEXT,
qty TEXT,
specs TEXT DEFAULT '[]',
sort_order INTEGER DEFAULT 0,
is_active INTEGER DEFAULT 1
)`);
db.run(`CREATE TABLE IF NOT EXISTS equipment_gallery (
id INTEGER PRIMARY KEY AUTOINCREMENT,
equipment_id INTEGER NOT NULL,
image_path TEXT NOT NULL,
sort_order INTEGER DEFAULT 0,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (equipment_id) REFERENCES equipment(id) ON DELETE CASCADE
)`);
db.run(`CREATE TABLE IF NOT EXISTS geo_regions (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
sort_order INTEGER DEFAULT 0
)`);
db.run(`CREATE TABLE IF NOT EXISTS geo_settings (
id INTEGER PRIMARY KEY AUTOINCREMENT,
key TEXT UNIQUE NOT NULL,
value TEXT
)`);
db.run(`CREATE TABLE IF NOT EXISTS licenses (
id INTEGER PRIMARY KEY AUTOINCREMENT,
svg_icon TEXT,
title TEXT NOT NULL,
description TEXT,
sort_order INTEGER DEFAULT 0
)`);
db.run(`CREATE TABLE IF NOT EXISTS license_gallery (
id INTEGER PRIMARY KEY AUTOINCREMENT,
title TEXT NOT NULL,
description TEXT,
image_path TEXT,
sort_order INTEGER DEFAULT 0
)`);
db.run(`CREATE TABLE IF NOT EXISTS public_activities (
id INTEGER PRIMARY KEY AUTOINCREMENT,
svg_icon TEXT,
title TEXT NOT NULL,
description TEXT,
sort_order INTEGER DEFAULT 0
)`);
db.run(`CREATE TABLE IF NOT EXISTS activity_gallery (
id INTEGER PRIMARY KEY AUTOINCREMENT,
title TEXT NOT NULL,
description TEXT,
image_path TEXT,
sort_order INTEGER DEFAULT 0
)`);
db.run(`CREATE TABLE IF NOT EXISTS partners (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
logo_path TEXT,
sort_order INTEGER DEFAULT 0,
is_active INTEGER DEFAULT 1
)`);
db.run(`CREATE TABLE IF NOT EXISTS settings (
id INTEGER PRIMARY KEY AUTOINCREMENT,
key TEXT UNIQUE NOT NULL,
value TEXT
)`);
db.get(`SELECT COUNT(*) as cnt FROM settings`, (err, row) => {
if (row && row.cnt > 0) {
db.run(`INSERT OR IGNORE INTO settings (key, value) VALUES ('logo_path', './img/logo.webp')`);
resolve();
return;
}
seedAll().then(resolve).catch(reject);
});
});
});
}
async function seedAll() {
const run = (sql, params) => new Promise(r => db.run(sql, params || [], () => r()));
const runEach = (sql, rows) => Promise.all(rows.map(r => {
const stmt = db.prepare(sql);
return new Promise(res => {
stmt.run(...r, function() { stmt.finalize(); res(); });
});
}));
const heroDefaults = [
['hero_bg', './img/hero-bg.webp'], ['badge_text', 'Лицензии СРО и НОСТРОЙ'],
['h1_text', 'демонтаж нефтегазопроводов по России, утилизация отходов'],
['subtitle', 'Собственная спецтехника. Лицензии СРО и НОСТРОЙ. Более {years} лет опыта. Работаем на опасных производственных объектах без привлечения субподрядчиков.'],
['phone_800', '8 (800) 555-29-31'], ['phone_ekb', '8 (343) 237-25-66'],
['email', 'sts_zakaz@mail.ru'], ['address', 'г. Екатеринбург, ул. Московская, 11, оф. 702'],
['button1_text', 'Оставить заявку'], ['button1_link', '#contacts'],
['button2_text', 'Наши услуги'], ['button2_link', '#services']
];
await runEach('INSERT OR IGNORE INTO hero_settings (key, value) VALUES (?, ?)', heroDefaults);
await runEach('INSERT INTO hero_stats (label, value, is_dynamic, sort_order) VALUES (?, ?, ?, ?)', [
['лет на рынке', '{years}', 1, 0], ['объектов выполнено', '200', 0, 1],
['единиц техники', '80', 0, 2], ['федеральных округов', '6', 0, 3]
]);
await runEach('INSERT OR IGNORE INTO about_settings (key, value) VALUES (?, ?)', [
['section_subtitle', 'Компания «СТС-Авто» — надёжный партнёр в сфере демонтажа, оказывает услуги по демонтажу всех типов магистральных и промысловых сетей (нефтепроводы, газопроводы, водоводы). Мы работаем на всей территории Российской Федерации.'],
['main_heading', 'Собственная техника и полный контроль'], ['about_image', './img/hero-bg.webp'],
['paragraph_1', 'Наш автопарк состоит из более чем 80 единиц современной спецтехники. Мы используем экскаваторы, краны, погрузчики, самосвалы и тралы ведущих мировых производителей: KAMAZ, Komatsu, Zoomlion, SDLG, Соболь, УАЗ.'],
['paragraph_2', 'Все работы выполняются исключительно силами компании — без привлечения субподрядчиков. Это гарантирует полное соответствие качества, сроков и ответственности на каждом этапе проекта.'],
['paragraph_3', 'Мы работаем в самых сложных условиях: труднодоступные районы, заболоченные территории, Крайний Север. Гибкие варианты оплаты: работаем по договору']
]);
await runEach('INSERT INTO about_features (svg_icon, title, description, sort_order) VALUES (?, ?, ?, ?)', [
['', 'Без субподрядчиков', 'Все работы силами компании', 1],
['', 'Сложные условия', 'Болота, Крайний Север, труднодоступные районы', 2],
['', 'Гибкая оплата', 'Включая расчёт трубой (бартер)', 3]
]);
const svcIcon = {
demolish: '',
clear: '',
lezh: '',
scheme1: '',
scheme2: ''
};
await runEach('INSERT INTO services (svg_icon, title, description, items, is_large, sort_order) VALUES (?, ?, ?, ?, ?, ?)', [
[svcIcon.demolish, 'Демонтаж нефтегазопроводов, утилизация отходов', 'Выполняем полный цикл работ по демонтажу магистральных и промысловых трубопроводов любого типа и диаметра, а также утилизацию отходов.', '["Нефтепроводы, газопроводы, водоводы — все типы магистральных и промысловых сетей","Полный цикл: от вскрытия и вырезки дефектных участков до вывоза и сдачи металлолома","Работа с трубопроводами любого диаметра в любых климатических условиях","Разделка ж/д транспорта, переработка и утилизация для предприятий"]', 1, 0],
[svcIcon.clear, 'Расчистка территории от мелколесья и ДКР', 'Подготовка полосы отвода: расчистка от древесно-кустарниковой растительности.', '["Валка, корчёвка, дробление пней","Планировка полосы отвода","Мульчеры и кусторезы на гусеничном ходу"]', 0, 2],
[svcIcon.lezh, 'Устройство лежневого настила', 'Обеспечение проходимости для тяжёлой техники по болотам и слабым грунтам.', '["Изготовление секций из бревен и бруса","Укладка перекрытий на слабых грунтах","Обеспечение проходимости для тяжёлой гусеничной техники"]', 0, 3]
]);
await runEach('INSERT INTO work_schemes (svg_icon, title, description, items, sort_order) VALUES (?, ?, ?, ?, ?)', [
[svcIcon.scheme1, 'Схема 1 — с доставкой заказчику', 'Подходит для компаний, планирующих повторное использование труб или их последующую реализацию. Расходный договор для заказчика.', '["Полный цикл работ по демонтажу трубопровода","Резка и маркировка труб в соответствии с требованиями","Транспортировка демонтированных труб на указанные территории хранения","Оформление всей сопроводительной документации (акты приёма-передачи)"]', 0],
[svcIcon.scheme2, 'Схема 2 — вывоз на базы подрядчика', 'Экономически выгодное решение для заказчиков, заинтересованных в минимизации затрат. Доходный договор для заказчика.', '["Полный цикл работ по демонтажу трубопровода","Перевозка и размещение на сертифицированных площадках временного хранения ООО «СТС-АВТО»","Покупка трубы в земле — заказчик получает доход от металлолома","Оформление полного пакета закрывающей документации"]', 1]
]);
await runEach('INSERT INTO process_steps (step_number, title, description, sort_order) VALUES (?, ?, ?, ?)', [
[1, 'Заявка', 'Вы оставляете заявку на сайте, по электронной почте или звоните нам. Наши специалисты оперативно свяжутся с вами для обсуждения деталей проекта, объёма работ и сроков.', 0],
[2, 'Выезд специалиста и оценка', 'Наш инженер выезжает на объект для проведения осмотра, оценки объёма работ, определения необходимых ресурсов и техники. По результатам составляется техническое задание и подписывается договор.', 1],
[3, 'Выполнение работ', 'Мобилизуем технику и персонал на объект. Выполняем демонтаж и утилизацию отходов в соответствии с проектной документацией. Ежедневные отчёты о ходе работ.', 2],
[4, 'Сдача объекта', 'По завершении всех работ подписывается акт выполненных работ, передаётся полный комплект закрывающей документации. При необходимости — сопровождение сдачи объекта экспертизе.', 3]
]);
await runEach('INSERT INTO equipment (name, brand, image_path, qty, specs, sort_order) VALUES (?, ?, ?, ?, ?, ?)', [
['Автокран КАМАЗ КС-55717К-3', 'КАМАЗ', 'ks-45721.webp', '10 единиц', '[{"label":"Грузоподъёмность","value":"25 тонн"},{"label":"Вылет стрелы","value":"до 28 м"},{"label":"Шасси","value":"Полноприводное 6×6"}]', 0],
['Автокран Zoomlion ZTC300', 'Zoomlion', 'zoomlion-ztc300.webp', '2 единицы', '[{"label":"Грузоподъёмность","value":"30 тонн"},{"label":"Вылет стрелы","value":"до 32 м"},{"label":"Стрела","value":"Телескопическая"}]', 1],
['Экскаватор гусеничный Komatsu PC210-10M0', 'Komatsu', 'komatsu-pc210.webp', '20 единиц', '[{"label":"Масса","value":"21 тонна"},{"label":"Объём ковша","value":"1.0–1.2 м³"},{"label":"Глубина копания","value":"до 6.5 м"}]', 2],
['Экскаватор гусеничный Zoomlion ZE215E', 'Zoomlion', 'zoomlion-ze215e.webp', '2 единицы', '[{"label":"Масса","value":"21.5 тонны"},{"label":"Объём ковша","value":"1.1 м³"},{"label":"Аналог","value":"Komatsu PC210"}]', 3],
['Погрузчик колёсный SDLG LG933L', 'SDLG', 'sdlg-lg933l.webp', '2 единицы', '[{"label":"Грузоподъёмность","value":"3 тонны"},{"label":"Объём ковша","value":"1.7 м³"},{"label":"Тип","value":"Колёсный"}]', 4],
['Соболь 4×4 грузо-пассажирский', 'Соболь', 'sobol-4x4.webp', '13 единиц', '[{"label":"Грузоподъёмность","value":"до 1 т"},{"label":"Привод","value":"Полный 4×4"},{"label":"Назначение","value":"Доставка персонала и запчастей"}]', 5],
['Ломовоз с КМУ (кран-манипулятор)', 'Ломовоз', 'lomovoz-kmu.webp', '3 единицы', '[{"label":"Грузоподъёмность КМУ","value":"до 8 т"},{"label":"Объём платформы","value":"до 20 м³"},{"label":"Назначение","value":"Вывоз металлолома"}]', 6],
['Седельный тягач Камаз 53504-50', 'КамАЗ', 'kamaz-53504.webp', '6 единиц', '[{"label":"Тяговый класс","value":"до 50 т"},{"label":"Привод","value":"Полный привод"},{"label":"Назначение","value":"Перевозка негабарита и тралов"}]', 7],
['Экскаватор-амфибия на понтонной платформе', 'Амфибия', 'amfibia.webp', '4 единицы', '[{"label":"Тип","value":"Гусеничный, плавающий"},{"label":"Работает","value":"На болотах и водных преградах"},{"label":"Особенность","value":"Там, где не видно дна"}]', 8],
['УАЗ Пикап (полный привод)', 'УАЗ', 'uaz-pickup.webp', 'Несколько единиц', '[{"label":"Привод","value":"Полный привод"},{"label":"Назначение","value":"Доставка запчастей на месторождения"}]', 9],
['Тралы тяжеловозы для доставки спецтехники', 'Тралы', 'tral-1.webp', '3 единицы', '[{"label":"Тяговый класс","value":"до 50 т"},{"label":"Назначение","value":"Доставка спецтехники на объекты"}]', 10]
]);
await runEach('INSERT INTO geo_regions (name, sort_order) VALUES (?, ?)', [
['УрФО', 0], ['СФО', 1], ['ПФО', 2], ['СЗФО', 3], ['ДФО', 4], ['ЮФО', 5]
]);
await runEach('INSERT OR IGNORE INTO geo_settings (key, value) VALUES (?, ?)', [
['section_subtitle', 'Работаем во всех федеральных округах Российской Федерации. Особые условия для труднодоступных районов Крайнего Севера и заболоченных территорий.'],
['difficult_title', '🔧 Труднодоступные районы'],
['difficult_desc', 'Мы располагаем специализированной техникой для работы в болотах ХМАО-Югры, ЯНАО, на севере Красноярского края, в Иркутской области. Гусеничная техника и лежневые настилы обеспечивают проходимость даже в самых сложных условиях.'],
['map_image', './img/geo.webp']
]);
const licIcon = '';
await runEach('INSERT INTO licenses (svg_icon, title, description, sort_order) VALUES (?, ?, ?, ?)', [
[licIcon, 'СРО — допуск к работам на опасных объектах', 'Свидетельство о допуске к работам на опасных производственных объектах нефтегазового комплекса.', 0],
[licIcon, 'Членство в НОСТРОЙ', 'Действующее членство в Национальном объединении строителей — допуск к строительным работам.', 1],
['', 'Сертификат ISO 9001 (качество)', 'Международный стандарт системы менеджмента качества.', 2],
['', 'Сертификат OHSAS 18001 (охрана труда)', 'Система менеджмента охраны труда и промышленной безопасности.', 3],
['', 'Договор ДМС для сотрудников', 'Добровольное медицинское страхование всех сотрудников.', 4],
['', 'Лицензия на заготовку и переработку лома', 'Лицензия на заготовку, хранение и переработку лома черных металлов.', 5]
]);
await runEach('INSERT INTO license_gallery (title, description, image_path, sort_order) VALUES (?, ?, ?, ?)', [
['Лицензия на отходы I–IV класса опасности', '№ (66) -6527 - СТО/П от 21 мая 2019 г.', 'license-otxody.webp', 0],
['Лицензия на лом черных и цветных металлов', '№ ЛМ 000092 от 31 октября 2018 г.', 'license-lom.webp', 1]
]);
await runEach('INSERT INTO public_activities (svg_icon, title, description, sort_order) VALUES (?, ?, ?, ?)', [
['', 'Спонсорство', 'Поддерживаем спортивные, культурные и общественные мероприятия в регионах присутствия. Помогаем развитию местных сообществ.', 0],
['', 'Благотворительность', 'Оказываем адресную помощь детским домам, ветеранским и общественным организациям. Участвуем в социальных проектах.', 1],
['', 'Экология', 'Участвуем в экологических акциях, субботниках и проектах по озеленению. Следим за снижением воздействия на окружающую среду.', 2],
['', 'Поддержка образования', 'Сотрудничаем с профильными вузами и колледжами. Организуем практику для студентов, участвуем в ярмарках вакансий.', 3]
]);
await runEach('INSERT INTO activity_gallery (title, description, image_path, sort_order) VALUES (?, ?, ?, ?)', [
['Благодарственное письмо', 'За вклад в развитие региона', 'thanks-1.webp', 0],
['Благодарственное письмо', 'За благотворительную деятельность', 'thanks-2.webp', 1]
]);
await runEach('INSERT INTO partners (name, logo_path, sort_order) VALUES (?, ?, ?)', [
['Газпром', 'газпром.webp', 0], ['Роснефть', 'роснефть.webp', 1],
['Сибур', 'сибур.webp', 2], ['Сургутнефтегаз', 'сургутнефтегаз.webp', 3],
['Транснефть', 'транснефть.webp', 4]
]);
await runEach('INSERT OR IGNORE INTO settings (key, value) VALUES (?, ?)', [
['logo_path', './img/logo.webp'],
['contact_phone_800', '8 (800) 555-29-31'], ['contact_phone_ekb', '8 (343) 237-25-66'],
['contact_email', 'sts_zakaz@mail.ru'], ['contact_address', 'г. Екатеринбург, ул. Московская, 11, оф. 702'],
['contact_work_hours', 'Пн–Пт: 9:00 – 18:00|Сб: 10:00 – 15:00'], ['contact_map_image', './img/secret.webp'],
['footer_text', '© {year} ООО «СТС-Авто». Все права защищены. 16+'],
['form_title', 'Оставить заявку'], ['form_subtitle', 'Заполните форму и мы свяжемся с вами в ближайшее время'],
['section_services_subtitle', 'Полный спектр работ по демонтажу и утилизации трубопроводной инфраструктуры. Работаем на опасных производственных объектах с собственным парком спецтехники.'],
['section_schemes_subtitle', 'Мы разработали гибкие схемы работы, позволяющие выбрать оптимальное решение с учётом ваших целей и бюджета.'],
['section_process_subtitle', 'Прозрачный и отлаженный процесс от первого обращения до сдачи объекта. Каждый этап контролируется инженерами компании.'],
['section_equipment_subtitle', 'Собственный парк из более чем 80 единиц современной спецтехники ведущих мировых производителей.'],
['section_licenses_subtitle', 'Все необходимые допуски и сертификаты для выполнения работ на опасных производственных объектах. Полная прозрачность и соответствие требованиям законодательства РФ.'],
['section_activity_subtitle', 'Компания «СТС-Авто» активно участвует в социальной и общественной жизни регионов присутствия.'],
['section_partners_subtitle', 'Сотрудничаем с ведущими компаниями нефтегазового сектора.'],
['section_contacts_subtitle', 'Оставьте заявку или позвоните — мы оперативно ответим на ваши вопросы и рассчитаем стоимость работ.']
]);
}
function getDb() {
return db;
}
module.exports = { init, getDb };