Files
clickstream-ch-kafka-supers…/.scratch/generator-model-time-startup-history/issues/21-merge-prep-gitignore-nullable-params.md
T
ddadmin bec56da1c3 fix(airflow): необязательные поля формы generator_control стали необязательными
- Зачем:
  - форма Trigger DAG требовала заполнить все поля: канонический запуск
    «выбрать профиль, остальное пусто» через UI был невозможен (находка F1
    ручного HITL); артефакты backfill (data/*.json, 49 МБ) рисковали
    попасть в коммит.
- Что:
  - пять необязательных Param переведены на Param(None, type=["null",
    "string"]) — идиома необязательного поля, проверено по Context7
    (Airflow 2.10.5); все места чтения уже None-безопасны (or "").
  - контрактный тест дополнен: у необязательных Param есть "null" в type,
    у operation/profile — нет.
  - .gitignore: правило data/*.json (сиды data/*.jsonl остаются под git);
    задача 21 закрыта в .scratch.
- Проверка:
  - make test (205 + 31 passed) и make lint — зелёные.
2026-07-19 22:17:50 +03:00

4.7 KiB
Raw Blame History

Status: done

Подготовка ветки к слиянию: .gitignore для артефактов и необязательные поля формы

Parent

.scratch/generator-model-time-startup-history/PRD.md — закрывающая гигиена перед слиянием feature/data-generator в main. Находка F1 — из .scratch/generator-model-time-startup-history/hitl-findings.md.

Что не так

  1. Побочные артефакты backfill не покрыты .gitignore. После HITL в data/ лежит ci_backfill.json (49 МБ) — риск случайного коммита. Сиды проекта в data/ — это *.jsonl, они под git и должны остаться.
  2. F1 (BUG): в форме generator_control (Trigger DAG w/ config) все пять необязательных полей (duration, seed, model_time_speed, artifact_path, expected_t_end) показаны обязательными: красная *, браузер не даёт отправить форму с пустым полем. Канонический запуск «выбрать профиль, остальное пусто» через UI невозможен.

Причина F1 (проверено)

В airflow/dags/generator_control_dag.py:230-265 эти Param(...) объявлены с type="string". Шаблон формы Airflow вешает * и HTML-атрибут required на каждое поле, у которого в type нет "null".

Проверено по Context7 (/apache/airflow/2.10.5, 2026-07-19): идиома необязательного строкового параметра — Param(None, type=["null", "string"]); поле с "null" в type форма не помечает обязательным.

Чтение параметров в DAG уже терпимо к None: везде str(_param(...) or "").strip() (строки 71-161), поэтому смена пустого значения с "" на None ничего не ломает — но это надо перепроверить глазами по каждому месту чтения.

Что сделать

  • В .gitignore добавить правило data/*.json (раздел «Тестовые данные и артефакты») с комментарием: артефакты генератора; сиды data/*.jsonl остаются под git.
  • Пять необязательных Param в airflow/dags/generator_control_dag.py перевести на Param(None, type=["null", "string"]). Обязательные (operation, profile) не трогать. У изменённых Param коротким комментарием зафиксировать: "null" в type = необязательное поле формы (проверено по Context7, Airflow 2.10.5).
  • Убедиться, что каждое место чтения этих параметров в DAG переживает None (сегодня везде or "" — сверить полный список).
  • В generator/tests/test_generator_control_dag_contract.py дополнить контракт: у пяти необязательных Param в объявлении есть "null", у operation/profile — нет.
  • docs/OPERATIONS.md: сверить описание формы generator_control; если там есть обход «заполняйте все поля» — убрать, поведение «пусто = из профиля» оставить как есть.
  • Дешёвые проверки зелёные: make test и make lint (нужен docker; если в песочнице исполнителя недоступен — явно сказать в отчёте, прогонит оркестратор).

Границы

  • Логику генератора (generator/src/) не менять.
  • Профили и их состав не трогать (это отдельная задача редизайна).
  • Форму DAG не перестраивать (отдельный DAG next-day — тоже отдельная задача, F3).
  • data/ci_backfill.json не удалять и не коммитить.
  • Коммиты не делать.

Сначала прочитать

  1. Этот файл.
  2. .scratch/generator-model-time-startup-history/hitl-findings.md — F1.
  3. airflow/dags/generator_control_dag.py — объявления и чтение Param.
  4. generator/tests/test_generator_control_dag_contract.py.