<?xml version="1.0" encoding="utf-8" ?>
<rss version="2.0" xml:base="https://graker.ru/" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Разработка</title>
    <link>https://graker.ru/</link>
    <description>RSS домовой страницы</description>
    <language>ru</language>
    
    <item>
  <title>Claude Code и технические инструкции</title>
  <link>https://graker.ru/news/2026/10/13/claude-code-and-tech-manuals</link>
  <description>&lt;div class=&quot;paragraph paragraph--text&quot;&gt;&lt;p&gt;После «редизайна за 600» обновлять Доктурист стало куда проще. Вчера залили интеграцию с ОФД Ферма, которая была готова еще до редизайна, но включить не успели. Теперь вот включили — даже мердж почти без конфликтов оказался. Жизнь-то налаживается :шляпа:  &lt;/p&gt;
&lt;p&gt;К слову, в ходе таких интеграций и деплоев оказалось очень полезно подключать нейросети к подготовке сопроводительных материалов. Свои статьи я иичку писать не доверю ни за что, там из каждого предложения потом развесистые уши роботов торчат. А вот подготовить статью «Как пользоваться функцией из этого коммита» — запросто. Текст технический, написан точно, в эпистолярных изысках не нуждается. Вот, например, &lt;a href=&quot;https://docturist.ru/news/ferma-check-integration&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;инструкция как выбивать чеки&lt;/a&gt; — я её руками почти не правил.&lt;/p&gt;
&lt;p&gt;Более того, мусье Клод умеет подключаться к Хрому и Плейрайту, так что на роботов можно полностью переложить ещё и производство скриншотов.&lt;/p&gt;
&lt;p&gt;Применительно к инструкции, Клод не просто сделал все скрины (а он сделал). Когда мы закончили и выложили новый дизайн, внезапно™ оказалось, что у нас скрины сервиса и даже видео являются его, дизайна, элементами. Но только дизайн у нас теперь новый, а скрины и видео — старые. К тому же, в блоге проекта до редизайна уже было несколько инструкций. И они, конечно, тоже в одночасье устарели.  &lt;/p&gt;
&lt;p&gt;Переснимать всё это заново руками очень не хотелось, так что я сразу свалил это на Клода. И вот чего он сделал:  &lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Написал манифест со списком скринов из разных разделов сайта, с каких страниц и под какими аккаунтами их делать.  &lt;/li&gt;
&lt;li&gt;Написал скрипт, который делает все или часть скринов из манифеста, при этом логинясь за нужный аккаунт и заходя на нужные страницы.  &lt;/li&gt;
&lt;li&gt;И даже для видео скрипт написал, который снимает несколько кусков из разных разделов отдельно, а потом клеит из них интро целиком.  &lt;/li&gt;
&lt;li&gt;Если на скрине нужна ошибка, которую трудно воспроизвести (скажем, редкая ошибка из ОФД), он просто рисует её манипуляциями с DOM, раз в десять быстрее, чем я бы догадался. А если не хватает тестовых данных — генерит на ходу, или тоже в DOM вставляет. &lt;/li&gt;
&lt;li&gt;Теперь, если я решил изменить немножко вид какой-то страницы, или блоки переставить, я просто перезапускаю скрипт* и у меня сразу готов набор обновлённых скриншотов.&lt;br&gt;
А если добавлю новый раздел или фичу — клод заскринит и в манифест сразу скрины впишет тоже. &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Очень рекомендую на вооружение, если ещё не.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;*на самом деле я не перезапускаю скрипт, мне лень. Я клоду говорю, чтоб он переснял нужные страницы, а он перезапускает сам.&lt;/em&gt;&lt;/p&gt;&lt;/div&gt;
</description>
  <pubDate>Tue, 13 Oct 2026 08:50:00 +0000</pubDate>
    <dc:creator>graker</dc:creator>
    <guid isPermaLink="false">2244 at https://graker.ru</guid>
    </item>
<item>
  <title>PR на шиссот!</title>
  <link>https://graker.ru/news/2026/10/07/pr-600</link>
  <description>&lt;div class=&quot;paragraph paragraph--text&quot;&gt;&lt;p&gt;На днях PR на 610 файлов был окончательно повержен и смерджен! На выходе получился полный редизайн Доктуриста. Наружной части (лендинга и блога) немного тоже, но в первую очередь — всего внутряка. Всех страниц, форм и диалогов самой crmки.  &lt;/p&gt;
&lt;p&gt;Это еще один пример как можно увлечься, решая задачи с нейросетью. Изначально идея была значительно скромнее. Дэшборд, он же рабочий стол, он же главная страница внутри системы — был сделан довольно простеньким. Вот так он выглядел:&lt;/p&gt;&lt;/div&gt;
&lt;figure data-component-id=&quot;grakerru:figure&quot; class=&quot;figure figure--center figure--medium&quot;&gt;
      &lt;a href=&quot;/sites/default/files/uploads/2026-10/dashboard.png&quot; data-lightbox=&quot;node-2243&quot;&gt;
    &lt;img loading=&quot;lazy&quot; srcset=&quot;/sites/default/files/styles/content_medium/public/uploads/2026-10/dashboard.png.webp?itok=yo1Bng8q 850w, /sites/default/files/styles/content_medium_2x/public/uploads/2026-10/dashboard.png.webp?itok=S8nvKheF 1700w&quot; sizes=&quot;(min-width: 1200px) 850px, (min-width: 768px) 75vw, calc(100vw - 30px)&quot; width=&quot;850&quot; height=&quot;413&quot; src=&quot;/sites/default/files/styles/content_medium/public/uploads/2026-10/dashboard.png.webp?itok=yo1Bng8q&quot; alt=&quot;dashboard.thumb.png&quot; /&gt;



&lt;/a&gt;
    &lt;/figure&gt;
&lt;div class=&quot;paragraph paragraph--text&quot;&gt;&lt;p&gt;Конечно, турагенты сообщили, что виджетами этого стола не пользуются совсем. Только ссылками, чтобы сразу прыгнуть в нужный раздел. А хотелось чтобы это был скорее быстрый доступ к важным разделам и информации. Чтобы некоторые вещи вообще можно было сделать, не уходя с дэшборда.  &lt;/p&gt;
&lt;p&gt;Вот этим мы с клод-дизайном и занялись. Переосмыслили содержимое дэшборда с целью сделать его удобным и используемым, а не просто местом для ссылок как рабочий стол в win95. И вышеприведенное «было» превратилось в новое «стало»:  &lt;/p&gt;&lt;/div&gt;
&lt;figure data-component-id=&quot;grakerru:figure&quot; class=&quot;figure figure--center figure--medium&quot;&gt;
      &lt;a href=&quot;/sites/default/files/uploads/2026-10/dashboard_3.png&quot; data-lightbox=&quot;node-2243&quot;&gt;
    &lt;img loading=&quot;lazy&quot; srcset=&quot;/sites/default/files/styles/content_medium/public/uploads/2026-10/dashboard_3.png.webp?itok=ORE5xe4w 850w, /sites/default/files/styles/content_medium_2x/public/uploads/2026-10/dashboard_3.png.webp?itok=f57DgDy- 1700w&quot; sizes=&quot;(min-width: 1200px) 850px, (min-width: 768px) 75vw, calc(100vw - 30px)&quot; width=&quot;850&quot; height=&quot;531&quot; src=&quot;/sites/default/files/styles/content_medium/public/uploads/2026-10/dashboard_3.png.webp?itok=ORE5xe4w&quot; alt=&quot;dashboard.thumb.png&quot; /&gt;



&lt;/a&gt;
    &lt;/figure&gt;
