Skip to content

feat(relations): add multi-target issue relation removal - #254

Merged
ruby-automation merged 2 commits into
mainfrom
EXT-42-multi-target-issue-relation-removal
Sep 6, 2026
Merged

feat(relations): add multi-target issue relation removal#254
ruby-automation merged 2 commits into
mainfrom
EXT-42-multi-target-issue-relation-removal

Conversation

@ruby-automation

Copy link
Copy Markdown
Contributor

Summary

  • Implements lc issue relation remove ISSUE RELATED_ISSUE... --type TYPE (aliases: r, rm)
  • Resolves the exact stored relation by listing the subject issue's relations, matching by wire type + direction + endpoint identifier, then calling issueRelationDelete(id:) — no arbitrary deletion
  • blocked-by correctly targets the inbound blocks relation (same reversal logic as add)
  • Absent relation is a per-target no-op; ambiguous match (multiple rows for same endpoint pair) fails that target and lists every matching relation ID
  • Each target is processed independently; partial failures do not roll back successful deletions

Scope of changes

  • app/lib/linear_cli/linear/issue_relation.exdestroy :destroy action + ManualDestroy module calling issueRelationDelete
  • app/lib/linear_cli/linear.exdelete_issue_relation code interface
  • app/lib/linear_cli/cli/commands.exissue_relation_remove/1 with per-target result tuples, matching logic, and human/JSON output
  • app/lib/linear_cli/cli.exremove subcommand spec, dispatch clause, r/rm aliases
  • Tests: ManualDestroy unit tests, CLI command tests (17 new scenarios covering all acceptance criteria), alias normalization tests
  • documents/ash-domain-erd.adoc:destroy action and delete_issue_relation interface documented

Test plan

  • mix precommit passes (format + credo + tests) — confirmed in commit hook
  • 471 tests pass (22 new tests added)
  • All acceptance criteria from EXT-42 covered: removal for all types, blocked-by reversal, N+ targets, absent no-op, ambiguous failure, API error, partial failure, human and JSON output, non-zero exit on failure

Closes EXT-42

🤖 Generated with Claude Code

Implements `lc issue relation remove ISSUE RELATED_ISSUE... --type TYPE`
(aliases: r, rm) as the deletion counterpart to `relation add`.

- Adds ManualDestroy action to IssueRelation backed by the
  `issueRelationDelete(id: String!)` GraphQL mutation
- Adds `delete_issue_relation/1` domain code interface
- Adds `issue_relation_remove/1` in CLI.Commands: resolves the stored
  relation by listing the subject's relations then matching by wire type,
  direction, and endpoint identifier; handles blocked-by reversal;
  absent relation is a per-target no-op; ambiguous match (multiple rows)
  fails with all matching IDs listed; each target processed independently
  with per-target human/JSON result reporting and non-zero exit on failure
- Adds `remove` subcommand spec and dispatch; aliases r and rm
- Extends IssueRelation, Commands, and CLI alias tests; updates ERD doc

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@ruby-automation
ruby-automation force-pushed the EXT-42-multi-target-issue-relation-removal branch from 73d05c7 to 5ed1603 Compare September 6, 2026 02:34

bougyman commented Sep 6, 2026

Copy link
Copy Markdown
Member

There's an ugly case at https://github.com/rubyists/linear-cli/pull/254/files#diff-3c0f086fbd3d0b0af6f9c0e48ed5b2fbc473169f2cbdd632bf4e79ee701af2ebR1222 that needs to be idiomatically elixired. (multiple methods with matchers)

Replace the `case matches do` in `remove_single_relation/4` with three
`do_remove/2` function clauses, matching on the empty list, single-element
list, and multiple-element list patterns — the idiomatic Elixir approach.

No behaviour change; all 471 tests still pass.
@ruby-automation

Copy link
Copy Markdown
Contributor Author

Rework: addressed review feedback

Review comment addressed: "There's an ugly case at line 1222 that needs to be idiomatically elixired. (multiple methods with matchers)"

What changed:

Refactored remove_single_relation/4 in app/lib/linear_cli/cli/commands.ex to replace the case matches do block with three pattern-matched do_remove/2 function clauses — the idiomatic Elixir approach:

  • do_remove([], related_id){:absent, related_id}
  • do_remove([relation], related_id) → calls delete_issue_relation, returns {:removed, ...} or {:failed, ...}
  • do_remove(relations, related_id){:ambiguous, related_id, ids}

The dispatch is now a single pipeline in remove_single_relation/4:

subject_id
|> find_matching_relations(related_id, user_type, all_relations)
|> do_remove(related_id)

No behaviour change. All 471 tests still pass, credo 0 issues (716 mods/funs now with the 3 new do_remove clauses).

Commit: e029548 refactor(relations): use function clauses for remove match dispatch

@ruby-automation
ruby-automation merged commit cbeff42 into main Sep 6, 2026
3 checks passed
@ruby-automation
ruby-automation deleted the EXT-42-multi-target-issue-relation-removal branch September 6, 2026 03:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants