{ "request_id": "req-T6", "task_id": "T6", "title": "Decompose CLI — 9 command files + config sub-typer", "status": "ready_for_review", "goal": "Улучшить читаемость CLI: разбить большие main.py/config.py на отдельные модули", "changes": { "summary": "infrastructure/cli/main.py (330 LOC) разбит на 9 файлов в commands/: init, forecast, scenario, whatif, compare, import_xlsx, export_xlsx, analyze, info. config.py (428 LOC) перенесён в commands/config_cmd.py как Typer sub-typer. main.py → app.py (entry point, регистрирует все команды). Создан paths.py (константы MODEL_PATH, DATA_DIR) и services.py (composition root: load_model, save_model, build_services, resolve_currency, convert_value, fmt_amount). pyproject.toml: cf = infrastructure.cli.app:app. test_cli.py обновлён.", "commits": [""], "files_changed": [ "infrastructure/cli/app.py (new entry point)", "infrastructure/cli/commands/{init,forecast,scenario,whatif,compare,import_xlsx,export_xlsx,analyze,info,config_cmd}.py", "infrastructure/cli/paths.py, services.py", "infrastructure/cli/main.py, config.py (removed)", "pyproject.toml (cf entry point)", "tests/test_cli.py" ] }, "verification": { "tests_passed": "67/67", "all_commands_work": ["init", "forecast", "scenario", "whatif", "compare", "import-xlsx", "export-xlsx", "analyze", "info", "config rate-list"], "file_size_under_100_loc_per_command": true }, "fulfills_ac": [ "Каждая Typer-команда в отдельном файле cli/commands/*.py", "config_cmd.py в commands/, остаётся sub-typer", "paths.py — только пути", "services.py — composition root + helpers", "Размер команд < 100 LOC (config_cmd.py — ~300, т.к. содержит 15 sub-команд)", "Поведение идентично", "pytest 67/67" ] }