Тема
Сеть и стек склада
Проект interbase · техническое предложение, не ТЗ

Сеть и стек склада

Предполагаемая топология сети заказчика, целевой стек и порядок замены складской программы на Delphi 7 / InterBase — без остановки работы склада.

20 000 SKU · автозапчасти Delphi 7 + InterBase рабочие места на Windows XP сервер: Debian 13 почты у заказчика пока нет топология построена на допущениях принципы: простота · надёжность · быстродействие
Документ носит предварительный характер

Обследование ещё не проводилось. Точных сведений о топологии сети нет: схема ниже построена на типовом устройстве сети предприятия такого размера и на предположении, что шлюзом служит MikroTik. Количество рабочих мест — оценка по четырём названным ролям и объёму в 20 000 позиций. Версия InterBase и структура базы не установлены.

Что от этого не изменится: выбор технологий — он опирается на подтверждённые факты (Delphi 7, InterBase, Windows XP на рабочих местах) и на три принципа заказчика; необходимость отдельной машины под сервер; порядок поэтапного перехода без остановки склада.

Что будет уточнено: схема сети и число сегментов, количество рабочих мест и оборудования, объём работ по переносу данных, а вместе с ним — сроки и стоимость. Оценивать последние две величины до того, как станет известно содержимое базы, было бы неточно.

Вводные

Исходные данные и допущения

Оранжевым отмечено то, что пока принято как предположение. Эти пункты подтверждаются или заменяются фактами при обследовании — на них опирается значительная часть документа, поэтому просьба к заказчику прочитать их первыми и поправить, где не так.

Факты от заказчика
  • Складская программа написана на Delphi 7, база — InterBase.
  • Около 20 000 номенклатур, автозапчасти.
  • Система работает только во внутренней сети.
  • Рабочие места на Windows XP.
  • Есть отдельный интернет-магазин (пока вне работ).
  • Роли: менеджер, кладовщик, директор, бухгалтер.
  • Ежедневно снимается копия базы на внешний диск.
  • Уведомления по почте заложены в работу складской программы.
  • У разработчика есть личный VPS с почтовым сервером.
Предположительно · сеть
  • Шлюз — MikroTik, RouterOS 6 или 7.
  • Сеть плоская, без VLAN, вероятно 192.168.88.0/24 (дефолт MikroTik).
  • Коммутаторы неуправляемые, включены каскадом.
  • Сервер InterBase — обычный ПК под Windows, файл .gdb на локальном диске.
  • 10–12 рабочих станций, 20–25 устройств всего.
  • Внешний диск с копиями постоянно подключён к серверу.
  • Из копии ни разу не восстанавливали.
Предположительно · типичное для этого поколения
  • Delphi-клиент ходит в базу напрямую по TCP 3050, без сервера приложений.
  • Бизнес-логика живёт в формах Delphi и в хранимых процедурах, а не в одном слое.
  • Исходники клиента либо утеряны, либо у стороннего автора.
  • Кодировка базы — WIN1251 или, хуже, NONE.
  • Копия снимается копированием файла .gdb при работающем сервере — а не через gbak.
  • Наружу проброшен RDP или сам порт 3050.
Сеть

Целевая топология

Схема ниже предположительная: она построена на типовом устройстве сети предприятия такого размера, а количество рабочих мест выведено из четырёх названных ролей. После обследования числа и сегменты будут уточнены, но замысел останется тем же — вынести XP-машины в отдельные сегменты без выхода в интернет, а всё новое поставить на один сервер Debian. Пока хотя бы одна XP-машина имеет одновременно и доступ в интернет, и доступ к базе, защита остальной сети не имеет смысла.

Интернет ISP · внешний IP Внешние сервисы заказчика почта на его домене · интернет-магазин SMTP ДЛЯ ПРИЛОЖЕНИЯ · ВНЕШНЯЯ КОПИЯ БАЗЫ Разработчик WIREGUARD · UDP 13231 MikroTik · шлюз и межсетевой экран RouterOS 7 · маршрутизация между VLAN · WireGuard · DHCP · DNS WINBOX И SSH — ТОЛЬКО ИЗ VLAN 99 ТУННЕЛЬ WIREGUARD, БЕЗ ОТКРЫТЫХ ПОРТОВ Управляемый коммутатор L2 802.1Q · TRUNK ДО РОУТЕРА · ACCESS-ПОРТЫ ПО VLAN VLAN 10 · СЕРВЕРЫ · 10.10.10.0/24 Сервер приложений — Debian 13 PostgreSQL 17 · Nginx · PHP-FPM 8.4 Laravel · синхронизация по расписанию резервные копии, оповещения, Git 10.10.10.10 · TCP 443, 5432 (ЛОКАЛЬНО) Сервер InterBase — Windows боевая база .gdb · до конца миграции внешний диск — ежедневная копия 10.10.10.20 · TCP 3050 (GDS_DB) VLAN 20 · ОФИС · 10.10.20.0/24 Менеджеры · 4 ПК Delphi-клиент + браузер WINDOWS XP Бухгалтерия · 2 ПК 1С, банк-клиент, выгрузки ОТДЕЛЬНОЕ ПРАВИЛО ДЛЯ БАНКА Директор · ПК и ноутбук ТОЛЬКО ОТЧЁТЫ, БЕЗ ПРАВ НА ПРАВКУ VLAN 30 · СКЛАД · 10.10.30.0/24 Кладовщики · 3 ПК приёмка, отбор, отгрузка WINDOWS XP · СКАНЕРЫ USB (HID) Принтер этикеток Zebra печать ZPL с сервера, минуя драйверы XP 10.10.30.50 · TCP 9100 Интернета нет разрешены только 10.10.10.10:443 и 10.10.10.20:3050 VLAN 40 · WI-FI СКЛАДА · 10.10.40.0/24 2 точки доступа + ТСД 3 терминала сбора данных на Android WPA3/WPA2-Enterprise, изоляция клиентов РАЗРЕШЕНО ТОЛЬКО 10.10.10.10:443 VLAN 50 · ГОСТИ · 10.10.50.0/24 Телефоны сотрудников, гости только интернет, ограничение полосы полная изоляция от остальных VLAN ЛИЧНЫЕ УСТРОЙСТВА — СЮДА, И ТОЛЬКО СЮДА VLAN 99 · УПРАВЛЕНИЕ · 10.10.99.0/24 Роутер, коммутатор, точки доступа веб-интерфейсы оборудования, IPMI доступ — с рабочего места админа и по VPN ИЗ ДРУГИХ VLAN НЕДОСТУПЕН
допущение, требует подтверждения новое: ставится в этом проекте наследие и связанный с ним риск существующее оборудование
Количество рабочих мест — оценка под четыре названные роли и объём в 20 000 позиций. Структура сегментов от точного числа машин не зависит: изменится только размер закупки коммутатора.

План адресов и доступов

Адресация предлагаемая: нынешняя, скорее всего, плоская и на заводских настройках роутера. Конкретные подсети значения не имеют и могут быть любыми — важно само разделение на сегменты и правила между ними.

VLAN Сегмент Подсеть Кому и куда разрешено Интернет
10 Серверы 10.10.10.0/24 Debian-сервер ходит в InterBase :3050; входящие — только 443 и SSH из VLAN 99 исходящий, для обновлений
20 Офис 10.10.20.0/24 10.10.10.10:443, 10.10.10.20:3050, сетевые принтеры да, с фильтрацией DNS
30 Склад 10.10.30.0/24 10.10.10.10:443, 10.10.10.20:3050, принтер этикеток :9100 запрещён
40 Wi-Fi склада 10.10.40.0/24 только 10.10.10.10:443 запрещён
50 Гости 10.10.50.0/24 ничего внутри сети да, с ограничением полосы
99 Управление 10.10.99.0/24 доступ ко всему оборудованию; попасть можно с места админа и по WireGuard нет

Порты на MikroTik

Сам роутер и версия RouterOS пока тоже предположительны, но список ниже от модели не зависит — так же он выглядел бы на любом другом оборудовании. Снаружи открыт ровно один порт, и тот не TCP; всё остальное живёт внутри периметра. Правила делятся на две цепочки: обращения к самому роутеру и прохождение трафика между сегментами.

