From f3162ccbea732c81fab3d8cb6bfa5c8eb58b31fd Mon Sep 17 00:00:00 2001 From: fumimowdan Date: Wed, 27 Sep 2023 14:52:43 +0100 Subject: [PATCH] Add GenerateUrns service This service will create all the available urns per application route. They will be randomized, unique and the next available urn to be taken will retreived with the Urn.next method. Once all the urn are exhausted this method will raise an error and the format of the URN will need updating ie increase the size of the suffix set. Urn::MAX_SUFFIX --- app/services/generate_urns.rb | 62 +++++++++++++++++++++++++++++ spec/services/generate_urns_spec.rb | 13 ++++++ 2 files changed, 75 insertions(+) create mode 100644 app/services/generate_urns.rb create mode 100644 spec/services/generate_urns_spec.rb diff --git a/app/services/generate_urns.rb b/app/services/generate_urns.rb new file mode 100644 index 00000000..a0a33274 --- /dev/null +++ b/app/services/generate_urns.rb @@ -0,0 +1,62 @@ +# Service responsible for the generation of all urns +# It will save the set of available urns based the current URN format +# and store it in the database URNs table. +# +# The Urn model will then be able to fetch the next available unique and +# random urn for application submition +# +# Example: +# +# Urn.next("teacher") # => "IRPTE12345" +# Urn.next("teacher") # => "IRPTE12345" +# Urn.next("salaried_trainee") # => "IRPST12345" +# +class GenerateUrns + def self.call + return if Urn.count.positive? # Do not override the current urn state + + Urn.transaction do + Urn::VALID_CODES.each_value do |code| + new(code:).generate + end + end + end + + def initialize(code:) + @code = code + end + + attr_reader :code + + def generate + data = unused_urns.map do |suffix| + { prefix: Urn::PREFIX, code: code, suffix: suffix } + end + Urn.insert_all(data) # rubocop:disable Rails/SkipsModelValidations + end + +private + + def unused_urns + generate_suffixes - existing_suffixes + end + + def generate_suffixes + Array + .new(Urn::MAX_SUFFIX) { _1 } + .drop(1) + .shuffle! + end + + def existing_suffixes + route = Urn::VALID_CODES.key(code) + Application + .where(application_route: route) + .pluck(:urn) + .map { extract_suffix(_1) } + end + + def extract_suffix(urn) + urn.match(/\d+/)[0].to_i + end +end diff --git a/spec/services/generate_urns_spec.rb b/spec/services/generate_urns_spec.rb new file mode 100644 index 00000000..ebde4c31 --- /dev/null +++ b/spec/services/generate_urns_spec.rb @@ -0,0 +1,13 @@ +require "rails_helper" + +RSpec.describe GenerateUrns do + subject(:service) { described_class } + + describe ".call" do + it { fail } + end + + describe ".generate" do + it { fail } + end +end