Skip to content

Commit

Permalink
Remove PhonyRails
Browse files Browse the repository at this point in the history
  • Loading branch information
samnang committed Jan 20, 2025
1 parent 0206b8d commit e0efd90
Show file tree
Hide file tree
Showing 27 changed files with 181 additions and 64 deletions.
1 change: 0 additions & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ gem "pg"
gem "pghero"
gem "pg_query"
gem "phony"
gem "phony_rails"
gem "puma"
gem "pumi"
gem "record_tag_helper", github: "rails/record_tag_helper"
Expand Down
4 changes: 0 additions & 4 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -377,9 +377,6 @@ GEM
pghero (3.6.1)
activerecord (>= 6.1)
phony (2.21.1)
phony_rails (0.15.0)
activesupport (>= 3.0)
phony (>= 2.18.12)
propshaft (1.1.0)
actionpack (>= 7.0.0)
activesupport (>= 7.0.0)
Expand Down Expand Up @@ -630,7 +627,6 @@ DEPENDENCIES
pg_query
pghero
phony
phony_rails
propshaft
pry
puma
Expand Down
6 changes: 3 additions & 3 deletions app/models/call_flow_logic/ews_registration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ module CallFlowLogic
class EWSRegistration < Base
Language = Struct.new(:code, :name, :links, keyword_init: true)
FEEDBACK_FEATURE_FLAG_PHONE_NUMBERS = [
"+855715100860", "+85570753999", "+855966164166", "+85592943196", "+855965636025",
"+85578746371", "+85512716884", "+855966946549", "+85511765511"
"855715100860", "85570753999", "855966164166", "85592943196", "855965636025",
"85578746371", "85512716884", "855966946549", "85511765511"
].freeze

# https://en.wikipedia.org/wiki/ISO_639-3
Expand Down Expand Up @@ -286,7 +286,7 @@ def record_feedback?
end

def feedback_enabled?
FEEDBACK_FEATURE_FLAG_PHONE_NUMBERS.include?(phone_call.contact.msisdn)
FEEDBACK_FEATURE_FLAG_PHONE_NUMBERS.include?(phone_call.contact.msisdn.value)
end

def language_gathered?
Expand Down
5 changes: 4 additions & 1 deletion app/models/callout_participation.rb
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
class CalloutParticipation < ApplicationRecord
include MsisdnHelpers
include MetadataHelpers
include HasCallFlowLogic

DEFAULT_RETRY_STATUSES = [
"failed"
].freeze

attribute :msisdn, :phone_number

belongs_to :callout
belongs_to :contact
belongs_to :callout_population,
Expand All @@ -26,6 +27,8 @@ class CalloutParticipation < ApplicationRecord
:set_call_flow_logic,
on: :create

validates :msisdn, presence: true

def self.still_trying(max_phone_calls)
where(answered: false).where(arel_table[:phone_calls_count].lt(max_phone_calls))
end
Expand Down
26 changes: 3 additions & 23 deletions app/models/concerns/msisdn_helpers.rb
Original file line number Diff line number Diff line change
@@ -1,29 +1,9 @@
module MsisdnHelpers
extend ActiveSupport::Concern

included do
delegate :normalize_number, to: :class

validates :msisdn,
presence: true,
phony_plausible: true

before_validation :normalize_msisdn
end

class_methods do
def where_msisdn(value)
where(msisdn: normalize_number(value))
end
NUMBER_FORMAT = /\A\d+\z/

def normalize_number(value)
PhonyRails.normalize_number(value)
end
end

private

def normalize_msisdn
self.msisdn = normalize_number(msisdn)
included do
validates :msisdn, presence: true, format: { with: NUMBER_FORMAT }
end
end
5 changes: 4 additions & 1 deletion app/models/contact.rb
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
class Contact < ApplicationRecord
extend Enumerize

include MsisdnHelpers
include MetadataHelpers

attribute :msisdn, :phone_number

enumerize :status, in: [ :active, :disabled ], scope: :shallow
enumerize :gender, in: [ "M", "F" ]
enumerize :disability_status, in: [ :normal, :disabled ]
Expand All @@ -17,6 +18,8 @@ class Contact < ApplicationRecord
has_many :phone_calls
has_many :remote_phone_call_events, through: :phone_calls

validates :msisdn, presence: true

delegate :call_flow_logic,
to: :account,
allow_nil: true
Expand Down
2 changes: 1 addition & 1 deletion app/models/filter/attribute/msisdn.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ module Filter
module Attribute
class Msisdn < Filter::Base
def apply
association_chain.where(msisdn: PhonyRails.normalize_number(msisdn))
association_chain.where(msisdn: PhoneNumberType.new.cast(msisdn))
end

def apply?
Expand Down
4 changes: 3 additions & 1 deletion app/models/phone_call.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,15 @@ class PhoneCall < ApplicationRecord
inbound: "inbound"
}.freeze

attribute :msisdn, :phone_number

belongs_to :callout_participation, optional: true, counter_cache: true
belongs_to :contact, validate: true
belongs_to :account
belongs_to :callout, optional: true
has_many :remote_phone_call_events, dependent: :restrict_with_error

include MetadataHelpers
include MsisdnHelpers
include HasCallFlowLogic

delegate :call_flow_logic, to: :callout_participation, prefix: true, allow_nil: true
Expand All @@ -41,6 +42,7 @@ class PhoneCall < ApplicationRecord

before_validation :set_defaults, on: :create
before_destroy :validate_destroy
validates :msisdn, presence: true

accepts_nested_key_value_fields_for :remote_response
accepts_nested_key_value_fields_for :remote_queue_response
Expand Down
19 changes: 19 additions & 0 deletions app/models/phone_number_parser.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
class PhoneNumberParser
attr_reader :parser

def initialize(parser: Phony)
@parser = parser
end

def valid?(value)
return false if value.starts_with?("0")

parser.plausible?(value)
end

def split(value)
raise ArgumentError, "Not E-164 number" unless valid?(value)

parser.split(value)
end
end
13 changes: 13 additions & 0 deletions app/request_schemas/application_request_schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,19 @@ class ApplicationRequestSchema < Dry::Validation::Contract

delegate :success?, :errors, to: :result

module Types
include Dry.Types()

Number = String.constructor do |string|
string.gsub(/\D/, "") if string.present?
end

UpcaseString = String.constructor do |string|
string.upcase if string.present?
end
end


register_macro(:phone_number_format) do
key.failure(text: "is invalid") if key? && !Phony.plausible?(value)
end
Expand Down
7 changes: 0 additions & 7 deletions app/request_schemas/types.rb

This file was deleted.

6 changes: 3 additions & 3 deletions app/request_schemas/v1/beneficiary_request_schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ class BeneficiaryRequestSchema < JSONAPIRequestSchema
required(:data).value(:hash).schema do
required(:type).filled(:str?, eql?: "beneficiary")
required(:attributes).value(:hash).schema do
required(:phone_number).filled(:string)
required(:phone_number).filled(Types::Number)
required(:iso_country_code).filled(Types::UpcaseString, included_in?: Contact.iso_country_code.values)
optional(:language_code).maybe(:string)
optional(:date_of_birth).maybe(:date)
Expand All @@ -27,7 +27,7 @@ class BeneficiaryRequestSchema < JSONAPIRequestSchema

attribute_rule(:phone_number).validate(:phone_number_format)
attribute_rule(:phone_number) do |attributes|
next unless account.contacts.where_msisdn(attributes.fetch(:phone_number)).exists?
next unless account.contacts.where(msisdn: attributes.fetch(:phone_number)).exists?

key([ :data, :attributes, :phone_number ]).failure(text: "must be unique")
end
Expand All @@ -45,7 +45,7 @@ class BeneficiaryRequestSchema < JSONAPIRequestSchema

def output
result = super
result[:msisdn] = PhonyRails.normalize_number(result.delete(:phone_number))
result[:msisdn] = result.delete(:phone_number)
result
end
end
Expand Down
6 changes: 3 additions & 3 deletions app/request_schemas/v1/update_beneficiary_request_schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ class UpdateBeneficiaryRequestSchema < JSONAPIRequestSchema
required(:id).filled(:integer)
required(:type).filled(:str?, eql?: "beneficiary")
required(:attributes).value(:hash).schema do
optional(:phone_number).filled(Types::Number)
optional(:iso_country_code).filled(Types::UpcaseString, included_in?: Contact.iso_country_code.values)
optional(:disability_status).maybe(:string, included_in?: Contact.disability_status.values)
optional(:phone_number).filled(:string)
optional(:language_code).maybe(:string)
optional(:date_of_birth).maybe(:date)
optional(:gender).maybe(:string, included_in?: Contact.gender.values)
Expand All @@ -18,15 +18,15 @@ class UpdateBeneficiaryRequestSchema < JSONAPIRequestSchema

attribute_rule(:phone_number).validate(:phone_number_format)
attribute_rule(:phone_number) do |attributes|
next unless account.contacts.where_msisdn(attributes.fetch(:phone_number)).where.not(id: resource.id).exists?
next unless account.contacts.where(msisdn: attributes.fetch(:phone_number)).where.not(id: resource.id).exists?

