Skip to content

docs(cli): per-field operator support, page_scope, retired filter params - #129

Merged
yosriady merged 1 commit into
mainfrom
chore/cli-canonical-filter-support
Aug 3, 2026
Merged

docs(cli): per-field operator support, page_scope, retired filter params#129
yosriady merged 1 commit into
mainfrom
chore/cli-canonical-filter-support

Conversation

@yosriady

@yosriady yosriady commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Why

Follow-up to #124 and #125, which brought the CLI docs onto the canonical filter envelope. Two gaps remained.

contains was listed alongside the other operators with no per-field guidance, and startsWith/endsWith were absent from the list even though the API accepts them. Per packages/shared/constants/filterCapability.ts in formono, each field class implements a different subset and an unsupported pairing is a 400 — the docs gave no way to predict that.

What changed

cli/profiles.mdx — add startsWith/endsWith to the operator list, plus the per-field support table:

  • .balance fields: comparison operators only, JSON number values
  • labels.value: comparison plus contains (case-insensitive, new in P-2387)
  • routable string attributes: full vocabulary, case-sensitive substring matching
  • social fields: contains + notEmpty; startsWith/endsWith/isEmpty rejected
  • users.paid_source: fixed ad-network enum
  • users.lifecycle: eq and in only

cli/analytics.mdx — document page_scope (P-2378, on kpis/top_*/revenue_*/volume_by_metric), spell out that the single --filters array now carries profile, social, lifecycle and resource predicates on the user-aggregate pipes, and warn that the retired per-family params are rejected with a 400 rather than ignored.

Pairs with getformo/cli#34.

🤖 Generated with Claude Code


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

`contains` was documented as social-only. The profiles surface supports it
on routable string attributes and, since P-2387, on `labels.value`;
`startsWith`/`endsWith` were missing from the operator list entirely. Add
the per-field support table the API enforces.

Document `page_scope` on the kpis/top_*/revenue_*/volume_by_metric pipes,
and record that the retired per-family analytics params are rejected with a
400 rather than silently ignored.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@mintlify

mintlify Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
formo 🟢 Ready View Preview Aug 3, 2026, 2:34 AM

💡 Tip: Enable Workflows to automatically generate PRs for you.

@yosriady
yosriady merged commit a56640c into main Aug 3, 2026
7 checks passed
@yosriady
yosriady deleted the chore/cli-canonical-filter-support branch August 3, 2026 02:37

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ba5a81bf91

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread cli/analytics.mdx
| `revenue_timeseries` | `address` (required) |
| `revenue_by_metric`, `volume_by_metric`, `top_sources` | `metric_column`, `limit`, `offset` |
| `top_chains`, `top_events`, `top_locations`, `top_pages`, `top_wallets` | `limit`, `offset` |
| `kpis`, `top_*`, `revenue_*`, `volume_by_metric` | `page_scope` — `page` (default) or `session` |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Exclude revenue_timeseries from the page_scope wildcard

The revenue_* wildcard includes revenue_timeseries, but the authoritative GET /v0/revenue_timeseries definition in api/openapi.json accepts only address, date_from, and date_to; unlike revenue_overview and revenue_by_metric, it accepts neither filters nor page_scope. Users following this table can therefore pass an unsupported parameter that cannot affect this wallet-scoped endpoint. List the two revenue endpoints that actually expose page_scope instead of using the wildcard.

Useful? React with 👍 / 👎.

Comment thread cli/analytics.mdx
| `top_chains`, `top_events`, `top_locations`, `top_pages`, `top_wallets` | `limit`, `offset` |
| `kpis`, `top_*`, `revenue_*`, `volume_by_metric` | `page_scope` — `page` (default) or `session` |

`page_scope` only affects requests that carry a `page` filter. The default scopes metrics to activity on that page; `session` restores the legacy behaviour where metrics include all activity in any session that viewed the page.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Describe the KPI-specific page scope behavior

For kpis with a page filter, the default does not scope every metric to activity on that page as this sentence claims. The contract documented in api/query/kpis.mdx and AnalyticsPageScope keeps sessions and visitors unchanged, counts only pageviews on the filtered page, and computes bounce rate and duration for sessions that landed there. The generic wording will cause users to misinterpret KPI results, so this section should state that exception or link to the precise KPI behavior.

Useful? React with 👍 / 👎.

Comment thread cli/analytics.mdx

A JSON array of `{ field, op, value }` filters, e.g. `[{"field":"location","op":"eq","value":"US"}]`. For multi-value matching, use `in` / `nin` with an array value (e.g. `["chrome","firefox"]`); pipe-delimited strings remain supported by the analytics query boundary.

This one array carries every predicate. On the user-aggregate pipes (`lifecycle`, `frequency`) it also takes profile metrics, social identity fields, a lifecycle entry (`{"field":"lifecycle","op":"in","value":["New","Power user"]}`), and resource entries using the stable fields `chains.balance`, `apps.balance`, `tokens.balance` and `labels.value` with named qualifiers (`chain_id`, `app_id`, `token_address`, `scope`, `tag_id`).

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve the separate user-aggregate filter parameters

On both lifecycle and frequency, the OpenAPI contract still exposes behavior_filters, source_filter, and channel_filter as separate predicates in addition to filters. In particular, behavior filters use an incompatible {event, op, times, ...} shape, while source and channel filters have distinct semantics, so they cannot all be moved into this one array. Saying that --filters carries every predicate leaves CLI users without a documented way to express these supported constraints; limit this claim to the migrated profile-family filters and document the remaining parameters under --params.

Useful? React with 👍 / 👎.

Comment thread cli/profiles.mdx
| `labels.value` | comparison operators plus `contains` (case-insensitive) |
| Numeric profile metrics (`users.net_worth_usd`, `users.volume`, `users.revenue`, `users.points`) | comparison operators |
| Routable string attributes (`users.device`, `users.os`, `users.referrer`, `users.utm_*`, `users.click_id`, and the `first_*`/`last_*` attribution variants) | the full vocabulary; `contains`, `startsWith` and `endsWith` match case-sensitively |
| Social fields (`users.twitter`, `users.email`, `users.farcaster`, …) | `contains` (case-insensitive) and `notEmpty`; `startsWith`, `endsWith` and `isEmpty` are rejected |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Reconcile the social-field operator guidance

This exhaustive supported-operator row now conflicts with the published profile API guide in api/profiles/search.mdx, which says social fields support exact eq and neq matching and describes isEmpty as the inverse presence check, including an exact-email example. The new CLI page instead omits eq/neq and explicitly says isEmpty is rejected, leaving users with mutually exclusive instructions for the same endpoint. If this row reflects the current implementation, update the API guide in the same change so the site has one consistent contract.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant