Skip to content

Tracking: standardize expression types across schema, Ruby, and UIs #11

Open

Description

@jnunemaker

Tracking issue for enforcing expression types from a single source of truth (this schema repo), spanning three repos. Lives here because expressions is the root dependency and lowest-traffic repo.

Goal

  • Q1: enforce flipper_properties value types (scalars only).
  • Q2: enforce operator argument types via the JSON Schema, shared by Ruby + JS.
  • Standardize on flippercloud/expressions as the source of truth; Ruby vendors the schemas, the Vue UIs import the JS package.

Merge / publish order (hard dependency chain)

① expressions (merge + npm publish) → ② flipper → ③ Vue UIs. Nothing downstream can land until the package is published.

① expressions (this repo)

  • Commit the schema work — added FeatureEnabled.schema.json, category metadata. (Note: the property definition was dropped during review since it described context values, not expressions.)
  • Push, open PR, review, merge — Add FeatureEnabled expression, schema metadata, and publish under @flippercloud scope #10 (MERGED).
  • Package renamed @flippercloud.io/expressions → @flippercloud/expressions, version bumped to 1.1.0 on main.
  • Publish npm @flippercloud/expressions@1.1.0 ← still pending; this unblocks everything below (npm currently 404s for the new name).

② flipper — PR flippercloud/flipper#1000 (green, ready)

  • Vendored schemas into lib/flipper/expression/schemas (no npm); Flipper::Expression::Schema + #validate/#valid? backed by an optional, lazily-required json_schemer (core stays lightweight; validation runs at the boundaries, not on the evaluate hot path or in enable).
  • Q1 property enforcement in Gates::Expression (warn + drop non-scalar values; uses a Ruby ALLOWED_PROPERTY_TYPES constant, so unaffected by the dropped property definition).
  • Operator parity: added Add/Subtract/Multiply/Divide/Min/Max, restored Duration (enables relative-time windows, e.g. Now < Time(signup_at) + Duration(7, "days")).
  • Shared example test runs the vendored examples/*.json so Ruby and JS test the same cases; rake expressions:vendor re-copies schemas + examples.
  • Re-vendored to match merged main (dropped property def). Vendored schemas now identical to the source of truth.
  • After ①.publish: optional version bump + CHANGELOG; merge #1000.

③ Vue UIs — flippercloud + flipper-pro (not started; needs its own workspace)

  • Add @flippercloud/expressions dependency (note the renamed scope).
  • Derive operators + constraints from the schema in Condition.vue / templates.js instead of hardcoding.
  • Validate client-side before save.
  • Add operators the UIs are missing (FeatureEnabled, flippercloud).

Decisions locked in

  • json_schemer optional (its dep bigdecimal is a C extension); validation at the UI/API boundaries, not core enable.
  • In/NotIn deferred until implemented end-to-end (referenced only in flippercloud's display-only ExpressionDescriber; not evaluable in Ruby today).
  • Duration kept; full arithmetic family kept and tested; per-operator Ruby specs kept alongside the shared suite.
  • Property values are scalar-only (string/number/boolean/null), enforced in Ruby via ALLOWED_PROPERTY_TYPES; arrays gated behind a future In/NotIn.

Activity

  1. self-assigned this
    on Jun 8, 2026
  2. jnunemaker commented on Jun 8, 2026

    @jnunemaker
    ContributorAuthor

    ✅ ①.publish done — @flippercloud/expressions@1.1.0 is live on npm (59 files, all 26 schemas incl. FeatureEnabled, examples, dist).

    ② flipper PR #1000 is green (46/46) and ready to merge — no version bump / CHANGELOG needed (version bumps at release time; changelog via GitHub Releases). Gate is cleared.

    Next: merge #1000, then start ③ (Vue UIs) — note the renamed scope @flippercloud/expressions.

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

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions