@wrangled/cli 0.3.0 → 0.3.2
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/dlc-map-example.js +4 -4
- package/dist/main.js +11 -1
- package/dist/playbooks.js +2 -2
- package/package.json +1 -1
package/dist/dlc-map-example.js
CHANGED
|
@@ -47,11 +47,11 @@ export const dlcExampleMap = {
|
|
|
47
47
|
delivery: "event",
|
|
48
48
|
price: 3497,
|
|
49
49
|
currency: "USD",
|
|
50
|
-
price_note: "GA $3,497 (some $3,597); VIP upgrade +$597; guest $497; guest VIP $397.
|
|
50
|
+
price_note: "GA $3,497 (some $3,597); VIP upgrade +$597; guest $497; guest VIP $397.",
|
|
51
51
|
stack_position: 5,
|
|
52
52
|
matches: [
|
|
53
|
-
{ platform: "ghl", match_type: "
|
|
54
|
-
{ platform: "ghl", match_type: "
|
|
53
|
+
{ platform: "ghl", match_type: "name_starts_with", value: "OWL" },
|
|
54
|
+
{ platform: "ghl", match_type: "name_starts_with", value: "OCA" },
|
|
55
55
|
],
|
|
56
56
|
},
|
|
57
57
|
{
|
|
@@ -63,7 +63,7 @@ export const dlcExampleMap = {
|
|
|
63
63
|
currency: "USD",
|
|
64
64
|
price_note: "financed: full pay, or a deposit then financing payments",
|
|
65
65
|
stack_position: 6,
|
|
66
|
-
matches: [{ platform: "ghl", match_type: "
|
|
66
|
+
matches: [{ platform: "ghl", match_type: "name_starts_with", value: "Protege" }],
|
|
67
67
|
},
|
|
68
68
|
],
|
|
69
69
|
funnels: [
|
package/dist/main.js
CHANGED
|
@@ -126,6 +126,7 @@ const commands = {
|
|
|
126
126
|
if (options.format === "json")
|
|
127
127
|
return printJson({ funnel });
|
|
128
128
|
printReport(`Funnel by ${funnel.grain}`, funnel, ["period", "currency"], FUNNEL_NUMBERS);
|
|
129
|
+
printLeftOut(funnel.left_out, "sales, revenue_net and roas");
|
|
129
130
|
},
|
|
130
131
|
},
|
|
131
132
|
money: {
|
|
@@ -145,6 +146,7 @@ const commands = {
|
|
|
145
146
|
}
|
|
146
147
|
if (money.refund_days.length > 0)
|
|
147
148
|
console.log(`\nBiggest refund days:\n${renderTable(["date", "currency", "refunds"], money.refund_days)}`);
|
|
149
|
+
printLeftOut(money.left_out, "roas (net still counts it)");
|
|
148
150
|
},
|
|
149
151
|
},
|
|
150
152
|
campaigns: {
|
|
@@ -158,6 +160,7 @@ const commands = {
|
|
|
158
160
|
return printJson({ campaignResults });
|
|
159
161
|
const title = campaignResults.channel === null ? "Campaigns, best first" : `${campaignResults.channel} campaigns, best first`;
|
|
160
162
|
printReport(title, campaignResults, ["channel", "campaign_id", "campaign_name", "currency"], CAMPAIGN_NUMBERS);
|
|
163
|
+
printLeftOut(campaignResults.left_out, "the totals (the rows keep it)");
|
|
161
164
|
},
|
|
162
165
|
},
|
|
163
166
|
"tools list": {
|
|
@@ -1067,7 +1070,7 @@ const commands = {
|
|
|
1067
1070
|
const { fact } = await api(await resolveConnection(options.apiUrl), `${FACTS_PATH}/${encodeURIComponent(args[0])}`);
|
|
1068
1071
|
if (options.format === "json")
|
|
1069
1072
|
return printJson({ fact });
|
|
1070
|
-
printFields({ ...factRow(fact), summary: fact.summary, value: fact.value, evidence: fact.evidence, author: fact.author, "confirmed by": fact.confirmedBy, replaces: fact.replaces });
|
|
1073
|
+
printFields({ ...factRow(fact), summary: fact.summary, value: fact.value, evidence: fact.evidence, author: fact.author, "confirmed by": fact.confirmedBy, "decided by": fact.decidedBy, replaces: fact.replaces });
|
|
1071
1074
|
},
|
|
1072
1075
|
},
|
|
1073
1076
|
"facts propose": {
|
|
@@ -1447,6 +1450,13 @@ function reportQuery(options, extra) {
|
|
|
1447
1450
|
return query.size ? `?${query}` : "";
|
|
1448
1451
|
}
|
|
1449
1452
|
/** The rows, then the totals, which are one row per currency. */
|
|
1453
|
+
/** What confirmed leave-out rules took out of `figures`, one line per rule and currency. */
|
|
1454
|
+
function printLeftOut(leftOut, figures) {
|
|
1455
|
+
if (!leftOut?.length)
|
|
1456
|
+
return;
|
|
1457
|
+
const rows = leftOut.flatMap((l) => l.amounts.map((a) => ({ fact: l.fact_id, currency: a.currency, revenue: a.revenue, sales: a.sales, rule: l.summary })));
|
|
1458
|
+
console.log(`\nLeft out of ${figures} by confirmed leave-out rules:\n${renderTable(["fact", "currency", "revenue", "sales", "rule"], rows)}`);
|
|
1459
|
+
}
|
|
1450
1460
|
function printReport(title, report, labels, numbers) {
|
|
1451
1461
|
if (report.rows.length === 0)
|
|
1452
1462
|
return console.log(`No numbers from ${report.from} to ${report.to}.`);
|
package/dist/playbooks.js
CHANGED
|
@@ -621,8 +621,8 @@ Start from the shape that fits, then rename and add steps to match what you read
|
|
|
621
621
|
|
|
622
622
|
Write \`map.json\` as \`{"offers": [...], "funnels": [...]}\`, in this order.
|
|
623
623
|
|
|
624
|
-
1. **Offers**, front end first, numbered by \`stack_position\` from 1. Each has an \`offer_key\` (lowercase, digits and underscores), \`name\`, \`tier\` (\`front_end\` or \`back_end\`), \`delivery\` (course, event, coaching, service, product, membership, webinar, lead_magnet or other), \`price\`, \`currency\`, an optional \`price_note\` (plain words on the price: other prices, payment plans, doubts), and \`matches\`: how a sale is recognised. A match is \`{"platform": ..., "match_type": ..., "value": "..."}\`: platform \`stripe\`, \`ghl\` or \`shopify\`, and match_type \`product_id\`, \`price_id\`, \`amount\` (whole units, with a \`currency\`)
|
|
625
|
-
- **Price.** A free webinar's \`price\` is 0 when its page or GoHighLevel says it is free. When GoHighLevel and Stripe both show a sale, \`price\` is the GoHighLevel price that names the product, \`price_note\` gives the Stripe amount, and the offer matches both:
|
|
624
|
+
1. **Offers**, front end first, numbered by \`stack_position\` from 1. Each has an \`offer_key\` (lowercase, digits and underscores), \`name\`, \`tier\` (\`front_end\` or \`back_end\`), \`delivery\` (course, event, coaching, service, product, membership, webinar, lead_magnet or other), \`price\`, \`currency\`, an optional \`price_note\` (plain words on the price: other prices, payment plans, doubts), and \`matches\`: how a sale is recognised. A match is \`{"platform": ..., "match_type": ..., "value": "..."}\`: platform \`stripe\`, \`ghl\` or \`shopify\`, and match_type \`product_id\`, \`price_id\`, \`amount\` (whole units, with a \`currency\`), \`name_contains\` (any part of the product's name, ignoring case) or \`name_starts_with\` (the start of the product's name, ignoring case). Use \`name_starts_with\` for a family of products whose names begin with one code, such as event tickets named "OCA Dallas" and "OCA Austin"; \`name_contains\` "OCA" would also catch "Local Coaching". Stripe charges carry no product, so match them by \`amount\`. Prefer a GoHighLevel or Shopify name match on the product's name when one price is shared by two offers, as a $497 bump and a $497 guest ticket can be. An offer nobody pays for, such as a free webinar, may have no \`matches\`.
|
|
625
|
+
- **Price.** A free webinar's \`price\` is 0 when its page or GoHighLevel says it is free. When GoHighLevel and Stripe both show a sale, \`price\` is the GoHighLevel price that names the product, \`price_note\` gives the Stripe amount, and the offer matches both: a GoHighLevel name match and the Stripe \`amount\`. Any other price you cannot find in the evidence is \`null\`, with a \`price_note\` saying why.
|
|
626
626
|
2. **Funnels and steps.** A funnel has a \`funnel_key\`, \`name\`, \`kind\` (\`front_end\` or \`back_end\`), \`entry_offer_key\`, \`window_days\` (how many days after one step a sale still counts for the next; 365 when left out) and \`steps\`. A step has a \`step_key\`, \`position\` (1, 2, 3 in the order people walk them), \`step_type\`, \`name\`, and optionally the \`offer_key\` it sells, a \`wait_note\` (plain words on the wait before it, such as "the months after the course"), \`assets\` and \`rules\`.
|
|
627
627
|
- Step types: \`ad\`, \`landing_page\`, \`vsl\`, \`optin\`, \`application\`, \`booking\`, \`confirmation\`, \`sales_call\`, \`checkout\`, \`order_bump\`, \`upsell\`, \`downsell\`, \`thank_you\`, \`webinar_registration\`, \`webinar\`, \`event\`, \`email_nurture\`, \`sms_nurture\`, \`onboarding\`, \`other\`.
|
|
628
628
|
3. **Assets** on each step: \`{"asset_type": ..., "ref": ...}\` with refs from the evidence: \`meta_campaign\` (campaign id), \`url\` (page address), \`content_item\` (content item id), \`ghl_funnel_step\` (step id), \`ghl_calendar\`, \`ghl_pipeline_stage\`, \`ghl_tag\`, \`webinar\` (webinar id). Give the step after Traffic its page, the funnel's first page, as a \`url\`, a \`content_item\` from \`pages\` or a \`ghl_funnel_step\`: the Traffic step finds its ads from it. Only that step's pages count, so a checkout page that two funnels share is never mistaken for a first page.
|