Путь айтишника
130 subscribers
865 photos
1 file
482 links
Путь становления айтишника глазами практикующего специалиста. Личный опыт, полезные инструменты, разбор технологий, план развития и взгляд на индустрию изнутри.
Download Telegram
От дебага звонка до собственной игры в Telegram. Иногда кажется, что рабочий день - это просто череда мелких задач. А
потом внезапно понимаешь: ты уже три часа дебажишь звонок, который «не
идёт».

Asterisk и звонок напрямую
На работе столкнулся с занятной историей. Не мог позвонить на сотовый
номер по определённому транку. Перебрал параметры, покрутил настройки
- тишина.

В какой-то момент нашёл простое, но неожиданное решение для
тестирования: звонить прямо из командной строки.

 bash
asterisk -rx "channel originate SIP/89876543210@beeline application Playback demo-congrats"


Команда инициирует вызов и проигрывает файл. Никакой магии - просто
прямой вызов в Asterisk.

В итоге всё-таки дозвонился. Иногда лучший способ понять, что происходит
внутри, --- убрать всё лишнее и пойти напрямую.

Бэкап виртуальной машины в Proxmox
Ещё одна хитрая задача --- виртуальная машина в Proxmox с двумя дисками:
системный (Debian) и большой диск под бэкапы (scsi1). Нужно было сделать
резервную копию только системного диска.

Решение оказалось элегантным: остановить ВМ, временно удалить второй
диск из конфигурации, выполнить обычный бэкап через vzdump, а затем
вернуть диск обратно.

 bash
qm stop 100
qm set 100 --delete scsi1
vzdump 100 --mode stop --storage local --compress zstd
qm set 100 --scsi1 san01_lun1:0.0.1.scsi-3600000000000000000e0000000040001
qm start 100


В архив попадёт только первый диск. Минимум шаманства - максимум
контроля.

Memento mori - игра для Telegram
Параллельно начал делать свою HTML5‑игру для Telegram. Назвал её
«Memento mori».
Это небольшая казуальная игра на тренировку памяти: открываешь пары
карточек и стараешься уложиться в минимальное число ходов. Решил сделать
её в готической эстетике --- вампиры, скелеты, мрачная палитра. Почему
бы и нет.
Когда декомпозировал задачу, понял масштаб.

Что нужно собрать
- Telegram‑бот для запуска Mini App.
- Backend с авторизацией через Telegram и хранением пользователей и
результатов.
- Frontend с двумя сценами и игровым полем на Phaser.
- Лендинг для тех, кто зайдёт не из Telegram.
- CI/CD через GitLab, Docker Compose и SSL.
- Claude AI для помощи в разработке.
По отдельности всё выглядит просто. Вместе - уже задача со звёздочкой.

И самое забавное: взаимодействие с игровым движком - процентов десять
от общего объёма работ. Основное время уходит на инфраструктуру,
авторизацию, деплой и окружение.
Фронтенд и бэкенд решил писать на Next.js - один репозиторий, проще
отлаживать и поддерживать.

С Phaser поразбирался отдельно. Для React он ощущается как чёрный ящик.
Всё рисуется на Canvas. А Canvas - это просто растровое полотно:
браузер не знает ни про кнопки, ни про спрайты. Есть только картинка.
Нужно изменить сцену - перерисовываешь всё целиком.

Если нужно из React «достучаться» до игры - используешь ref.
Если из Phaser передать что-то наружу - EventEmitter.
Очень напоминает работу с фреймами в старые добрые времена.

Пока показать из кода особо нечего - только репозиторий:
https://gitlab.com/orion55/memento
Но картинки для двух уровней уже сгенерировал с помощью ChatGPT.

Чем дальше вникаю, тем яснее вижу: игра - это не про спрайты. Это про
архитектуру, окружение и десятки маленьких решений, которые должны
сойтись в одну систему. Дорогу осилит идущий.
❤1👍1
Продолжаю делать компьютерную HTML5-игру для Telegram «Memento mori» https://gitlab.com/orion55/memento

Небольшая казуальная штука на память: открываешь карточки, ищешь пары и стараешься уложиться в минимальное количество ходов.