&lt;div class=&quot;paragraph paragraph--text&quot;&gt;&lt;p&gt;Тут уже и показатели всякие, и главное лента с броньками более умная. Хочешь, смотри последние брони по дате, хочешь — требующие определённого внимания.  &lt;/p&gt;
&lt;p&gt;Сдерживать оформительские порывы Клода я не стал, поэтому в нагрузку получил сразу и новый стиль. Предыдущий стиль делался на теме color admin, которую я в 2018-м специально покупал. Тема, конечно, с тех пор несколько состарилась и подрастеряла актуальность.&lt;/p&gt;
&lt;p&gt;Так или иначе, когда есть новое оформление — остальные страницы оставлять в старом не хочется. И так, страничка за страничкой, компонент за компонентом мы сначала с Claude Design, а затем с Claude Code привели весь сервис к новым стилям. А поскольку просто так перерисовывать скучно, то заодно переосмыслили, доработали и переделали компоненты на страничках.&lt;/p&gt;
&lt;p&gt;Вот и получился PR на 610 файликов. Который я конечно умотался проверять и тестировать. И в целом тезисы моего &lt;a href=&quot;/news/2026/08/11/zeldevmeetup-talk-2026&quot;&gt;доклада&lt;/a&gt; на эту тему сохраняются. Надо тестировать, структурировать, декомпозировать. А вот не смотреть на нейрокод по заветам Роберта Мартина пока еще не получается: я проверял каждый экранчик — смотрел изменения, тесты, фронт, и в каждом находил что что-то было сделано не совсем так, или не работало, или влекло проблемы какие-то новые.&lt;/p&gt;
&lt;p&gt;Но в конечном итоге всё проверил, погонял руками и залил. Так что теперь у нас в Доктуристе не только новый, переосмысленный, современный дизайн, но и всякие юзабилити-мелочи, в том числе:&lt;/p&gt;
&lt;p&gt;— Доктурист запоминает и сразу показывает набор операторов, с которыми часто работает агент, не нужно каждый раз искать по автодополнению.&lt;br&gt;
— &lt;code&gt;/&lt;/code&gt; или &lt;code&gt;Ctrl+F&lt;/code&gt; немедленно включают поиск по всем данным (повторный Ctrl+F включает нативный поиск).&lt;br&gt;
— Документы по брони можно сгенерировать и подписать прямо из всплывашки с рабочего стола, необязательно в бронь проваливаться.&lt;br&gt;
— Улучшена работа календаря на мобильных устройствах (мобильный календарь просто сделан заново).&lt;br&gt;
— Страница профиля наконец-то разделена на 5 секций по соответствующим тематикам настроек.&lt;br&gt;&lt;/p&gt;
&lt;p&gt;Результатом доволен, теперь обновления снова можно выкатывать чаще, не проверяя такие большие PRы. В целом редизайн занял где-то полтора месяца. Теперь на очереди интеграция сервиса онлайн-касс (уже готова) и тёмная тема (уже тоже). Работаем!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https://docturist.ru&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Доктурист — умный ежедневник турагента&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;&lt;/div&gt;
</description>
  <pubDate>Wed, 07 Oct 2026 18:30:00 +0000</pubDate>
    <dc:creator>graker</dc:creator>
    <guid isPermaLink="false">2243 at https://graker.ru</guid>
    </item>
<item>
  <title>Антропики всех забанят?</title>
  <link>https://graker.ru/news/2026/10/02/Will-anthropic-ban-us-all</link>
  <description>&lt;div class=&quot;paragraph paragraph--text&quot;&gt;&lt;p&gt;Последние несколько дней отовсюду появляются сообщения о лютых банах у антропиков. Отдельные авторы в своих каналах сообщают о досадных банах. В нескольких тематических сообществах многие делятся, как их заживо забанили. На Хабре пишут, что за использование VPN банят весь Гонконг и заодно нас в России накрывает тоже. Даже кто-то там из Яндекса пожаловался, что пришлось на &lt;s&gt;Гигачат&lt;/s&gt; Codex перейти.&lt;/p&gt;&lt;p&gt;Ещё в многочисленных отзывах делятся, что теперь для нового аккаунта в клод.аи надо показать паспорт, снилс и сдать биоматериалы. Так что, дорогие друзья, возможно нас с вами нейросети и не заменят: не пройдём по форме черепа.&lt;/p&gt;&lt;p&gt;С одной стороны — выкусите, роботы! Я еще сам кодить не разучился. С другой, мне бы еще месяцок свою игрушечку по ночам повайбкодить…&lt;/p&gt;&lt;p&gt;Я, правда, пока держусь — с августа слышу от разных людей, что банят. А сам через раз забываю VPN включить, постоянно обсуждаю с Клодом ТСПУ, заставляю сертификаты Минцифры устанавливать и парсить ресурсы, которые на заграницу не работают. Но видимо скоро роботы начнут что-то подозревать.&lt;/p&gt;&lt;p&gt;Кстати, в понедельник очередная подписка заканчивается, все выходные буду выжимать все соки!&lt;/p&gt;&lt;p&gt;P.S. А вообще, кто как спасается, коллеги? Codex, Cursor? Гигачат? 一个鲜为人知的中国神经网络? Человекорукокодинг?&lt;/p&gt;&lt;/div&gt;
</description>
  <pubDate>Fri, 02 Oct 2026 05:14:00 +0000</pubDate>
    <dc:creator>graker</dc:creator>
    <guid isPermaLink="false">2242 at https://graker.ru</guid>
    </item>
<item>
  <title>Нейроотладка</title>
  <link>https://graker.ru/news/2026/09/08/neurodebug</link>
  <description>&lt;div class=&quot;paragraph paragraph--text&quot;&gt;&lt;p&gt;Нейросети продолжают безжалостно нас заменять. На этот раз, в расследованиях и отладке.  &lt;/p&gt;
&lt;p&gt;Дано: редактор потерял немножко контента. Чегой-то нажал и всё пропало. Никогда такого не было и вот опять.  &lt;/p&gt;
&lt;p&gt;— Эй, Клод, вот тут подчищенные дампы базы с нескольких сайтов, редактор на мастере чего-то делал, и контент на нескольких сайтах пропал. Найди, куда он делся и выясни, что нажал редактор. Только осторожно смотри, там три гига.&lt;br&gt;
— Авек плезир. И парсить дампы я не буду, не бойсь.  &lt;/p&gt;
&lt;p&gt;Смотрит логику синхронизации контента. Поднимает сам в докере контейнеры mysql, накатывает дампы. Раскручивает по таблицам ревизии страниц. 15 минут и пишет отчёт: вот тут, число месяц время, редактор отменил подписки на контент и всё пропало. Вот тут он их вернул, но было уже поздно, ха-ха-ха. А вот чего надо настроить, чтобы поздно больше не было. Но это в другой раз, сейчас — извиняй — контент уже не вернуть. Спасибо пожалуйста, пиши ещё.  &lt;/p&gt;
&lt;p&gt;И как это можно ещё сильнее автоматизировать? Пустить его на прод, разве что, и в джиру, чтобы сам редактору рассказывал? Некоторые, я знаю, уже пускают, но нам на прод пока боязно. Да и не во все проекты можно.  &lt;/p&gt;
&lt;p&gt;И что вообще дальше? Что там у Фрэнка Герберта делали, чтобы совсем эти все компьютеры зопретить?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;upd:&lt;/strong&gt; Всё-таки кожаные ещё нужны.&lt;/p&gt;
&lt;p&gt;Пристрастное изучение отчета выявило несколько проблем, которые иичко решило не объяснять и которые находками отчета в принципе не могут быть объяснены. Покопался глубже уже сам в недоступных нейросети местах и нашёл баг в стороннем SaaS сервисе, который в проекте используется.&lt;/p&gt;
&lt;p&gt;Думаю, Клод бы это тоже нашел, но кто ж его туда пустит.&lt;/p&gt;
&lt;p&gt;Чувствую себя могучим. Выкусите, роботы!&lt;/p&gt;&lt;/div&gt;
</description>
  <pubDate>Mon, 07 Sep 2026 22:05:00 +0000</pubDate>
    <dc:creator>graker</dc:creator>
    <guid isPermaLink="false">2238 at https://graker.ru</guid>
    </item>
<item>
  <title>Доктурист разжился курсами валют туроператоров</title>
  <link>https://graker.ru/news/2026/08/18/docturist-and-operator-currency-rates</link>
  <description>&lt;div class=&quot;paragraph paragraph--text&quot;&gt;&lt;p&gt;У нас в Доктуристе новое обновление: добавили &lt;a href=&quot;https://docturist.ru/news/operator-currency-rates&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;поддержку валют туроператоров&lt;/a&gt;. Что это значит? Туроператоры ведут расчет по заграничным броням в валюте, долларах или евро. Что логично: нужно вести расчеты с иностранными контрагентами в условиях постоянно меняющегося курса.&lt;/p&gt;
