Class: CardTransition

Inherits:
Object
  • Object
show all
Defined in:
app/services/card_transition.rb

Overview

The only code path that moves a card between columns. Validates legality, runs the old column's leave policy and the new column's enter policy, and emits the transition events (§3, §11). Controllers and future automations all call this — never Card#update(column:) directly.

Defined Under Namespace

Classes: Result

Instance Method Summary collapse

Constructor Details

#initialize(card, to_column:, position: nil, actor: "user") ⇒ CardTransition

Returns a new instance of CardTransition.



8
9
10
11
12
13
14
# File 'app/services/card_transition.rb', line 8

def initialize(card, to_column:, position: nil, actor: "user")
  @card = card
  @from = card.column
  @to = to_column
  @position = position
  @actor = actor
end

Instance Method Details

#callObject



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'app/services/card_transition.rb', line 16

def call
  return reposition! if @from == @to
  return failure("Column belongs to a different board") if @to.board_id != @card.board_id
  if @card.working? && @from.execution?
    # An agent process is live — no silent kills (§3). Cancel it first.
    return failure("##{@card.number} has an active run — cancel it before moving the card")
  end
  # Accept policy (card #15): the destination decides which columns may feed
  # it, forcing cards through a defined workflow rather than any-to-any drops.
  return rejected! unless @to.accepts?(@from)

  Card.transaction do
    leave_policy!
    place_in_column!
    enter_policy!
  end
  Result.new(success?: true, card: @card, error: nil)
rescue ActiveRecord::RecordInvalid => e
  failure(e.message)
end