JavaRush /Курсы /Claude code /Runtime flow и точки входа

Runtime flow и точки входа

Claude code
7 уровень , 4 лекция
Открыта

1. Карта папок — это скелет, который не двигается

После inventory и dependency map кажется, что проект понятен. Это иллюзия: вы видите скелет, а скелет не двигается. Статическая карта отвечает «что есть в проекте», runtime flow — «что происходит, когда система работает» (например при оформлении заказа в Commerce OS). Спутаете оптики — поправите не тот сервис и сломаете половину сценария.

Вопрос Статическая карта Runtime flow
Где живёт логика заказов? В модуле orders/
POST /api/orders
попадает в контроллер, потом в сервис, потом в репозиторий и события
Какие модули связаны с оплатой? orders/ зависит от payments/ Оплата вызывается после резерва товара и до сохранения заказа
Что происходит, если товара не хватает? Обычно карта не отвечает Сервис прерывается, возвращается ошибка, запись в БД не происходит
Какой конфиг влияет на поведение? Можно найти файл настроек Можно понять, в какой момент настройки реально меняют путь выполнения

Прочитав flow, вы перестаёте видеть «набор папок» и начинаете видеть систему.

2. Точка входа — не всегда main()

Сначала найдите, где сценарий начинается, — это entry point. Частая ошибка: считать, что точка входа всегда main(). В бизнес-приложении их много, каждая запускает свой тип поведения: заказ — HTTP-маршрут, пересчёт метрик по расписанию — фоновая задача, инициализация кэша — стартовая логика.

Тип точки входа Пример в Commerce OS Где искать
HTTP-запрос
POST /api/orders
контроллеры, роуты, интеграционные тесты
Действие в интерфейсе клик по кнопке «Оформить заказ» React-компонент, клиент API, обработчик формы
Фоновая задача пересчёт метрик dashboard jobs/, планировщики, cron-настройки
Старт приложения инициализация модулей
main
, конфигурация, startup listeners
Командный сценарий импорт данных из файла CLI-команда, runner, shell-скрипт

Для оформления заказа серверная точка входа выглядит примерно так:

@PostMapping("/api/orders")
public OrderResponse create(@RequestBody OrderRequest request) {
    return orderService.placeOrder(request); // первая серверная точка входа
}

Аннотации Spring наизусть знать не нужно — нужен принцип: кнопка → HTTP-запрос → метод контроллера, отсюда начинается путь данных внутри backend.

Прося Claude найти точку входа, формулируйте через конкретную пользовательскую историю:

Найди точку входа для сценария «покупатель оформляет заказ».
Покажи:
1. где начинается путь в интерфейсе или API,
2. какой маршрут принимает запрос,
3. какой метод вызывается первым на сервере,
4. какими файлами это подтверждается.
Если что-то не проверено, пометь это явно.

Правило: один runtime flow — одна история. Тяните в один запрос заказ, возврат и уведомления сразу — получите лапшу, а Claude начнёт обобщать там, где нужны следы.

3. Читайте цепочку вызовов, а не список файлов

После точки входа идёт call chain — упорядоченный путь от обработчика до результата. Без порядка это список файлов; с порядком видно, кто кого вызывает, где меняются данные, где возникают побочные эффекты.

Для сценария «оформить заказ» в Commerce OS:

flowchart TD
    A[POST /api/orders] --> B[OrderController#create]
    B --> C[OrderService#placeOrder]
    C --> D[InventoryService#reserve]
    D -->|товар есть| E[PaymentService#authorize]
    D -->|товара нет| X[Ответ с ошибкой]
    E -->|оплата успешна| F[OrderRepository#save]
    E -->|ошибка оплаты| Y[Ответ с ошибкой]
    F --> G[(PostgreSQL)]
    F --> H[OrderPlacedEvent]
    H --> I[notifications / jobs]

Схема даёт порядок: резерв раньше оплаты, оплата раньше сохранения, событие — только после записи в базу. И ветвления: нет товара — не идём в PaymentService; не прошла оплата — заказ не сохранить как успешный.

Центр цепочки часто живёт в одном сервисном методе:

public OrderResponse placeOrder(OrderRequest request) {
    inventoryService.reserve(request.items());      // резервируем товар
    paymentService.authorize(request.payment());    // пробуем оплату
    Order saved = orderRepository.save(mapper.toOrder(request));
    eventPublisher.publish(new OrderPlacedEvent(saved.id())); // побочный эффект
    return mapper.toResponse(saved);
}

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

Отмечайте и путь данных: OrderRequest (HTTP) → валидация → доменная модель Order → PostgreSQL → наружу OrderResponse. Не зафиксируете — запутаетесь, где входной JSON, а где внутренняя модель.

И не забывайте про конфиги — они незаметно меняют flow. Сервис оплаты выбирает реализацию по настройке:

app:
  payments:
    provider: mock-pay   # какой провайдер оплаты будет вызван
  orders:
    max-items: 20        # ограничение на размер заказа

Цепочка без конфигов и переменных окружения — слишком гладкая. Реальная система всегда подчиняется настройкам, профилям и флагам.

4. Ветка ошибки важна не меньше основной

Типичная ошибка — проследить только красивый сценарий и закрыть задачу. Но код чаще ломается на ветках ошибок. Runtime flow без error path — половина картины, иногда меньше.

В оформлении заказа очевидны минимум две ветки: нет товара на складе и не прошёл платёж. Не понимаете, где они отрезают выполнение, — не понимаете систему. Перенесёте запись в базу раньше проверки оплаты — получите «успешные» заказы без оплаты. Такой баг приходит ночью.

Error path удобно проверять по тестам. Интеграционный тест подтверждает, что при нехватке товара контроллер возвращает конфликт:

@Test
void createOrder_returnsConflict_when_item_is_unavailable() throws Exception {
    mockMvc.perform(post("/api/orders").content(невалидныйЗапрос()))
           .andExpect(status().isConflict()); // 409, если товара не хватает
}

Смысл читается даже без знания тестового API: это доказательство для ветки ошибки — система завершает сценарий конкретно, а не «как-то ругается».

Здесь работает дисциплина из прошлой лекции: нет подтверждения error path в коде, тестах или конфигах — не дорисовывайте, пишите не проверено. Например: «не проверено, есть ли retry при частичном падении платёжного провайдера». Это хорошая инженерная запись. Слабость — когда модель придумала, а вы молча унесли это в inventory как факт.

При разборе flow держите четыре вопроса: где начинается основная ветка, где она может оборваться, какие побочные эффекты успевают произойти до ошибки и чем это подтверждается.

5. Запрашивайте flow с evidence

Спросите «как работает оформление заказа?» — Claude ответит уверенно и обобщённо. Читать приятно, работать неудобно. Нужен не пересказ архитектуры, а разбор потока с доказательствами. Помогает контраст слабого и сильного вопроса:

Слабый запрос Сильный запрос
Как работает заказ? Проследи сценарий «покупатель оформляет заказ» от HTTP-маршрута до записи в БД и публикации события
Объясни модуль orders Найди точку входа, цепочку вызовов, ветки ошибок, влияющие конфиги и тесты
Где тут логика оплаты? Покажи, в какой момент flow вызывает оплату и что происходит, если она не прошла

Шаблон запроса, который обычно даёт полезный результат:

Проследи поток выполнения сценария «покупатель оформляет заказ».

Покажи в ответе:
1. точку входа;
2. цепочку вызовов по файлам, методам и классам;
3. как меняются данные по пути;
4. какие побочные эффекты происходят;
5. какие конфиги или env-переменные влияют на поведение;
6. какие тесты подтверждают этот сценарий;
7. какие есть ветки ошибки;
8. что ты не проверил и какие предположения сделал.

Для каждого важного шага укажи файл или метод, на который ты опираешься.
Если уверенность средняя или низкая, пометь это явно.

Магии нет: вы заранее задаёте формат и запрещаете модели прятать неопределённость за красивыми формулировками.

После ответа — ручная проверка. Не перечитывайте все файлы, откройте две-три опоры: точку входа, центральный сервисный метод, тест на ошибку. Этот выборочный проход резко снижает риск унести в заметки красивую, но неверную историю.

И не просите разом «объяснить flow» и «предложить улучшения». Сначала установите, как система работает сейчас. Иначе Claude смешает факты с улучшениями, а вам потом разбирать, где описание, а где совет.

6. Перенесите flow в CODEBASE_INVENTORY.md

Разбор не должен остаться в чате. Динамический срез добавляем в тот же CODEBASE_INVENTORY.md. Отдельный RUNTIME_FLOW.md на первом проходе не нужен: карта проекта должна жить в одном месте. Хороший формат:

## Runtime flow — оформление заказа

Точка входа:
`POST /api/orders` → `orders/OrderController#create`

Цепочка вызовов:
`OrderController#create` → `OrderService#placeOrder`
→ `InventoryService#reserve` → `PaymentService#authorize`
→ `OrderRepository#save` → `OrderPlacedEvent`

Побочные эффекты:
- резерв товара
- запись заказа в PostgreSQL
- публикация события для уведомлений

Ветка ошибки:
- нет товара → ответ 409, заказ не сохраняется
- ошибка оплаты → заказ не подтверждается

Конфиги:
- `app.payments.provider`
- `app.orders.max-items`

Тесты:
- `OrderServiceIntegrationTest#placeOrder_happy_path`
- `OrderControllerTest#create_returnsConflict_when_item_is_unavailable`

Непроверено:
- retry при частичном падении платёжного провайдера

Формат короткий: inventory — не роман о судьбе заказа. Он отвечает на правильные вопросы: откуда flow начинается, через что проходит, где может оборваться, чем подтверждается — и честно хранит неизвестное.

Правило прежнее: одна секция — одна история. Несколько историй — несколько коротких секций, иначе inventory превращается в стену текста, которую все игнорируют.

Раньше вы видели папки orders/, payments/, jobs/. Теперь — маршрут запроса: где входит, через какие сервисы проходит, где останавливается, какие настройки влияют, какие тесты держат поведение. Перед вами уже не репозиторий, а система, в которой можно работать по следам реального выполнения кода.

1
Задача
Claude code, 7 уровень, 4 лекция
Недоступна
Runtime flow для сценария place order внутри Claude Code
Runtime flow для сценария place order внутри Claude Code
1
Задача
Claude code, 7 уровень, 4 лекция
Недоступна
Анализ runtime flow: неверный порядок вызовов в OrderService
Анализ runtime flow: неверный порядок вызовов в OrderService
1
Опрос
Discovery незнакомого проекта в Claude Code, 7 уровень, 4 лекция
Недоступен
Discovery незнакомого проекта в Claude Code
Discovery незнакомого проекта в Claude Code
Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