&lt;p&gt;Поэтому стоимость тура обычно указана в валюте, а платежи оператор принимает в рублях, пересчитывая их на стоимость тура по курсу. Но не по курсу Центробанка разумеется, а по собственному курсу, который каждый оператор устанавливает самостоятельно (обычно на несколько рублей выше курса ЦБ).&lt;/p&gt;
&lt;p&gt;В Доктуристе можно вести заявки как в рублях — вручную пересчитывая всё что нужно, — так и в валюте. Вот если вести их в валюте, обычно возникают вопросы: сколько примерно стоит тур в рублях на сегодня? Сколько осталось заплатить? Сколько учесть в долларах от стоимости тура, если турист заплатил $1000?&lt;/p&gt;
&lt;p&gt;До сегодняшнего дня Доктурист чисто в иллюстративных целях показывал расчеты по курсу ЦБ, что можно использовать только для примерной оценки. Для точной оценки можно было ввести курс пересчета вручную и увидеть сумму.&lt;/p&gt;
&lt;p&gt;Но зачем это делать вручную, когда можно взять курс с сайта оператора и применить его для получения точных сумм. Так что мы подсуетились и добавили поддержку курсов операторов. Теперь если для туроператора, с которым сделана бронь, поддерживаются курсы валют, они будут иметь приоритет над курсами ЦБ и пользователь получит точные вычисления (ручной ввод все еще возможен и приоритетнее).&lt;/p&gt;
&lt;p&gt;С технической точки зрения, это конечно не самое любимое занятие — писать десятки парсеров. Где-то стоит SPA с гидрацией после загрузки и обычные запросы не видят курсов, приходится выискивать API. Где-то — бан на иностранные IP-адреса, и приходится иишечке вручную фикстуры для проверки парсера выдавать. Какой-то сайт взял и забанил известные диапазоны адресов хостингов, и просто так с живого сервера не попарсишь. А где-то и вовсе скрипт защиты от ботов и без playwright/puppeteer HTML страницы никак не вытащить.&lt;/p&gt;
&lt;p&gt;Неприятно через эти дебри пробираться: вроде ничего не воруешь, всё чисто для удобства пользователей, которые этим же операторам приносят деньги. Но ограничений столько, как будто это страшный секрет какой-то, а не засвеченный прямо на главной странице блок USD/EUR.&lt;/p&gt;
&lt;p&gt;Но так или иначе, первая дюжина операторов побеждена и добавлена в сервис — как автоматический парсер per operator в очереди, так и фоллбэк на ручной ввод. А также планы B и C на случай, если всё сломается, или кто-то подбанит IP.&lt;/p&gt;
&lt;p&gt;Продолжаем работу!&lt;/p&gt;
&lt;p&gt;P.S. А если вас интересуют курсы валют Центробанка, посмотрите на &lt;a href=&quot;https://botopotamus.ru/demo/currency&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;бота Валютопотама&lt;/a&gt;.&lt;/p&gt;&lt;/div&gt;
</description>
  <pubDate>Tue, 18 Aug 2026 11:45:00 +0000</pubDate>
    <dc:creator>graker</dc:creator>
    <guid isPermaLink="false">2234 at https://graker.ru</guid>
    </item>
<item>
  <title>RTS Дачники против слизней</title>
  <link>https://graker.ru/news/2026/08/04/rts-dachniki-vs-slizni</link>
  <description>&lt;p&gt;В порядке подготовки к докладу выкладываю, так сказать, пример вайбкода. Придумал несколько маленьких идей, закинул даже не в Claude Code, а просто в Claude чатик обсудить, а он взял и за 15 минут собрал демо игры. Буквально самую малость подрихтовали и вот, делюсь результатом.&lt;/p&gt;
&lt;p&gt;Это RTS/защита базы, дачники (в лице моих традиционных героев) должны защищать теплицу от слизней, которые нападают волнами. Копи огурцы, покупай юнитов, гаси слизней пока теплица еще цела. Конечно, это всего лишь прототип, персонажей Клод сделал эмодзиками, вариативности тоже немного. Но — подтянуть немножко баланс, добавить генерацию карты, постройки, арты, звуки, и…&lt;/p&gt;
&lt;p&gt;Но даже так, вот что можно сделать агентом просто, повторюсь, за 15 минут.&lt;/p&gt;
&lt;p&gt;Сделано всё на JavaScript, Клод мне её прямо в чатике продемонстрировал. Чуть больше 800 строк кода — это вместе со всеми текстами и репликами, HTML и стилями. Ну и плюс логика игры, и даже алгоритм расчета маршрута к теплице для слизней (flow field).&lt;/p&gt;
&lt;p&gt;Поиграть можно прямо под катом.&lt;/p&gt;</description>
  <pubDate>Tue, 04 Aug 2026 09:20:00 +0000</pubDate>
    <dc:creator>graker</dc:creator>
    <guid isPermaLink="false">2232 at https://graker.ru</guid>
    </item>
<item>
  <title>Unleash my inner speaker</title>
  <link>https://graker.ru/news/2026/08/03/unleash-my-inner-speaker</link>
  <description>&lt;div class=&quot;paragraph paragraph--text&quot;&gt;&lt;p&gt;Пришла пора расчехлить своего внутреннего спикера. Буду докладывать на митапе &lt;a href=&quot;https://zeldev.ru/agentikus&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://zeldev.ru/agentikus&lt;/a&gt; через неделю. Доклад на основе моих, так сказать, &lt;a href=&quot;/news/2026/04/08/robots-code-we-take-responsibility&quot;&gt;апрельских тезисов&lt;/a&gt; — полгода почти прошло, есть чем их дополнить.&lt;/p&gt;
&lt;p&gt;В последний раз публично что-то докладывал году наверно в 2015м. Так что придётся готовиться: рисовать презентацию буду с камнями во рте аки Демосфен. Надеюсь, получится интересно.&lt;/p&gt;&lt;/div&gt;
</description>
  <pubDate>Mon, 03 Aug 2026 10:40:00 +0000</pubDate>
    <dc:creator>graker</dc:creator>
    <guid isPermaLink="false">2231 at https://graker.ru</guid>
    </item>
<item>
  <title>Обновления в Ботопотамах</title>
  <link>https://graker.ru/news/2026/07/29/botopotamus-updates</link>
  <description>&lt;div class=&quot;paragraph paragraph--text&quot;&gt;&lt;p&gt;На днях удалось как следует поработать над &lt;a href=&quot;https://botopotamus.ru/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Ботопотамами&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Во-первых, &lt;strong&gt;добавил нового публичного бота&lt;/strong&gt;: знакомьтесь, &lt;a href=&quot;https://botopotamus.ru/demo/currency&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Валютопотам&lt;/a&gt;. Берет из Центробанка XML с курсами валют, парсит и показывает вам. Таких ботов много, но &lt;del&gt;этот мой&lt;/del&gt; мулька в том, что этот, в интервал когда ЦБ обычно выкатывает новые курсы, стучится туда постоянно. И если подписаться — сразу отправит уведомление как курсы вышли.&lt;/p&gt;
&lt;p&gt;Это может быть полезно для принятия решений, например, в турбизнесе. Срочно бежать оплачивать заявки сейчас, или отложить на завтра? Валютопотам расскажет в &lt;a href=&quot;https://t.me/CurrencypotamusBot&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Telegram&lt;/a&gt; или в &lt;a href=&quot;https://max.ru/id7735584860_3_bot&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Максе&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Во-вторых, &lt;strong&gt;основательно доработал саму платформу&lt;/strong&gt;. Сделал модульную архитектуру — теперь каждый ботопотам добавляется отдельной директорий со всей своей логикой, изолированной внутри. С доступом к общим функциям: крону, кэшу, очередям, событиям, статистике и так далее. При этом модуль — это некая фича бота, а сами боты добавляются из админки: вставил реквизиты телеги и макса, накликал какие функции нужны — и бот готов.&lt;/p&gt;
&lt;p&gt;Добавил локализацию: язык детектится из сообщения юзера, если в боте несколько языков, то можно вручную менять.&lt;/p&gt;
&lt;p&gt;Немного улучшил &lt;a href=&quot;https://botopotamus.ru/demo/monitor&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;бот мониторов&lt;/a&gt;: теперь если какой-то сайт падает, бот некоторое время дёргает его чаще — чтобы быстрее задетектить когда сайт встанет обратно.&lt;/p&gt;
&lt;p&gt;Запилил под эти изменения новый лендос Ботопотамов. Старый был чисто про бот мониторинга, новый — про разработку ботов. Ну и публичные боты получили по мини-лендингу. Claude design неплохо справился по-моему, лично я все время залипаю с летающего слоника.&lt;/p&gt;
&lt;p&gt;Продолжаем работу, на очереди еще парочка полезных ботов.&lt;/p&gt;&lt;/div&gt;
</description>
  <pubDate>Tue, 28 Jul 2026 22:20:00 +0000</pubDate>
    <dc:creator>graker</dc:creator>
    <guid isPermaLink="false">2228 at https://graker.ru</guid>
    </item>
<item>
  <title>Нейросети и анализ кода</title>
  <link>https://graker.ru/news/2026/07/22/ai-code-analysis</link>
  <description>&lt;div class=&quot;paragraph paragraph--text&quot;&gt;&lt;p&gt;Вчера считал эстимейты на группу из ~40 тикетов. Все сделаны по отчету ИИ об анализе кода большого проекта на Drupal. Проекту около 10 лет, кодовая база развивалась все это время, 20 поддоменов, интеграции, апишки, синхронизация контента, в общем прикольный проект.&lt;/p&gt;
&lt;p&gt;Отчет структурированный, нейросеть проверяла всех четырёх всадников попокалипсиса в проекте: Уязвимости, Баги, Тормоза и Грязный код. Изначально из переданного отчета получалось гораздо больше задач, но процентов на 30% я сразу won&#039;t fix навесил. Там и глюки нашлись, и непонимание контекста. Но 40 тикетов тем не менее осталось.&lt;/p&gt;
&lt;p&gt;Среди них тоже в основном таски с минимальнейшим приоритетом, типа&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;в кастомном модуле не проставлена зависимость от чего-нибудь типа paragraphs;&lt;/li&gt;
&lt;li&gt;где-то в коде наглый программист вызвал \Drupal::service() вместо инъекции зависимостей;&lt;/li&gt;
&lt;li&gt;где-то deprecated-версии Друпала не убраны из поддерживаемых версий и тому подобное.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Нашлось и несколько более серьезных претензий:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;парочка проблем N+1;&lt;/li&gt;
&lt;li&gt;несколько XSS-уязвимостей (доступных только админам, но всё же);&lt;/li&gt;
&lt;li&gt;несколько мест, где отсутствуют проверки на наличие ключа в массиве (спамит в лог предупрежденими);&lt;/li&gt;
&lt;li&gt;и даже одна уязвимость типа timing oracle.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Да, грязненький код — признак грязненьких мыслей :) Да, хорошо бы всё это почистить. Но за вычетом 3–4 претензий, это получается больше ста часов работы суммарно, а выхлоп — немножко более чистый код, причёсанное legacy, немножко меньше техдолга и warning/debug-записей в логе. Хорошо конечно, когда заказчик не против провести такую генеральную уборку. И честь и хвала аккаунтам, которые могут убедить заказчика в необходимости такой уборки при примерно нулевой ценности для конечного пользователя.&lt;/p&gt;
&lt;p&gt;А ощущения от таких отчетов по-прежнему странные. Вроде и находит что-то. Но суеты с этими отчетами пока куда больше, чем пользы.&lt;/p&gt;&lt;/div&gt;
</description>
  <pubDate>Wed, 22 Jul 2026 09:15:00 +0000</pubDate>
    <dc:creator>graker</dc:creator>
    <guid isPermaLink="false">2227 at https://graker.ru</guid>
    </item>
<item>
  <title>Смена Max API URL и сертификаты Минцифры</title>
  <link>https://graker.ru/news/2026/07/18/max-api-url-change-and-mincifry-certs</link>
  <description>&lt;div class=&quot;paragraph paragraph--text&quot;&gt;&lt;p&gt;Коллеги, если занимаетесь разработкой или просто завели ботов в Max, напоминаю, что с завтрашнего дня необходимо использовать новый URL для общения с API: &lt;code&gt;https://platform-api2.max.ru&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Кроме того, необходимо будет установить сертификаты Минцифры в доверенные на хост, так как новый URL апишки работает именно с этими сертификатами.&lt;/p&gt;
&lt;h3&gt;Как обновить сертификаты&lt;/h3&gt;
&lt;p&gt;В данных примерах я скачиваю сертификаты в &lt;code&gt;build/certs/&lt;/code&gt; потому что потом оттуда добавляю в докер-контейнеры, но вы можете скачать куда хотите.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Скачать актуальные файлы (официальный источник — &lt;code&gt;gu-st.ru&lt;/code&gt;, у него самого
сертификат подписан этим же УЦ, поэтому проверку приходится отключать флагом &lt;code&gt;-k&lt;/code&gt;):
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;curl -k -o build/certs/russian_trusted_root_ca.cer \
   &quot;https://gu-st.ru/content/Other/doc/russian_trusted_root_ca.cer&quot;
curl -k -o build/certs/russian_trusted_sub_ca.cer \
   &quot;https://gu-st.ru/content/Other/doc/russian_trusted_sub_ca.cer&quot;&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;Проверить, что скачалось что-то осмысленное (валидный сертификат, ожидаемый subject/issuer):
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;openssl x509 -in build/certs/russian_trusted_root_ca.cer -noout -subject -issuer -enddate
openssl x509 -in build/certs/russian_trusted_sub_ca.cer  -noout -subject -issuer -enddate&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Ожидаемый &lt;code&gt;subject&lt;/code&gt;/&lt;code&gt;issuer&lt;/code&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;root: &lt;code&gt;subject = issuer = C=RU, O=The Ministry of Digital Development and Communications, CN=Russian Trusted Root CA&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;sub: &lt;code&gt;subject = C=RU, ... CN=Russian Trusted Sub CA&lt;/code&gt;, &lt;code&gt;issuer = ... CN=Russian Trusted Root CA&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Я в &lt;code&gt;Dockerfile&lt;/code&gt; добавляю&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;COPY ./build/certs/russian_trusted_root_ca.cer /usr/local/share/ca-certificates/russian_trusted_root_ca.crt
COPY ./build/certs/russian_trusted_sub_ca.cer /usr/local/share/ca-certificates/russian_trusted_sub_ca.crt
RUN update-ca-certificates&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;и сертификаты встают в нужных контейнерах.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Также сертификаты можно скачать &lt;a href=&quot;https://www.gosuslugi.ru/crt&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;со страницы Госуслуг&lt;/a&gt;.&lt;/p&gt;&lt;/div&gt;
</description>
  <pubDate>Sat, 18 Jul 2026 10:40:00 +0000</pubDate>
    <dc:creator>graker</dc:creator>
    <guid isPermaLink="false">2225 at https://graker.ru</guid>
    </item>
<item>
  <title>Уведомления в Доктуристе</title>
  <link>https://graker.ru/news/2026/07/16/docturist-user-notifications</link>
  <description>&lt;div class=&quot;paragraph paragraph--text&quot;&gt;&lt;p&gt;Залили на &lt;a href=&quot;https://docturist.ru/news/notifications&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Доктурист&lt;/a&gt; внутрисистемные уведомления. В первую очередь работают внутри агентств, если кто-то добавил, поменял, удалил бронь, платеж, дедлайн, или статус поменял, остальным агентам (у которых есть доступ) приходит уведомление. Но и для соло-агентов — если они применяют интеграции с банком или сервисом подписания документов — тоже пригодятся.&lt;/p&gt;
&lt;p&gt;Уведомления приходят на иконку колокольчика, сопровождаются анимацией, полупрозрачной всплывашкой на 5 секунд, и нежным ненавязчивым «пыком» из динамика. Всплывашку и «пык» при желании можно отключить.&lt;/p&gt;
&lt;p&gt;Генеративные нейросети и код-агенты конечно позволяют ворочать значительно большими смысловыми блоками при разработке ПО. Первый предложенный вариант реализации был еще более массивным shotgun surgery, чем &lt;a href=&quot;https://t.me/graker_coding/566&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;прошлая фича&lt;/a&gt; — десятки изменений по 3–4 одинаковых строчки, утечки деталей реализации в контроллеры. 60+ измененных файлов (включая тесты). Предложил клоду более элегантное решение, практически без повторений, DI и event-driven, всё как в лучших домах Рио плюс де-Жанейро. Получилось решение более красивое, чистое как слеза Роберта Мартина — но уже на 100+ измененных файлов.&lt;/p&gt;
&lt;p&gt;Работает хорошо, надо бы теперь пуши к этому прикрутить. И выделить время, чтобы расписать в виде небольших кейсов.&lt;/p&gt;&lt;/div&gt;
</description>
  <pubDate>Thu, 16 Jul 2026 13:05:00 +0000</pubDate>
    <dc:creator>graker</dc:creator>
    <guid isPermaLink="false">2224 at https://graker.ru</guid>
    </item>
<item>
  <title>Виртуализация локальной разработки, docker-compose и traefik</title>
  <link>https://graker.ru/news/2026/06/25/local-dev-virtualization-docker-compose-and-traefik</link>
  <description>&lt;p&gt;Когда-то давно описывал &lt;a href=&quot;/news/2019/03/26/virtual-local-projects-in-docker&quot;&gt;довольно простой способ виртуализации проектов&lt;/a&gt;, над которыми работаю, чтобы было удобно переключаться и они друг другу не мешали. Прошло уже 7 лет и способ конечно эволюционировал. Когда-то использовать отдельные контейнеры, запускаемые по `docker run` было быстрее и удобнее и поэтому я докерфайлы и docker-compose-файлы не писал. Но прогресс конечно добрался до меня в этом вопросе и победил. Теперь я для локальной разработки тоже использую docker compose.&lt;/p&gt;