key([ :data, :attributes, :phone_number ]).failure(text: "must be unique")
end


def output
result = super
result[:msisdn] = PhonyRails.normalize_number(result.delete(:phone_number)) if result.key?(:phone_number)
result[:msisdn] = result.delete(:phone_number) if result.key?(:phone_number)
result
end
end
Expand Down
2 changes: 1 addition & 1 deletion app/serailizers/beneficiary_serializer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ class BeneficiarySerializer < ResourceSerializer
has_many :addresses, serializer: BeneficiaryAddressSerializer

attribute :phone_number do |object|
object.msisdn
object.msisdn.value
end
end
63 changes: 63 additions & 0 deletions app/types/phone_number_type.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
class PhoneNumberType < ActiveRecord::Type::String
AREA_CODE_COUNTRY_PREFIXES = [ "1" ].freeze

PhoneNumber = Struct.new(:value, :country_code, :area_code, :e164, keyword_init: true) do
def to_s
value
end

def e164?
e164
end

def sip?
sip
end

def ==(other)
if other.is_a?(self.class)
value == other.value
else
value == other
end
end

def possible_countries
@possible_countries ||= e164? ? ISO3166::Country.find_all_country_by_country_code(country_code) : ISO3166::Country.all
end

def country
possible_countries.first if possible_countries.one?
end
end

attr_reader :parser

def initialize(**options)
super

@parser = options.fetch(:parser) { PhoneNumberParser.new }
end

def cast(value)
return if value.blank?
return value if value.is_a?(PhoneNumber)

value = value.gsub(/\D/, "")
return if value.blank?

return PhoneNumber.new(value:, e164: false) unless parser.valid?(value)

country_code, area_code, = parser.split(value)
PhoneNumber.new(
value:,
e164: true,
country_code: country_code,
area_code: (area_code if country_code.in?(AREA_CODE_COUNTRY_PREFIXES))
)
end

def serialize(value)
cast(value)&.value
end
end
2 changes: 1 addition & 1 deletion app/workflows/handle_phone_call_event.rb
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ def create_or_find_contact!(platform_account_sid, msisdn)
account = Account.find_by_platform_account_sid(platform_account_sid)
Contact.find_or_create_by!(
account: account,
msisdn: PhonyRails.normalize_number(msisdn),
msisdn: msisdn,
) do |record|
record.iso_country_code = ACCOUNT_COUNTRY_CODES.fetch(account.id, "KH")
end
Expand Down
3 changes: 3 additions & 0 deletions config/initializers/attribute_types.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Rails.application.config.to_prepare do
ActiveRecord::Type.register(:phone_number, PhoneNumberType)
end
2 changes: 1 addition & 1 deletion spec/jobs/queue_remote_call_job_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
).with(
body: {
"From" => "1234",
"To" => "+855715100860",
"To" => "855715100860",
"Url" => "https://scfm.somleng.org/twilio_webhooks/phone_call_events",
"StatusCallback" => "https://scfm.somleng.org/twilio_webhooks/phone_call_events"
}
Expand Down
2 changes: 1 addition & 1 deletion spec/models/call_flow_logic/ews_registration_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
end

it "prompts the main menu" do
contact = create(:contact, msisdn: "+855715100860")
contact = create(:contact, msisdn: "855715100860")
phone_call = create(
:phone_call,
:inbound,
Expand Down
2 changes: 1 addition & 1 deletion spec/models/callout_participation_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
describe "validations" do
it { is_expected.to validate_presence_of(:msisdn) }
it { is_expected.to allow_value(generate(:phone_number)).for(:msisdn) }
it { is_expected.not_to allow_value("252123456").for(:msisdn) }
it { is_expected.to allow_value("252123456").for(:msisdn) }
it { is_expected.to allow_value("+252 66-(2)-345-678").for(:msisdn) }
end

Expand Down
2 changes: 1 addition & 1 deletion spec/models/contact_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
describe "validations" do
it { is_expected.to validate_presence_of(:msisdn) }
it { is_expected.to allow_value(generate(:phone_number)).for(:msisdn) }
it { is_expected.not_to allow_value("252123456").for(:msisdn) }
it { is_expected.to allow_value("252123456").for(:msisdn) }
it { is_expected.to allow_value("+252 66-(2)-345-678").for(:msisdn) }
end
end
2 changes: 1 addition & 1 deletion spec/request_schemas/v1/beneficiary_request_schema_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ module V1
).output

expect(result).to include(
msisdn: "+855972345678",
msisdn: "855972345678",
iso_country_code: "KH"
)
end
Expand Down
Loading

0 comments on commit e0efd90

Please sign in to comment.