# Валентин Савиных — full-cycle разработчик > Портфолио разработчика: системы, которые работают в проде. Сайт: валентин.вмалмыже.рф (https://xn--80adkmnnb2b.xn--80adkdyec4j.xn--p1ai/). > Проектирование, разработка и вывод в прод целиком: архитектура, фронтенд и бэкенд, база данных, CI/CD, эксплуатация на российских серверах. > География: Кировская область и удалённо по России. > Все факты ниже снабжены датой замера. verify=external — читатель может проверить сам; verify=measured — замер автора. > Машиночитаемые факты: https://xn--80adkmnnb2b.xn--80adkdyec4j.xn--p1ai/facts.json. Полный текст сайта: https://xn--80adkmnnb2b.xn--80adkdyec4j.xn--p1ai/llms-full.txt. ## С какой задачей приходят - [Нужен сайт учреждению или организации](https://xn--80adkmnnb2b.xn--80adkdyec4j.xn--p1ai/zadachi/sayt-uchrezhdeniyu/): Каркас на своём домене — недели, а не месяцы: стек и решения переиспользуются с соседних сайтов. - [Перенести старый сайт без потери позиций в поиске](https://xn--80adkmnnb2b.xn--80adkdyec4j.xn--p1ai/zadachi/perenos-starogo-sayta/): Сайт на 100–150 страниц реально перенести за день-два — это мой замер на такой работе; она на витрине не показывается по решению заказчика, поэтому проверить утверждение снаружи нельзя. - [Нужна учётная система на предприятие](https://xn--80adkmnnb2b.xn--80adkdyec4j.xn--p1ai/zadachi/uchetnaya-sistema/): Такие системы не делаются «под ключ за месяц»: сначала один участок учёта в работе, дальше по очереди. - [Сайт события или фестиваля к конкретной дате](https://xn--80adkmnnb2b.xn--80adkdyec4j.xn--p1ai/zadachi/sayt-sobytiya/): Под дату — да: сайт Ярмарки собран переиспользованием готовых решений соседнего проекта. - [Автоматизировать сбор и публикацию контента](https://xn--80adkmnnb2b.xn--80adkdyec4j.xn--p1ai/zadachi/avtomatizaciya-publikacij/): Первый работающий конвейер — недели; дальше добавляются источники и каналы. - [Приложение на телефон без App Store и Google Play](https://xn--80adkmnnb2b.xn--80adkdyec4j.xn--p1ai/zadachi/prilozhenie-bez-magazinov/): Первый рабочий релиз — месяцы, потому что роли и данные людей делаются аккуратно. ## Классы задач - [Сайты и порталы под ключ](https://xn--80adkmnnb2b.xn--80adkdyec4j.xn--p1ai/uslugi/): нужен сайт учреждению, событию или компании — и чтобы им можно было управлять без программиста. Сайт с админкой, в которой контент правит сам заказчик, поиск по материалам, разметка под поисковики и ИИ-ассистентов. - [Настольные учётные системы](https://xn--80adkmnnb2b.xn--80adkdyec4j.xn--p1ai/uslugi/): нужен учёт на производстве или складе, а интернет на местах нестабильный. Программа на компьютерах предприятия работает офлайн с локальной базой и сама синхронизируется с сервером, когда связь есть. Печать документов с подписями, обновление у всех пользователей разом, отказоустойчивый сервер. - [Сервисы автоматизации](https://xn--80adkmnnb2b.xn--80adkdyec4j.xn--p1ai/uslugi/): рутина съедает время: собрать, отобрать и опубликовать контент вручную. Сервис мониторит источники, отбирает нужное (в том числе с помощью ИИ) и публикует по расписанию сразу в несколько каналов. Фоновые очереди, устойчивость к сбоям внешних сервисов. - [Мобильные приложения без магазинов приложений](https://xn--80adkmnnb2b.xn--80adkdyec4j.xn--p1ai/uslugi/): нужно приложение у людей в телефоне, но не хочется проходить публикацию в сторах. Устанавливаемое веб-приложение (PWA) с офлайн-режимом и пуш-уведомлениями — работает и на iPhone, и на Android. Обновление выкатывается сразу всем, без ожидания модерации. - [Вход, роли и 152-ФЗ](https://xn--80adkmnnb2b.xn--80adkdyec4j.xn--p1ai/uslugi/): в системе персональные данные — нужно сделать правильно с первого дня. Единый вход для нескольких сервисов, роли и права с первого дня, соответствие закону о персональных данных, включая детские: согласие, локализация в РФ, минимизация, план действий при инциденте. - [Вывод в прод и эксплуатация](https://xn--80adkmnnb2b.xn--80adkdyec4j.xn--p1ai/uslugi/): код есть, а до работающего сайта на своём домене руки не доходят. Сборка в CI, деплой по SSH, HTTPS с автопродлением, кириллические домены, экономная эксплуатация на недорогих серверах с жёсткими лимитами памяти, проверка после каждого деплоя. ## Флагманы ### Матрица РМЗ — Настольная ERP-система для завода по ремонту двигателей - Страница: https://xn--80adkmnnb2b.xn--80adkdyec4j.xn--p1ai/raboty/matrica-rmz/ - Статус: в проде - Стек: TypeScript; Electron + React 18 (клиент), Node 22 + Express (сервер); PostgreSQL 16 / SQLite, Drizzle ORM; pnpm-монорепо - Что даёт: Единая учётная система завода: заказы, склад, наряды и отчёты в одной базе вместо разрозненных таблиц и бумаги. Программа стоит на компьютерах завода и работает даже без интернета, а когда связь появляется — сама синхронизирует данные с общим сервером. Есть печать нарядов с подписями и автообновление у всех пользователей разом. - Факт (замер автора, 2026-07-31): Самый активный проект: 523 коммита за 30 дней. - Факт (замер автора, 2026-07-31): Работает офлайн: данные пишутся локально и догоняют сервер при появлении связи. - Факт (замер автора, 2026-07-31): Многоэтапный аудит безопасности — критичные находки закрыты на проде. ### Гоньба — Сайт-CMS населённого пункта: новости и материалы под управлением редактора - Страница: https://xn--80adkmnnb2b.xn--80adkdyec4j.xn--p1ai/raboty/gonba/ - Работающий сайт: https://xn--80abf4be9f.xn--p1ai/ (гоньба.рф) - Статус: в проде - Стек: Next.js 15 + Payload CMS, TypeScript, PostgreSQL, pnpm 10; CI/CD на GitHub Actions - Что даёт: Сайт локального сообщества, которым легко управлять: редактор правит тексты прямо на странице, а часть контента сама подтягивается из группы ВКонтакте. Заточен под поисковики и ИИ-ассистентов, чтобы его находили. Подходит местному СМИ, блогу или информационному порталу. - Факт (проверяется снаружи, 2026-08-01): Сайт открыт и работает — можно зайти и проверить самому. - Факт (замер автора, 2026-09-04): 47 коммитов за последние 30 дней; серия из 8 зелёных деплоев подряд. - Факт (замер автора, 2026-08-01): Редактор правит сайт сам — программист для наполнения не нужен. ### Тренер — Платформа спортивной школы: сеть филиалов, расписание, объявления, подтверждения от родителей - Страница: https://xn--80adkmnnb2b.xn--80adkdyec4j.xn--p1ai/raboty/trener/ - Работающий сайт: https://xn--e1afpni.xn--80adkdyec4j.xn--p1ai/ (интер.вмалмыже.рф) - Статус: в проде - Стек: Next.js 15 + Payload CMS 3.75 + React 19 + PostgreSQL; клиент — PWA; web-push (APNs / FCM + VAPID); хостинг в РФ - Что даёт: Решает вечную боль школы «родители не в курсе изменений». Тренеры ведут расписание своих групп и рассылают объявления, родители получают уведомление и подтверждают одним тапом. Тренер сразу видит, кто заметил, а администратор управляет структурой — филиалами, группами, тренерами и детьми. - Факт (проверяется снаружи, 2026-08-01): Сайт открыт и работает — можно зайти и проверить самому. - Факт (замер автора, 2026-09-04): В проде с 26 июня 2026 — больше двух месяцев обслуживает живых пользователей. - Факт (замер автора, 2026-07-31): Из приложения одной школы выросло в платформу сети филиалов с ролями владельца, администратора, тренера и родителя. - Факт (замер автора, 2026-07-31): Требования 152-ФЗ по детским данным заложены в архитектуру, а не добавлены потом. ## Сайты организаций и событий ### Сабантуй Малмыж — Сайт национального фестиваля с живой программой дня и народной фотолентой - Страница: https://xn--80adkmnnb2b.xn--80adkdyec4j.xn--p1ai/raboty/sabantuy-malmyzh/ - Работающий сайт: https://xn--80aac7atuli.xn--80adkdyec4j.xn--p1ai/ (сабантуй.вмалмыже.рф) - Статус: в проде - Стек: Next.js 15 + Payload CMS 3.75 + PostgreSQL, TypeScript, pnpm 10 - Что даёт: Сайт праздника, который организаторы наполняют сами через админку. Посетители видят программу с отметкой «идёт сейчас», листают галереи, регистрируются на события и выкладывают свои снимки в общую ленту: снимок виден сразу, а неподходящее скрывается по жалобам посетителей автоматически или модератором вручную. В день фестиваля сайт держал пик нагрузки без единого сбоя. - Факт (проверяется снаружи, 2026-08-01): Сайт открыт и работает — можно зайти и проверить самому. - Факт (замер автора, 2026-07-04): В день фестиваля пик 4,6 запроса в секунду, ноль сбоев, запас мощности около четырёхкратного. - Факт (замер автора, 2026-07-25): Контрольный нагрузочный замер показал потолок около 84 запросов в секунду на том же сервере. ### Ярмарка Казанская — Сайт городского праздника с летописью по годам и живым режимом дня события - Страница: https://xn--80adkmnnb2b.xn--80adkdyec4j.xn--p1ai/raboty/yarmarka-kazanskaya/ - Работающий сайт: https://xn--80aaa0andu6a3j.xn--80adkdyec4j.xn--p1ai/ (казанская.вмалмыже.рф) - Статус: в проде - Стек: Next.js 15 + Payload CMS 3.75 + PostgreSQL, pnpm 10 - Что даёт: Сайт старинной купеческой ярмарки: афиша, живой режим программы в день праздника и летопись прошлых лет с фотографиями по каждому году. Собран по образцу уже работающего сайта Сабантуя — поэтому запущен быстро. Когда праздник 2026 года отменили, сайт за часы перевели в режим объявления, не ломая летопись. - Факт (проверяется снаружи, 2026-08-01): Сайт открыт и работает — можно зайти и проверить самому. - Факт (замер автора, 2026-07-31): Запуск за счёт переиспользования стека соседнего проекта — недели вместо месяцев. - Факт (проверяется снаружи, 2026-07-24): Отмену праздника 2026 года сайт отработал сменой режима, а не переделкой. ### вМалмыже — Городской информационный портал района - Страница: https://xn--80adkmnnb2b.xn--80adkdyec4j.xn--p1ai/raboty/vmalmyzhe/ - Работающий сайт: https://xn--80adkdyec4j.xn--p1ai/ (вмалмыже.рф) - Статус: в проде - Стек: Next.js 15 + Payload CMS 3.75 + PostgreSQL, TypeScript, pnpm; CI/CD + systemd - Что даёт: Информационный портал города и района: лента новостей, афиша, объявления, рубрики и поиск. Редактор ведёт портал сам через админку, без участия программиста. - Факт (проверяется снаружи, 2026-08-01): Портал открыт и работает — можно зайти и проверить самому. - Факт (замер автора, 2026-07-26): Первые рабочие этапы портала выведены в прод в день запуска работ. ### Портал культуры Малмыжского района — Портал-матрёшка: учреждения культуры района под одной крышей, каждое со своим лицом - Страница: https://xn--80adkmnnb2b.xn--80adkdyec4j.xn--p1ai/raboty/dom-kultury/ - Работающий сайт: https://xn--80atdujec4e.xn--80adkdyec4j.xn--p1ai/ (культура.вмалмыже.рф) - Статус: в проде - Стек: Next.js 15 + Payload CMS 3.75 + PostgreSQL, TypeScript, pnpm; CI/CD + systemd - Что даёт: Вырос из сайта одного Дома культуры в портал всего района. Каждое учреждение получает внутри портала собственное лицо — оформление, эмблему, новости и афишу, — но живёт на общей платформе: одна админка, один сервер, одно обновление на всех. Сельским клубам больше не нужен свой сайт и свой подрядчик, а район получает единую точку, где видно всю культурную жизнь сразу. - Факт (проверяется снаружи, 2026-09-04): Портал открыт и работает — можно зайти и проверить самому. - Факт (проверяется снаружи, 2026-09-04): Основной адрес — культура.вмалмыже.рф; прежний домкультуры.вмалмыже.рф отвечает перенаправлением, старые ссылки не теряются. - Факт (замер автора, 2026-09-04): Первый сбор материалов прошёл по всем 33 сообществам учреждений района: 632 записи и 2457 медиафайлов легли в портал черновиками, до решения редактора о публикации. - Факт (проверяется снаружи, 2026-09-05): Собственное фирменное оформление с эмблемой портала, разделами праздников и страницами домов культуры района — вместо типового каркаса. ## Сервисы и автоматизация ### ПОЗВОНИ — Справочник услуг города: одно приложение, много дверей — первым открылось такси - Страница: https://xn--80adkmnnb2b.xn--80adkdyec4j.xn--p1ai/raboty/pozvoni/ - Работающий сайт: https://xn--b1ajetccd.xn--80adkdyec4j.xn--p1ai/ (позвони.вмалмыже.рф) - Статус: в проде - Стек: Next.js + Payload CMS + PostgreSQL, TypeScript, pnpm; клиент — PWA; MapLibre + собственные тайлы OSM (PMTiles) + локальный геокодер; OIDC-вход - Что даёт: Городской справочник «кому позвонить»: телефон, справочные цены и часы работы — в одно касание, без поиска по группам и объявлениям. Сейчас наполнен раздел такси; услуги, мастера и магазины заведены категориями и собираются. Адрес находится по карте города, которая работает даже при плохой связи. Устроено как матрёшка: тот же справочник открывается и целиком, и отдельной дверью под свою тему — «Такси Малмыж» живёт на своём адресе, но это одно приложение и одна база номеров, а не копия сайта. - Факт (проверяется снаружи, 2026-09-11): Справочник открыт и работает — можно зайти и проверить самому. - Факт (замер автора, 2026-09-04): Первый выход в прод — 29 августа 2026; вторая дверь, весь справочник целиком, открыта 30 августа. - Факт (проверяется снаружи, 2026-08-29): Карта и поиск адреса работают без единого обращения к сторонним сервисам — видно в панели сети браузера. - Факт (замер автора, 2026-08-29): В адресной базе города 103 улицы и 2094 адреса, карта укладывается в 1,23 МиБ. - Факт (замер автора, 2026-09-03): Вход через единый вход экосистемы проверен живым входом, без ручной регистрации. ### Рекламная площадка «Сарафан» — Сеть районных новостных сообществ и продажа рекламы в ней - Страница: https://xn--80adkmnnb2b.xn--80adkdyec4j.xn--p1ai/raboty/sarafan-reklama/ - Работающий сайт: https://xn--80aaa6cmey.xn--80adkdyec4j.xn--p1ai/regions/links (сарафан.вмалмыже.рф) - Статус: в проде - Стек: Python 3.12, FastAPI, Celery + Redis, PostgreSQL, интеграция с VK API; витрина — серверный рендер - Что даёт: Витрина сети районных новостных сообществ и способ купить в них рекламу, не обзванивая каждое по отдельности. Рекламодатель отмечает районы галочками, видит охват и цену со скидкой прямо на странице и одной кнопкой копирует готовый заказ. Сарафанное радио, только цифровое: одно объявление расходится по десяткам местных групп там, где нет ни городских газет, ни билбордов. - Факт (проверяется снаружи, 2026-08-02): Сеть из 26 сообществ, 29 173 подписчика суммарно — числа на странице живые, обновляются каждую ночь. - Факт (проверяется снаружи, 2026-08-02): Охват — 23 района Кировской области и 3 сообщества в Татарстане: экспансия за пределы области уже началась. - Факт (замер автора, 2026-08-02): Новости в сообществах выходят без участия человека, круглосуточно — сеть растёт без роста ручного труда. ### Сарафан — Автоматизированная редакция: сбор новостей, ИИ-отбор и публикация по расписанию - Страница: https://xn--80adkmnnb2b.xn--80adkdyec4j.xn--p1ai/raboty/sarafan/ - Статус: внутренний сервис - Стек: Python 3.12, FastAPI, Celery + Redis, PostgreSQL, интеграция с VK API; деплой по SSH + systemd - Что даёт: Система сама собирает новости из сообществ ВКонтакте, отбирает нужное с помощью ИИ и публикует по расписанию сразу в несколько каналов — ВКонтакте, Telegram, сайты. Заменяет ручную работу редакции сразу для десятков региональных каналов. Дополнительно служит общим сервисом для соседних проектов: единый вход и шлюз к ВКонтакте. - Факт (замер автора, 2026-07-29): Единый вход «ЕСА вМалмыже.рф» работает от начала до конца; выдача клиентов и ключей — самообслуживанием. - Факт (замер автора, 2026-07-29): Около 1400 автотестов. - Почему нет скриншотов: Внутренний сервис: публичного интерфейса нет — показывать нечего, кроме результата его работы на сайтах-клиентах. ### Карман — Личный менеджер кредитов с напоминаниями в Telegram - Страница: https://xn--80adkmnnb2b.xn--80adkdyec4j.xn--p1ai/raboty/karman/ - Статус: в проде - Стек: Next.js 16 (App Router) + React 19 + TypeScript, Drizzle ORM + PostgreSQL, Tailwind CSS v4 - Что даёт: Помогает держать все займы, графики выплат и документы в одном месте, чтобы ничего не потерять и не просрочить. Заранее шлёт напоминание о ближайшем платеже в Telegram, а отметить платёж выполненным можно кнопкой прямо в сообщении. - Факт (замер автора, 2026-07-31): Три разных стека (Django, Vite, Express) сведены в один без сброса паролей пользователей. - Факт (замер автора, 2026-07-31): Воркер напоминаний не тянет ни одной внешней зависимости. - Почему нет скриншотов: Личный финансовый сервис: на экранах — суммы и договоры реальных пользователей. ## Инструменты - [Черновик техзадания](https://xn--80adkmnnb2b.xn--80adkdyec4j.xn--p1ai/tehzadanie/): восемь вопросов, из которых собирается техзадание на разработку — что нужно, кто будет пользоваться, что уже есть, кто ведёт после запуска, сроки, персональные данные, деньги, что считать результатом. Считается в браузере, ответы никуда не отправляются; на выходе документ, который можно распечатать или отдать другому исполнителю. Полный список вопросов с пояснениями «зачем спрашиваю» — на самой странице и в https://xn--80adkmnnb2b.xn--80adkdyec4j.xn--p1ai/llms-full.txt. ## Разборы производственных ошибок (журнал грабель) - [После статической сборки кириллица в /llms.txt превращается в кашу](https://xn--80adkmnnb2b.xn--80adkdyec4j.xn--p1ai/grabli/staticheskiy-eksport-teryaet-content-type/): Next.js 15, output: export, route handler, отдающий текст. Обработчик маршрута сам ставит заголовок content-type с charset, но при статическом экспорте он запекается в обычный файл — заголовки задаёт уже веб-сервер по расширению. Расширения .txt для сервера достаточно, чтобы отдать text/plain, но недостаточно, чтобы догадаться про UTF-8. Лечение: Дописать кодировку на стороне веб-сервера для конкретных файлов. Заголовок в коде обработчика при этом остаётся — он работает в режиме разработки и вводит в заблуждение ровно до первого выхода в прод. - [Картинка для соцсетей генерируется, но превью ссылки остаётся пустым](https://xn--80adkmnnb2b.xn--80adkdyec4j.xn--p1ai/grabli/generator-og-kartinki-bez-rasshireniya/): Next.js 15, opengraph-image.tsx, output: export. Генератор запекается в файл без расширения. Веб-сервер отдаёт его как поток байтов, а соцсети и ассистенты принимают картинку только с типом image/*. Сама картинка при этом корректная — её можно скачать и открыть. Лечение: Либо дописать тип на веб-сервере, либо не генерировать картинку маршрутом, а положить готовый файл с расширением в статику и сослаться на него в метаданных. Второе не зависит от настройки сервера. - [У всех внутренних страниц в превью показывается заголовок и адрес главной](https://xn--80adkmnnb2b.xn--80adkdyec4j.xn--p1ai/grabli/opengraph-ne-nasleduetsya-vglub/): Next.js App Router, metadata в дочерних страницах. Блок openGraph не сливается с родительским поглубже: дочерняя страница либо задаёт его целиком, либо наследует целиком. Задать title и description на странице недостаточно — og-блок останется родительским, вместе с og:url корня. Лечение: Собирать метаданные одним общим помощником, который обязательно принимает путь страницы и строит og:url из него. Не писать og-блок руками на каждой странице — забудут в первой же новой. - [Поиск по проекту «ничего не нашёл» — а искомое в проекте есть](https://xn--80adkmnnb2b.xn--80adkdyec4j.xn--p1ai/grabli/proverka-grepom-lozhno-chistaya/): grep и ripgrep, кириллица и пути с ведущим слешем. Регистронезависимый поиск не работает с кириллицей так, как ожидается, а у ripgrep свои умолчания по игнорируемым путям. Пустой вывод в обоих случаях выглядит одинаково — как чистый результат. Лечение: Никогда не принимать пустой вывод как доказательство отсутствия. Рядом с проверкой запускать контрольный поиск строки, которая точно есть в текущем дереве, — если и он пуст, сломан инструмент, а не проект. - [Проверка снаружи молчит по таймауту — кажется, что сайт упал](https://xn--80adkmnnb2b.xn--80adkdyec4j.xn--p1ai/grabli/vneshniy-taymaut-ne-znachit-sayt-lezhit/): Проверка доступности из другой сети или другой страны. Отказ канала проверки и отказ сайта выглядят одинаково: пустой ответ. Промежуточные сети могут резать соединение по имени сайта, поэтому соседний адрес на том же сервере отвечает, а проверяемый — нет. Лечение: Сначала выяснить, куда вообще указывает имя, и повторить проверку из другого канала. Вывод «лежит» имеет право появиться только после совпадения двух независимых проверок. - [Сканер секретов «работает» — на подсадном ключе из документации](https://xn--80adkmnnb2b.xn--80adkdyec4j.xn--p1ai/grabli/skaner-sekretov-proveren-primerom-iz-dokumentacii/): Сканеры секретов со списками известных примеров. Ключи из официальной документации внесены в списки исключений именно потому, что встречаются в примерах у всех. Сканер их пропускает намеренно. Лечение: Проверять сканер случайно сгенерированным значением нужного формата, а не примером из документации поставщика. - [На снимке всей страницы вместо картинок пустые места](https://xn--80adkmnnb2b.xn--80adkdyec4j.xn--p1ai/grabli/skrinshot-ne-zhdet-lenivye-kartinki/): Headless-браузер, полностраничный снимок, картинки с ленивой загрузкой. Ленивые картинки грузятся при попадании в область просмотра. Снимок всей страницы область просмотра не двигает — для браузера они так и не понадобились. Лечение: Перед съёмкой прокрутить страницу до конца и дождаться загрузки, и только потом снимать. - [Сборка падает на удалении каталога: устройство занято](https://xn--80adkmnnb2b.xn--80adkdyec4j.xn--p1ai/grabli/sborka-padaet-iz-za-zapushchennogo-servera/): Сборка статического экспорта при запущенном локальном сервере. Локальный сервер держит открытым каталог, который сборка пытается очистить. Ошибка приходит от файловой системы и о сервере не упоминает. Лечение: Остановить сервер перед пересборкой. - [Сайт рассказывает о себе то, что перестало быть правдой](https://xn--80adkmnnb2b.xn--80adkdyec4j.xn--p1ai/grabli/sayt-utverzhdaet-o-sebe-ustarevshee/): Любой сайт, где текст о поведении лежит отдельно от кода этого поведения. Утверждение «здесь нет скриншотов такой-то системы» живёт в тексте страницы, а сами скриншоты — в каталоге данных. Добавление снимков текст не трогает, и он тихо становится ложью. Лечение: Меняя поведение, обыскивать сайт на утверждения об этом поведении. Где возможно — считать утверждение из тех же данных, а не набирать руками. - [У числа, которое считается само, стоит дата замера — и она врёт](https://xn--80adkmnnb2b.xn--80adkdyec4j.xn--p1ai/grabli/data-zamera-u-vychislyaemogo-chisla/): Витрины и отчёты, где рядом стоят посчитанные и набранные руками числа. Посчитанное число меняется вместе с данными, а подпись «сняты такого-то числа» остаётся прежней. Первое же изменение данных делает подпись неверной, причём именно для того числа, которое как раз актуально. Лечение: Датировать только то, что набрано руками. Про вычисляемое честнее написать, что оно считается при сборке. ## Optional - [Полный текст сайта](https://xn--80adkmnnb2b.xn--80adkdyec4j.xn--p1ai/llms-full.txt): все страницы задач, услуг и работ одним файлом. - [Машиночитаемые факты](https://xn--80adkmnnb2b.xn--80adkdyec4j.xn--p1ai/facts.json): те же сведения в JSON, каждый факт с датой замера. - [Каталог работ](https://xn--80adkmnnb2b.xn--80adkdyec4j.xn--p1ai/raboty/): все системы одной страницей. ## Как связаться - Телефон: +7 922 900-59-10 - Почта: valstan@valstan.ru - Telegram: @VAL_STAN (https://t.me/VAL_STAN) - Код: https://github.com/Valstan Страница контактов — https://xn--80adkmnnb2b.xn--80adkdyec4j.xn--p1ai/kontakty/.