&lt;blockquote&gt;Инструментами со всякими пресетами типа lando или ddev я, тем не менее, стараюсь не пользоваться. В основном потому что когда с ними сталкивался, они нормально работали — до тех пор пока не надо было что-то в них поменять или сделать нестандартно. После чего начинался вынос мозга, иногда такой, что проще было самому пересобрать сразу.&lt;br&gt;
Кроме того, если собирать «чистые» окружения, есть шанс лучше понять, как это всё работает, а если пользоваться lando, forge, ddev и прочими — наоборот.&lt;/blockquote&gt;
&lt;p&gt;Итак, чем docker compose лучше.&lt;/p&gt;</description>
  <pubDate>Thu, 25 Jun 2026 15:20:00 +0000</pubDate>
    <dc:creator>graker</dc:creator>
    <guid isPermaLink="false">2220 at https://graker.ru</guid>
    </item>
<item>
  <title>Доктурист добавлен в интеграции Qui-Quo</title>
  <link>https://graker.ru/news/2026/06/15/docturist-qui-quo-integrations-listed</link>
  <description>&lt;div class=&quot;paragraph paragraph--text&quot;&gt;&lt;p&gt;Добрые люди из команды &lt;a href=&quot;https://qui-quo.ru/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Qui-Quo&lt;/a&gt;&amp;nbsp;— плагина без которого обходится мало какой уважающий себя турагент&amp;nbsp;— добавили наш &lt;a href=&quot;https://docturist.ru&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Доктурист&lt;/a&gt; в список интеграций.&lt;/p&gt;
&lt;p&gt;Теперь пользователям Доктуриста не нужно копировать в настройки интеграции загадочные адреса редиректов, а достаточно просто поставить галочку и интеграция заработает. Продолжаем развивать сервис!&lt;/p&gt;&lt;/div&gt;
</description>
  <pubDate>Sun, 14 Jun 2026 22:25:00 +0000</pubDate>
    <dc:creator>graker</dc:creator>
    <guid isPermaLink="false">2218 at https://graker.ru</guid>
    </item>
<item>
  <title>Интеграция Доктуриста с Точкой</title>
  <link>https://graker.ru/news/2026/06/09/tochka-bank-integration</link>
  <description>&lt;div class=&quot;paragraph paragraph--text&quot;&gt;&lt;p&gt;Турагенты могут вести десятки броней одновременно. Каждый день — новые оплаты от туристов, каждый день нужно вручную открыть банк, найти платёж, отметить в CRM оплату по туру (иначе как отслеживать что ничего не забыл?) Звучит как мелочь — но это копится ежедневно, сбивает с ритма и иногда порождает ошибки. И в целом это довольно нудно — переписывать руками из одного места в другое. А что нудно — нам делать не очень хочется.&lt;/p&gt;
&lt;p&gt;Поэтому мы добавили в &lt;a href=&quot;https://docturist.ru&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Доктурист&lt;/a&gt; возможность импорта платежей из банков и начали с интеграции API банка Точка. Здесь рассмотрим кейс о том, как подключили Точку к Доктуристу: сделали автоматические уведомления о платежах, умную привязку к бронированиям и создание платёжных ссылок прямо со страницы брони. И о нескольких нетривиальных вещах, с которыми пришлось разобраться по дороге. Технических и не очень.&lt;/p&gt;
&lt;h3&gt;Дано&lt;/h3&gt;
&lt;p&gt;Турагенты постоянно работают с деньгами, основных операций при этом две: принять (пред)оплату от туриста, отправить оплату оператору. Доктурист уже умеет вести историю платежей и показывать их в симпатичном таймлайне:&lt;/p&gt;&lt;/div&gt;
&lt;figure data-component-id=&quot;grakerru:figure&quot; class=&quot;figure figure--center figure--medium&quot;&gt;
      &lt;a href=&quot;/sites/default/files/uploads/2026-06/payments.png&quot; data-lightbox=&quot;node-2216&quot;&gt;
    &lt;img loading=&quot;lazy&quot; srcset=&quot;/sites/default/files/styles/content_medium/public/uploads/2026-06/payments.png.webp?itok=WkThDgBy 850w, /sites/default/files/styles/content_medium_2x/public/uploads/2026-06/payments.png.webp?itok=_Sug1HT4 1700w&quot; sizes=&quot;(min-width: 1200px) 850px, (min-width: 768px) 75vw, calc(100vw - 30px)&quot; width=&quot;850&quot; height=&quot;735&quot; src=&quot;/sites/default/files/styles/content_medium/public/uploads/2026-06/payments.png.webp?itok=WkThDgBy&quot; alt=&quot;payments.png&quot; /&gt;



&lt;/a&gt;
    &lt;/figure&gt;
