Skip to content

refactor: deploy UI issues and way we access data#4995

Merged
chronark merged 14 commits intomainfrom
deploy-ui-issues
Feb 12, 2026
Merged

refactor: deploy UI issues and way we access data#4995
chronark merged 14 commits intomainfrom
deploy-ui-issues

Conversation

@ogzhanolguncu
Copy link
Contributor

@ogzhanolguncu ogzhanolguncu commented Feb 11, 2026

What does this PR do?

So much stuff fixed here reported by the team. Major thing is way we consume tanstack db. We now pass frequently used queries to provider like a dependency injection then consume those. And scoping is so much better and easier, because we can easily fetch project specific resources instead of everything.

No more projectId, deploymentId prop drilling they are coming from URL directly but its behind hook to safe guard it.

How should this be tested?

  • Run make dev
  • Run go run . dev seed local
  • Run make build-local-image DOCKERFILE=./demo_api/Dockerfile NAME=demo_api TAG=local CONTEXT=./demo_api
  • Run go run . deploy --project-id=proj_1RblymOt --root-key="unkey_VGuLaFSquizjTFhzpjqF3B" --env=production --api-base-url="http://localhost:7070" ctlptl-registry:5000/demo_api:local. Grab your rootkey and projectId from step 2
  • Head over to localhost:3000 and check deploy pages.

@vercel
Copy link

vercel bot commented Feb 11, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
dashboard Ready Ready Preview, Comment Feb 11, 2026 9:02pm
1 Skipped Deployment
Project Deployment Actions Updated (UTC)
engineering Ignored Ignored Preview Feb 11, 2026 9:02pm

Request Review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 11, 2026

📝 Walkthrough

Walkthrough

Adds ProjectDataProvider and DeploymentLayoutProvider; migrates many components from per-project live DB queries to provider-driven data access; converts per-project collection factories to global collections that require projectId filters; updates UI components to derive IDs from the new providers; upgrades TanStack query-db/react-db deps.

Changes