Решил писать её вместе с AI Claude. И вот тут началось интересное. Я попросил реализовать авторизацию через Telegram и сохранение пользователей в базу --- фича сложная, многоступенчатая. Claude справился. Не с первого раза, но в целом достойно.

А потом я попросил написать API для таблицы лидеров - и начался цирк. Сначала мне предложили двухуровневый кэш: промежуточную таблицу в PostgreSQL плюс Redis. При том, что это пет-проект и трафика там кот наплакал. Попросил упростить - без Redis и без лишних сущностей. Тогда появилось материализованное представление. Объяснить, что мне нужен обычный SQL-запрос с нормальными индексами, удалось далеко не сразу.

В какой-то момент стало ясно: дело не в модели, а в ТЗ. Без нормальной постановки задачи результат получается соответствующий. Старая истина подтвердилась --- без ТЗ результат ХЗ. В итоге почти всю неделю писал документацию к проекту: формализовал входы, выходы, граничные случаи. Почувствовал себя бизнес-аналитиком.

Потом решил пойти дальше --- создал саб-агента в Claude, который делает код-ревью. И внезапно выяснилось, что только что написанный код таблицы лидеров содержит уязвимости. Отдельный квест - актуальность знаний. Последнюю версию NextJS Claude знает не лучшим образом, поэтому подключил Model Context Protocol (MCP)-сервер Context7 https://github.com/upstash/context7 Он подтягивает свежую документацию и сильно помогает.

В итоге, чтобы получить от Claude Code «просто нормальный код среднего уровня», приходится строить мини-фабрику: MCP-серверы, субагенты, маршрутизацию контекста, правила. Ты вроде просил фичу, а в итоге проектируешь среду, в которой она вообще может быть сгенерирована. И быстро понимаешь: всё упирается не в хитрые промпты, а в качественный бизнес-анализ и документацию. Пока не описаны процессы, границы, исключения и критерии «готово», агент будет уверенно ехать в разные стороны.

По ощущениям это уже чистое метапрограммирование. Ты не пишешь код --- ты строишь систему, которая пишет код. И это неожиданно похоже на generic'и: не «сделай Х», а «сделай механизм, который стабильно делает Х при разных входах». Самой сложной частью оказывается не генерация, а проектирование условий, в которых она становится предсказуемой.
👍9
Продолжаю делать компьютерную HTML5‑игру для Telegram «Memento mori». Неделя прошла не в геймдеве, а в тихой и упрямой войне под названием DevOps. Проект мало написать — его нужно доставить на удалённый сервер, который живёт 24/7 и не интересуется твоим вдохновением.

В качестве CI/CD я использую GitLab. Он получает код, по кнопке собирает Docker‑образы, складывает их в свой registry и запускает команды на удалённом сервере, чтобы вытянуть свежие образы и перезапустить контейнеры. Схема известная и рабочая. Но дьявол, как обычно, в нюансах: права, зависимости, мелкие несостыковки, которые съедают часы и нервы.

В 2026 году использовать Nginx как реверс‑прокси уже выглядит странно. OpenSource‑версия фактически умерла, активное развитие уехало в коммерческую сторону. Русская команда сделала форк и назвала его Angie https://angie.software/ — по сути, тот же Nginx, но с новыми модулями: Brotli, защита от DDoS, поддержка HTTP/3 и главное — модуль ACME.

Раньше всё было просто и муторно одновременно. Нужен SSL — ставишь certbot, получаешь бесплатный сертификат от Let’s Encrypt, через 90 дней обновляешь. Certbot в cron, то работает, то нет. И в какой‑то момент сайт внезапно с просроченным сертификатом. Мелочь, а геморроя вагон. В Angie модуль ACME берёт это на себя — сам получает и продлевает сертификаты, нужно только один раз грамотно настроить. Вот хороший видеоурок «Автоматические TLS‑сертификаты: модуль ACME» https://www.youtube.com/watch?v=ywJQ25tDwaY

И тут я решил усложнить себе жизнь — купить VPS в Латвии. Поднял сервер на 80‑м порту, подключил домен, всё заработало с первого раза. Почувствовал себя победителем. Но как только получил сертификат и включил 443 порт — сайт умер. Я перелопатил конфиги Angie, сетевые настройки, проверил TLS руками через openssl, убил кучу времени. А потом выяснилось, что Роскомнадзор активно режет зарубежные хостинги по 443 порту — в поисках сервисов из трёх букв, которые нельзя называть. Перенёс проект на хостинг в Санкт‑Петербург — и всё заработало мгновенно. Борьба идёт, но явно не с теми.

Вот сайт проекта https://mementus.ru/, а вот бот https://t.me/memento_mori_game_bot. Пока это даже не бета, а скорее заглушка, но фундамент уже стоит.

Смысл этой игры — не деньги, а прокачка навыков программиста и DevOps. Есть золотое правило: внедрять за раз одну новую технологию, а остальное держать старым и проверенным. Я же умудрился параллельно учить NextJS, Phaser, Angie и Claude AI. Вероятность не довести проект до конца при таком наборе растёт не линейно, а умножается. Технологии могут быть модными, но проблемы никуда не исчезают — их просто красиво асфальтируют маркетингом.

На работе, как только я рассказал про игру, посыпались вопросы. «А что будет, когда Telegram отключат?» — пока его собираются не отключать, а замедлять и отпиливать функции. Даже если полностью прикроют, технически переехать в VK или куда‑то ещё не проблема. Технической разницы почти нет.

«Сколько заработаешь?» — нисколько. Это pet‑проект. Чтобы зарабатывать, надо сначала понимать, кому ты продаёшь, какие у людей боли и за что они готовы платить. Игры для детей, подростков и взрослых — это три разных мира. А в простых головоломках уровня “три в ряд” конкуренция такая, что без продуманной стратегии туда лучше не лезть.

«Когда выйдет в Steam?» — никогда. Там и без меня 80% проектов очень странного качества. Пополнять этот список желания нет.

Самое забавное — я думал, что основная работа будет в игровом движке. По факту backend, frontend и DevOps съедают процентов 95 времени. До самого геймплея добираюсь урывками. И это я ещё не трогал полноценный мультиплеер с сетевым взаимодействием и многопоточную обработку данных.

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

Продолжаю делать компьютерную HTML5-игру для Telegram «Memento mori». Вот сайт проекта https://mementus.ru/, а вот бот https://t.me/memento_mori_game_bot. Следующий этап этой невидимой войны — дизайн. И вот тут быстро выяснилось, что красивые ИИ-эскизы и реальная вёрстка — это две большие разницы. Картинка на одном телефоне сидит нормально, на другом уже уехала, а там, где нужны точно поставленные интерактивные элементы, всё начинает разваливаться при первом же масштабировании.

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

В итоге пришлось расчехлять Photoshop и доводить всё напильником. Чтобы был понятен масштаб бедствия: я попросил ИИ нарисовать обычный крестик для закрытия окна в готическом стиле. Он нарисовал не кнопку закрытия, а какой-то мрачный крест с черепом, словно это артефакт из тёмного фэнтези. Я попросил сделать проще — получил тот же крест с черепом, только уже без фона. Убрал слово «готический» — и меня мгновенно унесло в киберпанк. В какой-то момент я плюнул и просто сам вырезал фон в Photoshop, чтобы получить нормальный объёмный металлический крестик, а не очередной полёт чужой фантазии.

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

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

Я даже отдельно спросил у начальника программистов, нормальна ли такая степень детализации и справятся ли они с задачей. На что он мне ответил фразой, которая, кажется, идеально описывает весь отечественный энтерпрайз: «Наши программисты закостылят что угодно». И вот в этот момент я почему-то испытал не ужас, а даже какую-то гордость за наш отдел. Потому что, как ни крути, в этой фразе было не только про костыли, но и про удивительную инженерную гибкость.

В итоге я поймал себя на простой мысли. ИИ хорошо помогает там, где всё можно строго формализовать: алгоритмы, данные, граничные случаи. Но как только начинается дизайн, интерфейсы и реальная вёрстка под десятки экранов — приходится возвращаться к старому инженерному инструменту: голове и напильнику. Пет‑проекты хороши тем, что очень быстро ставят всё на свои места.
👍4
Иногда обычная рабочая неделя неожиданно превращается в сборник технических историй: немного администрирования, немного борьбы с кривыми конфигами, немного экспериментов с AI и параллельно разработка собственной игры. Каждая такая задача сначала выглядит мелкой и рутинной, но стоит копнуть глубже — и она внезапно превращается в маленькую археологическую экспедицию по старому коду, странным решениям и забытым настройкам.
На работе возникла задача синхронизировать фамилии из телефонного справочника с названиями телефонов. Ситуация типичная: условно телефон закреплён за Ивановым, Иванов уволился, вместо него пришёл Петров — а телефон продолжает показывать, что это Иванов. Просто потому, что никто не поменял CallerID.
Проблем оказалось две. Первая — в конфигурации АТС числилась куча телефонов, которые физически зарегистрированы и при этом отсутствуют в справочнике. Лишний мусор. Пришлось написать скрипт, который прошёлся по конфигу и вычистил всё, что не используется.
Вторая проблема оказалась веселее: конфигурационный файл с телефонами оказался «битый». У Asterisk есть забавная привычка — при одной ошибке он может орать, что всё пропало, но при этом спокойно игнорировать опечатки в ключах. Например: pickguproup вместо pickupgroup или usename вместо username. Плюс у части телефонов вообще пустые значения в callerid.
Руками такое не исправишь: телефонов больше трёхсот. Поэтому я написал несколько скриптов, которые прошлись по конфигу, поправили ключи, проверили callerid и привели всё в порядок. В итоге удалось восстановить 29 «сбойных» телефонов — и заодно отсортировать результаты по алфавиту.

Параллельно продолжаю делать HTML5‑игру для Telegram «Memento mori». Вот сайт проекта [https://mementus.ru/](https://mementus.ru/) , а вот бот [https://t.me/memento_mori_game_bot](https://t.me/memento_mori_game_bot) .

Читая документацию по Claude, я долго удивлялся: зачем там столько сущностей — субагенты, скилы, оркестрация. На практике быстро выяснилось, что у AI память очень короткая. После длинного диалога он начинает забывать критические детали.
Отсюда и появляется архитектура из маленьких агентов. Универсальный «многорукий» помощник, который делает всё сразу, работает плохо. А вот отдельный агент с чёткой задачей — например проанализировать код или подготовить текст — справляется заметно лучше.
Хорошо об этом написано в статье «Контекст‑инжиниринг для coding‑агентов: почему агент тупит не из‑за модели» [https://habr.com/ru/companies/cloud_ru/articles/1008522/](https://habr.com/ru/companies/cloud_ru/articles/1008522/)
На практике диалог с coding‑агентом быстро превращается в стабильный шаблон:
Сначала: «прочитай эти файлы и объясни, как устроен модуль и где могут быть баги».
Потом: «предложи план изменений по шагам, код пока не трогай».
И только после этого: «вноси изменения строго по плану; если от него отходишь — объясни почему».
По сути, текстовые файлы и куски контекста просто путешествуют между разными агентами. Когда задача чёткая и ограниченная — например «внести правку в код» или «проанализировать текст» — всё работает отлично. Когда задача становится слишком общей, агент начинает быстро забывать детали.

Был и забавный эпизод. Перестало собираться приложение. Я был уверен, что AI исправит это за пару минут. В итоге он два часа создавал и удалял строки, переписал половину проекта и почти всё вернул обратно. Ошибка же решилась заменой одной строки. Единственное полезное открытие из этой истории — ключ claude --dangerously-skip-permissions, который отключает бесконечные запросы подтверждения.
Но случилось маленькое эпохальное событие: вчера я наконец добрался до работы с игровым движком Phaser. Прошёл ровно месяц с начала проекта.
За это время удалось:
- создать мини-лендинг для [https://mementus.ru/](https://mementus.ru/)
- реализовать backend: авторизацию через Telegram, таблицу лидеров и игровые сессии
- настроить интеграцию с Telegram
- собрать CI/CD и перенести проект на VPS
- подготовить дизайн экранов
- реализовать три интерфейса: начало игры, таблицу лидеров и настройки

Я наивно думал, что такой объём работы уложится в одну‑две недели. Но без всей этой «невидимой» подготовки сам игровой процесс просто не запустить.
Плюс параллельно пришлось осваивать кучу новых инструментов. И главный вопрос всё время был не «что делать», а «как именно это сделать».
Но проект движется. А значит всё идёт правильно.

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