&lt;div class=&quot;paragraph paragraph--text&quot;&gt;&lt;p&gt;&lt;strong&gt;Задача&lt;/strong&gt;: нужно сделать что-то более автоматизированное, чем старательно переписывать входящие платежи из банк-клиента. То есть получать входящие платежи в Доктуристе.&lt;/p&gt;
&lt;p&gt;Кроме того, агенты часто принимают оплату по ссылкам: создают в банковском приложении ссылку на оплату определенной суммы картой и/или СБП и отправляют туристу. Это такой облегченный эквайринг, когда можно не делать полноценную форму оплаты. И банк не против (если соблюсти определенные правила). &lt;strong&gt;Задача 2&lt;/strong&gt;: почему бы не дать пользователям возможность создавать ссылки на оплату прямо из интерфейса Доктуриста. Чтобы они могли копировать их и отправлять клиентам, а банковское приложение открывать было не нужно.&lt;/p&gt;
&lt;p&gt;Вот что конкретно мы научили Доктурист делать:&lt;/p&gt;
&lt;p&gt;— получать уведомления от банка о каждом входящем платеже;&lt;br&gt;
— автоматически привязывать платеж к бронированию (если это возможно);&lt;br&gt;
— давать пользователю привязывать платеж к бронированию вручную (если автоматически не вышло);&lt;br&gt;
— создавать ссылки на оплату картой и/или СБП.&lt;br&gt;&lt;/p&gt;
&lt;h3&gt;С чем столкнулись в процессе&lt;/h3&gt;
&lt;p&gt;Для входящих платежей Точка отправляет уведомления на зарегистрированные вебхуки, причем вебхуки регистрировать можно программно. Пользователю нужно лишь добавить токен для интеграции и проставить несколько разрешений в банк-клиенте. Уведомления по вебхукам приходят практически мгновенно.&lt;/p&gt;
&lt;h4&gt;Вебхуки как подписанный JWT&lt;/h4&gt;
&lt;p&gt;Первое, с чем пришлось разобраться — формат входящих уведомлений от банка. В отличие от сервисов, которые присылают простой JSON с подписью в заголовке, Точка отправляет тело вебхука целиком как &lt;em&gt;подписанный JWT.&lt;/em&gt; Это значит, что нельзя просто прочитать JSON — нужно сначала верифицировать подпись публичным ключом банка.&lt;/p&gt;
&lt;p&gt;Контроллер читает сырое тело запроса и декодирует JWT через библиотеку &lt;code&gt;firebase/php-jwt&lt;/code&gt;:&lt;/p&gt;&lt;/div&gt;
&lt;pre data-component-id=&quot;grakerru:code-block&quot; class=&quot;code-block language-none&quot;&gt;&lt;code class=&quot;language-none&quot;&gt;$token = $request-&amp;gt;getContent();
$pem   = config(&amp;#039;services.tochka.jwt_public_key_pem&amp;#039;);
$data  = JWT::decode($token, new Key($pem, &amp;#039;RS256&amp;#039;));&lt;/code&gt;&lt;/pre&gt;
&lt;div class=&quot;paragraph paragraph--text&quot;&gt;&lt;p&gt;При любой ошибке декодирования — логируем и тем не менее отвечаем http 200. Это важно: Точка интерпретирует любой не-200 как сбой и будет повторно доставлять уведомление. А так — бизнес-логика не выполняется, но и банк не уходит в цикл отправки.&lt;/p&gt;
&lt;p&gt;Тестирование этой механики потребовало отдельных настроек инфраструктуры: RSA-пара генерируется прямо в тестовом классе, публичный ключ подставляется в конфиг, и тогда мы подписываем тестовый пейлоад так же, как это делает Точка и расшифровываем как живое приложение.&lt;/p&gt;
&lt;h4&gt;Умная авто-линковка&lt;/h4&gt;
&lt;p&gt;Когда платёж приходит от банка, система пытается найти бронь автоматически — по тексту назначения платежа (например, «Оплата по бронированию ДЕМ-001»). Здесь возникает классическая проблема строкового поиска: если в агентстве есть брони &lt;code&gt;ДЕМ-10&lt;/code&gt; и &lt;code&gt;ДЕМ-100&lt;/code&gt;, то поиск &lt;code&gt;ДЕМ-10&lt;/code&gt; найдёт обе. Но мы не хотим ошибиться при связи броней с платежами, поэтому автоматически связываем только если найден ровно 1 результат.&lt;/p&gt;
&lt;p&gt;Если есть хотя бы еще одна бронь, чей номер начинается с найденного — линковка не происходит, платёж остаётся непривязанным. Пользователь увидит его в ленте и привяжет вручную. Для удобства привязки, поиск отфильтровывает старые, выполненные, оплаченные и отмененные брони.&lt;/p&gt;
&lt;h4&gt;Очень умная авто-линковка&lt;/h4&gt;
&lt;p&gt;Чтобы пользователи не забывали включать в назначение платежа номер брони, сделали, чтобы дефолтный текст при генерации платежной ссылки уже включал номер. Но боевое использование показало, что почти все платежи проходят мимо и ни с чем не линкуются.&lt;/p&gt;&lt;/div&gt;
&lt;figure data-component-id=&quot;grakerru:figure&quot; class=&quot;figure figure--center figure--medium&quot;&gt;
      &lt;a href=&quot;/sites/default/files/uploads/2026-06/payments_bank.png&quot; data-lightbox=&quot;node-2216&quot;&gt;
    &lt;img loading=&quot;lazy&quot; srcset=&quot;/sites/default/files/styles/content_medium/public/uploads/2026-06/payments_bank.png.webp?itok=YzndABJ9 850w, /sites/default/files/styles/content_medium_2x/public/uploads/2026-06/payments_bank.png.webp?itok=P7ZaOJBw 1470w&quot; sizes=&quot;(min-width: 1200px) 850px, (min-width: 768px) 75vw, calc(100vw - 30px)&quot; width=&quot;850&quot; height=&quot;697&quot; src=&quot;/sites/default/files/styles/content_medium/public/uploads/2026-06/payments_bank.png.webp?itok=YzndABJ9&quot; alt=&quot;payments_bank.png&quot; /&gt;



&lt;/a&gt;
    &lt;/figure&gt;
&lt;div class=&quot;paragraph paragraph--text&quot;&gt;&lt;p&gt;После некоторых исследований оказалось, что хотя платежи в банк-клиенте показываются с нормальным назначением типа &lt;em&gt;Оплата тура ФИО, номер брони&lt;/em&gt;, как мы задумали, в вебхук почему-то вместо этого прилетает &lt;em&gt;Оплата по QR-коду ID QRABCD12345678 …&lt;/em&gt;. Пришлось реализовать дополнительный метод из API, который при получении платежа с таким описанием дергает Точку еще раз, чтобы получить инфу о данном QR-коде. В этой информации назначение платежа уже правильно отражается и по нему можно линковать платеж к брони.&lt;/p&gt;
&lt;h4&gt;Валютная конвертация при привязке&lt;/h4&gt;
&lt;p&gt;Точка естественно присылает суммы в рублях, поскольку расчёты в России могут быть только рублевые. Но брони в Доктуристе могут быть заведены и в USD, и в EUR, так как туроператоры могут работать в этих единицах, а платежи принимать по курсу. Когда пользователь вручную привязывает рублёвый платёж к заявке в EUR, система должна рассчитать сумму в EUR, чтобы записать её в правильной валюте. При этом у каждого туроператора свой курс конвертации.&lt;/p&gt;
&lt;p&gt;Для этих случаев сделали два сценария:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Валютная заявка + override&lt;/strong&gt;&amp;nbsp;→ пользователь вводит вручную, какое количество USD/EUR получается из платежа (например, «150 EUR»), мы используем это значение в сохраняемом платеже по брони и вместе с ним сохраняем расчетный курс валюты.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Валютная заявка, без override&lt;/strong&gt;&amp;nbsp;→ берём последний курс ЦБ (он обновляется каждый день). В таком случае мы отмечаем связанный платеж как требующий внимания, поскольку авторасчет по курсу ЦБ это &lt;em&gt;примерный&lt;/em&gt; расчет, а курс у операторов всегда выше.&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;Дефолтные значения при создании платежных ссылок&lt;/h4&gt;
&lt;p&gt;В процессе использования интеграции оказалось, что во многих случаях пользователи хотят создавать платежные ссылки с одним и тем же пресетом, например «Карта выключена, СБП включен». Ошибка в выборе средства оплаты может привести к денежным потерям (комиссия банка на эквайринге и СБП очень разная), что конечно недопустимо. &lt;/p&gt;&lt;/div&gt;
&lt;figure data-component-id=&quot;grakerru:figure&quot; class=&quot;figure figure--center figure--medium&quot;&gt;
      &lt;a href=&quot;/sites/default/files/uploads/2026-06/payment_links.png&quot; data-lightbox=&quot;node-2216&quot;&gt;
    &lt;img loading=&quot;lazy&quot; srcset=&quot;/sites/default/files/styles/content_medium/public/uploads/2026-06/payment_links.png.webp?itok=BPA-XiWv 850w, /sites/default/files/styles/content_medium_2x/public/uploads/2026-06/payment_links.png.webp?itok=AW8FCDqT 1697w&quot; sizes=&quot;(min-width: 1200px) 850px, (min-width: 768px) 75vw, calc(100vw - 30px)&quot; width=&quot;850&quot; height=&quot;220&quot; src=&quot;/sites/default/files/styles/content_medium/public/uploads/2026-06/payment_links.png.webp?itok=BPA-XiWv&quot; alt=&quot;payment_links.png&quot; /&gt;



&lt;/a&gt;
    &lt;/figure&gt;
&lt;div class=&quot;paragraph paragraph--text&quot;&gt;&lt;p&gt;Пришлось реализовать дефолтную настройку для пользователей, указывающую, какие способы оплаты по умолчанию включены и какие выключены, чтобы снизить вероятность ошибки.&lt;/p&gt;
&lt;h4&gt;Песочница&lt;/h4&gt;
&lt;p&gt;В самом начале разработки из документации на API Точки выяснилось, что у них нет полноценной песочницы, позволяющей проводить «игрушечные» платежи, есть только фиксированный набор тестовых запросов, которые, если сделаны верно, возвращают фиксированные ответы. Тестовые запросы конечно небесполезны, но без песочницы невозможно, например, провести полный тестовый цикл: генерация платежной ссылки → её оплата → получение платежа → разбор и линковка к брони. Только по частям.&lt;/p&gt;
&lt;p&gt;Собственно, создание ссылок пришлось по большей части тестировать наживую, поскольку оно работает только на аккаунтах, для которых уже активирован эквайринг, а для остальных аккаунтов кидает ошибку 403 &quot;Forbidden by consent&quot;.&lt;/p&gt;
&lt;p&gt;Но зато в банке есть линия поддержки по интеграции API, которая действительно отвечает по имейлу и даже дает подробную информацию, которой в документации не нашлось.&lt;/p&gt;
&lt;h3&gt;Результаты&lt;/h3&gt;
&lt;p&gt;100+ тестов на разные случаи жизни. Мы сделали верификацию JWT-подписи, дедупликацию, авто-линковку с граничными случаями, валютную конвертацию, права доступа. Интеграция API работает с Laravel Horizon, то есть все входящие и исходящие процессы (уведомления о платежах, создание платежной ссылки, регистрация пользователя в системе, регистрация вебхуков) запускаются асинхронно в очередях. А для уведомления ожидающих пользователей используются &lt;a href=&quot;/news/2026/01/20/laravel-reverb-broadcasting-and-websockets&quot;&gt;вебсокеты через Reverb&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Реализация позволила создать и протестировать логику для импорта платежей и создания платежных ссылок, которая не обязана привязываться к одному банку. Теперь необходимо добавить уровень абстракции между платежами/ссылками и API банка, и можно подключать другие банки к системе уже с меньшими трудозатратами. Следующий кандидат на интеграцию — Альфа.&lt;/p&gt;
&lt;p&gt;Интеграция уже работает в продакшене. Агенты создают платёжные ссылки прямо со страницы брони и отправляют их туристам — без переключения в банковское приложение. Входящие платежи появляются в системе автоматически и в большинстве случаев сами привязываются к нужному бронированию. Руками нужно разбирать только то, что система не смогла распознать однозначно.&lt;/p&gt;&lt;/div&gt;
</description>
  <pubDate>Mon, 08 Jun 2026 22:30:00 +0000</pubDate>
    <dc:creator>graker</dc:creator>
    <guid isPermaLink="false">2216 at https://graker.ru</guid>
    </item>
<item>
  <title>Claude Mythos и уязвимости в Symfony</title>
  <link>https://graker.ru/news/2026/05/25/claude-mythos-symfony-security</link>
  <description>&lt;div class=&quot;paragraph paragraph--text&quot;&gt;&lt;p&gt;На днях в новостях &lt;a href=&quot;https://symfony.com/blog/claude-mythos-audited-symfony-and-found-19-vulnerabilities&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;сообщили&lt;/a&gt;, что разработчики Symfony закрыли 19 уязвимостей, найденных моделью Claude Mythos Preview. Что особенно интересно:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A few days later, and following &lt;a href=&quot;https://symfony.com/doc/current/contributing/code/security.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Symfony&#039;s security disclosure process&lt;/a&gt;, we received a ZIP file with all their findings. In total, Claude Mythos reported &lt;strong&gt;19 security vulnerabilities&lt;/strong&gt; in Symfony and Twig codebases. The Symfony Core Team reviewed every report manually, and all 19 findings turned out to be real vulnerabilities, with &lt;strong&gt;no false positives&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;ни одного ложноположительного результата.&lt;/p&gt;
&lt;p&gt;Раньше я уже сталкивался с AI-отчетами по безопасности разных web-проектов. Обычно коллеги, или даже заказчики присылали для изучения и доработки. Тогда эти отчеты состояли из ложноположительных срабатываний чуть менее чем полностью. Но даже так затраченное на изучение отчета время того стоило: за 20 «ненастоящими» уязвимостями находилась одна-две-три актуальных. Что само по себе круто, ведь теперь можно их самому не искать, достаточно отсеять из отчета всякую фигню.&lt;/p&gt;
&lt;p&gt;А тут — почти два десятка подтвержденных дырок и ни одной ошибки. И хотя Claude Mythos Preview еще не доступен каждому простолюдину — идет закрытое тестирование — это, видимо, успешный успех.&lt;/p&gt;
&lt;p&gt;Что тут можно сказать. В наши дни нужно внимательно, ещё внимательнее относиться к регулярным обновлениям ваших программ, пакетов, фреймворков. Claude Mythos Preview может быть доступен и не всем, но исследовать код программы на уязвимости с помощью Claude Code уже сейчас может любой. И на входе не спрашивают, с какими намерениями. &lt;/p&gt;
&lt;p&gt;А находить уязвимости умеет и он: XSS, утечки API-токенов, idorы всякие, господипрости. Так что был бы инструмент для поиска, а дырочка найдется. Как говорил нам классик, — &lt;em&gt;There is a crack in everything. That&#039;s how the light gets in.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Будем бдительны.&lt;/p&gt;&lt;/div&gt;
</description>
  <pubDate>Mon, 25 May 2026 07:00:00 +0000</pubDate>
    <dc:creator>graker</dc:creator>
    <guid isPermaLink="false">2214 at https://graker.ru</guid>
    </item>
<item>
  <title>Критичное обновление безопасности в Drupal</title>
  <link>https://graker.ru/news/2026/05/19/drupal-highly-critical-update</link>
  <description>&lt;div class=&quot;paragraph paragraph--text&quot;&gt;&lt;p&gt;Как понять, что у какого-то проекта клёвая инфраструктура?&lt;/p&gt;
&lt;p&gt;Ты прочитал письмо в рассылке, что у проекта через несколько дней выйдет обновление безопасности. Добавил в календарь, чтоб не забыть обновить всё и всех. Потом получил письмо СРОЧНО ВАЖНО от одного хостера. Потом от другого и третьего. Всё про это обновление безопасности.&lt;/p&gt;
&lt;p&gt;Потом прочитал напоминание в тематическом телеграм-канале. Потом ожили коллеги в джире, каждый тоже написал о будущем обновлении. Вслед за коллегами ожили клиенты: они тоже получили уведомления от своих хостеров и теперь переживают. В общем ВСЕ уже знают, что у Друпала завтра вечером выйдет патч безопасности. Все знают, все готовятся.&lt;/p&gt;
&lt;p&gt;Так что и я глаголю вам: да, завтра с 17 до 21 UTC должен выйти патч безопасности Drupal 10 и 11, вот &lt;a href=&quot;https://www.drupal.org/psa-2026-05-18&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;страничка&lt;/a&gt; об этом. Обновление обозначено как высоко критичное, набрало 20 из 25 баллов по шкале трэша, угара и содомиии рисков безопасности. В воздухе запахло озоном, на теле заныли шрамы, полученные в ходе Друпалгеддона I и II.&lt;/p&gt;
&lt;p&gt;Обновляйтесь, друзья, как можно скорее — это нужно. А если вы хотите сначала посмотреть, чо там будет, ответственно заявляю: всегда лучше обновиться, и посмотреть, чо там будет с теми, кто не стал, чем наоборот ;)&lt;/p&gt;
&lt;p&gt;И да — вот такая клёвая инфраструктура сейчас у Drupal. Отдельная рассылка по обновлениям безопасности. Команда, которая этими дырками занимается. Проверки дырочек не только в ядре, но и в контрибных модулях. Патчи выкладываются в определенный день с предварительным уведомлением.&lt;/p&gt;
&lt;p&gt;И да — Drupal при этом совершенно бесплатный.&lt;/p&gt;&lt;/div&gt;
</description>
  <pubDate>Tue, 19 May 2026 18:05:00 +0000</pubDate>
    <dc:creator>graker</dc:creator>
    <guid isPermaLink="false">2212 at https://graker.ru</guid>
    </item>
<item>
  <title>С днём рождения, Нетспарк!</title>
  <link>https://graker.ru/news/2026/04/25/happy-birthday-netspark</link>
  <description>&lt;div class=&quot;paragraph paragraph--text&quot;&gt;&lt;p&gt;Между прочим, нашему маленькому, но гордому юрлицу, нашей студии &lt;a href=&quot;https://netspark.ru/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;NetSpark&lt;/a&gt; исполняется сегодня 14 лет.&lt;/p&gt;
&lt;p&gt;По этому случаю вот новый субботний нейрослоп, который называется WSOD.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&quot;paragraph paragraph--embed&quot;&gt;&lt;iframe class=&quot;center-block&quot; width=&quot;100%&quot; height=&quot;405&quot; src=&quot;https://rutube.ru/play/embed/7044673332e02f139867badb2d59560e/?skinColor=d57700&quot; style=&quot;border: none;&quot; allow=&quot;clipboard-write; autoplay&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;&lt;/div&gt;
&lt;div class=&quot;paragraph paragraph--text&quot;&gt;&lt;p&gt;С днём рождения, Нетспарк!&lt;/p&gt;
&lt;p&gt;Канал «Культурный вайбкод»&lt;br&gt;
— &lt;a href=&quot;https://vkvideo.ru/@club237133639&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;в ВК&lt;/a&gt;&lt;br&gt;
— &lt;a href=&quot;https://rutube.ru/channel/43764662/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;в RuTube&lt;/a&gt;&lt;br&gt;
— &lt;a href=&quot;https://www.youtube.com/@CultureVibecode&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;в YouTube&lt;/a&gt;&lt;br&gt;&lt;/p&gt;&lt;/div&gt;
</description>
  <pubDate>Sat, 25 Apr 2026 15:00:00 +0000</pubDate>
    <dc:creator>graker</dc:creator>
    <guid isPermaLink="false">2208 at https://graker.ru</guid>
    </item>
<item>
  <title>Про пакет Canvas в Laravel</title>
  <link>https://graker.ru/news/2026/04/16/laravel-canvas-package</link>
  <description>&lt;div class=&quot;paragraph paragraph--text&quot;&gt;&lt;p&gt;Когда готовил &lt;a href=&quot;https://docturist.ru&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Доктурист&lt;/a&gt; к открытию, решил что должна быть все-таки у проекта какая-никакая новостная лента. До этого я сделал самый примитивный вариант: вывод ленты заголовков и текстовых сообщений с датами.  &lt;/p&gt;
&lt;p&gt;Решил, что этого конечно мало и какой-никакой джентльменский набор функций для постинга надо иметь. Хотя бы:&lt;br&gt;
— редактор с форматированием и загрузкой картинок&lt;br&gt;
— рубрики и/или теги&lt;br&gt;
— редактируемые адреса страниц&lt;br&gt;
— минимальную админку, чтобы из панели Orchid туда заходить&lt;br&gt;&lt;/p&gt;
&lt;p&gt;Конечно, писать я все это не хотел. Точнее я может и хотел бы, но каждый день старался сокращать число задач до запуска, а не увеличивать. Стал смотреть готовое.  &lt;/p&gt;
&lt;p&gt;Поиск и чат жопотэ присоветовали пакет &lt;a href=&quot;https://github.com/austintoddj/canvas/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Canvas&lt;/a&gt; для Laravel, его и взял. Редактор Quill внутри, небольшая админка на Vue.js с тёмной темой, есть немного лишних приблуд типа счётчика просмотров, есть базовое SEO, топики и теги. В общем, достаточно, чтобы не делать самому.  &lt;/p&gt;
&lt;p&gt;Прикрутил SSO, чтобы отдельно в эту админку не логиниться. Немного смутило, что в последнее время пакет не поддерживается. Но для ограниченного применения — ленты новостей и страниц документации — хватит. Стал пользоваться.  &lt;/p&gt;
&lt;p&gt;В процессе, правда, оказалось что админка почему-то не дружит с транслитом и не генерирует слаги с русскоязычных заголовков. Да вдобавок не даёт писать слаги для тегов и топиков самому: поле слага зачем-то блокируется во фронте, хотя бэк не против принять ручной ввод.  &lt;/p&gt;
&lt;p&gt;Взял Клода под мышку и пошёл это недоразумение исправлять. Клод говорит — смотри, эта фигня только во фронте, сейчас пару контролов попатчим, через композер патчи подключим, пересоберем и вуаля.  &lt;/p&gt;
&lt;p&gt;Стали делать — чото не работает, патченые контролы не собираются. И тут Клод такой: Je m&#039;en fous, не патчатся исходники — я тебе попатчу билд! И написал скрипт на питоне, который транслит и ручные слаги просто втыкает в минифицированный джаваскипт. И прописал в пост-инсталл скрипты композера.&lt;/p&gt;
&lt;p&gt;И я ведь как раз это недавно упоминал в &lt;a href=&quot;/news/2026/04/08/robots-code-we-take-responsibility&quot;&gt;статье про вайбкодинг&lt;/a&gt;. Машине всё равно, минимизирован код или нет, она его прочитает. Прочитает, воткнёт питоньим скриптом ещё нечитаемого кода, который через месяц никто не поймёт уже что делает, и будет такова. А для нас это неподдерживаемый код, которым ситуативно, в краткосрочной перспективе можно попользоваться (и я попользуюсь конечно). Но в долгосрочной надо форкать этот Canvas. Тем более редактор Quill в него так крепко встроен, что если я захочу кнопочек добавить в панель и плагинов всяких — всё равно придётся.&lt;/p&gt;
&lt;p&gt;А в остальном, пакет пригодный, если не хочется ставить целую CMS, или руками весь процесс публикаций создавать в админ-панели. Накатал в Канвасе уже несколько страниц документации для проекта, и продолжу пользоваться.&lt;/p&gt;
&lt;p&gt;P.S. Ещё недавно на другом проекте поработал с &lt;a href=&quot;https://www.bookstackapp.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;BookStack&lt;/a&gt; — прикольным wiki-решением для документации. Но оно для моих целей чересчур. И к тому же не прокатывает как ещё одна зависимость: её надо на отдельный сабдомен втыкать. И композером не обновляется — авторы предлагают обновления через git pull ставить.&lt;/p&gt;&lt;/div&gt;
</description>
  <pubDate>Thu, 16 Apr 2026 07:00:00 +0000</pubDate>
    <dc:creator>graker</dc:creator>
    <guid isPermaLink="false">2206 at https://graker.ru</guid>
    </item>
<item>
  <title>Код пишут роботы, но отвечать за него нам</title>
  <link>https://graker.ru/news/2026/04/08/robots-code-we-take-responsibility</link>
  <description>&lt;p&gt;В последнее время все чаще и больше в разработке использую генеративные нейросети в агентском режиме, для простоты будем называть это как все, вайб-кодингом. Ну а чего? Сейчас каждый утюг и его бабушка вайб-кодят и рассказывают о том, как это стало здорово. И в плане доступа к разработке тех, кто раньше разрабатывать не умел, это, кстати, действительно здорово.&lt;/p&gt;
&lt;p&gt;Но кто и раньше умел разрабатывать сам, всё-таки смотрит на предмет немножко под другим углом. Поэтому решил немного растечься мыслями, поворчать, позанудствовать и поразмышлять не о том, как настроить Codex, MCP-сервер, или натравить Claude Code на KWork. А об эффектах, о неизбежных изменениях, которые внесли, вносят и будут вносить в нашу повседневную работу — в разработку программного обеспечения живыми человеческими людьми — нейросети.&lt;/p&gt;
&lt;blockquote&gt;Сначала коротко определим наше место в пространстве и времени относительно самого феномена нейросетей (здесь и далее — в разработке ПО). Обсуждать, нужны ли они, помогают ли они, следует ли их использовать — уже поздно. Этот вопрос больше не стоит. Если вдруг еще не начали, надо начать. Кот смотрит на часы и говорит — Пора!&lt;/blockquote&gt;</description>
  <pubDate>Wed, 08 Apr 2026 08:20:00 +0000</pubDate>
    <dc:creator>graker</dc:creator>
    <guid isPermaLink="false">2202 at https://graker.ru</guid>
    </item>
<item>
  <title>Доктурист — CRM и документооборот для турагентов</title>
  <link>https://graker.ru/news/2026/03/29/docturist-touristic-crm-registration-open</link>
  <description>&lt;div class=&quot;paragraph paragraph--text&quot;&gt;&lt;p&gt;Ну что ж, прошло несколько лет, ковидов, и других катаклизмов — и я открыл-таки регистрацию в нашей туристической crmке, которая называется &lt;a href=&quot;https://docturist&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Доктурист&lt;/a&gt;. Ура!&lt;/p&gt;
&lt;p&gt;За последние месяцы была добавлена куча функций, без которых, как мне кажется, нельзя было запускать сервис. В моем списке таких функций еще очень много, но это ведь как ремонт — хочется сделать ещё вот это и вон то, а уж потом… В общем, в какой-то момент добавление фич можно было только приостановить для запуска. Последнее обновление, которое я выкатил сегодня ночью, готовилось 2 месяца и распухло до размеров небольшой планеты. В нём, в частности, была наконец открыта регистрация — так что теперь любой турагент может зайти и зарегистрироваться.&lt;/p&gt;
&lt;p&gt;Теперь можно вернуться в нормальный режим постепенной подготовки и накатывания обновлений. По чуть-чуть, но непрерывно, добавлять, улучшать, допиливать и даже переделывать. Как оно и должно было быть у нормального программного обеспечения. Continuous integration, continuous delivery. Continuous joy.&lt;/p&gt;
&lt;p&gt;В ближайшее время на очереди — открытие раздела статистики и подключение сервиса оплаты картами (сейчас пока можно только запросить счёт для оплаты по реквизитам).&lt;/p&gt;
&lt;p&gt;По технической части (у нас же здесь технический бложек) Доктурист — это Laravel, Vue.js, Redis / Horizon / Supervisor для очередей, Reverb для вебсокетов, Pulse для быстрого ревью чо-как в системе, Canvas для новостей и статей, и ~1000 тестов по методике TDD для лучшей поддерживаемости. Vue.js используется версии 2. Прежде чем пытаться апгрейдить фронт на 3 (серьезная работа) — нужно было довести до ума что есть. В конце концов, я только в прошлом году апнул &lt;a href=&quot;/news/2025/07/21/upgrade-from-laravel-5-to-laravel-12&quot;&gt;Laravel с 5 до 12&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;В общем, если вы турагент, добро пожаловать! На сайте &lt;a href=&quot;https://docturist.ru&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://docturist.ru&lt;/a&gt; есть также ссылки на телеграм-канал и чатик. А если нет — можете просто за меня немножко порадоваться. Не каждый день удается отбросить сомнения и все-таки запустить проект, который &lt;a href=&quot;/news/2025/07/03/touristic-crm&quot;&gt;начал делать&lt;/a&gt; еще в прошлом десятилетии. Есть повод порадоваться.&lt;/p&gt;&lt;/div&gt;
</description>
  <pubDate>Sun, 29 Mar 2026 12:05:00 +0000</pubDate>
    <dc:creator>graker</dc:creator>
    <guid isPermaLink="false">2199 at https://graker.ru</guid>
    </item>

  </channel>
</rss>
