refactor(commands): shared execute_request for single-item mutation tails (#589 #13) - #594
Conversation
…ails (#589) Dedup audit (#589 finding #13, follow-up of #582/epic #584). Across ~22 modules the single-item add/update/set subcommands ended with the same four-step tail — print the body under --dry-run, else build the client, post, and format the extracted result as JSON; only the service name varied (the RPC method already lives in `body`). That tail is hoisted into one `execute_request(ctx, service, body, dry_run, create_client)` in `_execute.py`; each command keeps its own `body` construction. Named method-agnostically (per review) so it covers add, update and set-bids alike. CLI surface byte-identical — `create_client` is passed from the caller's module global (resolved at call time), so `patch.object(<module>, "create_client")` keeps intercepting the live path; get commands (which format with --format, not hardcoded JSON) are untouched. Full offline suite green (2536 passed); ruff clean. `make_set_bids_command` (#12, the set-bids *body* dedup) remains in #589. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
@claude @codex review. Focus on critical issues only. Mechanical dedup (#589 #13): the identical single-item add/update/set tail (dry-run print → client_from_ctx → client.().post(data=body) → format extract as JSON) across ~22 modules is hoisted into one method-agnostic execute_request in _execute.py. Per-command body construction is unchanged. Please confirm (a) byte-identity of every migrated tail — no request method/service/payload change, dry-run output identical; (b) patchability preserved — create_client is passed from each caller's module global (resolved at call time), so patch.object(, create_client) still intercepts; (c) the regex did not migrate any get tail (those format with --format, not hardcoded JSON) or any command with extra processing in the tail. Do NOT nitpick style/naming/formatting. |
|
Claude finished @axisrow's task in 2m 16s —— View job Review:
|
|
Claude finished @axisrow's task in 15s —— View job Acknowledged — merge confirmed ✅Noted: PR #594 merged on the clean review (all three invariants verified — byte-identity of the migrated single-item Nothing further to do here. Remaining in #589:
|
Part of #589 (finding #13) / follow-up of #582 / эпик #584.
Что сделано
В ~22 модулях одиночные
add/update/set-команды заканчивались одинаковым хвостом из 4 шагов — печатьbodyпод--dry-run, иначе построить клиент, отправить и отформатироватьresult().extract()как JSON; различался только сервис (RPC-метод уже лежит вbody). Этот хвост вынесён в одинexecute_request(ctx, service, body, dry_run, create_client)вdirect_cli/commands/_execute.py; построениеbody(сборка item) остаётся в каждой команде.Хелпер назван метод-агностично (по итогам
/simplify-ревью): покрывает add, update и set-bids одинаково.Байт-идентичность
create_clientпередаётся из module global вызывающей команды (резолвится в момент вызова), поэтомуpatch.object(<module>, "create_client")продолжает перехватывать live-путь (в отличие от фабрик; обычное тело команды перечитывает глобал каждый вызов). Покрытоtest_cli(патч ads/campaigns create_client + invoke mutation).format_output(..., output_format, output), не hardcoded JSON — regex не совпадает)./simplify: 2 ревьюера. Applied: метод-агностичное имя + покрытие update (altitude). Отклонено: слияние с_batch.send_batch(разные задачи — chunking/partial-success vs простой single-item хвост); «patchability-риск» — намеренный корректный дизайн, доказан suite.Diff: +97 / −297 (нетто −200), 23 файла.
Остаётся в #589
make_set_bids_command(дедуп тела set-bids: сборкаBids[]+ валидация селектор/bid-полей в 4 модулях).🤖 Generated with Claude Code