From 8690a499710c3d4a4e4dde26d1a879694bd86f5d Mon Sep 17 00:00:00 2001 From: Rodribm10 Date: Wed, 15 Apr 2026 10:23:42 -0300 Subject: [PATCH] feat(lifecycle): REST endpoint for lifecycle config singleton --- .../captain/lifecycle_configs_controller.rb | 27 +++++++++++- .../lifecycle_configs/show.json.jbuilder | 1 + .../lifecycle_configs/update.json.jbuilder | 1 + .../captain/_lifecycle_config.json.jbuilder | 10 +++++ .../lifecycle_configs_controller_spec.rb | 42 +++++++++++++++++++ 5 files changed, 79 insertions(+), 2 deletions(-) create mode 100644 enterprise/app/views/api/v1/accounts/captain/lifecycle_configs/show.json.jbuilder create mode 100644 enterprise/app/views/api/v1/accounts/captain/lifecycle_configs/update.json.jbuilder create mode 100644 enterprise/app/views/api/v1/models/captain/_lifecycle_config.json.jbuilder create mode 100644 spec/enterprise/controllers/api/v1/accounts/captain/lifecycle_configs_controller_spec.rb diff --git a/enterprise/app/controllers/api/v1/accounts/captain/lifecycle_configs_controller.rb b/enterprise/app/controllers/api/v1/accounts/captain/lifecycle_configs_controller.rb index 8d7cf21df..a0dea1e33 100644 --- a/enterprise/app/controllers/api/v1/accounts/captain/lifecycle_configs_controller.rb +++ b/enterprise/app/controllers/api/v1/accounts/captain/lifecycle_configs_controller.rb @@ -1,5 +1,28 @@ +# frozen_string_literal: true + class Api::V1::Accounts::Captain::LifecycleConfigsController < Api::V1::Accounts::BaseController - def show - head :ok + before_action :current_account + before_action :set_config + before_action -> { check_authorization(@config) } + + def show; end + + def update + @config.update!(config_params) + render 'api/v1/accounts/captain/lifecycle_configs/show' + end + + private + + def set_config + @config = Captain::Lifecycle::Config.for_account(Current.account) + end + + def config_params + params.require(:config).permit( + :quiet_hours_enabled, :quiet_hours_from, :quiet_hours_to, + :min_interval_minutes, :pause_on_customer_reply, + :pause_on_customer_reply_within_minutes, :opt_out_label_id + ) end end diff --git a/enterprise/app/views/api/v1/accounts/captain/lifecycle_configs/show.json.jbuilder b/enterprise/app/views/api/v1/accounts/captain/lifecycle_configs/show.json.jbuilder new file mode 100644 index 000000000..dee9e5850 --- /dev/null +++ b/enterprise/app/views/api/v1/accounts/captain/lifecycle_configs/show.json.jbuilder @@ -0,0 +1 @@ +json.partial! 'api/v1/models/captain/lifecycle_config', resource: @config diff --git a/enterprise/app/views/api/v1/accounts/captain/lifecycle_configs/update.json.jbuilder b/enterprise/app/views/api/v1/accounts/captain/lifecycle_configs/update.json.jbuilder new file mode 100644 index 000000000..dee9e5850 --- /dev/null +++ b/enterprise/app/views/api/v1/accounts/captain/lifecycle_configs/update.json.jbuilder @@ -0,0 +1 @@ +json.partial! 'api/v1/models/captain/lifecycle_config', resource: @config diff --git a/enterprise/app/views/api/v1/models/captain/_lifecycle_config.json.jbuilder b/enterprise/app/views/api/v1/models/captain/_lifecycle_config.json.jbuilder new file mode 100644 index 000000000..b4114ea8e --- /dev/null +++ b/enterprise/app/views/api/v1/models/captain/_lifecycle_config.json.jbuilder @@ -0,0 +1,10 @@ +json.id resource.id +json.account_id resource.account_id +json.quiet_hours_enabled resource.quiet_hours_enabled +json.quiet_hours_from resource.quiet_hours_from&.strftime('%H:%M') +json.quiet_hours_to resource.quiet_hours_to&.strftime('%H:%M') +json.min_interval_minutes resource.min_interval_minutes +json.pause_on_customer_reply resource.pause_on_customer_reply +json.pause_on_customer_reply_within_minutes resource.pause_on_customer_reply_within_minutes +json.opt_out_label_id resource.opt_out_label_id +json.max_per_reservation 5 diff --git a/spec/enterprise/controllers/api/v1/accounts/captain/lifecycle_configs_controller_spec.rb b/spec/enterprise/controllers/api/v1/accounts/captain/lifecycle_configs_controller_spec.rb new file mode 100644 index 000000000..41d69e17e --- /dev/null +++ b/spec/enterprise/controllers/api/v1/accounts/captain/lifecycle_configs_controller_spec.rb @@ -0,0 +1,42 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe 'Api::V1::Accounts::Captain::LifecycleConfigs', type: :request do + let(:account) { create(:account) } + let(:admin) { create(:user, account: account, role: :administrator) } + let(:agent) { create(:user, account: account, role: :agent) } + + def json_response + JSON.parse(response.body, symbolize_names: true) + end + + describe 'GET /api/v1/accounts/:account_id/captain/lifecycle_config' do + it 'creates a default config on first access' do + get "/api/v1/accounts/#{account.id}/captain/lifecycle_config", + headers: admin.create_new_auth_token, as: :json + expect(response).to have_http_status(:success) + expect(json_response[:quiet_hours_enabled]).to be(false) + expect(json_response[:min_interval_minutes]).to eq(30) + expect(json_response[:max_per_reservation]).to eq(5) + end + end + + describe 'PATCH /api/v1/accounts/:account_id/captain/lifecycle_config' do + it 'blocks agents' do + patch "/api/v1/accounts/#{account.id}/captain/lifecycle_config", + params: { config: { quiet_hours_enabled: true } }, + headers: agent.create_new_auth_token, as: :json + expect(response).to have_http_status(:unauthorized) + end + + it 'updates for admin' do + patch "/api/v1/accounts/#{account.id}/captain/lifecycle_config", + params: { config: { quiet_hours_enabled: true, quiet_hours_from: '22:00', min_interval_minutes: 60 } }, + headers: admin.create_new_auth_token, as: :json + expect(response).to have_http_status(:success) + expect(json_response[:quiet_hours_enabled]).to be(true) + expect(json_response[:min_interval_minutes]).to eq(60) + end + end +end