Class: WhittakerTech::Aeon::Occurrence

Inherits:
ApplicationRecord show all
Defined in:
app/models/whittaker_tech/aeon/occurrence.rb

Overview

A materialized prediction projected from an Allocation. Each occurrence represents a single point or span on the timeline, with an immutable +time_range+ (tstzrange) backed by a GiST index for efficient range queries.

Coordinates (+time_range+, +starts_at+, +ends_at+, +allocation_id+) are frozen after creation. Only invalidation metadata and +state+ may change. Surgical per-instance deviations are expressed via Override, not by mutating the occurrence.

Constant Summary collapse

COORDINATE_FIELDS =

Fields that are immutable once the occurrence is persisted. Any AR-level mutation of these triggers +ReadonlyAttributeError+.

%w[
  time_range starts_at ends_at allocation_id
].freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Attribute Details

#allocationAllocation

The allocation that projected this occurrence.

Returns:



40
# File 'app/models/whittaker_tech/aeon/occurrence.rb', line 40

belongs_to :allocation, inverse_of: :occurrences

#invalidated_by_allocationAllocation?

The successor allocation that caused this occurrence to be invalidated during a fork operation.

Returns:



46
47
48
49
# File 'app/models/whittaker_tech/aeon/occurrence.rb', line 46

belongs_to :invalidated_by_allocation,
class_name: 'WhittakerTech::Aeon::Allocation',
inverse_of: :invalidated_occurrences,
optional: true

#overrideOverride? (readonly)

Optional surgical deviation (cancellation or reschedule).

Returns:



54
# File 'app/models/whittaker_tech/aeon/occurrence.rb', line 54

has_one :override, inverse_of: :occurrence

#stateString

Returns currently only +“active”+ (0).

Returns:

  • (String)

    currently only +“active”+ (0)



26
# File 'app/models/whittaker_tech/aeon/occurrence.rb', line 26

enum :state, { active: 0 }

Class Method Details

.activeActiveRecord::Relation

Occurrences that have not been invalidated or purged. Matches the partial index +idx_aeon_occurrences_active+.

Returns:

  • (ActiveRecord::Relation)


61
# File 'app/models/whittaker_tech/aeon/occurrence.rb', line 61

scope :active, -> { where(invalidated_at: nil, purged_at: nil) }

.invalidatedActiveRecord::Relation

Occurrences that have been invalidated by a fork.

Returns:

  • (ActiveRecord::Relation)


67
# File 'app/models/whittaker_tech/aeon/occurrence.rb', line 67

scope :invalidated, -> { where.not(invalidated_at: nil) }

.within_range(range) ⇒ ActiveRecord::Relation

Occurrences whose +time_range+ overlaps the given range, using the GiST-indexed +&&+ operator.

Parameters:

  • range (Range, String)

    a PG-compatible tstzrange

Returns:

  • (ActiveRecord::Relation)


75
# File 'app/models/whittaker_tech/aeon/occurrence.rb', line 75

scope :within_range, ->(range) { where('time_range && ?', range) }