Skip to content

Reintroduce houdini 2 - #528

Merged
rbjornstad merged 39 commits into
mainfrom
reintroduce_houdini2
Aug 10, 2026
Merged

Reintroduce houdini 2#528
rbjornstad merged 39 commits into
mainfrom
reintroduce_houdini2

Conversation

@thokra-nav

Copy link
Copy Markdown
Contributor

Revert revert houdini 2 (#527)"

This reverts commit 320b248.

Revert revert houdini 2 (#527)"

This reverts commit 320b248.
Copilot AI lite review requested due to automatic review settings July 2, 2026 14:41
@thokra-nav
thokra-nav marked this pull request as draft July 2, 2026 14:42

Copilot AI 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.

Pull request overview

Reintroduces Houdini v2 across the Console frontend after a prior revert, updating generated query behavior, route typings, and UI components to match Houdini 2’s masking and “non-exhaustive” union/interface type patterns.

Changes:

  • Bumps Houdini packages to stable v2 releases and updates Houdini/Vite/SvelteKit integration points (houdini.config.js, vite.config.ts, hooks/client).
  • Updates many route queries and pages to use Houdini 2 caching defaults (CacheAndNetwork), new facets shapes, and @mask_disable where unmasked presenter data is expected.
  • Refactors UI components to avoid interface-fragment pitfalls (adds shared IssueFragment.gql, centralizes issue resource derivation, and introduces exhaustive() helper for non-exhaustive union/interface variants).

Reviewed changes

Copilot reviewed 102 out of 104 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
vite.config.ts Ensures schema endpoint env var is available at build/runtime for Houdini schema fetching.
src/routes/userInfo.gql Adds __typename to align with Houdini 2 interface/union handling.
src/routes/team/[team]/valkey/query.gql Switches cache policy to CacheAndNetwork.
src/routes/team/[team]/valkey/create/+page.svelte Migrates route typing import to SvelteKit $types.
src/routes/team/[team]/valkey/+page.ts Updates Houdini input type imports for v2.
src/routes/team/[team]/unleash/+page.svelte Uses Houdini runtime GraphQLError type instead of a local copy.
src/routes/team/[team]/settings/service_accounts/[serviceAccountID]/token/create/+page.svelte Migrates route typing import to SvelteKit $types.
src/routes/team/[team]/settings/service_accounts/[serviceAccountID]/binding/add/+page.svelte Migrates route typing import to SvelteKit $types.
src/routes/team/[team]/settings/confirm_delete/+page.svelte Moves QueryResult typing to houdini/runtime.
src/routes/team/[team]/settings/+page.svelte Moves QueryResult typing to houdini/runtime.
src/routes/team/[team]/secrets/query.gql Switches cache policy to CacheAndNetwork.
src/routes/team/[team]/secrets/+page.ts Updates Houdini input type imports for v2.
src/routes/team/[team]/repositories/+page.ts Updates Houdini input type imports for v2.
src/routes/team/[team]/postgres/query.gql Switches cache policy to CacheAndNetwork.
src/routes/team/[team]/postgres/+page.ts Updates Houdini input type imports for v2.
src/routes/team/[team]/opensearch/query.gql Switches cache policy to CacheAndNetwork.
src/routes/team/[team]/opensearch/create/+page.svelte Migrates route typing import to SvelteKit $types.
src/routes/team/[team]/opensearch/+page.ts Updates Houdini input type imports for v2.
src/routes/team/[team]/members/AddMember.svelte Updates Houdini input type imports for v2.
src/routes/team/[team]/kafka/query.gql Switches cache policy to CacheAndNetwork.
src/routes/team/[team]/kafka/+page.ts Updates Houdini input type imports for v2.
src/routes/team/[team]/jobs/query.gql Switches cache policy to CacheAndNetwork.
src/routes/team/[team]/jobs/+page.ts Updates Houdini input type imports for v2.
src/routes/team/[team]/issues/query.gql Reworks issues query to use facets + shared IssueFragment unmasked.
src/routes/team/[team]/issues/metadata.gql Removes redundant metadata query (replaced by facets).
src/routes/team/[team]/issues/+page.ts Drops metadata loader and updates Houdini input type imports.
src/routes/team/[team]/issues/+page.svelte Consumes facets for filters and updates IssueType/severity handling.
src/routes/team/[team]/configs/query.gql Switches cache policy to CacheAndNetwork.
src/routes/team/[team]/configs/+page.ts Updates Houdini input type imports for v2.
src/routes/team/[team]/buckets/query.gql Switches cache policy to CacheAndNetwork.
src/routes/team/[team]/buckets/+page.ts Updates Houdini input type imports for v2.
src/routes/team/[team]/bigquery/query.gql Switches cache policy to CacheAndNetwork.
src/routes/team/[team]/bigquery/+page.ts Updates Houdini input type imports for v2.
src/routes/team/[team]/applications/query.gql Switches cache policy to CacheAndNetwork.
src/routes/team/[team]/applications/+page.ts Updates Houdini input type imports for v2.
src/routes/team/[team]/alerts/query.gql Switches to facets-based filtering and expands Prometheus alert fields.
src/routes/team/[team]/alerts/PrometheusAlarmDetail.svelte Moves ValueOf typing to houdini/runtime.
src/routes/team/[team]/alerts/metadata.gql Removes redundant metadata query (replaced by facets).
src/routes/team/[team]/alerts/+page.ts Drops metadata loader and updates Houdini input type imports.
src/routes/team/[team]/alerts/+page.svelte Consumes facets and simplifies Prometheus alert rendering.
src/routes/team/[team]/activity-log/query.gql Switches cache policy to CacheAndNetwork.
src/routes/team/[team]/activity-log/+page.ts Updates Houdini input type imports for v2.
src/routes/team/[team]/[env]/valkey/[valkey]/edit/+page.svelte Migrates route typing import to SvelteKit $types.
src/routes/team/[team]/[env]/valkey/[valkey]/edit/+page.server.ts Updates Houdini input type imports for v2.
src/routes/team/[team]/[env]/valkey/[valkey]/delete/+page.svelte Migrates route typing import to SvelteKit $types.
src/routes/team/[team]/[env]/valkey/[valkey]/(single)/query.gql Uses shared IssueFragment unmasked for issue presenters.
src/routes/team/[team]/[env]/postgres/[postgres]/delete/+page.svelte Migrates route typing import to SvelteKit $types.
src/routes/team/[team]/[env]/opensearch/[opensearch]/edit/+page.svelte Migrates route typing import to SvelteKit $types.
src/routes/team/[team]/[env]/opensearch/[opensearch]/edit/+page.server.ts Updates Houdini input type imports for v2.
src/routes/team/[team]/[env]/opensearch/[opensearch]/delete/+page.svelte Migrates route typing import to SvelteKit $types.
src/routes/team/[team]/[env]/opensearch/[opensearch]/(single)/query.gql Uses shared IssueFragment unmasked for issue presenters.
src/routes/team/[team]/[env]/job/[job]/query.gql Uses shared IssueFragment unmasked for issue presenters.
src/routes/team/[team]/[env]/job/[job]/logs/query.gql Expands log destination inline fragments to satisfy Houdini 2 masking.
src/routes/team/[team]/[env]/job/[job]/logs/JobLogs.svelte Uses generated $result type instead of manual prop typing.
src/routes/team/[team]/[env]/job/[job]/issues/query.gql Uses shared IssueFragment unmasked for issue presenters.
src/routes/team/[team]/[env]/job/[job]/issues/+page.ts Updates Houdini input type imports for v2.
src/routes/team/[team]/[env]/job/[job]/activity-log/+page.ts Updates Houdini input type imports for v2.
src/routes/team/[team]/[env]/cloudsql/[cloudsql]/query.gql Uses shared IssueFragment unmasked for issue presenters.
src/routes/team/[team]/[env]/app/[app]/utilization/query.gql Moves shared fields into inline fragments to satisfy Houdini 2 masking.
src/routes/team/[team]/[env]/app/[app]/utilization/+page.svelte Introduces exhaustive() usage and adapts to data payload shape changes.
src/routes/team/[team]/[env]/app/[app]/resize/+page.svelte Migrates route typing import to SvelteKit $types.
src/routes/team/[team]/[env]/app/[app]/query.gql Uses shared IssueFragment unmasked for issue presenters.
src/routes/team/[team]/[env]/app/[app]/logs/query.gql Expands log destination inline fragments to satisfy Houdini 2 masking.
src/routes/team/[team]/[env]/app/[app]/logs/Logs.svelte Uses generated $result typing and exhaustive() for safe iteration.
src/routes/team/[team]/[env]/app/[app]/issues/query.gql Uses shared IssueFragment unmasked for issue presenters.
src/routes/team/[team]/[env]/app/[app]/issues/+page.ts Updates Houdini input type imports for v2.
src/routes/team/[team]/[env]/app/[app]/image/+page.svelte Migrates route typing import to SvelteKit $types.
src/routes/team/[team]/[env]/app/[app]/activity-log/+page.ts Updates Houdini input type imports for v2.
src/routes/deployments/+page.ts Updates Houdini input type imports for v2.
src/routes/admin/userSyncLog/query.gql Refactors interface selection into inline fragments for Houdini 2.
src/routes/admin/userSyncLog/+page.svelte Uses exhaustive() to iterate safely over interface/union results.
src/routes/admin/teams/+page.ts Updates Houdini input type imports for v2.
src/routes/admin/service_accounts/[serviceAccountID]/token/create/+page.svelte Migrates route typing import to SvelteKit $types.
src/routes/admin/service_accounts/[serviceAccountID]/binding/add/+page.svelte Migrates route typing import to SvelteKit $types.
src/routes/admin/+layout.svelte Migrates route typing import to SvelteKit $types.
src/routes/+layout.svelte Migrates route typing import to SvelteKit $types.
src/lib/utils/houdini.ts Adds exhaustive() helper + Exhaustive<T> type for non-exhaustive variants.
src/lib/domain/vulnerability/SuppressFinding.svelte Moves ValueOf typing to houdini/runtime.
src/lib/domain/vulnerability/BulkSuppressCVE.svelte Moves ValueOf typing to houdini/runtime.
src/lib/domain/list-items/IssueListItem.svelte Switches to unmasked presenter data + centralized issue resource mapping.
src/lib/domain/list-items/DeploymentWithTeamListItem.svelte Moves ValueOf typing to houdini/runtime.
src/lib/domain/list-items/DeploymentListItem.svelte Moves ValueOf typing to houdini/runtime.
src/lib/domain/list-items/ActivityLogListItem.svelte Flattens type-keyed payload props for text components under Houdini 2.
src/lib/domain/issues/IssuesFacets.svelte Updates facets prop shapes to include counts.
src/lib/domain/issues/issueResource.ts Adds shared issue “resource” derivation and IssueDisplayData contract.
src/lib/domain/issues/IssueFragment.gql Adds a shared fragment used with @mask_disable for issue presenters.
src/lib/domain/issues/CriticalIssuesCard.svelte Updates issue typing to shared presenter contract.
src/lib/domain/issues/CriticalIssues.svelte Switches to shared fragment and updated row component props.
src/lib/domain/issues/CriticalIssueRow.svelte Refactors to shared issue resource mapping + safer link handling.
src/lib/domain/alerts/AlertsFacets.svelte Updates environment facets prop shape to include counts.
src/lib/domain/activity/TeamActivityCard.svelte Updates Houdini input type imports for v2.
src/lib/domain/activity/shared/texts/types.ts Updates activity log entry typing model for Houdini 2 interface fragments.
src/lib/domain/activity/shared/texts/PostgresDeletedActivityLogEntryText.svelte Adjusts typing to match Houdini 2 fragment data structure.
src/lib/domain/activity/shared/texts/DefaultText.svelte Adjusts typing to match Houdini 2 fragment data structure.
src/hooks.server.ts Reworks GraphQL request rewriting + cookie forwarding for Houdini 2 client behavior.
src/client.ts Removes custom endpoint switching and tightens SSE handler typing.
src/app.d.ts Extends App namespace types for GraphQL error extension codes.
schema.graphql Updates generated schema content (auto-generated).
pnpm-workspace.yaml Allows Houdini builds and adjusts minimum release age exclusions.
package.json Updates Houdini packages and GraphQL version.
houdini.config.js Adjusts Houdini v2 config (url, defaults, removes imperativeCache feature).
Dockerfile Adjusts build stage base image and keeps runtime stages on alpine.
AGENTS.md Documents Houdini 2 patterns (non-exhaustive variants, interface fragments, presenter strategy).

Comment thread src/routes/team/[team]/alerts/+page.svelte
Comment thread src/routes/team/[team]/alerts/query.gql
rbjornstad and others added 20 commits August 6, 2026 09:14
* Improve search modal defaults

* Replace team picker with global search

* Polish search modal interactions

* Refactor help toggle functionality in search component

* Improve search modal filters

* Remove search team filter on backspace

* Complete search team filter with tab

* Remove stale team slug label

* Polish search help chips

* Clarify search help team scope

* Explain search team tab completion

* Add favorites mode to search modal

* Address search modal review comments

* Update generated GraphQL schema

* Clean up search token styles

* Normalize generated GraphQL schema

* Fix search help shortcut and favorites badges

* Clarify team-scoped search

* Mention favorites in search modal

* Update favorites help action

* Harden search shortcut parsing

* Address search review follow-ups

* Tighten team slug token parsing

* Use declarative search shortcut binding

* Avoid duplicate search input ids

* Add search modal header

* Mount search shortcuts only when enabled

* Add team search modal header

* Fix search modal query parsing

* Show selected state for button search results

* Use Svelte class directives for search results

* Autofocus search input on modal open
* fix: improve documentation clarity for service account and team inputs

* fix: enhance layout responsiveness in WorkloadImageCard component
- **Activity log**: all ten service account entry types fell back to `DefaultText` and showed the raw server message; adds text components for each.
- **Broken bindings and tokens**: adds a `Missing workload` tag, fixes the method count under-reporting past the page size, and shows `Never expires`.
- **Workload ↔ account links**: neither direction was navigable; adds a sidebar card on app/job pages and links binding rows to their workload.
- **One account per workload**: the Add button was enabled for workloads already bound elsewhere; now a disabled `Bound to <account>`.
- **Token expiry**: replaces the date picker with presets defaulting to 1 year, resolved server-side. The "Custom" option shows the date picker.
* chore: update action versions in workflows for consistency

* Upgraded deps

* chore: update cronstrue dependency to version 3.24.0

* Upgrade deps

* Upgrade deps

* Upgrade deps

* chore: address dependency review feedback

* style: format after prettier upgrade

* refactor: update legend snippet context type for clarity

* style: add spacing between cost sections

* chore: remove stale release age exclusions
- Adds an activity feed to service account detail pages and team-level service account activity to the list page.
- Entries name what was touched: token name in update entries, a link to the workload in binding added/removed entries.
- Breadcrumbs show the account name instead of the ID.
* Improve instance group list text wrapping and columns
…sidebar mode to fix hydration mismatch warning
…and lint-staged to 17.2.0; adjust pnpm workspace exclusions

Copilot AI 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.

Pull request overview

Copilot reviewed 100 out of 102 changed files in this pull request and generated no new comments.

Suppressed comments (4)

src/routes/team/[team]/settings/service_accounts/[serviceAccountID]/query.gql:12

  • workloadBindings { ... } is selected here and also inside ServiceAccountAuthenticationFragment (see ServiceAccountAuthentications.svelte). Duplicating the same field selection can cause Houdini fragment masking/field-ownership conflicts and adds extra payload. Prefer relying on the fragment’s selection unless this page needs a different shape/args.
    src/routes/admin/service_accounts/[serviceAccountID]/query.gql:12
  • workloadBindings { ... } is selected here and also inside ServiceAccountAuthenticationFragment (see ServiceAccountAuthentications.svelte). Duplicating the same field selection can cause Houdini fragment masking/field-ownership conflicts and adds extra payload. Prefer relying on the fragment’s selection unless this page needs a different shape/args.
    src/routes/team/[team]/[env]/job/[job]/logs/JobLogs.svelte:4
  • This file now relies on Houdini 2 generated result types, which include the non-exhaustive catch-all for interface/union arrays. team.environment.job.logDestinations is iterated later with (logDestination.id) as the key; consider filtering with exhaustive() (like the app logs page does) to avoid type errors and future runtime issues if new LogDestination variants are introduced.
    src/lib/utils/houdini.ts:9
  • exhaustive() hard-codes the non-exhaustive typename string twice and uses double quotes, which is inconsistent with the rest of the TS files. Introduce a shared NON_EXHAUSTIVE_TYPENAME constant and reuse it in both the type and the predicate (also avoids typos).
type NonExhaustive = { readonly __typename: "non-exhaustive; don't match this" };

export type Exhaustive<T> = T extends NonExhaustive ? never : T;

export function exhaustive<T extends { __typename: string }>(items: readonly T[]): Exhaustive<T>[] {

Copilot AI 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.

Pull request overview

Copilot reviewed 105 out of 107 changed files in this pull request and generated no new comments.

CacheAndNetwork is the default policy in houdini.config.js, so
explicit annotations are no-ops. Remove them to reduce noise.
The CriticalIssues component was fetching via $effect, which meant
no data on first navigation and an unnecessary re-fetch cycle.

Load the query in +page.ts and pass the store as a prop instead.
Also fix delete alert spacing on the team overview page.
- Upgraded '@sveltejs/vite-plugin-svelte' from 7.2.0 to 7.3.0
- Updated eslint from 10.7.0 to 10.8.0 across multiple dependencies
- Changed globals version from 17.7.0 to 17.8.0
- Updated '@eslint/config-helpers' from 0.6.0 to 0.7.0
- Updated 'layerchart' and 'runed' dependencies to reflect the new version of '@sveltejs/vite-plugin-svelte'
- Updated 'magic-string' from 0.30.21 to 1.1.0
…#550)

* chore: upgrade pnpm version to 11.21.0 in configuration and Dockerfile

* upgrade deps

* chore: downgrade graphql version from 17.0.2 to 16.14.2 in package.json and pnpm-lock.yaml
@rbjornstad
rbjornstad marked this pull request as ready for review August 10, 2026 09:30
Copilot AI review requested due to automatic review settings August 10, 2026 09:30

Copilot AI 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.

Pull request overview

Copilot reviewed 122 out of 124 changed files in this pull request and generated 1 comment.

Files not reviewed (1)
  • pnpm-lock.yaml: Generated file
Suppressed comments (2)

src/routes/team/[team]/alerts/query.gql:50

  • teamEnvironment { environment { name } } is selected twice (inside the ... on PrometheusAlert block and again at the alert/interface level). This is redundant and risks masking/ownership issues in Houdini; keep the field selected in one place.
    src/lib/domain/activity/ActivityTimeline.svelte:22
  • The timeline list is keyed by index ((i)), which can cause DOM/state to be reused for the wrong entry if the list changes (e.g. filter change, refresh, or insertion). Since activity log entries have stable IDs, key by entry.id and reflect that in the prop typing.
	{#if entries.length > 0}
		{#each entries as entry, i (i)}
			<ActivityLogListItem item={entry} {mode} />
		{/each}

Comment thread src/routes/team/[team]/TeamHealth.gql
Copilot AI review requested due to automatic review settings August 10, 2026 09:53

Copilot AI 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.

Pull request overview

Copilot reviewed 122 out of 124 changed files in this pull request and generated no new comments.

Files not reviewed (1)
  • pnpm-lock.yaml: Generated file
Suppressed comments (2)

src/lib/domain/activity/ActivityTimeline.svelte:20

  • Keying activity log entries by array index can cause incorrect DOM reuse when new entries are inserted or removed (e.g., live updates / pagination), leading to mismatched content or preserved UI state on the wrong entry. Since entries include id (via ActivityLogEntryFragment), use that as the key instead of i.
		{#each entries as entry, i (i)}

src/lib/domain/list-items/IssueListItem.svelte:201

  • After switching IssueFragment to Houdini 2's type-keyed interface fragment shape (e.g. OpenSearchIssue, ValkeyIssue, etc.), the remaining fallback checks ('openSearch' in d, 'sqlInstance' in d, etc.) reference properties that are no longer part of $data. This is likely to fail type-checking and is dead/unreachable at runtime. Remove these legacy branches and keep the final default return.
		if ('openSearch' in d && d.openSearch) return OpenSearchIcon;
		if ('sqlInstance' in d && d.sqlInstance) return DatabaseIcon;
		if ('valkey' in d && d.valkey) return ValkeyIcon;
		if ('unleash' in d && d.unleash) return UnleashIcon;
		if ('job' in d && d.job) return BriefcaseClockIcon;

Copilot AI review requested due to automatic review settings August 10, 2026 11:06

Copilot AI 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.

Pull request overview

Copilot reviewed 122 out of 124 changed files in this pull request and generated 1 comment.

Files not reviewed (1)
  • pnpm-lock.yaml: Generated file
Suppressed comments (2)

src/routes/team/[team]/alerts/+page.svelte:180

  • This section assumes alert.alarms is always present, but alarms is only selected inside the ... on PrometheusAlert fragment in the query. If an alert node is not a Prometheus alert, alert.alarms can be undefined at runtime, causing errors when reading .length or iterating. Consider defaulting alarms to an empty array (or guarding this entire block to Prometheus alerts only).
    src/lib/domain/activity/ActivityTimeline.svelte:20
  • The {#each} block is keyed by the loop index ((i)), but entries items have a stable id (from ActivityLogEntryFragment). Keying by index can cause incorrect DOM reuse if items are inserted/removed/reordered (e.g. when paginating or refetching).
		{#each entries as entry, i (i)}

Comment thread src/lib/domain/list-items/ActivityLogListItem.svelte
@rbjornstad
rbjornstad merged commit 199dbef into main Aug 10, 2026
6 checks passed
@rbjornstad
rbjornstad deleted the reintroduce_houdini2 branch August 10, 2026 12:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants