control-plane-api: add a root effectiveAlertConfig(catalogPrefixOrName:) query - #3227
Merged
Conversation
GregorShear
commented
Jul 23, 2026
| pub struct PrefixFilter { | ||
| /// Match rows whose value is prefixed by this string. | ||
| pub starts_with: Option<String>, | ||
| /// Match the single row whose value equals this string exactly. |
Contributor
Author
There was a problem hiding this comment.
i'm not sure why this has to be a single row - could be multiple rows that have the same prefix, right?
GregorShear
force-pushed
the
greg/effective-config
branch
from
July 23, 2026 02:00
b7bcd02 to
2a516b7
Compare
4 tasks
GregorShear
force-pushed
the
greg/effective-config
branch
from
July 23, 2026 20:38
2a516b7 to
e2fcce7
Compare
GregorShear
changed the base branch from
master
to
greg/gql-storage-mappings-filter
July 23, 2026 20:38
GregorShear
commented
Jul 23, 2026
| let policy_result = crate::server::evaluate_names_authorization( | ||
| env.snapshot(), | ||
| claims, | ||
| models::Capability::Read, |
Contributor
Author
There was a problem hiding this comment.
could we use the capability_bit instead of legacy capability?
GregorShear
force-pushed
the
greg/effective-config
branch
from
July 23, 2026 20:51
e2fcce7 to
fe12453
Compare
GregorShear
force-pushed
the
greg/gql-storage-mappings-filter
branch
3 times, most recently
from
July 24, 2026 20:38
572cb9c to
95c7343
Compare
jshearer
previously approved these changes
Jul 27, 2026
jshearer
left a comment
Contributor
There was a problem hiding this comment.
LGTM, left a couple nits -- need to rebase ontop of master once the base branch is merged, regenerate graphql schema etc. Plus a test coverage nit and an error message nit
Let me know once you rebase/regen gql and I'll re-approve
GregorShear
force-pushed
the
greg/effective-config
branch
from
July 27, 2026 19:29
fe12453 to
7685414
Compare
GregorShear
changed the base branch from
greg/gql-storage-mappings-filter
to
master
July 27, 2026 19:30
…me:)` query Adds a top-level query that resolves the effective alert config at a single prefix or catalog name, merging all ancestor prefix layers and controller defaults, with per-field provenance. Unlike the existing field-level accessors (`AlertConfigEntry.effective`, `LiveSpec.effectiveAlertConfig`), this takes an arbitrary `catalogPrefixOrName` and does not require an `alert_configs` row to exist at that scope — so it answers for prefixes and names that carry no explicit config and are therefore absent from the `alertConfigs` listing. The caller must have `CatalogRead` capability on the scope; ancestor layers merged into the result are visible to anyone who can read the scope, matching the field-level accessors. Reuses the existing `resolve_effective_alert_config` helper and its provenance output. `validate_prefix_or_name` now rejects a slash-less token (e.g. `aliceCo`): it is neither a prefix nor a real catalog name, so it previously validated as a bare `Name` and then failed authorization with a confusing `PermissionDenied`. It now returns a clear validation error suggesting the trailing-slash prefix form, matching the slash requirement the mutation path already enforces via `governing_prefix`. Test coverage exercises defaults-only resolution, an inherited prefix override with provenance attribution, the exact-catalog-name layer, the slash-less validation rejection, and read-denied.
GregorShear
force-pushed
the
greg/effective-config
branch
from
July 27, 2026 20:23
7685414 to
d958300
Compare
jshearer
approved these changes
Jul 28, 2026
williamhbaker
pushed a commit
to estuary/homebrew-flowctl
that referenced
this pull request
Aug 12, 2026
## What's Changed * control-plane-api: fix storage-mapping suffix strip to respect path-segment boundaries by @GregorShear in estuary/flow#3239 * materialize: remove deprecated `constraints` from materialize protocol by @mdibaiee in estuary/flow#3104 * control-plane: verify delete permission for user storage mappings by @williamhbaker in estuary/flow#3197 * Gate invite-link private-DP grants on an existing private data plane by @GregorShear in estuary/flow#3234 * local: fix dashboard origin to the external UI (http://localhost:3000) by @jgraettinger in estuary/flow#3230 * data-plane-controller: add GitHub App git auth to replace SSH machine user by @skord in estuary/flow#3243 * data-plane-controller: fix broken deploy (comments in env/secrets block scalars) by @skord in estuary/flow#3250 * notifications: remove stale alert_notifications snapshot files by @jwhartley in estuary/flow#3079 * Docs: Link fixes, remove example pages by @aeluce in estuary/flow#3231 * data-plane-controller: cut git auth over to the GitHub App by @skord in estuary/flow#3249 * Docs: reference page for OpenSearch materialization by @aeluce in estuary/flow#3113 * vm: fix Lima development VMs on Linux hosts by @skord in estuary/flow#3267 * publisher: discard unauthorized recovered ACK intents by @jgraettinger in estuary/flow#3268 * docs: source-sqs by @Alex-Bair in estuary/flow#3201 * runtime-next: remove hardcoded materialization ser_policy fallback by @dgreer-dev in estuary/flow#3140 * runtime-v2: bind task terms to ShardSpec bytes and restart gracefully from Join-wait by @jgraettinger in estuary/flow#3264 * Extend `PrefixFilter` with `in` and add storage mapping query as a consumer by @GregorShear in estuary/flow#3242 * docs: add initial materialize-hubspot docs by @danielnelson in estuary/flow#3042 * shuffle: fix open-phase deadlock via EOF-cascade teardown by @jgraettinger in estuary/flow#3261 * docs: add dataMovementStalled threshold example and format by @jwhartley in estuary/flow#3251 * control-plane-api: add a root effectiveAlertConfig(catalogPrefixOrName:) query by @GregorShear in estuary/flow#3227 * runtime-next: stop constructing per-iteration timers in actor loops by @jgraettinger in estuary/flow#3273 * tests: update to projection constraints in ledger connector by @danielnelson in estuary/flow#3274 * docs: document _meta field selection and depth behavior by @jwhartley in estuary/flow#3209 * control-plane: refresh notification emails by @aeluce in estuary/flow#3179 * docs: source-braintree-native resources have configurable concurrency by @Alex-Bair in estuary/flow#3270 * docs: materialize-iceberg table_identifier_case and field_name_case options by @jacobmarble in estuary/flow#3262 * runtime-v2: fix shuffle recovery deadlock under split read cohorts by @jgraettinger in estuary/flow#3278 * 2781: Preemptively deploying states for Discovery and Publish by @bbartman in estuary/flow#3279 * Docs: Add Snowflake user type by @aeluce in estuary/flow#3280 * docs: rediscovery interval config setting for SQL capture connectors by @Alex-Bair in estuary/flow#3285 * docs: source-mailchimp-native by @nicolaslazo in estuary/flow#3288 * config-encryption: fix broken image and deploy from CI by @mdibaiee in estuary/flow#3308 * config-encryption: fix Cloud Run startup probe port by @mdibaiee in estuary/flow#3315 * Docs: Webhook capture organization and fixes by @aeluce in estuary/flow#3313 * Sync Schedule moved to runtime v2 by @dgreer-dev in estuary/flow#3269 * dekaf: fix avro schema when property type is invalid by @danielnelson in estuary/flow#3301 * docs: source-brevo rewrite by @Alex-Bair in estuary/flow#3316 * docs: AWS IAM auth cross-account guidance, correct Identity Provider ARN wording by @jwhartley in estuary/flow#3298 * Local-stack QA quality of life: arm64 connector containers, child-process cleanup, readiness by @jgraettinger in estuary/flow#3276 * control-plane-api: remove dead evolutions module by @jshearer in estuary/flow#3302 * Introduce an indirect form of built specifications by @jgraettinger in estuary/flow#3303 * docs: clarify BYOK KMS is decrypt-only and identity may not be in dashboard by @jwhartley in estuary/flow#3065 * shuffle: gate the causal-hint stall timeout on a requested checkpoint by @williamhbaker in estuary/flow#3323 * docs: source-shopify-native add markets stream by @Alex-Bair in estuary/flow#3331 * docs: source-commercetools by @Alex-Bair in estuary/flow#3332 **Full Changelog**: estuary/flow@v0.6.12...v0.6.13
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a top-level
effectiveAlertConfig(catalogPrefixOrName:)GraphQL query that resolves the effective alert config at a single prefix or catalog name — merging all ancestor prefix layers and controller defaults, with per-field provenance.Why a root query
Master already exposes effective config as fields (
AlertConfigEntry.effective,LiveSpec.effectiveAlertConfig), which only answer for scopes that have an entry or a live spec. This root query takes an arbitrarycatalogPrefixOrNameand does not require analert_configsrow to exist there, so it answers for prefixes and names that carry no explicit config and are therefore absent from thealertConfigslisting.It reuses the existing
resolve_effective_alert_confighelper and its provenance output; auth requiresCatalogReadon the scope, matching the field-level accessors.Input validation
validate_prefix_or_namenow rejects a slash-less token likealiceCo. Such a token is neither a prefix (no trailing/) nor a real catalog name (names are always hierarchical), so it previously validated as a bareNameand then failed authorization with a confusingPermissionDenied— a grant ataliceCo/never covers the bare stringaliceCo. It now returns a validation error pointing at the trailing-slash prefix form, matching the slash requirement the mutation path already enforces viagoverning_prefix.Testing
test_effective_alert_config_querycovers:source: null)aliceCo/in/capture-foo)SDL regenerated.