feat(lifecycle): REST endpoint for lifecycle deliveries audit log

This commit is contained in:
Rodribm10 2026-04-15 10:29:24 -03:00
parent 8690a49971
commit 0b195781c5
5 changed files with 133 additions and 1 deletions

View File

@ -1,5 +1,46 @@
class Api::V1::Accounts::Captain::LifecycleDeliveriesController < Api::V1::Accounts::BaseController
RESULTS_PER_PAGE = 25
MAX_RESULTS_PER_PAGE = 100
before_action :current_account
before_action -> { check_authorization(Captain::Lifecycle::Delivery) }
before_action :set_page, only: [:index]
before_action :set_delivery, only: [:show]
def index
head :ok
scope = base_scope
scope = apply_filters(scope)
@total_count = scope.count
@deliveries = scope.page(@page).per(@per_page)
end
def show; end
private
def set_page
@page = (params[:page] || 1).to_i
@per_page = [(params[:per_page] || RESULTS_PER_PAGE).to_i, MAX_RESULTS_PER_PAGE].min
end
def set_delivery
@delivery = Current.account.captain_lifecycle_deliveries.find(params[:id])
end
def base_scope
Current.account.captain_lifecycle_deliveries
.includes(:lifecycle_rule, captain_reservation: :contact)
.order(created_at: :desc)
end
# rubocop:disable Metrics/AbcSize
def apply_filters(scope)
scope = scope.where(status: params[:status]) if params[:status].present?
scope = scope.where(lifecycle_rule_id: params[:rule_id]) if params[:rule_id].present?
scope = scope.where(captain_reservation_id: params[:reservation_id]) if params[:reservation_id].present?
scope = scope.where('fire_at >= ?', params[:from]) if params[:from].present?
scope = scope.where('fire_at <= ?', params[:to]) if params[:to].present?
scope
end
# rubocop:enable Metrics/AbcSize
end

View File

@ -0,0 +1,11 @@
json.payload do
json.array! @deliveries do |delivery|
json.partial! 'api/v1/models/captain/lifecycle_delivery', resource: delivery
end
end
json.meta do
json.total_count @total_count
json.page @page
json.per_page @per_page
end

View File

@ -0,0 +1 @@
json.partial! 'api/v1/models/captain/lifecycle_delivery', resource: @delivery

View File

@ -0,0 +1,24 @@
json.id resource.id
json.account_id resource.account_id
json.lifecycle_rule_id resource.lifecycle_rule_id
json.lifecycle_rule_name resource.lifecycle_rule&.name
json.captain_reservation_id resource.captain_reservation_id
json.conversation_id resource.conversation_id
json.inbox_id resource.inbox_id
json.fire_at resource.fire_at&.iso8601
json.sent_at resource.sent_at&.iso8601
json.status resource.status
json.skip_reason resource.skip_reason
json.failure_reason resource.failure_reason
json.rendered_body resource.rendered_body
json.origin resource.origin
if resource.captain_reservation
json.reservation do
json.id resource.captain_reservation.id
json.suite_identifier resource.captain_reservation.suite_identifier
contact = resource.captain_reservation.contact
json.customer_name contact&.name
json.customer_phone contact&.phone_number
end
end

View File

@ -0,0 +1,55 @@
require 'rails_helper'
RSpec.describe 'Api::V1::Accounts::Captain::LifecycleDeliveries', type: :request do
let(:account) { create(:account) }
let(:admin) { create(:user, account: account, role: :administrator) }
let(:unit) { create(:captain_unit, account: account) }
let(:reservation) { create(:captain_reservation, account: account, unit: unit) }
def json_response
JSON.parse(response.body, symbolize_names: true)
end
describe 'GET /api/v1/accounts/:account_id/captain/lifecycle_deliveries' do
before do
allow(Captain::Lifecycle::Scheduler).to receive(:schedule_for)
end
it 'returns deliveries of the account, paginated' do
create_list(:captain_lifecycle_delivery, 3, account: account, captain_reservation: reservation)
get "/api/v1/accounts/#{account.id}/captain/lifecycle_deliveries",
headers: admin.create_new_auth_token, as: :json
expect(response).to have_http_status(:success)
expect(json_response[:payload].length).to eq(3)
expect(json_response[:meta][:total_count]).to eq(3)
end
it 'filters by status' do
create(:captain_lifecycle_delivery, account: account, captain_reservation: reservation, status: 'sent', sent_at: Time.current)
create(:captain_lifecycle_delivery, account: account, captain_reservation: reservation, status: 'skipped', skip_reason: 'quiet_hours')
get "/api/v1/accounts/#{account.id}/captain/lifecycle_deliveries?status=skipped",
headers: admin.create_new_auth_token, as: :json
expect(json_response[:payload].length).to eq(1)
expect(json_response[:payload].first[:status]).to eq('skipped')
end
end
describe 'GET /api/v1/accounts/:account_id/captain/lifecycle_deliveries/:id' do
before { allow(Captain::Lifecycle::Scheduler).to receive(:schedule_for) }
it 'returns the rendered_body' do
delivery = create(:captain_lifecycle_delivery,
account: account,
captain_reservation: reservation,
rendered_body: 'Oi João!')
get "/api/v1/accounts/#{account.id}/captain/lifecycle_deliveries/#{delivery.id}",
headers: admin.create_new_auth_token, as: :json
expect(response).to have_http_status(:success)
expect(json_response[:rendered_body]).to eq('Oi João!')
end
end
end