← Назад к новостям

Гео-аналитическая платформа вдвоём за 2,5 месяца, или история одной spec-driven разработки

Мне посчастливилось начать проект с чистого листа: амбициозная задача, никакого легаси и свобода выбрать любой подход. Я решил довериться AI по-максимуму и код больше не трогал. Сначала я не верил, что это выдержит реальный масштаб. Опыт подсказывал: чем больше проект, тем быстрее AI путается в контексте и упирается в лимиты. Но через 2,5 месяца мы вдвоём запустили гео-аналитическую платформу, которую в до-AI эпоху строили бы годами. Это поменяло моё представление о разработке. Задача В одной стране, где, по легенде, стоит резиденция Дракулы, идёт бурный экономический рост — и торговые сети наперегонки строят магазины. Рынок ещё не насыщен: у Lidl в Германии 39 магазинов на миллион жителей, в Чехии — 29, здесь — около 20. Конкуренты открывают по 15–25 точек в год. Кто первым займёт хорошие участки — тот и заберёт рынок. Выбор участка под магазин — это самый долгий и рискованный этап экспансии. Масштаб задачи: среди ~13 млн кадастровых участков найти места для ~600 будущих магазинов. Раньше выбирали вручную: менеджеры действовали по интуиции — так открывали 5 магазинов в год. План клиента — выйти на 20. Интуицию заменили математикой. Как клиент выбирает участки, мы не знали — приняли это за «чёрный ящик». Зато знали результат выбора: действующие магазины. В терминах ML это Positive-Unlabeled постановка: есть положительные примеры, а размеченных отрицательных нет — обучать классическую модель не на чем. Поэтому начали с простого: придумали признаки, эмпирически расставили им веса и посчитали взвешенный балл для каждого магазина сети — получился ранкинг. Считаем тот же балл для свободного участка — и видим, какое место он занял бы среди действующих магазинов. Так мы выразили свободные участки в существующих магазинах. Что мы построили Мы построили систему, которая сводит воедино полтора десятка источников данных: государственный реестр населённых пунктов, перепись, дорожный граф OpenStreetMap, кадастр, GPS-трафик, объявления о продаже земли, координаты магазинов двух десятков торговых сетей. К удивлению, такую базовую вещь, как координаты всех населённых пунктов страны, не знает даже Google Maps — их пришлось сводить из Mapbox, GeoNames и государственного реестра. По каждому городу собрали население, гендерный баланс, покупательную способность, класс дорог — от шоссе до просёлка — и транспортную доступность: сколько людей доберётся до точки за 15 и 30 минут. Самым ценным источником оказался GPS-трафик. Бесплатные мобильные приложения записывают геопозицию, агрегаторы скупают её — и эти данные можно достать. За год по всей стране — около 3 млрд записей. Скоринг работает на двух уровнях: города — куда вообще имеет смысл смотреть — и участки внутри перспективных городов. Параллельно система парсит местные маркетплейсы земли и следит за новыми объявлениями. На выходе менеджер получает приоритетный город и участок — остаётся найти владельца земли. Для этой работы построили CRM: комментарии, документы, ответственные, статусы, уведомления. Всё, чтобы вести участок от «модель подсветила» до «клиент подтвердил: строим здесь». Подход — spec-driven development Теперь — как мы это построили. Главное здесь — организация контекста для агентской разработки. В первый день мы рисовали архитектуру вручную: доменную модель, роли, связи между компонентами. А потом я записал 40-минутный созвон и отдал транскрипт LLM — этого оказалось достаточно, чтобы она сгенерировала PRD и диаграммы лучше, чем мы нарисовали за полдня. Код — следствие документации В проекте две сущности: документация и код. Код — следствие набора спецификаций. Документация живёт на двух осях: статическая ось — срез системы: актуальная архитектура, компоненты, фичи. Обновляется после каждой выкаченной фичи; временна́я ось — лог событий: спецификации, планы, архитектурные решения — что и почему мы решили (в терминах Event Sourcing). Эта модель отражена прямо в структуре репозитория — вот её ядро: . ├── .claude/ │ ├── skills/ ← переиспользуемые скиллы │ └── commands/ ← слэш-команды │ ├── docs/ │ ├── product/ ── срез: что продукт есть сейчас │ │ ├── features/ ← одна фича = один файл │ │ ├── architecture/ ← снимок системы; обновляется после каждой фичи │ │ └── PRD.md ← задача, пользователи, требования │ │ │ └── process/ ── лог событий: как мы к этому пришли │ ├── decisions/ ← ADR — архитектурные решения, append-only │ ├── specs/ ← что делаем (рождаются из brainstorming) │ └── plans/ ← как делаем, по шагам │ ├── ops/ ── эксплуатация: скрипты, деплой, рутины └── src/ ── код — следствие всего, что выше Начать с такой структуры можно с моего seed-репозитория: agentic-repo-seed . Агент видит и историю решений, и текущую архитектуру. Он вычленяет архитектурные паттерны проекта и расширяет систему, следуя им. Как менялся процесс Начинали до того, как у Anthropic появились Superpowers, поэтому роли написали сами: критик и исполнитель. Я описывал фичу, агент генерировал план, критик проверял его на расширяемость, безопасность и соответствие требованиям. Я вычитывал план, пока вопросов не оставалось ни у меня, ни у критика, — и только после этого начиналась имплементация. С переходом на Superpowers процесс почти автоматизировался: брейнсторминг, спецификация, утверждение, план, реализация. План я уже не читаю, код почти не смотрю — руками тестирую только edge-кейсы. Отдельно — про сбор входящих. В проекте есть Inbox, куда падают транскрипты всех встреч; из них мы выделяем фичи и архитектурные решения. Первые две недели работали в режиме хакатона, потом завели трекер задач. В нашей модели у трекера скромная роль: это хранилище одноразового — обсуждений и комментариев, которые не описывают состояние системы и которые не жалко выкинуть. Главное наблюдение: чем больше контекста накапливалось, тем быстрее шла разработка. В какой-то момент стало достаточно сказать «добавь в CRM такую-то сущность» — и агент по накопленным примерам сам создавал таблицу, сервис, контроллеры и фронтенд, и всё это вписывалось в дизайн продукта. Стек Backend: TypeScript + NestJS (API). Backend и frontend намеренно разделены. Frontend: Next.js (React) с server-side рендерингом. База: PostgreSQL. Для кадастра и GPS сначала использовали BigQuery, но предвычисленные индексные слои для быстрого рендера на карте всё же занесли в Postgres + расширение PostGIS . Карта почти в реальном времени: использовали H3 — гексагональный геоиндекс Uber. Для каждого уровня зума предвычислили гексагональные тайлы, и при отрисовке карта подгружает сотни объектов вместо миллионов — при 3 млрд исходных GPS-записей. Агентная разработка: Claude Code + Superpowers skills. Отдельно про разделение backend/frontend. С одной стороны — бутылочное горлышко. С другой — точка формализации контракта между слоями. Для агентов это дополнительный harness: строгая граница удерживает архитектуру и качество кода. Статистика Вот из-за чего я сам себе не верил. Все цифры — из git-истории проекта (2026-02-16 → 2026-06-30). Ядро собрали за ~2,5 месяца; сейчас проекту ~4,5 месяца, и он продолжает расти. Строки кода: Часть проекта Строк Документация ( *.md ) ~41k Код приложения (NestJS API + Next.js) ~155k Инструменты (Python) ~42k Всего ~240k Pull requests и темп: Метрика Значение Смёрдженных PR 230 Всего коммитов 1 928 Дней с коммитами 105 PR на человека в активный день ≈ 1,8 (в первый месяц у меня — 2,2) Добавлено строк на один PR ≈ 1 930 — по истории коммитов, включая переписанные позже Заключение Итоги У нас не было опыта работы с геоданными — и всё же мы построили систему, в которой геоданные несут всю основную нагрузку. Проект живёт уже 4,5 месяца и растёт: новые фичи выкатываем каждый день — без роста стоимости разработки и просадки качества. Страх из начала статьи не сбылся: в лимиты контекста мы так и не упёрлись, а скорость к концу проекта не просела. Результатом я доволен: это лучшее сочетание качества кода, тестов и документации за мои 25 лет в разработке. Причём 20 из них я писал backend на Java, а на TypeScript перешёл только полтора года назад. Ядро делали вдвоём с кофаундером : он — Product Owner и frontend, я — архитектура и backend. Позже подключился третий человек — по данным. Самый болезненный инсайт Код больше не надо трогать руками. Написание кода превратилось в интеллектуальное развлечение — вроде игры в шахматы. Приятно, но прямой пользы бизнесу не несёт. Ценность сместилась в управление продуктом и организацию контекста. Код — уже следствие, как деталь, сходящая с правильно настроенного ЧПУ-станка. Но это не значит, что инженер больше не нужен. Наоборот, именно инженерное мышление отделяет рабочую систему от красивой галлюцинации. Просто мыслить теперь нужно на уровне архитектуры, а не кода. Что дальше Продукт ответил на вопрос бизнеса: сказал, где строить, — и клиент пошёл строить. А мы ищем, что делать с этим опытом дальше. Для нас он сложился в три вектора: Система. Скоринг не привязан к магазинам — его легко адаптировать под любую нишу, где нужно оценивать и ранжировать локации. Команда и процесс. Мы научились быстро проходить путь от идеи до боевой системы — и собрали команду, которая умеет это повторять. Подход. Ту же организацию контекста я использую уже в десятке пет-проектов — например, qrshare.io и t-ntfy ( бот , код ). А на основном рабочем проекте сейчас натягиваю «семантический слой» на legacy-систему — чтобы получить ту же скорость разработки в существующем коде. Ваш опыт Вы ещё заглядываете в код — или уже доверяете агенту и работаете с кодом как с «чёрным ящиком»? Как вы организуете контекст в проекте — и как им делятся участники команды? Как поменялся ваш подход к разработке за последние пару лет? На правах рекламы: я веду телеграм-канал «ИИ без воды» — делюсь приёмами использования ИИ на практике, для разработки и личной продуктивности. Связаться с нами: Сергей Ройз · Сергей Воронов .
📊 Источник: Habr | Оригинал