Skip to content

Commit decafdb

Browse files
Copilotaepfli
andauthored
feat: support metadata merging in flag evaluation responses (#40)
## Description Implements metadata merging per the flagd provider specification: evaluation responses now merge flag-set metadata (root-level config fields) with flag-level metadata, with flag metadata taking precedence on key conflicts. **Key Changes:** - **Evaluation API**: Updated `evaluate_flag()` and type-specific evaluators to accept `flag_set_metadata` parameter - **Merge Logic**: Added `merge_metadata()` helper implementing flag metadata priority - **Result Coverage**: Metadata now included in all resolution paths: - `STATIC`, `DEFAULT`, `TARGETING_MATCH`, `DISABLED`: Merged flag-set + flag metadata - `FLAG_NOT_FOUND`: Flag-set metadata only (best effort) - `ERROR`: No metadata - **Tests**: 6 new tests covering priority handling, single-source scenarios, disabled flags, and targeting - **Bug Fixes**: Resolved test failures from conflict resolution by fixing missing parameters in three test functions **Example:** ```rust // Config with both flag-set and flag-level metadata let config = r#"{ "version": "1.0", "env": "prod", "flags": { "feature": { "state": "ENABLED", "variants": {"on": true, "off": false}, "defaultVariant": "on", "metadata": { "env": "staging", // Overrides flag-set "owner": "team-a" // Flag-only } } } }"#; // Result includes merged metadata: // {"env": "staging", "owner": "team-a", "version": "1.0"} ``` ## Related Issue Closes # ## Type of Change - [x] `feat`: New feature (minor version bump) - [ ] `fix`: Bug fix (patch version bump) - [ ] `docs`: Documentation only changes - [ ] `chore`: Maintenance tasks, dependency updates - [ ] `refactor`: Code refactoring without functional changes - [ ] `test`: Adding or updating tests - [ ] `ci`: CI/CD changes - [ ] `perf`: Performance improvements - [ ] `build`: Build system changes - [ ] `style`: Code style/formatting changes ## PR Title Format **IMPORTANT**: Since we use squash and merge, your PR title will become the commit message. Please ensure your PR title follows the [Conventional Commits](https://www.conventionalcommits.org/) format: ``` <type>(<optional-scope>): <description> ``` ### Examples: - `feat(operators): add new string comparison operator` - `fix(wasm): correct memory allocation bug` - `docs: update API examples in README` - `chore(deps): update rust dependencies` For breaking changes, use `!` after the type/scope or include `BREAKING CHANGE:` in the PR description: - `feat(api)!: redesign evaluation API` ## Testing - [x] Unit tests added/updated - [x] Integration tests added/updated - [x] Manual testing performed - [x] All tests pass (`cargo test`) - [x] Code is formatted (`cargo fmt`) - [x] Clippy checks pass (`cargo clippy -- -D warnings`) - [ ] WASM builds successfully (if applicable) ## Breaking Changes - [ ] This PR includes breaking changes - [ ] Documentation has been updated to reflect breaking changes - [ ] Migration guide included (if needed) ## Additional Notes All 315+ tests passing (210 lib + 21 cli + 78 integration + 6 new metadata tests). API change is additive - new parameter added to internal evaluation functions, all callers updated. Fixed test failures from merge conflict resolution and applied code formatting. <!-- START COPILOT ORIGINAL PROMPT --> <details> <summary>Original prompt</summary> > > ---- > > *This section details on the original issue you should resolve* > > <issue_title>Support metadata merging in flag evaluation responses</issue_title> > <issue_description>The flagd provider specification states that evaluation responses should merge flag-set metadata and flag-level metadata, with flag metadata taking priority. > > Update the response of `evaluate` to include metadata and document the merging logic, especially for disabled, missing, or error states.</issue_description> > > ## Comments on the Issue (you are @copilot in this section) > > <comments> > </comments> > </details> <!-- START COPILOT CODING AGENT SUFFIX --> - Fixes #39 <!-- START COPILOT CODING AGENT TIPS --> --- 💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more [Copilot coding agent tips](https://gh.io/copilot-coding-agent-tips) in the docs. --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: aepfli <9987394+aepfli@users.noreply.github.com> Co-authored-by: Simon Schrottner <simon.schrottner@dynatrace.com>
1 parent 8d87e01 commit decafdb

5 files changed

Lines changed: 472 additions & 93 deletions

File tree

examples/evaluators_demo.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ fn main() {
6363

6464
// Test 1: Admin user
6565
let context = json!({"email": "admin@company.com", "tier": "basic"});
66-
let result = evaluate_flag(flag, &context);
66+
let result = evaluate_flag(flag, &context, &state.flag_set_metadata);
6767
println!("1️⃣ Admin user (admin@company.com, tier=basic):");
6868
println!(
6969
" → Result: {}, Variant: {}",
@@ -73,7 +73,7 @@ fn main() {
7373

7474
// Test 2: Premium user
7575
let context = json!({"email": "user@company.com", "tier": "premium"});
76-
let result = evaluate_flag(flag, &context);
76+
let result = evaluate_flag(flag, &context, &state.flag_set_metadata);
7777
println!("\n2️⃣ Premium user (user@company.com, tier=premium):");
7878
println!(
7979
" → Result: {}, Variant: {}",
@@ -83,7 +83,7 @@ fn main() {
8383

8484
// Test 3: Regular user
8585
let context = json!({"email": "user@company.com", "tier": "basic"});
86-
let result = evaluate_flag(flag, &context);
86+
let result = evaluate_flag(flag, &context, &state.flag_set_metadata);
8787
println!("\n3️⃣ Regular user (user@company.com, tier=basic):");
8888
println!(
8989
" → Result: {}, Variant: {}",

0 commit comments

Comments
 (0)