@embedreach/components 0.3.17 → 0.3.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunks/index.js +99633 -97549
- package/dist/chunks/sandbox-loading-screen.js +1889 -1302
- package/dist/index.d.ts +19 -3
- package/dist/index.es.js +3 -3
- package/dist/index.umd.js +14 -14
- package/dist/styles.css +1 -1
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useState, useEffect } from "react";
|
|
3
|
-
import { R as ReachClientEnum, H as H3 } from "./index.js";
|
|
3
|
+
import { C as ChannelAccountTypeEnum, R as ReachClientEnum, H as H3 } from "./index.js";
|
|
4
4
|
var POSITIONALS_EXP$1 = /(%?)(%([sdijo]))/g;
|
|
5
5
|
function serializePositional$1(positional, flag) {
|
|
6
6
|
switch (flag) {
|
|
@@ -288,12 +288,12 @@ var until$1 = async (promise) => {
|
|
|
288
288
|
const executeHandlers = async ({
|
|
289
289
|
request,
|
|
290
290
|
requestId,
|
|
291
|
-
handlers
|
|
291
|
+
handlers,
|
|
292
292
|
resolutionContext
|
|
293
293
|
}) => {
|
|
294
294
|
let matchingHandler = null;
|
|
295
295
|
let result = null;
|
|
296
|
-
for (const handler of
|
|
296
|
+
for (const handler of handlers) {
|
|
297
297
|
result = await handler.run({ request, requestId, resolutionContext });
|
|
298
298
|
if (result !== null) {
|
|
299
299
|
matchingHandler = handler;
|
|
@@ -13167,7 +13167,7 @@ function storeResponseCookies(request, response) {
|
|
|
13167
13167
|
cookieStore.setCookie(responseCookies, request.url);
|
|
13168
13168
|
}
|
|
13169
13169
|
}
|
|
13170
|
-
async function handleRequest(request, requestId,
|
|
13170
|
+
async function handleRequest(request, requestId, handlers, options, emitter, handleRequestOptions) {
|
|
13171
13171
|
emitter.emit("request:start", { request, requestId });
|
|
13172
13172
|
if (request.headers.get("accept")?.includes("msw/passthrough")) {
|
|
13173
13173
|
emitter.emit("request:end", { request, requestId });
|
|
@@ -13178,7 +13178,7 @@ async function handleRequest(request, requestId, handlers2, options, emitter, ha
|
|
|
13178
13178
|
return executeHandlers({
|
|
13179
13179
|
request,
|
|
13180
13180
|
requestId,
|
|
13181
|
-
handlers
|
|
13181
|
+
handlers,
|
|
13182
13182
|
resolutionContext: handleRequestOptions?.resolutionContext
|
|
13183
13183
|
});
|
|
13184
13184
|
});
|
|
@@ -13476,8 +13476,8 @@ class SetupApi extends Disposable {
|
|
|
13476
13476
|
this.publicEmitter.removeAllListeners();
|
|
13477
13477
|
});
|
|
13478
13478
|
}
|
|
13479
|
-
validateHandlers(
|
|
13480
|
-
return
|
|
13479
|
+
validateHandlers(handlers) {
|
|
13480
|
+
return handlers.every((handler) => !Array.isArray(handler));
|
|
13481
13481
|
}
|
|
13482
13482
|
use(...runtimeHandlers) {
|
|
13483
13483
|
invariant$1(
|
|
@@ -15152,12 +15152,12 @@ function matchRequestUrl(url, path, baseUrl) {
|
|
|
15152
15152
|
const kDispatchEvent = Symbol("kDispatchEvent");
|
|
15153
15153
|
function handleWebSocketEvent(options) {
|
|
15154
15154
|
webSocketInterceptor.on("connection", async (connection) => {
|
|
15155
|
-
const
|
|
15155
|
+
const handlers = options.getHandlers();
|
|
15156
15156
|
const connectionEvent = new MessageEvent("connection", {
|
|
15157
15157
|
data: connection
|
|
15158
15158
|
});
|
|
15159
15159
|
const matchingHandlers = [];
|
|
15160
|
-
for (const handler of
|
|
15160
|
+
for (const handler of handlers) {
|
|
15161
15161
|
if (isHandlerKind("EventHandler")(handler) && handler.predicate({
|
|
15162
15162
|
event: connectionEvent,
|
|
15163
15163
|
parsedResult: handler.parse({
|
|
@@ -15516,10 +15516,10 @@ function getWorkerByRegistration(registration, absoluteWorkerUrl, findWorker) {
|
|
|
15516
15516
|
const relevantStates = allStates.filter((state) => {
|
|
15517
15517
|
return state != null;
|
|
15518
15518
|
});
|
|
15519
|
-
const
|
|
15520
|
-
return findWorker(
|
|
15519
|
+
const worker = relevantStates.find((worker2) => {
|
|
15520
|
+
return findWorker(worker2.scriptURL, absoluteWorkerUrl);
|
|
15521
15521
|
});
|
|
15522
|
-
return
|
|
15522
|
+
return worker || null;
|
|
15523
15523
|
}
|
|
15524
15524
|
var getWorkerInstance = async (url, options = {}, findWorker) => {
|
|
15525
15525
|
const absoluteWorkerUrl = getAbsoluteWorkerUrl(url);
|
|
@@ -16522,8 +16522,8 @@ var createStartHandler = (context) => {
|
|
|
16522
16522
|
options.serviceWorker.options,
|
|
16523
16523
|
options.findWorker
|
|
16524
16524
|
);
|
|
16525
|
-
const [
|
|
16526
|
-
if (!
|
|
16525
|
+
const [worker, registration] = instance;
|
|
16526
|
+
if (!worker) {
|
|
16527
16527
|
const missingWorkerMessage = customOptions?.findWorker ? devUtils.formatMessage(
|
|
16528
16528
|
`Failed to locate the Service Worker registration using a custom "findWorker" predicate.
|
|
16529
16529
|
|
|
@@ -16542,10 +16542,10 @@ Please consider using a custom "serviceWorker.url" option to point to the actual
|
|
|
16542
16542
|
);
|
|
16543
16543
|
throw new Error(missingWorkerMessage);
|
|
16544
16544
|
}
|
|
16545
|
-
context.worker =
|
|
16545
|
+
context.worker = worker;
|
|
16546
16546
|
context.registration = registration;
|
|
16547
16547
|
context.events.addListener(window, "beforeunload", () => {
|
|
16548
|
-
if (
|
|
16548
|
+
if (worker.state !== "redundant") {
|
|
16549
16549
|
context.workerChannel.send("CLIENT_CLOSED");
|
|
16550
16550
|
}
|
|
16551
16551
|
window.clearInterval(context.keepAliveInterval);
|
|
@@ -18041,8 +18041,8 @@ var SetupWorkerApi = class extends SetupApi {
|
|
|
18041
18041
|
startHandler = null;
|
|
18042
18042
|
stopHandler = null;
|
|
18043
18043
|
listeners;
|
|
18044
|
-
constructor(...
|
|
18045
|
-
super(...
|
|
18044
|
+
constructor(...handlers) {
|
|
18045
|
+
super(...handlers);
|
|
18046
18046
|
invariant(
|
|
18047
18047
|
!isNodeProcess(),
|
|
18048
18048
|
devUtils.formatMessage(
|
|
@@ -18179,8 +18179,8 @@ var SetupWorkerApi = class extends SetupApi {
|
|
|
18179
18179
|
this.stopHandler();
|
|
18180
18180
|
}
|
|
18181
18181
|
};
|
|
18182
|
-
function setupWorker(...
|
|
18183
|
-
return new SetupWorkerApi(...
|
|
18182
|
+
function setupWorker(...handlers) {
|
|
18183
|
+
return new SetupWorkerApi(...handlers);
|
|
18184
18184
|
}
|
|
18185
18185
|
function checkGlobals() {
|
|
18186
18186
|
invariant$1(
|
|
@@ -18682,38 +18682,6 @@ class HttpResponse extends FetchResponse$1 {
|
|
|
18682
18682
|
}
|
|
18683
18683
|
}
|
|
18684
18684
|
checkGlobals();
|
|
18685
|
-
let getRandomValues;
|
|
18686
|
-
const rnds8 = new Uint8Array(16);
|
|
18687
|
-
function rng() {
|
|
18688
|
-
if (!getRandomValues) {
|
|
18689
|
-
getRandomValues = typeof crypto !== "undefined" && crypto.getRandomValues && crypto.getRandomValues.bind(crypto);
|
|
18690
|
-
if (!getRandomValues) {
|
|
18691
|
-
throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");
|
|
18692
|
-
}
|
|
18693
|
-
}
|
|
18694
|
-
return getRandomValues(rnds8);
|
|
18695
|
-
}
|
|
18696
|
-
const byteToHex = [];
|
|
18697
|
-
for (let i2 = 0; i2 < 256; ++i2) {
|
|
18698
|
-
byteToHex.push((i2 + 256).toString(16).slice(1));
|
|
18699
|
-
}
|
|
18700
|
-
function unsafeStringify(arr, offset = 0) {
|
|
18701
|
-
return byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + "-" + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + "-" + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + "-" + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + "-" + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]];
|
|
18702
|
-
}
|
|
18703
|
-
const randomUUID = typeof crypto !== "undefined" && crypto.randomUUID && crypto.randomUUID.bind(crypto);
|
|
18704
|
-
const native = {
|
|
18705
|
-
randomUUID
|
|
18706
|
-
};
|
|
18707
|
-
function v4(options, buf, offset) {
|
|
18708
|
-
if (native.randomUUID && !buf && !options) {
|
|
18709
|
-
return native.randomUUID();
|
|
18710
|
-
}
|
|
18711
|
-
options = options || {};
|
|
18712
|
-
const rnds = options.random || (options.rng || rng)();
|
|
18713
|
-
rnds[6] = rnds[6] & 15 | 64;
|
|
18714
|
-
rnds[8] = rnds[8] & 63 | 128;
|
|
18715
|
-
return unsafeStringify(rnds);
|
|
18716
|
-
}
|
|
18717
18685
|
var e = [{ name: "Aegean Airlines", iataCode: "A3" }, { name: "Aeroflot", iataCode: "SU" }, { name: "Aerolineas Argentinas", iataCode: "AR" }, { name: "Aeromexico", iataCode: "AM" }, { name: "Air Algerie", iataCode: "AH" }, { name: "Air Arabia", iataCode: "G9" }, { name: "Air Canada", iataCode: "AC" }, { name: "Air China", iataCode: "CA" }, { name: "Air Europa", iataCode: "UX" }, { name: "Air France", iataCode: "AF" }, { name: "Air India", iataCode: "AI" }, { name: "Air Mauritius", iataCode: "MK" }, { name: "Air New Zealand", iataCode: "NZ" }, { name: "Air Niugini", iataCode: "PX" }, { name: "Air Tahiti", iataCode: "VT" }, { name: "Air Tahiti Nui", iataCode: "TN" }, { name: "Air Transat", iataCode: "TS" }, { name: "AirAsia X", iataCode: "D7" }, { name: "AirAsia", iataCode: "AK" }, { name: "Aircalin", iataCode: "SB" }, { name: "Alaska Airlines", iataCode: "AS" }, { name: "Alitalia", iataCode: "AZ" }, { name: "All Nippon Airways", iataCode: "NH" }, { name: "Allegiant Air", iataCode: "G4" }, { name: "American Airlines", iataCode: "AA" }, { name: "Asiana Airlines", iataCode: "OZ" }, { name: "Avianca", iataCode: "AV" }, { name: "Azul Linhas Aereas Brasileiras", iataCode: "AD" }, { name: "Azur Air", iataCode: "ZF" }, { name: "Beijing Capital Airlines", iataCode: "JD" }, { name: "Boliviana de Aviacion", iataCode: "OB" }, { name: "British Airways", iataCode: "BA" }, { name: "Cathay Pacific", iataCode: "CX" }, { name: "Cebu Pacific Air", iataCode: "5J" }, { name: "China Airlines", iataCode: "CI" }, { name: "China Eastern Airlines", iataCode: "MU" }, { name: "China Southern Airlines", iataCode: "CZ" }, { name: "Condor", iataCode: "DE" }, { name: "Copa Airlines", iataCode: "CM" }, { name: "Delta Air Lines", iataCode: "DL" }, { name: "Easyfly", iataCode: "VE" }, { name: "EasyJet", iataCode: "U2" }, { name: "EcoJet", iataCode: "8J" }, { name: "Egyptair", iataCode: "MS" }, { name: "El Al", iataCode: "LY" }, { name: "Emirates Airlines", iataCode: "EK" }, { name: "Ethiopian Airlines", iataCode: "ET" }, { name: "Etihad Airways", iataCode: "EY" }, { name: "EVA Air", iataCode: "BR" }, { name: "Fiji Airways", iataCode: "FJ" }, { name: "Finnair", iataCode: "AY" }, { name: "Flybondi", iataCode: "FO" }, { name: "Flydubai", iataCode: "FZ" }, { name: "FlySafair", iataCode: "FA" }, { name: "Frontier Airlines", iataCode: "F9" }, { name: "Garuda Indonesia", iataCode: "GA" }, { name: "Go First", iataCode: "G8" }, { name: "Gol Linhas Aereas Inteligentes", iataCode: "G3" }, { name: "Hainan Airlines", iataCode: "HU" }, { name: "Hawaiian Airlines", iataCode: "HA" }, { name: "IndiGo Airlines", iataCode: "6E" }, { name: "Japan Airlines", iataCode: "JL" }, { name: "Jeju Air", iataCode: "7C" }, { name: "Jet2", iataCode: "LS" }, { name: "JetBlue Airways", iataCode: "B6" }, { name: "JetSMART", iataCode: "JA" }, { name: "Juneyao Airlines", iataCode: "HO" }, { name: "Kenya Airways", iataCode: "KQ" }, { name: "KLM Royal Dutch Airlines", iataCode: "KL" }, { name: "Korean Air", iataCode: "KE" }, { name: "Kulula.com", iataCode: "MN" }, { name: "LATAM Airlines", iataCode: "LA" }, { name: "Lion Air", iataCode: "JT" }, { name: "LOT Polish Airlines", iataCode: "LO" }, { name: "Lufthansa", iataCode: "LH" }, { name: "Libyan Airlines", iataCode: "LN" }, { name: "Linea Aerea Amaszonas", iataCode: "Z8" }, { name: "Malaysia Airlines", iataCode: "MH" }, { name: "Nordwind Airlines", iataCode: "N4" }, { name: "Norwegian Air Shuttle", iataCode: "DY" }, { name: "Oman Air", iataCode: "WY" }, { name: "Pakistan International Airlines", iataCode: "PK" }, { name: "Pegasus Airlines", iataCode: "PC" }, { name: "Philippine Airlines", iataCode: "PR" }, { name: "Qantas Group", iataCode: "QF" }, { name: "Qatar Airways", iataCode: "QR" }, { name: "Republic Airways", iataCode: "YX" }, { name: "Royal Air Maroc", iataCode: "AT" }, { name: "Ryanair", iataCode: "FR" }, { name: "S7 Airlines", iataCode: "S7" }, { name: "SAS", iataCode: "SK" }, { name: "Satena", iataCode: "9R" }, { name: "Saudia", iataCode: "SV" }, { name: "Shandong Airlines", iataCode: "SC" }, { name: "Sichuan Airlines", iataCode: "3U" }, { name: "Singapore Airlines", iataCode: "SQ" }, { name: "Sky Airline", iataCode: "H2" }, { name: "SkyWest Airlines", iataCode: "OO" }, { name: "South African Airways", iataCode: "SA" }, { name: "Southwest Airlines", iataCode: "WN" }, { name: "SpiceJet", iataCode: "SG" }, { name: "Spirit Airlines", iataCode: "NK" }, { name: "Spring Airlines", iataCode: "9S" }, { name: "SriLankan Airlines", iataCode: "UL" }, { name: "Star Peru", iataCode: "2I" }, { name: "Sun Country Airlines", iataCode: "SY" }, { name: "SunExpress", iataCode: "XQ" }, { name: "TAP Air Portugal", iataCode: "TP" }, { name: "Thai AirAsia", iataCode: "FD" }, { name: "Thai Airways", iataCode: "TG" }, { name: "TUI Airways", iataCode: "BY" }, { name: "Tunisair", iataCode: "TU" }, { name: "Turkish Airlines", iataCode: "TK" }, { name: "Ukraine International", iataCode: "PS" }, { name: "United Airlines", iataCode: "UA" }, { name: "Ural Airlines", iataCode: "U6" }, { name: "VietJet Air", iataCode: "VJ" }, { name: "Vietnam Airlines", iataCode: "VN" }, { name: "Virgin Atlantic Airways", iataCode: "VS" }, { name: "Virgin Australia", iataCode: "VA" }, { name: "VivaAerobus", iataCode: "VB" }, { name: "VOEPASS Linhas Aereas", iataCode: "2Z" }, { name: "Volaris", iataCode: "Y4" }, { name: "WestJet", iataCode: "WS" }, { name: "Wingo", iataCode: "P5" }, { name: "Wizz Air", iataCode: "W6" }];
|
|
18718
18686
|
var a = [{ name: "Aerospatiale/BAC Concorde", iataTypeCode: "SSC" }, { name: "Airbus A300", iataTypeCode: "AB3" }, { name: "Airbus A310", iataTypeCode: "310" }, { name: "Airbus A310-200", iataTypeCode: "312" }, { name: "Airbus A310-300", iataTypeCode: "313" }, { name: "Airbus A318", iataTypeCode: "318" }, { name: "Airbus A319", iataTypeCode: "319" }, { name: "Airbus A319neo", iataTypeCode: "31N" }, { name: "Airbus A320", iataTypeCode: "320" }, { name: "Airbus A320neo", iataTypeCode: "32N" }, { name: "Airbus A321", iataTypeCode: "321" }, { name: "Airbus A321neo", iataTypeCode: "32Q" }, { name: "Airbus A330", iataTypeCode: "330" }, { name: "Airbus A330-200", iataTypeCode: "332" }, { name: "Airbus A330-300", iataTypeCode: "333" }, { name: "Airbus A330-800neo", iataTypeCode: "338" }, { name: "Airbus A330-900neo", iataTypeCode: "339" }, { name: "Airbus A340", iataTypeCode: "340" }, { name: "Airbus A340-200", iataTypeCode: "342" }, { name: "Airbus A340-300", iataTypeCode: "343" }, { name: "Airbus A340-500", iataTypeCode: "345" }, { name: "Airbus A340-600", iataTypeCode: "346" }, { name: "Airbus A350", iataTypeCode: "350" }, { name: "Airbus A350-900", iataTypeCode: "359" }, { name: "Airbus A350-1000", iataTypeCode: "351" }, { name: "Airbus A380", iataTypeCode: "380" }, { name: "Airbus A380-800", iataTypeCode: "388" }, { name: "Antonov An-12", iataTypeCode: "ANF" }, { name: "Antonov An-24", iataTypeCode: "AN4" }, { name: "Antonov An-26", iataTypeCode: "A26" }, { name: "Antonov An-28", iataTypeCode: "A28" }, { name: "Antonov An-30", iataTypeCode: "A30" }, { name: "Antonov An-32", iataTypeCode: "A32" }, { name: "Antonov An-72", iataTypeCode: "AN7" }, { name: "Antonov An-124 Ruslan", iataTypeCode: "A4F" }, { name: "Antonov An-140", iataTypeCode: "A40" }, { name: "Antonov An-148", iataTypeCode: "A81" }, { name: "Antonov An-158", iataTypeCode: "A58" }, { name: "Antonov An-225 Mriya", iataTypeCode: "A5F" }, { name: "Boeing 707", iataTypeCode: "703" }, { name: "Boeing 717", iataTypeCode: "717" }, { name: "Boeing 720B", iataTypeCode: "B72" }, { name: "Boeing 727", iataTypeCode: "727" }, { name: "Boeing 727-100", iataTypeCode: "721" }, { name: "Boeing 727-200", iataTypeCode: "722" }, { name: "Boeing 737 MAX 7", iataTypeCode: "7M7" }, { name: "Boeing 737 MAX 8", iataTypeCode: "7M8" }, { name: "Boeing 737 MAX 9", iataTypeCode: "7M9" }, { name: "Boeing 737 MAX 10", iataTypeCode: "7MJ" }, { name: "Boeing 737", iataTypeCode: "737" }, { name: "Boeing 737-100", iataTypeCode: "731" }, { name: "Boeing 737-200", iataTypeCode: "732" }, { name: "Boeing 737-300", iataTypeCode: "733" }, { name: "Boeing 737-400", iataTypeCode: "734" }, { name: "Boeing 737-500", iataTypeCode: "735" }, { name: "Boeing 737-600", iataTypeCode: "736" }, { name: "Boeing 737-700", iataTypeCode: "73G" }, { name: "Boeing 737-800", iataTypeCode: "738" }, { name: "Boeing 737-900", iataTypeCode: "739" }, { name: "Boeing 747", iataTypeCode: "747" }, { name: "Boeing 747-100", iataTypeCode: "741" }, { name: "Boeing 747-200", iataTypeCode: "742" }, { name: "Boeing 747-300", iataTypeCode: "743" }, { name: "Boeing 747-400", iataTypeCode: "744" }, { name: "Boeing 747-400D", iataTypeCode: "74J" }, { name: "Boeing 747-8", iataTypeCode: "748" }, { name: "Boeing 747SP", iataTypeCode: "74L" }, { name: "Boeing 747SR", iataTypeCode: "74R" }, { name: "Boeing 757", iataTypeCode: "757" }, { name: "Boeing 757-200", iataTypeCode: "752" }, { name: "Boeing 757-300", iataTypeCode: "753" }, { name: "Boeing 767", iataTypeCode: "767" }, { name: "Boeing 767-200", iataTypeCode: "762" }, { name: "Boeing 767-300", iataTypeCode: "763" }, { name: "Boeing 767-400", iataTypeCode: "764" }, { name: "Boeing 777", iataTypeCode: "777" }, { name: "Boeing 777-200", iataTypeCode: "772" }, { name: "Boeing 777-200LR", iataTypeCode: "77L" }, { name: "Boeing 777-300", iataTypeCode: "773" }, { name: "Boeing 777-300ER", iataTypeCode: "77W" }, { name: "Boeing 787", iataTypeCode: "787" }, { name: "Boeing 787-8", iataTypeCode: "788" }, { name: "Boeing 787-9", iataTypeCode: "789" }, { name: "Boeing 787-10", iataTypeCode: "781" }, { name: "Canadair Challenger", iataTypeCode: "CCJ" }, { name: "Canadair CL-44", iataTypeCode: "CL4" }, { name: "Canadair Regional Jet 100", iataTypeCode: "CR1" }, { name: "Canadair Regional Jet 200", iataTypeCode: "CR2" }, { name: "Canadair Regional Jet 700", iataTypeCode: "CR7" }, { name: "Canadair Regional Jet 705", iataTypeCode: "CRA" }, { name: "Canadair Regional Jet 900", iataTypeCode: "CR9" }, { name: "Canadair Regional Jet 1000", iataTypeCode: "CRK" }, { name: "De Havilland Canada DHC-2 Beaver", iataTypeCode: "DHP" }, { name: "De Havilland Canada DHC-2 Turbo-Beaver", iataTypeCode: "DHR" }, { name: "De Havilland Canada DHC-3 Otter", iataTypeCode: "DHL" }, { name: "De Havilland Canada DHC-4 Caribou", iataTypeCode: "DHC" }, { name: "De Havilland Canada DHC-6 Twin Otter", iataTypeCode: "DHT" }, { name: "De Havilland Canada DHC-7 Dash 7", iataTypeCode: "DH7" }, { name: "De Havilland Canada DHC-8-100 Dash 8 / 8Q", iataTypeCode: "DH1" }, { name: "De Havilland Canada DHC-8-200 Dash 8 / 8Q", iataTypeCode: "DH2" }, { name: "De Havilland Canada DHC-8-300 Dash 8 / 8Q", iataTypeCode: "DH3" }, { name: "De Havilland Canada DHC-8-400 Dash 8Q", iataTypeCode: "DH4" }, { name: "De Havilland DH.104 Dove", iataTypeCode: "DHD" }, { name: "De Havilland DH.114 Heron", iataTypeCode: "DHH" }, { name: "Douglas DC-3", iataTypeCode: "D3F" }, { name: "Douglas DC-6", iataTypeCode: "D6F" }, { name: "Douglas DC-8-50", iataTypeCode: "D8T" }, { name: "Douglas DC-8-62", iataTypeCode: "D8L" }, { name: "Douglas DC-8-72", iataTypeCode: "D8Q" }, { name: "Douglas DC-9-10", iataTypeCode: "D91" }, { name: "Douglas DC-9-20", iataTypeCode: "D92" }, { name: "Douglas DC-9-30", iataTypeCode: "D93" }, { name: "Douglas DC-9-40", iataTypeCode: "D94" }, { name: "Douglas DC-9-50", iataTypeCode: "D95" }, { name: "Douglas DC-10", iataTypeCode: "D10" }, { name: "Douglas DC-10-10", iataTypeCode: "D1X" }, { name: "Douglas DC-10-30", iataTypeCode: "D1Y" }, { name: "Embraer 170", iataTypeCode: "E70" }, { name: "Embraer 175", iataTypeCode: "E75" }, { name: "Embraer 190", iataTypeCode: "E90" }, { name: "Embraer 195", iataTypeCode: "E95" }, { name: "Embraer E190-E2", iataTypeCode: "290" }, { name: "Embraer E195-E2", iataTypeCode: "295" }, { name: "Embraer EMB.110 Bandeirante", iataTypeCode: "EMB" }, { name: "Embraer EMB.120 Brasilia", iataTypeCode: "EM2" }, { name: "Embraer Legacy 600", iataTypeCode: "ER3" }, { name: "Embraer Phenom 100", iataTypeCode: "EP1" }, { name: "Embraer Phenom 300", iataTypeCode: "EP3" }, { name: "Embraer RJ135", iataTypeCode: "ER3" }, { name: "Embraer RJ140", iataTypeCode: "ERD" }, { name: "Embraer RJ145 Amazon", iataTypeCode: "ER4" }, { name: "Ilyushin IL18", iataTypeCode: "IL8" }, { name: "Ilyushin IL62", iataTypeCode: "IL6" }, { name: "Ilyushin IL76", iataTypeCode: "IL7" }, { name: "Ilyushin IL86", iataTypeCode: "ILW" }, { name: "Ilyushin IL96-300", iataTypeCode: "I93" }, { name: "Ilyushin IL114", iataTypeCode: "I14" }, { name: "Lockheed L-182 / 282 / 382 (L-100) Hercules", iataTypeCode: "LOH" }, { name: "Lockheed L-188 Electra", iataTypeCode: "LOE" }, { name: "Lockheed L-1011 Tristar", iataTypeCode: "L10" }, { name: "Lockheed L-1049 Super Constellation", iataTypeCode: "L49" }, { name: "McDonnell Douglas MD11", iataTypeCode: "M11" }, { name: "McDonnell Douglas MD80", iataTypeCode: "M80" }, { name: "McDonnell Douglas MD81", iataTypeCode: "M81" }, { name: "McDonnell Douglas MD82", iataTypeCode: "M82" }, { name: "McDonnell Douglas MD83", iataTypeCode: "M83" }, { name: "McDonnell Douglas MD87", iataTypeCode: "M87" }, { name: "McDonnell Douglas MD88", iataTypeCode: "M88" }, { name: "McDonnell Douglas MD90", iataTypeCode: "M90" }, { name: "Sukhoi Superjet 100-95", iataTypeCode: "SU9" }, { name: "Tupolev Tu-134", iataTypeCode: "TU3" }, { name: "Tupolev Tu-154", iataTypeCode: "TU5" }, { name: "Tupolev Tu-204", iataTypeCode: "T20" }, { name: "Yakovlev Yak-40", iataTypeCode: "YK4" }, { name: "Yakovlev Yak-42", iataTypeCode: "YK2" }];
|
|
18719
18687
|
var r = [{ name: "Adelaide International Airport", iataCode: "ADL" }, { name: "Adolfo Suarez Madrid-Barajas Airport", iataCode: "MAD" }, { name: "Aeroparque Jorge Newbery Airport", iataCode: "AEP" }, { name: "Afonso Pena International Airport", iataCode: "CWB" }, { name: "Alfonso Bonilla Aragon International Airport", iataCode: "CLO" }, { name: "Amsterdam Airport Schiphol", iataCode: "AMS" }, { name: "Arturo Merino Benitez International Airport", iataCode: "SCL" }, { name: "Auckland International Airport", iataCode: "AKL" }, { name: "Beijing Capital International Airport", iataCode: "PEK" }, { name: "Belem Val de Cans International Airport", iataCode: "BEL" }, { name: "Belo Horizonte Tancredo Neves International Airport", iataCode: "CNF" }, { name: "Berlin-Tegel Airport", iataCode: "TXL" }, { name: "Bole International Airport", iataCode: "ADD" }, { name: "Brasilia-Presidente Juscelino Kubitschek International Airport", iataCode: "BSB" }, { name: "Brisbane International Airport", iataCode: "BNE" }, { name: "Brussels Airport", iataCode: "BRU" }, { name: "Cairns Airport", iataCode: "CNS" }, { name: "Cairo International Airport", iataCode: "CAI" }, { name: "Canberra Airport", iataCode: "CBR" }, { name: "Capetown International Airport", iataCode: "CPT" }, { name: "Charles de Gaulle International Airport", iataCode: "CDG" }, { name: "Charlotte Douglas International Airport", iataCode: "CLT" }, { name: "Chengdu Shuangliu International Airport", iataCode: "CTU" }, { name: "Chhatrapati Shivaji International Airport", iataCode: "BOM" }, { name: "Chicago O'Hare International Airport", iataCode: "ORD" }, { name: "Chongqing Jiangbei International Airport", iataCode: "CKG" }, { name: "Christchurch International Airport", iataCode: "CHC" }, { name: "Copenhagen Kastrup Airport", iataCode: "CPH" }, { name: "Dallas Fort Worth International Airport", iataCode: "DFW" }, { name: "Daniel K. Inouye International Airport", iataCode: "HNL" }, { name: "Denver International Airport", iataCode: "DEN" }, { name: "Don Mueang International Airport", iataCode: "DMK" }, { name: "Dubai International Airport", iataCode: "DXB" }, { name: "Dublin Airport", iataCode: "DUB" }, { name: "Dusseldorf Airport", iataCode: "DUS" }, { name: "El Dorado International Airport", iataCode: "BOG" }, { name: "Eleftherios Venizelos International Airport", iataCode: "ATH" }, { name: "Faa'a International Airport", iataCode: "PPT" }, { name: "Fort Lauderdale Hollywood International Airport", iataCode: "FLL" }, { name: "Fortaleza Pinto Martins International Airport", iataCode: "FOR" }, { name: "Frankfurt am Main Airport", iataCode: "FRA" }, { name: "George Bush Intercontinental Houston Airport", iataCode: "IAH" }, { name: "Gold Coast Airport", iataCode: "OOL" }, { name: "Guarulhos - Governador Andre Franco Montoro International Airport", iataCode: "GRU" }, { name: "Hartsfield-Jackson Atlanta International Airport", iataCode: "ATL" }, { name: "Helsinki Vantaa Airport", iataCode: "HEL" }, { name: "Hobart International Airport", iataCode: "HBA" }, { name: "Hong Kong International Airport", iataCode: "HKG" }, { name: "Houari Boumediene Airport", iataCode: "ALG" }, { name: "Hurgada International Airport", iataCode: "HRG" }, { name: "Incheon International Airport", iataCode: "ICN" }, { name: "Indira Gandhi International Airport", iataCode: "DEL" }, { name: "Istanbul Airport", iataCode: "IST" }, { name: "Jacksons International Airport", iataCode: "POM" }, { name: "Jeju International Airport", iataCode: "CJU" }, { name: "John F Kennedy International Airport", iataCode: "JFK" }, { name: "Jorge Chavez International Airport", iataCode: "LIM" }, { name: "Jose Maria Cordova International Airport", iataCode: "MDE" }, { name: "Josep Tarradellas Barcelona-El Prat Airport", iataCode: "BCN" }, { name: "Kahului Airport", iataCode: "OGG" }, { name: "King Abdulaziz International Airport", iataCode: "JED" }, { name: "Kuala Lumpur International Airport", iataCode: "KUL" }, { name: "Kunming Changshui International Airport", iataCode: "KMG" }, { name: "La Tontouta International Airport", iataCode: "NOU" }, { name: "Leonardo da Vinci-Fiumicino Airport", iataCode: "FCO" }, { name: "London Heathrow Airport", iataCode: "LHR" }, { name: "Los Angeles International Airport", iataCode: "LAX" }, { name: "McCarran International Airport", iataCode: "LAS" }, { name: "Melbourne International Airport", iataCode: "MEL" }, { name: "Mexico City International Airport", iataCode: "MEX" }, { name: "Miami International Airport", iataCode: "MIA" }, { name: "Ministro Pistarini International Airport", iataCode: "EZE" }, { name: "Minneapolis-St Paul International/Wold-Chamberlain Airport", iataCode: "MSP" }, { name: "Mohammed V International Airport", iataCode: "CMN" }, { name: "Moscow Domodedovo Airport", iataCode: "DME" }, { name: "Munich Airport", iataCode: "MUC" }, { name: "Murtala Muhammed International Airport", iataCode: "LOS" }, { name: "Nadi International Airport", iataCode: "NAN" }, { name: "Nairobi Jomo Kenyatta International Airport", iataCode: "NBO" }, { name: "Narita International Airport", iataCode: "NRT" }, { name: "Newark Liberty International Airport", iataCode: "EWR" }, { name: "Ninoy Aquino International Airport", iataCode: "MNL" }, { name: "Noumea Magenta Airport", iataCode: "GEA" }, { name: "O. R. Tambo International Airport", iataCode: "JNB" }, { name: "Orlando International Airport", iataCode: "MCO" }, { name: "Oslo Lufthavn", iataCode: "OSL" }, { name: "Perth Airport", iataCode: "PER" }, { name: "Phoenix Sky Harbor International Airport", iataCode: "PHX" }, { name: "Recife Guararapes-Gilberto Freyre International Airport", iataCode: "REC" }, { name: "Rio de Janeiro Galeao International Airport", iataCode: "GIG" }, { name: "Salgado Filho International Airport", iataCode: "POA" }, { name: "Salvador Deputado Luis Eduardo Magalhaes International Airport", iataCode: "SSA" }, { name: "San Francisco International Airport", iataCode: "SFO" }, { name: "Santos Dumont Airport", iataCode: "SDU" }, { name: "Sao Paulo-Congonhas Airport", iataCode: "CGH" }, { name: "Seattle Tacoma International Airport", iataCode: "SEA" }, { name: "Shanghai Hongqiao International Airport", iataCode: "SHA" }, { name: "Shanghai Pudong International Airport", iataCode: "PVG" }, { name: "Shenzhen Bao'an International Airport", iataCode: "SZX" }, { name: "Sheremetyevo International Airport", iataCode: "SVO" }, { name: "Singapore Changi Airport", iataCode: "SIN" }, { name: "Soekarno-Hatta International Airport", iataCode: "CGK" }, { name: 'Stockholm-Arlanda Airport"', iataCode: "ARN" }, { name: "Suvarnabhumi Airport", iataCode: "BKK" }, { name: "Sydney Kingsford Smith International Airport", iataCode: "SYD" }, { name: "Taiwan Taoyuan International Airport", iataCode: "TPE" }, { name: "Tan Son Nhat International Airport", iataCode: "SGN" }, { name: "Tokyo Haneda International Airport", iataCode: "HND" }, { name: "Toronto Pearson International Airport", iataCode: "YYZ" }, { name: "Tunis Carthage International Airport", iataCode: "TUN" }, { name: "Vancouver International Airport", iataCode: "YVR" }, { name: "Vienna International Airport", iataCode: "VIE" }, { name: "Viracopos International Airport", iataCode: "VCP" }, { name: "Vnukovo International Airport", iataCode: "VKO" }, { name: "Wellington International Airport", iataCode: "WLG" }, { name: "Xi'an Xianyang International Airport", iataCode: "XIY" }, { name: "Zhukovsky International Airport", iataCode: "ZIA" }, { name: "Zurich Airport", iataCode: "ZRH" }];
|
|
@@ -20676,1099 +20644,630 @@ var dr = { "application/epub+zip": { extensions: ["epub"] }, "application/gzip":
|
|
|
20676
20644
|
var it = { directory_path: br, mime_type: dr }, gr = it;
|
|
20677
20645
|
var ot = { color: qe, database: ar, date: nr, hacker: or, internet: ur, location: hr, metadata: fr, system: gr }, Fi = ot;
|
|
20678
20646
|
var f = new Xe({ locale: [ys, Fi] });
|
|
20679
|
-
const
|
|
20680
|
-
|
|
20681
|
-
|
|
20682
|
-
|
|
20683
|
-
|
|
20684
|
-
|
|
20685
|
-
|
|
20686
|
-
|
|
20687
|
-
|
|
20688
|
-
|
|
20689
|
-
|
|
20690
|
-
tracking_parameters_enabled: true
|
|
20691
|
-
},
|
|
20692
|
-
created_at: "2024-03-01T10:00:00.000Z",
|
|
20693
|
-
updated_at: "2024-03-10T10:00:00.000Z"
|
|
20647
|
+
const PLATFORM_ID_MAPPING = {
|
|
20648
|
+
// Goose platform IDs
|
|
20649
|
+
"01958180-06a0-7681-8064-6834e166d2e4": "goose",
|
|
20650
|
+
// Goose dev
|
|
20651
|
+
"01946b5c-f7c0-721f-bb65-ed92aa29e2fd": "goose",
|
|
20652
|
+
// Goose prod
|
|
20653
|
+
// Renterra platform IDs
|
|
20654
|
+
"0195c8e3-2185-7323-a3f5-0be8f1395240": "renterra",
|
|
20655
|
+
// Renterra dev
|
|
20656
|
+
"4277dfb9-7535-4206-962d-3f29ad143d8a": "renterra"
|
|
20657
|
+
// Renterra prod
|
|
20694
20658
|
};
|
|
20695
|
-
const
|
|
20696
|
-
|
|
20697
|
-
|
|
20698
|
-
ad_platform: "meta",
|
|
20699
|
-
status: "connected",
|
|
20700
|
-
ad_platform_metadata: {
|
|
20701
|
-
name: "Sandbox Meta Ads",
|
|
20702
|
-
pixel_id: "sandbox-meta-pixel-456",
|
|
20703
|
-
platform: "meta",
|
|
20704
|
-
customer_id: "sandbox-m-act-789",
|
|
20705
|
-
offline_conversions_enabled: true,
|
|
20706
|
-
tracking_parameters_enabled: false
|
|
20707
|
-
},
|
|
20708
|
-
created_at: "2024-03-05T11:00:00.000Z",
|
|
20709
|
-
updated_at: "2024-03-15T11:00:00.000Z"
|
|
20659
|
+
const getPlatformConfigKey = (platformId) => {
|
|
20660
|
+
if (!platformId) return "default";
|
|
20661
|
+
return PLATFORM_ID_MAPPING[platformId] || "default";
|
|
20710
20662
|
};
|
|
20711
|
-
const
|
|
20712
|
-
|
|
20713
|
-
id:
|
|
20714
|
-
|
|
20715
|
-
|
|
20716
|
-
|
|
20717
|
-
|
|
20718
|
-
created_at: "2024-01-15T10:00:00.000Z",
|
|
20719
|
-
updated_at: "2024-01-15T10:00:00.000Z",
|
|
20720
|
-
data_integration_completed_at: "2024-01-15T11:00:00.000Z",
|
|
20721
|
-
website_tracking_completed_at: "2024-01-15T12:00:00.000Z"
|
|
20722
|
-
},
|
|
20723
|
-
adAccountsGoogle: mockGoogleAdsAccount,
|
|
20724
|
-
adAccountsMeta: mockMetaAdsAccount,
|
|
20725
|
-
adAccounts: [mockGoogleAdsAccount, mockMetaAdsAccount],
|
|
20726
|
-
baseAggregatedMetrics: {
|
|
20727
|
-
google: {
|
|
20728
|
-
business_id: sandboxBusinessId,
|
|
20729
|
-
ads_spend: 750,
|
|
20730
|
-
clicks: 400,
|
|
20731
|
-
impressions: 8500,
|
|
20732
|
-
measured_conversions: 8,
|
|
20733
|
-
measured_revenue: 6050,
|
|
20734
|
-
new_leads: 600,
|
|
20735
|
-
new_customers: 6,
|
|
20736
|
-
customer_ltv: 8488,
|
|
20737
|
-
roas: 12,
|
|
20738
|
-
cost_per_click: 1.5,
|
|
20739
|
-
click_through_rate: 0.0133,
|
|
20740
|
-
date_range: { start: "2024-01-01", end: "2024-01-30" },
|
|
20741
|
-
campaigns: [
|
|
20742
|
-
{
|
|
20743
|
-
id: "sandbox-google-search-campaign",
|
|
20744
|
-
name: "Google Search Campaign",
|
|
20745
|
-
channel: "google",
|
|
20746
|
-
business_id: sandboxBusinessId,
|
|
20747
|
-
ads_spend: 750,
|
|
20748
|
-
clicks: 400,
|
|
20749
|
-
impressions: 8500,
|
|
20750
|
-
measured_conversions: 8,
|
|
20751
|
-
measured_revenue: 6050,
|
|
20752
|
-
new_leads: 600,
|
|
20753
|
-
new_customers: 6,
|
|
20754
|
-
customer_ltv: 8488,
|
|
20755
|
-
roas: 12,
|
|
20756
|
-
cost_per_click: 1.5,
|
|
20757
|
-
click_through_rate: 0.0133,
|
|
20758
|
-
date_range: { start: "2024-01-01", end: "2024-01-30" },
|
|
20759
|
-
ad_platform_campaign_id: "sandbox-google-search-campaign"
|
|
20760
|
-
}
|
|
20761
|
-
]
|
|
20762
|
-
},
|
|
20763
|
-
meta: {
|
|
20764
|
-
business_id: sandboxBusinessId,
|
|
20765
|
-
ads_spend: 325,
|
|
20766
|
-
clicks: 300,
|
|
20767
|
-
impressions: 6900,
|
|
20768
|
-
measured_conversions: 4,
|
|
20769
|
-
measured_revenue: 3025,
|
|
20770
|
-
new_leads: 400,
|
|
20771
|
-
new_customers: 7,
|
|
20772
|
-
customer_ltv: 3150,
|
|
20773
|
-
roas: 9,
|
|
20774
|
-
cost_per_click: 0.4,
|
|
20775
|
-
click_through_rate: 0.025,
|
|
20776
|
-
date_range: { start: "2024-01-01", end: "2024-01-30" },
|
|
20777
|
-
campaigns: [
|
|
20778
|
-
{
|
|
20779
|
-
id: "sandbox-meta-campaign",
|
|
20780
|
-
name: "Sandbox Meta Campaign Beta",
|
|
20781
|
-
channel: "meta",
|
|
20782
|
-
business_id: sandboxBusinessId,
|
|
20783
|
-
ads_spend: 325,
|
|
20784
|
-
clicks: 300,
|
|
20785
|
-
impressions: 6900,
|
|
20786
|
-
measured_conversions: 4,
|
|
20787
|
-
measured_revenue: 3025,
|
|
20788
|
-
new_leads: 400,
|
|
20789
|
-
new_customers: 7,
|
|
20790
|
-
customer_ltv: 3150,
|
|
20791
|
-
roas: 9,
|
|
20792
|
-
cost_per_click: 0.4,
|
|
20793
|
-
click_through_rate: 0.025,
|
|
20794
|
-
date_range: { start: "2024-01-01", end: "2024-01-30" },
|
|
20795
|
-
ad_platform_campaign_id: "sandbox-meta-campaign"
|
|
20796
|
-
}
|
|
20797
|
-
]
|
|
20798
|
-
},
|
|
20799
|
-
all: {
|
|
20800
|
-
business_id: sandboxBusinessId,
|
|
20801
|
-
ads_spend: 750 + 325,
|
|
20802
|
-
clicks: 400 + 300,
|
|
20803
|
-
impressions: 8500 + 6900,
|
|
20804
|
-
measured_conversions: 8 + 4,
|
|
20805
|
-
measured_revenue: 6050 + 3025,
|
|
20806
|
-
new_leads: 600 + 400,
|
|
20807
|
-
new_customers: 5 + 7,
|
|
20808
|
-
customer_ltv: (5 * 8488 + 7 * 3150) / (5 + 7),
|
|
20809
|
-
roas: (6050 + 3025) / (750 + 325),
|
|
20810
|
-
cost_per_click: (750 + 300) / (400 + 300),
|
|
20811
|
-
click_through_rate: (400 + 300) / (8500 + 6900),
|
|
20812
|
-
date_range: { start: "2024-01-01", end: "2024-01-30" },
|
|
20813
|
-
campaigns: []
|
|
20814
|
-
}
|
|
20663
|
+
const defaultPlatformConfigs = {
|
|
20664
|
+
default: {
|
|
20665
|
+
id: "default",
|
|
20666
|
+
name: "Sandbox",
|
|
20667
|
+
brandColors: ["#2563eb", "#059669", "#dc2626", "#9333ea"],
|
|
20668
|
+
locationNames: ["Manhattan", "Brooklyn", "Queens", "Bronx"],
|
|
20669
|
+
locationAreas: ["New York, NY", "Brooklyn, NY", "Queens, NY", "Bronx, NY"]
|
|
20815
20670
|
},
|
|
20816
|
-
|
|
20817
|
-
|
|
20818
|
-
|
|
20819
|
-
|
|
20820
|
-
|
|
20821
|
-
|
|
20822
|
-
|
|
20823
|
-
|
|
20824
|
-
|
|
20825
|
-
|
|
20826
|
-
|
|
20827
|
-
|
|
20828
|
-
|
|
20829
|
-
|
|
20830
|
-
|
|
20831
|
-
count: 15,
|
|
20832
|
-
amount: 13014.7
|
|
20833
|
-
},
|
|
20834
|
-
{
|
|
20835
|
-
primary_source: "Google Ads",
|
|
20836
|
-
source_type: "paid",
|
|
20837
|
-
count: 58,
|
|
20838
|
-
amount: 11968.48
|
|
20839
|
-
},
|
|
20840
|
-
{
|
|
20841
|
-
primary_source: "Google Organic Search",
|
|
20842
|
-
source_type: "organic_search",
|
|
20843
|
-
count: 19,
|
|
20844
|
-
amount: 2525.65
|
|
20845
|
-
},
|
|
20846
|
-
{
|
|
20847
|
-
primary_source: "Yahoo Organic",
|
|
20848
|
-
source_type: "organic_search",
|
|
20849
|
-
count: 3,
|
|
20850
|
-
amount: 945.05
|
|
20851
|
-
},
|
|
20852
|
-
{
|
|
20853
|
-
primary_source: "Facebook Organic",
|
|
20854
|
-
source_type: "social",
|
|
20855
|
-
count: 8,
|
|
20856
|
-
amount: 399.65
|
|
20857
|
-
},
|
|
20858
|
-
{
|
|
20859
|
-
primary_source: "unknown",
|
|
20860
|
-
source_type: "social",
|
|
20861
|
-
count: 1,
|
|
20862
|
-
amount: 278.89
|
|
20863
|
-
},
|
|
20864
|
-
{
|
|
20865
|
-
primary_source: "Facebook Ads",
|
|
20866
|
-
source_type: "paid",
|
|
20867
|
-
count: 3,
|
|
20868
|
-
amount: 5984.235
|
|
20869
|
-
// 9175.83
|
|
20870
|
-
},
|
|
20871
|
-
{
|
|
20872
|
-
primary_source: "android-app:",
|
|
20873
|
-
source_type: "referral",
|
|
20874
|
-
count: 7,
|
|
20875
|
-
amount: 185.17
|
|
20876
|
-
},
|
|
20877
|
-
{
|
|
20878
|
-
primary_source: "Bing Organic",
|
|
20879
|
-
source_type: "organic_search",
|
|
20880
|
-
count: 4,
|
|
20881
|
-
amount: 180.65
|
|
20882
|
-
},
|
|
20883
|
-
{
|
|
20884
|
-
primary_source: "duckduckgo.com",
|
|
20885
|
-
source_type: "referral",
|
|
20886
|
-
count: 1,
|
|
20887
|
-
amount: 146.78
|
|
20888
|
-
}
|
|
20671
|
+
goose: {
|
|
20672
|
+
id: "goose",
|
|
20673
|
+
name: "ACME Pet Spa",
|
|
20674
|
+
brandColors: ["#f59e0b", "#dc2626", "#059669", "#7c3aed"],
|
|
20675
|
+
locationNames: [
|
|
20676
|
+
"Pampered Paws Spa",
|
|
20677
|
+
"Fluffy Coat Grooming",
|
|
20678
|
+
"Tail Waggers Retreat",
|
|
20679
|
+
"Premier Pet Palace"
|
|
20680
|
+
],
|
|
20681
|
+
locationAreas: [
|
|
20682
|
+
"San Francisco, CA",
|
|
20683
|
+
"Oakland, CA",
|
|
20684
|
+
"Berkeley, CA",
|
|
20685
|
+
"Palo Alto, CA"
|
|
20889
20686
|
]
|
|
20890
20687
|
},
|
|
20891
|
-
|
|
20892
|
-
|
|
20893
|
-
|
|
20894
|
-
|
|
20895
|
-
|
|
20896
|
-
|
|
20897
|
-
|
|
20898
|
-
|
|
20899
|
-
|
|
20900
|
-
|
|
20901
|
-
|
|
20902
|
-
|
|
20903
|
-
|
|
20904
|
-
|
|
20905
|
-
|
|
20906
|
-
|
|
20907
|
-
|
|
20908
|
-
|
|
20909
|
-
|
|
20910
|
-
|
|
20911
|
-
|
|
20912
|
-
|
|
20913
|
-
|
|
20914
|
-
|
|
20915
|
-
|
|
20916
|
-
|
|
20917
|
-
|
|
20918
|
-
|
|
20919
|
-
|
|
20920
|
-
|
|
20921
|
-
|
|
20922
|
-
|
|
20923
|
-
|
|
20924
|
-
|
|
20925
|
-
|
|
20926
|
-
|
|
20927
|
-
|
|
20928
|
-
|
|
20929
|
-
|
|
20930
|
-
|
|
20931
|
-
|
|
20932
|
-
|
|
20933
|
-
|
|
20934
|
-
|
|
20935
|
-
|
|
20936
|
-
|
|
20937
|
-
|
|
20938
|
-
|
|
20939
|
-
|
|
20940
|
-
|
|
20941
|
-
|
|
20942
|
-
|
|
20943
|
-
|
|
20944
|
-
}
|
|
20945
|
-
},
|
|
20946
|
-
{
|
|
20947
|
-
id: "019615dc-9ea5-7fce-af51-51d311354885",
|
|
20948
|
-
created_at: "2025-04-08T14:44:05.536Z",
|
|
20949
|
-
updated_at: "2025-04-08T14:45:02.324Z",
|
|
20950
|
-
platform_id: "01958180-06a0-7681-8064-6834e166d2e4",
|
|
20951
|
-
business_id: sandboxBusinessId,
|
|
20952
|
-
partner_user_id: "fake-partner-user-002",
|
|
20953
|
-
external_id: "cm92103i803cs105k8b0l18hc",
|
|
20954
|
-
campaign_id: "sandbox-meta-campaign",
|
|
20955
|
-
communication_job_id: null,
|
|
20956
|
-
status: "paid",
|
|
20957
|
-
amount: "1120.75",
|
|
20958
|
-
currency: "USD",
|
|
20959
|
-
created_date: "2025-04-03T23:07:47.000Z",
|
|
20960
|
-
paid_date: "2025-04-03T23:07:47.000Z",
|
|
20961
|
-
due_date: "2025-04-26T00:00:00.000Z",
|
|
20962
|
-
deleted_at: null,
|
|
20963
|
-
metadata: {
|
|
20964
|
-
source_info: {
|
|
20965
|
-
referrer: "https://www.facebook.com/",
|
|
20966
|
-
utm_medium: "cpc",
|
|
20967
|
-
utm_source: "facebook",
|
|
20968
|
-
ad_platform: "meta",
|
|
20969
|
-
campaign_id: "sandbox-meta-campaign",
|
|
20970
|
-
source_type: "paid",
|
|
20971
|
-
utm_campaign: "Sandbox Meta Campaign Beta",
|
|
20972
|
-
ad_account_id: "sandbox-m-act-789",
|
|
20973
|
-
primary_source: "Facebook Ads",
|
|
20974
|
-
referrer_domain: "facebook.com",
|
|
20975
|
-
landing_page_url: "https://example.com/landing_page_meta_1",
|
|
20976
|
-
campaign_name: "Sandbox Meta Campaign Beta"
|
|
20977
|
-
}
|
|
20978
|
-
},
|
|
20979
|
-
user_name: "Carlos Ramirez",
|
|
20980
|
-
user_email: "c.ramirez@outlook.com",
|
|
20981
|
-
user_external_id: "fake-user-ext-002",
|
|
20982
|
-
source_info: {
|
|
20983
|
-
referrer: "https://www.facebook.com/",
|
|
20984
|
-
utm_medium: "cpc",
|
|
20985
|
-
utm_source: "facebook",
|
|
20986
|
-
ad_platform: "meta",
|
|
20987
|
-
campaign_id: "sandbox-meta-campaign",
|
|
20988
|
-
source_type: "paid",
|
|
20989
|
-
utm_campaign: "Sandbox Meta Campaign Beta",
|
|
20990
|
-
ad_account_id: "sandbox-m-act-789",
|
|
20991
|
-
primary_source: "Facebook Ads",
|
|
20992
|
-
referrer_domain: "facebook.com",
|
|
20993
|
-
landing_page_url: "https://example.com/landing_page_meta_1",
|
|
20994
|
-
campaign_name: "Sandbox Meta Campaign Beta"
|
|
20995
|
-
}
|
|
20996
|
-
},
|
|
20997
|
-
{
|
|
20998
|
-
id: "019615dc-9eaf-7f6f-b202-65e39f97487e",
|
|
20999
|
-
created_at: "2025-04-08T14:44:05.527Z",
|
|
21000
|
-
updated_at: "2025-04-08T14:45:02.339Z",
|
|
21001
|
-
platform_id: "01958180-06a0-7681-8064-6834e166d2e4",
|
|
21002
|
-
business_id: sandboxBusinessId,
|
|
21003
|
-
partner_user_id: "fake-partner-user-003",
|
|
21004
|
-
external_id: "cm920vc9s02qbgcprqphwyf0h",
|
|
21005
|
-
campaign_id: "sandbox-google-search-campaign",
|
|
21006
|
-
communication_job_id: null,
|
|
21007
|
-
status: "paid",
|
|
21008
|
-
amount: "365.00",
|
|
21009
|
-
currency: "USD",
|
|
21010
|
-
created_date: "2025-04-03T23:04:05.000Z",
|
|
21011
|
-
paid_date: "2025-04-03T23:04:05.000Z",
|
|
21012
|
-
due_date: "2025-04-21T00:00:00.000Z",
|
|
21013
|
-
deleted_at: null,
|
|
21014
|
-
metadata: {
|
|
21015
|
-
source_info: {
|
|
21016
|
-
referrer: "https://www.google.com/",
|
|
21017
|
-
utm_medium: "organic",
|
|
21018
|
-
utm_source: "google",
|
|
21019
|
-
ad_platform: "google",
|
|
21020
|
-
campaign_id: "sandbox-google-search-campaign",
|
|
21021
|
-
source_type: "paid",
|
|
21022
|
-
utm_campaign: "Sandbox Google Campaign Gamma",
|
|
21023
|
-
ad_account_id: "sandbox-g-customer-123",
|
|
21024
|
-
primary_source: "Google Ads",
|
|
21025
|
-
referrer_domain: "google.com",
|
|
21026
|
-
landing_page_url: "https://example.com/landing_page_google_2",
|
|
21027
|
-
campaign_name: "Sandbox Google Campaign Gamma"
|
|
21028
|
-
}
|
|
21029
|
-
},
|
|
21030
|
-
user_name: "Priya Singh",
|
|
21031
|
-
user_email: "priya.singh@yahoo.com",
|
|
21032
|
-
user_external_id: "fake-user-ext-003",
|
|
21033
|
-
source_info: {
|
|
21034
|
-
referrer: "https://www.google.com/",
|
|
21035
|
-
utm_medium: "organic",
|
|
21036
|
-
utm_source: "google",
|
|
21037
|
-
ad_platform: "google",
|
|
21038
|
-
campaign_id: "sandbox-google-search-campaign",
|
|
21039
|
-
source_type: "paid",
|
|
21040
|
-
utm_campaign: "Sandbox Google Campaign Gamma",
|
|
21041
|
-
ad_account_id: "sandbox-g-customer-123",
|
|
21042
|
-
primary_source: "Google Ads",
|
|
21043
|
-
referrer_domain: "google.com",
|
|
21044
|
-
landing_page_url: "https://example.com/landing_page_google_2",
|
|
21045
|
-
campaign_name: "Sandbox Google Campaign Gamma"
|
|
21046
|
-
}
|
|
21047
|
-
},
|
|
21048
|
-
{
|
|
21049
|
-
id: "019615dc-9eb4-71ac-bb7e-41a47aa99387",
|
|
21050
|
-
created_at: "2025-04-08T14:44:05.552Z",
|
|
21051
|
-
updated_at: "2025-04-08T14:45:02.343Z",
|
|
21052
|
-
platform_id: "01958180-06a0-7681-8064-6834e166d2e4",
|
|
21053
|
-
business_id: sandboxBusinessId,
|
|
21054
|
-
partner_user_id: "fake-partner-user-004",
|
|
21055
|
-
external_id: "cm9206knj039k105krtcb4rks",
|
|
21056
|
-
campaign_id: null,
|
|
21057
|
-
communication_job_id: null,
|
|
21058
|
-
status: "paid",
|
|
21059
|
-
amount: "247.50",
|
|
21060
|
-
currency: "USD",
|
|
21061
|
-
created_date: "2025-04-03T22:44:50.000Z",
|
|
21062
|
-
paid_date: "2025-04-03T22:44:50.000Z",
|
|
21063
|
-
due_date: "2025-05-12T00:00:00.000Z",
|
|
21064
|
-
deleted_at: null,
|
|
21065
|
-
metadata: {
|
|
21066
|
-
source_info: {
|
|
21067
|
-
source_type: "social",
|
|
21068
|
-
primary_source: "Facebook Organic"
|
|
21069
|
-
}
|
|
21070
|
-
},
|
|
21071
|
-
user_name: "Michael Chen",
|
|
21072
|
-
user_email: "michael.chen@protonmail.com",
|
|
21073
|
-
user_external_id: "fake-user-ext-004",
|
|
21074
|
-
source_info: {
|
|
21075
|
-
source_type: "social",
|
|
21076
|
-
primary_source: "Facebook Organic"
|
|
21077
|
-
}
|
|
21078
|
-
},
|
|
21079
|
-
{
|
|
21080
|
-
id: "019615dc-9ed0-77e4-b1c2-d15599b67afe",
|
|
21081
|
-
created_at: "2025-04-08T14:44:05.521Z",
|
|
21082
|
-
updated_at: "2025-04-08T14:45:02.365Z",
|
|
21083
|
-
platform_id: "01958180-06a0-7681-8064-6834e166d2e4",
|
|
21084
|
-
business_id: sandboxBusinessId,
|
|
21085
|
-
partner_user_id: "fake-partner-user-005",
|
|
21086
|
-
external_id: "cm91zrzyg02q5a87eai6rpft3",
|
|
21087
|
-
campaign_id: "sandbox-google-campaign-1",
|
|
21088
|
-
communication_job_id: null,
|
|
21089
|
-
status: "paid",
|
|
21090
|
-
amount: "341.10",
|
|
21091
|
-
currency: "USD",
|
|
21092
|
-
created_date: "2025-04-03T22:33:30.000Z",
|
|
21093
|
-
paid_date: "2025-04-03T22:33:30.000Z",
|
|
21094
|
-
due_date: "2025-04-19T00:00:00.000Z",
|
|
21095
|
-
deleted_at: null,
|
|
21096
|
-
metadata: {
|
|
21097
|
-
source_info: {
|
|
21098
|
-
source_type: "organic_search",
|
|
21099
|
-
primary_source: "Bing Organic"
|
|
21100
|
-
}
|
|
21101
|
-
},
|
|
21102
|
-
source_info: {
|
|
21103
|
-
source_type: "organic_search",
|
|
21104
|
-
primary_source: "Bing Organic"
|
|
21105
|
-
},
|
|
21106
|
-
user_name: "Samantha Lee",
|
|
21107
|
-
user_email: "sam.lee@gmail.com",
|
|
21108
|
-
user_external_id: "fake-user-ext-005"
|
|
21109
|
-
},
|
|
21110
|
-
{
|
|
21111
|
-
id: "019615dc-9e8f-7ec0-a18f-4015b9f18cc5",
|
|
21112
|
-
created_at: "2025-04-08T14:44:05.521Z",
|
|
21113
|
-
updated_at: "2025-04-08T14:45:02.308Z",
|
|
21114
|
-
platform_id: "01958180-06a0-7681-8064-6834e166d2e4",
|
|
21115
|
-
business_id: sandboxBusinessId,
|
|
21116
|
-
partner_user_id: "fake-partner-user-006",
|
|
21117
|
-
external_id: "cm91vhnqj01w0a87ep93avvfm",
|
|
21118
|
-
campaign_id: null,
|
|
21119
|
-
communication_job_id: null,
|
|
21120
|
-
status: "paid",
|
|
21121
|
-
amount: "1131.20",
|
|
21122
|
-
currency: "USD",
|
|
21123
|
-
created_date: "2025-04-03T20:33:29.000Z",
|
|
21124
|
-
paid_date: "2025-04-03T20:33:29.000Z",
|
|
21125
|
-
due_date: "2025-04-05T00:00:00.000Z",
|
|
21126
|
-
deleted_at: null,
|
|
21127
|
-
metadata: {
|
|
21128
|
-
source_info: {
|
|
21129
|
-
source_type: "direct",
|
|
21130
|
-
primary_source: "direct"
|
|
21131
|
-
}
|
|
21132
|
-
},
|
|
21133
|
-
source_info: {
|
|
21134
|
-
source_type: "direct",
|
|
21135
|
-
primary_source: "direct"
|
|
21136
|
-
},
|
|
21137
|
-
user_name: "David Kim",
|
|
21138
|
-
user_email: "david.kim@icloud.com",
|
|
21139
|
-
user_external_id: "fake-user-ext-006"
|
|
21140
|
-
},
|
|
21141
|
-
{
|
|
21142
|
-
id: "019615dc-9ebe-79bb-9a6d-8e5555f15157",
|
|
21143
|
-
created_at: "2025-04-08T14:44:05.539Z",
|
|
21144
|
-
updated_at: "2025-04-08T14:45:02.352Z",
|
|
21145
|
-
platform_id: "01958180-06a0-7681-8064-6834e166d2e4",
|
|
21146
|
-
business_id: sandboxBusinessId,
|
|
21147
|
-
partner_user_id: "fake-partner-user-007",
|
|
21148
|
-
external_id: "cm91v66mv01ytd7tksb2jvzz2",
|
|
21149
|
-
campaign_id: null,
|
|
21150
|
-
communication_job_id: null,
|
|
21151
|
-
status: "paid",
|
|
21152
|
-
amount: "470.00",
|
|
21153
|
-
currency: "USD",
|
|
21154
|
-
created_date: "2025-04-03T20:24:33.000Z",
|
|
21155
|
-
paid_date: "2025-04-03T20:24:33.000Z",
|
|
21156
|
-
due_date: "2025-04-09T00:00:00.000Z",
|
|
21157
|
-
deleted_at: null,
|
|
21158
|
-
metadata: {
|
|
21159
|
-
source_info: {
|
|
21160
|
-
referrer: "https://www.bing.com/",
|
|
21161
|
-
utm_source: "bing",
|
|
21162
|
-
source_type: "organic_search",
|
|
21163
|
-
primary_source: "Bing Organic",
|
|
21164
|
-
referrer_domain: "bing.com",
|
|
21165
|
-
landing_page_url: "https://example.com/boarding/"
|
|
21166
|
-
}
|
|
21167
|
-
},
|
|
21168
|
-
user_name: "Mohammed Ali",
|
|
21169
|
-
user_email: "m.ali@hotmail.com",
|
|
21170
|
-
user_external_id: "fake-user-ext-007"
|
|
21171
|
-
},
|
|
21172
|
-
{
|
|
21173
|
-
id: "019615dc-9ec1-73ea-b008-bc8797d2687e",
|
|
21174
|
-
created_at: "2025-04-08T14:44:05.537Z",
|
|
21175
|
-
updated_at: "2025-04-08T14:45:02.362Z",
|
|
21176
|
-
platform_id: "01958180-06a0-7681-8064-6834e166d2e4",
|
|
21177
|
-
business_id: sandboxBusinessId,
|
|
21178
|
-
partner_user_id: "fake-partner-user-008",
|
|
21179
|
-
external_id: "cm91uzeaa01ua105ky6toils7",
|
|
21180
|
-
campaign_id: null,
|
|
21181
|
-
communication_job_id: null,
|
|
21182
|
-
status: "paid",
|
|
21183
|
-
amount: "117.70",
|
|
21184
|
-
currency: "USD",
|
|
21185
|
-
created_date: "2025-04-03T20:19:17.000Z",
|
|
21186
|
-
paid_date: "2025-04-03T20:19:17.000Z",
|
|
21187
|
-
due_date: "2025-04-09T00:00:00.000Z",
|
|
21188
|
-
deleted_at: null,
|
|
21189
|
-
metadata: null,
|
|
21190
|
-
user_name: "Harley Quinn",
|
|
21191
|
-
user_email: "harley.quinn@example.com",
|
|
21192
|
-
user_external_id: "fake-user-ext-008"
|
|
21193
|
-
},
|
|
21194
|
-
{
|
|
21195
|
-
id: "019615dc-9ed2-7cd6-a2ce-9bcf0fc58c93",
|
|
21196
|
-
created_at: "2025-04-08T14:44:05.556Z",
|
|
21197
|
-
updated_at: "2025-04-08T14:45:02.373Z",
|
|
21198
|
-
platform_id: "01958180-06a0-7681-8064-6834e166d2e4",
|
|
21199
|
-
business_id: sandboxBusinessId,
|
|
21200
|
-
partner_user_id: "fake-partner-user-009",
|
|
21201
|
-
external_id: "cm91uf9lk016bgcprimw8ujr0",
|
|
21202
|
-
campaign_id: "sandbox-meta-campaign",
|
|
21203
|
-
communication_job_id: null,
|
|
21204
|
-
status: "paid",
|
|
21205
|
-
amount: "750.00",
|
|
21206
|
-
currency: "USD",
|
|
21207
|
-
created_date: "2025-04-03T20:03:38.000Z",
|
|
21208
|
-
paid_date: "2025-04-03T20:03:38.000Z",
|
|
21209
|
-
due_date: "2025-04-24T00:00:00.000Z",
|
|
21210
|
-
deleted_at: null,
|
|
21211
|
-
metadata: {
|
|
21212
|
-
source_info: {
|
|
21213
|
-
referrer: "http://m.facebook.com/",
|
|
21214
|
-
utm_medium: "social_organic",
|
|
21215
|
-
utm_source: "meta",
|
|
21216
|
-
ad_platform: "meta",
|
|
21217
|
-
campaign_id: "sandbox-meta-campaign",
|
|
21218
|
-
source_type: "paid",
|
|
21219
|
-
utm_campaign: "Sandbox Meta Campaign Delta",
|
|
21220
|
-
ad_account_id: "sandbox-m-act-789",
|
|
21221
|
-
primary_source: "Facebook Ads",
|
|
21222
|
-
referrer_domain: "m.facebook.com",
|
|
21223
|
-
landing_page_url: "https://example.com/landing_page_meta_2",
|
|
21224
|
-
campaign_name: "Sandbox Meta Campaign Delta"
|
|
21225
|
-
}
|
|
21226
|
-
},
|
|
21227
|
-
user_name: "Anna Petrova",
|
|
21228
|
-
user_email: "anna.petrova@mail.ru",
|
|
21229
|
-
user_external_id: "fake-user-ext-009",
|
|
21230
|
-
source_info: {
|
|
21231
|
-
referrer: "http://m.facebook.com/",
|
|
21232
|
-
utm_medium: "social_organic",
|
|
21233
|
-
utm_source: "meta",
|
|
21234
|
-
ad_platform: "meta",
|
|
21235
|
-
campaign_id: "sandbox-meta-campaign",
|
|
21236
|
-
source_type: "paid",
|
|
21237
|
-
utm_campaign: "Sandbox Meta Campaign Delta",
|
|
21238
|
-
ad_account_id: "sandbox-m-act-789",
|
|
21239
|
-
primary_source: "Facebook Ads",
|
|
21240
|
-
referrer_domain: "m.facebook.com",
|
|
21241
|
-
landing_page_url: "https://example.com/landing_page_meta_2",
|
|
21242
|
-
campaign_name: "Sandbox Meta Campaign Delta"
|
|
21243
|
-
}
|
|
21244
|
-
},
|
|
21245
|
-
{
|
|
21246
|
-
id: "019615dc-9ec0-7cae-851e-7ca31ecf4d4d",
|
|
21247
|
-
created_at: "2025-04-08T14:44:05.559Z",
|
|
21248
|
-
updated_at: "2025-04-08T14:45:02.353Z",
|
|
21249
|
-
platform_id: "01958180-06a0-7681-8064-6834e166d2e4",
|
|
21250
|
-
business_id: sandboxBusinessId,
|
|
21251
|
-
partner_user_id: "fake-partner-user-010",
|
|
21252
|
-
external_id: "cm91u841g014rgcprenattziv",
|
|
21253
|
-
campaign_id: "sandbox-google-campaign-1",
|
|
21254
|
-
communication_job_id: null,
|
|
21255
|
-
status: "paid",
|
|
21256
|
-
amount: "755.00",
|
|
21257
|
-
currency: "USD",
|
|
21258
|
-
created_date: "2025-04-03T19:58:04.000Z",
|
|
21259
|
-
paid_date: "2025-04-03T19:58:04.000Z",
|
|
21260
|
-
due_date: "2025-04-07T00:00:00.000Z",
|
|
21261
|
-
deleted_at: null,
|
|
21262
|
-
metadata: {
|
|
21263
|
-
source_info: {
|
|
21264
|
-
referrer: "https://www.google.com/search",
|
|
21265
|
-
utm_medium: "cpc",
|
|
21266
|
-
utm_source: "google",
|
|
21267
|
-
ad_platform: "google",
|
|
21268
|
-
campaign_id: "sandbox-google-search-campaign",
|
|
21269
|
-
source_type: "paid",
|
|
21270
|
-
utm_campaign: "Sandbox Google Search Campaign",
|
|
21271
|
-
ad_account_id: "sandbox-g-customer-123",
|
|
21272
|
-
primary_source: "Google Ads",
|
|
21273
|
-
referrer_domain: "google.com",
|
|
21274
|
-
landing_page_url: "https://example.com/landing_page_google_1",
|
|
21275
|
-
campaign_name: "Sandbox Google Search Campaign"
|
|
21276
|
-
}
|
|
21277
|
-
},
|
|
21278
|
-
user_name: "Lucas Silva",
|
|
21279
|
-
user_email: "lucas.silva@gmail.com",
|
|
21280
|
-
user_external_id: "fake-user-ext-010",
|
|
21281
|
-
source_info: {
|
|
21282
|
-
source_type: "organic_search",
|
|
21283
|
-
primary_source: "Yahoo Organic"
|
|
21284
|
-
}
|
|
21285
|
-
},
|
|
21286
|
-
{
|
|
21287
|
-
id: "019615dc-9ebf-70eb-b4f2-5d745708d1d9",
|
|
21288
|
-
created_at: "2025-04-08T14:44:05.743Z",
|
|
21289
|
-
updated_at: "2025-04-08T14:45:02.353Z",
|
|
21290
|
-
platform_id: "01958180-06a0-7681-8064-6834e166d2e4",
|
|
21291
|
-
business_id: sandboxBusinessId,
|
|
21292
|
-
partner_user_id: "fake-partner-user-011",
|
|
21293
|
-
external_id: "cm91t5d5h01ayla1em247pcur",
|
|
21294
|
-
campaign_id: null,
|
|
21295
|
-
communication_job_id: null,
|
|
21296
|
-
status: "paid",
|
|
21297
|
-
amount: "329.65",
|
|
21298
|
-
currency: "USD",
|
|
21299
|
-
created_date: "2025-04-03T19:27:56.000Z",
|
|
21300
|
-
paid_date: "2025-04-03T19:27:56.000Z",
|
|
21301
|
-
due_date: "2025-04-04T00:00:00.000Z",
|
|
21302
|
-
deleted_at: null,
|
|
21303
|
-
metadata: null,
|
|
21304
|
-
user_name: "Kate Austen",
|
|
21305
|
-
user_email: "kate.austen@example.com",
|
|
21306
|
-
user_external_id: "fake-user-ext-011"
|
|
21307
|
-
},
|
|
21308
|
-
{
|
|
21309
|
-
id: "019615dc-9ed4-7425-82b5-9ff1153ce66d",
|
|
21310
|
-
created_at: "2025-04-08T14:44:05.569Z",
|
|
21311
|
-
updated_at: "2025-04-08T14:45:02.376Z",
|
|
21312
|
-
platform_id: "01958180-06a0-7681-8064-6834e166d2e4",
|
|
21313
|
-
business_id: sandboxBusinessId,
|
|
21314
|
-
partner_user_id: "fake-partner-user-012",
|
|
21315
|
-
external_id: "cm91t4qxc01aola1esayp6iwb",
|
|
21316
|
-
campaign_id: null,
|
|
21317
|
-
communication_job_id: null,
|
|
21318
|
-
status: "paid",
|
|
21319
|
-
amount: "630.15",
|
|
21320
|
-
currency: "USD",
|
|
21321
|
-
created_date: "2025-04-03T19:27:27.000Z",
|
|
21322
|
-
paid_date: "2025-04-03T19:27:27.000Z",
|
|
21323
|
-
due_date: "2025-04-10T00:00:00.000Z",
|
|
21324
|
-
deleted_at: null,
|
|
21325
|
-
metadata: {
|
|
21326
|
-
source_info: {
|
|
21327
|
-
source_type: "direct",
|
|
21328
|
-
primary_source: "direct"
|
|
21329
|
-
}
|
|
21330
|
-
},
|
|
21331
|
-
user_name: "Liz Lemon",
|
|
21332
|
-
user_email: "liz.lemon@example.com",
|
|
21333
|
-
user_external_id: "fake-user-ext-012",
|
|
21334
|
-
source_info: {
|
|
21335
|
-
source_type: "direct",
|
|
21336
|
-
primary_source: "direct"
|
|
21337
|
-
}
|
|
21338
|
-
},
|
|
21339
|
-
{
|
|
21340
|
-
id: "019615dc-9edf-7522-91ae-8915389496ad",
|
|
21341
|
-
created_at: "2025-04-08T14:44:05.546Z",
|
|
21342
|
-
updated_at: "2025-04-08T14:45:02.383Z",
|
|
21343
|
-
platform_id: "01958180-06a0-7681-8064-6834e166d2e4",
|
|
21344
|
-
business_id: sandboxBusinessId,
|
|
21345
|
-
partner_user_id: "fake-partner-user-013",
|
|
21346
|
-
external_id: "cm91sqvf70111a87ey4t94n6b",
|
|
21347
|
-
campaign_id: "sandbox-google-search-campaign",
|
|
21348
|
-
communication_job_id: null,
|
|
21349
|
-
status: "paid",
|
|
21350
|
-
amount: "1145.10",
|
|
21351
|
-
currency: "USD",
|
|
21352
|
-
created_date: "2025-04-03T19:16:40.000Z",
|
|
21353
|
-
paid_date: "2025-04-03T19:16:40.000Z",
|
|
21354
|
-
due_date: "2025-04-05T00:00:00.000Z",
|
|
21355
|
-
deleted_at: null,
|
|
21356
|
-
metadata: {
|
|
21357
|
-
source_info: {
|
|
21358
|
-
referrer: "https://www.googleadservices.com/",
|
|
21359
|
-
utm_medium: "shopping",
|
|
21360
|
-
utm_source: "google",
|
|
21361
|
-
ad_platform: "google",
|
|
21362
|
-
campaign_id: "sandbox-google-search-campaign",
|
|
21363
|
-
source_type: "paid",
|
|
21364
|
-
utm_campaign: "Sandbox Google Campaign Gamma",
|
|
21365
|
-
ad_account_id: "sandbox-g-customer-123",
|
|
21366
|
-
primary_source: "Google Ads",
|
|
21367
|
-
referrer_domain: "googleadservices.com",
|
|
21368
|
-
landing_page_url: "https://example.com/landing_page_google_2",
|
|
21369
|
-
campaign_name: "Sandbox Google Campaign Gamma"
|
|
21370
|
-
}
|
|
21371
|
-
},
|
|
21372
|
-
user_name: "Michael Scott",
|
|
21373
|
-
user_email: "michael.scott@example.com",
|
|
21374
|
-
user_external_id: "fake-user-ext-013",
|
|
21375
|
-
source_info: {
|
|
21376
|
-
referrer: "https://www.googleadservices.com/",
|
|
21377
|
-
utm_medium: "shopping",
|
|
21378
|
-
utm_source: "google",
|
|
21379
|
-
ad_platform: "google",
|
|
21380
|
-
campaign_id: "sandbox-google-search-campaign",
|
|
21381
|
-
source_type: "paid",
|
|
21382
|
-
utm_campaign: "Sandbox Google Campaign Gamma",
|
|
21383
|
-
ad_account_id: "sandbox-g-customer-123",
|
|
21384
|
-
primary_source: "Google Ads",
|
|
21385
|
-
referrer_domain: "googleadservices.com",
|
|
21386
|
-
landing_page_url: "https://example.com/landing_page_google_2",
|
|
21387
|
-
campaign_name: "Sandbox Google Campaign Gamma"
|
|
21388
|
-
}
|
|
21389
|
-
},
|
|
21390
|
-
{
|
|
21391
|
-
id: "019615dc-9ed4-7425-82b5-9ff29bbb2cd6",
|
|
21392
|
-
created_at: "2025-04-08T14:44:05.572Z",
|
|
21393
|
-
updated_at: "2025-04-08T14:45:02.378Z",
|
|
21394
|
-
platform_id: "01958180-06a0-7681-8064-6834e166d2e4",
|
|
21395
|
-
business_id: sandboxBusinessId,
|
|
21396
|
-
partner_user_id: "fake-partner-user-014",
|
|
21397
|
-
external_id: "cm91sop83014id7tkr8pgn819",
|
|
21398
|
-
campaign_id: null,
|
|
21399
|
-
communication_job_id: null,
|
|
21400
|
-
status: "paid",
|
|
21401
|
-
amount: "1000.00",
|
|
21402
|
-
currency: "USD",
|
|
21403
|
-
created_date: "2025-04-03T19:14:58.000Z",
|
|
21404
|
-
paid_date: "2025-04-03T19:14:58.000Z",
|
|
21405
|
-
due_date: "2025-04-29T00:00:00.000Z",
|
|
21406
|
-
deleted_at: null,
|
|
21407
|
-
metadata: {
|
|
21408
|
-
source_info: {
|
|
21409
|
-
source_type: "organic_search",
|
|
21410
|
-
primary_source: "Yahoo Organic"
|
|
21411
|
-
}
|
|
21412
|
-
},
|
|
21413
|
-
user_name: "Nancy Drew",
|
|
21414
|
-
user_email: "nancy.drew@example.com",
|
|
21415
|
-
user_external_id: "fake-user-ext-014",
|
|
21416
|
-
source_info: {
|
|
21417
|
-
source_type: "organic_search",
|
|
21418
|
-
primary_source: "Yahoo Organic"
|
|
21419
|
-
}
|
|
21420
|
-
},
|
|
21421
|
-
{
|
|
21422
|
-
id: "019615dc-9ee3-799a-991d-5972345c3753",
|
|
21423
|
-
created_at: "2025-04-08T14:44:05.577Z",
|
|
21424
|
-
updated_at: "2025-04-08T14:45:02.386Z",
|
|
21425
|
-
platform_id: "01958180-06a0-7681-8064-6834e166d2e4",
|
|
21426
|
-
business_id: sandboxBusinessId,
|
|
21427
|
-
partner_user_id: "fake-partner-user-015",
|
|
21428
|
-
external_id: "cm91sl6pj015xla1e1meqefwv",
|
|
21429
|
-
campaign_id: "sandbox-google-campaign-1",
|
|
21430
|
-
communication_job_id: null,
|
|
21431
|
-
status: "paid",
|
|
21432
|
-
amount: "1160.25",
|
|
21433
|
-
currency: "USD",
|
|
21434
|
-
created_date: "2025-04-03T19:12:15.000Z",
|
|
21435
|
-
paid_date: "2025-04-03T19:12:15.000Z",
|
|
21436
|
-
due_date: "2025-04-21T00:00:00.000Z",
|
|
21437
|
-
deleted_at: null,
|
|
21438
|
-
metadata: {
|
|
21439
|
-
source_info: {
|
|
21440
|
-
source_type: "referral",
|
|
21441
|
-
primary_source: "duckduckgo.com"
|
|
21442
|
-
}
|
|
21443
|
-
},
|
|
21444
|
-
user_name: "Olivia Benson",
|
|
21445
|
-
user_email: "olivia.benson@example.com",
|
|
21446
|
-
user_external_id: "fake-user-ext-015",
|
|
21447
|
-
source_info: {
|
|
21448
|
-
source_type: "referral",
|
|
21449
|
-
primary_source: "duckduckgo.com"
|
|
21450
|
-
}
|
|
21451
|
-
},
|
|
21452
|
-
{
|
|
21453
|
-
id: "019615dc-9ed1-770b-9c9c-7788267d8ef5",
|
|
21454
|
-
created_at: "2025-04-08T14:44:05.584Z",
|
|
21455
|
-
updated_at: "2025-04-08T14:45:02.378Z",
|
|
21456
|
-
platform_id: "01958180-06a0-7681-8064-6834e166d2e4",
|
|
21457
|
-
business_id: sandboxBusinessId,
|
|
21458
|
-
partner_user_id: "fake-partner-user-016",
|
|
21459
|
-
external_id: "cm91sig2r0129105k11lt7v7c",
|
|
21460
|
-
campaign_id: "sandbox-google-search-campaign",
|
|
21461
|
-
communication_job_id: null,
|
|
21462
|
-
status: "paid",
|
|
21463
|
-
amount: "347.99",
|
|
21464
|
-
currency: "USD",
|
|
21465
|
-
created_date: "2025-04-03T19:10:07.000Z",
|
|
21466
|
-
paid_date: "2025-04-03T19:10:07.000Z",
|
|
21467
|
-
due_date: "2025-04-05T00:00:00.000Z",
|
|
21468
|
-
deleted_at: null,
|
|
21469
|
-
metadata: {
|
|
21470
|
-
source_info: {
|
|
21471
|
-
referrer: "https://www.google.com/",
|
|
21472
|
-
utm_medium: "pmax",
|
|
21473
|
-
utm_source: "google",
|
|
21474
|
-
ad_platform: "google",
|
|
21475
|
-
campaign_id: "sandbox-google-search-campaign",
|
|
21476
|
-
source_type: "paid",
|
|
21477
|
-
utm_campaign: "Sandbox Google Campaign Gamma",
|
|
21478
|
-
ad_account_id: "sandbox-g-customer-123",
|
|
21479
|
-
primary_source: "Google Ads",
|
|
21480
|
-
referrer_domain: "google.com",
|
|
21481
|
-
landing_page_url: "https://example.com/landing_page_google_2",
|
|
21482
|
-
campaign_name: "Sandbox Google Campaign Gamma"
|
|
21483
|
-
}
|
|
21484
|
-
},
|
|
21485
|
-
user_name: "Peter Parker",
|
|
21486
|
-
user_email: "peter.parker@example.com",
|
|
21487
|
-
user_external_id: "fake-user-ext-016",
|
|
21488
|
-
source_info: {
|
|
21489
|
-
referrer: "https://www.google.com/",
|
|
21490
|
-
utm_medium: "pmax",
|
|
21491
|
-
utm_source: "google",
|
|
21492
|
-
ad_platform: "google",
|
|
21493
|
-
campaign_id: "sandbox-google-search-campaign",
|
|
21494
|
-
source_type: "paid",
|
|
21495
|
-
utm_campaign: "Sandbox Google Campaign Gamma",
|
|
21496
|
-
ad_account_id: "sandbox-g-customer-123",
|
|
21497
|
-
primary_source: "Google Ads",
|
|
21498
|
-
referrer_domain: "google.com",
|
|
21499
|
-
landing_page_url: "https://example.com/landing_page_google_2",
|
|
21500
|
-
campaign_name: "Sandbox Google Campaign Gamma"
|
|
21501
|
-
}
|
|
21502
|
-
},
|
|
21503
|
-
{
|
|
21504
|
-
id: "019615dc-9f1e-7ae2-a2ba-33db28d91f6f",
|
|
21505
|
-
created_at: "2025-04-08T14:44:05.603Z",
|
|
21506
|
-
updated_at: "2025-04-08T14:45:02.447Z",
|
|
21507
|
-
platform_id: "01958180-06a0-7681-8064-6834e166d2e4",
|
|
21508
|
-
business_id: sandboxBusinessId,
|
|
21509
|
-
partner_user_id: "fake-partner-user-017",
|
|
21510
|
-
external_id: "cm91qi3mp00jua87ecc0i6zl6",
|
|
21511
|
-
campaign_id: null,
|
|
21512
|
-
communication_job_id: null,
|
|
21513
|
-
status: "paid",
|
|
21514
|
-
amount: "783.70",
|
|
21515
|
-
currency: "USD",
|
|
21516
|
-
created_date: "2025-04-03T18:13:51.000Z",
|
|
21517
|
-
paid_date: "2025-04-03T18:13:51.000Z",
|
|
21518
|
-
due_date: "2025-04-12T00:00:00.000Z",
|
|
21519
|
-
deleted_at: null,
|
|
21520
|
-
metadata: null,
|
|
21521
|
-
user_name: "Quentin Tarantino",
|
|
21522
|
-
user_email: "quentin.tarantino@example.com",
|
|
21523
|
-
user_external_id: "fake-user-ext-017"
|
|
21524
|
-
},
|
|
21525
|
-
{
|
|
21526
|
-
id: "019615dc-9ef1-741a-b31f-b74d490ddf8d",
|
|
21527
|
-
created_at: "2025-04-08T14:44:05.590Z",
|
|
21528
|
-
updated_at: "2025-04-08T14:45:02.404Z",
|
|
21529
|
-
platform_id: "01958180-06a0-7681-8064-6834e166d2e4",
|
|
21530
|
-
business_id: sandboxBusinessId,
|
|
21531
|
-
partner_user_id: "fake-partner-user-018",
|
|
21532
|
-
external_id: "cm91qfg2c00n1la1ecymxvki2",
|
|
21533
|
-
campaign_id: null,
|
|
21534
|
-
communication_job_id: null,
|
|
21535
|
-
status: "paid",
|
|
21536
|
-
amount: "1175.50",
|
|
21537
|
-
currency: "USD",
|
|
21538
|
-
created_date: "2025-04-03T18:11:47.000Z",
|
|
21539
|
-
paid_date: "2025-04-03T18:11:47.000Z",
|
|
21540
|
-
due_date: "2025-05-27T00:00:00.000Z",
|
|
21541
|
-
deleted_at: null,
|
|
21542
|
-
metadata: {
|
|
21543
|
-
source_info: {
|
|
21544
|
-
source_type: "direct",
|
|
21545
|
-
primary_source: "direct"
|
|
21546
|
-
}
|
|
21547
|
-
},
|
|
21548
|
-
source_info: {
|
|
21549
|
-
source_type: "direct",
|
|
21550
|
-
primary_source: "direct"
|
|
21551
|
-
},
|
|
21552
|
-
user_name: "Rachel Green",
|
|
21553
|
-
user_email: "rachel.green@example.com",
|
|
21554
|
-
user_external_id: "fake-user-ext-018"
|
|
21555
|
-
},
|
|
21556
|
-
{
|
|
21557
|
-
id: "019615dc-9ee0-7178-8f5f-09a8ca30f677",
|
|
21558
|
-
created_at: "2025-04-08T14:44:05.702Z",
|
|
21559
|
-
updated_at: "2025-04-08T14:45:02.384Z",
|
|
21560
|
-
platform_id: "01958180-06a0-7681-8064-6834e166d2e4",
|
|
21561
|
-
business_id: sandboxBusinessId,
|
|
21562
|
-
partner_user_id: "fake-partner-user-019",
|
|
21563
|
-
external_id: "cm91q0vw600jn105k0g764c1c",
|
|
21564
|
-
campaign_id: null,
|
|
21565
|
-
communication_job_id: null,
|
|
21566
|
-
status: "paid",
|
|
21567
|
-
amount: "1147.20",
|
|
21568
|
-
currency: "USD",
|
|
21569
|
-
created_date: "2025-04-03T18:00:28.000Z",
|
|
21570
|
-
paid_date: "2025-04-03T18:00:28.000Z",
|
|
21571
|
-
due_date: "2025-04-05T00:00:00.000Z",
|
|
21572
|
-
deleted_at: null,
|
|
21573
|
-
metadata: {
|
|
21574
|
-
source_info: {
|
|
21575
|
-
referrer: "https://www.google.com/",
|
|
21576
|
-
utm_medium: "organic",
|
|
21577
|
-
utm_source: "google",
|
|
21578
|
-
source_type: "organic_search",
|
|
21579
|
-
primary_source: "Google Organic Search",
|
|
21580
|
-
referrer_domain: "google.com",
|
|
21581
|
-
landing_page_url: "https://example.com/organic_search_result"
|
|
21582
|
-
}
|
|
21583
|
-
},
|
|
21584
|
-
source_info: {
|
|
21585
|
-
referrer: "https://www.google.com/",
|
|
21586
|
-
utm_medium: "organic",
|
|
21587
|
-
utm_source: "google",
|
|
21588
|
-
source_type: "organic_search",
|
|
21589
|
-
primary_source: "Google Organic Search",
|
|
21590
|
-
referrer_domain: "google.com",
|
|
21591
|
-
landing_page_url: "https://example.com/organic_search_result"
|
|
21592
|
-
},
|
|
21593
|
-
user_name: "Steve Rogers",
|
|
21594
|
-
user_email: "steve.rogers@example.com",
|
|
21595
|
-
user_external_id: "fake-user-ext-019"
|
|
21596
|
-
},
|
|
21597
|
-
{
|
|
21598
|
-
id: "019615dc-9ef4-7ad5-b5b4-eaa3d4e36e15",
|
|
21599
|
-
created_at: "2025-04-08T14:44:05.607Z",
|
|
21600
|
-
updated_at: "2025-04-08T14:45:02.412Z",
|
|
21601
|
-
platform_id: "01958180-06a0-7681-8064-6834e166d2e4",
|
|
21602
|
-
business_id: sandboxBusinessId,
|
|
21603
|
-
partner_user_id: "fake-partner-user-020",
|
|
21604
|
-
external_id: "cm91p0j5300bvtufrs8gv23ow",
|
|
21605
|
-
campaign_id: "sandbox-google-campaign-1",
|
|
21606
|
-
communication_job_id: null,
|
|
21607
|
-
status: "paid",
|
|
21608
|
-
amount: "290.99",
|
|
21609
|
-
currency: "USD",
|
|
21610
|
-
created_date: "2025-04-03T17:32:12.000Z",
|
|
21611
|
-
paid_date: "2025-04-03T17:32:12.000Z",
|
|
21612
|
-
due_date: "2025-05-23T00:00:00.000Z",
|
|
21613
|
-
deleted_at: null,
|
|
21614
|
-
metadata: {
|
|
21615
|
-
source_info: {
|
|
21616
|
-
source_type: "referral",
|
|
21617
|
-
primary_source: "duckduckgo.com"
|
|
21618
|
-
}
|
|
21619
|
-
},
|
|
21620
|
-
source_info: {
|
|
21621
|
-
source_type: "referral",
|
|
21622
|
-
primary_source: "duckduckgo.com"
|
|
21623
|
-
},
|
|
21624
|
-
user_name: "Tony Stark",
|
|
21625
|
-
user_email: "tony.stark@example.com",
|
|
21626
|
-
user_external_id: "fake-user-ext-020"
|
|
21627
|
-
},
|
|
21628
|
-
{
|
|
21629
|
-
id: "019615dc-9ef3-79b9-996e-883fcb18a0ff",
|
|
21630
|
-
created_at: "2025-04-08T14:45:01.717Z",
|
|
21631
|
-
updated_at: "2025-04-08T14:45:02.410Z",
|
|
21632
|
-
platform_id: "01958180-06a0-7681-8064-6834e166d2e4",
|
|
21633
|
-
business_id: sandboxBusinessId,
|
|
21634
|
-
partner_user_id: "fake-partner-user-021",
|
|
21635
|
-
external_id: "cm91oyf9k00bc2lig6ocxbjyi",
|
|
21636
|
-
campaign_id: null,
|
|
21637
|
-
communication_job_id: null,
|
|
21638
|
-
status: "paid",
|
|
21639
|
-
amount: "1188.00",
|
|
21640
|
-
currency: "USD",
|
|
21641
|
-
created_date: "2025-04-03T17:30:34.000Z",
|
|
21642
|
-
paid_date: "2025-04-03T17:30:34.000Z",
|
|
21643
|
-
due_date: "2025-05-16T00:00:00.000Z",
|
|
21644
|
-
deleted_at: null,
|
|
21645
|
-
metadata: null,
|
|
21646
|
-
user_name: "Ursula Buffay",
|
|
21647
|
-
user_email: "ursula.buffay@example.com",
|
|
21648
|
-
user_external_id: "fake-user-ext-021"
|
|
21649
|
-
},
|
|
21650
|
-
{
|
|
21651
|
-
id: "019615dc-9ef0-71cb-a0f8-fa675bdd2016",
|
|
21652
|
-
created_at: "2025-04-08T14:45:01.721Z",
|
|
21653
|
-
updated_at: "2025-04-08T14:45:02.398Z",
|
|
21654
|
-
platform_id: "01958180-06a0-7681-8064-6834e166d2e4",
|
|
21655
|
-
business_id: sandboxBusinessId,
|
|
21656
|
-
partner_user_id: "fake-partner-user-022",
|
|
21657
|
-
external_id: "cm91ogu8d00872lig9r0xtr9n",
|
|
21658
|
-
campaign_id: "sandbox-google-campaign-1",
|
|
21659
|
-
communication_job_id: null,
|
|
21660
|
-
status: "paid",
|
|
21661
|
-
amount: "826.50",
|
|
21662
|
-
currency: "USD",
|
|
21663
|
-
created_date: "2025-04-03T17:16:53.000Z",
|
|
21664
|
-
paid_date: "2025-04-03T17:16:53.000Z",
|
|
21665
|
-
due_date: "2025-04-22T00:00:00.000Z",
|
|
21666
|
-
deleted_at: null,
|
|
21667
|
-
metadata: {
|
|
21668
|
-
source_info: {
|
|
21669
|
-
referrer: "https://google.com/shopping",
|
|
21670
|
-
utm_medium: "pla",
|
|
21671
|
-
utm_source: "google",
|
|
21672
|
-
ad_platform: "google",
|
|
21673
|
-
campaign_id: "sandbox-google-search-campaign",
|
|
21674
|
-
source_type: "paid",
|
|
21675
|
-
utm_campaign: "Sandbox Google Search Campaign",
|
|
21676
|
-
ad_account_id: "sandbox-g-customer-123",
|
|
21677
|
-
primary_source: "Google Ads",
|
|
21678
|
-
referrer_domain: "google.com",
|
|
21679
|
-
landing_page_url: "https://example.com/landing_page_google_1",
|
|
21680
|
-
campaign_name: "Sandbox Google Search Campaign"
|
|
21681
|
-
}
|
|
21682
|
-
},
|
|
21683
|
-
user_name: "Victor VonDoom",
|
|
21684
|
-
user_email: "victor.vondoom@example.com",
|
|
21685
|
-
user_external_id: "fake-user-ext-022",
|
|
21686
|
-
source_info: {
|
|
21687
|
-
source_type: "referral",
|
|
21688
|
-
primary_source: "android-app:"
|
|
21689
|
-
}
|
|
20688
|
+
renterra: {
|
|
20689
|
+
id: "renterra",
|
|
20690
|
+
name: "Tomers Rentals",
|
|
20691
|
+
brandColors: ["#1e40af", "#059669", "#dc2626", "#7c2d12"],
|
|
20692
|
+
locationNames: [
|
|
20693
|
+
"Austin Branch",
|
|
20694
|
+
"Acorn Park Branch",
|
|
20695
|
+
"Michigan Branch",
|
|
20696
|
+
"Tampa Branch",
|
|
20697
|
+
"Warren Branch"
|
|
20698
|
+
],
|
|
20699
|
+
locationAreas: [
|
|
20700
|
+
"Austin, TX",
|
|
20701
|
+
"Chicago, IL",
|
|
20702
|
+
"Three Oaks, MI",
|
|
20703
|
+
"Tampa, FL",
|
|
20704
|
+
"Evanston, IL"
|
|
20705
|
+
]
|
|
20706
|
+
}
|
|
20707
|
+
};
|
|
20708
|
+
const getPlatformConfig = (platformId) => {
|
|
20709
|
+
const configKey = getPlatformConfigKey(platformId);
|
|
20710
|
+
return defaultPlatformConfigs[configKey];
|
|
20711
|
+
};
|
|
20712
|
+
const createGbpConnectionFactory = (platformConfig, businessId, status = "connected") => {
|
|
20713
|
+
const accountName = `${platformConfig.name} GBP Account`;
|
|
20714
|
+
const locations = Array.from(
|
|
20715
|
+
{ length: Math.min(platformConfig.locationNames.length, 4) },
|
|
20716
|
+
(_2, index) => ({
|
|
20717
|
+
name: `accounts/123456789/locations/${2e3 + index}`,
|
|
20718
|
+
title: platformConfig.locationNames[index],
|
|
20719
|
+
address: platformConfig.locationAreas[index] || platformConfig.locationAreas[0],
|
|
20720
|
+
phone: f.phone.number(),
|
|
20721
|
+
locationState: f.helpers.arrayElement([
|
|
20722
|
+
"VERIFIED",
|
|
20723
|
+
"PUBLISHED",
|
|
20724
|
+
"PENDING"
|
|
20725
|
+
])
|
|
20726
|
+
})
|
|
20727
|
+
);
|
|
20728
|
+
return {
|
|
20729
|
+
id: f.string.uuid(),
|
|
20730
|
+
business_id: businessId,
|
|
20731
|
+
provider: "gbp",
|
|
20732
|
+
status,
|
|
20733
|
+
metadata: {
|
|
20734
|
+
platform: "gbp",
|
|
20735
|
+
selectedAccount: {
|
|
20736
|
+
name: "accounts/123456789",
|
|
20737
|
+
accountName,
|
|
20738
|
+
permissionLevel: "OWNER_LEVEL",
|
|
20739
|
+
verificationState: "VERIFIED",
|
|
20740
|
+
locationCount: locations.length
|
|
21690
20741
|
},
|
|
21691
|
-
|
|
21692
|
-
|
|
21693
|
-
|
|
21694
|
-
|
|
21695
|
-
|
|
21696
|
-
|
|
21697
|
-
|
|
21698
|
-
|
|
21699
|
-
|
|
21700
|
-
|
|
21701
|
-
|
|
21702
|
-
|
|
21703
|
-
|
|
21704
|
-
|
|
21705
|
-
|
|
21706
|
-
|
|
21707
|
-
|
|
21708
|
-
|
|
21709
|
-
|
|
21710
|
-
|
|
21711
|
-
|
|
20742
|
+
selectedLocations: locations
|
|
20743
|
+
},
|
|
20744
|
+
created_at: f.date.past().toISOString(),
|
|
20745
|
+
updated_at: f.date.recent().toISOString()
|
|
20746
|
+
};
|
|
20747
|
+
};
|
|
20748
|
+
const createPartnerLocationsFactory = (platformConfig, businessId, platformId, count = 3) => {
|
|
20749
|
+
return Array.from({ length: count }, (_2, index) => ({
|
|
20750
|
+
id: f.string.uuid(),
|
|
20751
|
+
externalId: `partner-loc-${index}`,
|
|
20752
|
+
name: platformConfig.locationNames[index],
|
|
20753
|
+
addressLine1: f.location.streetAddress(),
|
|
20754
|
+
addressLine2: null,
|
|
20755
|
+
addressLine3: null,
|
|
20756
|
+
locality: platformConfig.locationAreas[index]?.split(",")[0] || f.location.city(),
|
|
20757
|
+
district: platformConfig.locationAreas[index]?.split(",")[1]?.trim() || f.location.state({ abbreviated: true }),
|
|
20758
|
+
postalCode: f.location.zipCode(),
|
|
20759
|
+
countryCode: "US",
|
|
20760
|
+
phone: f.phone.number(),
|
|
20761
|
+
email: f.internet.email(),
|
|
20762
|
+
website: `https://${platformConfig.name.toLowerCase().replace(/\s+/g, "-")}.com`,
|
|
20763
|
+
businessId,
|
|
20764
|
+
platformId,
|
|
20765
|
+
createdAt: f.date.past(),
|
|
20766
|
+
updatedAt: f.date.recent(),
|
|
20767
|
+
deletedAt: null
|
|
20768
|
+
}));
|
|
20769
|
+
};
|
|
20770
|
+
const createChannelDataFactory = (platformConfig) => {
|
|
20771
|
+
const domain = platformConfig.name.toLowerCase().replace(/\s+/g, "-") + ".com";
|
|
20772
|
+
const emailAccountId = f.string.uuid();
|
|
20773
|
+
const smsAccountId = f.string.uuid();
|
|
20774
|
+
const channelAccounts = [
|
|
20775
|
+
// Email account
|
|
20776
|
+
{
|
|
20777
|
+
id: emailAccountId,
|
|
20778
|
+
channelIntegrationId: f.string.uuid(),
|
|
20779
|
+
channelAccountMetadata: {
|
|
20780
|
+
type: ChannelAccountTypeEnum.REACH_MANAGED_SES,
|
|
20781
|
+
baseDomain: domain,
|
|
20782
|
+
dkimVerified: true,
|
|
20783
|
+
verifiedReturnPath: true
|
|
20784
|
+
}
|
|
20785
|
+
},
|
|
20786
|
+
// SMS account
|
|
20787
|
+
{
|
|
20788
|
+
id: smsAccountId,
|
|
20789
|
+
channelIntegrationId: f.string.uuid(),
|
|
20790
|
+
channelAccountMetadata: {
|
|
20791
|
+
type: ChannelAccountTypeEnum.TWILLIO,
|
|
20792
|
+
smsApplicationReferenceId: `AP${f.string.alphanumeric(32)}`
|
|
21712
20793
|
}
|
|
21713
|
-
],
|
|
21714
|
-
pagination: {
|
|
21715
|
-
hasNextPage: false,
|
|
21716
|
-
cursor: null,
|
|
21717
|
-
total: 55
|
|
21718
20794
|
}
|
|
21719
|
-
|
|
21720
|
-
|
|
20795
|
+
];
|
|
20796
|
+
const channelSenders = [
|
|
20797
|
+
// Email sender (linked to email account)
|
|
21721
20798
|
{
|
|
21722
|
-
id:
|
|
21723
|
-
|
|
21724
|
-
|
|
21725
|
-
|
|
21726
|
-
|
|
21727
|
-
|
|
21728
|
-
|
|
21729
|
-
|
|
20799
|
+
id: f.string.uuid(),
|
|
20800
|
+
channelAccountId: emailAccountId,
|
|
20801
|
+
channelSenderMetadata: {
|
|
20802
|
+
userPart: "noreply",
|
|
20803
|
+
baseDomain: domain,
|
|
20804
|
+
emailFromName: platformConfig.name,
|
|
20805
|
+
emailReplyTo: `noreply@${domain}`,
|
|
20806
|
+
from: null,
|
|
20807
|
+
messageServiceSid: null,
|
|
20808
|
+
friendlyName: null
|
|
20809
|
+
}
|
|
21730
20810
|
},
|
|
20811
|
+
// SMS sender (linked to SMS account)
|
|
21731
20812
|
{
|
|
21732
|
-
id:
|
|
21733
|
-
|
|
21734
|
-
|
|
21735
|
-
|
|
21736
|
-
|
|
21737
|
-
|
|
21738
|
-
|
|
21739
|
-
|
|
20813
|
+
id: f.string.uuid(),
|
|
20814
|
+
channelAccountId: smsAccountId,
|
|
20815
|
+
channelSenderMetadata: {
|
|
20816
|
+
userPart: null,
|
|
20817
|
+
baseDomain: null,
|
|
20818
|
+
emailFromName: null,
|
|
20819
|
+
emailReplyTo: null,
|
|
20820
|
+
from: f.phone.number(),
|
|
20821
|
+
messageServiceSid: `MG${f.string.alphanumeric(32)}`,
|
|
20822
|
+
friendlyName: `${platformConfig.name} SMS`
|
|
20823
|
+
}
|
|
21740
20824
|
}
|
|
21741
|
-
]
|
|
21742
|
-
};
|
|
21743
|
-
if (defaultPlatformData.baseAggregatedMetrics) {
|
|
21744
|
-
defaultPlatformData.baseAggregatedMetrics.all.campaigns = [
|
|
21745
|
-
...defaultPlatformData.baseAggregatedMetrics.google.campaigns,
|
|
21746
|
-
...defaultPlatformData.baseAggregatedMetrics.meta.campaigns
|
|
21747
20825
|
];
|
|
21748
|
-
}
|
|
21749
|
-
|
|
21750
|
-
|
|
21751
|
-
|
|
21752
|
-
|
|
20826
|
+
return { channelSenders, channelAccounts };
|
|
20827
|
+
};
|
|
20828
|
+
const createReputationConfigFactory = (platformConfig, businessId, partnerLocations, gbpLocations) => {
|
|
20829
|
+
const locationMappings = {};
|
|
20830
|
+
const maxMappings = Math.min(partnerLocations.length, gbpLocations.length);
|
|
20831
|
+
for (let i2 = 0; i2 < maxMappings; i2++) {
|
|
20832
|
+
locationMappings[partnerLocations[i2].externalId] = gbpLocations[i2].name;
|
|
20833
|
+
}
|
|
20834
|
+
return {
|
|
20835
|
+
id: f.string.uuid(),
|
|
20836
|
+
businessId,
|
|
20837
|
+
locationMappings,
|
|
20838
|
+
emailChannelSenderId: null,
|
|
20839
|
+
// Will be set when user configures
|
|
20840
|
+
smsChannelSenderId: null,
|
|
20841
|
+
// Will be set when user configures
|
|
20842
|
+
createdAt: f.date.past().toISOString(),
|
|
20843
|
+
updatedAt: f.date.recent().toISOString(),
|
|
20844
|
+
completedOnboardingAt: void 0
|
|
20845
|
+
// Will be set when onboarding is completed
|
|
20846
|
+
};
|
|
20847
|
+
};
|
|
20848
|
+
const createSmsApplicationFactory = () => {
|
|
20849
|
+
return null;
|
|
20850
|
+
};
|
|
20851
|
+
const createSandboxReputationData = (platformId, businessId) => {
|
|
20852
|
+
const platformConfig = getPlatformConfig(platformId);
|
|
20853
|
+
const gbpConnection = createGbpConnectionFactory(platformConfig, businessId);
|
|
20854
|
+
const partnerLocations = createPartnerLocationsFactory(
|
|
20855
|
+
platformConfig,
|
|
20856
|
+
businessId,
|
|
20857
|
+
platformId || "default"
|
|
20858
|
+
);
|
|
20859
|
+
const { channelSenders, channelAccounts } = createChannelDataFactory(platformConfig);
|
|
20860
|
+
const smsApplication = createSmsApplicationFactory();
|
|
20861
|
+
const gbpLocations = gbpConnection?.metadata?.selectedLocations || [];
|
|
20862
|
+
const reputationConfig = createReputationConfigFactory(
|
|
20863
|
+
platformConfig,
|
|
20864
|
+
businessId,
|
|
20865
|
+
partnerLocations,
|
|
20866
|
+
gbpLocations
|
|
20867
|
+
);
|
|
20868
|
+
return {
|
|
20869
|
+
gbpConnection,
|
|
20870
|
+
partnerLocations,
|
|
20871
|
+
channelSenders,
|
|
20872
|
+
channelAccounts,
|
|
20873
|
+
reputationConfig,
|
|
20874
|
+
smsApplication
|
|
20875
|
+
};
|
|
20876
|
+
};
|
|
20877
|
+
f.seed(42);
|
|
20878
|
+
const businessConfigs = {
|
|
20879
|
+
default: {
|
|
20880
|
+
name: "Reach Sandbox",
|
|
20881
|
+
website: "https://sandbox.example.com",
|
|
20882
|
+
tagline: "Your sandbox environment for testing",
|
|
20883
|
+
locations: [
|
|
20884
|
+
{
|
|
20885
|
+
addressLine1: "123 Tech Street",
|
|
20886
|
+
addressLine2: "Suite 100",
|
|
20887
|
+
locality: "San Francisco",
|
|
20888
|
+
district: "CA",
|
|
20889
|
+
postalCode: "94105",
|
|
20890
|
+
countryCode: "US"
|
|
20891
|
+
}
|
|
20892
|
+
],
|
|
20893
|
+
branding: {
|
|
20894
|
+
brandName: "Reach Sandbox",
|
|
20895
|
+
primaryColor: "#2563eb",
|
|
20896
|
+
secondaryColors: ["#059669", "#dc2626", "#9333ea"],
|
|
20897
|
+
brandTagline: "Your sandbox environment for testing",
|
|
20898
|
+
brandPersonality: {
|
|
20899
|
+
tone: "professional",
|
|
20900
|
+
voice: "friendly",
|
|
20901
|
+
values: ["innovation", "reliability", "growth"]
|
|
20902
|
+
},
|
|
20903
|
+
colorPalette: {
|
|
20904
|
+
primary: "#2563eb",
|
|
20905
|
+
accent: ["#059669", "#dc2626", "#9333ea"],
|
|
20906
|
+
background: ["#ffffff", "#f8fafc", "#f1f5f9"],
|
|
20907
|
+
text: ["#1e293b", "#475569", "#64748b"]
|
|
20908
|
+
}
|
|
20909
|
+
}
|
|
20910
|
+
},
|
|
20911
|
+
goose: {
|
|
21753
20912
|
name: "Paws Pet Hotel (Sandbox)",
|
|
21754
20913
|
website: "https://www.pawspethotel.com/",
|
|
20914
|
+
tagline: "Where happy tails wag all day!",
|
|
21755
20915
|
locations: [
|
|
21756
20916
|
{
|
|
21757
|
-
district: "ny",
|
|
21758
|
-
locality: "new york",
|
|
21759
|
-
postalCode: "10018",
|
|
21760
|
-
countryCode: "US",
|
|
21761
20917
|
addressLine1: "530 7th avenue",
|
|
21762
20918
|
addressLine2: "",
|
|
21763
|
-
|
|
20919
|
+
locality: "new york",
|
|
20920
|
+
district: "ny",
|
|
20921
|
+
postalCode: "10018",
|
|
20922
|
+
countryCode: "US"
|
|
21764
20923
|
}
|
|
21765
|
-
]
|
|
20924
|
+
],
|
|
20925
|
+
branding: {
|
|
20926
|
+
brandName: "Paws Pet Hotel",
|
|
20927
|
+
primaryColor: "#f59e0b",
|
|
20928
|
+
secondaryColors: ["#dc2626", "#059669", "#7c3aed"],
|
|
20929
|
+
brandTagline: "Where happy tails wag all day!",
|
|
20930
|
+
brandPersonality: {
|
|
20931
|
+
tone: "warm",
|
|
20932
|
+
voice: "caring",
|
|
20933
|
+
values: ["love", "safety", "fun"]
|
|
20934
|
+
},
|
|
20935
|
+
colorPalette: {
|
|
20936
|
+
primary: "#f59e0b",
|
|
20937
|
+
accent: ["#dc2626", "#059669", "#7c3aed"],
|
|
20938
|
+
background: ["#fef3c7", "#fef2f2", "#f0fdf4"],
|
|
20939
|
+
text: ["#92400e", "#991b1b", "#166534"]
|
|
20940
|
+
}
|
|
20941
|
+
}
|
|
21766
20942
|
},
|
|
21767
|
-
|
|
21768
|
-
|
|
21769
|
-
|
|
20943
|
+
renterra: {
|
|
20944
|
+
name: "Tomer's Rental",
|
|
20945
|
+
website: "https://tomersrental.com/",
|
|
20946
|
+
tagline: "Professional equipment rental solutions",
|
|
20947
|
+
locations: [
|
|
21770
20948
|
{
|
|
21771
|
-
|
|
20949
|
+
addressLine1: "1605 w 1450 s",
|
|
20950
|
+
addressLine2: "",
|
|
20951
|
+
locality: "springville",
|
|
20952
|
+
district: "ut",
|
|
20953
|
+
postalCode: "84663",
|
|
20954
|
+
countryCode: "US"
|
|
20955
|
+
}
|
|
20956
|
+
],
|
|
20957
|
+
branding: {
|
|
20958
|
+
brandName: "Tomer's Rental",
|
|
20959
|
+
primaryColor: "#1e40af",
|
|
20960
|
+
secondaryColors: ["#059669", "#dc2626", "#7c2d12"],
|
|
20961
|
+
brandTagline: "Professional equipment rental solutions",
|
|
20962
|
+
brandPersonality: {
|
|
20963
|
+
tone: "professional",
|
|
20964
|
+
voice: "reliable",
|
|
20965
|
+
values: ["quality", "trust", "efficiency"]
|
|
20966
|
+
},
|
|
20967
|
+
colorPalette: {
|
|
20968
|
+
primary: "#1e40af",
|
|
20969
|
+
accent: ["#059669", "#dc2626", "#7c2d12"],
|
|
20970
|
+
background: ["#dbeafe", "#f0fdf4", "#fef2f2"],
|
|
20971
|
+
text: ["#1e3a8a", "#166534", "#991b1b"]
|
|
20972
|
+
}
|
|
20973
|
+
}
|
|
20974
|
+
}
|
|
20975
|
+
};
|
|
20976
|
+
const getBusinessConfig = (platformId) => {
|
|
20977
|
+
const configKey = getPlatformConfigKey(platformId);
|
|
20978
|
+
return businessConfigs[configKey];
|
|
20979
|
+
};
|
|
20980
|
+
const createBusinessDataFactory = (platformConfig, businessId, platformId) => {
|
|
20981
|
+
const businessConfig = getBusinessConfig(platformId);
|
|
20982
|
+
const businessCreatedDate = (/* @__PURE__ */ new Date(
|
|
20983
|
+
"2024-02-15T08:00:00.000Z"
|
|
20984
|
+
)).toISOString();
|
|
20985
|
+
const businessUpdatedDate = (/* @__PURE__ */ new Date(
|
|
20986
|
+
"2024-02-28T14:30:00.000Z"
|
|
20987
|
+
)).toISOString();
|
|
20988
|
+
return {
|
|
20989
|
+
id: businessId,
|
|
20990
|
+
hash: f.string.alphanumeric(11),
|
|
20991
|
+
name: businessConfig.name,
|
|
20992
|
+
external_id: `${f.string.numeric(9)}-sandbox`,
|
|
20993
|
+
platform_id: platformId,
|
|
20994
|
+
website: businessConfig.website,
|
|
20995
|
+
locations: businessConfig.locations,
|
|
20996
|
+
branding: businessConfig.branding,
|
|
20997
|
+
created_at: businessCreatedDate,
|
|
20998
|
+
updated_at: businessUpdatedDate,
|
|
20999
|
+
data_integration_completed_at: businessCreatedDate,
|
|
21000
|
+
website_tracking_completed_at: businessCreatedDate
|
|
21001
|
+
};
|
|
21002
|
+
};
|
|
21003
|
+
const createAdAccountFactory = (businessId, platform, businessConfig) => {
|
|
21004
|
+
const baseMetadata = {
|
|
21005
|
+
name: `${businessConfig.branding.brandName} ${platform === "google" ? "Google" : "Meta"} Ads`,
|
|
21006
|
+
platform,
|
|
21007
|
+
customer_id: platform === "google" ? `sandbox-g-customer-${f.string.numeric(3)}` : `sandbox-m-act-${f.string.numeric(3)}`,
|
|
21008
|
+
offline_conversions_enabled: true,
|
|
21009
|
+
tracking_parameters_enabled: platform === "google"
|
|
21010
|
+
};
|
|
21011
|
+
let metadata;
|
|
21012
|
+
if (platform === "google") {
|
|
21013
|
+
metadata = baseMetadata;
|
|
21014
|
+
} else {
|
|
21015
|
+
metadata = {
|
|
21016
|
+
...baseMetadata,
|
|
21017
|
+
pixel_id: `sandbox-meta-pixel-${f.string.numeric(3)}`
|
|
21018
|
+
};
|
|
21019
|
+
}
|
|
21020
|
+
return {
|
|
21021
|
+
id: `sandbox-${platform === "google" ? "g" : "m"}-ad-act-001`,
|
|
21022
|
+
business_id: businessId,
|
|
21023
|
+
ad_platform: platform,
|
|
21024
|
+
status: "connected",
|
|
21025
|
+
ad_platform_metadata: metadata,
|
|
21026
|
+
created_at: f.date.past({ years: 0.5 }).toISOString(),
|
|
21027
|
+
updated_at: f.date.recent().toISOString()
|
|
21028
|
+
};
|
|
21029
|
+
};
|
|
21030
|
+
const createCampaignMetricsFactory = (campaignId, campaignName, channel, businessId, baseMetrics) => {
|
|
21031
|
+
const roas = baseMetrics.spend > 0 ? baseMetrics.revenue / baseMetrics.spend : 0;
|
|
21032
|
+
const cpc = baseMetrics.clicks > 0 ? baseMetrics.spend / baseMetrics.clicks : 0;
|
|
21033
|
+
const ctr = baseMetrics.impressions > 0 ? baseMetrics.clicks / baseMetrics.impressions : 0;
|
|
21034
|
+
return {
|
|
21035
|
+
id: campaignId,
|
|
21036
|
+
name: campaignName,
|
|
21037
|
+
channel,
|
|
21038
|
+
business_id: businessId,
|
|
21039
|
+
ads_spend: baseMetrics.spend,
|
|
21040
|
+
clicks: baseMetrics.clicks,
|
|
21041
|
+
impressions: baseMetrics.impressions,
|
|
21042
|
+
measured_conversions: baseMetrics.conversions,
|
|
21043
|
+
measured_revenue: baseMetrics.revenue,
|
|
21044
|
+
new_leads: baseMetrics.leads,
|
|
21045
|
+
new_customers: baseMetrics.customers,
|
|
21046
|
+
customer_ltv: baseMetrics.ltv,
|
|
21047
|
+
roas,
|
|
21048
|
+
cost_per_click: cpc,
|
|
21049
|
+
click_through_rate: ctr,
|
|
21050
|
+
date_range: { start: "2024-01-01", end: "2024-01-30" },
|
|
21051
|
+
ad_platform_campaign_id: campaignId
|
|
21052
|
+
};
|
|
21053
|
+
};
|
|
21054
|
+
const createChannelMetricsFactory = (businessId, channel, campaigns) => {
|
|
21055
|
+
const totals = campaigns.reduce(
|
|
21056
|
+
(acc, campaign) => ({
|
|
21057
|
+
spend: acc.spend + campaign.ads_spend,
|
|
21058
|
+
revenue: acc.revenue + campaign.measured_revenue,
|
|
21059
|
+
clicks: acc.clicks + campaign.clicks,
|
|
21060
|
+
impressions: acc.impressions + campaign.impressions,
|
|
21061
|
+
conversions: acc.conversions + campaign.measured_conversions,
|
|
21062
|
+
leads: acc.leads + campaign.new_leads,
|
|
21063
|
+
customers: acc.customers + campaign.new_customers,
|
|
21064
|
+
ltv: acc.ltv + campaign.customer_ltv * campaign.new_customers
|
|
21065
|
+
}),
|
|
21066
|
+
{
|
|
21067
|
+
spend: 0,
|
|
21068
|
+
revenue: 0,
|
|
21069
|
+
clicks: 0,
|
|
21070
|
+
impressions: 0,
|
|
21071
|
+
conversions: 0,
|
|
21072
|
+
leads: 0,
|
|
21073
|
+
customers: 0,
|
|
21074
|
+
ltv: 0
|
|
21075
|
+
}
|
|
21076
|
+
);
|
|
21077
|
+
const avgLtv = totals.customers > 0 ? totals.ltv / totals.customers : 0;
|
|
21078
|
+
const roas = totals.spend > 0 ? totals.revenue / totals.spend : 0;
|
|
21079
|
+
const cpc = totals.clicks > 0 ? totals.spend / totals.clicks : 0;
|
|
21080
|
+
const ctr = totals.impressions > 0 ? totals.clicks / totals.impressions : 0;
|
|
21081
|
+
return {
|
|
21082
|
+
business_id: businessId,
|
|
21083
|
+
ads_spend: totals.spend,
|
|
21084
|
+
clicks: totals.clicks,
|
|
21085
|
+
impressions: totals.impressions,
|
|
21086
|
+
measured_conversions: totals.conversions,
|
|
21087
|
+
measured_revenue: totals.revenue,
|
|
21088
|
+
new_leads: totals.leads,
|
|
21089
|
+
new_customers: totals.customers,
|
|
21090
|
+
customer_ltv: avgLtv,
|
|
21091
|
+
roas,
|
|
21092
|
+
cost_per_click: cpc,
|
|
21093
|
+
click_through_rate: ctr,
|
|
21094
|
+
date_range: { start: "2024-01-01", end: "2024-01-30" },
|
|
21095
|
+
campaigns
|
|
21096
|
+
};
|
|
21097
|
+
};
|
|
21098
|
+
const createOrderSourceBreakdownFactory = (platformConfig) => {
|
|
21099
|
+
const baseBreakdown = [
|
|
21100
|
+
{
|
|
21101
|
+
primary_source: "unknown",
|
|
21102
|
+
source_type: "unknown",
|
|
21103
|
+
count: f.number.int({ min: 8, max: 15 }),
|
|
21104
|
+
amount: f.number.float({ min: 5e3, max: 1e4, fractionDigits: 2 })
|
|
21105
|
+
},
|
|
21106
|
+
{
|
|
21107
|
+
primary_source: "direct",
|
|
21108
|
+
source_type: "direct",
|
|
21109
|
+
count: f.number.int({ min: 10, max: 20 }),
|
|
21110
|
+
amount: f.number.float({ min: 8e3, max: 15e3, fractionDigits: 2 })
|
|
21111
|
+
},
|
|
21112
|
+
{
|
|
21113
|
+
primary_source: "Google Ads",
|
|
21114
|
+
source_type: "paid",
|
|
21115
|
+
count: f.number.int({ min: 40, max: 70 }),
|
|
21116
|
+
amount: f.number.float({ min: 1e4, max: 2e4, fractionDigits: 2 })
|
|
21117
|
+
},
|
|
21118
|
+
{
|
|
21119
|
+
primary_source: "Google Organic Search",
|
|
21120
|
+
source_type: "organic_search",
|
|
21121
|
+
count: f.number.int({ min: 15, max: 25 }),
|
|
21122
|
+
amount: f.number.float({ min: 2e3, max: 4e3, fractionDigits: 2 })
|
|
21123
|
+
},
|
|
21124
|
+
{
|
|
21125
|
+
primary_source: "Facebook Ads",
|
|
21126
|
+
source_type: "paid",
|
|
21127
|
+
count: f.number.int({ min: 2, max: 8 }),
|
|
21128
|
+
amount: f.number.float({ min: 3e3, max: 8e3, fractionDigits: 2 })
|
|
21129
|
+
},
|
|
21130
|
+
{
|
|
21131
|
+
primary_source: "Facebook Organic",
|
|
21132
|
+
source_type: "social",
|
|
21133
|
+
count: f.number.int({ min: 5, max: 12 }),
|
|
21134
|
+
amount: f.number.float({ min: 300, max: 800, fractionDigits: 2 })
|
|
21135
|
+
}
|
|
21136
|
+
];
|
|
21137
|
+
if (platformConfig.id === "goose") {
|
|
21138
|
+
baseBreakdown.push({
|
|
21139
|
+
primary_source: "Yelp Organic",
|
|
21140
|
+
source_type: "referral",
|
|
21141
|
+
count: f.number.int({ min: 3, max: 8 }),
|
|
21142
|
+
amount: f.number.float({ min: 500, max: 1200, fractionDigits: 2 })
|
|
21143
|
+
});
|
|
21144
|
+
} else if (platformConfig.id === "renterra") {
|
|
21145
|
+
baseBreakdown.push({
|
|
21146
|
+
primary_source: "Industry Directory",
|
|
21147
|
+
source_type: "referral",
|
|
21148
|
+
count: f.number.int({ min: 2, max: 6 }),
|
|
21149
|
+
amount: f.number.float({ min: 800, max: 2e3, fractionDigits: 2 })
|
|
21150
|
+
});
|
|
21151
|
+
}
|
|
21152
|
+
return baseBreakdown;
|
|
21153
|
+
};
|
|
21154
|
+
const createSampleOrdersFactory = (businessId, platformId, campaignIds, count = 25) => {
|
|
21155
|
+
const orders = [];
|
|
21156
|
+
const baseDate = /* @__PURE__ */ new Date("2024-02-01");
|
|
21157
|
+
for (let i2 = 0; i2 < count; i2++) {
|
|
21158
|
+
const orderDate = new Date(baseDate);
|
|
21159
|
+
const hoursOffset = i2 * 2 + f.number.int({ min: -3, max: 5 });
|
|
21160
|
+
const minutesOffset = f.number.int({ min: 0, max: 59 });
|
|
21161
|
+
orderDate.setHours(orderDate.getHours() + hoursOffset, minutesOffset);
|
|
21162
|
+
const hasCampaign = Math.random() > 0.3;
|
|
21163
|
+
const campaignId = hasCampaign ? f.helpers.arrayElement([...campaignIds, null]) : null;
|
|
21164
|
+
const sourceTypes = [
|
|
21165
|
+
"paid",
|
|
21166
|
+
"organic_search",
|
|
21167
|
+
"social",
|
|
21168
|
+
"direct",
|
|
21169
|
+
"referral"
|
|
21170
|
+
];
|
|
21171
|
+
const sourceType = campaignId ? "paid" : f.helpers.arrayElement(sourceTypes);
|
|
21172
|
+
let primarySource = "unknown";
|
|
21173
|
+
let adPlatform;
|
|
21174
|
+
let utmMedium;
|
|
21175
|
+
let utmSource;
|
|
21176
|
+
let referrer;
|
|
21177
|
+
if (sourceType === "paid") {
|
|
21178
|
+
if (campaignId?.includes("google")) {
|
|
21179
|
+
primarySource = "Google Ads";
|
|
21180
|
+
adPlatform = "google";
|
|
21181
|
+
utmMedium = f.helpers.arrayElement(["ppc", "cpc", "shopping"]);
|
|
21182
|
+
utmSource = "google";
|
|
21183
|
+
referrer = "https://www.google.com/";
|
|
21184
|
+
} else if (campaignId?.includes("meta")) {
|
|
21185
|
+
primarySource = "Facebook Ads";
|
|
21186
|
+
adPlatform = "meta";
|
|
21187
|
+
utmMedium = "cpc";
|
|
21188
|
+
utmSource = "facebook";
|
|
21189
|
+
referrer = "https://www.facebook.com/";
|
|
21190
|
+
}
|
|
21191
|
+
} else if (sourceType === "organic_search") {
|
|
21192
|
+
primarySource = f.helpers.arrayElement([
|
|
21193
|
+
"Google Organic Search",
|
|
21194
|
+
"Bing Organic",
|
|
21195
|
+
"Yahoo Organic"
|
|
21196
|
+
]);
|
|
21197
|
+
utmMedium = "organic";
|
|
21198
|
+
referrer = primarySource.includes("Google") ? "https://www.google.com/" : "https://www.bing.com/";
|
|
21199
|
+
} else if (sourceType === "social") {
|
|
21200
|
+
primarySource = "Facebook Organic";
|
|
21201
|
+
} else if (sourceType === "direct") {
|
|
21202
|
+
primarySource = "direct";
|
|
21203
|
+
}
|
|
21204
|
+
const order = {
|
|
21205
|
+
id: f.string.uuid(),
|
|
21206
|
+
created_at: orderDate.toISOString(),
|
|
21207
|
+
updated_at: new Date(orderDate.getTime() + 6e4).toISOString(),
|
|
21208
|
+
// 1 minute later
|
|
21209
|
+
platform_id: platformId,
|
|
21210
|
+
business_id: businessId,
|
|
21211
|
+
partner_user_id: `fake-partner-user-${f.string.alphanumeric(6)}`,
|
|
21212
|
+
external_id: f.string.alphanumeric(25),
|
|
21213
|
+
campaign_id: campaignId,
|
|
21214
|
+
communication_job_id: null,
|
|
21215
|
+
status: "paid",
|
|
21216
|
+
amount: f.number.float({
|
|
21217
|
+
min: 75 + i2 * 13 % 500,
|
|
21218
|
+
// Vary the minimum based on index
|
|
21219
|
+
max: 1200 + i2 * 47 % 800,
|
|
21220
|
+
// Vary the maximum based on index
|
|
21221
|
+
fractionDigits: 2
|
|
21222
|
+
}).toFixed(2),
|
|
21223
|
+
currency: "USD",
|
|
21224
|
+
created_date: orderDate.toISOString(),
|
|
21225
|
+
paid_date: orderDate.toISOString(),
|
|
21226
|
+
due_date: new Date(
|
|
21227
|
+
orderDate.getTime() + 7 * 24 * 60 * 60 * 1e3
|
|
21228
|
+
).toISOString(),
|
|
21229
|
+
// 7 days later
|
|
21230
|
+
deleted_at: null,
|
|
21231
|
+
metadata: sourceType !== "unknown" ? {
|
|
21232
|
+
source_info: {
|
|
21233
|
+
primary_source: primarySource,
|
|
21234
|
+
source_type: sourceType,
|
|
21235
|
+
ad_platform: adPlatform,
|
|
21236
|
+
utm_medium: utmMedium,
|
|
21237
|
+
utm_source: utmSource,
|
|
21238
|
+
referrer,
|
|
21239
|
+
campaign_id: campaignId || void 0,
|
|
21240
|
+
visit_date: new Date(
|
|
21241
|
+
orderDate.getTime() - f.number.int({ min: 0, max: 7 * 24 * 60 * 60 * 1e3 })
|
|
21242
|
+
).toISOString()
|
|
21243
|
+
}
|
|
21244
|
+
} : null,
|
|
21245
|
+
user_name: f.person.fullName(),
|
|
21246
|
+
user_email: f.internet.email(),
|
|
21247
|
+
user_external_id: `fake-user-ext-${f.string.alphanumeric(8)}`,
|
|
21248
|
+
source_info: sourceType !== "unknown" ? {
|
|
21249
|
+
primary_source: primarySource,
|
|
21250
|
+
source_type: sourceType,
|
|
21251
|
+
ad_platform: adPlatform,
|
|
21252
|
+
utm_medium: utmMedium,
|
|
21253
|
+
utm_source: utmSource,
|
|
21254
|
+
referrer,
|
|
21255
|
+
campaign_id: campaignId || void 0,
|
|
21256
|
+
visit_date: new Date(
|
|
21257
|
+
orderDate.getTime() - f.number.int({ min: 0, max: 7 * 24 * 60 * 60 * 1e3 })
|
|
21258
|
+
).toISOString()
|
|
21259
|
+
} : void 0
|
|
21260
|
+
};
|
|
21261
|
+
orders.push(order);
|
|
21262
|
+
}
|
|
21263
|
+
return orders;
|
|
21264
|
+
};
|
|
21265
|
+
const createWebPresenceContentFactory = (platformConfig, businessConfig) => {
|
|
21266
|
+
const baseAdGroups = [];
|
|
21267
|
+
if (platformConfig.id === "goose") {
|
|
21268
|
+
baseAdGroups.push(
|
|
21269
|
+
{
|
|
21270
|
+
ad: {
|
|
21772
21271
|
headlines: [
|
|
21773
21272
|
"Dog Daycare NYC",
|
|
21774
21273
|
"Safe Indoor & Outdoor Play",
|
|
@@ -21782,7 +21281,7 @@ const goosePlatformData = {
|
|
|
21782
21281
|
"Give your furry friend the care they deserve. Experienced staff, spacious facility & lots of fun. Book now!"
|
|
21783
21282
|
]
|
|
21784
21283
|
},
|
|
21785
|
-
adUrl:
|
|
21284
|
+
adUrl: `${businessConfig.website}daycare`,
|
|
21786
21285
|
theme: "Dog Daycare Services",
|
|
21787
21286
|
keywords: [
|
|
21788
21287
|
"new york dog daycare",
|
|
@@ -21792,31 +21291,6 @@ const goosePlatformData = {
|
|
|
21792
21291
|
"professional dog supervision"
|
|
21793
21292
|
]
|
|
21794
21293
|
},
|
|
21795
|
-
{
|
|
21796
|
-
ad: {
|
|
21797
|
-
headlines: [
|
|
21798
|
-
"Dog Boarding NYC",
|
|
21799
|
-
"Comfortable Overnight Care",
|
|
21800
|
-
"Reserve Your Dog's Stay",
|
|
21801
|
-
"24/7 Staff Supervision",
|
|
21802
|
-
"Feels Like Home For Dogs",
|
|
21803
|
-
"Peace Of Mind For Owners"
|
|
21804
|
-
],
|
|
21805
|
-
descriptions: [
|
|
21806
|
-
"Top-rated dog boarding in NYC. Safe, comfortable overnight care with 24/7 staff supervision.",
|
|
21807
|
-
"Your dog's home away from home. Loving environment, experienced care, and lots of playtime. Book now!"
|
|
21808
|
-
]
|
|
21809
|
-
},
|
|
21810
|
-
adUrl: "https://www.pawspethotel.com/services",
|
|
21811
|
-
theme: "Dog Boarding Services",
|
|
21812
|
-
keywords: [
|
|
21813
|
-
"new york dog boarding",
|
|
21814
|
-
"overnight dog care",
|
|
21815
|
-
"pet boarding near me",
|
|
21816
|
-
"safe dog lodging",
|
|
21817
|
-
"home away from home dogs"
|
|
21818
|
-
]
|
|
21819
|
-
},
|
|
21820
21294
|
{
|
|
21821
21295
|
ad: {
|
|
21822
21296
|
headlines: [
|
|
@@ -21832,7 +21306,7 @@ const goosePlatformData = {
|
|
|
21832
21306
|
"From baths to haircuts, we'll make your pup look and feel their best. Book your grooming appointment today!"
|
|
21833
21307
|
]
|
|
21834
21308
|
},
|
|
21835
|
-
adUrl:
|
|
21309
|
+
adUrl: `${businessConfig.website}grooming`,
|
|
21836
21310
|
theme: "Dog Grooming Services",
|
|
21837
21311
|
keywords: [
|
|
21838
21312
|
"new york dog grooming",
|
|
@@ -21842,82 +21316,9 @@ const goosePlatformData = {
|
|
|
21842
21316
|
"dog grooming near me"
|
|
21843
21317
|
]
|
|
21844
21318
|
}
|
|
21845
|
-
|
|
21846
|
-
}
|
|
21847
|
-
|
|
21848
|
-
adAccountsGoogle: {
|
|
21849
|
-
...defaultPlatformData.adAccountsGoogle,
|
|
21850
|
-
ad_platform_metadata: {
|
|
21851
|
-
...defaultPlatformData.adAccountsGoogle.ad_platform_metadata,
|
|
21852
|
-
name: "Paws Pet Hotel Google Ads"
|
|
21853
|
-
}
|
|
21854
|
-
},
|
|
21855
|
-
adAccountsMeta: {
|
|
21856
|
-
...defaultPlatformData.adAccountsMeta,
|
|
21857
|
-
ad_platform_metadata: {
|
|
21858
|
-
...defaultPlatformData.adAccountsMeta.ad_platform_metadata,
|
|
21859
|
-
name: "Paws Pet Hotel Meta Ads"
|
|
21860
|
-
}
|
|
21861
|
-
},
|
|
21862
|
-
// Initialize adAccounts array with both accounts
|
|
21863
|
-
adAccounts: [
|
|
21864
|
-
{
|
|
21865
|
-
...defaultPlatformData.adAccountsGoogle,
|
|
21866
|
-
ad_platform_metadata: {
|
|
21867
|
-
...defaultPlatformData.adAccountsGoogle.ad_platform_metadata,
|
|
21868
|
-
name: "Paws Pet Hotel Google Ads"
|
|
21869
|
-
}
|
|
21870
|
-
},
|
|
21871
|
-
{
|
|
21872
|
-
...defaultPlatformData.adAccountsMeta,
|
|
21873
|
-
ad_platform_metadata: {
|
|
21874
|
-
...defaultPlatformData.adAccountsMeta.ad_platform_metadata,
|
|
21875
|
-
name: "Paws Pet Hotel Meta Ads"
|
|
21876
|
-
}
|
|
21877
|
-
}
|
|
21878
|
-
],
|
|
21879
|
-
// Add Goose-specific campaigns
|
|
21880
|
-
campaigns: [
|
|
21881
|
-
{
|
|
21882
|
-
id: "sandbox-google-search-campaign",
|
|
21883
|
-
business_id: defaultPlatformData.businessesMe.id,
|
|
21884
|
-
ad_account_id: defaultPlatformData.adAccountsGoogle.id,
|
|
21885
|
-
external_id: "sandbox-google-search-campaign",
|
|
21886
|
-
name: "Paws Pet Hotel Google Search Campaign",
|
|
21887
|
-
status: "active",
|
|
21888
|
-
created_at: "2024-03-01T10:00:00.000Z",
|
|
21889
|
-
updated_at: "2024-03-10T10:00:00.000Z"
|
|
21890
|
-
},
|
|
21891
|
-
{
|
|
21892
|
-
id: "sandbox-meta-campaign",
|
|
21893
|
-
business_id: defaultPlatformData.businessesMe.id,
|
|
21894
|
-
ad_account_id: defaultPlatformData.adAccountsMeta.id,
|
|
21895
|
-
external_id: "sandbox-meta-campaign",
|
|
21896
|
-
name: "Paws Pet Hotel Meta Social Campaign",
|
|
21897
|
-
status: "active",
|
|
21898
|
-
created_at: "2024-03-05T11:00:00.000Z",
|
|
21899
|
-
updated_at: "2024-03-15T11:00:00.000Z"
|
|
21900
|
-
}
|
|
21901
|
-
]
|
|
21902
|
-
};
|
|
21903
|
-
const renterraPlatformData = {
|
|
21904
|
-
...defaultPlatformData,
|
|
21905
|
-
businessesMe: {
|
|
21906
|
-
...defaultPlatformData.businessesMe,
|
|
21907
|
-
name: "Tomer's Rental",
|
|
21908
|
-
website: "https://tomersrental.com/",
|
|
21909
|
-
locations: [
|
|
21910
|
-
{
|
|
21911
|
-
district: "ut",
|
|
21912
|
-
locality: "springville",
|
|
21913
|
-
postalCode: "84663",
|
|
21914
|
-
addressLine1: "1605 w 1450 s"
|
|
21915
|
-
}
|
|
21916
|
-
]
|
|
21917
|
-
},
|
|
21918
|
-
webPresenceContent: {
|
|
21919
|
-
url: "https://tomersrental.com/",
|
|
21920
|
-
adGroups: [
|
|
21319
|
+
);
|
|
21320
|
+
} else if (platformConfig.id === "renterra") {
|
|
21321
|
+
baseAdGroups.push(
|
|
21921
21322
|
{
|
|
21922
21323
|
ad: {
|
|
21923
21324
|
headlines: [
|
|
@@ -21933,7 +21334,7 @@ const renterraPlatformData = {
|
|
|
21933
21334
|
"All Equip Rental in Springville, UT. Wide range of equipment for your construction & landscaping needs."
|
|
21934
21335
|
]
|
|
21935
21336
|
},
|
|
21936
|
-
adUrl:
|
|
21337
|
+
adUrl: `${businessConfig.website}items/earthmoving`,
|
|
21937
21338
|
theme: "Heavy Equipment Rental",
|
|
21938
21339
|
keywords: [
|
|
21939
21340
|
"utah county equipment rental",
|
|
@@ -21958,7 +21359,7 @@ const renterraPlatformData = {
|
|
|
21958
21359
|
"All Equip Rental: Your one-stop shop for construction equipment needs. Serving multiple locations in Utah."
|
|
21959
21360
|
]
|
|
21960
21361
|
},
|
|
21961
|
-
adUrl:
|
|
21362
|
+
adUrl: `${businessConfig.website}items/forklift-and-material-handling`,
|
|
21962
21363
|
theme: "Construction Equipment Rental",
|
|
21963
21364
|
keywords: [
|
|
21964
21365
|
"construction equipment rental utah",
|
|
@@ -21967,89 +21368,259 @@ const renterraPlatformData = {
|
|
|
21967
21368
|
"power generation equipment rental",
|
|
21968
21369
|
"material handling rental utah"
|
|
21969
21370
|
]
|
|
21371
|
+
}
|
|
21372
|
+
);
|
|
21373
|
+
} else {
|
|
21374
|
+
baseAdGroups.push(
|
|
21375
|
+
{
|
|
21376
|
+
ad: {
|
|
21377
|
+
headlines: [
|
|
21378
|
+
"Sandbox Business Solutions",
|
|
21379
|
+
"Test Your Integration",
|
|
21380
|
+
"Demo Environment Ready",
|
|
21381
|
+
"Professional Development Tools",
|
|
21382
|
+
"Start Your Trial Today",
|
|
21383
|
+
"Powerful Testing Platform"
|
|
21384
|
+
],
|
|
21385
|
+
descriptions: [
|
|
21386
|
+
"Experience our comprehensive business platform in a safe sandbox environment. Perfect for testing and development.",
|
|
21387
|
+
"Get started with our demo environment. All features available for testing with realistic mock data."
|
|
21388
|
+
]
|
|
21389
|
+
},
|
|
21390
|
+
adUrl: `${businessConfig.website}demo`,
|
|
21391
|
+
theme: "Business Development Platform",
|
|
21392
|
+
keywords: [
|
|
21393
|
+
"sandbox testing platform",
|
|
21394
|
+
"development environment",
|
|
21395
|
+
"business demo software",
|
|
21396
|
+
"integration testing tools",
|
|
21397
|
+
"trial platform demo"
|
|
21398
|
+
]
|
|
21970
21399
|
},
|
|
21971
21400
|
{
|
|
21972
21401
|
ad: {
|
|
21973
21402
|
headlines: [
|
|
21974
|
-
"
|
|
21975
|
-
"
|
|
21976
|
-
"
|
|
21977
|
-
"
|
|
21978
|
-
"
|
|
21979
|
-
"
|
|
21403
|
+
"Enterprise Solutions",
|
|
21404
|
+
"Scalable Platform",
|
|
21405
|
+
"Advanced Features",
|
|
21406
|
+
"Custom Integration",
|
|
21407
|
+
"Business Growth Tools",
|
|
21408
|
+
"Professional Suite"
|
|
21980
21409
|
],
|
|
21981
21410
|
descriptions: [
|
|
21982
|
-
"
|
|
21983
|
-
"
|
|
21411
|
+
"Enterprise-grade solutions for growing businesses. Comprehensive tools and analytics for success.",
|
|
21412
|
+
"Scale your business with our professional platform. Advanced features designed for modern enterprises."
|
|
21984
21413
|
]
|
|
21985
21414
|
},
|
|
21986
|
-
adUrl:
|
|
21987
|
-
theme: "
|
|
21415
|
+
adUrl: `${businessConfig.website}enterprise`,
|
|
21416
|
+
theme: "Enterprise Business Solutions",
|
|
21988
21417
|
keywords: [
|
|
21989
|
-
"
|
|
21990
|
-
"
|
|
21991
|
-
"
|
|
21992
|
-
"
|
|
21993
|
-
"
|
|
21418
|
+
"enterprise software platform",
|
|
21419
|
+
"business growth solutions",
|
|
21420
|
+
"scalable business tools",
|
|
21421
|
+
"professional software suite",
|
|
21422
|
+
"custom business integration"
|
|
21994
21423
|
]
|
|
21995
21424
|
}
|
|
21996
|
-
|
|
21997
|
-
}
|
|
21998
|
-
|
|
21999
|
-
|
|
22000
|
-
|
|
22001
|
-
|
|
22002
|
-
|
|
22003
|
-
|
|
22004
|
-
|
|
22005
|
-
|
|
22006
|
-
|
|
22007
|
-
|
|
22008
|
-
|
|
22009
|
-
|
|
22010
|
-
|
|
22011
|
-
|
|
22012
|
-
|
|
22013
|
-
|
|
22014
|
-
|
|
21425
|
+
);
|
|
21426
|
+
}
|
|
21427
|
+
return {
|
|
21428
|
+
url: businessConfig.website,
|
|
21429
|
+
adGroups: baseAdGroups
|
|
21430
|
+
};
|
|
21431
|
+
};
|
|
21432
|
+
const createSandboxMeasureAndAcquireData = (platformId, businessId) => {
|
|
21433
|
+
const platformConfigKey = getPlatformConfigKey(platformId);
|
|
21434
|
+
const platformConfig = {
|
|
21435
|
+
id: platformConfigKey
|
|
21436
|
+
};
|
|
21437
|
+
const businessConfig = getBusinessConfig(platformId);
|
|
21438
|
+
const businessesMe = createBusinessDataFactory(
|
|
21439
|
+
platformConfig,
|
|
21440
|
+
businessId,
|
|
21441
|
+
platformId || "default"
|
|
21442
|
+
);
|
|
21443
|
+
const adAccountsGoogle = createAdAccountFactory(
|
|
21444
|
+
businessId,
|
|
21445
|
+
"google",
|
|
21446
|
+
businessConfig
|
|
21447
|
+
);
|
|
21448
|
+
const adAccountsMeta = createAdAccountFactory(
|
|
21449
|
+
businessId,
|
|
21450
|
+
"meta",
|
|
21451
|
+
businessConfig
|
|
21452
|
+
);
|
|
21453
|
+
const adAccounts = [adAccountsGoogle, adAccountsMeta];
|
|
21454
|
+
const googleCampaignId = "sandbox-google-search-campaign";
|
|
21455
|
+
const metaCampaignId = "sandbox-meta-campaign";
|
|
21456
|
+
const campaignCreatedDate = (/* @__PURE__ */ new Date(
|
|
21457
|
+
"2024-02-20T10:00:00.000Z"
|
|
21458
|
+
)).toISOString();
|
|
21459
|
+
const campaignUpdatedDate = (/* @__PURE__ */ new Date(
|
|
21460
|
+
"2024-02-27T16:15:00.000Z"
|
|
21461
|
+
)).toISOString();
|
|
21462
|
+
const campaigns = [
|
|
22015
21463
|
{
|
|
22016
|
-
|
|
22017
|
-
|
|
22018
|
-
|
|
22019
|
-
|
|
22020
|
-
}
|
|
21464
|
+
id: googleCampaignId,
|
|
21465
|
+
business_id: businessId,
|
|
21466
|
+
ad_account_id: adAccountsGoogle.id,
|
|
21467
|
+
external_id: googleCampaignId,
|
|
21468
|
+
name: `${businessConfig.branding.brandName} Google Search Campaign`,
|
|
21469
|
+
status: "active",
|
|
21470
|
+
created_at: campaignCreatedDate,
|
|
21471
|
+
updated_at: campaignUpdatedDate
|
|
22021
21472
|
},
|
|
22022
21473
|
{
|
|
22023
|
-
|
|
22024
|
-
|
|
22025
|
-
|
|
22026
|
-
|
|
22027
|
-
}
|
|
21474
|
+
id: metaCampaignId,
|
|
21475
|
+
business_id: businessId,
|
|
21476
|
+
ad_account_id: adAccountsMeta.id,
|
|
21477
|
+
external_id: metaCampaignId,
|
|
21478
|
+
name: `${businessConfig.branding.brandName} Meta Social Campaign`,
|
|
21479
|
+
status: "active",
|
|
21480
|
+
created_at: campaignCreatedDate,
|
|
21481
|
+
updated_at: campaignUpdatedDate
|
|
22028
21482
|
}
|
|
22029
|
-
]
|
|
22030
|
-
|
|
22031
|
-
|
|
21483
|
+
];
|
|
21484
|
+
const googleCampaignMetrics = createCampaignMetricsFactory(
|
|
21485
|
+
googleCampaignId,
|
|
21486
|
+
campaigns[0].name,
|
|
21487
|
+
"google",
|
|
21488
|
+
businessId,
|
|
22032
21489
|
{
|
|
22033
|
-
|
|
22034
|
-
|
|
22035
|
-
|
|
22036
|
-
|
|
22037
|
-
|
|
22038
|
-
|
|
22039
|
-
|
|
22040
|
-
|
|
22041
|
-
}
|
|
21490
|
+
spend: 750,
|
|
21491
|
+
revenue: 6050,
|
|
21492
|
+
clicks: 400,
|
|
21493
|
+
impressions: 8500,
|
|
21494
|
+
conversions: 8,
|
|
21495
|
+
leads: 600,
|
|
21496
|
+
customers: 6,
|
|
21497
|
+
ltv: 8488
|
|
21498
|
+
}
|
|
21499
|
+
);
|
|
21500
|
+
const metaCampaignMetrics = createCampaignMetricsFactory(
|
|
21501
|
+
metaCampaignId,
|
|
21502
|
+
campaigns[1].name,
|
|
21503
|
+
"meta",
|
|
21504
|
+
businessId,
|
|
22042
21505
|
{
|
|
22043
|
-
|
|
22044
|
-
|
|
22045
|
-
|
|
22046
|
-
|
|
22047
|
-
|
|
22048
|
-
|
|
22049
|
-
|
|
22050
|
-
|
|
21506
|
+
spend: 325,
|
|
21507
|
+
revenue: 3025,
|
|
21508
|
+
clicks: 300,
|
|
21509
|
+
impressions: 6900,
|
|
21510
|
+
conversions: 4,
|
|
21511
|
+
leads: 400,
|
|
21512
|
+
customers: 7,
|
|
21513
|
+
ltv: 3150
|
|
22051
21514
|
}
|
|
22052
|
-
|
|
21515
|
+
);
|
|
21516
|
+
const googleChannelMetrics = createChannelMetricsFactory(
|
|
21517
|
+
businessId,
|
|
21518
|
+
"google",
|
|
21519
|
+
[googleCampaignMetrics]
|
|
21520
|
+
);
|
|
21521
|
+
const metaChannelMetrics = createChannelMetricsFactory(businessId, "meta", [
|
|
21522
|
+
metaCampaignMetrics
|
|
21523
|
+
]);
|
|
21524
|
+
const allCampaigns = [googleCampaignMetrics, metaCampaignMetrics];
|
|
21525
|
+
const allChannelMetrics = createChannelMetricsFactory(
|
|
21526
|
+
businessId,
|
|
21527
|
+
"google",
|
|
21528
|
+
allCampaigns
|
|
21529
|
+
);
|
|
21530
|
+
const baseAggregatedMetrics = {
|
|
21531
|
+
google: googleChannelMetrics,
|
|
21532
|
+
meta: metaChannelMetrics,
|
|
21533
|
+
all: allChannelMetrics
|
|
21534
|
+
};
|
|
21535
|
+
const sourceBreakdown = createOrderSourceBreakdownFactory(platformConfig);
|
|
21536
|
+
const totalCount = sourceBreakdown.reduce((sum, item) => sum + item.count, 0);
|
|
21537
|
+
const totalAmount = sourceBreakdown.reduce(
|
|
21538
|
+
(sum, item) => sum + item.amount,
|
|
21539
|
+
0
|
|
21540
|
+
);
|
|
21541
|
+
const orderSourceInfoTotals = {
|
|
21542
|
+
baseStartDate: "2025-03-01",
|
|
21543
|
+
baseEndDate: "2025-05-29",
|
|
21544
|
+
totalCount,
|
|
21545
|
+
totalAmount,
|
|
21546
|
+
sourceBreakdown
|
|
21547
|
+
};
|
|
21548
|
+
const sampleOrders = createSampleOrdersFactory(
|
|
21549
|
+
businessId,
|
|
21550
|
+
platformId || "default",
|
|
21551
|
+
[googleCampaignId, metaCampaignId],
|
|
21552
|
+
25
|
|
21553
|
+
);
|
|
21554
|
+
const orderSourceInfoList = {
|
|
21555
|
+
baseStartDate: "2025-04-03",
|
|
21556
|
+
baseEndDate: "2025-04-04",
|
|
21557
|
+
results: sampleOrders,
|
|
21558
|
+
pagination: {
|
|
21559
|
+
hasNextPage: false,
|
|
21560
|
+
cursor: null,
|
|
21561
|
+
total: sampleOrders.length
|
|
21562
|
+
}
|
|
21563
|
+
};
|
|
21564
|
+
const webPresenceContent = createWebPresenceContentFactory(
|
|
21565
|
+
platformConfig,
|
|
21566
|
+
businessConfig
|
|
21567
|
+
);
|
|
21568
|
+
return {
|
|
21569
|
+
businessesMe,
|
|
21570
|
+
adAccountsGoogle,
|
|
21571
|
+
adAccountsMeta,
|
|
21572
|
+
adAccounts,
|
|
21573
|
+
baseAggregatedMetrics,
|
|
21574
|
+
orderSourceInfoTotals,
|
|
21575
|
+
orderSourceInfoList,
|
|
21576
|
+
campaigns,
|
|
21577
|
+
webPresenceContent
|
|
21578
|
+
};
|
|
21579
|
+
};
|
|
21580
|
+
const sandboxBusinessId = f.string.uuid();
|
|
21581
|
+
const defaultReputationData = createSandboxReputationData(
|
|
21582
|
+
void 0,
|
|
21583
|
+
sandboxBusinessId
|
|
21584
|
+
);
|
|
21585
|
+
const defaultMeasureAndAcquireData = createSandboxMeasureAndAcquireData(
|
|
21586
|
+
void 0,
|
|
21587
|
+
sandboxBusinessId
|
|
21588
|
+
);
|
|
21589
|
+
const defaultPlatformData = {
|
|
21590
|
+
// Use factory-generated data
|
|
21591
|
+
...defaultMeasureAndAcquireData,
|
|
21592
|
+
// Add reputation data
|
|
21593
|
+
reputationData: defaultReputationData
|
|
21594
|
+
};
|
|
21595
|
+
const goosePlatformId = "01958180-06a0-7681-8064-6834e166d2e4";
|
|
21596
|
+
const gooseBusinessId = defaultPlatformData.businessesMe.id;
|
|
21597
|
+
const gooseMeasureAndAcquireData = createSandboxMeasureAndAcquireData(
|
|
21598
|
+
goosePlatformId,
|
|
21599
|
+
gooseBusinessId
|
|
21600
|
+
);
|
|
21601
|
+
const gooseReputationData = createSandboxReputationData(
|
|
21602
|
+
goosePlatformId,
|
|
21603
|
+
gooseBusinessId
|
|
21604
|
+
);
|
|
21605
|
+
const goosePlatformData = {
|
|
21606
|
+
// Use factory-generated data
|
|
21607
|
+
...gooseMeasureAndAcquireData,
|
|
21608
|
+
reputationData: gooseReputationData
|
|
21609
|
+
};
|
|
21610
|
+
const renterraPlatformId = "4277dfb9-7535-4206-962d-3f29ad143d8a";
|
|
21611
|
+
const renterraBusinessId = defaultPlatformData.businessesMe.id;
|
|
21612
|
+
const renterraMeasureAndAcquireData = createSandboxMeasureAndAcquireData(
|
|
21613
|
+
renterraPlatformId,
|
|
21614
|
+
renterraBusinessId
|
|
21615
|
+
);
|
|
21616
|
+
const renterraReputationData = createSandboxReputationData(
|
|
21617
|
+
renterraPlatformId,
|
|
21618
|
+
renterraBusinessId
|
|
21619
|
+
);
|
|
21620
|
+
const renterraPlatformData = {
|
|
21621
|
+
// Use factory-generated data
|
|
21622
|
+
...renterraMeasureAndAcquireData,
|
|
21623
|
+
reputationData: renterraReputationData
|
|
22053
21624
|
};
|
|
22054
21625
|
const sandboxDataStore = {
|
|
22055
21626
|
// Goose dev platform ID
|
|
@@ -22105,6 +21676,38 @@ function parseDateRange(startDateString, endDateString, defaultDays = 30) {
|
|
|
22105
21676
|
endDate
|
|
22106
21677
|
};
|
|
22107
21678
|
}
|
|
21679
|
+
let getRandomValues;
|
|
21680
|
+
const rnds8 = new Uint8Array(16);
|
|
21681
|
+
function rng() {
|
|
21682
|
+
if (!getRandomValues) {
|
|
21683
|
+
getRandomValues = typeof crypto !== "undefined" && crypto.getRandomValues && crypto.getRandomValues.bind(crypto);
|
|
21684
|
+
if (!getRandomValues) {
|
|
21685
|
+
throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");
|
|
21686
|
+
}
|
|
21687
|
+
}
|
|
21688
|
+
return getRandomValues(rnds8);
|
|
21689
|
+
}
|
|
21690
|
+
const byteToHex = [];
|
|
21691
|
+
for (let i2 = 0; i2 < 256; ++i2) {
|
|
21692
|
+
byteToHex.push((i2 + 256).toString(16).slice(1));
|
|
21693
|
+
}
|
|
21694
|
+
function unsafeStringify(arr, offset = 0) {
|
|
21695
|
+
return byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + "-" + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + "-" + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + "-" + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + "-" + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]];
|
|
21696
|
+
}
|
|
21697
|
+
const randomUUID = typeof crypto !== "undefined" && crypto.randomUUID && crypto.randomUUID.bind(crypto);
|
|
21698
|
+
const native = {
|
|
21699
|
+
randomUUID
|
|
21700
|
+
};
|
|
21701
|
+
function v4(options, buf, offset) {
|
|
21702
|
+
if (native.randomUUID && true && !options) {
|
|
21703
|
+
return native.randomUUID();
|
|
21704
|
+
}
|
|
21705
|
+
options = options || {};
|
|
21706
|
+
const rnds = options.random || (options.rng || rng)();
|
|
21707
|
+
rnds[6] = rnds[6] & 15 | 64;
|
|
21708
|
+
rnds[8] = rnds[8] & 63 | 128;
|
|
21709
|
+
return unsafeStringify(rnds);
|
|
21710
|
+
}
|
|
22108
21711
|
function scaleChannelMetrics(channelMetrics, options) {
|
|
22109
21712
|
const {
|
|
22110
21713
|
requestedDays,
|
|
@@ -22339,6 +21942,58 @@ function generateAndDistributeOrders({
|
|
|
22339
21942
|
const uniqueSuffix = i2 * baseSetSize + index + 1;
|
|
22340
21943
|
newOrder.id = `MOCK-ORD-${uniqueSuffix.toString().padStart(4, "0")}`;
|
|
22341
21944
|
newOrder.external_id = `MOCK-EXT-${uniqueSuffix.toString().padStart(4, "0")}`;
|
|
21945
|
+
newOrder.user_name = f.person.fullName();
|
|
21946
|
+
newOrder.user_email = f.internet.email();
|
|
21947
|
+
newOrder.user_external_id = `fake-user-ext-${f.string.alphanumeric(8)}`;
|
|
21948
|
+
newOrder.partner_user_id = `fake-partner-user-${f.string.alphanumeric(6)}`;
|
|
21949
|
+
const baseAmount = parseFloat(newOrder.amount);
|
|
21950
|
+
const variance = 0.15;
|
|
21951
|
+
const newAmount = baseAmount * (1 + (Math.random() - 0.5) * 2 * variance);
|
|
21952
|
+
newOrder.amount = Math.max(50, newAmount).toFixed(2);
|
|
21953
|
+
if (Math.random() < 0.3 && newOrder.source_info) {
|
|
21954
|
+
const currentSource = newOrder.source_info.primary_source;
|
|
21955
|
+
if (currentSource === "Google Ads" && newOrder.campaign_id?.includes("google")) {
|
|
21956
|
+
const googleVariations = ["ppc", "cpc", "shopping", "search"];
|
|
21957
|
+
newOrder.source_info.utm_medium = f.helpers.arrayElement(googleVariations);
|
|
21958
|
+
} else if (currentSource === "Facebook Ads" && newOrder.campaign_id?.includes("meta")) {
|
|
21959
|
+
const facebookVariations = ["cpc", "social", "paid-social"];
|
|
21960
|
+
newOrder.source_info.utm_medium = f.helpers.arrayElement(facebookVariations);
|
|
21961
|
+
} else if (!newOrder.campaign_id) {
|
|
21962
|
+
const organicSources = [
|
|
21963
|
+
{
|
|
21964
|
+
primary_source: "Google Organic Search",
|
|
21965
|
+
source_type: "organic_search",
|
|
21966
|
+
utm_source: "google",
|
|
21967
|
+
utm_medium: "organic"
|
|
21968
|
+
},
|
|
21969
|
+
{
|
|
21970
|
+
primary_source: "Bing Organic",
|
|
21971
|
+
source_type: "organic_search",
|
|
21972
|
+
utm_source: "bing",
|
|
21973
|
+
utm_medium: "organic"
|
|
21974
|
+
},
|
|
21975
|
+
{
|
|
21976
|
+
primary_source: "Yahoo Organic",
|
|
21977
|
+
source_type: "organic_search",
|
|
21978
|
+
utm_source: "yahoo",
|
|
21979
|
+
utm_medium: "organic"
|
|
21980
|
+
},
|
|
21981
|
+
{ primary_source: "Facebook Organic", source_type: "social" },
|
|
21982
|
+
{ primary_source: "direct", source_type: "direct" }
|
|
21983
|
+
];
|
|
21984
|
+
const newSource = f.helpers.arrayElement(organicSources);
|
|
21985
|
+
newOrder.source_info.primary_source = newSource.primary_source;
|
|
21986
|
+
newOrder.source_info.source_type = newSource.source_type;
|
|
21987
|
+
newOrder.source_info.utm_source = newSource.utm_source;
|
|
21988
|
+
newOrder.source_info.utm_medium = newSource.utm_medium;
|
|
21989
|
+
}
|
|
21990
|
+
if (newOrder.metadata?.source_info) {
|
|
21991
|
+
newOrder.metadata.source_info.primary_source = newOrder.source_info.primary_source;
|
|
21992
|
+
newOrder.metadata.source_info.source_type = newOrder.source_info.source_type;
|
|
21993
|
+
newOrder.metadata.source_info.utm_source = newOrder.source_info.utm_source;
|
|
21994
|
+
newOrder.metadata.source_info.utm_medium = newOrder.source_info.utm_medium;
|
|
21995
|
+
}
|
|
21996
|
+
}
|
|
22342
21997
|
allGeneratedOrders.push(newOrder);
|
|
22343
21998
|
});
|
|
22344
21999
|
}
|
|
@@ -22359,6 +22014,25 @@ function generateAndDistributeOrders({
|
|
|
22359
22014
|
order.updated_at = new Date(
|
|
22360
22015
|
newCreatedDateMs + deltaUpdatedAt
|
|
22361
22016
|
).toISOString();
|
|
22017
|
+
const hasCampaign = !!order.campaign_id;
|
|
22018
|
+
const sevenDaysMs = 7 * 24 * 60 * 60 * 1e3;
|
|
22019
|
+
const ninetyDaysMs = 90 * 24 * 60 * 60 * 1e3;
|
|
22020
|
+
if (hasCampaign) {
|
|
22021
|
+
const earliestAllowed = newCreatedDateMs - ninetyDaysMs;
|
|
22022
|
+
const randomOffset = Math.floor(Math.random() * sevenDaysMs);
|
|
22023
|
+
let proposed = newCreatedDateMs - randomOffset;
|
|
22024
|
+
if (proposed < earliestAllowed) proposed = earliestAllowed;
|
|
22025
|
+
if (proposed > newCreatedDateMs) proposed = newCreatedDateMs;
|
|
22026
|
+
order.source_info = {
|
|
22027
|
+
...order.source_info || {},
|
|
22028
|
+
visit_date: new Date(proposed).toISOString()
|
|
22029
|
+
};
|
|
22030
|
+
} else {
|
|
22031
|
+
order.source_info = {
|
|
22032
|
+
...order.source_info || {},
|
|
22033
|
+
visit_date: new Date(newCreatedDateMs).toISOString()
|
|
22034
|
+
};
|
|
22035
|
+
}
|
|
22362
22036
|
});
|
|
22363
22037
|
}
|
|
22364
22038
|
return allGeneratedOrders;
|
|
@@ -22409,7 +22083,7 @@ const setMSWSandboxPlatformId = (platformId) => {
|
|
|
22409
22083
|
`[ REACH ] Sandbox platformId set to: ${platformId || "default"}`
|
|
22410
22084
|
);
|
|
22411
22085
|
};
|
|
22412
|
-
const
|
|
22086
|
+
const measureAndAcquireHandlers = [
|
|
22413
22087
|
http.get(`${HOSTNAME}/api/businesses/me`, () => {
|
|
22414
22088
|
const platformData = getSandboxDataForPlatform(currentSandboxPlatformId);
|
|
22415
22089
|
return HttpResponse.json({
|
|
@@ -22747,6 +22421,24 @@ const handlers = [
|
|
|
22747
22421
|
data: platformData.webPresenceContent
|
|
22748
22422
|
});
|
|
22749
22423
|
}),
|
|
22424
|
+
http.post(`${HOSTNAME}/api/web-presence/content`, async () => {
|
|
22425
|
+
await withDelay(3e3);
|
|
22426
|
+
const platformData = getSandboxDataForPlatform(currentSandboxPlatformId);
|
|
22427
|
+
if (!platformData.webPresenceContent) {
|
|
22428
|
+
return HttpResponse.json(
|
|
22429
|
+
{
|
|
22430
|
+
success: false,
|
|
22431
|
+
message: "Web presence content not found for this platform"
|
|
22432
|
+
},
|
|
22433
|
+
{ status: 404 }
|
|
22434
|
+
);
|
|
22435
|
+
}
|
|
22436
|
+
return HttpResponse.json({
|
|
22437
|
+
success: true,
|
|
22438
|
+
message: "Website content analyzed successfully (Sandbox)",
|
|
22439
|
+
data: platformData.webPresenceContent
|
|
22440
|
+
});
|
|
22441
|
+
}),
|
|
22750
22442
|
http.get(`${HOSTNAME}/api/ad-account-metrics/aggregated/campaign`, (req) => {
|
|
22751
22443
|
const url = new URL(req.request.url);
|
|
22752
22444
|
const campaignId = url.searchParams.get("campaignId");
|
|
@@ -22822,6 +22514,18 @@ const handlers = [
|
|
|
22822
22514
|
}
|
|
22823
22515
|
});
|
|
22824
22516
|
}),
|
|
22517
|
+
http.get(
|
|
22518
|
+
`${HOSTNAME}/api/ad-platform-tracking/google/check-for-existing?ad_account_id=sandbox-g-customer-123`,
|
|
22519
|
+
async () => {
|
|
22520
|
+
return HttpResponse.json({
|
|
22521
|
+
success: true,
|
|
22522
|
+
message: "Success (Sandbox)",
|
|
22523
|
+
data: {
|
|
22524
|
+
ads_with_tracking: []
|
|
22525
|
+
}
|
|
22526
|
+
});
|
|
22527
|
+
}
|
|
22528
|
+
),
|
|
22825
22529
|
http.get(
|
|
22826
22530
|
`${HOSTNAME}/api/ad-platform-tracking/meta/check-for-existing?ad_account_id=sandbox-m-act-789`,
|
|
22827
22531
|
async () => {
|
|
@@ -22835,11 +22539,892 @@ const handlers = [
|
|
|
22835
22539
|
}
|
|
22836
22540
|
)
|
|
22837
22541
|
];
|
|
22838
|
-
const
|
|
22542
|
+
const generateReputationResponsesData = ({
|
|
22543
|
+
platformData,
|
|
22544
|
+
startDate,
|
|
22545
|
+
endDate,
|
|
22546
|
+
locationIds,
|
|
22547
|
+
cursor,
|
|
22548
|
+
limit,
|
|
22549
|
+
searchTerm
|
|
22550
|
+
}) => {
|
|
22551
|
+
const platformConfig = getPlatformConfig(
|
|
22552
|
+
platformData.businessesMe?.platform_id
|
|
22553
|
+
);
|
|
22554
|
+
const queryStartDate = startDate ? new Date(startDate) : new Date(Date.now() - 30 * 24 * 60 * 60 * 1e3);
|
|
22555
|
+
const queryEndDate = endDate ? new Date(endDate) : /* @__PURE__ */ new Date();
|
|
22556
|
+
const queryDays = Math.ceil(
|
|
22557
|
+
(queryEndDate.getTime() - queryStartDate.getTime()) / (1e3 * 60 * 60 * 24)
|
|
22558
|
+
) + 1;
|
|
22559
|
+
const baseResponseCount = 50;
|
|
22560
|
+
const scaledResponseCount = Math.max(
|
|
22561
|
+
10,
|
|
22562
|
+
Math.round(baseResponseCount * queryDays / 30)
|
|
22563
|
+
);
|
|
22564
|
+
const allResponses = generateResponsePool(
|
|
22565
|
+
platformConfig,
|
|
22566
|
+
platformData,
|
|
22567
|
+
queryStartDate,
|
|
22568
|
+
queryEndDate,
|
|
22569
|
+
scaledResponseCount
|
|
22570
|
+
);
|
|
22571
|
+
let filteredResponses = allResponses;
|
|
22572
|
+
if (locationIds.length > 0) {
|
|
22573
|
+
filteredResponses = filteredResponses.filter(
|
|
22574
|
+
(response) => response.locationId && locationIds.includes(response.locationId)
|
|
22575
|
+
);
|
|
22576
|
+
}
|
|
22577
|
+
if (searchTerm && searchTerm.length >= 3) {
|
|
22578
|
+
const searchLower = searchTerm.toLowerCase();
|
|
22579
|
+
filteredResponses = filteredResponses.filter(
|
|
22580
|
+
(response) => response.content.toLowerCase().includes(searchLower) || response.userName.toLowerCase().includes(searchLower) || response.userEmail.toLowerCase().includes(searchLower)
|
|
22581
|
+
);
|
|
22582
|
+
}
|
|
22583
|
+
filteredResponses.sort(
|
|
22584
|
+
(a2, b2) => new Date(b2.createdAt).getTime() - new Date(a2.createdAt).getTime()
|
|
22585
|
+
);
|
|
22586
|
+
let startIndex = 0;
|
|
22587
|
+
if (cursor) {
|
|
22588
|
+
startIndex = parseInt(cursor, 10) || 0;
|
|
22589
|
+
}
|
|
22590
|
+
const endIndex = startIndex + limit;
|
|
22591
|
+
const paginatedResponses = filteredResponses.slice(startIndex, endIndex);
|
|
22592
|
+
const hasMore = endIndex < filteredResponses.length;
|
|
22593
|
+
const nextCursor = hasMore ? endIndex.toString() : null;
|
|
22594
|
+
return {
|
|
22595
|
+
data: paginatedResponses,
|
|
22596
|
+
nextCursor,
|
|
22597
|
+
hasMore,
|
|
22598
|
+
total: filteredResponses.length
|
|
22599
|
+
};
|
|
22600
|
+
};
|
|
22601
|
+
function generateResponsePool(platformConfig, platformData, startDate, endDate, totalCount) {
|
|
22602
|
+
const responses = [];
|
|
22603
|
+
const partnerLocations = platformData.reputationData?.partnerLocations || [];
|
|
22604
|
+
const googleReviewCount = Math.round(totalCount * 0.7);
|
|
22605
|
+
const internalFeedbackCount = totalCount - googleReviewCount;
|
|
22606
|
+
for (let i2 = 0; i2 < googleReviewCount; i2++) {
|
|
22607
|
+
responses.push(
|
|
22608
|
+
createGoogleReview(platformConfig, partnerLocations, startDate, endDate)
|
|
22609
|
+
);
|
|
22610
|
+
}
|
|
22611
|
+
for (let i2 = 0; i2 < internalFeedbackCount; i2++) {
|
|
22612
|
+
responses.push(
|
|
22613
|
+
createInternalFeedback(
|
|
22614
|
+
platformConfig,
|
|
22615
|
+
partnerLocations,
|
|
22616
|
+
startDate,
|
|
22617
|
+
endDate
|
|
22618
|
+
)
|
|
22619
|
+
);
|
|
22620
|
+
}
|
|
22621
|
+
return responses;
|
|
22622
|
+
}
|
|
22623
|
+
function createGoogleReview(platformConfig, partnerLocations, startDate, endDate) {
|
|
22624
|
+
const rating = f.helpers.weightedArrayElement([
|
|
22625
|
+
{ weight: 50, value: 5 },
|
|
22626
|
+
// 50% 5-star reviews
|
|
22627
|
+
{ weight: 30, value: 4 },
|
|
22628
|
+
// 30% 4-star reviews
|
|
22629
|
+
{ weight: 10, value: 3 },
|
|
22630
|
+
// 10% 3-star reviews
|
|
22631
|
+
{ weight: 7, value: 2 },
|
|
22632
|
+
// 7% 2-star reviews
|
|
22633
|
+
{ weight: 3, value: 1 }
|
|
22634
|
+
// 3% 1-star reviews
|
|
22635
|
+
]);
|
|
22636
|
+
const reviewContent = generateReviewContent(platformConfig, rating);
|
|
22637
|
+
const location2 = partnerLocations.length > 0 ? f.helpers.arrayElement(partnerLocations) : null;
|
|
22638
|
+
return {
|
|
22639
|
+
id: f.string.uuid(),
|
|
22640
|
+
source: "google",
|
|
22641
|
+
rating,
|
|
22642
|
+
userName: f.person.fullName(),
|
|
22643
|
+
userEmail: f.internet.email(),
|
|
22644
|
+
// In real Google reviews, email might not be available
|
|
22645
|
+
content: reviewContent,
|
|
22646
|
+
createdAt: f.date.between({ from: startDate, to: endDate }).toISOString(),
|
|
22647
|
+
hasReply: f.helpers.weightedArrayElement([
|
|
22648
|
+
{ weight: 30, value: true },
|
|
22649
|
+
// 30% have business replies
|
|
22650
|
+
{ weight: 70, value: false }
|
|
22651
|
+
]),
|
|
22652
|
+
isResponded: false,
|
|
22653
|
+
// Not applicable for Google reviews
|
|
22654
|
+
actionUrl: `https://business.google.com/reviews/l/${f.string.alphanumeric(21)}`,
|
|
22655
|
+
locationId: location2?.externalId || void 0
|
|
22656
|
+
};
|
|
22657
|
+
}
|
|
22658
|
+
function createInternalFeedback(platformConfig, partnerLocations, startDate, endDate) {
|
|
22659
|
+
const rating = f.helpers.weightedArrayElement([
|
|
22660
|
+
{ weight: 80, value: 5 },
|
|
22661
|
+
// Thumbs up (positive feedback) - 80%
|
|
22662
|
+
{ weight: 20, value: 1 }
|
|
22663
|
+
// Thumbs down (negative feedback) - 20%
|
|
22664
|
+
]);
|
|
22665
|
+
const feedbackContent = generateFeedbackContent(platformConfig, rating);
|
|
22666
|
+
const location2 = partnerLocations.length > 0 ? f.helpers.arrayElement(partnerLocations) : null;
|
|
22667
|
+
return {
|
|
22668
|
+
id: f.string.uuid(),
|
|
22669
|
+
source: "internal",
|
|
22670
|
+
rating,
|
|
22671
|
+
userName: f.person.fullName(),
|
|
22672
|
+
userEmail: f.internet.email(),
|
|
22673
|
+
content: feedbackContent,
|
|
22674
|
+
createdAt: f.date.between({ from: startDate, to: endDate }).toISOString(),
|
|
22675
|
+
hasReply: false,
|
|
22676
|
+
// Not applicable for internal feedback
|
|
22677
|
+
isResponded: f.helpers.weightedArrayElement([
|
|
22678
|
+
{ weight: 40, value: true },
|
|
22679
|
+
// 40% have customer responses
|
|
22680
|
+
{ weight: 60, value: false }
|
|
22681
|
+
]),
|
|
22682
|
+
actionUrl: void 0,
|
|
22683
|
+
// Internal feedback doesn't have external action URLs
|
|
22684
|
+
locationId: location2?.externalId || void 0
|
|
22685
|
+
};
|
|
22686
|
+
}
|
|
22687
|
+
function generateReviewContent(platformConfig, rating) {
|
|
22688
|
+
const platformName = platformConfig.name || "Business";
|
|
22689
|
+
const templates = getReviewTemplates(platformConfig.id, rating);
|
|
22690
|
+
const template = f.helpers.arrayElement(templates);
|
|
22691
|
+
return template.replace(/\{business\}/g, platformName);
|
|
22692
|
+
}
|
|
22693
|
+
function generateFeedbackContent(platformConfig, rating) {
|
|
22694
|
+
const platformName = platformConfig.name || "Business";
|
|
22695
|
+
const templates = getFeedbackTemplates(platformConfig.id, rating);
|
|
22696
|
+
const template = f.helpers.arrayElement(templates);
|
|
22697
|
+
return template.replace(/\{business\}/g, platformName);
|
|
22698
|
+
}
|
|
22699
|
+
function getReviewTemplates(platformId, rating) {
|
|
22700
|
+
const commonPositive = [
|
|
22701
|
+
"Great experience at {business}! The service was excellent and the staff was very friendly.",
|
|
22702
|
+
"Highly recommend {business}. Everything was exactly as promised and the quality was outstanding.",
|
|
22703
|
+
"Amazing service! The team at {business} went above and beyond to help us.",
|
|
22704
|
+
"Best {business} in the area! Professional, reliable, and great value for money."
|
|
22705
|
+
];
|
|
22706
|
+
const commonNegative = [
|
|
22707
|
+
"Disappointing experience at {business}. The service didn't meet our expectations.",
|
|
22708
|
+
"Had some issues with {business}. The staff was unresponsive and the quality was poor.",
|
|
22709
|
+
"Not satisfied with the service from {business}. Would not recommend to others.",
|
|
22710
|
+
"Poor experience overall. {business} needs to improve their customer service significantly."
|
|
22711
|
+
];
|
|
22712
|
+
const commonNeutral = [
|
|
22713
|
+
"Average experience at {business}. Service was okay but nothing special.",
|
|
22714
|
+
"{business} did the job but there's definitely room for improvement.",
|
|
22715
|
+
"Mixed experience with {business}. Some things were good, others could be better.",
|
|
22716
|
+
"Standard service from {business}. Met basic expectations but not exceptional."
|
|
22717
|
+
];
|
|
22718
|
+
if (platformId === "goose") {
|
|
22719
|
+
const petSpaPositive = [
|
|
22720
|
+
"My dog absolutely loves coming to {business}! The groomers are so gentle and caring.",
|
|
22721
|
+
"Fantastic pet spa! My cat came out looking amazing and was totally relaxed.",
|
|
22722
|
+
"Best grooming experience ever! The staff at {business} clearly loves animals.",
|
|
22723
|
+
"Professional pet care at {business}. My dog's coat has never looked better!"
|
|
22724
|
+
];
|
|
22725
|
+
const petSpaNegative = [
|
|
22726
|
+
"My pet seemed stressed after the visit to {business}. Not happy with the service.",
|
|
22727
|
+
"Overpriced for what we received. My dog didn't seem comfortable at {business}.",
|
|
22728
|
+
"Poor communication from {business}. They didn't follow our specific grooming instructions.",
|
|
22729
|
+
"Disappointing grooming job. My pet's nails weren't trimmed properly at {business}."
|
|
22730
|
+
];
|
|
22731
|
+
if (rating >= 4) return [...commonPositive, ...petSpaPositive];
|
|
22732
|
+
if (rating <= 2) return [...commonNegative, ...petSpaNegative];
|
|
22733
|
+
return commonNeutral;
|
|
22734
|
+
}
|
|
22735
|
+
if (platformId === "renterra") {
|
|
22736
|
+
const rentalPositive = [
|
|
22737
|
+
"Great equipment rental from {business}! Everything was clean and worked perfectly.",
|
|
22738
|
+
"Excellent service at {business}. The delivery was on time and the equipment was top quality.",
|
|
22739
|
+
"Highly recommend {business} for equipment rentals. Professional and reliable service.",
|
|
22740
|
+
"Best rental experience! {business} made our project so much easier with their quality equipment."
|
|
22741
|
+
];
|
|
22742
|
+
const rentalNegative = [
|
|
22743
|
+
"Equipment from {business} broke down during our project. Very inconvenient and costly.",
|
|
22744
|
+
"Poor condition equipment and late delivery from {business}. Not satisfied at all.",
|
|
22745
|
+
"Overcharged and under-delivered. {business} needs to improve their equipment maintenance.",
|
|
22746
|
+
"Terrible customer service from {business}. They were unresponsive when we had issues."
|
|
22747
|
+
];
|
|
22748
|
+
if (rating >= 4) return [...commonPositive, ...rentalPositive];
|
|
22749
|
+
if (rating <= 2) return [...commonNegative, ...rentalNegative];
|
|
22750
|
+
return commonNeutral;
|
|
22751
|
+
}
|
|
22752
|
+
if (rating >= 4) return commonPositive;
|
|
22753
|
+
if (rating <= 2) return commonNegative;
|
|
22754
|
+
return commonNeutral;
|
|
22755
|
+
}
|
|
22756
|
+
function getFeedbackTemplates(platformId, rating) {
|
|
22757
|
+
const commonPositive = [
|
|
22758
|
+
"I wanted to share my positive experience with {business}. The entire process was smooth and professional. The staff was knowledgeable and took the time to explain everything clearly. I'm very satisfied with the service and would definitely return.",
|
|
22759
|
+
"Excellent service from {business}! From the initial consultation to the final delivery, everything exceeded my expectations. The team was responsive to my questions and made sure I was completely satisfied with the outcome.",
|
|
22760
|
+
"Outstanding experience with {business}. The quality of work was exceptional and the customer service was top-notch. I appreciated the attention to detail and the follow-up communication. Highly recommend!"
|
|
22761
|
+
];
|
|
22762
|
+
const commonNegative = [
|
|
22763
|
+
"I had several issues with my recent experience at {business}. The initial promise was not met, and when I tried to address my concerns, the customer service was lacking. The quality of service was below what I expected based on the pricing.",
|
|
22764
|
+
"Unfortunately, my experience with {business} was disappointing. There were delays in service delivery, and the communication was poor throughout the process. I hope they can improve their operations for future customers.",
|
|
22765
|
+
"Not satisfied with the service from {business}. The staff seemed unprepared and the final result didn't match what was discussed initially. For the price paid, I expected much better quality and professionalism."
|
|
22766
|
+
];
|
|
22767
|
+
const commonNeutral = [
|
|
22768
|
+
"My experience with {business} was average. The service was completed as requested, but there were some minor issues along the way. The staff was generally helpful, though response times could be improved. Overall, it met basic expectations.",
|
|
22769
|
+
"Mixed feelings about {business}. Some aspects of the service were good, while others fell short. The pricing was fair, but the execution could have been better. They have potential but need some improvements."
|
|
22770
|
+
];
|
|
22771
|
+
if (platformId === "goose") {
|
|
22772
|
+
const petSpaDetailed = rating >= 4 ? [
|
|
22773
|
+
"My experience at {business} was wonderful. The staff clearly has extensive training in animal care and grooming techniques. My pet was comfortable throughout the entire process, and the grooming results were exactly what I requested. The facility is clean and well-organized, and I appreciate the care they take with each animal."
|
|
22774
|
+
] : [
|
|
22775
|
+
"I had concerns about my pet's experience at {business}. While the grooming was completed, my animal seemed stressed afterward. The staff could benefit from additional training on handling anxious pets. The facility was clean, but the process could be more gentle and patient."
|
|
22776
|
+
];
|
|
22777
|
+
if (rating >= 4) return [...commonPositive, ...petSpaDetailed];
|
|
22778
|
+
if (rating <= 2) return [...commonNegative, ...petSpaDetailed];
|
|
22779
|
+
}
|
|
22780
|
+
if (platformId === "renterra") {
|
|
22781
|
+
const rentalDetailed = rating >= 4 ? [
|
|
22782
|
+
"Excellent equipment rental experience with {business}. The reservation process was straightforward, and the equipment was delivered on time in perfect working condition. The staff provided clear instructions for operation and maintenance. When we had a minor question during the rental period, they were quick to respond and helpful."
|
|
22783
|
+
] : [
|
|
22784
|
+
"Had some challenges with my rental from {business}. The equipment arrived later than scheduled, which impacted our project timeline. Additionally, the equipment showed signs of wear that weren't disclosed upfront. Customer service was slow to respond when we reported issues."
|
|
22785
|
+
];
|
|
22786
|
+
if (rating >= 4) return [...commonPositive, ...rentalDetailed];
|
|
22787
|
+
if (rating <= 2) return [...commonNegative, ...rentalDetailed];
|
|
22788
|
+
}
|
|
22789
|
+
if (rating >= 4) return commonPositive;
|
|
22790
|
+
if (rating <= 2) return commonNegative;
|
|
22791
|
+
return commonNeutral;
|
|
22792
|
+
}
|
|
22793
|
+
const generateReviewAnalyticsData = ({
|
|
22794
|
+
platformData,
|
|
22795
|
+
queryParams
|
|
22796
|
+
}) => {
|
|
22797
|
+
const platformConfig = getPlatformConfig(
|
|
22798
|
+
platformData.businessesMe?.platform_id
|
|
22799
|
+
);
|
|
22800
|
+
const isAllTimeQuery = !queryParams.start_date || !queryParams.end_date;
|
|
22801
|
+
let scalingFactor = 1;
|
|
22802
|
+
if (!isAllTimeQuery) {
|
|
22803
|
+
const { requestedDays } = parseDateRange(
|
|
22804
|
+
queryParams.start_date || null,
|
|
22805
|
+
queryParams.end_date || null,
|
|
22806
|
+
30
|
|
22807
|
+
);
|
|
22808
|
+
const basePeriodDays = 30;
|
|
22809
|
+
scalingFactor = requestedDays / basePeriodDays;
|
|
22810
|
+
}
|
|
22811
|
+
const currentPeriodData = generateReviewPeriodData(
|
|
22812
|
+
platformConfig,
|
|
22813
|
+
scalingFactor,
|
|
22814
|
+
false,
|
|
22815
|
+
isAllTimeQuery
|
|
22816
|
+
);
|
|
22817
|
+
if (queryParams.include_comparison) {
|
|
22818
|
+
const previousPeriodData = generateReviewPeriodData(
|
|
22819
|
+
platformConfig,
|
|
22820
|
+
scalingFactor,
|
|
22821
|
+
true,
|
|
22822
|
+
isAllTimeQuery
|
|
22823
|
+
);
|
|
22824
|
+
const comparison = calculateReviewComparison(
|
|
22825
|
+
currentPeriodData,
|
|
22826
|
+
previousPeriodData
|
|
22827
|
+
);
|
|
22828
|
+
const responseWithComparison = {
|
|
22829
|
+
reviewSource: "google_business_profile",
|
|
22830
|
+
current: currentPeriodData,
|
|
22831
|
+
previous: previousPeriodData,
|
|
22832
|
+
comparison
|
|
22833
|
+
};
|
|
22834
|
+
return responseWithComparison;
|
|
22835
|
+
}
|
|
22836
|
+
const basicResponse = {
|
|
22837
|
+
reviewSource: "google_business_profile",
|
|
22838
|
+
totalCount: currentPeriodData.totalCount,
|
|
22839
|
+
averageRating: currentPeriodData.averageRating,
|
|
22840
|
+
ratingDistribution: currentPeriodData.ratingDistribution
|
|
22841
|
+
};
|
|
22842
|
+
return basicResponse;
|
|
22843
|
+
};
|
|
22844
|
+
function generateReviewPeriodData(platformConfig, scalingFactor, isPrevious = false, isAllTime = false) {
|
|
22845
|
+
const baseMetrics = isAllTime ? getAllTimePlatformReviewMetrics(platformConfig) : getBasePlatformReviewMetrics(platformConfig);
|
|
22846
|
+
const scaledTotalCount = isAllTime ? baseMetrics.totalCount : Math.max(1, Math.round(baseMetrics.totalCount * scalingFactor));
|
|
22847
|
+
const performanceMultiplier = isPrevious ? f.number.float({ min: 0.85, max: 0.95 }) : 1;
|
|
22848
|
+
const adjustedTotalCount = Math.round(
|
|
22849
|
+
scaledTotalCount * performanceMultiplier
|
|
22850
|
+
);
|
|
22851
|
+
const adjustedAverageRating = baseMetrics.averageRating * performanceMultiplier;
|
|
22852
|
+
const ratingDistribution = generateRatingDistribution(
|
|
22853
|
+
adjustedTotalCount,
|
|
22854
|
+
adjustedAverageRating
|
|
22855
|
+
);
|
|
22856
|
+
return {
|
|
22857
|
+
totalCount: adjustedTotalCount,
|
|
22858
|
+
averageRating: parseFloat(adjustedAverageRating.toFixed(1)),
|
|
22859
|
+
ratingDistribution
|
|
22860
|
+
};
|
|
22861
|
+
}
|
|
22862
|
+
function getBasePlatformReviewMetrics(platformConfig) {
|
|
22863
|
+
const industryMultipliers = {
|
|
22864
|
+
// Pet spa industry (Goose) - high customer satisfaction
|
|
22865
|
+
"ACME Pet Spa": {
|
|
22866
|
+
totalCount: 45,
|
|
22867
|
+
averageRating: 4.6
|
|
22868
|
+
},
|
|
22869
|
+
// Equipment rental (Renterra) - moderate review volume
|
|
22870
|
+
"Tomer's Rentals": {
|
|
22871
|
+
totalCount: 28,
|
|
22872
|
+
averageRating: 4.2
|
|
22873
|
+
},
|
|
22874
|
+
// Default platform
|
|
22875
|
+
default: {
|
|
22876
|
+
totalCount: 35,
|
|
22877
|
+
averageRating: 4.3
|
|
22878
|
+
}
|
|
22879
|
+
};
|
|
22880
|
+
const baseKey = platformConfig.name in industryMultipliers ? platformConfig.name : "default";
|
|
22881
|
+
return industryMultipliers[baseKey];
|
|
22882
|
+
}
|
|
22883
|
+
function getAllTimePlatformReviewMetrics(platformConfig) {
|
|
22884
|
+
const industryMultipliers = {
|
|
22885
|
+
// Pet spa industry (Goose) - high customer satisfaction
|
|
22886
|
+
"ACME Pet Spa": {
|
|
22887
|
+
totalCount: 342,
|
|
22888
|
+
// Much higher for all-time
|
|
22889
|
+
averageRating: 4.3
|
|
22890
|
+
// Slightly lower all-time average
|
|
22891
|
+
},
|
|
22892
|
+
// Equipment rental (Renterra) - moderate review volume
|
|
22893
|
+
"Tomer's Rentals": {
|
|
22894
|
+
totalCount: 189,
|
|
22895
|
+
averageRating: 4.1
|
|
22896
|
+
},
|
|
22897
|
+
// Default platform
|
|
22898
|
+
default: {
|
|
22899
|
+
totalCount: 267,
|
|
22900
|
+
averageRating: 4.2
|
|
22901
|
+
}
|
|
22902
|
+
};
|
|
22903
|
+
const baseKey = platformConfig.name in industryMultipliers ? platformConfig.name : "default";
|
|
22904
|
+
return industryMultipliers[baseKey];
|
|
22905
|
+
}
|
|
22906
|
+
function generateRatingDistribution(totalCount, targetAverage) {
|
|
22907
|
+
const baseDistribution = {
|
|
22908
|
+
5: 0.6,
|
|
22909
|
+
// 60% 5-star
|
|
22910
|
+
4: 0.25,
|
|
22911
|
+
// 25% 4-star
|
|
22912
|
+
3: 0.1,
|
|
22913
|
+
// 10% 3-star
|
|
22914
|
+
2: 0.03,
|
|
22915
|
+
// 3% 2-star
|
|
22916
|
+
1: 0.02
|
|
22917
|
+
// 2% 1-star
|
|
22918
|
+
};
|
|
22919
|
+
const adjustedDistribution = adjustDistributionForAverage(
|
|
22920
|
+
baseDistribution,
|
|
22921
|
+
targetAverage
|
|
22922
|
+
);
|
|
22923
|
+
const distribution = [];
|
|
22924
|
+
let remainingCount = totalCount;
|
|
22925
|
+
for (let rating = 5; rating >= 2; rating--) {
|
|
22926
|
+
const percentage = adjustedDistribution[rating];
|
|
22927
|
+
const count = Math.round(totalCount * percentage);
|
|
22928
|
+
distribution.push({ rating, count });
|
|
22929
|
+
remainingCount -= count;
|
|
22930
|
+
}
|
|
22931
|
+
distribution.push({ rating: 1, count: Math.max(0, remainingCount) });
|
|
22932
|
+
return distribution.sort((a2, b2) => b2.rating - a2.rating);
|
|
22933
|
+
}
|
|
22934
|
+
function adjustDistributionForAverage(baseDistribution, targetAverage) {
|
|
22935
|
+
const adjusted = { ...baseDistribution };
|
|
22936
|
+
if (targetAverage > 4.4) {
|
|
22937
|
+
const shift = Math.min(0.1, adjusted[4] * 0.3);
|
|
22938
|
+
adjusted[5] += shift;
|
|
22939
|
+
adjusted[4] -= shift;
|
|
22940
|
+
} else if (targetAverage < 4.2) {
|
|
22941
|
+
const shift = Math.min(0.05, adjusted[5] * 0.2);
|
|
22942
|
+
adjusted[5] -= shift;
|
|
22943
|
+
adjusted[3] += shift;
|
|
22944
|
+
}
|
|
22945
|
+
return adjusted;
|
|
22946
|
+
}
|
|
22947
|
+
function calculateReviewComparison(currentPeriod, previousPeriod) {
|
|
22948
|
+
const totalCountChange = currentPeriod.totalCount - previousPeriod.totalCount;
|
|
22949
|
+
const totalCountChangePercent = previousPeriod.totalCount > 0 ? parseFloat(
|
|
22950
|
+
(totalCountChange / previousPeriod.totalCount * 100).toFixed(1)
|
|
22951
|
+
) : null;
|
|
22952
|
+
const averageRatingChange = currentPeriod.averageRating && previousPeriod.averageRating ? parseFloat(
|
|
22953
|
+
(currentPeriod.averageRating - previousPeriod.averageRating).toFixed(
|
|
22954
|
+
2
|
|
22955
|
+
)
|
|
22956
|
+
) : null;
|
|
22957
|
+
const averageRatingChangePercent = averageRatingChange && previousPeriod.averageRating ? parseFloat(
|
|
22958
|
+
(averageRatingChange / previousPeriod.averageRating * 100).toFixed(
|
|
22959
|
+
1
|
|
22960
|
+
)
|
|
22961
|
+
) : null;
|
|
22962
|
+
return {
|
|
22963
|
+
totalCountChange,
|
|
22964
|
+
totalCountChangePercent,
|
|
22965
|
+
averageRatingChange,
|
|
22966
|
+
averageRatingChangePercent
|
|
22967
|
+
};
|
|
22968
|
+
}
|
|
22969
|
+
const generateFeedbackAnalyticsData = ({
|
|
22970
|
+
platformData,
|
|
22971
|
+
queryParams
|
|
22972
|
+
}) => {
|
|
22973
|
+
const platformConfig = getPlatformConfig(
|
|
22974
|
+
platformData.businessesMe?.platform_id
|
|
22975
|
+
);
|
|
22976
|
+
const isAllTimeQuery = !queryParams.start_date || !queryParams.end_date;
|
|
22977
|
+
let scalingFactor = 1;
|
|
22978
|
+
if (!isAllTimeQuery) {
|
|
22979
|
+
const { requestedDays } = parseDateRange(
|
|
22980
|
+
queryParams.start_date || null,
|
|
22981
|
+
queryParams.end_date || null,
|
|
22982
|
+
30
|
|
22983
|
+
);
|
|
22984
|
+
const basePeriodDays = 30;
|
|
22985
|
+
scalingFactor = requestedDays / basePeriodDays;
|
|
22986
|
+
}
|
|
22987
|
+
const currentPeriodData = generateFeedbackPeriodData(
|
|
22988
|
+
platformConfig,
|
|
22989
|
+
scalingFactor,
|
|
22990
|
+
false,
|
|
22991
|
+
isAllTimeQuery
|
|
22992
|
+
);
|
|
22993
|
+
if (queryParams.include_comparison) {
|
|
22994
|
+
const previousPeriodData = generateFeedbackPeriodData(
|
|
22995
|
+
platformConfig,
|
|
22996
|
+
scalingFactor,
|
|
22997
|
+
true,
|
|
22998
|
+
isAllTimeQuery
|
|
22999
|
+
);
|
|
23000
|
+
const comparison = calculateFeedbackComparison(
|
|
23001
|
+
currentPeriodData,
|
|
23002
|
+
previousPeriodData
|
|
23003
|
+
);
|
|
23004
|
+
const responseWithComparison = {
|
|
23005
|
+
current: currentPeriodData,
|
|
23006
|
+
previous: previousPeriodData,
|
|
23007
|
+
comparison
|
|
23008
|
+
};
|
|
23009
|
+
return responseWithComparison;
|
|
23010
|
+
}
|
|
23011
|
+
const basicResponse = {
|
|
23012
|
+
totalSent: currentPeriodData.totalSent,
|
|
23013
|
+
totalResponded: currentPeriodData.totalResponded,
|
|
23014
|
+
averageRating: currentPeriodData.averageRating,
|
|
23015
|
+
responseRate: currentPeriodData.responseRate,
|
|
23016
|
+
positiveResponses: currentPeriodData.positiveResponses,
|
|
23017
|
+
negativeResponses: currentPeriodData.negativeResponses
|
|
23018
|
+
};
|
|
23019
|
+
return basicResponse;
|
|
23020
|
+
};
|
|
23021
|
+
function generateFeedbackPeriodData(platformConfig, scalingFactor, isPrevious = false, isAllTime = false) {
|
|
23022
|
+
const baseMetrics = isAllTime ? getAllTimePlatformFeedbackMetrics(platformConfig) : getBasePlatformFeedbackMetrics(platformConfig);
|
|
23023
|
+
const scaledTotalSent = isAllTime ? baseMetrics.totalSent : Math.max(1, Math.round(baseMetrics.totalSent * scalingFactor));
|
|
23024
|
+
const performanceMultiplier = isPrevious ? f.number.float({ min: 0.88, max: 0.95 }) : 1;
|
|
23025
|
+
const adjustedTotalSent = Math.round(scaledTotalSent * performanceMultiplier);
|
|
23026
|
+
const responseRate = baseMetrics.responseRate * performanceMultiplier;
|
|
23027
|
+
const totalResponded = Math.round(adjustedTotalSent * (responseRate / 100));
|
|
23028
|
+
const positiveRate = baseMetrics.positiveRate * performanceMultiplier;
|
|
23029
|
+
const positiveResponses = Math.round(totalResponded * positiveRate);
|
|
23030
|
+
const negativeResponses = totalResponded - positiveResponses;
|
|
23031
|
+
const averageRating = calculateAverageFromSentiment(
|
|
23032
|
+
positiveResponses,
|
|
23033
|
+
negativeResponses
|
|
23034
|
+
);
|
|
23035
|
+
return {
|
|
23036
|
+
totalSent: adjustedTotalSent,
|
|
23037
|
+
totalResponded,
|
|
23038
|
+
averageRating: parseFloat(averageRating.toFixed(1)),
|
|
23039
|
+
responseRate: parseFloat(responseRate.toFixed(1)),
|
|
23040
|
+
positiveResponses,
|
|
23041
|
+
negativeResponses
|
|
23042
|
+
};
|
|
23043
|
+
}
|
|
23044
|
+
function getBasePlatformFeedbackMetrics(platformConfig) {
|
|
23045
|
+
const industryMultipliers = {
|
|
23046
|
+
// Pet spa industry (Goose) - high engagement, positive feedback
|
|
23047
|
+
"ACME Pet Spa": {
|
|
23048
|
+
totalSent: 85,
|
|
23049
|
+
responseRate: 42,
|
|
23050
|
+
// 42% response rate
|
|
23051
|
+
positiveRate: 0.78
|
|
23052
|
+
// 78% positive
|
|
23053
|
+
},
|
|
23054
|
+
// Equipment rental (Renterra) - moderate engagement
|
|
23055
|
+
"Tomer's Rentals": {
|
|
23056
|
+
totalSent: 65,
|
|
23057
|
+
responseRate: 35,
|
|
23058
|
+
// 35% response rate
|
|
23059
|
+
positiveRate: 0.72
|
|
23060
|
+
// 72% positive
|
|
23061
|
+
},
|
|
23062
|
+
// Default platform
|
|
23063
|
+
default: {
|
|
23064
|
+
totalSent: 75,
|
|
23065
|
+
responseRate: 38,
|
|
23066
|
+
// 38% response rate
|
|
23067
|
+
positiveRate: 0.75
|
|
23068
|
+
// 75% positive
|
|
23069
|
+
}
|
|
23070
|
+
};
|
|
23071
|
+
const baseKey = platformConfig.name in industryMultipliers ? platformConfig.name : "default";
|
|
23072
|
+
return industryMultipliers[baseKey];
|
|
23073
|
+
}
|
|
23074
|
+
function getAllTimePlatformFeedbackMetrics(platformConfig) {
|
|
23075
|
+
const industryMultipliers = {
|
|
23076
|
+
// Pet spa industry (Goose) - high engagement, positive feedback
|
|
23077
|
+
"ACME Pet Spa": {
|
|
23078
|
+
totalSent: 1247,
|
|
23079
|
+
// Much higher for all-time
|
|
23080
|
+
responseRate: 39,
|
|
23081
|
+
// Slightly lower all-time response rate
|
|
23082
|
+
positiveRate: 0.76
|
|
23083
|
+
// Slightly lower positive rate
|
|
23084
|
+
},
|
|
23085
|
+
// Equipment rental (Renterra) - moderate engagement
|
|
23086
|
+
"Tomer's Rentals": {
|
|
23087
|
+
totalSent: 892,
|
|
23088
|
+
responseRate: 33,
|
|
23089
|
+
positiveRate: 0.7
|
|
23090
|
+
},
|
|
23091
|
+
// Default platform
|
|
23092
|
+
default: {
|
|
23093
|
+
totalSent: 1089,
|
|
23094
|
+
responseRate: 36,
|
|
23095
|
+
positiveRate: 0.73
|
|
23096
|
+
}
|
|
23097
|
+
};
|
|
23098
|
+
const baseKey = platformConfig.name in industryMultipliers ? platformConfig.name : "default";
|
|
23099
|
+
return industryMultipliers[baseKey];
|
|
23100
|
+
}
|
|
23101
|
+
function calculateAverageFromSentiment(positiveCount, negativeCount) {
|
|
23102
|
+
if (positiveCount === 0 && negativeCount === 0) {
|
|
23103
|
+
return 0;
|
|
23104
|
+
}
|
|
23105
|
+
const positiveAverage = 4.3;
|
|
23106
|
+
const negativeAverage = 1.8;
|
|
23107
|
+
const totalResponses = positiveCount + negativeCount;
|
|
23108
|
+
const weightedSum = positiveCount * positiveAverage + negativeCount * negativeAverage;
|
|
23109
|
+
return weightedSum / totalResponses;
|
|
23110
|
+
}
|
|
23111
|
+
function calculateFeedbackComparison(currentPeriod, previousPeriod) {
|
|
23112
|
+
const totalSentChange = currentPeriod.totalSent - previousPeriod.totalSent;
|
|
23113
|
+
const totalSentChangePercent = previousPeriod.totalSent > 0 ? parseFloat(
|
|
23114
|
+
(totalSentChange / previousPeriod.totalSent * 100).toFixed(1)
|
|
23115
|
+
) : null;
|
|
23116
|
+
const totalRespondedChange = currentPeriod.totalResponded - previousPeriod.totalResponded;
|
|
23117
|
+
const totalRespondedChangePercent = previousPeriod.totalResponded > 0 ? parseFloat(
|
|
23118
|
+
(totalRespondedChange / previousPeriod.totalResponded * 100).toFixed(1)
|
|
23119
|
+
) : null;
|
|
23120
|
+
const averageRatingChange = currentPeriod.averageRating && previousPeriod.averageRating ? parseFloat(
|
|
23121
|
+
(currentPeriod.averageRating - previousPeriod.averageRating).toFixed(
|
|
23122
|
+
2
|
|
23123
|
+
)
|
|
23124
|
+
) : null;
|
|
23125
|
+
const averageRatingChangePercent = averageRatingChange && previousPeriod.averageRating ? parseFloat(
|
|
23126
|
+
(averageRatingChange / previousPeriod.averageRating * 100).toFixed(
|
|
23127
|
+
1
|
|
23128
|
+
)
|
|
23129
|
+
) : null;
|
|
23130
|
+
const responseRateChange = currentPeriod.responseRate - previousPeriod.responseRate;
|
|
23131
|
+
const responseRateChangePercent = previousPeriod.responseRate > 0 ? parseFloat(
|
|
23132
|
+
(responseRateChange / previousPeriod.responseRate * 100).toFixed(1)
|
|
23133
|
+
) : null;
|
|
23134
|
+
return {
|
|
23135
|
+
totalSentChange,
|
|
23136
|
+
totalSentChangePercent,
|
|
23137
|
+
totalRespondedChange,
|
|
23138
|
+
totalRespondedChangePercent,
|
|
23139
|
+
averageRatingChange,
|
|
23140
|
+
averageRatingChangePercent,
|
|
23141
|
+
responseRateChange: parseFloat(responseRateChange.toFixed(1)),
|
|
23142
|
+
responseRateChangePercent
|
|
23143
|
+
};
|
|
23144
|
+
}
|
|
23145
|
+
const mockStore = {
|
|
23146
|
+
reputationConfig: null
|
|
23147
|
+
};
|
|
23148
|
+
const reputationHandlers = [
|
|
23149
|
+
// External OAuth - GBP Connection
|
|
23150
|
+
http.get(`${HOSTNAME}/api/external-oauth/gbp`, () => {
|
|
23151
|
+
const platformData = getSandboxDataForPlatform(currentSandboxPlatformId);
|
|
23152
|
+
return HttpResponse.json({
|
|
23153
|
+
success: true,
|
|
23154
|
+
message: "Success (Sandbox)",
|
|
23155
|
+
data: platformData.reputationData?.gbpConnection || null
|
|
23156
|
+
});
|
|
23157
|
+
}),
|
|
23158
|
+
// Partner Locations
|
|
23159
|
+
http.get(`${HOSTNAME}/api/partner-locations`, () => {
|
|
23160
|
+
const platformData = getSandboxDataForPlatform(currentSandboxPlatformId);
|
|
23161
|
+
return HttpResponse.json({
|
|
23162
|
+
success: true,
|
|
23163
|
+
message: "Success (Sandbox)",
|
|
23164
|
+
data: {
|
|
23165
|
+
locations: platformData.reputationData?.partnerLocations || []
|
|
23166
|
+
}
|
|
23167
|
+
});
|
|
23168
|
+
}),
|
|
23169
|
+
// Channel Senders
|
|
23170
|
+
http.get(`${HOSTNAME}/api/channel/senders`, () => {
|
|
23171
|
+
const platformData = getSandboxDataForPlatform(currentSandboxPlatformId);
|
|
23172
|
+
return HttpResponse.json({
|
|
23173
|
+
success: true,
|
|
23174
|
+
message: "Success (Sandbox)",
|
|
23175
|
+
data: {
|
|
23176
|
+
results: platformData.reputationData?.channelSenders || []
|
|
23177
|
+
}
|
|
23178
|
+
});
|
|
23179
|
+
}),
|
|
23180
|
+
// Channel Accounts
|
|
23181
|
+
http.get(`${HOSTNAME}/api/channel/accounts`, () => {
|
|
23182
|
+
const platformData = getSandboxDataForPlatform(currentSandboxPlatformId);
|
|
23183
|
+
return HttpResponse.json({
|
|
23184
|
+
success: true,
|
|
23185
|
+
message: "Success (Sandbox)",
|
|
23186
|
+
data: {
|
|
23187
|
+
results: platformData.reputationData?.channelAccounts || []
|
|
23188
|
+
}
|
|
23189
|
+
});
|
|
23190
|
+
}),
|
|
23191
|
+
// Reputation Config
|
|
23192
|
+
http.get(`${HOSTNAME}/api/reputation/config`, () => {
|
|
23193
|
+
if (mockStore.reputationConfig) {
|
|
23194
|
+
const response2 = {
|
|
23195
|
+
success: true,
|
|
23196
|
+
message: "Success (Sandbox)",
|
|
23197
|
+
data: mockStore.reputationConfig
|
|
23198
|
+
};
|
|
23199
|
+
return HttpResponse.json(response2);
|
|
23200
|
+
}
|
|
23201
|
+
const platformData = getSandboxDataForPlatform(currentSandboxPlatformId);
|
|
23202
|
+
const initialConfig = platformData.reputationData?.reputationConfig || null;
|
|
23203
|
+
mockStore.reputationConfig = initialConfig;
|
|
23204
|
+
const response = {
|
|
23205
|
+
success: true,
|
|
23206
|
+
message: "Success (Sandbox)",
|
|
23207
|
+
data: initialConfig
|
|
23208
|
+
};
|
|
23209
|
+
return HttpResponse.json(response);
|
|
23210
|
+
}),
|
|
23211
|
+
http.post(`${HOSTNAME}/api/reputation/config`, async ({ request }) => {
|
|
23212
|
+
const body = await request.json();
|
|
23213
|
+
const currentConfig = mockStore.reputationConfig || getSandboxDataForPlatform(currentSandboxPlatformId).reputationData?.reputationConfig;
|
|
23214
|
+
if (currentConfig) {
|
|
23215
|
+
const updatedConfig = {
|
|
23216
|
+
...currentConfig,
|
|
23217
|
+
locationMappings: body.locationMappings || currentConfig.locationMappings,
|
|
23218
|
+
emailChannelSenderId: body.emailChannelSenderId,
|
|
23219
|
+
smsChannelSenderId: body.smsChannelSenderId,
|
|
23220
|
+
completedOnboardingAt: body.completedOnboardingAt,
|
|
23221
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
23222
|
+
};
|
|
23223
|
+
mockStore.reputationConfig = updatedConfig;
|
|
23224
|
+
}
|
|
23225
|
+
const response = {
|
|
23226
|
+
success: true,
|
|
23227
|
+
message: "Configuration updated successfully (Sandbox)",
|
|
23228
|
+
data: mockStore.reputationConfig
|
|
23229
|
+
};
|
|
23230
|
+
return HttpResponse.json(response);
|
|
23231
|
+
}),
|
|
23232
|
+
// SMS Registration Application
|
|
23233
|
+
http.get(`${HOSTNAME}/api/sms-registration/application/latest`, () => {
|
|
23234
|
+
const platformData = getSandboxDataForPlatform(currentSandboxPlatformId);
|
|
23235
|
+
return HttpResponse.json({
|
|
23236
|
+
success: true,
|
|
23237
|
+
message: "Success (Sandbox)",
|
|
23238
|
+
data: platformData.reputationData?.smsApplication || {
|
|
23239
|
+
application: null,
|
|
23240
|
+
status: null,
|
|
23241
|
+
id: null
|
|
23242
|
+
}
|
|
23243
|
+
});
|
|
23244
|
+
}),
|
|
23245
|
+
http.get(`${HOSTNAME}/api/sms-registration/`, () => {
|
|
23246
|
+
const platformData = getSandboxDataForPlatform(currentSandboxPlatformId);
|
|
23247
|
+
return HttpResponse.json({
|
|
23248
|
+
success: true,
|
|
23249
|
+
message: "Success (Sandbox)",
|
|
23250
|
+
data: platformData.reputationData?.smsApplication || {
|
|
23251
|
+
application: null,
|
|
23252
|
+
status: null,
|
|
23253
|
+
id: null
|
|
23254
|
+
}
|
|
23255
|
+
});
|
|
23256
|
+
}),
|
|
23257
|
+
http.post(`${HOSTNAME}/api/sms-registration/`, async () => {
|
|
23258
|
+
return HttpResponse.json({
|
|
23259
|
+
success: true,
|
|
23260
|
+
message: "SMS application submitted successfully (Sandbox)",
|
|
23261
|
+
data: {
|
|
23262
|
+
status: "pending"
|
|
23263
|
+
}
|
|
23264
|
+
});
|
|
23265
|
+
}),
|
|
23266
|
+
// OAuth GBP Connection (additional endpoint for available accounts)
|
|
23267
|
+
http.get(`${HOSTNAME}/api/oauth/gbp/available-accounts`, () => {
|
|
23268
|
+
const platformData = getSandboxDataForPlatform(currentSandboxPlatformId);
|
|
23269
|
+
const gbpConnection = platformData.reputationData?.gbpConnection;
|
|
23270
|
+
if (gbpConnection?.metadata?.selectedAccount) {
|
|
23271
|
+
return HttpResponse.json({
|
|
23272
|
+
success: true,
|
|
23273
|
+
message: "Success (Sandbox)",
|
|
23274
|
+
data: {
|
|
23275
|
+
accounts: [
|
|
23276
|
+
{
|
|
23277
|
+
...gbpConnection.metadata.selectedAccount,
|
|
23278
|
+
locations: gbpConnection.metadata.selectedLocations?.map(
|
|
23279
|
+
(loc) => ({
|
|
23280
|
+
name: loc.name,
|
|
23281
|
+
title: loc.title,
|
|
23282
|
+
storefrontAddress: {
|
|
23283
|
+
locality: loc.address?.split(",")[0] || "",
|
|
23284
|
+
administrativeArea: loc.address?.split(",")[1]?.trim() || ""
|
|
23285
|
+
},
|
|
23286
|
+
phoneNumbers: {
|
|
23287
|
+
primaryPhone: loc.phone
|
|
23288
|
+
},
|
|
23289
|
+
locationState: loc.locationState
|
|
23290
|
+
})
|
|
23291
|
+
) || []
|
|
23292
|
+
}
|
|
23293
|
+
]
|
|
23294
|
+
}
|
|
23295
|
+
});
|
|
23296
|
+
}
|
|
23297
|
+
return HttpResponse.json({
|
|
23298
|
+
success: true,
|
|
23299
|
+
message: "Success (Sandbox)",
|
|
23300
|
+
data: {
|
|
23301
|
+
accounts: []
|
|
23302
|
+
}
|
|
23303
|
+
});
|
|
23304
|
+
}),
|
|
23305
|
+
// OAuth GBP Connection Status
|
|
23306
|
+
http.get(`${HOSTNAME}/api/oauth/gbp/connection`, () => {
|
|
23307
|
+
const platformData = getSandboxDataForPlatform(currentSandboxPlatformId);
|
|
23308
|
+
return HttpResponse.json({
|
|
23309
|
+
success: true,
|
|
23310
|
+
message: "Success (Sandbox)",
|
|
23311
|
+
data: platformData.reputationData?.gbpConnection || null
|
|
23312
|
+
});
|
|
23313
|
+
}),
|
|
23314
|
+
// Business Branding Update (used in preview step)
|
|
23315
|
+
http.put(`${HOSTNAME}/api/businesses/me`, async ({ request }) => {
|
|
23316
|
+
const body = await request.json();
|
|
23317
|
+
const platformData = getSandboxDataForPlatform(currentSandboxPlatformId);
|
|
23318
|
+
const existingBusiness = platformData.businessesMe;
|
|
23319
|
+
const updatedBranding = {
|
|
23320
|
+
...existingBusiness?.branding,
|
|
23321
|
+
...body?.branding
|
|
23322
|
+
};
|
|
23323
|
+
return HttpResponse.json({
|
|
23324
|
+
success: true,
|
|
23325
|
+
message: "Branding updated successfully (Sandbox)",
|
|
23326
|
+
data: {
|
|
23327
|
+
...existingBusiness,
|
|
23328
|
+
name: body?.name || existingBusiness?.name || "Updated Brand",
|
|
23329
|
+
branding: updatedBranding
|
|
23330
|
+
}
|
|
23331
|
+
});
|
|
23332
|
+
}),
|
|
23333
|
+
// Reputation Responses (unified reviews and internal feedback)
|
|
23334
|
+
http.get(`${HOSTNAME}/api/reputation/responses`, ({ request }) => {
|
|
23335
|
+
const url = new URL(request.url);
|
|
23336
|
+
const startDate = url.searchParams.get("start_date");
|
|
23337
|
+
const endDate = url.searchParams.get("end_date");
|
|
23338
|
+
const locationIds = url.searchParams.getAll("location_ids");
|
|
23339
|
+
const cursor = url.searchParams.get("cursor");
|
|
23340
|
+
const limit = parseInt(url.searchParams.get("limit") || "25", 10);
|
|
23341
|
+
const searchTerm = url.searchParams.get("search_term");
|
|
23342
|
+
const platformData = getSandboxDataForPlatform(currentSandboxPlatformId);
|
|
23343
|
+
const responsesData = generateReputationResponsesData({
|
|
23344
|
+
platformData,
|
|
23345
|
+
startDate,
|
|
23346
|
+
endDate,
|
|
23347
|
+
locationIds,
|
|
23348
|
+
cursor,
|
|
23349
|
+
limit,
|
|
23350
|
+
searchTerm
|
|
23351
|
+
});
|
|
23352
|
+
return HttpResponse.json({
|
|
23353
|
+
success: true,
|
|
23354
|
+
message: "Success (Sandbox)",
|
|
23355
|
+
data: responsesData
|
|
23356
|
+
});
|
|
23357
|
+
}),
|
|
23358
|
+
// Review Analytics
|
|
23359
|
+
http.get(`${HOSTNAME}/api/reviews/analytics`, ({ request }) => {
|
|
23360
|
+
const url = new URL(request.url);
|
|
23361
|
+
const startDate = url.searchParams.get("start_date");
|
|
23362
|
+
const endDate = url.searchParams.get("end_date");
|
|
23363
|
+
const locationIds = url.searchParams.get("location_ids");
|
|
23364
|
+
const includeComparison = url.searchParams.get("include_comparison") === "true";
|
|
23365
|
+
const platformData = getSandboxDataForPlatform(currentSandboxPlatformId);
|
|
23366
|
+
const queryParams = {
|
|
23367
|
+
start_date: startDate || void 0,
|
|
23368
|
+
end_date: endDate || void 0,
|
|
23369
|
+
location_ids: locationIds ? locationIds.split(",").filter(Boolean) : void 0,
|
|
23370
|
+
include_comparison: includeComparison
|
|
23371
|
+
};
|
|
23372
|
+
const analyticsData = generateReviewAnalyticsData({
|
|
23373
|
+
platformData,
|
|
23374
|
+
queryParams
|
|
23375
|
+
});
|
|
23376
|
+
return HttpResponse.json({
|
|
23377
|
+
success: true,
|
|
23378
|
+
message: "Success (Sandbox)",
|
|
23379
|
+
data: analyticsData
|
|
23380
|
+
});
|
|
23381
|
+
}),
|
|
23382
|
+
// Feedback Analytics
|
|
23383
|
+
http.get(`${HOSTNAME}/api/feedback/analytics`, ({ request }) => {
|
|
23384
|
+
const url = new URL(request.url);
|
|
23385
|
+
const startDate = url.searchParams.get("start_date");
|
|
23386
|
+
const endDate = url.searchParams.get("end_date");
|
|
23387
|
+
const includeComparison = url.searchParams.get("include_comparison") === "true";
|
|
23388
|
+
const platformData = getSandboxDataForPlatform(currentSandboxPlatformId);
|
|
23389
|
+
const queryParams = {
|
|
23390
|
+
include_comparison: includeComparison
|
|
23391
|
+
};
|
|
23392
|
+
if (startDate) {
|
|
23393
|
+
queryParams.start_date = startDate;
|
|
23394
|
+
}
|
|
23395
|
+
if (endDate) {
|
|
23396
|
+
queryParams.end_date = endDate;
|
|
23397
|
+
}
|
|
23398
|
+
const analyticsData = generateFeedbackAnalyticsData({
|
|
23399
|
+
platformData,
|
|
23400
|
+
queryParams
|
|
23401
|
+
});
|
|
23402
|
+
return HttpResponse.json({
|
|
23403
|
+
success: true,
|
|
23404
|
+
message: "Success (Sandbox)",
|
|
23405
|
+
data: analyticsData
|
|
23406
|
+
});
|
|
23407
|
+
})
|
|
23408
|
+
];
|
|
23409
|
+
const getHandlersByFeatures = (features) => {
|
|
23410
|
+
const allHandlers = [];
|
|
23411
|
+
if (features.includes("all")) {
|
|
23412
|
+
return [...measureAndAcquireHandlers, ...reputationHandlers];
|
|
23413
|
+
}
|
|
23414
|
+
if (features.includes("measure") || features.includes("acquire")) {
|
|
23415
|
+
allHandlers.push(...measureAndAcquireHandlers);
|
|
23416
|
+
}
|
|
23417
|
+
if (features.includes("reputation")) {
|
|
23418
|
+
allHandlers.push(...reputationHandlers);
|
|
23419
|
+
}
|
|
23420
|
+
return allHandlers;
|
|
23421
|
+
};
|
|
23422
|
+
getHandlersByFeatures(["all"]);
|
|
23423
|
+
let currentWorker = setupWorker(...getHandlersByFeatures(["all"]));
|
|
22839
23424
|
const MAX_RETRIES = 3;
|
|
22840
23425
|
const RETRY_DELAY = 1e3;
|
|
22841
23426
|
const START_TIMEOUT = 5e3;
|
|
22842
|
-
async function startWorkerWithRetry(attempt = 1, debug = false, isIframe = false) {
|
|
23427
|
+
async function startWorkerWithRetry(attempt = 1, debug = false, isIframe = false, workerInstance = currentWorker) {
|
|
22843
23428
|
try {
|
|
22844
23429
|
if (debug) {
|
|
22845
23430
|
console.log(`[ REACH ] Starting MSW worker (attempt ${attempt})...`);
|
|
@@ -22852,7 +23437,7 @@ async function startWorkerWithRetry(attempt = 1, debug = false, isIframe = false
|
|
|
22852
23437
|
const workerUrl = isIframe ? "/iframe/app/mockServiceWorker.js" : "/mockServiceWorker.js";
|
|
22853
23438
|
const workerScope = isIframe ? "/iframe/app/" : "/";
|
|
22854
23439
|
await Promise.race([
|
|
22855
|
-
|
|
23440
|
+
workerInstance.start({
|
|
22856
23441
|
quiet: true,
|
|
22857
23442
|
serviceWorker: {
|
|
22858
23443
|
url: workerUrl,
|
|
@@ -22884,16 +23469,18 @@ async function startWorkerWithRetry(attempt = 1, debug = false, isIframe = false
|
|
|
22884
23469
|
console.log(`[ REACH ] Retrying in ${RETRY_DELAY}ms...`);
|
|
22885
23470
|
}
|
|
22886
23471
|
await new Promise((resolve) => setTimeout(resolve, RETRY_DELAY));
|
|
22887
|
-
return startWorkerWithRetry(attempt + 1, debug, isIframe);
|
|
23472
|
+
return startWorkerWithRetry(attempt + 1, debug, isIframe, workerInstance);
|
|
22888
23473
|
}
|
|
22889
23474
|
throw error2;
|
|
22890
23475
|
}
|
|
22891
23476
|
}
|
|
22892
|
-
async function startSandboxMSW(platformIdToSimulate, debug = false, isIframe = false) {
|
|
23477
|
+
async function startSandboxMSW(platformIdToSimulate, debug = false, isIframe = false, features = ["all"]) {
|
|
22893
23478
|
if (debug) {
|
|
22894
23479
|
console.log("[ REACH ] Initializing sandbox mode...");
|
|
23480
|
+
console.log(`[ REACH ] Features enabled: ${features.join(", ")}`);
|
|
22895
23481
|
}
|
|
22896
23482
|
setMSWSandboxPlatformId(platformIdToSimulate);
|
|
23483
|
+
const featureWorker = setupWorker(...getHandlersByFeatures(features));
|
|
22897
23484
|
if (document.readyState !== "complete") {
|
|
22898
23485
|
if (debug) {
|
|
22899
23486
|
console.log("[ REACH ] Waiting for document to be ready...");
|
|
@@ -22903,7 +23490,7 @@ async function startSandboxMSW(platformIdToSimulate, debug = false, isIframe = f
|
|
|
22903
23490
|
});
|
|
22904
23491
|
}
|
|
22905
23492
|
try {
|
|
22906
|
-
await startWorkerWithRetry(1, debug, isIframe);
|
|
23493
|
+
await startWorkerWithRetry(1, debug, isIframe, featureWorker);
|
|
22907
23494
|
} catch (error2) {
|
|
22908
23495
|
if (debug) {
|
|
22909
23496
|
console.error(
|
|
@@ -22912,7 +23499,7 @@ async function startSandboxMSW(platformIdToSimulate, debug = false, isIframe = f
|
|
|
22912
23499
|
);
|
|
22913
23500
|
}
|
|
22914
23501
|
try {
|
|
22915
|
-
await
|
|
23502
|
+
await featureWorker.stop();
|
|
22916
23503
|
} catch (stopError) {
|
|
22917
23504
|
if (debug) {
|
|
22918
23505
|
console.error("[ REACH ] Failed to stop MSW worker:", stopError);
|
|
@@ -22953,7 +23540,7 @@ const useMswSandbox = ({
|
|
|
22953
23540
|
useEffect(() => {
|
|
22954
23541
|
return () => {
|
|
22955
23542
|
if (mswInitialized) {
|
|
22956
|
-
|
|
23543
|
+
currentWorker.stop();
|
|
22957
23544
|
if (debug)
|
|
22958
23545
|
console.log("[MSW Sandbox] Component unmounted, MSW stopped");
|
|
22959
23546
|
}
|