iachat/enterprise/app/services/captain/lifecycle/scheduler.rb
Rodribm10 bb4631f427 feat(lifecycle): add Scheduler service and DispatcherJob stub
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 01:35:31 -03:00

61 lines
2.1 KiB
Ruby

# frozen_string_literal: true
class Captain::Lifecycle::Scheduler
CHECKIN_EVENTS = %w[checkin.scheduled_at checkin.detected].freeze
class << self
def schedule_for(reservation)
rules = Captain::Lifecycle::Rule
.where(account_id: reservation.account_id)
.active
rules.each { |rule| schedule_one_rule(reservation, rule) }
end
def cancel_pending(reservation)
Captain::Lifecycle::Delivery
.where(captain_reservation_id: reservation.id, status: 'scheduled')
.update_all(status: 'cancelled', updated_at: Time.current) # rubocop:disable Rails/SkipsModelValidations
end
def reschedule_for_checkin_change(reservation)
Captain::Lifecycle::Delivery
.where(captain_reservation_id: reservation.id, status: 'scheduled')
.joins('INNER JOIN captain_lifecycle_rules ON captain_lifecycle_rules.id = captain_lifecycle_deliveries.lifecycle_rule_id')
.where(captain_lifecycle_rules: { event: CHECKIN_EVENTS })
.update_all(status: 'cancelled', updated_at: Time.current) # rubocop:disable Rails/SkipsModelValidations
Captain::Lifecycle::Rule
.where(account_id: reservation.account_id, event: CHECKIN_EVENTS)
.active
.each { |rule| schedule_one_rule(reservation, rule) }
end
private
def schedule_one_rule(reservation, rule)
return unless rule.matches_reservation?(reservation)
fire_at = compute_fire_at(reservation, rule)
return if fire_at.nil? || fire_at <= Time.current
delivery = Captain::Lifecycle::Delivery.create!(
account_id: reservation.account_id,
lifecycle_rule_id: rule.id,
captain_reservation_id: reservation.id,
inbox_id: reservation.unit&.concierge_inbox_id,
fire_at: fire_at,
status: 'scheduled',
origin: 'scheduled_lifecycle'
)
Captain::Lifecycle::DispatcherJob.perform_at(fire_at, delivery.id)
end
def compute_fire_at(reservation, rule)
event_time = Captain::Lifecycle::EventResolver.resolve(reservation, rule.event)
return nil if event_time.nil?
event_time + rule.offset_minutes.minutes
end
end
end