Skip to content

Comments

refactor: deploy settings tanstack#5104

Open
ogzhanolguncu wants to merge 9 commits intomainfrom
deploy-settings-tanstack
Open

refactor: deploy settings tanstack#5104
ogzhanolguncu wants to merge 9 commits intomainfrom
deploy-settings-tanstack

Conversation

@ogzhanolguncu
Copy link
Contributor

@ogzhanolguncu ogzhanolguncu commented Feb 20, 2026

What does this PR do?

This PR moves all the deploy settings into tanstackdb, also creates a nice DI for accessing environmentId(in the future we'll have different apps/envs) so this structure will help us a lot. We are not gonna change anything in the setting forms we'll just tell settings where to read and commit their mesages.

Also fixed some UI issues reported by @chronark.

By default current settings form persists and reads everything from production environment.

How should this be tested?

  • Deploy settings should save and fetch the latest data without an issue

@vercel
Copy link

vercel bot commented Feb 20, 2026

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

Project Deployment Actions Updated (UTC)
dashboard Ready Ready Preview, Comment Feb 20, 2026 1:33pm
engineering Ready Ready Preview, Comment Feb 20, 2026 1:33pm

Request Review

@ogzhanolguncu ogzhanolguncu changed the title refacotr: deploy settings tanstack refactor: deploy settings tanstack Feb 20, 2026
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 20, 2026

📝 Walkthrough

Walkthrough

This pull request introduces a centralized environment settings management system by creating an EnvironmentSettingsProvider and migrating multiple build/runtime setting components from TRPC-based remote mutations to collection-based local state updates. The settings page layout is reorganized, and Port settings is relocated from build to runtime. Support for environment variable and environment settings collections is added.

Changes

Cohort / File(s) Summary
Environment Settings Infrastructure
environment-provider.tsx
New provider and hook for centralized environment settings access. Subscribes to live environment settings via collection query and provides context to descendants.
Build Settings Refactoring
build-settings/dockerfile-settings.tsx, build-settings/github-settings/index.tsx, build-settings/root-directory-settings.tsx
Migrated from TRPC queries/mutations to useEnvironmentSettings hook and collection-based updates. Renamed components for clarity (DockerfileSettings → Dockerfile, GitHubSettings → GitHub, RootDirectorySettings → RootDirectory). Removed toast notifications and server-side mutation logic.
Build Settings Removal
build-settings/port-settings.tsx
Deleted build port settings entirely; functionality moved to runtime settings.
Runtime Settings Refactoring
runtime-settings/command.tsx, runtime-settings/cpu.tsx, runtime-settings/memory.tsx, runtime-settings/regions.tsx, runtime-settings/instances.tsx, runtime-settings/healthcheck/index.tsx
Migrated from TRPC to useEnvironmentSettings and collection-based updates. Removed separate form components and mutation logic. Simplified saving state to rely on isSubmitting only.
Runtime Settings Addition
runtime-settings/port-settings.tsx
New Port component for runtime settings with zod validation (port 2000–54000) and collection-based persistence via useEnvironmentSettings.
Advanced Settings
advanced-settings/custom-domains/index.tsx, advanced-settings/custom-domains/custom-domain-row.tsx, advanced-settings/env-vars/index.tsx
Custom domains now uses useEnvironmentSettings for defaultEnvironmentId. EnvVars migrated from TRPC server-side to collection-based client-side operations. Removed error handling/toasts, relying on form state for feedback. Custom domain row hover styling simplified.
Sentinel Settings
sentinel-settings/keyspaces.tsx
Migrated from useProjectData and TRPC to useEnvironmentSettings. Replaced mutation flow with collection-based draft updates. Removed toast notifications.
Form Components
shared/form-setting-card.tsx
Added preventDefault() on form submission to prevent collapse during submit.
Collections & Infrastructure
lib/collections/deploy/env-vars.ts, lib/collections/deploy/environment-settings.ts, lib/collections/deploy/utils.ts, lib/collections/index.ts
Introduced new env-vars and environmentSettings collections backed by TanStack React DB. Env-vars collection handles environment variable CRUD via TRPC with toast feedback. EnvironmentSettings collection aggregates build/runtime/sentinel settings with batch mutation support. Added environmentId filtering utilities mirroring projectId pattern.
TRPC Router Fix
lib/trpc/routers/deploy/environment-settings/get.ts
Added length check before parsing sentinelConfig to prevent 500 errors on empty strings.
Page Layout & Integration
(overview)/settings/page.tsx
Restructured settings page with new EnvironmentSettingsProvider wrapper. Reorganized component imports (renamed build settings, added new Port in runtime). Consolidated layout from nested groups to sectioned structure (Build, Runtime, Sentinel, Advanced).
Settings Card Scroll Enhancement
internal/ui/src/components/settings-card.tsx
Added auto-scroll behavior on expansion to reveal overflowing content. Introduced DOM traversal to locate scrollable parent container.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The PR description explains the core change (moving deploy settings to tanstackdb, creating DI for environmentId), mentions UI fixes, and provides a testing instruction. However, it is missing several required checklist items and does not fill out the 'Type of change' section with required checkboxes. Complete the required checklist items (e.g., self-review, build/fmt checks, no console.logs), select the 'Type of change' (appears to be 'Chore'), and ensure all required boxes are explicitly checked before merging.
Docstring Coverage ⚠️ Warning Docstring coverage is 28.57% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title 'refactor: deploy settings tanstack' clearly and concisely describes the main change - moving deploy settings to tanstackdb. It is specific enough for developers scanning history to understand the primary refactor.

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

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch deploy-settings-tanstack

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

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 (1)
web/apps/dashboard/lib/trpc/routers/deploy/environment-settings/get.ts (1)

30-35: ⚠️ Potential issue | 🟠 Major

Remove type assertion and validate sentinelConfig with a zod schema.

The type assertion as SentinelConfig violates the no-type-assertion rule. Add schema validation to ensure type safety without casts.

Proposed fix
 import { and, db, eq } from "@/lib/db";
 import { environmentBuildSettings, environmentRuntimeSettings } from "@unkey/db/src/schema";
 import { z } from "zod";
 import { workspaceProcedure } from "../../../trpc";
 import type { SentinelConfig } from "./sentinel/update-middleware";
 
+const sentinelConfigSchema = z.object({
+  policies: z.array(
+    z.object({
+      id: z.string(),
+      name: z.string(),
+      enabled: z.boolean(),
+      keyauth: z.object({ keySpaceIds: z.array(z.string()) }),
+    }),
+  ),
+});
+
 export const getEnvironmentSettings = workspaceProcedure
   .input(z.object({ environmentId: z.string() }))
   .query(async ({ ctx, input }) => {
@@ -29,9 +39,7 @@ export const getEnvironmentSettings = workspaceProcedure
             // Without that length check this will Buffer.from gives "", and JSON.parse("") throws 500.
             sentinelConfig: runtimeSettings.sentinelConfig?.length
-              ? (JSON.parse(
-                  Buffer.from(runtimeSettings.sentinelConfig).toString(),
-                ) as SentinelConfig)
+              ? sentinelConfigSchema.parse(
+                  JSON.parse(Buffer.from(runtimeSettings.sentinelConfig).toString()),
+                )
               : undefined,
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@web/apps/dashboard/lib/trpc/routers/deploy/environment-settings/get.ts`
around lines 30 - 35, Replace the unsafe cast of runtimeSettings.sentinelConfig
to SentinelConfig with a zod validation step: define a SentinelConfigSchema
(using zod) that matches the SentinelConfig shape, parse the
Buffer.from(runtimeSettings.sentinelConfig).toString() JSON and run
SentinelConfigSchema.safeParse on the result, and then set sentinelConfig to the
parsed data when safeParse.success is true (or handle/log/return undefined on
failure) instead of using "as SentinelConfig"; update the code paths that read
sentinelConfig to expect undefined when validation fails.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@web/apps/dashboard/app/`(app)/[workspaceSlug]/projects/[projectId]/(overview)/settings/components/advanced-settings/env-vars/index.tsx:
- Around line 118-134: Remove the unsafe type assertions in the env var
mutations: stop casting the result of toTrpcType(...) and stop casting v.id;
instead rely on the return type of toTrpcType as-is (it already yields
"recoverable" | "writeonly") when calling collection.envVars.insert and
collection.envVars.update, and add an explicit runtime guard before calling
collection.envVars.update to ensure v.id is a defined string (e.g., skip or
throw if v.id is undefined) so you no longer need the v.id as string assertion.

In
`@web/apps/dashboard/app/`(app)/[workspaceSlug]/projects/[projectId]/(overview)/settings/components/runtime-settings/port-settings.tsx:
- Around line 18-29: The form's defaultValues from useForm (resolver:
zodResolver(portSchema)) only apply on mount so when defaultValue (from
useEnvironmentSettings/useLiveQuery) changes the form stays stale; add a
useEffect that watches defaultValue and calls the form reset method (from
useForm) with the new value (e.g., reset({ port: defaultValue })) so useWatch/
currentPort and formState (isValid/isSubmitting/errors) reflect the updated
environment value; place the effect near the useForm/useWatch setup and
reference reset, defaultValue, useEffect, useWatch, and portSchema.

In
`@web/apps/dashboard/app/`(app)/[workspaceSlug]/projects/[projectId]/(overview)/settings/environment-provider.tsx:
- Around line 37-41: Replace the raw Error thrown in useEnvironmentSettings with
a fault-created error and correct the provider name: import fault from 'fault'
(or the project's fault import pattern), check the EnvironmentContext as you do
now, and when it's missing throw fault("useEnvironmentSettings must be used
within EnvironmentSettingsProvider") instead of new Error(...); ensure the
change references useEnvironmentSettings and EnvironmentContext and uses the
fault helper to construct the error with the corrected provider name
EnvironmentSettingsProvider.

---

Outside diff comments:
In `@web/apps/dashboard/lib/trpc/routers/deploy/environment-settings/get.ts`:
- Around line 30-35: Replace the unsafe cast of runtimeSettings.sentinelConfig
to SentinelConfig with a zod validation step: define a SentinelConfigSchema
(using zod) that matches the SentinelConfig shape, parse the
Buffer.from(runtimeSettings.sentinelConfig).toString() JSON and run
SentinelConfigSchema.safeParse on the result, and then set sentinelConfig to the
parsed data when safeParse.success is true (or handle/log/return undefined on
failure) instead of using "as SentinelConfig"; update the code paths that read
sentinelConfig to expect undefined when validation fails.

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.

1 participant