refactor: dedup admin field-flag application into applyStringFieldFlags (POS-187) - #36
Conversation
…gs (POS-187) The soul/post/feed/profile admin commands each carried a near-identical loop that walked a [][2]string flag→API-key mapping and copied string flags into the request body. feed's version already generalized the two semantics (create = omit empty, update = send changed incl. empty) via a forCreate bool; the other three just hadn't been pointed at it. Extract that loop once as applyStringFieldFlags(cmd, mapping, fields, omitEmpty) and have all four call sites delegate to it. No behavior change: the array (--framework/--tag) and bool handlers are untouched, and the existing e2e/golden wire-body assertions still pass. Net -11 lines, four copies of the loop collapsed to one. Co-Authored-By: Paperclip <noreply@paperclip.ing>
Review: APPROVE ✅ (R. Cutie, POS-195)Verdict: approve — faithful dedup, no behavior change, independently verified byte-identical wire bodies vs Diff review
Independent e2e verification (mock API)Built binaries from
Gates (rerun locally on this branch)
CI hygiene failure — pre-existing, NOT this PRThe red Merge remains a human action per policy. |
What & why (POS-187 daily code-health)
The four hidden admin commands —
soul,post,feed,profile— each carried a near-identical loop that walks a[][2]stringflag→API-key mapping and copies string flags into the JSON request body.feed's copy already generalized the two semantics via aforCreatebool; the other three just hadn't been pointed at it. This is the single clearest copy-paste cluster in the repo (the rest ofinternal/cli/internal/api/outputis already well-factored), so it's today's highest impact-to-risk win.Change
Extract the loop once as:
omitEmpty=true(create): send only non-empty values → empty optionals fall through to server defaults.omitEmpty=false(update): send every explicitly-set flag, incl. empty → clears the field.All four call sites now delegate:
applySoulFieldFlags/applyPostFieldFlags→…, false(keep their--framework/--tagarray handlers untouched)applyFeedStringFlags→ thin wrapper passingforCreatethrough (call sites unchanged)profile createinline loop →…, trueBefore / after
admin.go,post.go,feed.go,profile.go.Behavior
No behavior change. The only mechanical difference is that the shared helper calls
GetStringon every mapped flag rather than only changed ones — harmless, since every mapped flag is registered and theChanged/omitEmptyguard still decides inclusion. Wire-body ordering is preserved (ordered[][2]string).Gates
go build ./...✓go vet ./...✓make fmt-check✓ (clean)make lint✓ (golangci-lint v2.12.2, 0 issues)make test-race✓ (full suite incl.cmd/positronicke2e + golden wire-body assertions that pin--framework→frameworks,--tag→tags,--author-handle, create paths)Never merged — handing to R. Cutie for review + e2e.
Co-Authored-By: Paperclip noreply@paperclip.ing
🤖 Generated with Claude Code