Откуда Порт Куда и зачем Решение
Из интернета UDP 13231 WireGuard — единственный вход снаружи. Через него заходят администратор и разработчик разрешено
Из интернета всё прочее Winbox, SSH, RDP, веб-интерфейс роутера, порт базы. Правил проброса нет ни одного запрещено
VLAN 99 и WireGuard TCP 8291, 22 Winbox и SSH на самом роутере — управление разрешено
Все внутренние VLAN UDP 53 DNS. Рабочие места спрашивают у роутера, какому имени какой адрес соответствует. Здесь же живёт внутреннее имя сервера разрешено
Все внутренние VLAN UDP 67, 68 DHCP. Выдача адреса, маски, шлюза и адреса DNS при включении компьютера. Роутер слушает 67, компьютер отвечает с 68 разрешено
Все внутренние VLAN ICMP Отклик на пинг. Нужен для проверки связи и для корректной работы протоколов; отключать его — распространённая ошибка, создающая трудноуловимые сбои разрешено
VLAN 20 · офис TCP 443
TCP 3050
TCP 9100
Новая система, база InterBase, сетевые принтеры. Плюс выход в интернет разрешено
VLAN 30 · склад TCP 443
TCP 3050
TCP 9100
То же, но без интернета — только эти три направления и ничего больше строго по списку
VLAN 40 · ТСД TCP 443 Только веб-приложение. Ни базы, ни принтеров, ни интернета строго по списку
VLAN 50 · гости Внутрь сети — ничего. Наружу — интернет с ограничением полосы изоляция
VLAN 10 · серверы TCP 3050
исходящие 443, 587, 53
Сервер ходит в InterBase, за обновлениями, за почтой заказчика и в DNS разрешено
Ловушка, на которой ломается вся затея с сегментацией

InterBase использует порт 3050 для соединения, но для событий открывает второй порт, выбираемый случайно. Пока сеть плоская, этого никто не замечает. Как только между рабочими местами и сервером базы появляется фильтрация, старая программа начинает вести себя странно: соединение есть, а списки не обновляются или клиент подвисает.

Поэтому до включения правил нужно выяснить, использует ли Delphi-клиент события базы, и если да — зафиксировать этот порт в настройках InterBase и открыть его наравне с 3050. Проверять это следует на паре рабочих мест до того, как сегментация распространится на весь склад.

DHCP и DNS — две мелочи, о которых забывают при переходе на сегменты

DHCP не проходит между сегментами. Выдача адресов работает широковещательно в пределах своего VLAN, поэтому в каждом сегменте нужен свой пул адресов на роутере. И правило, разрешающее эти пакеты, должно стоять до общего запрета: типичная картина после включения сегментации — сеть настроена верно, но компьютеры не получают адрес, потому что запрещающее правило отработало раньше.

Серверу нужно имя, а не адрес. Сертификат выписывается на имя, поэтому на роутере заводится статическая запись — например sklad в домене заказчика указывает на 10.10.10.10. Пользователь открывает адрес по имени, браузер не ругается на сертификат. Снаружи то же имя ведёт на сайт заказчика: внутренняя запись видна только внутри сети.

Что отключить на самом роутере

По умолчанию RouterOS держит включёнными службы, которые здесь не нужны и лишь расширяют поверхность атаки: telnet, ftp, www, api, api-ssl. Оставляем winbox и ssh, ограничив их адресами VLAN 99.

Отдельно — доступ по MAC-адресу: mac-server и mac-winbox. Через них к роутеру подключаются в обход всех правил фильтрации по адресам, и об этом регулярно забывают. Оставить их следует только на интерфейсе управления. Туда же — обнаружение соседей, bandwidth-test и romon выключить полностью.

Порядок правил обычный для RouterOS: сначала пропуск установленных соединений, затем отбрасывание недействительных, затем разрешающие правила по списку, и последним — запрещающее всё остальное с записью в журнал. Именно последнее правило и делает список выше исчерпывающим.

Первое, что нужно проверить на объекте

Не проброшены ли наружу RDP (3389) и сам порт InterBase (3050). Проброшенный 3050 означает, что базу склада может скачать кто угодно: аутентификация InterBase старых версий ломается перебором за часы. Если проброс есть — закрыть его в первый же день и выдать вместо него WireGuard.

Защита

Безопасность сервера: минимум, который работает

Принцип простоты применим и здесь. Сложная защита, которую никто не понимает и не проверяет, надёжнее не делает — она лишь создаёт ощущение защищённости и мешает работать. Ниже — короткий список того, что даёт основной эффект и не требует постоянного внимания.

Мера Что даёт Хлопоты
Наружу не смотрит ничего Главная мера, обесценивающая большинство атак. Ни SSH, ни база, ни панель управления не имеют внешнего адреса: снаружи попасть можно только через WireGuard Настраивается один раз
Вход по ключу, без пароля Парольный вход и вход под root отключены. Подобрать нечего Две строки в конфигурации SSH
PostgreSQL слушает только себя listen_addresses = 'localhost'. База недоступна по сети даже изнутри — к ней ходит только приложение на той же машине Одна строка
Автоматические обновления безопасности unattended-upgrades ставит исправления Debian сам. Это то, чего принципиально нет на XP, и главное преимущество Linux-машины в повседневности Установка одной командой
Приложение работает не от root Свой системный пользователь, свой пользователь базы с правами только на свою схему. Ошибка в коде не становится доступом ко всей машине Часть установки
Ограничение попыток входа в приложении Штатное средство Laravel: после нескольких неудач вход по этой учётной записи тормозится. Работает точнее сетевых блокировок, потому что видит имя пользователя, а не только адрес Встроено
Журнал действий пользователей Кто провёл документ, кто изменил цену, кто списал позицию. Нужен не столько для защиты, сколько для разбора спорных ситуаций на складе — а это происходит регулярно Проектируется сразу, дописать потом дороже
fail2ban Блокирует адреса после серии неудачных попыток. Подробнее ниже: при правильной сегментации это второй рубеж, а не первый Установка и один файл настроек
fail2ban: зачем он нужен, если снаружи и так ничего не видно

Честно говоря, при работающей сегментации сети ловить ему почти нечего — SSH закрыт за туннелем, база слушает только себя. Ставить его стоит по другой причине: он защищает от собственной ошибки. Правило на роутере однажды поправят «на пять минут, чтобы проверить», забудут вернуть, и порт останется открытым на месяцы. Вот тогда fail2ban и отработает — молча, без чьего-либо участия.

Настройка ровно одна: отслеживание неудачных входов по SSH, блокировка на час после пяти попыток. Внутренние подсети — в исключениях, иначе сотрудник, трижды опечатавшийся в пароле, останется без работы до конца обеда, и звонить будут вам. Веб-форму входа сторожит не он, а штатное ограничение Laravel: оно видит, к какой учётной записи подбирают пароль, а не только с какого адреса.

Чего сознательно не делаем

Антивирус на сервере Linux, системы обнаружения вторжений, сбор и анализ журналов в отдельной подсистеме, доменная служба каталогов на двенадцать человек, политика обязательной смены паролей раз в месяц. Первые четыре — это постоянная работа по обслуживанию без соразмерной пользы на таком масштабе. Последняя и вовсе вредна: она надёжно приводит к паролям на бумажках под клавиатурой.

Вместо этого — то, что перечислено выше, плюс две вещи вне сервера: ИБП и место для машины, куда не заходят посторонние. Сервер, стоящий в проходе склада, — риск более вероятный, чем сетевая атака.

Организация работ

Удалённая настройка сервера

Работы ведутся удалённо, и это накладывает два условия. Первое: нужно как-то получить доступ в сеть, где пока нет ни сервера, ни VPN. Второе, и более важное: нужно устроить всё так, чтобы этот доступ нельзя было потерять одной неудачной командой — потому что восстанавливать его будет некому.

Как появляется первый доступ

ШАГ 1

Установка системы на месте. Кто-то должен физически поставить Debian: загрузиться с флешки и дойти до конца установщика. Это делает сотрудник заказчика или поставщик оборудования — по короткой письменной инструкции, либо с подготовленной флешки, где установка проходит автоматически и от человека требуется только выбрать загрузку с неё.

полчаса времени одного человека на объекте

ШАГ 2

Сервер сам звонит наружу. В установку включается готовый файл настройки: сразу после первого запуска сервер поднимает исходящее соединение до внешней точки встречи. Дальше подключение идёт по этому туннелю.

Ключевое свойство: исходящему соединению не нужен ни один открытый порт на роутере. Ничего настраивать в MikroTik на этом этапе не требуется вовсе — а значит, не требуется и человек, умеющий это делать.

доступ появляется без единой правки в сети заказчика

ШАГ 3

Полноценный VPN на роутере. Когда сервер уже доступен, с него же настраивается WireGuard на MikroTik — это и становится постоянным способом подключения, принадлежащим заказчику. Временный туннель после этого остаётся вторым, запасным путём.

