Skip to content

feat: decouple feature flag composition when split config is enabled - #3034

Merged
wilsonrivera merged 23 commits into
mainfrom
wilson/eng-9783-controlplane-decouple-feature-flag-composition-when-split
Jul 6, 2026
Merged

feat: decouple feature flag composition when split config is enabled#3034
wilsonrivera merged 23 commits into
mainfrom
wilson/eng-9783-controlplane-decouple-feature-flag-composition-when-split

Conversation

@wilsonrivera

@wilsonrivera wilsonrivera commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Summary by CodeRabbit

  • New Features
    • Added feature-flag-based graph composition support with surfaced indicators and feature-flag name in composition details.
    • Enabled split-config loading to control backend composition/deploy behavior and Studio composition page columns/tabs.
  • Bug Fixes
    • Improved feature-flag composition linking, subgraph reconciliation, and “latest valid” evaluation.
    • Refined affected-graph reconciliation and old-data cleanup to align with updated feature-flag composition relationships.
  • Database / Schema
    • Updated the feature-flag composition schema-version mapping (nullable base composition, primary key change, and supporting composite index).
  • Tests
    • Adjusted test coverage for split-config loading expectations in latest-composition feature flag results.

Checklist

Open Source AI Manifesto

This project follows the principles of the Open Source AI Manifesto. Please ensure your contribution aligns with its principles.

split-config-compositions

@coderabbitai

coderabbitai Bot commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Adds feature-flag composition fields to proto, generated code, and DTOs. Updates the feature-flag mapping table and migration to allow nullable base schema version IDs and a new key layout. Threads splitConfigEnabled through composition persistence and deploy logic, updates composition history lookups, and surfaces feature-flag composition metadata in Studio.

Changes

Feature Flag Composition Metadata and Split-Config Wiring

Layer / File(s) Summary
Proto, DTO, and DB schema changes
proto/wg/cosmo/platform/v1/platform.proto, connect/src/wg/cosmo/platform/v1/platform_pb.ts, controlplane/src/types/index.ts, controlplane/src/db/schema.ts, controlplane/migrations/0145_wild_lady_bullseye.sql, controlplane/migrations/meta/_journal.json
GraphComposition gains isFeatureFlagComposition and featureFlagName in proto and generated code; GraphCompositionDTO is extended; federatedGraphsToFeatureFlagSchemaVersions makes baseCompositionSchemaVersionId nullable, changes its primary key, adds fgffsv_composite_idx, and records the migration.
Feature-flag schema version selection
controlplane/src/core/repositories/FeatureFlagRepository.ts
getFeatureFlagSchemaVersionByBaseSchemaVersion now checks the split-config-loading organization feature and changes its schema-version filter accordingly.
GraphCompositionRepository feature-flag composition logic
controlplane/src/core/repositories/GraphCompositionRepository.ts
addComposition accepts featureFlagId and branches previous-composition lookup for feature-flag and non-feature-flag paths; subgraph reconciliation changes how added, updated, unchanged, and removed subgraphs are derived; composition reads select and return feature-flag metadata and use new validity helpers; getCompositionSubgraphs can include child composition subgraphs.
FederatedGraphRepository addSchemaVersion split-config wiring
controlplane/src/core/repositories/FederatedGraphRepository.ts
addSchemaVersion accepts splitConfigEnabled, stores a null baseCompositionSchemaVersionId for feature-flag inserts when split config is enabled, and passes featureFlagId into compositionRepo.addComposition.
Composer and CompositionService splitConfigEnabled threading
controlplane/src/core/composition/composer.ts, controlplane/src/core/services/CompositionService.ts
Composer.saveComposition accepts and forwards splitConfigEnabled; CompositionService passes splitConfigEnabled through compose and deploy flows and uses it to gate router config population, path overrides, and deployFeatureFlags calls.
Subgraph lookup and cleanup updates
controlplane/src/core/repositories/SubgraphRepository.ts, controlplane/src/bin/cleanup-old-data.ts, controlplane/src/core/bufservices/federated-graph/getCompositionDetails.ts
Feature-subgraph label lookup excludes contract federated graphs; cleanup-old-data stops retaining the unused deleteOldSchemaVersions return value and filters out falsy baseCompositionSchemaVersionId values before mapping them; composition details now fetch subgraphs using the resolved composition id and schema version id.
Studio compositions UI feature-flag column and detail gating
studio/src/pages/[organizationSlug]/[namespace]/graph/[slug]/compositions/index.tsx, studio/src/pages/[organizationSlug]/[namespace]/graph/[slug]/compositions/[compositionId]/index.tsx
The compositions list page gates feature-flag composition loading on split-config-loading, conditionally shows a Feature Flag column, and renders badges from the new fields; the composition detail page derives isFeatureFlagComposition and hides the feature-flag tab for feature-flag compositions.
Feature-flag latest-composition test updates
controlplane/test/feature-flag/get-feature-flags-in-latest-composition-by-federated-graph.test.ts
The feature-flag latest-composition test now runs with split-config-loading enabled, expects no feature flags from the latest-composition lookup, and verifies the compositions list instead of the previous feature-flag list assertions.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • wundergraph/cosmo#2903: Modifies FederatedGraphRepository.addSchemaVersion and GraphCompositionRepository.addComposition, the same persistence path extended here.
  • wundergraph/cosmo#2969: Modifies the recomposeAndDeployAffectedBatch / persistAndUploadBatch path in CompositionService, which this PR threads with splitConfigEnabled.
  • wundergraph/cosmo#2847: Changes the router-side split-config-loading flow that consumes the split-config outputs this PR deploys.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly matches the main change: decoupling feature flag composition behavior when split config is enabled.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

Comment @coderabbitai help to get the list of available commands.

@codecov

codecov Bot commented Jun 30, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 89.81818% with 28 lines in your changes missing coverage. Please review.
✅ Project coverage is 43.43%. Comparing base (f9789a3) to head (82efb3a).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
[...g]/[namespace]/graph/[slug]/compositions/index.tsx](https://app.codecov.io/gh/wundergraph/cosmo/pull/3034?src=pr&el=tree&filepath=studio%2Fsrc%2Fpages%2F%5BorganizationSlug%5D%2F%5Bnamespace%5D%2Fgraph%2F%5Bslug%5D%2Fcompositions%2Findex.tsx&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=wundergraph#diff-c3R1ZGlvL3NyYy9wYWdlcy9bb3JnYW5pemF0aW9uU2x1Z10vW25hbWVzcGFjZV0vZ3JhcGgvW3NsdWddL2NvbXBvc2l0aW9ucy9pbmRleC50c3g=) 0.00% 13 Missing ⚠️
...raph/[slug]/compositions/[compositionId]/index.tsx 0.00% 7 Missing ⚠️
...ane/src/core/repositories/FeatureFlagRepository.ts 75.00% 4 Missing ⚠️
controlplane/src/bin/cleanup-old-data.ts 0.00% 2 Missing ⚠️
...rc/core/repositories/GraphCompositionRepository.ts 98.99% 2 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##             main    #3034       +/-   ##
===========================================
- Coverage   61.69%   43.43%   -18.27%     
===========================================
  Files         261     1069      +808     
  Lines       30602   139019   +108417     
  Branches        0     7229     +7229     
===========================================
+ Hits        18881    60385    +41504     
- Misses      10201    76779    +66578     
- Partials     1520     1855      +335     
Files with missing lines Coverage Δ
...fservices/federated-graph/getCompositionDetails.ts 93.02% <100.00%> (ø)
...ices/federated-graph/getFederatedGraphSDLByName.ts 66.66% <100.00%> (ø)
controlplane/src/core/composition/composer.ts 67.71% <100.00%> (ø)
.../src/core/repositories/FederatedGraphRepository.ts 84.99% <100.00%> (ø)
...ntrolplane/src/core/services/CompositionService.ts 87.96% <100.00%> (ø)
controlplane/src/db/schema.ts 100.00% <100.00%> (ø)
controlplane/src/types/index.ts 100.00% <ø> (ø)
controlplane/src/bin/cleanup-old-data.ts 0.00% <0.00%> (ø)
...rc/core/repositories/GraphCompositionRepository.ts 98.45% <98.99%> (ø)
...ane/src/core/repositories/FeatureFlagRepository.ts 92.42% <75.00%> (ø)
... and 2 more

... and 813 files with indirect coverage changes

🚀 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.

@github-actions

github-actions Bot commented Jun 30, 2026

Copy link
Copy Markdown

Router image scan passed

✅ No security vulnerabilities found in image:

ghcr.io/wundergraph/cosmo/router:sha-c537fd85a2aa49f176c1f5cb04ac964a5cd6009a

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@studio/src/pages/`[organizationSlug]/[namespace]/graph/[slug]/compositions/[compositionId]/index.tsx:
- Around line 647-648: Normalize the active tab in the composition details page
when feature-flag compositions are hidden: the current `Tabs` value can still
point to `ffCompostions` even though `featureFlagCompositions` is being omitted,
leaving no valid panel selected. Update the tab selection logic in the
composition page component (`Tabs` / selected tab state around
`isFeatureFlagComposition` and `featureFlagCompositions`) so that when
`isFeatureFlagComposition` is true, the selected tab is coerced to a valid
default tab instead of preserving the invalid feature-flag tab value.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: cb91eff0-aa70-45ce-9f88-e9414dd6ee7b

📥 Commits

Reviewing files that changed from the base of the PR and between 9ccfaf2 and 0c26d31.

⛔ Files ignored due to path filters (1)
  • connect-go/gen/proto/wg/cosmo/platform/v1/platform.pb.go is excluded by !**/*.pb.go, !**/gen/**
📒 Files selected for processing (15)
  • connect/src/wg/cosmo/platform/v1/platform_pb.ts
  • controlplane/migrations/0145_wild_lady_bullseye.sql
  • controlplane/migrations/meta/0145_snapshot.json
  • controlplane/migrations/meta/_journal.json
  • controlplane/src/bin/cleanup-old-data.ts
  • controlplane/src/core/composition/composer.ts
  • controlplane/src/core/repositories/FederatedGraphRepository.ts
  • controlplane/src/core/repositories/GraphCompositionRepository.ts
  • controlplane/src/core/repositories/SubgraphRepository.ts
  • controlplane/src/core/services/CompositionService.ts
  • controlplane/src/db/schema.ts
  • controlplane/src/types/index.ts
  • proto/wg/cosmo/platform/v1/platform.proto
  • studio/src/pages/[organizationSlug]/[namespace]/graph/[slug]/compositions/[compositionId]/index.tsx
  • studio/src/pages/[organizationSlug]/[namespace]/graph/[slug]/compositions/index.tsx

@coderabbitai coderabbitai 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.

🧹 Nitpick comments (1)
studio/src/pages/[organizationSlug]/[namespace]/graph/[slug]/compositions/[compositionId]/index.tsx (1)

211-213: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Prefer const for the normalized tab value.

This is a single derived value, so keeping both bindings immutable is simpler and matches the repo rule.

♻️ Proposed refactor
-  let tab = router.query.tab as string;
-  tab = isFeatureFlagComposition && tab === 'ffCompostions' ? 'output' : tab;
+  const requestedTab = router.query.tab as string;
+  const tab = isFeatureFlagComposition && requestedTab === 'ffCompostions' ? 'output' : requestedTab;

As per coding guidelines, **/*.{js,jsx,ts,tsx}: Prefer const over let and let over var.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@studio/src/pages/`[organizationSlug]/[namespace]/graph/[slug]/compositions/[compositionId]/index.tsx
around lines 211 - 213, The tab normalization in the composition page uses a
mutable binding even though it is only derived once; update the logic around
router.query.tab so the normalized tab value is assigned with const instead of
let. Keep the same behavior for the isFeatureFlagComposition and ffCompostions
check, but make both bindings immutable to match the repo’s const-over-let
guideline.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In
`@studio/src/pages/`[organizationSlug]/[namespace]/graph/[slug]/compositions/[compositionId]/index.tsx:
- Around line 211-213: The tab normalization in the composition page uses a
mutable binding even though it is only derived once; update the logic around
router.query.tab so the normalized tab value is assigned with const instead of
let. Keep the same behavior for the isFeatureFlagComposition and ffCompostions
check, but make both bindings immutable to match the repo’s const-over-let
guideline.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: d39c7abe-3648-4a76-9607-f80fd1c3db30

📥 Commits

Reviewing files that changed from the base of the PR and between 0c26d31 and b3c32cc.

📒 Files selected for processing (1)
  • studio/src/pages/[organizationSlug]/[namespace]/graph/[slug]/compositions/[compositionId]/index.tsx

@coderabbitai coderabbitai 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.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@controlplane/src/core/repositories/FeatureFlagRepository.ts`:
- Around line 1397-1402: The split-config lookup in FeatureFlagRepository should
stay scoped to the base federated graph instead of filtering only by
featureFlagId. Update the conditional branch in the query that uses
splitConfigFeature?.enabled to also derive the federated graph from
baseSchemaVersionId and add
federatedGraphsToFeatureFlagSchemaVersions.federatedGraphId to that filter,
matching the scope used by the non-split branch.

In `@controlplane/src/core/repositories/GraphCompositionRepository.ts`:
- Around line 403-408: The child subgraph query in GraphCompositionRepository
currently joins all feature-flag schema-version rows for a base schema version,
which can include stale recomposition entries. Update the query that builds the
composed subgraphs to first select only the latest row per feature flag/base
composition pair, then join that filtered set to graphCompositions so
hasMultipleChangedSubgraphs and triggeredBySubgraphName are based on the most
recent composition only. Use the existing latest-per-feature-flag selection
pattern already used elsewhere in GraphCompositionRepository as the reference
for the join/filter logic.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: aa1adba5-e5b1-4065-876a-b8d7b6e52399

📥 Commits

Reviewing files that changed from the base of the PR and between b3c32cc and edccc3c.

📒 Files selected for processing (5)
  • controlplane/src/core/bufservices/federated-graph/getCompositionDetails.ts
  • controlplane/src/core/repositories/FeatureFlagRepository.ts
  • controlplane/src/core/repositories/GraphCompositionRepository.ts
  • controlplane/test/feature-flag/get-feature-flags-in-latest-composition-by-federated-graph.test.ts
  • studio/src/pages/[organizationSlug]/[namespace]/graph/[slug]/compositions/index.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • studio/src/pages/[organizationSlug]/[namespace]/graph/[slug]/compositions/index.tsx

Comment thread controlplane/src/core/repositories/FeatureFlagRepository.ts
Comment thread controlplane/src/core/repositories/GraphCompositionRepository.ts

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

🧹 Nitpick comments (1)
controlplane/test/feature-flag/get-feature-flags-in-latest-composition-by-federated-graph.test.ts (1)

106-108: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Stray line-continuation backslash in comment.

The comment at line 107 ends with a trailing \ before the line break, which is a leftover artifact (likely from copy/paste) and serves no purpose inside a // comment.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@controlplane/test/feature-flag/get-feature-flags-in-latest-composition-by-federated-graph.test.ts`
around lines 106 - 108, Remove the stray trailing line-continuation backslash
from the comment in
get-feature-flags-in-latest-composition-by-federated-graph.test.ts so the
explanatory text around recomposeFeatureFlag reads cleanly; keep the comment
content the same, just delete the unnecessary backslash artifact.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@controlplane/test/feature-flag/get-feature-flags-in-latest-composition-by-federated-graph.test.ts`:
- Around line 123-132: The inline comment in
getFeatureFlagsInLatestCompositionByFederatedGraph test is stale and contradicts
the assertion. Update the comment near withSecondFlag in the test to match the
current split-config-loading behavior: the second flag may be composed, but it
is not surfaced in featureFlags, so the expected length remains 0. Keep the
assertion unchanged and make the comment align with the actual behavior of
client.getFeatureFlagsInLatestCompositionByFederatedGraph and createFeatureFlag.

---

Nitpick comments:
In
`@controlplane/test/feature-flag/get-feature-flags-in-latest-composition-by-federated-graph.test.ts`:
- Around line 106-108: Remove the stray trailing line-continuation backslash
from the comment in
get-feature-flags-in-latest-composition-by-federated-graph.test.ts so the
explanatory text around recomposeFeatureFlag reads cleanly; keep the comment
content the same, just delete the unnecessary backslash artifact.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 4d505270-c761-4bb6-a1e8-0bb3b0db1ebe

📥 Commits

Reviewing files that changed from the base of the PR and between edccc3c and 5bffba4.

📒 Files selected for processing (2)
  • controlplane/test/feature-flag/get-feature-flags-in-latest-composition-by-federated-graph.test.ts
  • studio/src/pages/[organizationSlug]/[namespace]/graph/[slug]/compositions/index.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • studio/src/pages/[organizationSlug]/[namespace]/graph/[slug]/compositions/index.tsx

@wilsonrivera
wilsonrivera marked this pull request as ready for review June 30, 2026 20:54
@wilsonrivera
wilsonrivera requested review from a team as code owners June 30, 2026 20:54
Comment thread controlplane/src/core/repositories/FeatureFlagRepository.ts
Comment thread controlplane/src/core/repositories/GraphCompositionRepository.ts
Comment thread controlplane/src/core/repositories/FeatureFlagRepository.ts Outdated
…e-flag-composition-when-split

# Conflicts:
#	connect/src/wg/cosmo/platform/v1/platform_pb.ts
@wilsonrivera
wilsonrivera merged commit f704e34 into main Jul 6, 2026
51 checks passed
@wilsonrivera
wilsonrivera deleted the wilson/eng-9783-controlplane-decouple-feature-flag-composition-when-split branch July 6, 2026 14:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants