🪶 Aeon::ExceptionManager – 4 + 1 Architecture¶
Marks the moments that should never happen again.
1️⃣ Logical View¶
Purpose:
Manages IceCube exception dates for Aeon recurrences, ensuring mutated occurrences are removed from original series.
Responsibilities
- Insert exception times for skipped occurrences.
- Apply “until” cutoffs for Change All Future.
- Maintain serialized rules in repetition_rules.
2️⃣ Process View¶
- Mutator calls
add_exception(timestamp, time)orend_recurrence_at. - Manager loads IceCube schedule via RecurrenceAdapter.
- Adds
add_exception_timeor setsuntil:. - Serializes back into timestamp.
- CacheInvalidation runs.
3️⃣ Development View¶
File: app/services/aeon/exception_manager.rb
class Aeon::ExceptionManager
def self.add_exception(timestamp, time)
adapter = Aeon::RecurrenceAdapter.new(timestamp)
schedule = adapter.schedule
schedule.add_exception_time(time)
timestamp.update!(repetition_rules: schedule.to_hash)
end
def self.end_recurrence_at(timestamp, cutoff)
adapter = Aeon::RecurrenceAdapter.new(timestamp)
schedule = adapter.schedule
schedule.end_time = cutoff
timestamp.update!(repetition_rules: schedule.to_hash)
end
end
4️⃣ Physical View¶
| Attribute | Description |
|---|---|
| Store | Postgres (via Aeon::Timestamp) |
| Dependency | IceCube |
| Observability | Argus aeon.exception.added |
➕ 1 Scenario View¶
Scenario A – Skipping a Holiday¶
add_exception_time called for Dec 25.
Calendar hides that day automatically.
Scenario B – Splitting Series¶
end_recurrence_at called at edit boundary for Change All Future.