постоянный доступ на инфраструктуре заказчика

Как не потерять доступ

Главный риск удалённой настройки — заблокировать себя самому: одно правило межсетевого экрана, одна ошибка в настройке сети, и машина жива, но недосягаема. Меры простые и стоят почти ничего.

Два независимых пути

WireGuard на роутере и обратный туннель с сервера работают по-разному и ломаются от разных причин. Потерять оба одновременно почти невозможно, а вернуться по любому из них достаточно.

Безопасный режим на MikroTik

Winbox умеет применять изменения с автоматической отменой: если связь с роутером пропадёт, все правки откатятся сами. При удалённой настройке правил это не рекомендация, а обязательный порядок работы.

Отложенный откат на сервере

Перед рискованной правкой сети или экрана ставится задание, возвращающее прежнюю настройку через десять минут. Всё прошло удачно — задание отменяется вручную. Не прошло — сервер чинит себя сам.

Человек на объекте

Нужна договорённость заранее: кто именно может подойти к серверу, включить его или подключить монитор, и по какому телефону он доступен. Один человек и его номер — этого достаточно, но выяснять это в момент аварии уже поздно.

Управление по отдельному каналу

Серверные платы умеют отдавать экран и клавиатуру по сети независимо от операционной системы — с ними машину видно, даже когда она не загружается. Удорожает покупку, но для удалённой работы окупается первым же случаем. Существуют и недорогие внешние устройства с той же функцией.

Настройка как код

Установка описывается сценарием, а не выполняется руками по памяти. Сервер можно повторить с нуля за час — на новом железе или после серьёзной поломки. Для одной машины достаточно одного простого сценария, без сложной оснастки.

Что из этого требуется от заказчика

Немного: один человек на объекте, который поставит систему по инструкции и будет на связи на случай, если к серверу придётся подойти физически. Всё остальное делается удалённо — включая настройку роутера, перенос данных и обновления. Приезд на объект нужен только если оборудование окажется с сюрпризом.

Наследие

Что следует из связки Delphi 7 и InterBase

Сама по себе эта связка ещё не говорит, как устроена программа внутри. Она задаёт три вопроса, и ответы на них определяют объём работ сильнее, чем что-либо ещё в этом документе. Все три выясняются в первые дни обследования.

Есть ли промежуточный слой

Предположительно его нет — так устроено подавляющее большинство программ этого поколения: каждое рабочее место открывает собственное соединение и пишет в таблицы напрямую. Тогда новую систему нельзя вставить в середину — она может только читать ту же базу рядом, а затем забирать участки работы себе.

Реже встречается трёхзвенная схема с сервером приложений посередине. Если окажется так — это хорошая новость: появляется место, куда можно встроиться.

Где живёт бизнес-логика

Здесь три расклада. Логика может быть в базе — в хранимых процедурах и триггерах; тогда правила читаются прямо из неё, и это лучший случай. Может быть в формах Delphi — тогда база лишь хранилище, и без исходников правила придётся восстанавливать по данным и расспросам сотрудников. Предположительно здесь третий вариант — и там, и там: он встречается чаще прочих.

Проверяется просто: выгрузить перечень объектов базы. Две сотни процедур на тысячи строк означают одно, пять простых вставок — совсем другое.

Версия InterBase решает всё

Здесь предположений нет, только развилка. InterBase 6.0 читается свободным Firebird — тогда копию базы можно поднять на Debian и работать с ней как угодно. InterBase 7 и новее — уже нет: понадобится либо InterBase под Linux, либо оставить чтение на Windows-машине.

Почему эти три ответа стоят дороже всех остальных

От них зависит не выбор технологий — он уже сделан и от них не меняется, — а сроки и стоимость. Логика в хранимых процедурах читается за дни; логика в утерянных исходниках Delphi восстанавливается неделями, через наблюдение за работой людей. Разброс между лучшим и худшим раскладом здесь кратный, и до обследования любая названная цифра была бы догадкой.

Одна команда, которая снимает половину неизвестности

На сервере базы выполнить gstat -h имя_базы.gdb. Вывод покажет версию ODS (структуру файла), кодировку по умолчанию, размер страницы и объём. По ODS сразу понятно, читается ли база свободным Firebird, а по кодировке — насколько больно будет переносить кириллицу. Делать это на копии файла, снятой через gbak, а не на боевом файле.

Оценка рисков

Что означает Windows XP на рабочих местах

Возраст системы сам по себе мало о чём говорит: она работает и делает свою работу уже много лет. Значение имеет другое — какие именно риски она создаёт сегодня и сколько дней склад не сможет отгружать, если эти риски сработают. Ниже — проверяемые факты и последствия каждого из них для склада.

Сценарий, ради которого всё это пишется

Одна машина в офисе ловит шифровальщика — через почту, флешку или сайт с «прошивкой для сканера». У этой машины есть сетевой доступ к файлу базы склада. Через несколько минут .gdb зашифрован. Дальше всё зависит ровно от одного: есть ли копия, из которой действительно можно восстановиться.

Ежедневная копия на внешний диск от этого сценария не спасает. Шифровальщики специально ищут подключённые тома — внешний диск, висящий на USB сервера, шифруется вместе с базой в том же проходе. А если копия одна и перезаписывается каждый день, то повреждение, замеченное через двое суток, к этому моменту уже уехало в копию поверх исправной.

Это не гипотеза про будущее: именно так в 2017 году останавливались предприятия, где остался SMBv1, — а XP не умеет ничего, кроме SMBv1.

Факт Что это значит на складе Уровень
Поддержка закончилась 8 апреля 2014
Продлённые обновления по ветке POSReady — до 9 апреля 2019
Уязвимости, найденные после этой даты, не закрываются никогда. Их число только растёт, и они публичны — эксплойты лежат в открытом доступе. критично
Только SMBv1 Протокол, по которому WannaCry и NotPetya прошли по сетям целых предприятий. Заражение одной машины расходится на все остальные автоматически, без участия человека. критично
Современные антивирусы не ставятся Производители прекратили выпуск версий под XP. То, что стоит на машинах сейчас, не получает баз и не видит ничего нового. критично
Нет современной защиты памяти В новых системах эксплойт чаще всего просто не срабатывает. На XP он срабатывает почти всегда. критично
TLS 1.0 Банк-клиенты, платёжные шлюзы, порталы поставщиков и госсервисы один за другим отказываются работать. Это уже происходит и будет происходить дальше — просто в неудобный момент. срочно
Пользователи работают администраторами Так исторически настроено почти везде, где остался XP. Любая запущенная программа получает полные права на машину. срочно
Драйверов под новое оборудование нет Новый принтер этикеток, сканер или сетевая карта могут просто не заработать. Выбор техники ограничен вторичным рынком. срочно
Современное ПО не поддерживает XP 1С 8.3, актуальные банк-клиенты, ЭДО, любая новая программа — всё это на XP не встанет. Развитие бизнеса упирается в операционную систему. срочно
Железу пятнадцать лет и больше Диски, блоки питания и память отрабатывают ресурс. Запчастей нет, а выход из строя машины кладовщика — это остановка отгрузок на день-два. срочно
Персональные данные клиентов Они хранятся и обрабатываются на системе, которая по определению не может считаться защищённой. Для проверяющих это не спорный вопрос. срочно
Обоснование

Зачем нужна хотя бы одна машина на Linux

Это не вопрос вкуса и не «потому что разработчик так привык». Без отдельного сервера половина работ по проекту физически негде выполнить, а самый острый риск — отсутствие резервных копий — не закрывается вообще ничем.

Копии становятся проверяемыми

Ежедневная копия у заказчика уже есть — не хватает второго адреса, глубины хранения и проверки. Ночной gbak уезжает на сервер, оттуда зашифрованным — на внешнюю площадку, и раз в неделю автоматически разворачивается обратно. Копия, из которой ни разу не восстанавливали, копией не считается.

Есть где поднять копию базы

Всю разработку и разбор старой схемы можно вести на копии, не касаясь боевой базы. Без этого любой эксперимент идёт на живых данных склада.

Единственное место с современным TLS

Обновления безопасности прилетают автоматически и бесплатно до 2030 года. Всё, что должно ходить наружу — обмен с поставщиками, магазин, почта, — ходит отсюда, а не с XP-машины.

Новую систему больше некуда ставить

PostgreSQL, веб-приложение, очереди — на XP это не запускается ни в каком виде. Сервер нужен в любом случае, вопрос только в том, купить его в начале проекта или в середине.

