restore: re-merge ORCH-069 qg0_title_max
All checks were successful
CI / test (pull_request) Successful in 21s

# Conflicts:
#	CHANGELOG.md
This commit is contained in:
stream
2026-06-08 14:58:30 +03:00
18 changed files with 866 additions and 2 deletions

View File

@@ -1,3 +1,4 @@
from pydantic import field_validator
from pydantic_settings import BaseSettings
@@ -422,6 +423,24 @@ class Settings(BaseSettings):
tracker_live_status_ttl_s: int = 60
tracker_live_status_timeout_s: int = 3
# 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
@field_validator("qg0_title_max", mode="before")
@classmethod
def _qg0_title_max_default(cls, v):
# Graceful (ORCH-069 AC-3): empty / non-numeric env -> default 200, the
# process must not crash on startup. Never raises (self-hosting safety).
try:
if v is None or (isinstance(v, str) and v.strip() == ""):
return 200
return int(v)
except (TypeError, ValueError):
return 200
class Config:
env_prefix = "ORCH_"
env_file = ".env"

View File

@@ -416,8 +416,11 @@ def _qg0_errors(name: str, description: str) -> list:
errors = []
if not name or len(name) < 5:
errors.append("Title \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u043a\u043e\u0440\u043e\u0442\u043a\u0438\u0439 (\u043d\u0443\u0436\u043d\u043e >= 5 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432)")
if len(name) > 80:
errors.append("Title \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u0434\u043b\u0438\u043d\u043d\u044b\u0439 (\u043c\u0430\u043a\u0441\u0438\u043c\u0443\u043c 80 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432)")
if len(name) > settings.qg0_title_max:
errors.append(
f"Title \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u0434\u043b\u0438\u043d\u043d\u044b\u0439 "
f"(\u043c\u0430\u043a\u0441\u0438\u043c\u0443\u043c {settings.qg0_title_max} \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432)"
)
if not description or len(description.strip()) < 20:
errors.append("Description \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u043a\u043e\u0440\u043e\u0442\u043a\u0438\u0439 (\u043d\u0443\u0436\u043d\u043e >= 20 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432)")