Class: WhittakerTech::Aeon::OverrideApplier

Inherits:
Object
  • Object
show all
Defined in:
app/services/whittaker_tech/aeon/override_applier.rb

Overview

Stateless service that applies a surgical single-instance deviation to an Occurrence. Creates an Override row — either a cancellation or a replacement time range. Never triggers re-projection.

A DB unique index ensures at most one override per occurrence.

Examples:

Cancel an occurrence

OverrideApplier.call(occurrence_id: occ.id, canceled: true)

Reschedule an occurrence

OverrideApplier.call(occurrence_id: occ.id, replacement_time_range: new_range)

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(occurrence_id:, canceled:, replacement_time_range:) ⇒ OverrideApplier

Returns a new instance of OverrideApplier.

Parameters:

  • occurrence_id (String)

    UUID of the occurrence to override

  • canceled (Boolean)

    whether to cancel the occurrence

  • replacement_time_range (String, nil)

    replacement tstzrange



36
37
38
39
40
# File 'app/services/whittaker_tech/aeon/override_applier.rb', line 36

def initialize(occurrence_id:, canceled:, replacement_time_range:)
  @occurrence_id = occurrence_id
  @canceled = canceled
  @replacement_time_range = replacement_time_range
end

Class Method Details

.call(occurrence_id:, canceled: false, replacement_time_range: nil) ⇒ Override

Returns the created override record.

Parameters:

  • occurrence_id (String)

    UUID of the occurrence to override

  • canceled (Boolean) (defaults to: false)

    whether to cancel the occurrence (default: false)

  • replacement_time_range (String, nil) (defaults to: nil)

    PG tstzrange literal for rescheduling (mutually exclusive with +canceled: true+, setting both will raise an ArgumentError)

Returns:

  • (Override)

    the created override record

Raises:

  • (ArgumentError)


23
24
25
26
27
28
29
30
31
# File 'app/services/whittaker_tech/aeon/override_applier.rb', line 23

def self.call(occurrence_id:, canceled: false, replacement_time_range: nil)
  raise ArgumentError, 'cannot cancel and replace simultaneously' if canceled && replacement_time_range

  new(
    occurrence_id: occurrence_id,
    canceled: canceled,
    replacement_time_range: replacement_time_range
  ).call
end

Instance Method Details

#callOverride

Finds the occurrence, validates it, and creates the override.

Returns:

Raises:

  • (ActiveRecord::RecordNotFound)

    if the occurrence does not exist

  • (ArgumentError)

    if the occurrence is invalidated or no action (neither +canceled+ nor +replacement_time_range+) is specified



48
49
50
51
52
# File 'app/services/whittaker_tech/aeon/override_applier.rb', line 48

def call
  occurrence = find_occurrence!
  validate_occurrence!(occurrence)
  create_override!(occurrence)
end