- Зачем:
- форма 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 — зелёные.
4.7 KiB
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.
Что не так
- Побочные артефакты backfill не покрыты
.gitignore. После HITL вdata/лежитci_backfill.json(49 МБ) — риск случайного коммита. Сиды проекта вdata/— это*.jsonl, они под git и должны остаться. - 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не удалять и не коммитить.- Коммиты не делать.
Сначала прочитать
- Этот файл.
.scratch/generator-model-time-startup-history/hitl-findings.md— F1.airflow/dags/generator_control_dag.py— объявления и чтение Param.generator/tests/test_generator_control_dag_contract.py.