-
Notifications
You must be signed in to change notification settings - Fork 7
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
Creation Quote Metric #55
Conversation
…queries extraction demand it
Hi! I'm VTEX IO CI/CD Bot and I'll be helping you to publish your app! 🤖 Please select which version do you want to release:
And then you just need to merge your PR when you are ready! There is no need to create a release commit/tag.
|
Beep boop 🤖 I noticed you didn't make any changes at the
In order to keep track, I'll create an issue if you decide now is not a good time
|
docs/README.md
Outdated
--- | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you forgot these lines
const userEmail = sessionResponse?.namespaces?.profile?.email?.value | ||
const { data: userData } = useQuery(CHECK_PERMISSIONS, { | ||
variables: { email: userEmail }, | ||
}) | ||
|
||
const costCenterId: string = userData?.getUserByEmail?.[0]?.costId | ||
const { data: costCenterData } = useQuery(GET_COSTCENTER_BY_ID, { | ||
variables: { id: costCenterId }, | ||
}) | ||
|
||
const orgId: string = userData?.getUserByEmail?.[0]?.orgId | ||
const { data: organizationData } = useQuery(GET_ORGANIZATION_BY_ID, { | ||
variables: { id: orgId }, | ||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will make us fetch all that data every time this page is rendered, even if we end up not needing it.
It seems like we only ever need this when sending the metric, right? So it's best if we only do this data fetching at that time, within the sendMetric
function.
In that case you won't be doing the fetching using hooks (hooks are these functions with names starting with use
). React hooks have logic behind the scenes that cause the screen to be rerendered when the data is loading, and then again when it arrives. For your use case we should do everything behind the scenes and without causing rerenders. If these data fetches were not graphql calls you could just use axios
for that, for example. In graphql's case you can use a simple library like graphql-request instead.
const userEmail = sessionResponse?.namespaces?.profile?.email?.value | ||
const { data: userData } = useQuery(CHECK_PERMISSIONS, { | ||
variables: { email: userEmail }, | ||
}) | ||
|
||
const costCenterId: string = userData?.getUserByEmail?.[0]?.costId | ||
const { data: costCenterData } = useQuery(GET_COSTCENTER_BY_ID, { | ||
variables: { id: costCenterId }, | ||
}) | ||
|
||
const orgId: string = userData?.getUserByEmail?.[0]?.orgId | ||
const { data: organizationData } = useQuery(GET_ORGANIZATION_BY_ID, { | ||
variables: { id: orgId }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One of the advantages of graphql is that you don't need to do separate fetches to get information. Since you need all three of these to send the metric, you can build a single graphql query joining them all together in a single request. Also, it's probably better to build a new query for this use case anyway, since you probably don't need the exact same data that those existing queries were asking for. You can drop the unused fields and join the queries together, resulting in a better API request.
userData: userData?.getUserByEmail?.[0], | ||
costCenterName: costCenterData?.getCostCenterById?.name, | ||
buyOrgName: organizationData?.getOrganizationById?.name, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not 100% sure, but it's possible that all this data is already present in the session or segment cookie, so it would be good to double check before making the changes I suggested to the data fetching.
react/utils/metrics.ts
Outdated
try { | ||
const metric = buildQuoteMetric(sendToSalesRep, metricsParam) | ||
|
||
axios.post(ANALYTICS_URL, metric) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's better to have an await
call here, otherwise you won't catch errors correctly
axios.post(ANALYTICS_URL, metric) | |
await axios.post(ANALYTICS_URL, metric) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this case, I'm not sure I need to catch errors. The idea of not having an await is not having to wait for the response from analytics API and not delay a bit more the response for users.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that it's not very important for you to catch errors here, but in that case you should remove the try/catch in this function. Without the await it won't work well if the request actually fails.
If you want to keep catching the errors here you can add the await. That won't really change the behavior of the call, because you don't await the sendMetric
call itself, so it will still run in the background without affecting the rendering thread in any way.
react/utils/metrics.ts
Outdated
|
||
axios.post(ANALYTICS_URL, metric) | ||
} catch (error) { | ||
console.error('Unable to log metrics', error) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's best to make this a warn
, since its a background call that doesn't (and shouldn't) break the page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks Mauro! Just smaller suggestions now.
react/utils/metrics.ts
Outdated
getUserByEmail(email: $email) @context(provider: "vtex.storefront-permissions") { | ||
costId | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a small indentation fix:
getUserByEmail(email: $email) @context(provider: "vtex.storefront-permissions") { | |
costId | |
} | |
getUserByEmail(email: $email) @context(provider: "vtex.storefront-permissions") { | |
costId | |
} |
react/utils/metrics.ts
Outdated
buy_org_name: metricsData.organizationName, | ||
cost_center_id: metricsData.costId, | ||
cost_center_name: metricsData.costCenterName, | ||
member_id: namespaces?.profile?.id?.value, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In line 98 the code is assuming that namespaces.profile.email.value
is always set, but here you're handling the case where namespaces
and profile
might not be set. If that's a possibility we need to also add this to lines 97 and 98, skipping the whole metric process in case the values are not set (since those are required).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of skipping the while metric process, I'll check the namespace, profile, and email, and let it save null values. I believe it's better to save the metric with the data we have than not save it at all
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree, if the metric is still useful, let's save it!
react/utils/metrics.ts
Outdated
const { data } = ( | ||
await axios.post(GRAPHQL_URL(accountName, workspace), query) | ||
).data | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When a GraphQL request fails, the response status is often 200 anyway, depending on the type of the error (mainly because there can be partial errors). So there would be no exception thrown here, but data
might be undefined, or it might only have part of the information you requested. In those cases the response will contain a field called errors
, so you can check for that here.
const { data } = ( | |
await axios.post(GRAPHQL_URL(accountName, workspace), query) | |
).data | |
const { data, errors } = ( | |
await axios.post(GRAPHQL_URL(accountName, workspace), query) | |
).data | |
More information on graphql errors here.
react/utils/metrics.ts
Outdated
).data | ||
|
||
const quoteResult = data.getQuote as Omit<QuoteMetricsData, 'costId'> | ||
const costId = data.getUserByEmail?.[0].costId as string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're using an optional operator here, so you're assuming that data.getUserByEmail
might not be set, right? If that's a possibility then you shouldn't cast to string here, as it'll make costId
's type not consider the use case where it will be undefined
. Is it ok if costId
isn't set? If it isn't it's better to bail early here, and if it's ok then you should let it be string | undefined
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lgtm, thanks! 👏
@mtakeda don't forget to select the version bump within vtex-io-ci-cd bot's message at the further above in this PR, or that check will keep failing. |
Use Quote Metric
manifest.json
Outdated
@@ -1,7 +1,7 @@ | |||
{ | |||
"vendor": "vtex", | |||
"name": "b2b-quotes", | |||
"version": "1.5.5", | |||
"version": "1.5.6", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This shouldn't be changed here in the PR. It will be changed automatically by the vtex io bot once this PR is merged. You should revert this change, and just select the right type of version bump in the question post from vtex io bot.
react/package.json
Outdated
@@ -1,6 +1,6 @@ | |||
{ | |||
"name": "vtex.b2b-quotes", | |||
"version": "1.5.5", | |||
"version": "1.5.6", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here, please revert this line.
react/utils/metrics/createQuote.ts
Outdated
buy_org_id: metricsData.organization, | ||
buy_org_name: metricsData.organizationName, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've just noticed that this PR also has the typos:
buy_org_id: metricsData.organization, | |
buy_org_name: metricsData.organizationName, | |
buyer_org_id: metricsData.organization, | |
buyer_org_name: metricsData.organizationName, |
Can you check if there are others and fix them? Same for the metrics for using quotes.
Kudos, SonarCloud Quality Gate passed! 0 Bugs 0.0% Coverage The version of Java (11.0.17) you have used to run this analysis is deprecated and we will stop accepting it soon. Please update to at least Java 17. |
Your PR has been merged! App is being published. 🚀 After the publishing process has been completed (check #vtex-io-releases) and doing A/B tests with the new version, you can deploy your release by running:
After that your app will be updated on all accounts. For more information on the deployment process check the docs. 📖 |
What problem is this solving?
Sending quotation created metrics to analytics in order to have more business data to take decisions and analyze user's behavior.
How to test it?
Create a quote in
https://takeda--b2bstore005.myvtex.com/deals
After one hour (maximum), data should appear in Analytics Redshift, into table
"vtex"."schemaless"."b2b_suite_buyerorg_data_raw"
Workspace
Screenshots or example usage:
No changes in layout. Current quotation create workflow kept as is.
Redshit query and result example:
type:
Describe alternatives you've considered, if any.
NA
Related to / Depends on
NA
How does this PR make you feel?