Cohort / File(s) Summary
Data providers & layout providers
web/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/(overview)/data-provider.tsx, web/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/(overview)/deployments/[deploymentId]/layout-provider.tsx
Adds ProjectDataProvider (useProjectData) exposing projectId, project, domains, deployments, environments, selectors, and refetch helpers; adds DeploymentLayoutProvider (useDeployment) exposing deploymentId.
Project layout & wrapper
web/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/layout.tsx, web/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/page.tsx
Wraps project pages with ProjectDataProvider, simplifies layout signature, and moves page components to consume useProjectData instead of collection-based live queries.
Deployment layout & navigation
.../deployments/[deploymentId]/layout.tsx, .../navigations/use-deployment-breadcrumb-config.ts
Wraps deployment routes with DeploymentLayoutProvider; breadcrumb config now sources IDs from useDeployment/useProjectData and breadcrumb item type extended.
Deployment overview sections & controls
.../deployments/[deploymentId]/(overview)/components/sections/*.tsx, .../components/scroll-to-bottom-button.tsx, .../deployments/[deploymentId]/page.tsx
Refactors sections (domains, info, logs, network) to use useDeployment + useProjectData (removes useParams/useLiveQuery); introduces ScrollToBottomButton; updates tab logic and loading flags.
Network view & project details
.../network/deployment-network-view.tsx, .../network/unkey-flow/.../project-details.tsx, .../network/page.tsx
Removes projectId/deploymentId props; components derive IDs via hooks; adds refetchInterval to network query and adjusts ProjectDetails to no-arg usage.
Deployments hooks & list UI
.../deployments/hooks/use-deployments.ts, .../deployments/components/table/deployments-list.tsx, .../domain_list.tsx, .../get-row-class.ts
useDeployments now returns only deployments; lists and domain components use useProjectData/getDeploymentById; DomainList adds status prop; getRowClassName signature updated to destructure deployment object.
Dialogs & actions (promotion/rollback)
.../promotion-dialog.tsx, .../rollback-dialog.tsx, .../actions/*.tsx, .../deployment-list-table-action.popover.constants.tsx
Replaces live DB queries with useProjectData helpers (getDomainsForDeployment/getEnvironmentOrLiveDomains), consolidates refetch calls to refetchAll, and adapts domain data shape (plain arrays).
Sentinel/logs & requests
.../use-deployment-sentinel-logs-query.ts, .../use-sentinel-logs-query.ts, .../sentinel-logs-provider.tsx, .../sentinel-log-details/index.tsx
Switches hooks to use useProjectData/useDeployment for IDs; sentinel logs provider API expanded (setSelectedLog, isLive, toggleLive); adds projectId-based filtering to related queries.
Filters & controls
.../deployment-list-filters/.../environment-filter.tsx, .../sentinel-logs-environment-filter.tsx
Environment and domain filters now source data from useProjectData instead of live queries; options mapping updated to new data shapes.
Project details & custom domains
.../details/custom-domains-section/*, .../details/domain-row.tsx, .../project-details-expandables/*
Removes projectId props from many detail components; components now call useProjectData internally; replaces DomainRowEmpty with EmptySection.
Environment variables & settings
.../details/env-variables-section/*, .../settings/components/*, .../settings/page.tsx
EnvironmentVariablesSection and settings components (GitHubAppCard, GitHubSettingsClient, RepositoryCard) no longer accept projectId prop and derive it via useProjectData; UI/empty states updated.
OpenAPI diff & requests pages
.../openapi-diff/*, .../requests/*
OpenAPI diff and requests components switch to useProjectData and add projectId-based filtering where applicable.
Project navigation & other components
.../navigations/project-navigation.tsx, .../components/project-content-wrapper.tsx, .../_components/list/index.tsx
ProjectNavigation removed projectId prop and now uses useProjectData; ProjectContentWrapper uses useProjectLayout; proximity prefetch removed preload handler.
New UI components
web/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/components/empty-section.tsx, .../components/region-flags-skeleton.tsx, .../components/region-flags.tsx
Adds EmptySection and RegionFlagsSkeleton; RegionFlags renders skeleton when instances empty; ActiveDeploymentCardEmpty updated to use EmptySection.
Collections refactor & utils
web/apps/dashboard/lib/collections/deploy/{deployments,domains,environments}.ts, web/apps/dashboard/lib/collections/deploy/utils.ts, web/apps/dashboard/lib/collections/index.ts
Converts per-project collection factories into global collections (deployments, domains, environments); adds parseProjectIdFromWhere and validateProjectIdInQuery; enforces projectId presence in queries; removes collectionManager and per-project manager API.
Collection typing updates
web/apps/dashboard/lib/collections/deploy/projects.ts, .../ratelimit/namespaces.ts, .../ratelimit/overrides.ts
Adds second generic parameter (string) to several createCollection calls, adjusting exported collection typings.
Misc UI & styling / deps
web/apps/dashboard/components/ui/switch.tsx, .../env-variables-section/*, .../project-details-expandables/sections.tsx, web/apps/dashboard/package.json, web/apps/dashboard/tailwind.config.js
Removes dark-mode thumb style from Switch and re-exports it; tweaks env-var delete button and secret-switch styles; small null-safety fix; adds shimmer keyframes/animation; upgrades @tanstack/query-db-collection and @tanstack/react-db versions.

Sequence Diagram

sequenceDiagram
    actor User
    participant Route as Next.js Route Params
    participant Provider as ProjectDataProvider
    participant DeploymentCtx as DeploymentLayoutProvider
    participant Collections as Global Collections
    participant TRPC as TRPC Client
    participant Component as Dashboard Component

    User->>Route: Navigate to /projects/[projectId] or /deployments/[deploymentId]
    Route->>Provider: Initialize with projectId
    Route->>DeploymentCtx: Initialize with deploymentId
    Provider->>Collections: Subscribe/query projects, deployments, domains, environments
    Collections->>TRPC: TRPC queries filtered by projectId
    TRPC-->>Collections: Return data
    Collections-->>Provider: Emit data
    Provider->>Provider: Memoize selectors & refetch functions
    Provider-->>Component: Context (useProjectData) available
    DeploymentCtx-->>Component: Context (useDeployment) available
    Component->>Provider: Call selectors (getDeploymentById, getDomainsForDeployment)
    User->>Component: Trigger action (promotion/rollback/refetch)
    Component->>Provider: Call refetchAll() or specific refetch
    Provider->>Collections: Trigger refetch
    Collections->>TRPC: Re-query updated data
    TRPC-->>Collections: New data
    Collections-->>Provider: Emit updates
    Provider-->>Component: Context updates cause re-render
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 1 | ❌ 2
❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 4.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ❓ Inconclusive The description addresses the major change (TanStack DB consumption via provider pattern) and removal of prop drilling, with testing instructions provided. However, it lacks the structured template sections and issue reference. Add a 'Fixes #' reference, include 'Type of change' checkboxes, and expand the 'How should this be tested?' section with explicit test cases to follow the template structure.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main refactoring: consolidating how the UI accesses data through a provider pattern and fixing deploy UI issues.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch deploy-ui-issues

No actionable comments were generated in the recent review. 🎉


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

@vercel vercel bot temporarily deployed to Preview – engineering February 11, 2026 14:39 Inactive
@vercel vercel bot temporarily deployed to Preview – dashboard February 11, 2026 14:39 Inactive
@vercel vercel bot temporarily deployed to Preview – engineering February 11, 2026 18:50 Inactive
@vercel vercel bot temporarily deployed to Preview – dashboard February 11, 2026 18:51 Inactive
@vercel vercel bot temporarily deployed to Preview – dashboard February 11, 2026 19:19 Inactive
@vercel vercel bot temporarily deployed to Preview – dashboard February 11, 2026 19:29 Inactive
@ogzhanolguncu ogzhanolguncu marked this pull request as ready for review February 11, 2026 19:37
@vercel vercel bot temporarily deployed to Preview – engineering February 11, 2026 19:39 Inactive
@vercel vercel bot temporarily deployed to Preview – dashboard February 11, 2026 19:42 Inactive
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
web/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/(overview)/openapi-diff/page.tsx (1)

72-84: ⚠️ Potential issue | 🟠 Major

The diff query is disabled and never executes.

The enabled: false option prevents this query from ever running. There's no refetch() call or mechanism to trigger the query when deployments are selected. The diffData will always be undefined, so the diff content will never render.

Should this be enabled: !!selectedFromDeployment && !!selectedToDeployment to fetch when both deployments are selected?

🐛 Proposed fix
   {
-    enabled: false,
+    enabled: !!selectedFromDeployment && !!selectedToDeployment,
   },
web/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/(overview)/deployments/components/table/deployments-list.tsx (1)

295-306: ⚠️ Potential issue | 🟠 Major

Bug: liveDeployment retrieves the current row's deployment instead of the actual live deployment.

Line 295 calls getDeploymentById(deployment.id) which returns the same deployment being rendered in the current row. Based on the prop usage in DeploymentListTableActions, the liveDeployment is compared against selectedDeployment.id to determine if rollback/promote actions should be enabled. When liveDeployment equals the current row's deployment, the condition selectedDeployment.id !== liveDeployment.id is always false, disabling these actions for all rows. The code should retrieve the actual live deployment using liveDeploymentId instead.

🐛 Proposed fix
       render: ({
         deployment,
         environment,
       }: {
         deployment: Deployment;
         environment?: Environment;
       }) => {
-          const liveDeployment = getDeploymentById(deployment.id);
+          const liveDeployment = liveDeploymentId ? getDeploymentById(liveDeploymentId) : undefined;
         return (
           <div className="pl-5">
             <DeploymentListTableActions
               selectedDeployment={deployment}
               liveDeployment={liveDeployment}
               environment={environment}
             />
           </div>
         );
       },
web/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/(overview)/deployments/[deploymentId]/network/deployment-network-view.tsx (1)

34-63: ⚠️ Potential issue | 🟡 Minor

Remove the non-null assertion on deploymentId.

The deploymentId from useDeployment() is always a non-null string (the context provider validates it at the boundary), so the deploymentId! non-null assertion is redundant and violates the repo's type-safety guideline. Simply pass deploymentId directly.

Minimal fix
             <InternalDevTreeGenerator
               // biome-ignore lint/style/noNonNullAssertion: will be fixed later, when we actually implement tRPC logic
-              deploymentId={deploymentId!}
+              deploymentId={deploymentId}
               onGenerate={setGeneratedTree}
🤖 Fix all issues with AI agents
In
`@web/apps/dashboard/app/`(app)/[workspaceSlug]/projects/[projectId]/(overview)/deployments/[deploymentId]/(overview)/navigations/use-deployment-breadcrumb-config.ts:
- Line 29: Replace the unsafe type assertion for workspaceSlug by validating
params.workspaceSlug at runtime: in useDeploymentBreadcrumbConfig, check if
params.workspaceSlug is a string (or if it's an array, pick the first element or
treat as error) and handle undefined accordingly (throw a clear error, return a
fallback, or navigate away). Use typeof params.workspaceSlug === "string" and
Array.isArray(params.workspaceSlug) to branch and avoid `as string`; ensure
subsequent code uses the validated local variable (workspaceSlug) only after
these checks.

In
`@web/apps/dashboard/app/`(app)/[workspaceSlug]/projects/[projectId]/(overview)/details/env-variables-section/index.tsx:
- Around line 67-80: The icon-only toggle Button (the Button using
onClick={toggleExpanded} with the ChevronDown icon) lacks an accessible name;
add an aria-label describing the control (e.g., "Toggle environment variables"
or similar) to the Button and set aria-expanded={isExpanded} so screen readers
know the state; also mark the decorative icon (ChevronDown) as aria-hidden to
avoid duplicate announcements.

In
`@web/apps/dashboard/app/`(app)/[workspaceSlug]/projects/[projectId]/(overview)/settings/page.tsx:
- Around line 14-23: The default for environmentId uses environments.length at
init so it stays "" when environments load async; instead keep the useQueryState
default as an empty string and add a useEffect that watches environments and
environmentId, and when environments becomes non-empty and environmentId is
falsy call setEnvironmentId(environments[0].id) (use the same history/shallow
semantics if needed) to auto-select the first environment; refer to
useProjectData, environments, environmentId, setEnvironmentId, and useQueryState
in your change.

In `@web/apps/dashboard/components/ui/switch.tsx`:
- Around line 22-28: Remove the stray JSX text node following the
SwitchPrimitives.Thumb element (the {" "} after the component) in the switch
component; locate the SwitchPrimitives.Thumb in ui/switch.tsx (and any similar
occurrences) and delete the extraneous {" "} so no empty text node is rendered
and SSR/layout diffs are avoided.
🧹 Nitpick comments (8)
web/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/(overview)/details/custom-domains-section/custom-domain-row.tsx (1)

84-88: Empty catch blocks silently swallow errors.

The empty catch {} blocks at lines 87 and 108 discard mutation errors without any handling. While toast.promise shows error feedback, this pattern could mask debugging information and prevent error boundaries from catching issues.

Consider logging the error or removing the try-catch if toast.promise already handles the error display adequately.

🔧 Proposed fix
     try {
       await mutation;
       onDelete();
-    } catch {}
+    } catch (err) {
+      // Error already shown via toast.promise
+      console.error("Failed to delete domain:", err);
+    }
     try {
       await mutation;
       onRetry();
-    } catch {}
+    } catch (err) {
+      // Error already shown via toast.promise
+      console.error("Failed to retry verification:", err);
+    }

Also applies to: 105-109

web/apps/dashboard/lib/collections/deploy/utils.ts (1)

8-9: any type usage acknowledged with lint suppression.

The any types are used because TanStack DB doesn't expose internal types for the where expression structure. The biome-ignore comments document this reasoning appropriately.

For improved type safety in the future, consider creating a local type definition that mirrors the expected structure, even if not perfectly accurate:

type WhereExpr = {
  name?: string;
  type?: string;
  args?: Array<{ path?: string[]; type?: string; value?: unknown }>;
};

This would provide some IntelliSense benefits while acknowledging the type isn't officially exported. As per coding guidelines: "Never compromise type safety: No any" — though this case has documented justification.

Also applies to: 15-16, 63-64

web/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/(overview)/deployments/components/table/utils/get-row-class.ts (1)

49-54: The environment parameter is unused.

The function signature now accepts { deployment, environment } but environment is never referenced in the function body. If this is preparatory for future functionality, consider adding a TODO comment. Otherwise, consider keeping the simpler signature until the parameter is needed.

♻️ Option: Remove unused parameter
 export const getRowClassName = (
-  { deployment }: { deployment: Deployment; environment: Environment },
+  deployment: Deployment,
   selectedDeploymentId: string | null,
   liveDeploymentId: string | null,
   isRolledBack: boolean,
 ) => {

Note: This would require updating all call sites to pass deployment directly instead of the object.

web/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/(overview)/data-provider.tsx (1)

42-44: Consider using the fault library for error handling.

The coding guidelines specify using the fault library for error handling. Currently, a plain Error is thrown when projectId is missing.

As per coding guidelines: "Use fault library for error handling."

web/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/(overview)/deployments/components/table/components/actions/deployment-list-table-action.popover.constants.tsx (1)

92-98: Consider memoizing the data computation.

data is computed on every render (Line 25-27) and included in the useMemo dependency array. Since getDomainsForDeployment likely returns a new array reference each time, this could cause menuItems to recompute unnecessarily.

♻️ Suggested improvement
+ import { useMemo } from "react";
  // ...
  const { getDomainsForDeployment } = useProjectData();
- const data = getDomainsForDeployment(selectedDeployment.id).map((domain) => ({
-   host: domain.fullyQualifiedDomainName,
- }));
+ const data = useMemo(
+   () =>
+     getDomainsForDeployment(selectedDeployment.id).map((domain) => ({
+       host: domain.fullyQualifiedDomainName,
+     })),
+   [getDomainsForDeployment, selectedDeployment.id],
+ );
web/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/(overview)/deployments/[deploymentId]/(overview)/components/sections/deployment-logs-section.tsx (1)

21-27: Confusing variable naming: isReady means the opposite.

The variable isReady is true when deploymentStatus !== "ready", which is semantically inverted. This makes the code harder to understand at a glance.

♻️ Suggested naming improvement
- const isReady = deploymentStatus !== "ready";
+ const isBuilding = deploymentStatus !== "ready";

- const [tab, setTab] = useState(isReady ? "build-logs" : "requests");
+ const [tab, setTab] = useState(isBuilding ? "build-logs" : "requests");

  useEffect(() => {
-   setTab(isReady ? "build-logs" : "requests");
- }, [isReady]);
+   setTab(isBuilding ? "build-logs" : "requests");
+ }, [isBuilding]);

And on Line 35:

- <TabsTrigger value="requests" className="text-accent-12 text-[13px]" disabled={isReady}>
+ <TabsTrigger value="requests" className="text-accent-12 text-[13px]" disabled={isBuilding}>
web/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/(overview)/deployments/hooks/use-deployments.ts (1)

35-44: Type assertion as Record<...> violates coding guidelines.

The code uses as Record<DeploymentListFilterField, (string | number)[]> which bypasses type safety. As per coding guidelines, avoid as Type assertions.

♻️ Type-safe alternative
  const groupedFilters = filters.reduce(
-   (acc, f) => {
+   (acc: Partial<Record<DeploymentListFilterField, (string | number)[]>>, f) => {
      if (!acc[f.field]) {
        acc[f.field] = [];
      }
-     acc[f.field].push(f.value);
+     acc[f.field]!.push(f.value);
      return acc;
    },
-   {} as Record<DeploymentListFilterField, (string | number)[]>,
+   {},
  );

Note: The ! on acc[f.field]!.push is safe here because we just checked/initialized it, but if you want to avoid even that:

const groupedFilters = filters.reduce<Partial<Record<DeploymentListFilterField, (string | number)[]>>>(
  (acc, f) => {
    const existing = acc[f.field] ?? [];
    existing.push(f.value);
    acc[f.field] = existing;
    return acc;
  },
  {},
);
web/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/(overview)/settings/components/github-settings-client.tsx (1)

47-47: Minor: Extra whitespace in JSX.

There's an extra space before hasInstallations.

♻️ Fix formatting
- <GitHubAppCard  hasInstallations={true} />
+ <GitHubAppCard hasInstallations={true} />

Or even simpler:

- <GitHubAppCard  hasInstallations={true} />
+ <GitHubAppCard hasInstallations />

Copy link
Member

@perkinsjr perkinsjr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we now have another version of <Empty>? When we have one

https://engineering.unkey.com/design/components/empty

Why are we also creating a single component that we reuse dozens of time and placing it in a non shared location like components or somewhere. otherwise we end us with this.

import { DomainRow, DomainRowSkeleton, EmptySection } from "./(overview)/details/domain-row"; 

 import { DomainRow, DomainRowSkeleton, EmptySection } from "../../../../../details/domain-row";

import { useProjectData } from "../../../../../data-provider";

please spend some time actually making this code reusable, reusing components we have, and if we can't place them in a place if you are going to reuse them dozens of time.

I don't want to waste time in the future, refactoring hundreds of components to use reusable components or figuring out which one is broken (Which happens so often)

@ogzhanolguncu
Copy link
Contributor Author

../../../../../details/domain-row

wdym they are both pointing the same directory? Depending on the depth LSP picks the import path

import { useProjectData } from "../../../../data-provider";
import { useDeployment } from "../../layout-provider";

export function ScrollToBottomButton() {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@perkinsjr @chronark This is kinda experimental if we don't like it we can kill it. lemme know how you feel

@vercel vercel bot temporarily deployed to Preview – dashboard February 11, 2026 20:57 Inactive
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
web/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/(overview)/deployments/[deploymentId]/network/deployment-network-view.tsx (1)

57-63: ⚠️ Potential issue | 🟠 Major

Remove the non‑null assertion on deploymentId.

Line 62 uses deploymentId!, which violates the type safety guideline. Gate the dev generator on deploymentId being defined instead.

✅ Minimal fix
-          {process.env.NODE_ENV === "development" && (
-            <InternalDevTreeGenerator
-              // biome-ignore lint/style/noNonNullAssertion: will be fixed later, when we actually implement tRPC logic
-              deploymentId={deploymentId!}
-              onGenerate={setGeneratedTree}
-              onReset={() => setGeneratedTree(null)}
-            />
-          )}
+          {process.env.NODE_ENV === "development" && deploymentId && (
+            <InternalDevTreeGenerator
+              deploymentId={deploymentId}
+              onGenerate={setGeneratedTree}
+              onReset={() => setGeneratedTree(null)}
+            />
+          )}

As per coding guidelines: "Never compromise type safety: No any, no ! (non-null assertion), no as Type".

@vercel vercel bot temporarily deployed to Preview – dashboard February 11, 2026 21:02 Inactive
@chronark chronark merged commit c3017a4 into main Feb 12, 2026
15 checks passed
@chronark chronark deleted the deploy-ui-issues branch February 12, 2026 07:41
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.

3 participants