feat(lifecycle): REST endpoint for lifecycle rules CRUD

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Rodribm10 2026-04-15 10:17:59 -03:00
parent cb67a1063d
commit 7c17a7cb96
7 changed files with 148 additions and 1 deletions

View File

@ -1,5 +1,43 @@
class Api::V1::Accounts::Captain::LifecycleRulesController < Api::V1::Accounts::BaseController
before_action :current_account
before_action -> { check_authorization(Captain::Lifecycle::Rule) }
before_action :set_rule, only: [:show, :update, :destroy]
def index
head :ok
@rules = Current.account.captain_lifecycle_rules.order(priority: :asc, id: :desc)
end
def show; end
def create
@rule = Current.account.captain_lifecycle_rules.create!(
rule_params.merge(created_by_user: Current.user)
)
render 'api/v1/accounts/captain/lifecycle_rules/show'
end
def update
@rule.update!(rule_params)
render 'api/v1/accounts/captain/lifecycle_rules/show'
end
def destroy
@rule.destroy!
head :no_content
end
private
def set_rule
@rule = Current.account.captain_lifecycle_rules.find(params[:id])
end
def rule_params
params.require(:rule).permit(
:name, :description, :enabled, :event, :offset_minutes,
:message_type, :message_body, :priority,
filters: {},
message_payload: {}
)
end
end

View File

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

View File

@ -0,0 +1,9 @@
json.payload do
json.array! @rules do |rule|
json.partial! 'api/v1/models/captain/lifecycle_rule', resource: rule
end
end
json.meta do
json.total_count @rules.count
end

View File

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

View File

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

View File

@ -0,0 +1,15 @@
json.id resource.id
json.account_id resource.account_id
json.name resource.name
json.description resource.description
json.enabled resource.enabled
json.event resource.event
json.offset_minutes resource.offset_minutes
json.filters resource.filters || {}
json.message_type resource.message_type
json.message_body resource.message_body
json.message_payload resource.message_payload
json.priority resource.priority
json.created_by_user_id resource.created_by_user_id
json.created_at resource.created_at&.iso8601
json.updated_at resource.updated_at&.iso8601

View File

@ -0,0 +1,82 @@
require 'rails_helper'
RSpec.describe 'Api::V1::Accounts::Captain::LifecycleRules', type: :request do
let(:account) { create(:account) }
let(:admin) { create(:user, account: account, role: :administrator) }
let(:agent) { create(:user, account: account, role: :agent) }
let(:other_account) { create(:account) }
def json_response
JSON.parse(response.body, symbolize_names: true)
end
describe 'GET /api/v1/accounts/:account_id/captain/lifecycle_rules' do
it 'returns 401 when unauthenticated' do
get "/api/v1/accounts/#{account.id}/captain/lifecycle_rules"
expect(response).to have_http_status(:unauthorized)
end
it 'returns the account rules (and not others)' do
create_list(:captain_lifecycle_rule, 2, account: account)
create(:captain_lifecycle_rule, account: other_account)
get "/api/v1/accounts/#{account.id}/captain/lifecycle_rules",
headers: admin.create_new_auth_token, as: :json
expect(response).to have_http_status(:success)
expect(json_response[:payload].length).to eq(2)
end
end
describe 'POST /api/v1/accounts/:account_id/captain/lifecycle_rules' do
let(:valid_params) do
{
rule: {
name: 'Lembrete pré check-in',
event: 'checkin.scheduled_at',
offset_minutes: -10,
message_type: 'text',
message_body: 'Oi {{ customer.first_name }}',
filters: { unit_ids: [1] },
enabled: true
}
}
end
it 'blocks agents' do
post "/api/v1/accounts/#{account.id}/captain/lifecycle_rules",
params: valid_params, headers: agent.create_new_auth_token, as: :json
expect(response).to have_http_status(:unauthorized)
end
it 'creates for admin' do
post "/api/v1/accounts/#{account.id}/captain/lifecycle_rules",
params: valid_params, headers: admin.create_new_auth_token, as: :json
expect(response).to have_http_status(:success)
expect(json_response[:name]).to eq('Lembrete pré check-in')
expect(Captain::Lifecycle::Rule.where(account: account).count).to eq(1)
end
end
describe 'PATCH /api/v1/accounts/:account_id/captain/lifecycle_rules/:id' do
let(:rule) { create(:captain_lifecycle_rule, account: account, name: 'old') }
it 'updates for admin' do
patch "/api/v1/accounts/#{account.id}/captain/lifecycle_rules/#{rule.id}",
params: { rule: { name: 'new' } },
headers: admin.create_new_auth_token, as: :json
expect(response).to have_http_status(:success)
expect(rule.reload.name).to eq('new')
end
end
describe 'DELETE /api/v1/accounts/:account_id/captain/lifecycle_rules/:id' do
it 'destroys for admin' do
rule = create(:captain_lifecycle_rule, account: account)
delete "/api/v1/accounts/#{account.id}/captain/lifecycle_rules/#{rule.id}",
headers: admin.create_new_auth_token, as: :json
expect(response).to have_http_status(:success)
expect(Captain::Lifecycle::Rule.where(id: rule.id)).to be_empty
end
end
end