From 13acb6c0521050231c017c366901730274b9842f Mon Sep 17 00:00:00 2001 From: Rafael Batista Date: Fri, 3 Apr 2026 15:28:41 -0300 Subject: [PATCH 1/2] iniciando o desenvolvimento da api mobile --- app/controllers/mobile/v1/auth_controller.rb | 62 +++++++++++++ app/controllers/mobile/v1/base_controller.rb | 44 ++++++++++ .../mobile/v1/budgets_controller.rb | 85 ++++++++++++++++++ .../mobile/v1/health_controller.rb | 11 +++ .../mobile/v1/order_services_controller.rb | 88 +++++++++++++++++++ app/models/mobile_api_session.rb | 40 +++++++++ app/models/user.rb | 1 + config/environments/development.rb | 1 + config/environments/production.rb | 1 + config/routes.rb | 1 + config/routes/mobile.rb | 13 +++ ...260403111500_create_mobile_api_sessions.rb | 17 ++++ db/schema.rb | 17 +++- 13 files changed, 380 insertions(+), 1 deletion(-) create mode 100644 app/controllers/mobile/v1/auth_controller.rb create mode 100644 app/controllers/mobile/v1/base_controller.rb create mode 100644 app/controllers/mobile/v1/budgets_controller.rb create mode 100644 app/controllers/mobile/v1/health_controller.rb create mode 100644 app/controllers/mobile/v1/order_services_controller.rb create mode 100644 app/models/mobile_api_session.rb create mode 100644 config/routes/mobile.rb create mode 100644 db/migrate/20260403111500_create_mobile_api_sessions.rb diff --git a/app/controllers/mobile/v1/auth_controller.rb b/app/controllers/mobile/v1/auth_controller.rb new file mode 100644 index 00000000..63c2d9b9 --- /dev/null +++ b/app/controllers/mobile/v1/auth_controller.rb @@ -0,0 +1,62 @@ +class Mobile::V1::AuthController < Mobile::V1::BaseController + skip_before_action :authenticate_mobile_user!, only: [:login] + + TOKEN_TTL = 30.days + + def login + email = params[:email].to_s.downcase.strip + password = params[:password].to_s + + user = User.find_by(email: email) + if user.blank? || !user.valid_password?(password) + return render json: { error: "Credenciais inválidas." }, status: :unauthorized + end + + unless user.active? + return render json: { error: "Usuário inativo." }, status: :forbidden + end + + unless user.access_enabled? + return render json: { error: "Acesso da empresa está desativado." }, status: :forbidden + end + + expires_at = (Time.current + TOKEN_TTL).end_of_day + token = MobileApiSession.issue_for!(user: user, expires_at: expires_at) + + render json: { + token: token, + token_type: "Bearer", + expires_at: expires_at.iso8601, + user: mobile_user_payload(user) + }, status: :ok + end + + def me + render json: { user: mobile_user_payload(current_mobile_user) }, status: :ok + end + + def logout + current_mobile_session&.revoke! + render json: { message: "Logout realizado com sucesso." }, status: :ok + end + + def logout_all + current_mobile_user.mobile_api_sessions.active.update_all(revoked_at: Time.current, updated_at: Time.current) + render json: { message: "Logout de todos os dispositivos realizado com sucesso." }, status: :ok + end + + private + + def mobile_user_payload(user) + { + id: user.id, + name: user.name, + email: user.email, + role: user.role, + company: { + id: user.company_id, + name: user.company&.name + } + } + end +end diff --git a/app/controllers/mobile/v1/base_controller.rb b/app/controllers/mobile/v1/base_controller.rb new file mode 100644 index 00000000..8baf2a12 --- /dev/null +++ b/app/controllers/mobile/v1/base_controller.rb @@ -0,0 +1,44 @@ +class Mobile::V1::BaseController < ActionController::API + before_action :authenticate_mobile_user! + + attr_reader :current_mobile_session + attr_reader :current_mobile_user + + private + + def authenticate_mobile_user! + token = bearer_token + return render_unauthorized("Token de acesso não informado.") if token.blank? + + session = MobileApiSession.find_active_by_raw_token(token) + return render_unauthorized("Token inválido ou expirado.") if session.blank? + + user = session.user + return render_unauthorized("Usuário inativo.") unless user.active? + return render_unauthorized("Acesso da empresa está desativado.") unless user.access_enabled? + + @current_mobile_session = session + @current_mobile_user = user + touch_mobile_session_usage + end + + def bearer_token + header = request.headers["Authorization"].to_s + return if header.blank? + + scheme, token = header.split(" ", 2) + return if scheme.to_s.downcase != "bearer" + + token + end + + def render_unauthorized(message) + render json: { error: message }, status: :unauthorized + end + + def touch_mobile_session_usage + return if current_mobile_session.blank? + + current_mobile_session.update_column(:last_used_at, Time.current) + end +end diff --git a/app/controllers/mobile/v1/budgets_controller.rb b/app/controllers/mobile/v1/budgets_controller.rb new file mode 100644 index 00000000..d13f3429 --- /dev/null +++ b/app/controllers/mobile/v1/budgets_controller.rb @@ -0,0 +1,85 @@ +class Mobile::V1::BudgetsController < Mobile::V1::BaseController + def index + scope = current_mobile_user.company.budgets.includes(:client, :order_service) + scope = scope.where(status: params[:status]) if valid_status_filter? + + page = [params[:page].to_i, 1].max + per = params[:per].to_i + per = 20 if per <= 0 + per = 100 if per > 100 + + budgets = scope.order(created_at: :desc).page(page).per(per) + + render json: { + data: budgets.map { |budget| budget_index_payload(budget) }, + meta: { + current_page: budgets.current_page, + total_pages: budgets.total_pages, + total_count: budgets.total_count, + per_page: budgets.limit_value + } + }, status: :ok + end + + def show + budget = current_mobile_user.company.budgets + .includes(:client, :order_service, :service_items) + .find(params[:id]) + + render json: { data: budget_show_payload(budget) }, status: :ok + end + + private + + def valid_status_filter? + params[:status].present? && Budget.statuses.key?(params[:status].to_s) + end + + def budget_index_payload(budget) + { + id: budget.id, + code: budget.code, + title: budget.title, + status: budget.status, + client_name: budget.client&.name, + valid_until: budget.valid_until&.iso8601, + approval_expires_at: budget.approval_expires_at&.iso8601, + total_value: budget.total_value.to_s + } + end + + def budget_show_payload(budget) + { + id: budget.id, + code: budget.code, + title: budget.title, + description: budget.description, + status: budget.status, + valid_until: budget.valid_until&.iso8601, + approval_expires_at: budget.approval_expires_at&.iso8601, + approval_sent_at: budget.approval_sent_at&.iso8601, + approved_at: budget.approved_at&.iso8601, + rejected_at: budget.rejected_at&.iso8601, + rejection_reason: budget.rejection_reason, + estimated_delivery_days: budget.estimated_delivery_days, + total_value: budget.total_value.to_s, + client: { + id: budget.client_id, + name: budget.client&.name + }, + order_service: { + id: budget.order_service_id, + code: budget.order_service&.code + }, + service_items: budget.service_items.order(:created_at).map do |item| + { + id: item.id, + description: item.description, + quantity: item.quantity, + unit_price: item.unit_price.to_s, + total_price: (item.quantity.to_d * item.unit_price.to_d).to_s + } + end + } + end +end diff --git a/app/controllers/mobile/v1/health_controller.rb b/app/controllers/mobile/v1/health_controller.rb new file mode 100644 index 00000000..1c5abf9d --- /dev/null +++ b/app/controllers/mobile/v1/health_controller.rb @@ -0,0 +1,11 @@ +class Mobile::V1::HealthController < Mobile::V1::BaseController + skip_before_action :authenticate_mobile_user! + + def show + render json: { + status: "ok", + service: "catalystops-mobile-api", + version: "v1" + }, status: :ok + end +end diff --git a/app/controllers/mobile/v1/order_services_controller.rb b/app/controllers/mobile/v1/order_services_controller.rb new file mode 100644 index 00000000..862c7aa6 --- /dev/null +++ b/app/controllers/mobile/v1/order_services_controller.rb @@ -0,0 +1,88 @@ +class Mobile::V1::OrderServicesController < Mobile::V1::BaseController + def index + scope = current_mobile_user.company.order_services.includes(:client, :users) + scope = scope.where(status: params[:status]) if valid_status_filter? + + page = [params[:page].to_i, 1].max + per = params[:per].to_i + per = 20 if per <= 0 + per = 100 if per > 100 + + order_services = scope.order(created_at: :desc).page(page).per(per) + + render json: { + data: order_services.map { |os| order_service_index_payload(os) }, + meta: { + current_page: order_services.current_page, + total_pages: order_services.total_pages, + total_count: order_services.total_count, + per_page: order_services.limit_value + } + }, status: :ok + end + + def show + order_service = current_mobile_user.company.order_services + .includes(:client, :users, :service_items) + .find(params[:id]) + + render json: { data: order_service_show_payload(order_service) }, status: :ok + end + + private + + def valid_status_filter? + params[:status].present? && OrderService.statuses.key?(params[:status].to_s) + end + + def order_service_index_payload(order_service) + { + id: order_service.id, + code: order_service.code, + title: order_service.title, + status: order_service.status, + client_name: order_service.client&.name, + technicians: order_service.users.map(&:name), + scheduled_at: order_service.scheduled_at&.iso8601, + expected_end_at: order_service.expected_end_at&.iso8601, + total_value: order_service.total_value.to_s + } + end + + def order_service_show_payload(order_service) + { + id: order_service.id, + code: order_service.code, + title: order_service.title, + description: order_service.description, + status: order_service.status, + observations: order_service.observations, + rejection_reason: order_service.rejection_reason, + scheduled_at: order_service.scheduled_at&.iso8601, + expected_end_at: order_service.expected_end_at&.iso8601, + started_at: order_service.started_at&.iso8601, + finished_at: order_service.finished_at&.iso8601, + client: { + id: order_service.client_id, + name: order_service.client&.name + }, + technicians: order_service.users.map { |user| { id: user.id, name: user.name } }, + financial: { + subtotal_value: order_service.subtotal_value.to_s, + discount_type: order_service.discount_type, + discount_value: order_service.discount_value.to_s, + discount_amount: order_service.discount_amount.to_s, + total_value: order_service.total_value.to_s + }, + service_items: order_service.service_items.order(:created_at).map do |item| + { + id: item.id, + description: item.description, + quantity: item.quantity, + unit_price: item.unit_price.to_s, + total_price: (item.quantity.to_d * item.unit_price.to_d).to_s + } + end + } + end +end diff --git a/app/models/mobile_api_session.rb b/app/models/mobile_api_session.rb new file mode 100644 index 00000000..6bcb0b8d --- /dev/null +++ b/app/models/mobile_api_session.rb @@ -0,0 +1,40 @@ +class MobileApiSession < ApplicationRecord + TOKEN_BYTES = 32 + + belongs_to :user + + validates :token_digest, presence: true, uniqueness: true + validates :expires_at, presence: true + + scope :active, -> { where(revoked_at: nil).where("expires_at > ?", Time.current) } + + def self.issue_for!(user:, expires_at:) + raw_token = SecureRandom.hex(TOKEN_BYTES) + create!( + user: user, + token_digest: digest(raw_token), + expires_at: expires_at, + last_used_at: Time.current + ) + + raw_token + end + + def self.find_active_by_raw_token(raw_token) + return nil if raw_token.blank? + + active.find_by(token_digest: digest(raw_token)) + end + + def self.digest(raw_token) + Digest::SHA256.hexdigest(raw_token.to_s) + end + + def active? + revoked_at.nil? && expires_at.future? + end + + def revoke! + update!(revoked_at: Time.current) + end +end diff --git a/app/models/user.rb b/app/models/user.rb index 9d5da73b..18b33ff4 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -23,6 +23,7 @@ class User < ApplicationRecord has_many :order_services, through: :assignments has_many :clients, foreign_key: :company_id, primary_key: :company_id, class_name: "Client" has_many :reports, dependent: :destroy + has_many :mobile_api_sessions, dependent: :destroy has_many :support_tickets, dependent: :nullify has_many :assigned_support_tickets, class_name: "SupportTicket", foreign_key: :assigned_to_id, dependent: :nullify diff --git a/config/environments/development.rb b/config/environments/development.rb index ab79b704..a01a5a9d 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -87,6 +87,7 @@ config.hosts << "register.catalystops.local" config.hosts << "webhook.catalystops.local" config.hosts << "sidekiq.catalystops.local" + config.hosts << "mobile.catalystops.local" config.hosts << /.*\.catalystops\.local/ config.action_dispatch.tld_length = 1 diff --git a/config/environments/production.rb b/config/environments/production.rb index ed74a5c8..cc3c6f81 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -143,6 +143,7 @@ config.hosts << "register.catalystops.com.br" config.hosts << "webhook.catalystops.com.br" config.hosts << "sidekiq.catalystops.com.br" + config.hosts << "mobile.catalystops.com.br" config.hosts << "localhost" config.hosts << "127.0.0.1" diff --git a/config/routes.rb b/config/routes.rb index 126b6d36..589a96c9 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -20,6 +20,7 @@ def draw(routes_name) draw :register draw :cliente draw :webhook + draw :mobile # Rotas padrão (sem subdomínio) # root to: "home#index" diff --git a/config/routes/mobile.rb b/config/routes/mobile.rb new file mode 100644 index 00000000..73f8c99f --- /dev/null +++ b/config/routes/mobile.rb @@ -0,0 +1,13 @@ +constraints subdomain: "mobile" do + scope module: "mobile/v1", path: "v1", defaults: { format: :json } do + get "health", to: "health#show" + + post "auth/login", to: "auth#login" + get "auth/me", to: "auth#me" + delete "auth/logout", to: "auth#logout" + delete "auth/logout_all", to: "auth#logout_all" + + resources :order_services, only: [:index, :show] + resources :budgets, only: [:index, :show] + end +end diff --git a/db/migrate/20260403111500_create_mobile_api_sessions.rb b/db/migrate/20260403111500_create_mobile_api_sessions.rb new file mode 100644 index 00000000..f04eb315 --- /dev/null +++ b/db/migrate/20260403111500_create_mobile_api_sessions.rb @@ -0,0 +1,17 @@ +class CreateMobileApiSessions < ActiveRecord::Migration[7.1] + def change + create_table :mobile_api_sessions, id: :uuid do |t| + t.references :user, null: false, type: :uuid, foreign_key: true + t.string :token_digest, null: false + t.datetime :expires_at, null: false + t.datetime :last_used_at + t.datetime :revoked_at + + t.timestamps + end + + add_index :mobile_api_sessions, :token_digest, unique: true + add_index :mobile_api_sessions, [:user_id, :revoked_at] + add_index :mobile_api_sessions, :expires_at + end +end diff --git a/db/schema.rb b/db/schema.rb index f0384272..e1b97e7a 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.1].define(version: 2026_04_02_131500) do +ActiveRecord::Schema[7.1].define(version: 2026_04_03_111500) do # These are extensions that must be enabled in order to support this database enable_extension "pgcrypto" enable_extension "plpgsql" @@ -218,6 +218,20 @@ # Could not dump table "knowledge_base_articles" because of following StandardError # Unknown type 'vector(1536)' for column 'embedding' + create_table "mobile_api_sessions", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + t.uuid "user_id", null: false + t.string "token_digest", null: false + t.datetime "expires_at", null: false + t.datetime "last_used_at" + t.datetime "revoked_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["expires_at"], name: "index_mobile_api_sessions_on_expires_at" + t.index ["token_digest"], name: "index_mobile_api_sessions_on_token_digest", unique: true + t.index ["user_id", "revoked_at"], name: "index_mobile_api_sessions_on_user_id_and_revoked_at" + t.index ["user_id"], name: "index_mobile_api_sessions_on_user_id" + end + create_table "order_services", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| t.string "title" t.text "description" @@ -448,6 +462,7 @@ add_foreign_key "coupon_redemptions", "companies" add_foreign_key "coupon_redemptions", "coupons" add_foreign_key "coupon_redemptions", "subscriptions" + add_foreign_key "mobile_api_sessions", "users" add_foreign_key "order_services", "clients" add_foreign_key "order_services", "companies" add_foreign_key "reports", "companies" From d1cbe5413a42cc658bde1f90bfbb621921f53758 Mon Sep 17 00:00:00 2001 From: Rafael Batista Date: Fri, 3 Apr 2026 16:31:41 -0300 Subject: [PATCH 2/2] ajustando os logs de acesso mobile --- app/controllers/mobile/v1/auth_controller.rb | 32 +++++++----- app/controllers/mobile/v1/base_controller.rb | 49 +++++++++++++++++++ .../mobile/v1/budgets_controller.rb | 35 +++++++------ .../mobile/v1/order_services_controller.rb | 37 ++++++++------ app/models/audit_event.rb | 2 +- app/services/audit/action_catalog.rb | 10 ++++ 6 files changed, 122 insertions(+), 43 deletions(-) diff --git a/app/controllers/mobile/v1/auth_controller.rb b/app/controllers/mobile/v1/auth_controller.rb index 63c2d9b9..bd3cc5c1 100644 --- a/app/controllers/mobile/v1/auth_controller.rb +++ b/app/controllers/mobile/v1/auth_controller.rb @@ -8,20 +8,15 @@ def login password = params[:password].to_s user = User.find_by(email: email) - if user.blank? || !user.valid_password?(password) - return render json: { error: "Credenciais inválidas." }, status: :unauthorized - end - - unless user.active? - return render json: { error: "Usuário inativo." }, status: :forbidden - end - - unless user.access_enabled? - return render json: { error: "Acesso da empresa está desativado." }, status: :forbidden - end + return login_error!(email: email, user: user, message: "Credenciais inválidas.", status: :unauthorized) if user.blank? || !user.valid_password?(password) + return login_error!(email: email, user: user, message: "Usuário inativo.", status: :forbidden) unless user.active? + return login_error!(email: email, user: user, message: "Acesso da empresa está desativado.", status: :forbidden) unless user.access_enabled? expires_at = (Time.current + TOKEN_TTL).end_of_day token = MobileApiSession.issue_for!(user: user, expires_at: expires_at) + Current.user = user + Current.source = "mobile" + Audit::AuthLogger.login_succeeded(user: user) render json: { token: token, @@ -32,21 +27,36 @@ def login end def me + mobile_audit( + action: "mobile.api.auth.me.viewed", + metadata: { user_id: current_mobile_user.id } + ) + render json: { user: mobile_user_payload(current_mobile_user) }, status: :ok end def logout current_mobile_session&.revoke! + Audit::AuthLogger.logout_succeeded(user: current_mobile_user) render json: { message: "Logout realizado com sucesso." }, status: :ok end def logout_all current_mobile_user.mobile_api_sessions.active.update_all(revoked_at: Time.current, updated_at: Time.current) + mobile_audit( + action: "mobile.api.auth.logout_all.succeeded", + metadata: { user_id: current_mobile_user.id } + ) render json: { message: "Logout de todos os dispositivos realizado com sucesso." }, status: :ok end private + def login_error!(email:, user:, message:, status:) + Audit::AuthLogger.login_failed(email: email, user: user) + render json: { error: message }, status: status + end + def mobile_user_payload(user) { id: user.id, diff --git a/app/controllers/mobile/v1/base_controller.rb b/app/controllers/mobile/v1/base_controller.rb index 8baf2a12..765071b1 100644 --- a/app/controllers/mobile/v1/base_controller.rb +++ b/app/controllers/mobile/v1/base_controller.rb @@ -1,5 +1,6 @@ class Mobile::V1::BaseController < ActionController::API before_action :authenticate_mobile_user! + around_action :with_mobile_current_context attr_reader :current_mobile_session attr_reader :current_mobile_user @@ -36,9 +37,57 @@ def render_unauthorized(message) render json: { error: message }, status: :unauthorized end + def mobile_company + current_mobile_user&.company + end + + def mobile_audit(action:, resource: nil, metadata: {}, actor: nil, company: nil) + resolved_actor = actor || current_mobile_user + resolved_company = company || resolved_actor&.company || mobile_company + + Audit::Log.call( + action: action, + actor: resolved_actor, + company: resolved_company, + resource: resource, + metadata: metadata + ) + end + + def pagination_params(default_per: 20, max_per: 100) + page = [params[:page].to_i, 1].max + per = params[:per].to_i + per = default_per if per <= 0 + per = max_per if per > max_per + [page, per] + end + + def render_paginated(data:, collection:) + render json: { + data: data, + meta: { + current_page: collection.current_page, + total_pages: collection.total_pages, + total_count: collection.total_count, + per_page: collection.limit_value + } + }, status: :ok + end + def touch_mobile_session_usage return if current_mobile_session.blank? current_mobile_session.update_column(:last_used_at, Time.current) end + + def with_mobile_current_context + Current.user = current_mobile_user + Current.request_id = request.request_id + Current.ip_address = request.remote_ip + Current.user_agent = request.user_agent + Current.source = "mobile" + yield + ensure + Current.reset + end end diff --git a/app/controllers/mobile/v1/budgets_controller.rb b/app/controllers/mobile/v1/budgets_controller.rb index d13f3429..e13cf8f6 100644 --- a/app/controllers/mobile/v1/budgets_controller.rb +++ b/app/controllers/mobile/v1/budgets_controller.rb @@ -1,30 +1,35 @@ class Mobile::V1::BudgetsController < Mobile::V1::BaseController def index - scope = current_mobile_user.company.budgets.includes(:client, :order_service) + scope = mobile_company.budgets.includes(:client, :order_service) scope = scope.where(status: params[:status]) if valid_status_filter? - page = [params[:page].to_i, 1].max - per = params[:per].to_i - per = 20 if per <= 0 - per = 100 if per > 100 - + page, per = pagination_params budgets = scope.order(created_at: :desc).page(page).per(per) + mobile_audit( + action: "mobile.api.budgets.listed", + metadata: { + status: params[:status], + page: page, + per: per, + count: budgets.size + } + ) - render json: { + render_paginated( data: budgets.map { |budget| budget_index_payload(budget) }, - meta: { - current_page: budgets.current_page, - total_pages: budgets.total_pages, - total_count: budgets.total_count, - per_page: budgets.limit_value - } - }, status: :ok + collection: budgets + ) end def show - budget = current_mobile_user.company.budgets + budget = mobile_company.budgets .includes(:client, :order_service, :service_items) .find(params[:id]) + mobile_audit( + action: "mobile.api.budgets.viewed", + resource: budget, + metadata: { budget_id: budget.id } + ) render json: { data: budget_show_payload(budget) }, status: :ok end diff --git a/app/controllers/mobile/v1/order_services_controller.rb b/app/controllers/mobile/v1/order_services_controller.rb index 862c7aa6..27de0521 100644 --- a/app/controllers/mobile/v1/order_services_controller.rb +++ b/app/controllers/mobile/v1/order_services_controller.rb @@ -1,30 +1,35 @@ class Mobile::V1::OrderServicesController < Mobile::V1::BaseController def index - scope = current_mobile_user.company.order_services.includes(:client, :users) + scope = mobile_company.order_services.includes(:client, :users) scope = scope.where(status: params[:status]) if valid_status_filter? - page = [params[:page].to_i, 1].max - per = params[:per].to_i - per = 20 if per <= 0 - per = 100 if per > 100 - + page, per = pagination_params order_services = scope.order(created_at: :desc).page(page).per(per) - - render json: { - data: order_services.map { |os| order_service_index_payload(os) }, - meta: { - current_page: order_services.current_page, - total_pages: order_services.total_pages, - total_count: order_services.total_count, - per_page: order_services.limit_value + mobile_audit( + action: "mobile.api.order_services.listed", + metadata: { + status: params[:status], + page: page, + per: per, + count: order_services.size } - }, status: :ok + ) + + render_paginated( + data: order_services.map { |order_service| order_service_index_payload(order_service) }, + collection: order_services + ) end def show - order_service = current_mobile_user.company.order_services + order_service = mobile_company.order_services .includes(:client, :users, :service_items) .find(params[:id]) + mobile_audit( + action: "mobile.api.order_services.viewed", + resource: order_service, + metadata: { order_service_id: order_service.id } + ) render json: { data: order_service_show_payload(order_service) }, status: :ok end diff --git a/app/models/audit_event.rb b/app/models/audit_event.rb index ca8dc169..505acfd3 100644 --- a/app/models/audit_event.rb +++ b/app/models/audit_event.rb @@ -1,5 +1,5 @@ class AuditEvent < ApplicationRecord - SOURCES = %w[app admin login cliente webhook job system].freeze + SOURCES = %w[app admin login cliente webhook mobile job system].freeze belongs_to :company, optional: true diff --git a/app/services/audit/action_catalog.rb b/app/services/audit/action_catalog.rb index 1f47c1cb..b15aa476 100644 --- a/app/services/audit/action_catalog.rb +++ b/app/services/audit/action_catalog.rb @@ -82,6 +82,15 @@ module ActionCatalog webhook.failed ].freeze + MOBILE_API = %w[ + mobile.api.auth.me.viewed + mobile.api.auth.logout_all.succeeded + mobile.api.order_services.listed + mobile.api.order_services.viewed + mobile.api.budgets.listed + mobile.api.budgets.viewed + ].freeze + SYSTEM = %w[ job.started job.completed @@ -100,6 +109,7 @@ module ActionCatalog coupons: COUPONS, subscriptions: SUBSCRIPTIONS, webhooks: WEBHOOKS, + mobile_api: MOBILE_API, system: SYSTEM }.freeze