You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This is the largest and most complex domain. It covers the entire user workflow of creating, editing, validating, and publishing catalog specifications.
PostgREST endpoints in use:
Endpoint
Type
UI
flowctl
Operations
GraphQL?
drafts
table
SELECT, INSERT, DELETE
SELECT, INSERT, DELETE
Full CRUD for change-sets
None
drafts_ext
view
SELECT
SELECT
List drafts with computed fields
None
draft_specs
table
SELECT, INSERT, UPDATE, DELETE, UPSERT
SELECT, INSERT, DELETE
Core spec editing
None
draft_specs_ext
view
SELECT
SELECT
Extended draft specs with authz
None
draft_errors
view
SELECT
SELECT
Validation error display
None
publications
table
INSERT, SELECT (polling)
INSERT
Trigger publish, poll for completion
None
publication_specs_ext
view
SELECT
SELECT
Publication history with user info
Partial: flowctl catalog history uses GraphQL PublicationHistoryQuery; UI still uses PostgREST
discovers
table
INSERT, SELECT (polling)
INSERT, SELECT
Auto-discovery of connector resources
None
view_logs
RPC
yes
yes
Stream job logs during publish/discover
None
Existing GraphQL coverage: flowctl's catalog history command uses a PublicationHistoryQuery via GraphQL, which queries publication history for a specific live spec. The UI does not use this yet.
Need to figure out what to do about drafts, as well as migrating the UI; flowctl ought to be fairly straightforward
view_logs is a polling-based log streaming mechanism that will need a GraphQL equivalent. Maybe polling, maybe SSE
Estimated size: XL. This is probably 40-50% of the total migration work.
2. Live Specs
The "read" side of the catalog: querying what's currently deployed.
Endpoint
Type
UI
flowctl
Operations
GraphQL?
live_specs
table
SELECT
SELECT
Fetch active specs
GraphQL exists (backend + flowctl)
live_specs_ext
view
SELECT (heavy)
SELECT
Denormalized view with connector info, shard labels, stats
Partial: GraphQL liveSpecs query covers core fields; _ext columns (connector image, shard labels, writes_to/reads_from as text) not all exposed
live_spec_flows
table
SELECT
-
Data lineage (source/target relationships)
GraphQL exists as readsFrom/writesTo/readBy/writtenBy on LiveSpec type
Existing GraphQL coverage:
Backend: liveSpecs query with filtering by prefix, name, catalog type, data plane. Includes readsFrom, writesTo, readBy, writtenBy relationship traversal.
flowctl: catalog list and catalog status fully migrated to GraphQL.
UI: Uses GraphQL liveSpecs query in src/api/gql/liveSpecs.ts for entity listing (catalog names + types). But the main entity tables and detail views still use live_specs_ext via PostgREST extensively (dozens of query variants in src/api/liveSpecsExt.ts and src/hooks/useLiveSpecsExt.ts).
Migration notes: The live_specs_ext view is the single most heavily queried PostgREST endpoint in the UI. It joins live_specs with connectors, connector_tags, user profiles, and data planes to produce a denormalized row. Migrating this requires either:
Expanding the GraphQL LiveSpec type to expose all the joined fields the UI needs (connector image name/tag, logo URL, shard labels, writes_to/reads_from text columns, last_pub_user_* fields)
Or building new UI components that compose multiple GraphQL queries
Estimated size: L. High value because live_specs_ext is so heavily used. Already ~50% complete
3. Connectors
Endpoint
Type
UI
flowctl
Operations
GraphQL?
connectors
table
SELECT (with nested connector_tags)
SELECT
Connector registry/menu
GraphQL exists (backend); UI not yet migrated
connector_tags
table
SELECT
SELECT
Connector versions and schemas
GraphQL exists as ConnectorSpec (backend); UI not yet migrated
Backend: connectors query (paginated, filterable by protocol), connector lookup (by image name or ID), connectorSpec resolver (full image name to spec). PR graphql: add basic connector queries #2757 is merged.
flowctl: encrypt.rs already migrated to use connectorSpec GraphQL query.
UI: Travis has been integrating locally off the PR branch. The UI still queries connectors and connector_tags via PostgREST in the meantime.
Estimated size: S. Backend ready; UI work in progress (estuary/ui#1949)
4. Authorization and Grants
Endpoint
Type
UI
flowctl
Operations
GraphQL?
combined_grants_ext
view
SELECT
SELECT
Combined user+role grants view
None
user_grants
table
SELECT, INSERT, UPDATE, DELETE
SELECT, INSERT, UPDATE, DELETE
Per-user prefix permissions
None
role_grants
table
SELECT, INSERT, DELETE
SELECT, INSERT, UPDATE, DELETE
Role-to-role delegation
None
auth_roles
RPC
SELECT (GQL for support users, PostgREST for regular users)
-
Get user's authorized prefixes
Partial: GraphQL prefixes query used in UI for support staff only (regular users still use PostgREST due to snapshot staleness bounded by MIN_REFRESH_INTERVAL=20s / MAX_REFRESH_INTERVAL=5min, worst case ~5min not ~30s; see GRAPHQL.md); flowctl auth list fully migrated
directives
table
SELECT, INSERT, UPDATE
-
Privileged operations (org provisioning, grant tokens)
None
applied_directives
table
SELECT, UPDATE
-
User-applied directives with claims
None
exchange_directive_token
RPC
yes
-
Redeem bearer tokens for directives
None
Existing GraphQL coverage:
auth_roles RPC: the GraphQL prefixes query exists and is used by flowctl (auth list) and the UI's EntitiesHydratorForSupport. However, the UI only uses GraphQL for users with the support role. Regular users still use PostgREST via EntitiesHydrator → useHydrateStateWithPostgres because the auth snapshot refreshes on an interval, and first-time-user flows can hit the worst case and not see their newly-created tenant.
inviteLinks (query, create, redeem, delete) are fully on GraphQL in both backend and UI. These partially overlap with the directives mechanism but are a separate system.
Migration notes:combined_grants_ext is a complex view joining user_grants, role_grants, and user profile information. The UI uses it for the access grants admin panel and user information lookups. user_grants and role_grants are full CRUD from both UI and flowctl. Directives are a somewhat isolated subsystem (org provisioning, grant links) used in onboarding flows that we may want to transition away from now that we have an actual API.
Estimated size: L. CRUD operations on grants tables + the combined_grants_ext view denormalization + directives subsystem.
5. Alerts and Monitoring
Endpoint
Type
UI
flowctl
Operations
GraphQL?
alert_history
table
-
-
(direct table not queried)
GraphQL only
alert_subscriptions
table
SELECT (legacy check)
-
Legacy subscription check
GraphQL primary
alert_data_processing
table
INSERT, UPDATE, DELETE
-
Per-task data processing alert config
Being replaced by GraphQL
Alert queries
GQL
SELECT
SELECT
Alert history, active alerts
GraphQL only
Alert subscriptions
GQL
Full CRUD
Full CRUD
Subscription management
GraphQL only
Alert types
GQL
SELECT
-
Alert type metadata
GraphQL only
Existing GraphQL coverage: This domain is the most fully migrated:
Alert history querying: GraphQL only (UI AlertHistory table component uses gql directly)
Alert subscriptions: Full CRUD via GraphQL mutations in both UI and flowctl
alert_subscriptions table: one legacy PostgREST query (getNotificationSubscriptionForUser) that checks whether a specific email is subscribed to a prefix. This could likely be replaced by the existing GraphQL alertSubscriptions query.
Estimated size: S. Just alert_data_processing CRUD and one legacy subscription check to migrate.
6. Infrastructure (Data Planes, Storage Mappings)
Endpoint
Type
UI
flowctl
Operations
GraphQL?
data_planes
table
SELECT (via GQL + PostgREST)
SELECT
Data plane listing
GraphQL primary
storage_mappings
table
SELECT (via GQL + PostgREST)
SELECT
Storage config
GraphQL primary
republish_prefix
RPC
yes
-
Republish after storage mapping change
None
Existing GraphQL coverage: This domain is almost fully migrated:
Data planes: GraphQL dataPlanes query used by UI (src/api/gql/dataPlanes.ts) and available in backend
Storage mappings: Full GraphQL coverage in UI. Queries (storageMappings), mutations (createStorageMapping, updateStorageMapping), and health checks (testConnectionHealth) all implemented in src/api/gql/storageMappings.ts
Remaining PostgREST usage:
data_planes via PostgREST: flowctl still uses PostgREST (local_specs.rs). UI has some residual PostgREST calls for data plane lookups outside the new storage mapping admin flow.
storage_mappings via PostgREST: flowctl still uses PostgREST (local_specs.rs). The UI's entities store hydrator (useStorageMappingsHydrator) still calls getAllStorageMappingStores() via PostgREST.
republish_prefix RPC: called from the UI after storage mapping updates. No GraphQL equivalent.
Estimated size: S. Mostly cleanup of residual PostgREST calls and migrating republish_prefix.
The billing edge functions (supabase/functions/billing/) wrap Stripe API calls and are separate from PostgREST. We want to migrate all of them into GraphQL queries/mutations. See Migrate billing edge functions to GraphQL #2879 for the edge function migration
The tenants table is used for billing context (trial dates, payment provider, GCM account ID) and to check hide_preview flags.
catalog_stats is heavily used in the UI dashboard for usage charts.
billing_report_202308 (generating invoices) remains in the database for now. Ultimately I would love to also migrate this to Rust, but that's out of scope.
Estimated size: M-L. catalog_stats has complex time-series queries with grain filtering. Billing is a separate subsystem with its own edge functions. tenants is relatively simple reads.
8. Schema
Endpoint
Type
UI
flowctl
Operations
GraphQL?
inferred_schemas
table
SELECT
SELECT
Auto-inferred collection schemas
None
registered_avro_schemas
table
-
-
Avro schema registry (used by Dekaf)
None
Existing GraphQL coverage: None.
Migration notes:inferred_schemas is a straightforward read (fetch schema JSON by collection name). registered_avro_schemas is primarily consumed by Dekaf (data plane component), not the UI or flowctl directly. The UI reads inferred_schemas during capture/materialization editing.
Estimated size: S.
9. Auth and Tokens
Endpoint
Type
UI
flowctl
Operations
GraphQL?
refresh_tokens
table
SELECT, UPDATE
-
Token management admin UI
None
create_refresh_token
RPC
yes
-
Generate refresh tokens
None
generate_access_token
RPC
-
yes (flow-client-next)
Exchange refresh token for access token
None
user_info_summary
RPC
yes
-
Current user profile/summary
None
oauth
edge function
yes
-
OAuth connector config encryption
None
Existing GraphQL coverage: None.
Migration notes: Token management and the OAuth edge function are tied to Supabase's auth system. generate_access_token and create_refresh_token are part of the authentication flow that is tightly coupled to Supabase JWT infrastructure. These may be among the last things to migrate because they depend on how authentication works post-Supabase. user_info_summary is called on every UI session start.
1. Catalog Lifecycle (drafts, publications, discovers, evolutions)
This is the largest and most complex domain. It covers the entire user workflow of creating, editing, validating, and publishing catalog specifications.
PostgREST endpoints in use:
draftsdrafts_extdraft_specsdraft_specs_extdraft_errorspublicationspublication_specs_extcatalog historyuses GraphQLPublicationHistoryQuery; UI still uses PostgRESTdiscoversview_logsExisting GraphQL coverage: flowctl's
catalog historycommand uses aPublicationHistoryQueryvia GraphQL, which queries publication history for a specific live spec. The UI does not use this yet.RFC for this work lives at #2782
Migration notes: This is the hardest domain to migrate because:
createBuild/activateBuildmutation pairview_logsis a polling-based log streaming mechanism that will need a GraphQL equivalent. Maybe polling, maybe SSEEstimated size: XL. This is probably 40-50% of the total migration work.
2. Live Specs
The "read" side of the catalog: querying what's currently deployed.
live_specslive_specs_extliveSpecsquery covers core fields;_extcolumns (connector image, shard labels,writes_to/reads_fromas text) not all exposedlive_spec_flowsreadsFrom/writesTo/readBy/writtenByonLiveSpectypeExisting GraphQL coverage:
liveSpecsquery with filtering by prefix, name, catalog type, data plane. IncludesreadsFrom,writesTo,readBy,writtenByrelationship traversal.catalog listandcatalog statusfully migrated to GraphQL.liveSpecsquery insrc/api/gql/liveSpecs.tsfor entity listing (catalog names + types). But the main entity tables and detail views still uselive_specs_extvia PostgREST extensively (dozens of query variants insrc/api/liveSpecsExt.tsandsrc/hooks/useLiveSpecsExt.ts).Migration notes: The
live_specs_extview is the single most heavily queried PostgREST endpoint in the UI. It joinslive_specswithconnectors,connector_tags, user profiles, and data planes to produce a denormalized row. Migrating this requires either:LiveSpectype to expose all the joined fields the UI needs (connector image name/tag, logo URL, shard labels,writes_to/reads_fromtext columns,last_pub_user_*fields)Estimated size: L. High value because
live_specs_extis so heavily used. Already ~50% complete3. Connectors
connectorsconnector_tags)connector_tagsConnectorSpec(backend); UI not yet migratedconnectorsquery (paginated, filterable by protocol),connectorlookup (by image name or ID),connectorSpecresolver (full image name to spec). PR graphql: add basic connector queries #2757 is merged.encrypt.rsalready migrated to useconnectorSpecGraphQL query.connectorsandconnector_tagsvia PostgREST in the meantime.Estimated size: S. Backend ready; UI work in progress (estuary/ui#1949)
4. Authorization and Grants
combined_grants_extuser_grantsrole_grantsauth_rolesprefixesquery used in UI for support staff only (regular users still use PostgREST due to snapshot staleness bounded byMIN_REFRESH_INTERVAL=20s/MAX_REFRESH_INTERVAL=5min, worst case ~5min not ~30s; seeGRAPHQL.md); flowctlauth listfully migrateddirectivesapplied_directivesexchange_directive_tokenExisting GraphQL coverage:
auth_rolesRPC: the GraphQLprefixesquery exists and is used by flowctl (auth list) and the UI'sEntitiesHydratorForSupport. However, the UI only uses GraphQL for users with the support role. Regular users still use PostgREST viaEntitiesHydrator→useHydrateStateWithPostgresbecause the auth snapshot refreshes on an interval, and first-time-user flows can hit the worst case and not see their newly-created tenant.inviteLinks(query, create, redeem, delete) are fully on GraphQL in both backend and UI. These partially overlap with thedirectivesmechanism but are a separate system.Migration notes:
combined_grants_extis a complex view joininguser_grants,role_grants, and user profile information. The UI uses it for the access grants admin panel and user information lookups.user_grantsandrole_grantsare full CRUD from both UI and flowctl. Directives are a somewhat isolated subsystem (org provisioning, grant links) used in onboarding flows that we may want to transition away from now that we have an actual API.Estimated size: L. CRUD operations on grants tables + the
combined_grants_extview denormalization + directives subsystem.5. Alerts and Monitoring
alert_historyalert_subscriptionsalert_data_processingExisting GraphQL coverage: This domain is the most fully migrated:
AlertHistorytable component usesgqldirectly)AlertTypeQuery)Remaining PostgREST usage:
alert_data_processingtable: Being removed as part of Customizable alerting #2868alert_subscriptionstable: one legacy PostgREST query (getNotificationSubscriptionForUser) that checks whether a specific email is subscribed to a prefix. This could likely be replaced by the existing GraphQLalertSubscriptionsquery.Estimated size: S. Just
alert_data_processingCRUD and one legacy subscription check to migrate.6. Infrastructure (Data Planes, Storage Mappings)
data_planesstorage_mappingsrepublish_prefixExisting GraphQL coverage: This domain is almost fully migrated:
dataPlanesquery used by UI (src/api/gql/dataPlanes.ts) and available in backendstorageMappings), mutations (createStorageMapping,updateStorageMapping), and health checks (testConnectionHealth) all implemented insrc/api/gql/storageMappings.tsRemaining PostgREST usage:
data_planesvia PostgREST: flowctl still uses PostgREST (local_specs.rs). UI has some residual PostgREST calls for data plane lookups outside the new storage mapping admin flow.storage_mappingsvia PostgREST: flowctl still uses PostgREST (local_specs.rs). The UI's entities store hydrator (useStorageMappingsHydrator) still callsgetAllStorageMappingStores()via PostgREST.republish_prefixRPC: called from the UI after storage mapping updates. No GraphQL equivalent.Estimated size: S. Mostly cleanup of residual PostgREST calls and migrating
republish_prefix.7. Statistics and Billing
catalog_statstask_stats_by_dayinvoices_extbillingtenantsExisting GraphQL coverage: None.
Migration notes:
supabase/functions/billing/) wrap Stripe API calls and are separate from PostgREST. We want to migrate all of them into GraphQL queries/mutations. See Migrate billing edge functions to GraphQL #2879 for the edge function migrationtenantstable is used for billing context (trial dates, payment provider, GCM account ID) and to checkhide_previewflags.catalog_statsis heavily used in the UI dashboard for usage charts.billing_report_202308(generating invoices) remains in the database for now. Ultimately I would love to also migrate this to Rust, but that's out of scope.Estimated size: M-L.
catalog_statshas complex time-series queries with grain filtering. Billing is a separate subsystem with its own edge functions.tenantsis relatively simple reads.8. Schema
inferred_schemasregistered_avro_schemasExisting GraphQL coverage: None.
Migration notes:
inferred_schemasis a straightforward read (fetch schema JSON by collection name).registered_avro_schemasis primarily consumed by Dekaf (data plane component), not the UI or flowctl directly. The UI readsinferred_schemasduring capture/materialization editing.Estimated size: S.
9. Auth and Tokens
refresh_tokenscreate_refresh_tokengenerate_access_tokenuser_info_summaryoauthExisting GraphQL coverage: None.
Migration notes: Token management and the OAuth edge function are tied to Supabase's auth system.
generate_access_tokenandcreate_refresh_tokenare part of the authentication flow that is tightly coupled to Supabase JWT infrastructure. These may be among the last things to migrate because they depend on how authentication works post-Supabase.user_info_summaryis called on every UI session start.Related: #2774
Estimated size: M. Auth/token RPCs are small individually but coupled to Supabase auth infrastructure.
10. Misc
draft_collections_eligible_for_deletiongenerate_opengraph_valuetier_line_itemsEstimated size: XS.