@picked/client 0.0.1-dev.1785305085063 → 0.0.1-dev.1785908062293
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/.tsbuildinfo +1 -0
- package/dist/api-03c5jvVk.js +38 -0
- package/dist/api-CQxCVIrm.cjs +1 -0
- package/dist/cjs/form/index.js +1 -1
- package/dist/cjs/index.js +2 -2
- package/dist/cjs/plugins/dom-observer/index.js +1 -1
- package/dist/cjs/plugins/dynamic-experiences/index.js +1 -1
- package/dist/cjs/server/index.js +1 -1
- package/dist/docs/explanation/conditions-and-the-logic-engine.md +94 -0
- package/dist/docs/explanation/feature-flag-allocation.md +176 -0
- package/dist/docs/explanation/how-picked-works.md +124 -0
- package/dist/docs/explanation/how-pickedql-works.md +76 -0
- package/dist/docs/explanation/pages-and-flows.md +64 -0
- package/dist/docs/explanation/the-content-model.md +77 -0
- package/dist/docs/explanation/the-two-apis.md +68 -0
- package/dist/docs/explanation/why-server-side-rendering.md +76 -0
- package/dist/docs/explanation/workspaces-and-versions.md +71 -0
- package/dist/docs/how-to/add-a-step-field-or-action.md +43 -0
- package/dist/docs/{pickedql/examples.md → how-to/analytics/index.md} +53 -28
- package/dist/docs/how-to/archive-or-delete-a-workspace.md +46 -0
- package/dist/docs/how-to/authenticate-with-a-magic-link.md +40 -0
- package/dist/docs/how-to/authenticate-with-a-password.md +51 -0
- package/dist/docs/how-to/authenticate-with-an-api-key.md +51 -0
- package/dist/docs/how-to/authenticate-with-oauth.md +40 -0
- package/dist/docs/how-to/build-a-flow.md +83 -0
- package/dist/docs/how-to/connect-the-mcp-server.md +38 -0
- package/dist/docs/how-to/create-a-project.md +29 -0
- package/dist/docs/how-to/create-an-experience.md +42 -0
- package/dist/docs/how-to/create-and-revoke-an-api-key.md +37 -0
- package/dist/docs/how-to/debug-with-the-chrome-extension.md +57 -0
- package/dist/docs/how-to/define-a-page-layout.md +39 -0
- package/dist/docs/how-to/fill-and-publish-a-page.md +50 -0
- package/dist/docs/how-to/install-the-gtm-template.md +84 -0
- package/dist/docs/how-to/install-the-sdk.md +68 -0
- package/dist/docs/how-to/install-the-vite-plugin.md +56 -0
- package/dist/docs/how-to/invite-and-remove-members.md +34 -0
- package/dist/docs/how-to/preview-a-workspace.md +28 -0
- package/dist/docs/how-to/publish-a-workspace.md +30 -0
- package/dist/docs/how-to/read-a-feature-flag.md +101 -0
- package/dist/docs/how-to/register-a-component.md +55 -0
- package/dist/docs/how-to/register-an-action-handler.md +67 -0
- package/dist/docs/how-to/render-a-step-form.md +132 -0
- package/dist/docs/how-to/render-an-unpublished-preview.md +41 -0
- package/dist/docs/how-to/reuse-a-section.md +37 -0
- package/dist/docs/how-to/reuse-a-step-field-or-action.md +28 -0
- package/dist/docs/how-to/roll-back-a-published-version.md +26 -0
- package/dist/docs/how-to/run-an-ab-test.md +49 -0
- package/dist/docs/how-to/run-code-on-a-form-submission.md +125 -0
- package/dist/docs/how-to/server-render-a-page.md +81 -0
- package/dist/docs/how-to/set-a-content-security-policy.md +32 -0
- package/dist/docs/how-to/set-up-mfa.md +69 -0
- package/dist/docs/how-to/upload-and-use-an-asset.mdx +73 -0
- package/dist/docs/how-to/validate-a-field.md +52 -0
- package/dist/docs/how-to/write-a-condition.md +45 -0
- package/dist/docs/how-to/write-a-predicate.md +60 -0
- package/dist/docs/index.md +41 -59
- package/dist/docs/reference/dashboard/actions.mdx +53 -0
- package/dist/docs/reference/dashboard/api-keys.mdx +37 -0
- package/dist/docs/reference/dashboard/conditions.mdx +42 -0
- package/dist/docs/reference/dashboard/content/asset-library.mdx +63 -0
- package/dist/docs/reference/dashboard/content/content-entries.mdx +44 -0
- package/dist/docs/reference/dashboard/content/layouts.mdx +62 -0
- package/dist/docs/reference/dashboard/content/pages.mdx +35 -0
- package/dist/docs/reference/dashboard/content/sections.mdx +28 -0
- package/dist/docs/reference/dashboard/experiences.mdx +51 -0
- package/dist/docs/reference/dashboard/features.mdx +114 -0
- package/dist/docs/reference/dashboard/fields.mdx +100 -0
- package/dist/docs/reference/dashboard/flow-builder/canvas.mdx +58 -0
- package/dist/docs/reference/dashboard/flow-builder/condition-builder.md +57 -0
- package/dist/docs/reference/dashboard/flow-builder/keyboard-shortcuts.md +72 -0
- package/dist/docs/reference/dashboard/flow-builder/nodes.md +63 -0
- package/dist/docs/reference/dashboard/projects.mdx +44 -0
- package/dist/docs/reference/dashboard/reports.mdx +43 -0
- package/dist/docs/reference/dashboard/steps.mdx +37 -0
- package/dist/docs/reference/dashboard/team-management.md +29 -0
- package/dist/docs/reference/dashboard/workspace-versioning.mdx +30 -0
- package/dist/docs/reference/dashboard/workspaces.mdx +76 -0
- package/dist/docs/{delivery-api → reference/delivery-api}/experience-content.md +17 -5
- package/dist/docs/reference/delivery-api/index.md +45 -0
- package/dist/docs/reference/delivery-api/preview-caching-crawling.md +79 -0
- package/dist/docs/{delivery-api → reference/delivery-api}/project-config.md +15 -6
- package/dist/docs/reference/glossary.md +173 -0
- package/dist/docs/reference/management-api/authentication.md +74 -0
- package/dist/docs/{api → reference/management-api}/authorization-and-scopes.md +70 -47
- package/dist/docs/reference/management-api/error-handling.md +233 -0
- package/dist/docs/{api → reference/management-api}/pagination.md +36 -20
- package/dist/docs/reference/pickedql/data-sources.md +174 -0
- package/dist/docs/reference/pickedql/dimensions.md +87 -0
- package/dist/docs/{pickedql → reference/pickedql}/filtering.md +17 -6
- package/dist/docs/reference/pickedql/index.md +18 -0
- package/dist/docs/reference/pickedql/schema.md +172 -0
- package/dist/docs/reference/pickedql/virtual-functions.md +237 -0
- package/dist/docs/reference/sdk/actions.md +30 -0
- package/dist/docs/{sdk → reference/sdk}/conditions.md +15 -5
- package/dist/docs/reference/sdk/content-security-policy.md +21 -0
- package/dist/docs/reference/sdk/experiences.md +51 -0
- package/dist/docs/reference/sdk/features.md +233 -0
- package/dist/docs/reference/sdk/fields.md +209 -0
- package/dist/docs/reference/sdk/index.md +68 -0
- package/dist/docs/{sdk → reference/sdk}/plugins/create-experience.md +25 -34
- package/dist/docs/reference/sdk/plugins/dynamic-experiences.md +74 -0
- package/dist/docs/reference/sdk/plugins/index.md +29 -0
- package/dist/docs/{sdk → reference/sdk}/plugins/window-object.md +6 -0
- package/dist/docs/reference/sdk/predicates.md +43 -0
- package/dist/docs/reference/sdk/ssr/index.md +33 -0
- package/dist/docs/reference/sdk/ssr/rendering-and-hydration.md +103 -0
- package/dist/docs/reference/sdk/ssr/serialize.md +77 -0
- package/dist/docs/reference/sdk/ssr/slots-and-placements.md +59 -0
- package/dist/docs/reference/sdk/steps.md +87 -0
- package/dist/docs/reference/tools/chrome-extension.md +16 -0
- package/dist/docs/reference/tools/image-optimisation-service.md +104 -0
- package/dist/docs/reference/tools/mcp.md +88 -0
- package/dist/docs/reference/tools/vite-plugin.md +88 -0
- package/dist/docs/tutorials/first-api-call.md +228 -0
- package/dist/docs/tutorials/first-experience-in-the-dashboard.mdx +143 -0
- package/dist/docs/tutorials/first-experience.mdx +255 -0
- package/dist/docs/tutorials/first-server-rendered-page.mdx +186 -0
- package/dist/{dom-BwmTHeT7.js → dom-BqcToNL0.js} +1 -3
- package/dist/{dom-CDrHc_j9.cjs → dom-DlLH3FxV.cjs} +1 -1
- package/dist/esm/form/index.js +2 -4
- package/dist/esm/index.js +225 -186
- package/dist/esm/plugins/dom-observer/index.js +1 -1
- package/dist/esm/plugins/dynamic-experiences/index.js +3 -3
- package/dist/esm/preview/index.js +1 -1
- package/dist/esm/server/index.js +33 -31
- package/dist/{experience-instance-DOJShRk5.js → experience-instance-DGk11d8a.js} +3 -3
- package/dist/experience-instance-Dej3P1sE.cjs +1 -0
- package/dist/plugin-CHOVsx7Z.js +287 -0
- package/dist/plugin-DsaGXQHx.cjs +1 -0
- package/dist/{preview-channel-DW9J8t4B.js → preview-channel-CSr96XAo.js} +1 -1
- package/dist/{protocol-DSqOlW2r.js → protocol-C5KkkiZc.js} +1 -1
- package/dist/types/client.d.ts +7 -6
- package/dist/types/data-source/api.d.ts +60 -0
- package/dist/types/data-source/api.d.ts.map +1 -0
- package/dist/types/data-source/provider.d.ts +97 -0
- package/dist/types/data-source/provider.d.ts.map +1 -0
- package/dist/types/entities/action/action.d.ts +5 -4
- package/dist/types/entities/action/action.d.ts.map +1 -1
- package/dist/types/entities/component/component.d.ts +6 -5
- package/dist/types/entities/component/component.d.ts.map +1 -1
- package/dist/types/entities/condition/condition.d.ts +5 -5
- package/dist/types/entities/content/content.d.ts +4 -3
- package/dist/types/entities/experience/experience.d.ts +11 -10
- package/dist/types/entities/experience/experience.d.ts.map +1 -1
- package/dist/types/entities/experience-instance/experience-instance.d.ts +10 -9
- package/dist/types/entities/feature/feature.d.ts +19 -2
- package/dist/types/entities/feature/feature.d.ts.map +1 -1
- package/dist/types/entities/field/field.d.ts +7 -6
- package/dist/types/entities/framework/framework.d.ts +7 -6
- package/dist/types/entities/framework/framework.d.ts.map +1 -1
- package/dist/types/entities/history/history.d.ts +6 -6
- package/dist/types/entities/plugin/plugin.d.ts +3 -2
- package/dist/types/entities/plugin/plugin.d.ts.map +1 -1
- package/dist/types/entities/predicate/predicate.d.ts +4 -3
- package/dist/types/entities/predicate/predicate.d.ts.map +1 -1
- package/dist/types/entities/response/response-validation.d.ts +3 -2
- package/dist/types/entities/response/response.d.ts +12 -11
- package/dist/types/entities/session/session.d.ts +2 -1
- package/dist/types/entities/step/step.d.ts +6 -5
- package/dist/types/exports.d.ts +2 -1
- package/dist/types/exports.d.ts.map +1 -1
- package/dist/types/form/build-responses.d.ts +2 -1
- package/dist/types/form/create-field-evaluator.d.ts +4 -3
- package/dist/types/form/create-field-validation.d.ts +5 -4
- package/dist/types/form/create-form.d.ts +7 -6
- package/dist/types/form/create-submit-pipeline.d.ts +7 -6
- package/dist/types/form/get-step-fields.d.ts +3 -2
- package/dist/types/lifecycle/condition-selection.d.ts +14 -4
- package/dist/types/lifecycle/lifecycle.d.ts +4 -3
- package/dist/types/lifecycle/rules-logic.d.ts +4 -3
- package/dist/types/lifecycle/state-snapshot.d.ts +4 -3
- package/dist/types/picked.d.ts +79 -62
- package/dist/types/picked.d.ts.map +1 -1
- package/dist/types/ping.d.ts +1 -1
- package/dist/types/ping.d.ts.map +1 -1
- package/dist/types/plugins/create-experience/create-experience.d.ts +9 -8
- package/dist/types/plugins/create-experience/create-experience.d.ts.map +1 -1
- package/dist/types/plugins/create-experience/plugin.d.ts +3 -2
- package/dist/types/plugins/create-experience/plugin.d.ts.map +1 -1
- package/dist/types/plugins/create-experience/serialization.d.ts.map +1 -1
- package/dist/types/plugins/dom-observer/plugin.d.ts +1 -1
- package/dist/types/plugins/dynamic-experiences/hash.d.ts +40 -5
- package/dist/types/plugins/dynamic-experiences/hash.d.ts.map +1 -1
- package/dist/types/plugins/dynamic-experiences/index.d.ts +2 -0
- package/dist/types/plugins/dynamic-experiences/index.d.ts.map +1 -1
- package/dist/types/plugins/dynamic-experiences/plugin.d.ts +4 -36
- package/dist/types/plugins/dynamic-experiences/plugin.d.ts.map +1 -1
- package/dist/types/plugins/dynamic-experiences/types.d.ts +42 -11
- package/dist/types/plugins/dynamic-experiences/types.d.ts.map +1 -1
- package/dist/types/plugins/experience-browser-storage/plugin.d.ts +1 -1
- package/dist/types/plugins/experience-browser-storage/plugin.d.ts.map +1 -1
- package/dist/types/plugins/history-browser-storage/plugin.d.ts +1 -1
- package/dist/types/plugins/history-browser-storage/plugin.d.ts.map +1 -1
- package/dist/types/plugins/responses-browser-storage/plugin.d.ts +1 -1
- package/dist/types/plugins/responses-browser-storage/plugin.d.ts.map +1 -1
- package/dist/types/plugins/responses-indexeddb/plugin.d.ts +1 -1
- package/dist/types/plugins/single-page-app/plugin.d.ts +1 -1
- package/dist/types/plugins/single-page-app/plugin.d.ts.map +1 -1
- package/dist/types/plugins/web-components/plugin.d.ts +2 -1
- package/dist/types/plugins/window-object/plugin.d.ts +2 -2
- package/dist/types/preview-channel.d.ts +5 -1
- package/dist/types/preview-receiver/index.d.ts +18 -1
- package/dist/types/preview-receiver/protocol.d.ts +10 -1
- package/dist/types/server/index.d.ts +3 -3
- package/dist/types/server/serialize.d.ts +8 -2
- package/dist/types/server/serialize.d.ts.map +1 -1
- package/dist/types/utils/dom.d.ts +2 -1
- package/dist/types/utils/events.d.ts +6 -6
- package/dist/types/utils/events.d.ts.map +1 -1
- package/dist/types/utils/global-obj.d.ts +1 -1
- package/dist/types/utils/global-obj.d.ts.map +1 -1
- package/dist/types/utils/id.d.ts.map +1 -1
- package/dist/types/utils/logger.d.ts +2 -1
- package/dist/types/utils/logger.d.ts.map +1 -1
- package/dist/types/utils/node-tree/get-next-node-from-action.d.ts +2 -1
- package/dist/types/utils/node-tree/get-next-node-from-condition.d.ts +2 -1
- package/dist/types/utils/node-tree/get-next-node.d.ts +1 -1
- package/dist/types/utils/node-tree/get-next-node.d.ts.map +1 -1
- package/dist/types/utils/node-tree/get-origin-node.d.ts +1 -1
- package/dist/types/utils/node-tree/get-origin-node.d.ts.map +1 -1
- package/dist/types/utils/node-tree/min-max-steps-to-leaf.d.ts +1 -1
- package/dist/types/utils/node-tree/min-max-steps-to-leaf.d.ts.map +1 -1
- package/dist/types/utils/node-tree/min-max-steps-to-origin.d.ts +1 -1
- package/dist/types/utils/node-tree/min-max-steps-to-origin.d.ts.map +1 -1
- package/dist/types/utils/node-tree/next-reachable-step-nodes.d.ts +1 -1
- package/dist/types/utils/node-tree/next-reachable-step-nodes.d.ts.map +1 -1
- package/dist/types/utils/nodes.d.ts +1 -1
- package/dist/types/utils/picked-config.d.ts +2 -1
- package/dist/types/utils/rehydrate-scripts.d.ts +6 -0
- package/dist/types/utils/rehydrate-scripts.d.ts.map +1 -1
- package/dist/types/utils/rules-logic.d.ts +6 -2
- package/dist/types/utils/storage.d.ts +1 -1
- package/dist/types/utils/storage.d.ts.map +1 -1
- package/package.json +22 -23
- package/dist/api-CPL40b7A.js +0 -40
- package/dist/api-Dz5rgRgQ.cjs +0 -1
- package/dist/docs/actions.mdx +0 -78
- package/dist/docs/api/authentication.md +0 -376
- package/dist/docs/api/error-handling.md +0 -211
- package/dist/docs/api/index.md +0 -197
- package/dist/docs/api-keys.mdx +0 -40
- package/dist/docs/chrome-extension.md +0 -51
- package/dist/docs/conditions.mdx +0 -59
- package/dist/docs/content/asset-library.mdx +0 -93
- package/dist/docs/content/content-entries.mdx +0 -30
- package/dist/docs/content/layouts.mdx +0 -70
- package/dist/docs/content/pages.mdx +0 -67
- package/dist/docs/content/sections.mdx +0 -33
- package/dist/docs/delivery-api/index.md +0 -46
- package/dist/docs/delivery-api/preview-caching-crawling.md +0 -59
- package/dist/docs/experiences.mdx +0 -42
- package/dist/docs/features.mdx +0 -58
- package/dist/docs/fields.mdx +0 -79
- package/dist/docs/flow-builder/building-flows.md +0 -61
- package/dist/docs/flow-builder/condition-builder.md +0 -54
- package/dist/docs/flow-builder/keyboard-shortcuts.md +0 -66
- package/dist/docs/flow-builder/nodes.md +0 -43
- package/dist/docs/flow-builder/overview.mdx +0 -50
- package/dist/docs/gtm-template.md +0 -69
- package/dist/docs/guides/build-a-personalized-page.mdx +0 -143
- package/dist/docs/image-optimisation-service.md +0 -80
- package/dist/docs/mcp.md +0 -120
- package/dist/docs/pickedql/data-sources.md +0 -145
- package/dist/docs/pickedql/dimensions.md +0 -65
- package/dist/docs/pickedql/index.md +0 -36
- package/dist/docs/pickedql/schema.md +0 -156
- package/dist/docs/pickedql/virtual-functions.md +0 -204
- package/dist/docs/projects.mdx +0 -37
- package/dist/docs/reports.mdx +0 -18
- package/dist/docs/sdk/actions.md +0 -66
- package/dist/docs/sdk/content-security-policy.md +0 -32
- package/dist/docs/sdk/experiences.md +0 -46
- package/dist/docs/sdk/features.md +0 -212
- package/dist/docs/sdk/fields.md +0 -263
- package/dist/docs/sdk/index.md +0 -83
- package/dist/docs/sdk/plugins/dynamic-experiences.md +0 -58
- package/dist/docs/sdk/plugins/index.md +0 -9
- package/dist/docs/sdk/predicates.md +0 -112
- package/dist/docs/sdk/ssr/index.md +0 -62
- package/dist/docs/sdk/ssr/rendering-and-hydration.md +0 -141
- package/dist/docs/sdk/ssr/serialize.md +0 -86
- package/dist/docs/sdk/ssr/slots-and-placements.md +0 -35
- package/dist/docs/sdk/steps.md +0 -434
- package/dist/docs/steps.mdx +0 -44
- package/dist/docs/team-management.md +0 -40
- package/dist/docs/vite-plugin.md +0 -82
- package/dist/docs/workspace-versioning.mdx +0 -28
- package/dist/docs/workspaces.mdx +0 -102
- package/dist/experience-instance-DurC3pE-.cjs +0 -1
- package/dist/plugin-CFXwbXeM.js +0 -247
- package/dist/plugin-m4qekgtA.cjs +0 -1
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
layout: docs
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
# Dimension columns
|
|
6
|
-
|
|
7
|
-
Dimension columns are available on all data sources. On `metrics`, they are included directly in the table. On `events` and `features`, the required `LEFT JOIN` is added automatically when you reference them — you never write joins yourself.
|
|
8
|
-
|
|
9
|
-
## Available dimensions
|
|
10
|
-
|
|
11
|
-
| Source | Columns |
|
|
12
|
-
|---|---|
|
|
13
|
-
| `dim_variant` | `variant_type`, `ab_feature_name`, `ab_feature_value` |
|
|
14
|
-
| `dim_device` | `device_category`, `browser_name`, `browser_version`, `os_name`, `os_version`, `platform` |
|
|
15
|
-
| `dim_geo` | `country_code`, `country_name`, `region`, `city` |
|
|
16
|
-
| `dim_utm` | `utm_source`, `utm_medium`, `utm_campaign`, `utm_term`, `utm_content` |
|
|
17
|
-
| `dim_product` | `product_name`, `product_category`, `product_page` |
|
|
18
|
-
| `steps` | `step_title` |
|
|
19
|
-
| `experiences` | `experience_title` |
|
|
20
|
-
| `projects` | `project_name`, `project_timezone` |
|
|
21
|
-
|
|
22
|
-
The `steps`, `experiences`, and `projects` sources are reference tables sourced from the operational database. They are auto-joined onto `events`/`fact_events` when their analyst-facing columns are referenced, **and** they require their own tenant filter when queried directly:
|
|
23
|
-
|
|
24
|
-
| Source | Tenant filter required |
|
|
25
|
-
|---|---|
|
|
26
|
-
| `steps`, `experiences` | `WHERE project_id = '<project_id>'` |
|
|
27
|
-
| `projects` | `WHERE id = '<project_id>'` (the row's `id` IS the project id) |
|
|
28
|
-
|
|
29
|
-
When auto-joined, these reference tables also receive a tenant equality on the JOIN's `ON` clause (e.g. `AND st.project_id = '<project_id>'`, `AND pr.id = '<project_id>'`) so ClickHouse prunes the dim scan instead of reading the full table. The predicate is added to `ON` rather than `WHERE` to preserve `LEFT JOIN` semantics.
|
|
30
|
-
|
|
31
|
-
Analyst-facing column names are prefixed (`step_title`, `project_name`, etc.) to avoid collisions across sources — for example, `steps.title` and `experiences.title` both exist, but you reference them as `step_title` and `experience_title`.
|
|
32
|
-
|
|
33
|
-
```sql
|
|
34
|
-
-- Group events by experience and step name (auto-joins both `experiences` and `steps`)
|
|
35
|
-
SELECT experience_title, step_title, count(*)
|
|
36
|
-
FROM events
|
|
37
|
-
WHERE project_id = 'your-project-id'
|
|
38
|
-
GROUP BY experience_title, step_title
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
Auto-joins also work inside subqueries and CTEs — reference dimension columns wherever you need them and the required `LEFT JOIN` is injected at that level:
|
|
42
|
-
|
|
43
|
-
```sql
|
|
44
|
-
-- Dimension columns inside a CTE
|
|
45
|
-
WITH per_step AS (
|
|
46
|
-
SELECT step_title, count(*) AS n
|
|
47
|
-
FROM events
|
|
48
|
-
WHERE project_id = 'your-project-id'
|
|
49
|
-
GROUP BY step_title
|
|
50
|
-
)
|
|
51
|
-
SELECT * FROM per_step ORDER BY n DESC
|
|
52
|
-
|
|
53
|
-
-- Dimension columns inside a nested SELECT
|
|
54
|
-
SELECT step_title, n FROM (
|
|
55
|
-
SELECT step_title, count(*) AS n FROM events
|
|
56
|
-
WHERE project_id = 'your-project-id'
|
|
57
|
-
GROUP BY step_title
|
|
58
|
-
) sub
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
## Native event columns
|
|
62
|
-
|
|
63
|
-
These columns are available directly on `events` and require no join:
|
|
64
|
-
|
|
65
|
-
`event_type`, `interaction_type`, `experience_id`, `step_id`, `event_id`, `user_canonical_id`, `session_id`, `client_local_date`, `is_purchase`, `is_cart_add`, `event_meta`.
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
layout: docs
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
# PickedQL
|
|
6
|
-
|
|
7
|
-
PickedQL is a SQL query language for querying your Picked analytics data. Write simple SQL using virtual tables and functions — PickedQL expands them into optimized queries with automatic joins and A/B test aggregations.
|
|
8
|
-
|
|
9
|
-
## Quick start
|
|
10
|
-
|
|
11
|
-
```sql
|
|
12
|
-
-- How many users are in the control vs variant group?
|
|
13
|
-
SELECT control_users(), variant_users()
|
|
14
|
-
FROM metrics
|
|
15
|
-
WHERE project_id = 'your-project-id'
|
|
16
|
-
```
|
|
17
|
-
|
|
18
|
-
PickedQL handles table mapping and dimension joins automatically. You write concise, readable SQL — PickedQL does the rest.
|
|
19
|
-
|
|
20
|
-
## How PickedQL works
|
|
21
|
-
|
|
22
|
-
1. **Virtual table expansion**: Table names like `metrics` map to underlying data tables
|
|
23
|
-
2. **Virtual function expansion**: Shorthand functions like `control_users()` expand to full aggregate expressions
|
|
24
|
-
3. **Auto dimension joins**: References to dimension columns (like `device_category` or `country_code`) trigger automatic `LEFT JOIN` clauses — you never write joins yourself
|
|
25
|
-
4. **Tenant isolation**: Every query must include a tenant filter in the `WHERE` clause — usually `project_id`, but `projects` uses `id` (the row's `id` IS the project id). PickedQL extracts the filter and verifies you have permission to access that project
|
|
26
|
-
5. **SQL passthrough**: Standard SQL (including `CASE WHEN`, window functions, and subqueries) works alongside virtual functions
|
|
27
|
-
|
|
28
|
-
## Best practices
|
|
29
|
-
|
|
30
|
-
- **Use `metrics` for dashboards**: Pre-aggregated data is significantly faster than raw events for standard reporting
|
|
31
|
-
- **Use `events` for deep dives**: Raw event-level data gives full flexibility for custom breakdowns and funnels
|
|
32
|
-
- **Use `experience_journey` for sankey / funnel charts**: One line of SQL returns `source, target, users` — the 8-CTE scaffold (dedup, top-N path ranking, lagInFrame) is handled internally; pass parameters via `WHERE`
|
|
33
|
-
- **Don't write JOINs**: PickedQL injects them automatically when you reference dimension columns
|
|
34
|
-
- **Group by any dimension**: Add dimension columns to `SELECT` and `GROUP BY` freely — required joins are handled for you
|
|
35
|
-
- **Reference table metadata for free**: Use `step_title`, `experience_title`, `project_name` directly in `events` queries — PickedQL auto-joins the `steps`, `experiences`, and `projects` reference tables
|
|
36
|
-
|
|
@@ -1,156 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
layout: docs
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
# Schema
|
|
6
|
-
|
|
7
|
-
Column reference for each PickedQL data source.
|
|
8
|
-
|
|
9
|
-
## `metrics`
|
|
10
|
-
|
|
11
|
-
Pre-aggregated daily data. One row per unique combination of dimensions per day.
|
|
12
|
-
|
|
13
|
-
| Column | Type | Description |
|
|
14
|
-
|---|---|---|
|
|
15
|
-
| `project_id` | String | Project identifier (required in `WHERE`) |
|
|
16
|
-
| `project_local_date` | Date | Date in project timezone |
|
|
17
|
-
| `experience_id` | String | Experience identifier |
|
|
18
|
-
| `step_id` | String | Step identifier |
|
|
19
|
-
| `event_type` | String | Event type (e.g., `page_view`, `click`) |
|
|
20
|
-
| `interaction_type` | String | Interaction type (e.g., `Button Click`) |
|
|
21
|
-
| `variant_type` | String | `Control`, `Variant`, or `Unknown` |
|
|
22
|
-
| `device_category` | String | Device category (e.g., `Desktop`, `Mobile`) |
|
|
23
|
-
| `country_code` | String | ISO country code |
|
|
24
|
-
| `utm_source` | String | UTM source |
|
|
25
|
-
| `utm_medium` | String | UTM medium |
|
|
26
|
-
| `product_name` | String | Product name |
|
|
27
|
-
| `product_category` | String | Product category |
|
|
28
|
-
| `landing_page_url` | String | Landing page URL |
|
|
29
|
-
|
|
30
|
-
:::note
|
|
31
|
-
Aggregate columns (`users`, `sessions`, `events`, etc.) are not queried directly — use [virtual functions](./virtual-functions) instead.
|
|
32
|
-
:::
|
|
33
|
-
|
|
34
|
-
## `events`
|
|
35
|
-
|
|
36
|
-
User-level event data. One row per event per user. Dimension columns are joined automatically when referenced.
|
|
37
|
-
|
|
38
|
-
### Native columns
|
|
39
|
-
|
|
40
|
-
| Column | Type | Description |
|
|
41
|
-
|---|---|---|
|
|
42
|
-
| `project_id` | String | Project identifier (required in `WHERE`) |
|
|
43
|
-
| `event_id` | String | Unique event identifier |
|
|
44
|
-
| `user_canonical_id` | String | Canonical user identifier |
|
|
45
|
-
| `session_id` | String | Session identifier |
|
|
46
|
-
| `experience_id` | String | Experience identifier |
|
|
47
|
-
| `step_id` | String | Step identifier |
|
|
48
|
-
| `event_type` | String | Event type (e.g., `page_view`, `click`) |
|
|
49
|
-
| `interaction_type` | String | Interaction type (e.g., `Button Click`) |
|
|
50
|
-
| `client_local_date` | Date | Date in client timezone |
|
|
51
|
-
| `is_purchase` | UInt8 | `1` if checkout complete event |
|
|
52
|
-
| `is_cart_add` | UInt8 | `1` if cart add event |
|
|
53
|
-
| `is_first_session` | UInt8 | `1` if first session for this user |
|
|
54
|
-
| `landing_page_url` | String | Landing page URL |
|
|
55
|
-
| `features` | Map(String, String) | Feature flag assignments |
|
|
56
|
-
| `feature_keys` | Map(String, String) | Feature key assignments |
|
|
57
|
-
| `event_meta` | String | Event metadata |
|
|
58
|
-
|
|
59
|
-
### Dimension columns (auto-joined)
|
|
60
|
-
|
|
61
|
-
These columns are joined automatically when referenced — no `JOIN` syntax needed.
|
|
62
|
-
|
|
63
|
-
| Column | Source | Description |
|
|
64
|
-
|---|---|---|
|
|
65
|
-
| `variant_type` | dim_variant | `Control`, `Variant`, or `Unknown` |
|
|
66
|
-
| `ab_feature_name` | dim_variant | A/B feature name |
|
|
67
|
-
| `ab_feature_value` | dim_variant | A/B feature value |
|
|
68
|
-
| `device_category` | dim_device | Device category |
|
|
69
|
-
| `browser_name` | dim_device | Browser name |
|
|
70
|
-
| `browser_version` | dim_device | Browser version |
|
|
71
|
-
| `os_name` | dim_device | Operating system name |
|
|
72
|
-
| `os_version` | dim_device | Operating system version |
|
|
73
|
-
| `platform` | dim_device | Platform |
|
|
74
|
-
| `country_code` | dim_geo | ISO country code |
|
|
75
|
-
| `country_name` | dim_geo | Country name |
|
|
76
|
-
| `region` | dim_geo | Region |
|
|
77
|
-
| `city` | dim_geo | City |
|
|
78
|
-
| `utm_source` | dim_utm | UTM source |
|
|
79
|
-
| `utm_medium` | dim_utm | UTM medium |
|
|
80
|
-
| `utm_campaign` | dim_utm | UTM campaign |
|
|
81
|
-
| `utm_term` | dim_utm | UTM term |
|
|
82
|
-
| `utm_content` | dim_utm | UTM content |
|
|
83
|
-
| `product_name` | dim_product | Product name |
|
|
84
|
-
| `product_category` | dim_product | Product category |
|
|
85
|
-
| `product_page` | dim_product | Product page |
|
|
86
|
-
| `step_title` | steps | Step title (joined on `project_id` + `experience_id` + `step_id`) |
|
|
87
|
-
| `experience_title` | experiences | Experience title (joined on `project_id` + `experience_id`) |
|
|
88
|
-
| `project_name` | projects | Project name |
|
|
89
|
-
| `project_timezone` | projects | Project timezone |
|
|
90
|
-
|
|
91
|
-
## `steps`, `experiences`, `projects`
|
|
92
|
-
|
|
93
|
-
Reference tables describing your Picked configuration. Auto-joined onto `events` when their analyst-facing columns are referenced; require a per-table tenant filter when queried directly.
|
|
94
|
-
|
|
95
|
-
| Source | Real Columns | Analyst Columns (when referenced from `events`) | Tenant filter (when queried directly) |
|
|
96
|
-
|---|---|---|---|
|
|
97
|
-
| `steps` | `id`, `title`, `experience_id`, `project_id`, `organization_id` | `step_title` | `project_id = '…'` |
|
|
98
|
-
| `experiences` | `id`, `title`, `project_id`, `organization_id` | `experience_title` | `project_id = '…'` |
|
|
99
|
-
| `projects` | `id`, `name`, `timezone`, `organization_id` | `project_name`, `project_timezone` | `id = '<project_id>'` |
|
|
100
|
-
|
|
101
|
-
When queried directly, use the real column names:
|
|
102
|
-
|
|
103
|
-
```sql
|
|
104
|
-
-- List all experiences for a project
|
|
105
|
-
SELECT id, title FROM experiences WHERE project_id = 'your-project-id'
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
When referenced from `events`, use the prefixed analyst names — joins are injected automatically:
|
|
109
|
-
|
|
110
|
-
```sql
|
|
111
|
-
SELECT experience_title, step_title, count(*)
|
|
112
|
-
FROM events
|
|
113
|
-
WHERE project_id = 'your-project-id'
|
|
114
|
-
GROUP BY experience_title, step_title
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
## `features`
|
|
118
|
-
|
|
119
|
-
The `features` table provides [parameterized virtual functions](./virtual-functions#feature-functions-features--events) for querying feature flag assignments:
|
|
120
|
-
|
|
121
|
-
| Function | Description |
|
|
122
|
-
|---|---|
|
|
123
|
-
| `feature_users('name', 'bucket' [, 'key'])` | Unique users in a feature bucket |
|
|
124
|
-
| `feature_sessions('name', 'bucket' [, 'key'])` | Unique sessions in a feature bucket |
|
|
125
|
-
| `feature_events('name', 'bucket' [, 'key'])` | Unique events in a feature bucket |
|
|
126
|
-
|
|
127
|
-
## `experience_journey`
|
|
128
|
-
|
|
129
|
-
Aggregated step-transition edges for sankey / funnel charts. Parameters are supplied via the outer `WHERE` clause (PickedQL extracts them and substitutes into the underlying scaffold).
|
|
130
|
-
|
|
131
|
-
### Columns
|
|
132
|
-
|
|
133
|
-
| Column | Type | Description |
|
|
134
|
-
|---|---|---|
|
|
135
|
-
| `source` | String | Edge start, formatted as `NN. <step title>` (e.g., `001. Welcome screen`) |
|
|
136
|
-
| `target` | String | Edge end, formatted as `NN. <step title>`.
|
|
137
|
-
| `users` | UInt64 | Distinct `user_canonical_id` count that traversed this edge. |
|
|
138
|
-
|
|
139
|
-
### Parameters (via `WHERE`)
|
|
140
|
-
|
|
141
|
-
| Key | Type | Required | Purpose |
|
|
142
|
-
|---|---|---|---|
|
|
143
|
-
| `project_id` | String | ✓ | Tenant filter. |
|
|
144
|
-
| `experience_id` | String | | Restrict to one `fact_events.experience_id`. |
|
|
145
|
-
| `starting_step` | String | | Anchor edges at first occurrence of this `step_id`. Defaults to each user's first step. |
|
|
146
|
-
| `targeting_step` | String | | Trim each user's window at their first occurrence of this `step_id`. Non-reachers still contribute their pre-cut journey. |
|
|
147
|
-
| `num_nodes_after_start` | Integer | | Forward window from start: keep steps where `seq_pos < start_seq + N` (card 4129 semantics). |
|
|
148
|
-
| `num_nodes_before_target` | Integer | | Backward window from target: keep steps where `seq_pos >= target_seq - N` (card 2740 semantics). Requires `targeting_step`. |
|
|
149
|
-
| `top_n_path` | Integer | | Keep only the top-N most-walked paths by user count. Defaults to no limit. |
|
|
150
|
-
| `user_cohort_event` | String | | Restrict to users who have at least one `fact_events` row with this `event_type`. Implemented as `user_canonical_id IN (SELECT DISTINCT user_canonical_id FROM fact_events WHERE event_type = '…')`. |
|
|
151
|
-
| `client_local_date` | Date | | Date range filter, pushed into the underlying scan. Supports `=`, `<`, `<=`, `>`, `>=`, `BETWEEN`. |
|
|
152
|
-
| `event_timestamp` | DateTime64 | | Server-side timestamp filter. Same operators as `client_local_date`. |
|
|
153
|
-
|
|
154
|
-
When both window params are set, both predicates apply (intersection). Date filters combine via `AND` with the other params.
|
|
155
|
-
|
|
156
|
-
See [data sources → experience_journey](./data-sources#experience_journey--sankey-ready-step-transitions) for usage examples.
|
|
@@ -1,204 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
layout: docs
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
# Virtual functions
|
|
6
|
-
|
|
7
|
-
Virtual functions are shorthand for aggregate expressions. They are **table-aware** — the same function expands differently on `metrics` (pre-aggregated) vs `events` (user-level).
|
|
8
|
-
|
|
9
|
-
## A/B test metrics
|
|
10
|
-
|
|
11
|
-
| Function | Description |
|
|
12
|
-
|---|---|
|
|
13
|
-
| `control_users([condition])` | Unique users in the Control group, optionally filtered by a custom condition |
|
|
14
|
-
| `variant_users([condition])` | Unique users in the Variant group, optionally filtered by a custom condition |
|
|
15
|
-
| `all_users()` | All unique users |
|
|
16
|
-
| `control_sessions([condition])` | Unique sessions in the Control group, optionally filtered by a custom condition |
|
|
17
|
-
| `variant_sessions([condition])` | Unique sessions in the Variant group, optionally filtered by a custom condition |
|
|
18
|
-
| `all_sessions()` | All unique sessions |
|
|
19
|
-
|
|
20
|
-
### Custom filters on `events`
|
|
21
|
-
|
|
22
|
-
On the `events` table, `control_*`/`variant_*` functions accept **one optional filter argument** to count only users/sessions matching the given expression, in addition to the implicit `variant_type` filter. The argument can be **positional** or **named** (`filter=`).
|
|
23
|
-
|
|
24
|
-
The filter uses the same `column=value` syntax as conversion-rate conditions, with `AND`/`OR` operators and parentheses for grouping.
|
|
25
|
-
|
|
26
|
-
```sql
|
|
27
|
-
-- Default: all Control users
|
|
28
|
-
SELECT control_users() FROM events
|
|
29
|
-
|
|
30
|
-
-- Custom filter (positional)
|
|
31
|
-
SELECT control_users('event_type=app_initialize') FROM events
|
|
32
|
-
SELECT variant_users('event_type=app_initialize AND step_id=xxx') FROM events
|
|
33
|
-
|
|
34
|
-
-- AND/OR + parentheses
|
|
35
|
-
SELECT control_users('event_type=app_initialize OR event_type=app_load') FROM events
|
|
36
|
-
SELECT control_users('event_type=form_submit AND (step_id=lead-capture OR step_id=xxx)') FROM events
|
|
37
|
-
|
|
38
|
-
-- Sessions
|
|
39
|
-
SELECT control_sessions('event_type=step_enter') FROM events
|
|
40
|
-
SELECT variant_sessions('event_type=step_enter AND step_id=checkout') FROM events
|
|
41
|
-
|
|
42
|
-
-- Named form
|
|
43
|
-
SELECT control_users(filter='event_type=app_initialize AND step_id=xxx') FROM events
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
:::note
|
|
47
|
-
Custom filters are **not supported on `metrics`** (pre-aggregated data). On `metrics`, these functions ignore any arguments and use the default Control/Variant filter only.
|
|
48
|
-
:::
|
|
49
|
-
|
|
50
|
-
## Conversion metrics
|
|
51
|
-
|
|
52
|
-
| Function | Description |
|
|
53
|
-
|---|---|
|
|
54
|
-
| `all_purchase_users()` | Users who completed a purchase |
|
|
55
|
-
| `control_purchase_users()` | Control users who purchased (`metrics` only) |
|
|
56
|
-
| `variant_purchase_users()` | Variant users who purchased (`metrics` only) |
|
|
57
|
-
| `all_purchase_sessions()` | Sessions with a purchase (`metrics` only) |
|
|
58
|
-
| `all_purchase_orders()` | Unique order count (`metrics` only) |
|
|
59
|
-
| `all_cart_add_users()` | Users who added to cart |
|
|
60
|
-
|
|
61
|
-
## Conversion rates
|
|
62
|
-
|
|
63
|
-
| Function | Description |
|
|
64
|
-
|---|---|
|
|
65
|
-
| `control_conversion_rate([numerator [, denominator]])` | Conversion rate for Control. Defaults to purchase users / all users |
|
|
66
|
-
| `variant_conversion_rate([numerator [, denominator]])` | Conversion rate for Variant. Same args as above |
|
|
67
|
-
| `conversion_rate_uplift([numerator [, denominator]])` | Relative improvement: `(variant CR - control CR) / control CR`. Same args as above |
|
|
68
|
-
|
|
69
|
-
### Custom conditions on `events`
|
|
70
|
-
|
|
71
|
-
On the `events` table, conversion rate functions accept up to **2 optional arguments** to customize the numerator and denominator. Each argument can be either a **condition expression string** or a **nested virtual function call** (see below). Arguments can be **positional** or **named** (`numerator=`, `denominator=`).
|
|
72
|
-
|
|
73
|
-
Each condition expression uses `column=value` with `AND`/`OR` operators and parentheses for grouping.
|
|
74
|
-
|
|
75
|
-
```sql
|
|
76
|
-
-- Default: purchase users / all users
|
|
77
|
-
SELECT control_conversion_rate() FROM events
|
|
78
|
-
|
|
79
|
-
-- Custom numerator, default denominator (all users)
|
|
80
|
-
SELECT control_conversion_rate('event_type=form_submit_success') FROM events
|
|
81
|
-
|
|
82
|
-
-- AND/OR in conditions
|
|
83
|
-
SELECT control_conversion_rate('event_type=checkout_complete OR event_type=order_create') FROM events
|
|
84
|
-
SELECT control_conversion_rate('step_id=lead-capture AND event_type=form_submit_success') FROM events
|
|
85
|
-
|
|
86
|
-
-- Parentheses for grouping
|
|
87
|
-
SELECT control_conversion_rate('event_type=form_submit AND (step_id=lead-capture OR step_id=xxx)') FROM events
|
|
88
|
-
|
|
89
|
-
-- Custom numerator AND denominator (positional)
|
|
90
|
-
SELECT control_conversion_rate('event_type=form_submit', 'step_id=lead-capture') FROM events
|
|
91
|
-
|
|
92
|
-
-- Named arguments (explicit, any order)
|
|
93
|
-
SELECT control_conversion_rate(numerator='event_type=form_submit', denominator='step_id=lead-capture') FROM events
|
|
94
|
-
|
|
95
|
-
-- Named: denominator only (numerator defaults to purchase)
|
|
96
|
-
SELECT control_conversion_rate(denominator='step_id=lead-capture') FROM events
|
|
97
|
-
|
|
98
|
-
-- Uplift with named args
|
|
99
|
-
SELECT conversion_rate_uplift(numerator='event_type=form_submit', denominator='step_id=lead-capture') FROM events
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
#### Nested virtual functions as numerator / denominator
|
|
103
|
-
|
|
104
|
-
Instead of a condition string, you can pass a **virtual function call** as the numerator or denominator. The inner aggregate is substituted in place — no implicit `variant_type` filter is added on top of it (the nested function controls its own filter).
|
|
105
|
-
|
|
106
|
-
This is the most flexible form when the numerator and denominator have different segments (e.g., Control users who fired event X over **all** users regardless of variant):
|
|
107
|
-
|
|
108
|
-
```sql
|
|
109
|
-
-- (Control users who fired app_initialize) / (all users)
|
|
110
|
-
SELECT control_conversion_rate(
|
|
111
|
-
control_users('event_type=app_initialize'),
|
|
112
|
-
all_users()
|
|
113
|
-
) FROM events
|
|
114
|
-
|
|
115
|
-
-- Mix string and nested forms
|
|
116
|
-
SELECT control_conversion_rate(
|
|
117
|
-
'event_type=form_submit',
|
|
118
|
-
all_users()
|
|
119
|
-
) FROM events
|
|
120
|
-
|
|
121
|
-
-- Uplift with nested args
|
|
122
|
-
SELECT conversion_rate_uplift(
|
|
123
|
-
control_users('event_type=app_initialize'),
|
|
124
|
-
all_users()
|
|
125
|
-
) FROM events
|
|
126
|
-
```
|
|
127
|
-
|
|
128
|
-
:::note
|
|
129
|
-
Custom conditions and nested virtual function args are **not supported on `metrics`** (pre-aggregated data). On `metrics`, these functions always use the default purchase / all users definition.
|
|
130
|
-
:::
|
|
131
|
-
|
|
132
|
-
## Visitor segmentation (`metrics` only)
|
|
133
|
-
|
|
134
|
-
| Function | Description |
|
|
135
|
-
|---|---|
|
|
136
|
-
| `new_users()` | First-time visitors |
|
|
137
|
-
| `returning_users()` | Returning visitors |
|
|
138
|
-
| `new_sessions()` | Sessions from new visitors |
|
|
139
|
-
| `returning_sessions()` | Sessions from returning visitors |
|
|
140
|
-
|
|
141
|
-
## Funnel metrics (`events` only)
|
|
142
|
-
|
|
143
|
-
:::note
|
|
144
|
-
Funnel metrics are being continuously updated. Check back for new functions.
|
|
145
|
-
:::
|
|
146
|
-
|
|
147
|
-
| Function | Description |
|
|
148
|
-
|---|---|
|
|
149
|
-
| `step_enter_users()` | Users who entered a funnel step |
|
|
150
|
-
| `step_enter_sessions()` | Sessions that entered a funnel step |
|
|
151
|
-
|
|
152
|
-
## Cohort filters (`events` only)
|
|
153
|
-
|
|
154
|
-
Predicate-shaped functions that emit a `user_canonical_id IN (SELECT … FROM events …)` subquery. Use in `WHERE` to restrict any analysis to users who have at least one event matching a custom condition.
|
|
155
|
-
|
|
156
|
-
| Function | Description |
|
|
157
|
-
|---|---|
|
|
158
|
-
| `user_cohort_filter('<condition>')` | Restrict the query to users with ≥1 `events` row matching `<condition>` |
|
|
159
|
-
| `user_cohort_filter(filter='<condition>')` | Same, named-arg form |
|
|
160
|
-
|
|
161
|
-
`<condition>` uses the same `column=value [AND\|OR …]` shorthand as `control_users` / `variant_users`.
|
|
162
|
-
|
|
163
|
-
```sql
|
|
164
|
-
-- Funnel scoped to users who eventually submitted lead capture
|
|
165
|
-
SELECT all_users(), all_purchase_users()
|
|
166
|
-
FROM events
|
|
167
|
-
WHERE project_id = 'proj-abc'
|
|
168
|
-
AND user_cohort_filter('event_type=lead_capture')
|
|
169
|
-
|
|
170
|
-
-- Multi-condition cohort with OR-grouping
|
|
171
|
-
SELECT all_sessions()
|
|
172
|
-
FROM events
|
|
173
|
-
WHERE project_id = 'proj-abc'
|
|
174
|
-
AND user_cohort_filter('event_type=signup OR event_type=trial_start')
|
|
175
|
-
```
|
|
176
|
-
|
|
177
|
-
The outer query MUST filter by a single `project_id` — the function bakes that tenant into the inner subquery so the cohort scan is scoped to your project, not the whole warehouse.
|
|
178
|
-
|
|
179
|
-
## Feature functions (`features` / `events`)
|
|
180
|
-
|
|
181
|
-
Parameterized functions that accept the feature name, bucket, and an optional feature key:
|
|
182
|
-
|
|
183
|
-
| Function | Description |
|
|
184
|
-
|---|---|
|
|
185
|
-
| `feature_users('name', 'bucket' [, 'key'])` | Unique users in a feature bucket |
|
|
186
|
-
| `feature_sessions('name', 'bucket' [, 'key'])` | Unique sessions in a feature bucket |
|
|
187
|
-
| `feature_events('name', 'bucket' [, 'key'])` | Unique events in a feature bucket |
|
|
188
|
-
|
|
189
|
-
```sql
|
|
190
|
-
-- Compare feature buckets
|
|
191
|
-
SELECT
|
|
192
|
-
feature_users('homepage_test', 'control') AS control,
|
|
193
|
-
feature_users('homepage_test', 'variant') AS variant
|
|
194
|
-
FROM features
|
|
195
|
-
|
|
196
|
-
-- With feature key filter
|
|
197
|
-
SELECT feature_users('homepage_test', 'control', 'v1') FROM features
|
|
198
|
-
```
|
|
199
|
-
|
|
200
|
-
## Other (`metrics` only)
|
|
201
|
-
|
|
202
|
-
| Function | Description |
|
|
203
|
-
|---|---|
|
|
204
|
-
| `event_count()` | Total event count (from pre-aggregation) |
|
package/dist/docs/projects.mdx
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
layout: docs
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
import { Screenshot } from '../../components/Screenshot'
|
|
6
|
-
|
|
7
|
-
# Projects
|
|
8
|
-
|
|
9
|
-
A project represents one website or app you want to instrument with Picked. Each project has its own set of experiences, entities, and configuration.
|
|
10
|
-
|
|
11
|
-
<Screenshot
|
|
12
|
-
route="/{orgSlug}"
|
|
13
|
-
alt="The organization home page on the Picked dashboard, listing the projects in an organization"
|
|
14
|
-
/>
|
|
15
|
-
|
|
16
|
-
## Create a project
|
|
17
|
-
|
|
18
|
-
You need an organization first. If you don't have one, create it when you sign up.
|
|
19
|
-
|
|
20
|
-
1. Open your organization.
|
|
21
|
-
2. Click **New Project**.
|
|
22
|
-
3. Enter a name.
|
|
23
|
-
4. Click **Create**.
|
|
24
|
-
|
|
25
|
-
## Workspaces
|
|
26
|
-
|
|
27
|
-
Each project contains one or more [Workspaces](/workspaces) for configuring and previewing experiences before publishing.
|
|
28
|
-
|
|
29
|
-
## Project home
|
|
30
|
-
|
|
31
|
-
When you open a project, you land on the project home page. It shows your SDK installation snippet and a getting-started checklist.
|
|
32
|
-
|
|
33
|
-
Copy the snippet and add it to your site. This connects your site to the project and enables experience delivery. See [SDK Installation](/sdk) for setup details.
|
|
34
|
-
|
|
35
|
-
## Project navigation
|
|
36
|
-
|
|
37
|
-
The sidebar shows all sections available in your project: **Experiences**, **Fields**, **Steps**, **Actions**, **Conditions**, and more. Some sections appear only when enabled for your account.
|
package/dist/docs/reports.mdx
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
layout: docs
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
import { Screenshot } from '../../components/Screenshot'
|
|
6
|
-
|
|
7
|
-
# Reports
|
|
8
|
-
|
|
9
|
-
Reports show analytics data for your project. Track how visitors interact with your experiences and features.
|
|
10
|
-
|
|
11
|
-
<Screenshot
|
|
12
|
-
route="/{orgSlug}/{projectId}/reports"
|
|
13
|
-
alt="The reports list for a project on the Picked dashboard"
|
|
14
|
-
/>
|
|
15
|
-
|
|
16
|
-
## View report data
|
|
17
|
-
|
|
18
|
-
Open a report to see its analytics. Data updates as new visitor interactions are recorded.
|
package/dist/docs/sdk/actions.md
DELETED
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
layout: docs
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
# Actions
|
|
6
|
-
|
|
7
|
-
Register action handlers on the Picked client so the SDK can invoke them when an experience flow reaches an action node.
|
|
8
|
-
|
|
9
|
-
## Registering actions
|
|
10
|
-
|
|
11
|
-
Register actions when creating the Picked client. Each key in the `actions` object must match an action key defined in the dashboard:
|
|
12
|
-
|
|
13
|
-
```ts
|
|
14
|
-
import { createClient } from '@picked/client'
|
|
15
|
-
|
|
16
|
-
const picked = createClient({
|
|
17
|
-
projectId: 'your-project-id',
|
|
18
|
-
actions: {
|
|
19
|
-
'track-signup': () => {
|
|
20
|
-
analytics.track('signup_completed')
|
|
21
|
-
},
|
|
22
|
-
'notify': (params) => {
|
|
23
|
-
sendNotification(params)
|
|
24
|
-
},
|
|
25
|
-
},
|
|
26
|
-
})
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
Each action is a function that receives optional parameters and usually runs a side effect. When the flow reaches an action node, the SDK calls the matching function and branches on whether it succeeds or throws (see [Success and failure branching](#success-and-failure-branching)).
|
|
30
|
-
|
|
31
|
-
## How actions work
|
|
32
|
-
|
|
33
|
-
1. **Registration**: Actions are registered to the Picked client during initialization
|
|
34
|
-
2. **Flow traversal**: When the SDK traverses the experience flow and reaches an action node, it looks up the action by its key
|
|
35
|
-
3. **Execution**: The matching function is called and awaited. The SDK then continues to the next node based on the action's outcome
|
|
36
|
-
4. **Non-blocking**: Actions don't interrupt the visitor's experience. The current step stays on screen while an async action runs
|
|
37
|
-
|
|
38
|
-
## Success and failure branching
|
|
39
|
-
|
|
40
|
-
An action node can have separate **success** and **failure** branches. The SDK selects the branch from the action's outcome:
|
|
41
|
-
|
|
42
|
-
- **Failure** — the action throws (or its promise rejects). The flow follows the failure (`onFail`) branch.
|
|
43
|
-
- **Success** — the action resolves to any value (`void`, `true`, `false`, or a string). A resolved `false` is a valid response, not a failure. The flow follows the success (`onSuccess`) branch.
|
|
44
|
-
|
|
45
|
-
Reserve the failure branch for genuine errors — throw on the failure case, since a returned value never routes to `onFail`:
|
|
46
|
-
|
|
47
|
-
```ts
|
|
48
|
-
'check-eligibility': async () => {
|
|
49
|
-
const response = await fetch('/api/eligibility')
|
|
50
|
-
// Throw only when the request itself fails — that takes the failure branch.
|
|
51
|
-
if (!response.ok) throw new Error('Eligibility request failed')
|
|
52
|
-
}
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
A valid negative result is not a failure. An API that returns `200` with a "no" (for example `{ serviced: false }`) should record that value as a response and branch on it with a condition, rather than throw:
|
|
56
|
-
|
|
57
|
-
```ts
|
|
58
|
-
'check-serviced-area': async ({ client, responses }) => {
|
|
59
|
-
const postcode = responses.find((r) => r.fieldKey === 'postcode')?.value
|
|
60
|
-
const { serviced } = await fetch(`/api/serviced?postcode=${postcode}`).then((r) => r.json())
|
|
61
|
-
// Commit the outcome as a response; a downstream condition routes the flow.
|
|
62
|
-
client.responses.register('is-serviced', serviced)
|
|
63
|
-
}
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
If an action node has only a single plain connection (no explicit success or failure branch), the flow continues through it on either outcome.
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
layout: docs
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
# Content Security Policy
|
|
6
|
-
|
|
7
|
-
The Picked SDK loads resources from the following domains. Add each to the matching CSP directive.
|
|
8
|
-
|
|
9
|
-
## Required domains
|
|
10
|
-
|
|
11
|
-
| Domain | Directive | Purpose |
|
|
12
|
-
| --- | --- | --- |
|
|
13
|
-
| `api.picked.app` | `connect-src` | API requests, project configuration, experiences, session tracking |
|
|
14
|
-
| `evnts.pckd.dev` | `connect-src` | Analytics event collection (Snowplow) |
|
|
15
|
-
| `img.picked-content.com` | `img-src` | Optimised images served via the [image optimisation service](../image-optimisation-service.md) |
|
|
16
|
-
|
|
17
|
-
## Configuration
|
|
18
|
-
|
|
19
|
-
As an HTTP header:
|
|
20
|
-
|
|
21
|
-
```
|
|
22
|
-
Content-Security-Policy: connect-src 'self' https://api.picked.app https://evnts.pckd.dev; img-src 'self' https://img.picked-content.com;
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
Or as a `<meta>` tag:
|
|
26
|
-
|
|
27
|
-
```html
|
|
28
|
-
<meta
|
|
29
|
-
http-equiv="Content-Security-Policy"
|
|
30
|
-
content="connect-src 'self' https://api.picked.app https://evnts.pckd.dev; img-src 'self' https://img.picked-content.com;"
|
|
31
|
-
/>
|
|
32
|
-
```
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
layout: docs
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
# Experiences
|
|
6
|
-
|
|
7
|
-
Define experiences in code with `createExperience()`, or load them from the dashboard at runtime with the [Dynamic Experiences Plugin](./plugins/dynamic-experiences).
|
|
8
|
-
|
|
9
|
-
The execution flow below targets a DOM selector and renders into it. A Page experience instead renders through a named slot: target it to `.picked-slot-<name>` and render `<ExperienceSlot name="<name>" />` on your server. Use the slot path for SEO-critical, server-rendered Pages; use the selector path for browser-rendered Flows. See [Server-Side Rendering](/sdk/ssr) and [Slots & Placements](/sdk/ssr/slots-and-placements).
|
|
10
|
-
|
|
11
|
-
## Creating experiences
|
|
12
|
-
|
|
13
|
-
```ts
|
|
14
|
-
import { createExperience } from '@picked/client/plugins/create-experience'
|
|
15
|
-
import { adaptSvelteComponent } from '@picked/svelte'
|
|
16
|
-
import appCss from '../app.css?inline'
|
|
17
|
-
|
|
18
|
-
export const productPageExperience = createExperience({
|
|
19
|
-
id: 'product-page-experience',
|
|
20
|
-
name: 'Product Page Experience',
|
|
21
|
-
condition: {
|
|
22
|
-
'==': [
|
|
23
|
-
{ var: 'location.pathname' },
|
|
24
|
-
'/product/',
|
|
25
|
-
],
|
|
26
|
-
},
|
|
27
|
-
targets: [{ selector: 'body', placement: 'after' }],
|
|
28
|
-
component: adaptSvelteComponent(
|
|
29
|
-
import('../ui/ProductPageExperience.svelte'),
|
|
30
|
-
{ css: [appCss] },
|
|
31
|
-
),
|
|
32
|
-
})
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
Register experiences using the [Create Experience Plugin](./plugins/create-experience) for code-defined experiences, or the [Dynamic Experiences Plugin](./plugins/dynamic-experiences) to fetch and manage them from the dashboard at runtime.
|
|
36
|
-
|
|
37
|
-
## How experiences work
|
|
38
|
-
|
|
39
|
-
When an experience is registered, the SDK follows this execution flow:
|
|
40
|
-
|
|
41
|
-
1. **Registration**: Experiences are registered to the Picked client using [createExperiencePlugin](./plugins/create-experience) for code-defined experiences, or [dynamicExperiencesPlugin](./plugins/dynamic-experiences) for dashboard-managed experiences
|
|
42
|
-
2. **Condition evaluation**: The SDK evaluates the experience's `condition` using the logic engine to determine if it should be shown
|
|
43
|
-
3. **Target resolution**: The SDK searches the DOM for elements matching the `targets` selectors (e.g., `body`, `.product-page`, `#checkout`)
|
|
44
|
-
4. **Initialization**: If the condition evaluates to `true` and at least one target element exists, the experience is initialized
|
|
45
|
-
5. **Component rendering**: The experience's component is rendered and injected into the DOM at the specified target location and placement (before, after, append, prepend, or replace)
|
|
46
|
-
6. **Flow execution**: If the experience contains steps, fields, and conditionals, users can progress through the multi-step flow with validation and branching logic
|