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

Generate inline taxonomy mapping in taxonomy.json #123

Merged
merged 5 commits into from
Apr 5, 2024

Conversation

chesterbot01
Copy link
Contributor

@chesterbot01 chesterbot01 commented Mar 26, 2024

Generate inline taxonomy mapping:
Screenshot 2024-03-25 at 10 17 11 PM

  • Taxonomy viewer works as normal

@chesterbot01 chesterbot01 marked this pull request as ready for review March 26, 2024 02:18
@elsom25
Copy link
Collaborator

elsom25 commented Mar 26, 2024

@chesterbot01 can we start with new dist files for mappings only? Once those are made (and vetted), we can add this to taxonomy.json

@elsom25
Copy link
Collaborator

elsom25 commented Mar 26, 2024

We should also be preparing a fresh schema cue file to validate these for json. I'd also suggest thinking through what (if any) the appropriate txt representation might be

@@ -70,5 +72,61 @@ def serialize_nested(connection)
name: connection.name,
}
end

def build_mapping_blocks(mapping_rules)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use the instance variable instead of passing this in? The other ones take a param because they're operating against a subset of the instance var vs its entirety

Comment on lines 80 to 81
Integration.all.each do |integration|
[true, false].each do |from_shopify|
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Integration.all.each do |integration|
[true, false].each do |from_shopify|
mapping_rules = Integration.all.flat_map do |integration|
[true, false].filter_map do |from_shopify|
rules = mapping_rules.where(integration:, from_shopify:)
rules if rule.any?
end
end

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mostly, if you decompose this it'll be easier to read with each piece being more focused. Also makes it simpler to use map methods, which are nice that each with manual tracking arrays 😁

Comment on lines 88 to 95
mappings = []
Category.verticals.each do |vertical|
mappings << MappingBuilder.build_one_to_one_mappings_for_vertical(
mapping_rules: mapping_rule_block,
vertical: vertical,
)
end
processed_mappings = mappings.flatten.compact
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAICT compact isn't needed here

Suggested change
mappings = []
Category.verticals.each do |vertical|
mappings << MappingBuilder.build_one_to_one_mappings_for_vertical(
mapping_rules: mapping_rule_block,
vertical: vertical,
)
end
processed_mappings = mappings.flatten.compact
mappings = Category.verticals.flat_map do |vertical|
MappingBuilder.build_one_to_one_mappings_for_vertical(mapping_rules:, vertical:)
end

