Оглавление

Раньше это был PHP/Laravel-скрипт, а теперь Python-сервис, который я переписал с помощью Codex

Domaintools

domaintools.site начинался у меня как простой PHP/Laravel-проект: быстро поднять прототип, собрать в одном месте доменные утилиты, сделать понятный интерфейс и проверить, вообще будет ли этим кто-то пользоваться.

Потом я всерьёз пошёл учить Python, а в ChatGPT появился Codex (тот самый агентный режим, когда правки приходят в виде pull request’ов). И я решил сделать нормальный инженерный эксперимент: взять живой проект и перенести его на Python так, чтобы это не было “переписал всё одной простынёй”, а было похоже на взрослую разработку с ревью и диффами.

Сайт: domaintools.site. Репозиторий: github.com/A-Krivoshen/domaintools.

Что это за сервис сейчас

По факту domaintools.site это набор утилит “на каждый день”, когда работаешь с доменами, DNS и IP. Не энтерпрайз-комбайн и не “проверка домена на одной кнопке”, а нормальный набор инструментов, который помогает быстро получить ответ и не лезть в десять разных сервисов.

Что умеет

Я держу фокус на практичных вещах. То, что реально используется:

  • Проверка доменного имени и быстрый поиск вариантов по зонам.
  • WHOIS по домену.
  • DNS-записи (A, AAAA, MX, NS, TXT и т.д.) с нормальным выводом.
  • Поиск IP по домену и домена по IP.
  • Сервисные проверки вроде “site checker” (проверка доступности/ответов, без фанатизма).

Смысл простой: я хочу, чтобы открываешь страницу, вводишь домен, получаешь результат быстро и понятно. Без “вот вам JSON, дальше разберётесь”.

Почему я ушёл от PHP/Laravel версии

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

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

Где здесь Codex и почему это не просто “чатик подсказал”

Я использовал Codex так, как мне нравится больше всего: не “нагенерь мне проект”, а “сделай маленький кусок работы, оформи это PR, а я посмотрю дифф”. В итоге история изменений в репозитории выглядит аккуратно: серия небольших pull request’ов, которые можно ревьюить и мерджить без риска снести половину проекта.

Это важный момент. Когда изменения приходят через PR, у тебя остаётся контроль: что поменялось, где поменялось, почему, и как откатиться, если что-то не зашло. Я не люблю “магическую” разработку. Я люблю диффы.

Если хочется посмотреть именно историю агентных правок, вот репозиторий и список PR: github.com/A-Krivoshen/domaintools/pulls.

Что я улучшал при переносе на Python

Я не делал “идеальную архитектуру на века”. Я делал сервис, которым удобно пользоваться и который не разваливается от реальных входных данных. Поэтому улучшения были вполне приземлённые.

Параллельность там, где всё упирается в сеть

Проверка доменных зон и DNS это в основном ожидание. Если делать всё последовательно, сайт начинает казаться “тормозным”, хотя CPU у сервера может вообще не напрягаться. Поэтому логика проверок уехала в параллельный режим с ограничениями по количеству зон и воркеров.

Настройки удобно держать через env, чтобы не лезть в код при каждом изменении лимитов:

# пример export DOMAIN_CHECK_MAX_TLDS=20 export DOMAIN_CHECK_WORKERS=8

Нормальный вывод данных, а не “простыня JSON”

Большая часть доменных утилит страдает одной болезнью: они честно показывают ответ, но этот ответ невозможно читать. Поэтому вывод DNS/WHOIS и похожих вещей я приводил к “табличному” виду: ключ и значение, аккуратная верстка, без ощущения, что ты открыл дамп из консоли.

Язык и интерфейс

Проект стал более “прикладным”: где-то подчистил шаблоны, где-то добавил двуязычность ru/en, где-то упростил логику страниц. Я не пытался сделать дизайн как у SaaS-платформы. Задача проще: чтобы инструмент выглядел нормально и не раздражал.

Сразу скажу честно. Codex это не “сделай всё за меня”. Это скорее “сделай кусок работы, оформи как PR, а я посмотрю глазами”. Если держать этот подход, агент становится ускорителем. Если отпустить руль, получится набор разрозненных правок, которые сложно поддерживать.

Главное правило: одна задача — один PR

У меня простая дисциплина. Один PR решает одну проблему. Не “рефакторинг всего проекта”, а “ускорить доменную проверку и добавить лимиты”, “нормально отрисовать JSON таблицей”, “поправить обработку ошибок в одном модуле”.

Почему так лучше:

  • дифф читается за 2–5 минут;
  • если PR не зашёл, его легко откатить;
  • легко понять, что именно улучшилось;
  • не появляется эффект “всё поменялось, но почему и где”;

Как я пишу задачу Codex: структура запроса, которая не подводит

Я не пишу “сделай красиво” или “улучши производительность”. Я пишу задачу в формате: контекст, цель, ограничения, критерии готовности. Прямо как для нормального разработчика.

Шаблон задачи

Контекст: - Проект: domaintools.site (Python/Flask) - Файл/модуль: app/site_checker.py (пример) - Сейчас: запросы выполняются последовательно, иногда таймауты. Цель: - Сделать параллельную проверку с лимитом на количество задач. Ограничения: - Не трогать внешний API/роуты. - Не добавлять тяжёлые зависимости. - Ошибки должны быть читаемыми, без traceback в ответе. Критерии готовности: - Есть PR с диффом. - В логах видно понятные ошибки. - Параметры лимитов берутся из env и имеют safe default.