Одна машина вместо пяти ролей

База, веб, резервные копии, наблюдение, конец VPN-туннеля наружу — всё на одном системном блоке. Лицензии Windows Server не нужны, а под нагрузку в 12 человек и 20 000 позиций запаса хватит на годы вперёд.

Точка, откуда видно, что происходит

Сегодня никто не знает, сделалась ли копия и жив ли сервер базы. Появляется наблюдение и оповещение в почту или Telegram: место кончается, копия не прошла, сервис упал.

Резервное копирование: что уже есть и чего не хватает

Ежедневная копия на внешний диск — это уже больше, чем бывает на таких объектах, и отталкиваться есть от чего. Но между «копия делается» и «из копии можно восстановиться в понедельник утром» лежат семь свойств, и внешний диск закрывает из них одно.

Свойство Сейчас Что добавляем
Способ снятия проверить в первую очередь Если файл .gdb просто копируется при работающем сервере — копия несогласованна. Она может открыться, отработать месяцы и развалиться позже gbak — штатная выгрузка InterBase, согласованная по транзакциям
Глубина хранения Похоже, одна копия, перезаписываемая ежедневно 30 суточных точек плюс недельные и месячные. Порча, замеченная через неделю, всё ещё поправима
Число экземпляров Один — внешний диск Три: сервер, внешний диск, зашифрованная копия на внешней площадке
Копия вне здания Нет. Пожар, кража или залив уносят сервер и диск вместе Внешняя площадка, оформленная на заказчика: арендованный сервер или облачное хранилище
Устойчивость к шифровальщику Нет. Постоянно подключённый диск шифруется вместе с базой Отдельный доступ на внешней площадке, где копии можно только дописывать, но не переписывать и не удалять
Проверка восстановления скорее всего не проводилась Еженедельный автоматический разворот копии в отдельную базу с отчётом об итоге
Оповещение о сбое Нет. Скрипт может не отрабатывать месяцами, и никто не узнает Сообщение в Telegram или письмо, если копия не прошла или кончается место
Шифрование носителя Нет. Вынесенный диск — это готовая база клиентов на руках Копии шифруются при создании, на диск и на внешнюю площадку попадают уже зашифрованными
Потери при сбое До суток работы: всё, что сделано после ночной копии Для новой базы — журнал транзакций PostgreSQL, восстановление на любую минуту

Физическое резервирование и непрерывный архив WAL

Ночной дамп отвечает на вопрос «что было вчера в три часа». Журнал предзаписи отвечает на вопрос «что было сегодня в 14:31, за минуту до того, как удалили не тот документ». Для боевого склада нужен именно второй ответ, поэтому физическое резервирование с непрерывным архивированием WAL включается сразу, а не откладывается на потом.

Уровень Что это От чего защищает Частота
Базовая копия
pg_basebackup через pgBackRest
Побайтовый снимок кластера целиком — точка отсчёта, к которой применяются журналы Потеря диска, повреждение кластера, отказ сервера Полная — раз в неделю, разностная — каждую ночь
Непрерывный архив WAL Каждый сегмент журнала предзаписи сразу уезжает в хранилище. Это и есть непрерывность: между копиями нет дыр Ошибка человека и приложения: удалили документ, испортили справочник, выполнили не тот запрос Непрерывно, archive_timeout = 60 — сегмент закрывается минимум раз в минуту
Логический дамп
pg_dump
Текстовая выгрузка структуры и данных, независимая от версии и формата хранения Повреждение самого формата и потребность вытащить одну таблицу, не разворачивая весь кластер Еженедельно, хранится дольше остальных
Копия InterBase
gbak
Штатная согласованная выгрузка старой базы Всё то же самое, пока источником истины остаётся InterBase Ежедневно, до конца миграции

Что это даёт в цифрах

Потеря данных при сбое — не более минуты вместо суток. Время восстановления — порядка получаса на разворот кластера из базовой копии плюс проигрывание журналов.

Сегодня оба показателя — «сутки» и «сколько получится».

Откат на точку во времени

Восстановление задаётся временем: развернуть состояние на 14:31 и посмотреть, что было в документе до правки. Инвентаризацию, испорченную неверным пересчётом, можно поднять отдельно и сверить, не трогая боевую базу.

Чего WAL не заменяет

Архив на том же сервере шифровальщик зашифрует вместе с базой. Поэтому копия обязательно уходит на внешний носитель и на внешнюю площадку — архив WAL это дополняет, но не отменяет.

И это не реплика: физическое резервирование про восстановление, а не про доступность.

Почему pgBackRest, а не свои скрипты

Он закрывает ровно эту задачу: параллельная выгрузка, сжатие, шифрование, разностные копии, контроль целостности и команда check, проверяющая, что архивирование действительно работает. Самописный archive_command — это те же функции, только без проверок и без автора рядом. Здесь готовый инструмент работает на простоту, а не против неё.

Проверка, без которой всё вышеописанное — теория

Раз в неделю сервер сам разворачивает вчерашнюю копию в отдельный экземпляр, проигрывает журналы, выполняет несколько контрольных запросов — число позиций, сумма остатков — и присылает результат. Если разворот не удался, вы узнаёте об этом в спокойный вторник, а не в тот день, когда копия понадобилась по-настоящему.

Когда появится вторая машина, тот же архив WAL превращается в постоянную реплику — данные едут на неё непрерывно, и при отказе основного сервера склад продолжает работать. Но это уже про доступность и отдельные деньги; резервирование нужно раньше и в любом случае.

Что покупать

Компонент Минимум Комфортно Почему
Процессор 4 ядра 6–8 ядер PostgreSQL, PHP-FPM, служба синхронизации и отчёты работают одновременно
Память 16 ГБ 32 ГБ ECC База целиком помещается в кэш — отчёты по 20 000 позиций отвечают мгновенно
Диски 2 × 500 ГБ NVMe, зеркало 2 × 1 ТБ NVMe, зеркало Зеркало — чтобы отказ одного диска не был событием. Это не замена резервным копиям
ИБП обязательно с корректным завершением работы Внезапное отключение питания — самый частый способ повредить базу
Внешний диск 1 ТБ USB плюс копия на внешней площадке Третий экземпляр копии, физически отдельный от сервера
Внешняя площадка нужна, но она должна быть на заказчике

Схеме нужна точка вне офиса: там лежит третий экземпляр резервных копий — зашифрованный, вне здания, чтобы пожар или кража не унесли всё сразу. Оттуда же уходит почта, и туда же на пятой фазе переезжает обмен с интернет-магазином.

Оформляется всё это на заказчика: его домен, его учётная запись, его оплата. Личный сервер разработчика на этой роли выглядит удобно ровно до первого отпуска — подробнее в следующем разделе.

Связь между офисом и внешней площадкой — только туннель WireGuard. Ни PostgreSQL, ни тем более InterBase наружу не открываются никогда.

Почта

Кто отправляет письма и с чьего домена

Уведомления заложены в работу склада, значит почта — не дополнительная опция, а часть системы. И здесь важно с самого начала развести два совершенно разных потока писем: их путают почти всегда, а требования у них противоположные.

Поток А · внутрь

Служебные оповещения

Не прошла резервная копия, кончается место, сервис не отвечает, сбой синхронизации. Получателей один-два, объём — единицы сообщений в день. Никого снаружи они не касаются.

Лучше вообще не почтой, а ботом в Telegram: доходит мгновенно, не попадает в спам и не требует почтового сервера. Для «копия не сделалась» это точнее любого письма.

Поток Б · наружу

Письма клиентам заказчика

Подтверждение заказа, счёт, накладная, статус отгрузки. Это письма от лица фирмы, и уходить они обязаны с её домена, с её подписью и реквизитами.

Письмо о заказе автозапчастей, пришедшее с личного домена постороннего человека, выглядит как мошенничество — и почтовые службы обойдутся с ним соответственно.

Что предложить взамен

Вариант Когда подходит Цена и хлопоты Оценка
Использовать почту, которая у них уже есть Почти наверняка этот случай: раз есть интернет-магазин, есть и корпоративная почта на своём домене. Приложение отправляет через их SMTP как обычный почтовый клиент Ноль. Настройка — полчаса начать отсюда
Сервис транзакционной отправки Если писем много или своя почта плохо доходит. Письма уходят с домена заказчика, а доставляемость и репутация — забота сервиса На их объёмах бесплатно или символически. Аккаунт оформляется на заказчика если понадобится
Свой почтовый сервер у заказчика Только если есть требование держать переписку внутри периметра Постоянная работа: репутация IP, чёрные списки, PTR-запись, антиспам, обновления, резервирование на 12 человек не окупается
Принцип, который стоит держаться

