feat(lifecycle): add ContextBuilder for Liquid render variables
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
8e0a06246b
commit
f6aa39921a
63
enterprise/app/services/captain/lifecycle/context_builder.rb
Normal file
63
enterprise/app/services/captain/lifecycle/context_builder.rb
Normal file
@ -0,0 +1,63 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class Captain::Lifecycle::ContextBuilder
|
||||
def self.build(reservation)
|
||||
new(reservation).build
|
||||
end
|
||||
|
||||
def initialize(reservation)
|
||||
@reservation = reservation
|
||||
@contact = reservation.contact
|
||||
@unit = reservation.unit
|
||||
end
|
||||
|
||||
def build
|
||||
{
|
||||
'customer' => customer_context,
|
||||
'reservation' => reservation_context,
|
||||
'hotel' => hotel_context
|
||||
}
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def customer_context
|
||||
name = @contact&.name.to_s
|
||||
{
|
||||
'name' => name,
|
||||
'first_name' => name.split.first.to_s,
|
||||
'phone' => @contact&.phone_number.to_s,
|
||||
'cpf' => @contact&.custom_attributes.to_h['cpf'].to_s
|
||||
}
|
||||
end
|
||||
|
||||
def reservation_context
|
||||
{
|
||||
'suite' => @reservation.suite_identifier.to_s,
|
||||
'unit_name' => @unit&.name.to_s,
|
||||
'check_in_at' => format_datetime(@reservation.check_in_at),
|
||||
'check_out_at' => format_datetime(@reservation.check_out_at),
|
||||
'amount' => format_money(@reservation.total_amount),
|
||||
'permanencia' => @reservation.metadata.to_h['permanencia'].to_s
|
||||
}
|
||||
end
|
||||
|
||||
def hotel_context
|
||||
(@unit&.concierge_variables || {}).stringify_keys
|
||||
end
|
||||
|
||||
def format_datetime(value)
|
||||
return '' unless value
|
||||
|
||||
value.in_time_zone('America/Sao_Paulo').strftime('%d/%m/%Y %H:%M')
|
||||
end
|
||||
|
||||
def format_money(value)
|
||||
ActiveSupport::NumberHelper.number_to_currency(
|
||||
value.to_f,
|
||||
unit: 'R$ ',
|
||||
separator: ',',
|
||||
delimiter: '.'
|
||||
)
|
||||
end
|
||||
end
|
||||
@ -0,0 +1,69 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Captain::Lifecycle::ContextBuilder do
|
||||
let(:account) { create(:account) }
|
||||
let(:brand) { create(:captain_brand, account: account) }
|
||||
let(:unit) do
|
||||
Captain::Unit.create!(
|
||||
account: account,
|
||||
brand: brand,
|
||||
name: 'Águas Lindas',
|
||||
concierge_config: {
|
||||
'persona_name' => 'Sofia',
|
||||
'variables' => { 'wifi_password' => 'hotel1001', 'menu_link' => 'https://menu.x' }
|
||||
}
|
||||
)
|
||||
end
|
||||
let(:contact) { create(:contact, account: account, name: 'João Silva', phone_number: '+5561999999999') }
|
||||
let(:reservation) do
|
||||
create(:captain_reservation,
|
||||
account: account,
|
||||
unit: unit,
|
||||
contact: contact,
|
||||
suite_identifier: 'Alexa',
|
||||
total_amount: 160.0,
|
||||
check_in_at: Time.zone.parse('2026-04-20 22:00:00'),
|
||||
check_out_at: Time.zone.parse('2026-04-21 12:00:00'),
|
||||
metadata: { 'permanencia' => 'Pernoite' })
|
||||
end
|
||||
|
||||
describe '.build' do
|
||||
subject(:ctx) { described_class.build(reservation) }
|
||||
|
||||
it 'includes customer.name and first_name' do
|
||||
expect(ctx['customer']['name']).to eq('João Silva')
|
||||
expect(ctx['customer']['first_name']).to eq('João')
|
||||
end
|
||||
|
||||
it 'includes customer.phone' do
|
||||
expect(ctx['customer']['phone']).to eq('+5561999999999')
|
||||
end
|
||||
|
||||
it 'includes reservation.suite' do
|
||||
expect(ctx['reservation']['suite']).to eq('Alexa')
|
||||
end
|
||||
|
||||
it 'includes reservation.unit_name' do
|
||||
expect(ctx['reservation']['unit_name']).to eq('Águas Lindas')
|
||||
end
|
||||
|
||||
it 'formats reservation.amount as BRL' do
|
||||
expect(ctx['reservation']['amount']).to include('R$')
|
||||
expect(ctx['reservation']['amount']).to include('160')
|
||||
end
|
||||
|
||||
it 'includes reservation.permanencia' do
|
||||
expect(ctx['reservation']['permanencia']).to eq('Pernoite')
|
||||
end
|
||||
|
||||
it 'includes hotel.wifi_password from unit variables' do
|
||||
expect(ctx['hotel']['wifi_password']).to eq('hotel1001')
|
||||
end
|
||||
|
||||
it 'includes hotel.menu_link from unit variables' do
|
||||
expect(ctx['hotel']['menu_link']).to eq('https://menu.x')
|
||||
end
|
||||
end
|
||||
end
|
||||
Loading…
Reference in New Issue
Block a user