feat(masters): add direct masters adimages delete/set - #677
Conversation
|
@claude @codex review PR #677 at exact head 6046684 (round 75587fb9-94e5-442a-9404-3a6deef10f09). Focus on critical issues: bugs, security vulnerabilities, logical errors, data loss risks, performance problems. Do NOT nitpick style, naming conventions, minor formatting, or subjective preferences — only flag issues that could break functionality or cause real harm in production. |
|
Claude finished @axisrow's task in 2m 54s —— View job Review:
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6046684aa7
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| "masters.adimages.delete", | ||
| "masters.adimages.set", |
There was a problem hiding this comment.
Add dry-run protection to destructive image commands
When an operator supplies the wrong campaign ID or accidentally uses --all, these browser-driven commands can immediately remove the entire production image set without a preview checkpoint. Adding masters.adimages.delete and masters.adimages.set to DRY_RUN_EXCEPTIONS bypasses the repository's required safety contract; implement --dry-run so it resolves the current set and reports the planned removals/uploads without saving instead of exempting these destructive commands.
AGENTS.md reference: AGENTS.md:L493-L496
Useful? React with 👍 / 👎.
| if not before_ids: | ||
| return {"CampaignId": campaign_id, "Deleted": 0, "Count": 0} |
There was a problem hiding this comment.
Honor --launch when the image set is already empty
When --all --launch targets an empty DRAFT campaign, this early return skips _save_and_verify_images, so the publish button is never clicked even though the command reports success; the equivalent shortcut in set_master_images at lines 2031–2032 causes the same behavior for set --allow-empty --launch. Only treat the empty operation as a no-op when launch is false, otherwise continue through the draft-launch path.
Useful? React with 👍 / 👎.
f4d4736 to
fd0ac00
Compare
Completes the `masters adimages` subgroup: with `get` (read) and `add` (append) already in place, these two cover removal and whole-set replacement, so a campaign's images can be managed end-to-end rather than only point-replaced via `masters update --image`. direct masters adimages delete 72349978 --position 2 direct masters adimages delete 72349978 --all direct masters adimages set 72349978 --image-file a.png `delete` addresses images by `--position` (1-based, as shown by `adimages get`), `--content-id`, or `--all`. `--all` on an already-empty set is an idempotent no-op — no modal is opened and nothing is saved — while naming a position or content ID that doesn't exist is always an error. `--all` cannot be combined with `--position`/`--content-id`: the combination is ambiguous and risks silent data loss, so it is a UsageError rather than a silent "ignore the narrower ones". `set` replaces the whole set inside ONE `_apply_image_operations` call (remove everything, then upload everything), so a 5→5 replacement never transiently exceeds Yandex's cap the way a two-phase delete-then-add would. With no `--image-file` at all it would empty the set, so it requires an explicit `--allow-empty` — a guard against an accidentally empty shell glob, not a restriction: the empty end state stays reachable, just deliberately, and `delete --all` says the same thing more plainly. Leaving a campaign with zero images is a valid end state, which is what `_verify_image_set_mismatches`'s absolute end-state check exists for: `delete --all` genuinely asserts the saved set is now empty rather than inferring it from a count delta the way the older "removed == added" verifier had to. Confirmed live 2026-08-03 on DRAFT campaign 713234191: delete --position, delete --all, set (full replacement) and set --allow-empty all round-tripped across a fresh reload. This settles the one previously-unverified risk flagged when the primitive was written — Yandex's Save control stays clickable when the modal's selection is reduced to zero. Refs #648 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
6046684 to
2c6875e
Compare
Триаж замечаний Codex1. P1
|
Смерджено с флаки тестом, вроде он вынесен в фоллоу ап AGENTS.md described the canonical shape as exactly `direct <group> <command>`, which no longer matches the repo: PR #674 made three command tree walkers recursive specifically to support nested groups, and PR #675-#677 shipped `masters adimages get|add|delete|set` as a real three-level leaf. The stale wording already produced a false P1 from Codex on PR #675, citing these exact lines as a contract violation. Reword the contract to describe a path of one or more group segments plus a leaf command, each segment validated the same way, and add `masters adimages` as a documented example of the existing pattern. Closes #680 Co-authored-by: axisrow <axisrow@users.noreply.github.com>
…813) Смерджено в ручную Re-recon (2026-08-08, DRAFT campaign 713234191) of everything `masters update --image`/`masters adimages get/add/delete/set` (#670/#672/#675-#677) depend on, per issue #648's Этап D follow-up instructions (same discipline video's #806->#811 correction required). - Every ImageSuggestionsEditor*/ImageSuggestionsEditorModal* testid constant matches the live DOM exactly — no corrections needed, unlike video's guessed-and-wrong testids. - _apply_image_operations's previously "not live-verified" risk — uploading multiple files via one set_input_files([path1, path2]) call — is now confirmed working live (panel grew 3 -> 5 after one such call). - No genuine new command was warranted: images already have a full variable-length add/remove surface via 'masters adimages add/delete/set' (#675-#677), a deliberate command-group split from 'masters update --image' point-replacement made when #670/#675-#677 were originally scoped — adding --add-image/--remove-image flags to 'update' on top of that would just create two competing APIs for the same operation. All live interactions were abandoned via the modal's Cancel button (never Save) — verified the campaign's saved image set is unchanged before and after. Part of #648. Claude-Session: https://claude.ai/code/session_01PcYzUsFvZbn6VLhLAFuYgv Co-authored-by: axisrow <axisrow@users.noreply.github.com> Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
Завершает подгруппу
masters adimages: с уже имеющимисяget(чтение) иadd(дозапись) эти две команды закрывают удаление и замену всего набора, так что изображениями кампании можно управлять от начала до конца, а не только точечно заменять черезmasters update --image.deleteадресует изображения по--position(1-based, как показываетadimages get), по--content-idили через--all.--allна уже пустом наборе — идемпотентный no-op: модалка не открывается и ничего не сохраняется, — тогда как указание несуществующей позиции или content ID всегда ошибка.--allнельзя комбинировать с--position/--content-id: комбинация неоднозначна и рискует молчаливой потерей данных, поэтому этоUsageError, а не тихое «проигнорируем более узкие».setзаменяет весь набор внутри ОДНОГО вызова_apply_image_operations(удалить всё, затем загрузить всё), так что замена 5→5 никогда не превышает лимит Яндекса транзиентно, как это сделала бы двухфазная связка delete-then-add. Без единого--image-fileкоманда опустошила бы набор, поэтому она требует явного--allow-empty— защита от случайно пустого шелл-глоба, а не ограничение: пустое конечное состояние остаётся достижимым, просто осознанно, аdelete --allговорит то же самое прямее.Кампания с нулём изображений — валидное конечное состояние, и именно ради этого существует абсолютная проверка конечного состояния в
_verify_image_set_mismatches:delete --allдействительно утверждает, что сохранённый набор теперь пуст, а не выводит это из дельты счётчиков, как приходилось старому верификатору «удалено == добавлено».Живая проверка 2026-08-03 на DRAFT-кампании 713234191:
delete --position,delete --all,set(полная замена) иset --allow-empty— все прошли round-trip через свежую перезагрузку. Это закрывает единственный ранее непроверенный риск, отмеченный при написании примитива: контрол «Сохранить» у Яндекса остаётся кликабельным, когда выбор в модалке сведён к нулю.Refs #648
🤖 Generated with Claude Code