Когда я начал делать систему для логистов, первое что меня удивило — это где у них хранятся цены. Я думал — в личных кабинетах транспортных компаний, в API, в каком-то отраслевом маркетплейсе. Нет. Цены хранятся в почте.
Каждую неделю менеджеру падает 25-30 писем от транспортных компаний. Внутри — самая дикая помесь форматов, которую я видел в работе.
Бывает аккуратное письмо с Excel-вложением, где таблица идеально структурирована. Бывает то же письмо, но таблица сразу в теле — без вложения, прямо HTML. Бывают PDF-прайсы на пять страниц с водяными знаками. Бывают просто три строки текста: «маршрут Шанхай-СПб, $4200, срок 35-40 дней». А бывает самое весёлое — письмо-уведомление: «мы пересчитали ставку по Юго-Восточной Азии, теперь плюс 200 долларов с понедельника». Никакой таблицы, никаких приложений — просто фраза в теле, по которой нужно обновить уже существующую запись в базе.
Менеджер раньше открывал каждое такое письмо, переписывал цифры в свой Excel. На это уходил весь понедельник. К среде Excel уже неактуален, потому что прилетели новые письма.
Я сделал так. Бот логинится в IMAP, забирает свежие письма, и дальше через каскад. Сначала смотрит вложения: Excel — через pandas с эвристиками по структуре, PDF — через табличный OCR. Если вложений нет — парсится тело письма: HTML-таблица отдельно, простой текст с цифрами — через регулярки, а если не справились — отдаём LLM с просьбой «выдай мне маршрут, ставку и валюту». Каждая ставка падает в базу с пометкой «из такого-то письма».
И вот тут оказалось самое интересное. Я изначально думал что все письма — это «вот наш полный прайс». Оказалось, существенная часть писем — это изменения. То есть парсер должен не создать новую запись, а найти старую и обновить её. Я это сначала пропустил. Получилась смешная картина: после каждого письма-уведомления в базе появлялась дублирующая ставка с другой ценой, и менеджер не понимал какая из двух актуальная.
Переписывать пришлось не парсер. Пришлось переписывать модель данных — добавлять историю изменений, делать так чтобы ставка не была «строкой в таблице», а была сущностью с версиями. Это уже не интеграция, это нормальный продукт.
Логистика — это вообще не «возим контейнеры». Логистика — это бесконечный поток мелких изменений в условиях, и кто быстрее всех видит свежие цифры, тот и зарабатывает. Я раньше этого не понимал.