Files

6.1 KiB
Raw Permalink Blame History

ТЗ — ORCH-069: QG-0 title-лимит → параметр ORCH_QG0_TITLE_MAX (дефолт 200)

Work Item ID: ORCH-069

1. Задействованные модули src/

Файл Текущее состояние Требуемое изменение
src/config.py Settings(BaseSettings), env_prefix = "ORCH_" (строки 4, 347-349) Добавить поле qg0_title_max: int = 200 с комментарием-описанием.
src/webhooks/plane.py _qg0_errors (строки 357-367), хардкод if len(name) > 80: (строка 362); from ..config import settings уже импортирован (строка 11) Заменить хардкод > 80 на > settings.qg0_title_max; текст ошибки — динамический с подстановкой лимита.

Других модулей изменение не затрагивает.

2. Изменение config.py

Добавить в класс Settings новое поле (рядом с другими ORCH_* группами, рекомендуется отдельный блок с комментарием):

# ORCH-069: QG-0 upper title-length limit (entry gate _qg0_errors). The 80-char
# cap was a hygiene limit, not structural (slug is cut to [:30] independently,
# DB title TEXT is unbounded). Configurable via env ORCH_QG0_TITLE_MAX; default
# 200 (was hardcoded 80). Invalid/empty value -> default (graceful, no crash).
qg0_title_max: int = 200
  • Env-переменная: ORCH_QG0_TITLE_MAX (автоматически из env_prefix = "ORCH_").
  • Тип int, дефолт 200.

3. Изменение _qg0_errors (src/webhooks/plane.py)

Текущий блок (строки 362-363):

if len(name) > 80:
    errors.append("Title слишком длинный (максимум 80 символов)")

Требуемое:

if len(name) > settings.qg0_title_max:
    errors.append(
        f"Title слишком длинный (максимум {settings.qg0_title_max} символов)"
    )

Требования:

  • Лимит берётся из settings.qg0_title_max (динамически, на каждый вызов — чтобы тесты могли подменять значение через мок/патч settings).
  • Текст ошибки содержит актуальное число лимита (для AC-1/AC-2: текст упоминает 200 / 120 соответственно).
  • Нижний лимит заголовка < 5 (строка 360-361) и проверка description < 20 (строка 364-365) — не трогать.
  • Сигнатура _qg0_errors(name, description) -> list не меняется.

4. Поведение границы (точная семантика)

  • Условие fail — строго len(name) > limit. То есть len == limit → PASS, len == limit + 1 → FAIL.
  • При дефолте: 200 символов → PASS, 201 → FAIL.
  • При ORCH_QG0_TITLE_MAX=120: 120 → PASS, 121 → FAIL.

5. Graceful-обработка невалидного значения (требование AC-3)

Требование: невалидное/отсутствующее ORCH_QG0_TITLE_MAX → используется дефолт 200, процесс не падает.

Нюанс для архитектора/разработчика: pydantic_settings по умолчанию при непарсящемся в int значении env (например ORCH_QG0_TITLE_MAX=abc или пустая строка) выбрасывает ValidationError на инстанцировании Settings() — т.е. падение на старте процесса. Это противоречит требованию graceful. Реализация должна обеспечить, что:

  • отсутствие переменной → дефолт 200 (это стандартное поведение, ОК «из коробки»);
  • пустая строка / нечисловое значение → дефолт 200 без исключения.

Способ (на усмотрение архитектора, без предписания со стороны аналитика) — например field-validator с mode="before", который при невалидном входе возвращает дефолт. Конкретный механизм фиксируется в ADR на стадии architecture.

6. Изменения API

Нет. Эндпоинты не меняются.

7. Изменения схемы БД

Нет. tasks.title TEXT остаётся без ограничения длины.

8. Новые QG checks

Нет. Реестр QG_CHECKS и STAGE_TRANSITIONS не меняются. QG-0 — не зарегистрированный stage-gate, а inline-валидация входа (_qg0_errors), её контракт сохраняется.

9. Артефакты pipeline, которые должны быть созданы/обновлены

  • .env.example — добавить ORCH_QG0_TITLE_MAX=200 с комментарием.
  • .env.staging.example — добавить ORCH_QG0_TITLE_MAX (дефолт/комментарий).
  • CHANGELOG.md — запись об ORCH-069.
  • README-таблица конфигов / CLAUDE.md — обновить при наличии релевантной таблицы параметров (по требованию reviewer; документация = golden source).
  • Юнит-тесты (tests/) — см. 04-test-plan.yaml.

10. Обратная совместимость

  • Дефолт 200 > прежних 80 → все ранее проходившие заголовки проходят и теперь.
  • Поведение при не заданном env идентично «как было», но с порогом 200 вместо 80.
  • Изменение чисто аддитивное; откатов/миграций не требует.