Class: Aidp::Harness::UsagePeriod

Inherits:
Object
  • Object
show all
Defined in:
lib/aidp/harness/usage_period.rb

Overview

Immutable value object representing a usage tracking period Handles time period calculations, boundaries, and reset logic

Constant Summary collapse

PERIOD_TYPES =
%w[daily weekly monthly].freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(period_type:, reset_day: 1, reference_time: Time.now) ⇒ UsagePeriod

Returns a new instance of UsagePeriod.



39
40
41
42
43
44
45
46
# File 'lib/aidp/harness/usage_period.rb', line 39

def initialize(period_type:, reset_day: 1, reference_time: Time.now)
  @period_type = validate_period_type(period_type)
  @reset_day = validate_reset_day(reset_day)
  @reference_time = reference_time

  calculate_boundaries
  freeze
end

Instance Attribute Details

#end_timeObject (readonly)

Returns the value of attribute end_time.



13
14
15
# File 'lib/aidp/harness/usage_period.rb', line 13

def end_time
  @end_time
end

#period_typeObject (readonly)

Returns the value of attribute period_type.



13
14
15
# File 'lib/aidp/harness/usage_period.rb', line 13

def period_type
  @period_type
end

#reset_dayObject (readonly)

Returns the value of attribute reset_day.



13
14
15
# File 'lib/aidp/harness/usage_period.rb', line 13

def reset_day
  @reset_day
end

#start_timeObject (readonly)

Returns the value of attribute start_time.



13
14
15
# File 'lib/aidp/harness/usage_period.rb', line 13

def start_time
  @start_time
end

Class Method Details

.current(period_type:, reset_day: 1, reference_time: Time.now) ⇒ UsagePeriod

Create a UsagePeriod for the current time

Parameters:

  • period_type (String)

    Type of period: daily, weekly, monthly

  • reset_day (Integer) (defaults to: 1)

    Day of month for reset (1-28 for monthly)

  • reference_time (Time) (defaults to: Time.now)

    Reference time (defaults to now)

Returns:



21
22
23
24
25
26
27
# File 'lib/aidp/harness/usage_period.rb', line 21

def self.current(period_type:, reset_day: 1, reference_time: Time.now)
  new(
    period_type: period_type,
    reset_day: reset_day,
    reference_time: reference_time
  )
end

.from_key(period_key, period_type:) ⇒ UsagePeriod

Create a UsagePeriod from a stored period key

Parameters:

  • period_key (String)

    Period key (e.g., "2024-01", "2024-W01", "2024-01-15")

  • period_type (String)

    Type of period

Returns:



34
35
36
37
# File 'lib/aidp/harness/usage_period.rb', line 34

def self.from_key(period_key, period_type:)
  reference_time = parse_period_key(period_key, period_type)
  new(period_type: period_type, reference_time: reference_time)
end

Instance Method Details

#==(other) ⇒ Object Also known as: eql?

Value equality



125
126
127
128
129
130
131
132
# File 'lib/aidp/harness/usage_period.rb', line 125

def ==(other)
  return false unless other.is_a?(UsagePeriod)

  period_type == other.period_type &&
    reset_day == other.reset_day &&
    start_time == other.start_time &&
    end_time == other.end_time
end

#contains?(time) ⇒ Boolean

Check if a given time falls within this period

Parameters:

  • time (Time)

    Time to check

Returns:

  • (Boolean)

    True if time is within period



66
67
68
# File 'lib/aidp/harness/usage_period.rb', line 66

def contains?(time)
  time >= @start_time && time < @end_time
end

#descriptionString

Human-readable period description

Returns:

  • (String)

    Period description



113
114
115
116
117
118
119
120
121
122
# File 'lib/aidp/harness/usage_period.rb', line 113

def description
  case @period_type
  when "daily"
    @start_time.strftime("%B %d, %Y")
  when "weekly"
    "Week of #{@start_time.strftime("%B %d, %Y")}"
  when "monthly"
    @start_time.strftime("%B %Y")
  end
end

#ended?(current_time = Time.now) ⇒ Boolean

Check if this period has ended

Parameters:

  • current_time (Time) (defaults to: Time.now)

    Current time (defaults to now)

Returns:

  • (Boolean)

    True if period has ended



74
75
76
# File 'lib/aidp/harness/usage_period.rb', line 74

def ended?(current_time = Time.now)
  current_time >= @end_time
end

#hashObject



136
137
138
# File 'lib/aidp/harness/usage_period.rb', line 136

def hash
  [period_type, reset_day, start_time, end_time].hash
end

#next_periodUsagePeriod

Get the next period after this one

Returns:



81
82
83
84
85
86
87
# File 'lib/aidp/harness/usage_period.rb', line 81

def next_period
  self.class.new(
    period_type: @period_type,
    reset_day: @reset_day,
    reference_time: @end_time + 1
  )
end

#period_keyString

Generate a unique key for this period (for storage)

Returns:

  • (String)

    Period key suitable for use as hash key



51
52
53
54
55
56
57
58
59
60
# File 'lib/aidp/harness/usage_period.rb', line 51

def period_key
  case @period_type
  when "daily"
    @start_time.strftime("%Y-%m-%d")
  when "weekly"
    @start_time.strftime("%Y-W%V")
  when "monthly"
    @start_time.strftime("%Y-%m")
  end
end

#previous_periodUsagePeriod

Get the previous period before this one

Returns:



92
93
94
95
96
97
98
# File 'lib/aidp/harness/usage_period.rb', line 92

def previous_period
  self.class.new(
    period_type: @period_type,
    reset_day: @reset_day,
    reference_time: @start_time - 1
  )
end

#remaining_seconds(current_time = Time.now) ⇒ Integer

Calculate remaining time in this period

Parameters:

  • current_time (Time) (defaults to: Time.now)

    Current time (defaults to now)

Returns:

  • (Integer)

    Seconds remaining in period



104
105
106
107
108
# File 'lib/aidp/harness/usage_period.rb', line 104

def remaining_seconds(current_time = Time.now)
  return 0 if ended?(current_time)

  (@end_time - current_time).to_i
end

#to_hObject

Convert to hash for serialization



141
142
143
144
145
146
147
148
149
# File 'lib/aidp/harness/usage_period.rb', line 141

def to_h
  {
    period_type: @period_type,
    reset_day: @reset_day,
    start_time: @start_time.iso8601,
    end_time: @end_time.iso8601,
    period_key: period_key
  }
end