Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Solve #33 - Refactor WIP limit Use Case #40

Merged
merged 5 commits into from
May 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 89 additions & 0 deletions lib/v2/bot/compare_wip_limit_count.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# frozen_string_literal: true

require_relative "./base"
require_relative "../read/postgres"
require_relative "../write/postgres"

module Bot
##
# The Bot::CompareWipLimitCount class serves as a bot implementation to read domains wip limits and
# counts from a PostgresDB database, compare the values to find exceeded counts, and write them on
# a PostgresDB table with a specific format.
#
# <br>
# <b>Example</b>
#
# options = {
# read_options: {
# connection: {
# host: "localhost",
# port: 5432,
# dbname: "bas",
# user: "postgres",
# password: "postgres"
# },
# db_table: "use_cases",
# bot_name: "FetchDomainsWipLimitFromNotion"
# },
# write_options: {
# connection: {
# host: "localhost",
# port: 5432,
# dbname: "bas",
# user: "postgres",
# password: "postgres"
# },
# db_table: "use_cases",
# bot_name: "CompareWipLimitCount"
# }
# }
#
# bot = Bot::CompareWipLimitCount.new(options)
# bot.execute
#
class CompareWipLimitCount < Bot::Base
# read function to execute the PostgresDB Read component
#
def read
reader = Read::Postgres.new(read_options)

reader.execute
end

# Process function to compare the domains wip counts and limits
#
def process(read_response)
return { success: { exceeded_domain_count: {} } } if unprocessable_response(read_response.data)

domains_limits = read_response.data["domains_limits"]
domain_wip_count = read_response.data["domain_wip_count"]

exceeded_domain_count = exceedded_counts(domains_limits, domain_wip_count)

{ success: { exceeded_domain_count: } }
end

# Write function to execute the PostgresDB write component
#
def write(process_response)
write = Write::Postgres.new(write_options, process_response)

write.execute
end

private

def unprocessable_response(read_data)
read_data.nil? || read_data == {} || read_data["domains_limits"] == [] || read_data["domain_wip_count"] == []
end

def exceedded_counts(limits, counts)
counts.to_a.map do |domain_wip_count|
domain, count = domain_wip_count
domain_limit = limits[domain]

{ domain:, exceeded: count - domain_limit } if count > domain_limit
end.compact
end
end
end
121 changes: 121 additions & 0 deletions lib/v2/bot/fetch_domains_wip_counts_from_notion.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
# frozen_string_literal: true

require_relative "./base"
require_relative "../read/default"
require_relative "../utils/notion/request"
require_relative "../write/postgres"

module Bot
##
# The Bot::FetchDomainsWipCountsFromNotion class serves as a bot implementation to fetch work items
# in progress or in hold from a Notion database, count how many are by domain, and write them on a
# PostgresDB table with a specific format.
#
# <br>
# <b>Example</b>
#
# options = {
# process_options: {
# database_id: "notion database id",
# secret: "notion secret"
# },
# write_options: {
# connection: {
# host: "host",
# port: 5432,
# dbname: "bas",
# user: "postgres",
# password: "postgres"
# },
# db_table: "use_cases",
# bot_name: "FetchDomainsWipCountsFromNotion"
# }
# }
#
# bot = Bot::FetchDomainsWipCountsFromNotion.new(options)
# bot.execute
#
class FetchDomainsWipCountsFromNotion < Bot::Base
# Read function to execute the default Read component
#
def read
reader = Read::Default.new

reader.execute
end

# Process function to execute the Notion utility to fetch work item from the notion database
#
def process(_read_response)
response = Utils::Notion::Request.execute(params)

if response.code == 200
work_items_domains = normalize_response(response.parsed_response["results"])
domain_wip_count = count_domain_items(work_items_domains)

{ success: { domain_wip_count: } }
else
{ error: { message: response.parsed_response, status_code: response.code } }
end
end

# Write function to execute the PostgresDB write component
#
def write(process_response)
write = Write::Postgres.new(write_options, process_response)

write.execute
end

private

def params
{
endpoint: "databases/#{process_options[:database_id]}/query",
secret: process_options[:secret],
method: "post",
body:
}
end

def body
{
filter: {
"and": [
{ property: "OK", formula: { string: { contains: "✅" } } },
{ "or": status_conditions }
]
}
}
end

def status_conditions
[
{ property: "Status", status: { equals: "In Progress" } },
{ property: "Status", status: { equals: "On Hold" } }
]
end

def normalize_response(results)
return [] if results.nil?

results.map do |pto|
work_item_fields = pto["properties"]

{
"domain" => extract_domain_field_value(work_item_fields["Responsible domain"])
}
end
end

def extract_domain_field_value(data)
data["select"]["name"]
end

def count_domain_items(work_items_list)
domain_work_items = work_items_list.group_by { |work_item| work_item["domain"] }

domain_work_items.transform_values(&:count)
end
end
end
127 changes: 127 additions & 0 deletions lib/v2/bot/fetch_domains_wip_limit_from_notion.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
# frozen_string_literal: true

require_relative "./base"
require_relative "../read/default"
require_relative "../utils/notion/request"
require_relative "../write/postgres"

module Bot
##
# The Bot::FetchDomainsWipLimitFromNotion class serves as a bot implementation to fetch domains wip
# limits from a Notion database, merge them with the count of how many are by domain, and write them
# on a PostgresDB table with a specific format.
#
# <br>
# <b>Example</b>
#
# options = {
# read_options: {
# connection: {
# host: "host",
# port: 5432,
# dbname: "bas",
# user: "postgres",
# password: "postgres"
# },
# db_table: "use_cases",
# bot_name: "FetchDomainsWipCountsFromNotion"
# },
# process_options: {
# database_id: "notion database id",
# secret: "notion secret"
# },
# write_options: {
# connection: {
# host: "host",
# port: 5432,
# dbname: "bas",
# user: "postgres",
# password: "postgres"
# },
# db_table: "use_cases",
# bot_name: "FetchDomainsWipLimitFromNotion"
# }
# }
#
# bot = Bot::FetchDomainsWipLimitFromNotion.new(options)
# bot.execute
#
class FetchDomainsWipLimitFromNotion < Bot::Base
# read function to execute the PostgresDB Read component
#
def read
reader = Read::Postgres.new(read_options)

reader.execute
end

# Process function to execute the Notion utility to fetch domain wip limits from the notion database
#
def process(read_response)
response = Utils::Notion::Request.execute(params)

if response.code == 200
domains_limits = normalize_response(response.parsed_response["results"])

wip_limit_data = wip_count(read_response).merge({ domains_limits: })

{ success: wip_limit_data }
else
{ error: { message: response.parsed_response, status_code: response.code } }
end
end

# Write function to execute the PostgresDB write component
#
def write(process_response)
write = Write::Postgres.new(write_options, process_response)

write.execute
end

private

def params
{
endpoint: "databases/#{process_options[:database_id]}/query",
secret: process_options[:secret],
method: "post",
body:
}
end

def body
{
filter: {
property: "WIP + On Hold limit",
number: { is_not_empty: true }
}
}
end

def normalize_response(results)
return [] if results.nil?

results.reduce({}) do |domains_limits, domain_wip_limit|
domain_fields = domain_wip_limit["properties"]

domain = extract_domain_name_value(domain_fields["Name"])
limit = extract_domain_limit_value(domain_fields["WIP + On Hold limit"])

domains_limits.merge({ domain => limit })
end
end

def extract_domain_name_value(data)
data["title"].first["plain_text"]
end

def extract_domain_limit_value(data)
data["number"]
end

def wip_count(read_response)
read_response.data.nil? ? {} : read_response.data
end
end
end
Loading
Loading