Почта оформляется на заказчика: его домен, его учётная запись, его оплата. Настройка выполняется исполнителем и входит в состав работ. Проверка простая: если завтра исполнителя не станет в проекте, у заказчика ничего не должно сломаться. Инфраструктура, привязанная к конкретному подрядчику, — это риск для обеих сторон.

И отдельно: отправка и приём — разные задачи. Складу почти наверняка нужна только отправка. Если же программа должна ещё и разбирать входящие письма — заказы от клиентов, прайсы поставщиков, — это совсем другой объём работы, и его нужно оценивать отдельно.

Домен

Первый вопрос — не «какой зарегистрировать», а какой у них уже есть. Раз работает интернет-магазин, домен почти наверняка существует, и почту нужно поднимать на нём: единый домен для магазина, сайта и писем — это узнаваемость, а два разных домена у одной фирмы только путают клиентов. Регистрировать новый есть смысл, только если магазин стоит на чужой площадке или конструкторе с их доменом.

detalsklad.ru

Прямо называет дело: детали и склад. Транслитерируется однозначно, по телефону диктуется без «а как это пишется». Рабочий вариант по умолчанию.

avtoresurs.ru

Солиднее и шире по смыслу — подойдёт, если фирма оптовая и планирует расти за пределы одной товарной группы.

partsklad.ru

Короче и современнее, но смешивает английское parts с русским складом — часть клиентов прочтёт как «партсклад». Годится, если аудитория помоложе.

Занятость всех трёх нужно проверять у регистратора — вероятность, что короткое имя в зоне .ru свободно, невелика. Если все заняты, работает приём «слово плюс город»: detalsklad-nsk.ru. Дефис в почтовом адресе неудобен, но лучше дефиса только своё короткое имя.

Домен регистрируется на заказчика — это не формальность

Владельцем и администратором в реквизитах указывается фирма-заказчик. Исполнителю достаточно технического доступа к DNS — этого хватает для любой настройки. Домен, оформленный на подрядчика, рано или поздно становится предметом спора, и спор этот некрасив для обеих сторон независимо от того, кто прав.

Сразу включите автопродление. Домен, потерянный из-за неоплаченного счёта, уводит вместе с собой и почту, и магазин, а выкупать его обратно приходится уже у перекупщиков.

Что настроить в DNS, чтобы письма доходили

Три записи обязательны, иначе почтовые службы отправят письма в спам независимо от их содержания: SPF — перечень серверов, которым разрешено слать от имени домена; DKIM — подпись, подтверждающая, что письмо не подменили; DMARC — правило, что делать с письмами, не прошедшими первые две проверки. Если почта поднимается на своём сервере, добавляется PTR — обратная запись для IP, её настраивает хостер.

При отправке через существующую почту заказчика или через сервис рассылки всё это либо уже настроено, либо делается по их инструкции за полчаса. Это ещё один довод не поднимать почтовый сервер с нуля.

Критерий выбора

Простота, надёжность, быстродействие

Заказчик назвал три принципа, и они не украшение — это готовый критерий, по которому отбрасывается лишнее. Прогон стека через них убрал из первого варианта четыре компонента, включая один язык программирования.

Простота

Считается не строчками кода, а числом того, что может сломаться и что нужно уметь чинить. Один язык, один сервер, минимум служб. И проверка на человеке: сможет ли посторонний специалист разобраться в системе без вас — от этого зависит, не станет ли заказчик заложником.

Надёжность

Не «не падает», а предсказуемо восстанавливается. Проверенные копии, откат за минуту, понятные журналы, оповещение о сбое. Чем меньше движущихся частей, тем меньше способов сломаться — поэтому надёжность здесь прямо следует из простоты, а не спорит с ней.

Быстродействие

Для кладовщика это не время ответа сервера, а число нажатий на приёмку одной позиции. Delphi-программы в этом сильны, и веб проигрывает им не скоростью сети, а лишними кликами. Требование: работа с клавиатуры, без мыши, с горячими клавишами — как привыкли.

Что принципы вычеркнули из первого варианта

Второй язык. В первом варианте синхронизация с InterBase была отдельной службой на Node — ради драйвера, не требующего клиентских библиотек. Выигрыш реальный, но небольшой, а плата — второй язык, вторая среда, вторые зависимости и вдвое больше того, в чём придётся разбираться постороннему специалисту. Против принципа простоты это не проходит: остаётся один PHP.

Docker. Для одного приложения на одной машине контейнеры добавляют слой между вами и проблемой. Всё ставится из репозиториев Debian и управляется systemd — так проще диагностировать и так сможет разобраться любой линуксовый администратор.

Отдельный сервер очередей. На двенадцать человек очереди прекрасно живут в PostgreSQL. Это минус одна служба, которая могла упасть.

Центр сертификации как служба. Вместо него — самоподписанный корневой сертификат, выпущенный один раз на десять лет и один раз установленный на рабочие места.

Стек

На чём переписывать

Одна машина под Debian 13, PostgreSQL на ней же — как вы и предложили. Всё ставится нативно из репозиториев и управляется systemd, без контейнеров: меньше слоёв между администратором и неисправностью. Обновление системы — git pull, установка зависимостей и миграции; откат — возврат на предыдущую версию в git.

Слой Выбор Почему именно так Статус
ОС сервера Debian 13 «trixie» Поддержка до 2030, свежие PHP 8.4 и PostgreSQL 17 прямо в базовых репозиториях, минимум лишнего. решено
База PostgreSQL 17 (PGDG) 20 000 позиций — мелочь, но кроссы и аналоги дают миллионы связей. pg_trgm закрывает поиск по артикулу с опечатками и по части номера — главный сценарий в автозапчастях. решено
Основной бэкенд PHP 8.4 + Laravel 12 Складской учёт — это документы, справочники, права и печатные формы. Laravel даёт очереди, миграции, авторизацию и админку из коробки. Один язык на весь проект — прямое следствие принципа простоты. решено
Синхронизация с InterBase Команда Laravel + pdo_firebird Не отдельная служба, а обычная задача по расписанию внутри того же приложения. Опрос раз в минуту вместо мгновенных событий — для зеркала этого достаточно, зато нет второй среды выполнения. Клиентская библиотека ставится из репозитория Debian одной строкой. решено
Фронтенд Blade + htmx 1.9 Страницы собираются на сервере. Никакого React и Vue: на XP они либо не запустятся, либо потребуют горы полифилов. htmx 1.x собран под IE11 — на XP-браузерах работает гарантированно. рекомендация
Веб-сервер Nginx + самоподписанный сертификат Let's Encrypt на XP не заработает (об этом ниже). Корневой сертификат выпускается openssl один раз на десять лет и один раз ставится в Firefox на рабочих местах. Отдельный центр сертификации как служба здесь — лишняя движущаяся часть. решено
Очереди Таблица в PostgreSQL Фоновая печать этикеток и выгрузки. На двенадцати пользователях отдельный сервер очередей не нужен — это минус одна служба, которая могла бы упасть. Redis добавим, если объёмы вырастут. решено
Терминалы склада ТСД на Android 10+ Тот же веб-интерфейс в Chrome, отдельная «крупнокнопочная» вёрстка. Сканер работает как клавиатура — писать нативное приложение не нужно. рекомендация
Печать этикеток ZPL прямо в принтер, TCP 9100 Сервер отправляет готовый ZPL на сетевой принтер. Драйверы печати под XP не нужны вообще — а это один из главных источников ежедневной боли. рекомендация
Резервные копии pgBackRest + restic PostgreSQL — база плюс журнал транзакций, восстановление на любой момент. InterBase — ночной gbak. Копии уезжают на второй носитель и наружу. обязательно
Удалённый доступ WireGuard на MikroTik Взамен любых пробросов портов. RouterOS 7 умеет его штатно. обязательно
Наблюдение Скрипт по расписанию → Telegram Проверяются три вещи: прошла ли ночная копия, сколько осталось места, отвечает ли сайт. Молчание означает, что всё в порядке. Zabbix и панели мониторинга на 25 устройств — избыточны. решено
Развёртывание systemd, без контейнеров PHP-FPM, Nginx и PostgreSQL — обычные службы Debian. Обновление: git pull и миграции, откат — возврат к предыдущей версии. Разобраться сможет любой линуксовый администратор, не только автор. решено
Где на самом деле берётся быстродействие

Не в выборе языка. Двадцать тысяч позиций — крошечный объём: PostgreSQL отвечает на такие запросы за миллисекунды на любом стеке. Скорость системы решают три другие вещи.

Индексы под поиск по артикулу. Главный запрос на складе — найти деталь по куску номера, с опечаткой, с чужим написанием. Расширение pg_trgm с индексом GIN отвечает на такое мгновенно; без него тот же запрос перебирает таблицу целиком. Разница — сотни раз, и она важнее всего остального в этом документе про скорость.

Отсутствие лишнего на странице. Страницы собираются на сервере и приходят готовыми. Списки — постранично: двадцать тысяч строк не выгружаются в браузер никогда, тем более на XP.

Число нажатий. Приёмка позиции должна занимать столько же действий, сколько в Delphi, или меньше. Фокус сам встаёт в поле ввода, сканирование сразу добавляет строку, сохранение — с клавиатуры. Если новая система окажется медленнее в руках кладовщика, все технические достоинства не будут стоить ничего — и именно на этом такие проекты чаще всего и проваливаются.

Рабочие места

Все остаются на XP и работают в браузере

Это и есть план. Новая система — внутренний веб-сайт: сотрудник открывает браузер, вводит логин и работает. Ничего устанавливать на рабочие места не нужно, парк менять сейчас не нужно, и именно поэтому фронтенд собирается на сервере, а не на React.

Обновление одно на всех

Новая версия выкладывается на сервер — и она у всех. Сегодня обновить Delphi-клиент значит обойти двенадцать машин; отсюда же берутся ситуации, когда у половины сотрудников версия разная.

На клиенте не нужно ничего

Ни библиотек InterBase, ни драйверов печати, ни настройки соединения с базой. Браузер и сетевой кабель — всё. Новое рабочее место заводится за пять минут.

Слабое железо перестаёт мешать

Страницы собираются на сервере, браузеру достаётся готовый HTML. Машине с гигабайтом памяти этого достаточно — при условии, что мы не пишем одностраничное приложение и не грузим 20 000 строк в одну таблицу.

Сканер работает сам собой

USB-сканер отдаёт штрихкод как набранный текст. Он работает в браузере ровно так же, как в Delphi, — переучивать кладовщика не придётся.

Печать уходит на сервер

Этикетки печатает сервер напрямую в сетевой принтер, минуя браузер и драйверы XP. Кривые печатные формы и «а у меня не печатает» как класс исчезают.

Чего это не решает

Браузер не чинит саму XP: без обновлений, без антивируса и с SMBv1 машина остаётся уязвимой. Поэтому веб-доступ работает только в связке с выносом XP в сегмент без интернета.

Два места, где план на XP всё же упирается в стену

Бухгалтерия. Банк-клиент, 1С и ЭДО веб-страницами не станут и XP уже не поддерживают. Эти одну-две машины придётся обновить отдельно и раньше остальных — независимо от нашего проекта.

Железо. Машины продолжат выходить из строя, и купить замену под XP негде. Правильная политика: сломавшуюся машину заменяем на новую с современной системой, а не ищем ещё один такой же системный блок. Через два-три года парк обновится сам, без разговора о единовременной закупке.

Технические рамки, которые из этого следуют

XP определяет не «дизайн посовременнее», а список технологий, которые просто не запустятся. Хорошая новость: если зафиксировать один браузер, ограничения оказываются мягче, чем кажется.

Браузер на XP TLS Что умеет Вывод
Firefox 52.9 ESR TLS 1.2 ES6, fetch, Promise, CSS-переменные, flexbox, grid. Своё хранилище сертификатов — корневой CA ставится в профиль. целевой браузер
Chrome 49 TLS 1.2 ES6 частично, CSS grid нет. Берёт корневые сертификаты из хранилища Windows — а там нет ни одного современного корня. запасной
Internet Explorer 8 TLS 1.0 Практически ничего из современного. исключить
Практический вывод

Ставим на все рабочие места Firefox 52.9 ESR и целимся в него одного. Тогда: собирать JS под ES2015 без модулей — одним файлом-бандлом; CSS-переменные и flexbox можно; полифилов почти не нужно. Сертификат берём от своего внутреннего CA и ставим корень в профиль Firefox — Let's Encrypt здесь бесполезен, потому что кросс-подпись, которой доверяли старые системы, истекла в 2021 году.

Что делать с самими машинами

Изолировать и оставить

XP живёт в VLAN 20 и 30 без интернета, единственный браузер — Firefox ESR. Стоит ноль. Пока работает Delphi-клиент, это единственный реалистичный вариант.

на время миграции

Превратить в тонкие клиенты

То же железо, но грузится лёгкий Debian с современным браузером. Актуальный TLS, обновления безопасности, ноль затрат на технику. Возможно только после того, как Delphi-клиент перестанет быть нужен.

после фазы 4

Обновить парк

Правильно, но это деньги заказчика и отдельный разговор. Заводить его стоит не «потому что XP старый», а под конкретную дату отключения Delphi-клиента.

решение заказчика

Интеграция

Как данные попадают в PostgreSQL

Это самая техничная часть проекта и главный источник скрытых сроков. Ошибка здесь обнаруживается не сразу, а через месяц — когда кто-то замечает, что остаток по позиции разошёлся на три штуки. Поэтому перенос строится так, чтобы его можно было запускать сколько угодно раз и каждый раз проверять результат.

Два слоя вместо одного

Слой 1

Схема raw — сырьё как есть

Точная копия таблиц InterBase, поле в поле, без единого улучшения. Сюда данные просто перекладываются. Задача этого слоя одна: получить содержимое старой базы внутри PostgreSQL, чтобы дальше работать привычными запросами, а не через мост.

Слой 2

Рабочая модель — как должно быть

Нормальная схема, спроектированная под задачу, наполняется преобразованием из raw. Здесь разбираются текстовые флаги, склеиваются дубли, наводится порядок в справочниках.

Зачем разделять, если можно перелить сразу

Разделение превращает одну необратимую операцию в две повторяемые. Перекладывание проверяется на совпадение количества строк, преобразование — на бизнес-правила, и каждое можно переделать, не трогая другое. При одном слое любая найденная ошибка означает повторный перенос всего с самого начала.

И второе. Схема старой базы несёт двадцать лет заплаток: поля-заглушки, флаги буквами, следы давно отменённых решений. Копировать её в новую систему — значит унаследовать всё это навсегда: обещание «перенесём как есть, а отрефакторим потом» не выполняется никогда. Слой raw позволяет опереться на старую структуру, не пуская её в новую систему.

Ловушки при переносе типов

InterBase PostgreSQL В чём подвох
VARCHAR(n)
CHARACTER SET WIN1251
text Перекодировка в UTF-8. Если у базы кодировка NONE, сервер отдаёт байты как есть — придётся распознавать кодировку самостоятельно и сверять результат глазами на выборке
DATE date или timestamp зависит от диалекта В первом диалекте DATE хранит ещё и время. Перенести его в date — молча потерять часы и минуты у всех документов
NUMERIC(15,2) numeric(15,2) Переносится верно. Но если суммы хранили в DOUBLE PRECISION, там уже накоплена погрешность округления — переносить нужно, зная об этом, и сверять итоги с отчётами старой системы
CHAR(1) 'Y' / 'N'
SMALLINT 0 / 1
boolean Почти всегда это логические поля. Проверить каждое: среди них попадаются трёхзначные, где третье состояние значимо, а NULL означает не то же самое, что «нет»
BLOB SUB_TYPE 1
BLOB SUB_TYPE 0
text
bytea
Текстовые блобы — те же вопросы с кодировкой. Двоичные — это картинки и вложения; их объём стоит оценить заранее, он может оказаться больше самой базы
GENERATOR sequence Последовательность выставляется на текущее значение генератора плюс запас. Забыть про это — получить конфликт ключей в первый же день записи
Триггеры и процедуры Код приложения Не переносятся, а прочитываются: в них записана часть бизнес-правил, и это самый достоверный их источник. Реализуются заново в Laravel

Как ловить изменения

Первая полная загрузка — простая часть. Сложность в том, чтобы дальше подхватывать изменения, пока в InterBase продолжают работать. Способы, по убыванию предпочтительности:

СПОСОБ 1

По собственному полю таблицы. Если есть дата изменения или растущий идентификатор из генератора — забираем всё, что больше запомненного значения. Ничего в боевой базе менять не нужно, риск нулевой. Проверить наличие таких полей — первое, что делается по схеме.

не трогаем чужую базу вообще

СПОСОБ 2

Триггеры в отдельный журнал. На нужные таблицы вешаются триггеры, пишущие в новую таблицу-журнал: что за таблица, какая запись, какая операция, когда. Синхронизация читает журнал и вычищает обработанное.

Ключевое различие в рисках: новые таблицы и триггеры Delphi-клиент не видит и не замечает — они безопасны. Опасно другое: добавлять поля в существующие таблицы. Программы того времени часто обращаются к полям по номеру, а не по имени, и лишняя колонка ломает форму. Этого не делаем.

сначала на копии, затем на боевой в нерабочее время, с готовым откатом

СПОСОБ 3

Полная сверка по расписанию. Для небольших справочников — просто перечитывать целиком раз в ночь. Двадцать тысяч позиций читаются за секунды, и никакой механики отслеживания не нужно вовсе. Самый простой способ там, где он проходит по объёму.

для справочников — предпочтительнее двух предыдущих

Сверка — то, что превращает перенос в доверие

Каждую ночь считаются и сравниваются: число строк по каждой таблице, суммы остатков по складу, итоги документов за период. Расхождение приходит письмом с указанием таблицы и записи. Пока цифры сходятся неделями подряд, разговор о переключении вообще возможен; без такой сверки любое расхождение всплывёт в самый неудобный момент и обнулит доверие ко всей новой системе.

Отсюда же берётся дата переключения: не «когда всё написано», а когда сверка не показывает расхождений заданное время подряд.

Обратная запись — самая опасная часть, и начинать её нужно с малого

С третьей фазы новая система пишет результат обратно в InterBase, чтобы Delphi видел согласованную картину. Здесь два правила. Идентификаторы берутся только у генераторов InterBase — присвоить их самостоятельно значит рано или поздно столкнуться с чужой записью. Вставка идёт теми же путями, что у Delphi, чтобы отработали существующие триггеры и проверки: обойти их — получить данные, которые старая программа считает испорченными.

Поэтому первым для записи выбирается замкнутый участок вроде приёмки: у него понятные границы, немедленная польза кладовщику и обозримые последствия, если что-то пойдёт не так.

Переход

Как заменить программу, не останавливая склад

Переписать всё и переключиться в одну ночь — верный способ остановить отгрузки. Вместо этого новая система сначала только читает данные рядом со старой, а потом по одному забирает участки работы себе, пока от старой не останется ничего.

СТАРАЯ СИСТЕМА — УБЫВАЕТ НОВАЯ СИСТЕМА — РАСТЁТ Клиенты Delphi 7 рабочие места на XP ФАЗЫ 0–4, ДАЛЬШЕ ОТКЛЮЧАЮТСЯ InterBase боевая база .gdb источник истины до фазы 3 TCP 3050 ПРЯМОЙ ДОСТУП Синхронизация команда Laravel · pdo_firebird опрос изменений раз в минуту внутри основного приложения сверка расхождений УДАЛЯЕТСЯ ПОСЛЕ ФАЗЫ 6 PostgreSQL 17 Debian 13 фазы 1–2: зеркало только для чтения фаза 3+: источник истины PG_TRGM · ПОИСК ПО АРТИКУЛАМ ПЕРЕНОС ФАЗА 3+: ОБРАТНАЯ ЗАПИСЬ Laravel 12 PHP 8.4 · Blade · htmx каталог и остатки приёмка и отгрузка заказы, отчёты, права HTTPS · СВОЙ ЦЕНТР СЕРТИФИКАЦИИ Firefox ESR на XP ТСД на Android позже — интернет-магазин Ключевое свойство схемы До фазы 3 новая система ничего не пишет в InterBase. Если она сломается — склад продолжает работать в Delphi, как будто ничего не произошло.
Слева направо — направление, в котором с каждой фазой смещается источник истины. Обратная стрелка появляется только на фазе 3, когда первый модуль начинает писать данные.

Фазы

ФАЗА 0

Обследование и резервная копия. Снять gbak с боевой базы и увезти копию к себе. Определить версию InterBase, ODS, кодировку, объём. Выгрузить схему: таблицы, индексы, триггеры, хранимые процедуры. Пересчитать машины, порты и пробросы. До этого момента ничего на объекте не менять.

Итог: копия базы поднята локально, схема выписана, список неизвестного закрыт

ФАЗА 1

Инфраструктура. Сервер на Debian 13, VLAN и правила экрана, WireGuard вместо пробросов, ночной gbak InterBase на Linux с проверкой восстановления. Порядок важен: резервные копии старой базы делаются до любых работ по сети.

Итог: сеть сегментирована, копии снимаются и проверяются, доступ снаружи закрыт

ФАЗА 2

Зеркало для чтения. служба синхронизации переносит данные в PostgreSQL. Веб даёт поиск по артикулам и кроссам, остатки, отчёты директору. Риск для склада нулевой: запись по-прежнему только через Delphi. Здесь же выясняется настоящее качество данных — дубли, битая кириллица, склад «в никуда».

Итог: первые пользователи в новой системе, доверие заработано на чтении

ФАЗА 3

Первый модуль с записью. Обычно это приёмка или инвентаризация на ТСД: замкнутый процесс, понятный результат, немедленная польза кладовщику. С этого места по выбранному участку источник истины — PostgreSQL, а синхронизация возвращает результат в InterBase, чтобы Delphi продолжал видеть согласованную картину.

Итог: двусторонняя синхронизация обкатана на одном безопасном участке

ФАЗА 4

Менеджерский контур. Заказы, резервы, цены, клиенты, отгрузка. Самая объёмная фаза и самая спорная по требованиям: именно здесь всплывают правила, которых нет ни в одной документации — только в головах менеджеров.

Итог: менеджеры работают в вебе, Delphi остаётся у бухгалтерии

ФАЗА 5

Бухгалтерия и обмен. Документы, взаиморасчёты, выгрузка в 1С. Плюс подключение интернет-магазина к новому API — до сих пор он, скорее всего, ходил в базу своим отдельным способом.

Итог: у обмена данными один источник вместо нескольких

ФАЗА 6

Отключение. Delphi-клиент снимается с рабочих мест, InterBase переводится в архив и хранится в копиях, код синхронизации удаляется. Только теперь имеет смысл разговор о замене или переводе XP-машин на тонкие клиенты.

Итог: одна система, один сервер, один язык интеграции

Риски

Где это может пойти не так

Риск Чем грозит Что делать
InterBase 7 и новее Копию базы не поднять свободным Firebird — вся схема чтения усложняется Проверить ODS в фазе 0. Запасной путь — оставить чтение на Windows-машине через мост ODBC
Кодировка базы NONE Кириллица переносится мусором, и обнаруживается это в самый неподходящий момент Определить фактическую кодировку по данным, перекодировать побайтово при переносе, сверить на выборке
Нет исходников Delphi Часть правил не восстановить чтением базы Разбирать по данным и опросам. Заложить время на это в фазе 4 — там оно и понадобится
Триггеры на боевой базе Delphi-приложения нередко ломаются от изменения схемы: они рассчитывают на точный состав и порядок полей Все триггеры — сначала на копии, потом на боевой, и только новые таблицы. Существующие не трогать
Один сервер Отказ железа останавливает и склад, и магазин Диски в зеркале, ИБП, проверенное восстановление из копии. Отдельно обсудить второй сервер про запас
Лицензии InterBase Возможен неприятный сюрприз при разговоре о легальности Выяснить в фазе 0. На результат проекта не влияет — это довод в пользу перехода
Качество данных 20 000 позиций за годы работы — это дубли, кроссы «в никуда», отрицательные остатки Чистка идёт в фазе 2, на зеркале, где ничего не сломается. Правила чистки утверждает заказчик
Обследование

Что забрать у заказчика, чтобы начать

Заказчик предложил выделить отдельный компьютер с XP и рабочей программой. Предложение правильное по сути, но избыточное по форме: нужна не машина, а её содержимое. И одних скриншотов при этом не хватит — они показывают, из чего состоят формы, но не показывают, что программа делает.

Что просить Зачем именно это Важность
Копия базы через gbak
боевая, не урезанная
Даёт схему, данные, хранимые процедуры, триггеры, реальные объёмы и настоящее качество данных. Это примерно две трети всей нужной информации. Урезанная выборка скроет ровно те аномалии, ради которых обследование и затевается. без этого нельзя
Программа в виртуальной машине
образ диска или комплект установки
Показывает поведение, которого в базе нет: что подставляется само, что проверяется, что происходит при нехватке товара, как ищутся аналоги. XP отлично живёт в VirtualBox на Linux — отдельное железо держать не нужно. почти обязательно
Запись экрана, 20–30 минут
кладовщик и менеджер, вслух
Приёмка от начала до конца и оформление заказа — с комментариями, что и почему нажимают. Одна такая запись полезнее сотни скриншотов: видно порядок действий, горячие клавиши и скорость работы. очень желательно
Печатные формы в PDF
или живые распечатки
Их потребуют воспроизвести один в один. Нужны точные поля, размеры, шрифты и расположение — по скриншоту это не восстановить, особенно для этикеток и накладных. очень желательно
Скриншоты форм Полезны как дополнение и как оглавление. Но пять экранов — это оценка снаружи: за каждой формой стоят справочники, фильтры, окна подбора и сообщения об ошибках, и в реальности состояний окажется в разы больше. дополнение
Исходники Delphi Если сохранились — снимают половину вопросов по бизнес-правилам. Если нет, ничего страшного: правила восстанавливаются по базе и по записи экрана, просто дольше. если есть
Почему виртуальная машина, а не переданный компьютер

Она снимает возражение «потом это будет не нужно»: виртуалка удаляется одной командой, а железо надо где-то держать и потом возвращать. Она запускается на вашем Linux в любой момент, её можно откатить к исходному состоянию после любого эксперимента и скопировать столько раз, сколько нужно. Физическая машина понадобится только в одном случае: если программа привязана к аппаратному ключу или конкретному железу — это стоит проверить сразу.

И одна поправка к формулировке «потом не нужна»: старая программа нужна до самого конца миграции. На фазах 2–5 по ней сверяются цифры — остаток по позиции в Delphi против того же остатка в новом отчёте. Без запущенного эталона каждый спор «раньше считалось иначе» выигрывает заказчик.

Ответственность за данные

В копии базы — персональные данные клиентов и вся коммерческая история. Условия обращения с ней: хранение в виртуальной машине без выхода в сеть, на шифрованном диске, удаление по окончании работ. Это фиксируется письменно до передачи копии, а не после.

Подготовка

Что нужно выяснить до покупки сервера

Три вопроса из этого списка способны изменить план работ и смету, поэтому задать их следует раньше остальных. Прочее — организация, но без неё установка встанет на полдня из-за отсутствующего монитора.

Определяют, выполним ли план в нынешнем виде

Внешний адрес — белый или серый

Если провайдер выдаёт адрес за своим общим шлюзом, входящее VPN-подключение к сети поднять невозможно в принципе. Тогда либо белый адрес за доплату провайдеру, либо весь удалённый доступ строится на исходящих соединениях от сервера.

Проверяется за минуту: сравнить адрес в настройках роутера с тем, что показывает любой сайт определения адреса. Совпадают — белый.

Коммутаторы — управляемые или нет

Разделение сети на сегменты требует управляемых коммутаторов. Если стоят простые, разделение либо не сделать вовсе, либо оно упирается в замену оборудования — а это отдельная статья расходов, которую лучше обнаружить сейчас, а не в середине работ.

Версия системы на роутере

Встроенный VPN появился только в седьмой версии RouterOS. На шестой понадобится либо обновление, либо другой способ подключения. Заодно — есть ли вообще пароль от роутера и у кого он.

Место, питание, сеть

Где физически встанет машинаНе в проходе склада и не там, где пыль и перепады температуры. Помещение, куда не заходят посторонние.
Розетка и источник бесперебойного питанияЕсть ли свободное место в имеющемся ИБП или нужен свой. Внезапное отключение питания — самый частый способ повредить базу.
Свободный порт коммутатора рядомИ проложен ли кабель до выбранного места. Мелочь, из-за которой установка нередко откладывается на неделю.
Монитор и клавиатура на время установкиНужны один раз, на полчаса. Их отсутствие обнаруживается ровно в тот момент, когда человек уже приехал ставить систему.
Скорость интернет-каналаОсобенно исходящая: по ней уходят резервные копии и идёт удалённая работа.

Оборудование и установка

Кто покупает машинуЗаказчик сам, его поставщик или подбор берёт на себя исполнитель. Характеристики — в разделе о том, что покупать.
Кто ставит операционную системуДостаточно одного человека на объекте, готового загрузиться с флешки и дойти до конца установщика по письменной инструкции.
Когда можно делать работы, задевающие сетьПереключение на сегменты кратковременно прерывает связь. Склад работает днём — значит вечер или выходной, и это нужно согласовать заранее.
Кто на связи при аварииИмя и телефон конкретного человека, который может подойти к серверу. Выяснять это в момент аварии поздно.
Есть ли требования к доступуВнутренние правила по удалённому подключению подрядчиков, если они установлены.
Обследование

Что спросить у заказчика

Первые пять пунктов закрывают почти всю неопределённость этого документа. Остальное можно выяснять по ходу.

Версия InterBase и ODSВывод gstat -h по базе. Определяет, читается ли копия свободным Firebird.
Кодировка и размер базыКодировка по умолчанию, объём файла .gdb, число таблиц и хранимых процедур.
Диалект базы — первый или третийОт него зависит, хранит ли DATE ещё и время. Ошибиться здесь — молча потерять часы у всех документов при переносе.
Есть ли в таблицах дата измененияИли растущий идентификатор. Если есть — изменения ловятся без единой правки в боевой базе.
Объём двоичных данныхКартинки и вложения в BLOB. Иногда они занимают больше, чем сама база, и меняют требования к диску.
Исходники DelphiЕсть ли они, кто автор, доступен ли он для вопросов.
Точный список рабочих местСколько машин, у кого какая роль, что за железо и сколько памяти.
Модель MikroTik и версия RouterOSОт неё зависит, есть ли WireGuard и как настраивать VLAN.
Проброшенные наружу портыОсобенно 3389 и 3050. Проверить в первый же визит.
Чем именно снимается копияКлючевой вопрос: gbak или простое копирование файла .gdb. Посмотреть сам скрипт или задание в планировщике.
Восстанавливали ли из копии хоть разЕсли нет — развернуть её в отдельную базу в первый же выезд. Это проверка, которая либо снимает тревогу, либо меняет приоритеты всего проекта.
Внешний диск: где и как подключёнПостоянно на USB или подключается вручную. Сколько копий хранится и сколько на нём места.
Связь с интернет-магазиномКак он получает остатки и цены сегодня: выгрузкой, прямым доступом в базу, вручную.
Через что программа шлёт письма сейчасРаз уведомления уже работают, где-то прописан SMTP. Найти его — и вопрос с почтой закрыт сам собой.
Есть ли корпоративная почта на своём доменеИ где она обслуживается. Скорее всего есть — тогда ничего нового заводить не нужно.
Какие уведомления и комуКлиентам наружу или только сотрудникам внутрь. И нужно ли программе читать входящие письма — это отдельная по объёму задача.
Есть ли 1С и какой обменЧто бухгалтерия делает руками, а что выгружается.
Сканеры и печать этикетокМодели сканеров, печатается ли что-то на этикетках сейчас.
Домен Active DirectoryИли все машины сами по себе. На 12 человек домен не нужен, но знать надо.
Кто на стороне заказчика принимает решенияИ кто из кладовщиков и менеджеров готов разбирать с вами рабочие процессы.
Статус

Это техническое предложение, а не техническое задание

Различие не формальное. Предложение отвечает на вопрос «как будет устроено» и пишется исполнителем. Задание отвечает на вопрос «что система должна делать», пишется от лица заказчика и подписывается им. По этому документу нельзя ни принять работу, ни назвать её стоимость: в нём нет ни одного проверяемого требования к тому, как работает приёмка или как считается резерв.

Документ Отвечает на вопрос Когда Состояние
Техническое предложение
этот документ
Как будет устроено решение: сеть, стек, порядок перехода, риски. Что нужно узнать и купить До обследования, на допущениях на согласовании
Отчёт об обследовании Что есть на самом деле: версия и диалект базы, схема, качество данных, реальная топология, как работают люди Фаза 0, по копии базы и записи экрана впереди
Техническое задание Что система обязана делать: процессы, роли и права, печатные формы, отчёты, измеримые требования к скорости, критерии приёмки, границы работ По итогам обследования, подписывается заказчиком впереди
Что требуется от заказчика на этом шаге

Прочитать раздел с исходными данными и поправить допущения, ответить на вопросы из последнего раздела и передать копию базы. После этого предложение превращается в отчёт об обследовании с точными цифрами, а из него — в техническое задание со сроками и стоимостью.