Merge pull request #2602 from Safelite/nation/CASH-1029

CASH-1029 Dynamo Logging
This commit is contained in:
CarlNation 2025-06-24 20:47:54 -04:00 committed by GitHub
commit f29d6082b3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 145 additions and 31 deletions

View file

@ -176,6 +176,10 @@ const endpoints = {
url: "/analytics/api/v1/analytics/log-part-questions",
method: "POST",
},
LogDigitalConsumer: {
url: "/analytics/api/v1/analytics/digitalconsumer-log",
method: "POST",
},
GetExperimentsByUser: {
url: "/analytics/api/v1/analytics/get-experiments",
method: "GET",

View file

@ -26,6 +26,7 @@ const experimentSettings = {
FOSTER_LOVE: "DisplayFosterLove",
SKIP_TO_INSURANCE: "SkipToInsurance",
DISPLAY_AFTERPAY_BREAKOUT_DISPLAY: "Display_AfterpayBreakoutDisplay",
DYNAMO_LOGGING: "DynamoLogging",
};
const experimentTriggers = {

View file

@ -63,6 +63,7 @@ const storeActions = {
LOG_CUSTOM_EVENT: "logCustomEvent",
INITIALIZE_SESSION: "initializeSession",
LOG_PART_QUESTIONS: "logPartQuestions",
LOG_DIGITALCONSUMER: "logDigitalConsumer",
// DEPENDENCY MUTATIONS
RESET_VEHICLE_STATE_AND_DEPENDENCIES: "resetVehicleStateAndDependencies",

View file

@ -100,34 +100,38 @@ export default {
return resolve(response);
},
(error) => {
if (logApiCall) {
analyticsMixIn.methods.pushEventToGA(
GaCategories.API_RESPONSE,
GaActions.RESULT,
`${GaLabels.ERROR}_${endpoint}`,
true
);
if (endpoint.toLowerCase().includes("/digitalconsumer-log")) {
return resolve({ data: null, error: "Ignore errors when logging" });
} else {
if (logApiCall) {
analyticsMixIn.methods.pushEventToGA(
GaCategories.API_RESPONSE,
GaActions.RESULT,
`${GaLabels.ERROR}_${endpoint}`,
true
);
}
if (error.response.status && error.response.status != "404") {
// Do not route to error logic when no wipers found or no promo found (404s)
const errorPayload = {
cause: `Response error ${error.response.status}`,
currentPage: pageNameToLog,
endpoint: endpoint,
};
router.bailout(errorPayload);
// do not log 404 errors from services because we return NotFound
// when a service doesn't return an object
global.$logger.logError(
`${method}: ${endpoint}: ${error.message}`,
error.response
);
}
return reject(error.response);
}
if (error.response.status && error.response.status != "404") {
// Do not route to error logic when no wipers found or no promo found (404s)
const errorPayload = {
cause: `Response error ${error.response.status}`,
currentPage: pageNameToLog,
endpoint: endpoint,
};
router.bailout(errorPayload);
// do not log 404 errors from services because we return NotFound
// when a service doesn't return an object
global.$logger.logError(
`${method}: ${endpoint}: ${error.message}`,
error.response
);
}
return reject(error.response);
}
);
});

View file

@ -12,7 +12,8 @@ import {
setSessionKeyIfUnset,
} from "@/helpers/heritage-integration/cookie-helper";
import { queryStrings } from "@/constants/query-strings";
import { experimentSettings } from "@/constants/experiments";
import { experimentSettings, experimentUniverses } from "@/constants/experiments";
import experimentMixin from "@/mixins/experiment-mixin";
import {
analyticsPageEvents,
GaCategories,
@ -128,6 +129,60 @@ export default {
}
},
async logDigitalConsumer() {
const currentPageName = getPageNameFromRouter();
const universes = store.getters.applicationUser.experiments;
console.log(JSON.stringify(universes));
let hasDynamoLogging = experimentMixin.methods.hasSettingEqualTo(
experimentSettings.DYNAMO_LOGGING,
"true",
universes
);
if (!hasDynamoLogging) {
return;
}
const variationNames = universes
.filter((item) => item.universeName === experimentUniverses.CONCEPT_FUNNEL)
.map((item) => item.variationName)
.filter(Boolean); // removes undefined/null
const conceptVariation = variationNames.length > 0 ? variationNames[0] : "";
const submittedOrder = baseMixin.methods.getSubmittedOrder();
const hasSubmittedOrder = baseMixin.methods.hasSubmittedOrder();
const hasSubmittedOrderAtConfirmationPage =
hasSubmittedOrder && currentPageName?.toLowerCase() == routeData.CONFIRMATION.name;
const refSequenceNum = hasSubmittedOrderAtConfirmationPage
? submittedOrder.referralSequenceNumber
: store.getters.order.referralSequenceNumber;
var payload = {
actionName: `Browser page:${currentPageName}`,
referralSequenceNumber: hasSubmittedOrderAtConfirmationPage
? submittedOrder.referralSequenceNumber
: store.getters.order.referralSequenceNumber,
referralNumber: hasSubmittedOrderAtConfirmationPage
? submittedOrder.referralNumber
: store.getters.order.referralNumber,
workOrderId: hasSubmittedOrderAtConfirmationPage
? submittedOrder.workOrderId
: store.getters.order.workOrderId,
workOrderNumber: hasSubmittedOrderAtConfirmationPage
? submittedOrder.workOrderNumber
: store.getters.order.workOrderNumber,
conceptVariation: conceptVariation,
};
await baseMixin.methods.dispatchStoreAction(
storeActions.LOG_DIGITALCONSUMER,
payload,
false
);
},
async pushEventForChatsToGA(category, action, label, pushToLogApp = false) {
const currentPageName = getPageNameFromRouter();
const value = `2.0_${currentPageName}`;

View file

@ -197,6 +197,18 @@ export default {
return [parseInt(v[1], 10), parseInt(v[2], 10), parseInt(v[3] || 0, 10)];
}
},
isMobileDevice() {
const userAgent = navigator.userAgent;
return (
userAgent.includes("Android") ||
userAgent.includes("Mobile") ||
userAgent.includes("iPod") ||
userAgent.includes("iPhone") ||
userAgent.includes("IEMobile") ||
userAgent.includes("BlackBerry") ||
userAgent.includes("webOS")
);
},
getSubmittedOrder() {
return JSON.parse(
window.sessionStorage.getItem(sessionStorageKeyConstants.SUBMITTED_STATE)

View file

@ -1,6 +1,9 @@
import analyticsMixin from "@/mixins/analytics-mixin";
export async function afterEach(to, from) {
// digital consumer logging
analyticsMixin.methods.logDigitalConsumer();
// Push page view to GA
analyticsMixin.methods.pushPageViewToGA();

View file

@ -11,7 +11,11 @@ import { experimentTriggers } from "@/constants/experiments";
import { damageLocationsSelected } from "@/constants/damage-locations-selected";
import { singleWindshieldCarIds } from "@/constants/single-windshield-carids";
import { routeData } from "@/router/constants/routes";
import { deleteFunnelCookie } from "@/helpers/heritage-integration/cookie-helper.js";
import {
deleteFunnelCookie,
getSessionIdValue,
getDeviceIdValue,
} from "@/helpers/heritage-integration/cookie-helper.js";
import { deepEqual } from "@/helpers/object-helper";
import baseMixin from "@/mixins/base-mixin.js";
import {
@ -1557,6 +1561,36 @@ export const actions = {
});
},
logDigitalConsumer(
context,
{
actionName,
referralSequenceNumber,
referralNumber,
workOrderId,
workOrderNumber,
conceptVariation,
}
) {
var payload = {
sessionId: getSessionIdValue(),
deviceId: getDeviceIdValue(),
actionName: actionName ?? "",
referralSequenceNumber: referralSequenceNumber ?? "",
referralNumber: referralNumber ?? "",
applicationName: baseMixin.methods.isMobileDevice() ? "2.0 Mobile" : "2.0",
workOrderId: workOrderId ?? "",
workOrderNumber: workOrderNumber ?? "",
conceptVariation: conceptVariation,
};
return globalMethods.callHttpClient({
method: endpoints.LogDigitalConsumer.method,
endpoint: endpoints.LogDigitalConsumer.url,
payload: payload,
});
},
// Misc Actions
setReferralInformation(context, { referralNumber, referralDate, referralCorrelationId, eon }) {
context.commit(storeMutations.UPDATE_REFERRAL_NUMBER, referralNumber);

View file

@ -121,8 +121,8 @@ $body-color: $gray-600;
//Fonts
$font-family-sans-serif: UrbanistRegular, Arial, Helvetica, sans-serif;
$font-family-monospace:
UrbanistRegular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
$font-family-monospace: UrbanistRegular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New",
monospace;
// stylelint-enable value-keyword-case
$font-family-base: $font-family-sans-serif;
$font-family-code: $font-family-monospace;