С таким запросом Codex обычно не расползается, потому что ему сразу ясно “где копать” и “что нельзя трогать”.

Какие задачи Codex делает лучше всего

На практике у меня Codex идеально заходит на такие типы работ:

  • локальный рефакторинг одного модуля: разложить функции, убрать дубли, привести код к нормальному виду;
  • улучшение обработки ошибок: понятные сообщения, аккуратные fallback, без “тихих падений”;
  • переписывание рендера в шаблонах: привести вывод JSON/DNS/таблиц к одному стилю;
  • настройки через env: добавить параметры, дефолты, проверку значений;
  • микро-оптимизации на структуре данных: list → set, кэширование, устранение лишних проходов;

А вот на задачи “перепиши всё приложение целиком” я Codex не пускаю. Не потому что “не умеет”, а потому что это сложно ревьюить и очень легко потерять контроль.

Как я заранее ограничиваю “креатив”

У меня есть несколько принципов, которые я проговариваю прямо в задаче. Они приземлённые, но сильно экономят время.

  • Не менять публичные роуты и формат ответа, если это не оговорено отдельно.
  • Не добавлять зависимости без причины. Если очень надо, объясни зачем.
  • Не делать “архитектуру ради архитектуры”. Решаем конкретную проблему.
  • Не трогать стили/верстку на всех страницах, если задача про один блок.

И ещё одно: если задача про скорость, я прошу предложить 2–3 варианта решения и выбрать самый простой, который даст нормальный эффект. Я люблю простое. Простое легче поддерживать.

Мой чек-лист перед мерджем PR от Codex

Это самая важная часть. Секрет успеха не в том, что Codex “идеально пишет”. Секрет в том, что ты не мерджишь вслепую.

  • Смотрю дифф глазами. Особенно места с обработкой ошибок и с network-частью.
  • Проверяю, не уехали ли env-переменные/настройки в странные значения.
  • Прогоняю минимум проверок локально (или на тестовом стенде): старт приложения, один-два запроса к ключевым страницам.
  • Если в PR добавлен параллелизм, смотрю лимиты и safe default.
  • Если PR трогает шаблоны, проверяю страницу в браузере и в мобиле.

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

# примерный минимум python -m compileall . python app.py # или твой entrypoint curl -I http://127.0.0.1:5000/ curl -s http://127.0.0.1:5000/dns?domain=example.com | head

Мне не нужно покрыть тестами вселенную. Мне нужно убедиться, что PR не ломает базовые маршруты и не добавляет сюрпризов.

Промпты, которые я реально использую на domaintools.site

Вот несколько готовых формулировок. Их можно копировать и адаптировать.

1) Рефакторинг модуля “Возьми модуль X. Разбей на мелкие функции, убери дубли, добавь понятные ошибки. Не меняй роуты и формат ответа. Сделай PR.” 2) Скорость и параллелизм “Ускорь проверки в функции Y. Добавь параллельность, но с лимитами и safe default. Параметры вынеси в env. Сделай PR и короткое объяснение.” 3) UI вывод данных “Сделай единый вывод JSON в виде таблицы key/value для страниц A, B, C. Без изменения логики получения данных. Только отображение. Сделай PR.” 4) Обработка ошибок “Сейчас при ошибке Z уходит traceback/500. Сделай аккуратный ответ пользователю и запись в лог. Не меняй happy-path. Сделай PR.”

Где Codex может ошибиться, и это нормально

Есть два типовых сценария, которые я вижу чаще всего:

  • агент может “слишком поверить” в переменные окружения и не защититься от кривых значений;
  • агент может чуть переборщить с рефакторингом и тронуть соседние части, хотя задача была локальной.

Это не трагедия. Это просто причина держать дисциплину: один PR — одна задача, и ревью глазами.

Итог

Codex для меня стал не “генератором кода”, а инструментом, который помогает быстрее двигать проект, сохраняя контроль. Формат “агент делает PR, я ревьюю и мерджу” хорошо ложится на реальную разработку. Особенно когда ты учишь новый стек и хочешь развивать проект без хаоса.

Репозиторий domaintools.site: github.com/A-Krivoshen/domaintools

Как пользоваться domaintools.site

Там всё довольно прямолинейно: выбираешь инструмент, вводишь домен или IP, получаешь результат. Если короткий маршрут, то обычно он такой:

    • Нужно понять, жив ли домен и что по зонам — начинаешь с поиска/проверки домена.

    • Нужно понять регистратора/сроки — идёшь в WHOIS.

    • Не сходится почта/веб — идёшь в DNS и смотришь записи.

    • Разбираешься с IP — используешь прямой/обратный поиск.

Ссылка на демо: domaintools.site.

Итог

Старый PHP/Laravel вариант был полезным стартом, но сейчас его уже нет смысла “продавать” как продукт. Вся основная жизнь проекта переехала в Python-версию, и перенос я делал как тест нового подхода: Codex как напарник, который готовит маленькие PR, а я принимаю решения и держу качество через ревью.