diff --git a/docs/web-console-docs/warehouse-native/modes.mdx b/docs/web-console-docs/warehouse-native/modes.mdx index b29a0246..161e03ee 100644 --- a/docs/web-console-docs/warehouse-native/modes.mdx +++ b/docs/web-console-docs/warehouse-native/modes.mdx @@ -34,49 +34,41 @@ In Hybrid mode, you keep the ABsmartly-managed data source as your default and a - Because that import lands the exposures inside your warehouse, **goals sourced from your warehouse can filter and enrich those exposures** the same way Fully mode does — strip out bots and internal traffic, or join in your own attributes table. **Goals that stay managed by ABsmartly don't get this**, since their exposures never leave ABsmartly's default data source. ```mermaid -%%{init: {"theme": "base", "themeVariables": {"fontFamily": "Manrope, system-ui, sans-serif", "primaryColor": "#ffffff", "primaryBorderColor": "#CA3721", "primaryTextColor": "#28293d", "lineColor": "#9296a6", "tertiaryColor": "#ffffff", "fontSize": "15px"}}}%% -flowchart TB - SDK(["Your app - ABsmartly SDK"]) - - subgraph ABC["ABsmartly (default)"] - DEFAULT[("Exposures (no filtering)
and managed goals")] - end - - subgraph EWH["Your warehouse (external)"] - IMPORT[("Imported
exposures")] - WGOALS[("Your goals")] - ATTR[("Your attributes")] - FILTER("Filter and enrich") - QUERY("Query interface") - end - - subgraph CLOUD["ABsmartly Cloud"] - ENGINE("Assignment logic, stats and
metric governance") - end - - SDK --> DEFAULT - DEFAULT -.->|"exposures import"| IMPORT - IMPORT --> FILTER - ATTR --> FILTER - FILTER --> QUERY - WGOALS --> QUERY - DEFAULT --> ENGINE - ENGINE -.->|"scheduled query"| QUERY - QUERY -.->|"aggregate results only"| ENGINE - - style ABC fill:#FBEDEA,stroke:#CA3721,stroke-width:1.5px,color:#28293d - style EWH fill:#EEF1FF,stroke:#465BFF,stroke-width:1.5px,color:#28293d - style CLOUD fill:#FBEDEA,stroke:#CA3721,stroke-width:1.5px,color:#28293d - style DEFAULT fill:#ffffff,stroke:#CA3721,stroke-width:1.5px,color:#28293d - style IMPORT fill:#ffffff,stroke:#465BFF,stroke-width:1.5px,color:#28293d - style WGOALS fill:#ffffff,stroke:#465BFF,stroke-width:1.5px,color:#28293d - style ATTR fill:#ffffff,stroke:#465BFF,stroke-width:1.5px,color:#28293d - style FILTER fill:#465BFF,stroke:#465BFF,stroke-width:1.5px,color:#ffffff - style QUERY fill:#ffffff,stroke:#465BFF,stroke-width:1.5px,color:#28293d - style ENGINE fill:#ffffff,stroke:#CA3721,stroke-width:1.5px,color:#28293d - style SDK fill:#ffffff,stroke:#9296a6,stroke-width:1.5px,color:#28293d +%%{init: {"themeVariables": {"fontFamily": "Manrope, system-ui, sans-serif", "fontSize": "15px", "archEdgeColor": "#9296a6", "archEdgeArrowColor": "#9296a6", "archGroupBorderColor": "#CA3721"}, "architecture": {"iconSize": 100, "padding": 60, "nodeSeparation": 160, "idealEdgeLengthMultiplier": 2.2, "numIter": 6000, "seed": 2}}}%% +architecture-beta + service sdk(mdi:cellphone-link)[Your app ABsmartly SDK] + + group abc(mdi:server)[ABsmartly default] + service default(mdi:database)[Exposures with no filtering and managed goals] in abc + + group ewh(mdi:server-network)[Your warehouse external] + service importsvc(mdi:database-import)[Imported exposures] in ewh + service wgoals(mdi:database)[Your goals] in ewh + service attr(mdi:database)[Your attributes] in ewh + service filtersvc(mdi:filter-outline)[Filter and enrich] in ewh + service query(mdi:magnify)[Query interface] in ewh + + group cloud(mdi:cloud-outline)[ABsmartly Cloud] + service engine(mdi:cog-outline)[Assignment stats and governance] in cloud + + align row sdk default importsvc wgoals + align row attr filtersvc query engine + align column importsvc filtersvc + align column wgoals query + + sdk:R --> L:default + default:R --> L:importsvc + importsvc:B --> T:filtersvc + attr:R --> L:filtersvc + filtersvc:R --> L:query + wgoals:B --> T:query + default:B --> T:engine + query:R --> L:engine + engine:L --> R:query ``` +*Across the privacy boundary between your warehouse and ABsmartly Cloud, ABsmartly runs a scheduled query in and only aggregate results come back out — no user-level data crosses that boundary. The default source's exposures flow into your warehouse on a scheduled exposures import.* + Hybrid lets you bring metrics into your warehouse at your own pace: you keep ABsmartly's battle-tested assignment and exposure pipeline, and move as many (or as few) of your goals into your warehouse as you like — gaining filtering and enrichment for each one you move. ## Fully Warehouse Native @@ -89,41 +81,36 @@ Because every exposure already lives in your warehouse, Fully extends Hybrid's w - **Enrich exposures with your own attributes.** You can join in an external **attributes** table to add segmentation dimensions, then slice experiment results by those attributes. ```mermaid -%%{init: {"theme": "base", "themeVariables": {"fontFamily": "Manrope, system-ui, sans-serif", "primaryColor": "#ffffff", "primaryBorderColor": "#CA3721", "primaryTextColor": "#28293d", "lineColor": "#9296a6", "tertiaryColor": "#ffffff", "fontSize": "15px"}}}%% -flowchart TB - SDK(["Your app - ABsmartly SDK"]) - - subgraph WH["Your warehouse (default)"] - EXP[("Exposures")] - GOALS[("Goals")] - ATTR[("Your attributes")] - FILTER("Filter and enrich") - QUERY("Query interface") - end - - subgraph ABC["ABsmartly Cloud"] - ENGINE("Assignment logic, stats and
metric governance
no user-level data stored") - end - - SDK --> EXP - EXP --> FILTER - ATTR --> FILTER - FILTER --> QUERY - GOALS --> QUERY - ENGINE -.->|"scheduled query"| QUERY - QUERY -.->|"aggregate results only"| ENGINE - - style WH fill:#EEF1FF,stroke:#465BFF,stroke-width:1.5px,color:#28293d - style ABC fill:#FBEDEA,stroke:#CA3721,stroke-width:1.5px,color:#28293d - style EXP fill:#ffffff,stroke:#465BFF,stroke-width:1.5px,color:#28293d - style GOALS fill:#ffffff,stroke:#465BFF,stroke-width:1.5px,color:#28293d - style ATTR fill:#ffffff,stroke:#465BFF,stroke-width:1.5px,color:#28293d - style FILTER fill:#465BFF,stroke:#465BFF,stroke-width:1.5px,color:#ffffff - style QUERY fill:#ffffff,stroke:#465BFF,stroke-width:1.5px,color:#28293d - style ENGINE fill:#ffffff,stroke:#CA3721,stroke-width:1.5px,color:#28293d - style SDK fill:#ffffff,stroke:#9296a6,stroke-width:1.5px,color:#28293d +%%{init: {"themeVariables": {"fontFamily": "Manrope, system-ui, sans-serif", "fontSize": "15px", "archEdgeColor": "#9296a6", "archEdgeArrowColor": "#9296a6", "archGroupBorderColor": "#CA3721"}, "architecture": {"iconSize": 100, "padding": 60, "nodeSeparation": 160, "idealEdgeLengthMultiplier": 2.2, "numIter": 6000, "seed": 2}}}%% +architecture-beta + service sdk(mdi:cellphone-link)[Your app ABsmartly SDK] + + group wh(mdi:cloud-outline)[Your warehouse default] + service exp(mdi:database)[Exposures] in wh + service goals(mdi:database)[Goals] in wh + service attr(mdi:database)[Your attributes] in wh + service filtersvc(mdi:filter-outline)[Filter and enrich] in wh + service query(mdi:magnify)[Query interface] in wh + + group cloud(mdi:cloud-outline)[ABsmartly Cloud] + service engine(mdi:cog-outline)[Assignment stats and governance with no user level data stored] in cloud + + align row sdk exp goals + align row attr filtersvc query engine + align column exp filtersvc + align column goals query + + sdk:R --> L:exp + exp:B --> T:filtersvc + attr:R --> L:filtersvc + filtersvc:R --> L:query + goals:B --> T:query + query:R --> L:engine + engine:L --> R:query ``` +*Across the privacy boundary between your warehouse and ABsmartly Cloud, ABsmartly runs a scheduled query in and only aggregate results come back out — no user-level data crosses that boundary.* + :::info Why the exposure source matters Exposure-side filtering (bots, scrapers, internal traffic) and attribute enrichment both operate on the exposure stream, and only work once that stream lives inside your warehouse. In **Hybrid**, that's true for goals you source from your warehouse — their imported exposures can be filtered and enriched. It's **not** true for goals that stay managed by ABsmartly, since their exposures never leave the default data source. In **Fully**, every exposure lives in your warehouse, so filtering and enrichment apply to every goal. ::: diff --git a/docusaurus.config.js b/docusaurus.config.js index 76193c50..508ec90f 100644 --- a/docusaurus.config.js +++ b/docusaurus.config.js @@ -56,8 +56,11 @@ const config = { locales: ["en"], }, - // Client modules for anchor redirects - clientModules: [require.resolve("./src/anchorRedirects.ts")], + // Client modules for anchor redirects and mermaid icon registration + clientModules: [ + require.resolve("./src/anchorRedirects.ts"), + require.resolve("./src/scripts/mermaidIcons.js"), + ], presets: [ [ diff --git a/package.json b/package.json index ca79f20b..2dba94df 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,7 @@ "@docusaurus/plugin-ideal-image": "^3.10.2", "@docusaurus/preset-classic": "^3.10.2", "@docusaurus/theme-mermaid": "^3.10.2", + "@iconify-json/mdi": "^1.2.3", "@mdx-js/react": "^3.1.1", "clsx": "^2.1.0", "docusaurus-plugin-openapi-docs": "^5.1.3", diff --git a/src/scripts/mermaidIcons.js b/src/scripts/mermaidIcons.js new file mode 100644 index 00000000..eae66272 --- /dev/null +++ b/src/scripts/mermaidIcons.js @@ -0,0 +1,7 @@ +import { icons } from "@iconify-json/mdi"; + +if (typeof window !== "undefined") { + import("mermaid").then(({ default: mermaid }) => { + mermaid.registerIconPacks([{ name: icons.prefix, icons }]); + }); +} diff --git a/yarn.lock b/yarn.lock index bcdbbdea..8b419119 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2258,7 +2258,14 @@ resolved "https://registry.yarnpkg.com/@hookform/error-message/-/error-message-2.0.1.tgz#6a37419106e13664ad6a29c9dae699ae6cd276b8" integrity sha512-U410sAr92xgxT1idlu9WWOVjndxLdgPUHEB8Schr27C9eh7/xUnITWpCMF93s+lGiG++D4JnbSnrb5A21AdSNg== -"@iconify/types@^2.0.0": +"@iconify-json/mdi@^1.2.3": + version "1.2.3" + resolved "https://registry.yarnpkg.com/@iconify-json/mdi/-/mdi-1.2.3.tgz#5e4ee9d8c8aaad04381c8cc6c6edbe3327f031b5" + integrity sha512-O3cLwbDOK7NNDf2ihaQOH5F9JglnulNDFV7WprU2dSoZu3h3cWH//h74uQAB87brHmvFVxIOkuBX2sZSzYhScg== + dependencies: + "@iconify/types" "*" + +"@iconify/types@*", "@iconify/types@^2.0.0": version "2.0.0" resolved "https://registry.yarnpkg.com/@iconify/types/-/types-2.0.0.tgz#ab0e9ea681d6c8a1214f30cd741fe3a20cc57f57" integrity sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==