mapping[:input][:attributes] = mapping[:input][:attributes].map do |attribute|
{
name: Property.find(attribute[:name]).gid,
value: attribute[:value].nil? ? nil : PropertyValue.find(attribute[:value]).gid,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
value: attribute[:value].nil? ? nil : PropertyValue.find(attribute[:value]).gid,
value: attribute[:value] || PropertyValue.find(attribute[:value]).gid,

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have to revert the change here because in some cases a nil attribute value will lead to a specific output that has been defined in YAML mapping rules.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah fair. Kinda makes me want a NilPropertyValue instead of magic nil, but this is fine

Comment on lines 6 to 12
relevant_rules = mapping_rules.select { |rule| rule.input.product_category_id.start_with?(vertical.id) }
relevant_rules.map do |rule|
{
input: rule.input.payload.delete_if { |_k, v| v.nil? },
output: rule.output.payload.delete_if { |_k, v| v.nil? },
}
end
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
relevant_rules = mapping_rules.select { |rule| rule.input.product_category_id.start_with?(vertical.id) }
relevant_rules.map do |rule|
{
input: rule.input.payload.delete_if { |_k, v| v.nil? },
output: rule.output.payload.delete_if { |_k, v| v.nil? },
}
end
mapping_rules
.select { _1.input.product_category_id.start_with?(vertical.id) }
.map do
{
input: _1.input.payload.delete_if { |_k, v| v.nil? },
output: _1.output.payload.delete_if { |_k, v| v.nil? },
}
end

Comment on lines 77 to 104
all_mapping_blocks = []
puts "Generating mappings ..."
mapping_count = 0
Integration.all.each do |integration|
[true, false].each do |from_shopify|
mapping_rule_block = mapping_rules.where(
integration_id: integration.id,
from_shopify: from_shopify,
)
next if mapping_rule_block.count.zero?

mappings = []
Category.verticals.each do |vertical|
mappings << MappingBuilder.build_one_to_one_mappings_for_vertical(
mapping_rules: mapping_rule_block,
vertical: vertical,
)
end
processed_mappings = mappings.flatten.compact
mapping_count += processed_mappings.count
all_mapping_blocks << {
input_taxonomy: "shopify/v1",
output_taxonomy: "#{integration.name}/v1",
rules: processed_mappings,
}
end
end
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had done this piece by piece, but assembling it:

Suggested change
all_mapping_blocks = []
puts "Generating mappings ..."
mapping_count = 0
Integration.all.each do |integration|
[true, false].each do |from_shopify|
mapping_rule_block = mapping_rules.where(
integration_id: integration.id,
from_shopify: from_shopify,
)
next if mapping_rule_block.count.zero?
mappings = []
Category.verticals.each do |vertical|
mappings << MappingBuilder.build_one_to_one_mappings_for_vertical(
mapping_rules: mapping_rule_block,
vertical: vertical,
)
end
processed_mappings = mappings.flatten.compact
mapping_count += processed_mappings.count
all_mapping_blocks << {
input_taxonomy: "shopify/v1",
output_taxonomy: "#{integration.name}/v1",
rules: processed_mappings,
}
end
end
mapping_rules = Integration.all.flat_map do |integration|
[true, false].filter_map do |from_shopify|
rules = mapping_rules.where(integration:, from_shopify:)
rules if rule.any?
end
end
rules = Category.verticals.flat_map do |vertical|
MappingBuilder.build_one_to_one_mappings_for_vertical(mapping_rules:, vertical:)
end
mapping_rules.map do |mapping|
{
input_taxonomy: "shopify/v1", # isn't this determined by the true/false technically?
output_taxonomy: "#{mapping.integration.name}/v1",
rules:,
}
end

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! Simplified the code based on the suggestion.

@chesterbot01
Copy link
Contributor Author

chesterbot01 commented Mar 26, 2024

can we start with new dist files for mappings only?

Sounds good, moved taxonomy mapping to a separate file for now.

@@ -2,9 +2,10 @@

module Dist
class JSONSerializer
def initialize(verticals:, properties:, version:)
def initialize(verticals:, properties:, mapping_rules: nil, version:)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need default value here?

Suggested change
def initialize(verticals:, properties:, mapping_rules: nil, version:)
def initialize(verticals:, properties:, mapping_rules:, version:)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed.

@@ -70,5 +79,56 @@ def serialize_nested(connection)
name: connection.name,
}
end

def build_mapping_blocks
puts "Generating mappings ..."
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need this in our serializers? I think it's reasonable for serializers to not have console output 😅

Copy link
Collaborator

@elsom25 elsom25 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, though I'd like someone from multi-channel land to give this a check before merge as well (cc @jeanrick)

@@ -70,5 +79,54 @@ def serialize_nested(connection)
name: connection.name,
}
end

def build_mapping_blocks
mapping_count = 0
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need this anymore, correct?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea, good catch!

@chesterbot01 chesterbot01 force-pushed the add-google-taxonomy-mapping branch 5 times, most recently from 4ff15f0 to 16fad0a Compare March 28, 2024 15:26
@@ -52,6 +54,7 @@ LOCAL_DB = tmp/local.sqlite3
# CUE imports needed for schema validation
ATTRIBUTES_DATA_CUE = schema/attributes_data.cue
CATEGORIES_DATA_CUE = schema/categories_data.cue
MAPPINGS_DATA_CUE = schema/mappings_data.cue
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You only need this if you need the data generated as part of integrity checks (see validations.cue)

Copy link
Contributor Author

@chesterbot01 chesterbot01 Mar 28, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

without schema/mappings_data.cue, cue vet -c will error out

mappings: field is required but not present:
    ./schema.cue:59:1

we have some validation logic for mappings defined in schema/schema.cue

@chesterbot01 chesterbot01 force-pushed the add-google-taxonomy-mapping branch 7 times, most recently from 582c246 to 1ee66df Compare April 2, 2024 20:48
Comment on lines 2 to 3
input_taxonomy: "2024-04"
output_taxonomy: "2021-09-21"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should still prefix these versions with the platform e.g. shopify/2024-04 and google/2021-09-21

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! Done.

@chesterbot01 chesterbot01 merged commit e8ec78a into main Apr 5, 2024
3 checks passed
@chesterbot01 chesterbot01 deleted the add-google-taxonomy-mapping branch April 5, 2024 16:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants