Skip to content

feat(constraints): add bulk edit mode for constraints#6017

Merged
kodiakhq[bot] merged 4 commits into
flipt-io:v2from
jgaul3:feat/add-bulk-constraints
Jun 12, 2026
Merged

feat(constraints): add bulk edit mode for constraints#6017
kodiakhq[bot] merged 4 commits into
flipt-io:v2from
jgaul3:feat/add-bulk-constraints

Conversation

@jgaul3

@jgaul3 jgaul3 commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Description

This PR raises the constraint value limit (MAX_JSON_ARRAY_ITEMS) from 100 to 10,000, pre-parses the values in the JSON on the backend so evaluation stays performant at larger sizes, and adds a bulk-edit UI for the isoneof and isnotoneof operators.

Large rollouts are currently possible on Flipt by creating multiple sets of constraints in the UI or by manually editing the YAML files, but neither is ideal. evaluation.go re-parses the JSON (and numbers) on each evaluation, so too many values may lead to performance issues. To address this, EvaluationConstraint now stores pre-parsed values and uses them for matching.

Behavior Change

  • Invalid constraint values (malformed isoneof/isnotoneof JSON and unparseable numbers for comparisons) now fail on snapshot load with an error naming the segment and property. Previously they were loaded fine and silently never matched at evaluation time (though they did produce a Debug-logged error). Hand-edited YAML with a bad constraint will block the whole snapshot.

Considerations / Open questions

  • 10,000 is an arbitrary value that struck me as a reasonable next step, any higher and I think we'd need to consider actual performance analysis.
  • This PR extends EvaluationConstraint rather than making a new parsed type. I don't love that a dev could construct an EvaluationConstraint and skip NewEvaluationConstraint(). That case now degrades to a logged error and non-match (same behavior as handling a malformed value prior to this PR). A new parsed type would make it unrepresentable. That would be a much bigger diff, though, and this is already pushing it...
  • matchesDateTime still parses the constraint value on every evaluation and could get a similar fix as a follow-up. I'm happy to do that if requested.

UI Screenshot

image

…faster evaluation, and add bulk edit mode for constraints

Signed-off-by: Jon Gaul <[email protected]>
@jgaul3
jgaul3 requested a review from a team as a code owner June 12, 2026 09:28
@dosubot dosubot Bot added the size:L This PR changes 100-499 lines, ignoring generated files. label Jun 12, 2026

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Verdict: request changes

The pre-parsed constraint optimization is well-structured and the bulk-edit UI is clean, but there's a correctness gap in matchesNumber: scalar number operators (eq, neq, lt, lte, gt, gte) use c.Number without a guard for whether PrepareForEvaluation was actually called. If a developer constructs an EvaluationConstraint directly and skips preparation, the constraint silently evaluates against 0.0 instead of erroring or non-matching, which contradicts the PR's stated intent.

internal/server/evaluation/evaluation.go

  • major (L733): matchesNumber for scalar operators (eq, neq, lt, lte, gt, gte) assigns value := c.Number after only checking c.Value == "". If a developer manually constructs an EvaluationConstraint with a non-empty Value and skips PrepareForEvaluation(), c.Number defaults to 0.0 and the constraint silently evaluates against zero instead of degrading to an error/non-match as the PR description intends. Either use *float64 for Number (so nil is an unambiguous unprepared sentinel) or add a guard that falls back to parsing when the field looks unpopulated.

🤖 Automated review by the Flipt PR review agent.

@codecov

codecov Bot commented Jun 12, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 82.10526% with 17 lines in your changes missing coverage. Please review.
✅ Project coverage is 61.43%. Comparing base (0def52e) to head (6e080e3).
⚠️ Report is 1 commits behind head on v2.

Files with missing lines Patch % Lines
internal/storage/fs/snapshot.go 27.77% 10 Missing and 3 partials ⚠️
internal/server/evaluation/evaluation.go 87.09% 2 Missing and 2 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##               v2    #6017      +/-   ##
==========================================
+ Coverage   61.39%   61.43%   +0.04%     
==========================================
  Files         142      142              
  Lines       14261    14315      +54     
==========================================
+ Hits         8755     8795      +40     
- Misses       4771     4782      +11     
- Partials      735      738       +3     
Flag Coverage Δ
integrationtests 34.40% <23.15%> (-0.08%) ⬇️
unittests 52.55% <81.05%> (+0.09%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

- add Datetime field and parseDatetime helper for DATETIME_COMPARISON_TYPE
- skip malformed segments during snapshot build with logged error instead of failing the entire namespace
- thread logger through addDoc for error reporting
- test error wrapping for all constraint parse failure paths (string, number, datetime)
- apply consistent error border styling on bulk-mode textarea

Signed-off-by: Roman Dmytrenko <[email protected]>
@dosubot dosubot Bot added size:XL This PR changes 500-999 lines, ignoring generated files. and removed size:L This PR changes 100-499 lines, ignoring generated files. labels Jun 12, 2026
@erka erka added the v2 Flipt v2 label Jun 12, 2026

@erka erka left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

thank you @jgaul3 for your work!

@erka erka added the automerge Used by Kodiak bot to automerge PRs label Jun 12, 2026
@kodiakhq
kodiakhq Bot merged commit 1bb4f9b into flipt-io:v2 Jun 12, 2026
28 of 30 checks passed
@github-project-automation github-project-automation Bot moved this to Done in Flipt V2 Jun 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

automerge Used by Kodiak bot to automerge PRs size:XL This PR changes 500-999 lines, ignoring generated files. v2 Flipt v2

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants