Conversation
|
|
The latest updates on your projects. Learn more about Vercel for GitHub.
1 Skipped Deployment
|
📝 WalkthroughWalkthroughSwitches deployment queries to project-scoped TRPC routes; adds a project layout/context and sub-navigation; introduces Active Deployment card with build logs and a right-side details panel; implements environment variables UI and local edit flow; adds project TRPC endpoints (details, logs, envs); and expands the internal icons library. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor User
participant Layout as ProjectLayoutWrapper
participant Ctx as ProjectLayoutContext
participant SubNav as ProjectSubNavigation
participant TRPC as tRPC
participant Panel as ProjectDetailsExpandable
participant Card as ActiveDeploymentCard
participant LogsHook as useDeploymentLogs
User->>Layout: Navigate to /projects/[projectId]
Layout->>TRPC: prefetch(envs.getEnvs { projectId })
Layout->>Ctx: provide { projectId, activeDeploymentId, isDetailsOpen }
SubNav->>Layout: onMount(distanceToTop)
Layout->>TRPC: prefetch(activeDeployment.details { deploymentId })
TRPC-->>Layout: details prefetched
Layout->>Panel: open with activeDeploymentId
Card->>Ctx: read activeDeploymentId
Card->>TRPC: getData(activeDeployment.details { deploymentId })
alt details present
Card->>User: render header & metadata
User->>Card: Expand logs
Card->>LogsHook: init(deploymentId)
LogsHook->>TRPC: query(buildLogs { deploymentId })
TRPC-->>LogsHook: { logs }
LogsHook-->>Card: filteredLogs + counts
Card->>User: show logs, filters, search, copy
else
Card->>User: render skeleton
end
sequenceDiagram
autonumber
actor User
participant EnvSec as EnvironmentVariablesSection
participant Hook as useEnvVars
participant TRPC as tRPC
EnvSec->>Hook: init({ projectId, environment })
Hook->>TRPC: getEnvs { projectId }
TRPC-->>Hook: { production, preview, development }
Hook-->>EnvSec: envVars
User->>EnvSec: Click "Add"
EnvSec->>Hook: startAdding / setNewVar
User->>EnvSec: Enter key/value, Save
EnvSec->>Hook: addVariable (client-side)
Note right of Hook: server mutations are TODO
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested labels
Tip 🔌 Remote MCP (Model Context Protocol) integration is now available!Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats. ✨ Finishing Touches
🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
CodeRabbit Configuration File (
|
|
Thank you for following the naming conventions for pull request titles! 🙏 |
There was a problem hiding this comment.
Actionable comments posted: 107
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (7)
internal/icons/src/icons/chevron-down.tsx (1)
19-25: Standardize SVG prop spread: put{...props}afterheight/width
Update all icons in this PR (e.g. chevron-down.tsx, bolt.tsx, circle-xmark.tsx, triangle-warning-2.tsx, etc.) so that{...props}appears last in the<svg>tag, ensuring consumer-specifiedheight/widtharen’t overridden.internal/icons/src/icons/triangle-warning-2.tsx (1)
20-26: Align SVG prop spread order with the chosen conventionThis file places
{...props}afterheight/width(allowing overrides). Ensure this matches the convention you select across the icon set to avoid inconsistent behavior.apps/dashboard/app/(app)/projects/[projectId]/deployments/components/controls/components/deployment-list-search/index.tsx (1)
52-56: Guard empty queries before calling the LLM endpointTrim and short-circuit on empty input to avoid noisy toasts from the backend and unnecessary requests.
- onSearch={(query) => - queryLLMForStructuredOutput.mutateAsync({ - query, - }) - } + onSearch={(query) => { + const q = query.trim(); + if (q.length === 0) { + toast.error("Please enter a search query.", { position: "top-right", duration: 5000 }); + return; + } + return queryLLMForStructuredOutput.mutateAsync({ query: q }); + }}apps/dashboard/app/(app)/projects/[projectId]/deployments/components/table/hooks/use-deployments-list-query.ts (2)
37-39: Don’t throw inside a hook for filter operator mismatches; fail-soft.Throwing here will crash the page on any malformed filter. Prefer skipping invalid filters.
Apply:
- if (!validOperators.includes(filter.operator)) { - throw new Error("Invalid operator"); - } + if (!validOperators.includes(filter.operator)) { + return; + }And similarly for the "branch" case:
- if (!validOperators.includes(filter.operator)) { - throw new Error("Invalid operator"); - } + if (!validOperators.includes(filter.operator)) { + return; + }Also applies to: 54-56
100-113: Map rebuild logic is fine; consider preserving total from the last page.Minor: you read
totalfrompages[0]. If the API ever changes this per page, prefer the last page (or an explicitmeta). Not blocking.- if (deploymentData.pages.length > 0) { - setTotalCount(deploymentData.pages[0].total); - } + const first = deploymentData.pages[0]; + if (first) setTotalCount(first.total);apps/dashboard/app/(app)/projects/[projectId]/navigations/project-navigation.tsx (1)
41-43: Avoid throwing in UI for missing project; render a fallback.Throwing crashes the page. Show Not Found or redirect.
- if (!activeProject) { - throw new Error(`Project with id "${projectId}" not found`); - } + if (!activeProject) { + return ( + <Navbar> + <Navbar.Breadcrumbs icon={<Cube />}> + <Navbar.Breadcrumbs.Link href="/projects">Projects</Navbar.Breadcrumbs.Link> + <Navbar.Breadcrumbs.Link href="#" isIdentifier noop> + Project not found + </Navbar.Breadcrumbs.Link> + </Navbar.Breadcrumbs> + </Navbar> + ); + }internal/icons/src/index.ts (1)
1-131: Optional: keep exports alphabetized for scanabilityIf there’s no enforced order, consider alphabetizing within the barrel to simplify diffs.
♻️ Duplicate comments (3)
internal/icons/src/icons/heart.tsx (1)
1-11: Same licensing concern as in double-chevron-left.Please address the Nucleo redistribution restriction here as well.
internal/icons/src/icons/list-radio.tsx (1)
1-11: Same licensing concern as in double-chevron-left.Please address the Nucleo redistribution restriction here as well.
internal/icons/src/icons/grid-circle.tsx (1)
1-11: Same licensing concern as in double-chevron-left.Please address the Nucleo redistribution restriction here as well.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (47)
apps/dashboard/app/(app)/projects/[projectId]/deployments/components/controls/components/deployment-list-search/index.tsx(1 hunks)apps/dashboard/app/(app)/projects/[projectId]/deployments/components/table/hooks/use-deployments-list-query.ts(1 hunks)apps/dashboard/app/(app)/projects/[projectId]/deployments/page.tsx(1 hunks)apps/dashboard/app/(app)/projects/[projectId]/details/active-deployment-card/card.tsx(1 hunks)apps/dashboard/app/(app)/projects/[projectId]/details/active-deployment-card/filter-button.tsx(1 hunks)apps/dashboard/app/(app)/projects/[projectId]/details/active-deployment-card/hooks/use-deployment-logs.tsx(1 hunks)apps/dashboard/app/(app)/projects/[projectId]/details/active-deployment-card/index.tsx(1 hunks)apps/dashboard/app/(app)/projects/[projectId]/details/active-deployment-card/info-chip.tsx(1 hunks)apps/dashboard/app/(app)/projects/[projectId]/details/active-deployment-card/skeleton.tsx(1 hunks)apps/dashboard/app/(app)/projects/[projectId]/details/active-deployment-card/status-indicator.tsx(1 hunks)apps/dashboard/app/(app)/projects/[projectId]/details/collapsible-row.tsx(1 hunks)apps/dashboard/app/(app)/projects/[projectId]/details/domain-row.tsx(1 hunks)apps/dashboard/app/(app)/projects/[projectId]/details/env-variables-section/add-env-var-row.tsx(1 hunks)apps/dashboard/app/(app)/projects/[projectId]/details/env-variables-section/env-var-row.tsx(1 hunks)apps/dashboard/app/(app)/projects/[projectId]/details/env-variables-section/hooks/use-env-var.tsx(1 hunks)apps/dashboard/app/(app)/projects/[projectId]/details/env-variables-section/index.tsx(1 hunks)apps/dashboard/app/(app)/projects/[projectId]/details/project-details-expandables/detail-section.tsx(1 hunks)apps/dashboard/app/(app)/projects/[projectId]/details/project-details-expandables/index.tsx(1 hunks)apps/dashboard/app/(app)/projects/[projectId]/details/project-details-expandables/sections.tsx(1 hunks)apps/dashboard/app/(app)/projects/[projectId]/layout-provider.tsx(1 hunks)apps/dashboard/app/(app)/projects/[projectId]/layout.tsx(1 hunks)apps/dashboard/app/(app)/projects/[projectId]/logs/page.tsx(1 hunks)apps/dashboard/app/(app)/projects/[projectId]/navigations/project-navigation.tsx(2 hunks)apps/dashboard/app/(app)/projects/[projectId]/navigations/project-sub-navigation.tsx(1 hunks)apps/dashboard/app/(app)/projects/[projectId]/page.tsx(1 hunks)apps/dashboard/lib/trpc/routers/deploy/project/active-deployment/getBuildLogs.ts(1 hunks)apps/dashboard/lib/trpc/routers/deploy/project/active-deployment/getDetails.ts(1 hunks)apps/dashboard/lib/trpc/routers/deploy/project/envs/list.ts(1 hunks)apps/dashboard/lib/trpc/routers/index.ts(2 hunks)internal/icons/src/icons/bolt.tsx(1 hunks)internal/icons/src/icons/chart-activity.tsx(1 hunks)internal/icons/src/icons/chevron-down.tsx(2 hunks)internal/icons/src/icons/circle-xmark.tsx(1 hunks)internal/icons/src/icons/code-commit.tsx(1 hunks)internal/icons/src/icons/connections.tsx(1 hunks)internal/icons/src/icons/double-chevron-left.tsx(1 hunks)internal/icons/src/icons/double-chevron-right.tsx(1 hunks)internal/icons/src/icons/grid-circle.tsx(1 hunks)internal/icons/src/icons/hard-drive.tsx(1 hunks)internal/icons/src/icons/heart.tsx(1 hunks)internal/icons/src/icons/list-radio.tsx(1 hunks)internal/icons/src/icons/location2.tsx(1 hunks)internal/icons/src/icons/message-writing.tsx(1 hunks)internal/icons/src/icons/paperclip-2.tsx(1 hunks)internal/icons/src/icons/share-up-right.tsx(1 hunks)internal/icons/src/icons/triangle-warning-2.tsx(2 hunks)internal/icons/src/index.ts(5 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{js,jsx,ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{js,jsx,ts,tsx}: Use Biome for formatting and linting in TypeScript/JavaScript projects
Prefer named exports over default exports in TypeScript/JavaScript, except for Next.js pages
Files:
apps/dashboard/app/(app)/projects/[projectId]/details/active-deployment-card/card.tsxinternal/icons/src/icons/heart.tsxinternal/icons/src/icons/list-radio.tsxapps/dashboard/app/(app)/projects/[projectId]/details/active-deployment-card/status-indicator.tsxinternal/icons/src/icons/double-chevron-right.tsxinternal/icons/src/icons/location2.tsxapps/dashboard/app/(app)/projects/[projectId]/details/env-variables-section/env-var-row.tsxinternal/icons/src/icons/circle-xmark.tsxinternal/icons/src/icons/triangle-warning-2.tsxapps/dashboard/app/(app)/projects/[projectId]/deployments/page.tsxinternal/icons/src/icons/paperclip-2.tsxapps/dashboard/app/(app)/projects/[projectId]/details/active-deployment-card/filter-button.tsxapps/dashboard/app/(app)/projects/[projectId]/deployments/components/controls/components/deployment-list-search/index.tsxapps/dashboard/lib/trpc/routers/deploy/project/active-deployment/getBuildLogs.tsapps/dashboard/app/(app)/projects/[projectId]/details/env-variables-section/add-env-var-row.tsxinternal/icons/src/icons/share-up-right.tsxinternal/icons/src/icons/chevron-down.tsxapps/dashboard/app/(app)/projects/[projectId]/details/domain-row.tsxapps/dashboard/app/(app)/projects/[projectId]/details/active-deployment-card/skeleton.tsxinternal/icons/src/icons/double-chevron-left.tsxapps/dashboard/app/(app)/projects/[projectId]/details/active-deployment-card/hooks/use-deployment-logs.tsxapps/dashboard/app/(app)/projects/[projectId]/details/collapsible-row.tsxapps/dashboard/app/(app)/projects/[projectId]/details/active-deployment-card/info-chip.tsxinternal/icons/src/icons/grid-circle.tsxinternal/icons/src/icons/code-commit.tsxinternal/icons/src/icons/chart-activity.tsxapps/dashboard/app/(app)/projects/[projectId]/details/project-details-expandables/index.tsxapps/dashboard/app/(app)/projects/[projectId]/logs/page.tsxapps/dashboard/app/(app)/projects/[projectId]/details/env-variables-section/hooks/use-env-var.tsxapps/dashboard/app/(app)/projects/[projectId]/details/project-details-expandables/sections.tsxapps/dashboard/app/(app)/projects/[projectId]/navigations/project-sub-navigation.tsxapps/dashboard/app/(app)/projects/[projectId]/deployments/components/table/hooks/use-deployments-list-query.tsapps/dashboard/app/(app)/projects/[projectId]/details/project-details-expandables/detail-section.tsxinternal/icons/src/icons/hard-drive.tsxapps/dashboard/app/(app)/projects/[projectId]/details/env-variables-section/index.tsxapps/dashboard/lib/trpc/routers/deploy/project/active-deployment/getDetails.tsapps/dashboard/app/(app)/projects/[projectId]/layout.tsxinternal/icons/src/icons/bolt.tsxapps/dashboard/app/(app)/projects/[projectId]/details/active-deployment-card/index.tsxapps/dashboard/app/(app)/projects/[projectId]/layout-provider.tsxapps/dashboard/app/(app)/projects/[projectId]/page.tsxapps/dashboard/lib/trpc/routers/deploy/project/envs/list.tsinternal/icons/src/icons/message-writing.tsxapps/dashboard/lib/trpc/routers/index.tsinternal/icons/src/icons/connections.tsxapps/dashboard/app/(app)/projects/[projectId]/navigations/project-navigation.tsxinternal/icons/src/index.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx}: Follow strict TypeScript configuration
Use Zod for runtime validation in TypeScript projects
Files:
apps/dashboard/app/(app)/projects/[projectId]/details/active-deployment-card/card.tsxinternal/icons/src/icons/heart.tsxinternal/icons/src/icons/list-radio.tsxapps/dashboard/app/(app)/projects/[projectId]/details/active-deployment-card/status-indicator.tsxinternal/icons/src/icons/double-chevron-right.tsxinternal/icons/src/icons/location2.tsxapps/dashboard/app/(app)/projects/[projectId]/details/env-variables-section/env-var-row.tsxinternal/icons/src/icons/circle-xmark.tsxinternal/icons/src/icons/triangle-warning-2.tsxapps/dashboard/app/(app)/projects/[projectId]/deployments/page.tsxinternal/icons/src/icons/paperclip-2.tsxapps/dashboard/app/(app)/projects/[projectId]/details/active-deployment-card/filter-button.tsxapps/dashboard/app/(app)/projects/[projectId]/deployments/components/controls/components/deployment-list-search/index.tsxapps/dashboard/lib/trpc/routers/deploy/project/active-deployment/getBuildLogs.tsapps/dashboard/app/(app)/projects/[projectId]/details/env-variables-section/add-env-var-row.tsxinternal/icons/src/icons/share-up-right.tsxinternal/icons/src/icons/chevron-down.tsxapps/dashboard/app/(app)/projects/[projectId]/details/domain-row.tsxapps/dashboard/app/(app)/projects/[projectId]/details/active-deployment-card/skeleton.tsxinternal/icons/src/icons/double-chevron-left.tsxapps/dashboard/app/(app)/projects/[projectId]/details/active-deployment-card/hooks/use-deployment-logs.tsxapps/dashboard/app/(app)/projects/[projectId]/details/collapsible-row.tsxapps/dashboard/app/(app)/projects/[projectId]/details/active-deployment-card/info-chip.tsxinternal/icons/src/icons/grid-circle.tsxinternal/icons/src/icons/code-commit.tsxinternal/icons/src/icons/chart-activity.tsxapps/dashboard/app/(app)/projects/[projectId]/details/project-details-expandables/index.tsxapps/dashboard/app/(app)/projects/[projectId]/logs/page.tsxapps/dashboard/app/(app)/projects/[projectId]/details/env-variables-section/hooks/use-env-var.tsxapps/dashboard/app/(app)/projects/[projectId]/details/project-details-expandables/sections.tsxapps/dashboard/app/(app)/projects/[projectId]/navigations/project-sub-navigation.tsxapps/dashboard/app/(app)/projects/[projectId]/deployments/components/table/hooks/use-deployments-list-query.tsapps/dashboard/app/(app)/projects/[projectId]/details/project-details-expandables/detail-section.tsxinternal/icons/src/icons/hard-drive.tsxapps/dashboard/app/(app)/projects/[projectId]/details/env-variables-section/index.tsxapps/dashboard/lib/trpc/routers/deploy/project/active-deployment/getDetails.tsapps/dashboard/app/(app)/projects/[projectId]/layout.tsxinternal/icons/src/icons/bolt.tsxapps/dashboard/app/(app)/projects/[projectId]/details/active-deployment-card/index.tsxapps/dashboard/app/(app)/projects/[projectId]/layout-provider.tsxapps/dashboard/app/(app)/projects/[projectId]/page.tsxapps/dashboard/lib/trpc/routers/deploy/project/envs/list.tsinternal/icons/src/icons/message-writing.tsxapps/dashboard/lib/trpc/routers/index.tsinternal/icons/src/icons/connections.tsxapps/dashboard/app/(app)/projects/[projectId]/navigations/project-navigation.tsxinternal/icons/src/index.ts
**/*.{env,js,ts,go}
📄 CodeRabbit inference engine (CLAUDE.md)
All environment variables must follow the format: UNKEY_<SERVICE_NAME>_VARNAME
Files:
apps/dashboard/lib/trpc/routers/deploy/project/active-deployment/getBuildLogs.tsapps/dashboard/app/(app)/projects/[projectId]/deployments/components/table/hooks/use-deployments-list-query.tsapps/dashboard/lib/trpc/routers/deploy/project/active-deployment/getDetails.tsapps/dashboard/lib/trpc/routers/deploy/project/envs/list.tsapps/dashboard/lib/trpc/routers/index.tsinternal/icons/src/index.ts
🧠 Learnings (9)
📓 Common learnings
Learnt from: mcstepp
PR: unkeyed/unkey#3662
File: apps/dashboard/lib/trpc/routers/deployment/list.ts:11-11
Timestamp: 2025-07-25T19:09:43.284Z
Learning: In apps/dashboard/lib/trpc/routers/deployment/list.ts, the listDeployments procedure intentionally queries the versions table rather than a deployments table. The user mcstepp indicated that renaming the table would require a database migration, which was deferred for the current PR focused on UI features.
📚 Learning: 2025-08-25T13:05:22.441Z
Learnt from: ogzhanolguncu
PR: unkeyed/unkey#3834
File: internal/ui/src/components/form/input.tsx:130-131
Timestamp: 2025-08-25T13:05:22.441Z
Learning: The Input component in internal/ui/src/components/form/input.tsx is designed to support interactive right icons (like X buttons for deletion) by enabling pointer events on the right icon container, allowing clicks to be handled by the icon rather than passed through to the input.
Applied to files:
internal/icons/src/icons/double-chevron-right.tsxinternal/icons/src/icons/share-up-right.tsx
📚 Learning: 2025-07-25T19:09:43.284Z
Learnt from: mcstepp
PR: unkeyed/unkey#3662
File: apps/dashboard/lib/trpc/routers/deployment/list.ts:11-11
Timestamp: 2025-07-25T19:09:43.284Z
Learning: In apps/dashboard/lib/trpc/routers/deployment/list.ts, the listDeployments procedure intentionally queries the versions table rather than a deployments table. The user mcstepp indicated that renaming the table would require a database migration, which was deferred for the current PR focused on UI features.
Applied to files:
apps/dashboard/app/(app)/projects/[projectId]/deployments/page.tsxapps/dashboard/app/(app)/projects/[projectId]/deployments/components/controls/components/deployment-list-search/index.tsxapps/dashboard/lib/trpc/routers/deploy/project/active-deployment/getBuildLogs.tsapps/dashboard/app/(app)/projects/[projectId]/deployments/components/table/hooks/use-deployments-list-query.tsapps/dashboard/lib/trpc/routers/deploy/project/active-deployment/getDetails.tsapps/dashboard/lib/trpc/routers/deploy/project/envs/list.tsapps/dashboard/lib/trpc/routers/index.ts
📚 Learning: 2025-07-25T19:11:00.208Z
Learnt from: mcstepp
PR: unkeyed/unkey#3662
File: apps/dashboard/lib/trpc/routers/deployment/getOpenApiDiff.ts:110-147
Timestamp: 2025-07-25T19:11:00.208Z
Learning: In apps/dashboard/lib/trpc/routers/deployment/getOpenApiDiff.ts, the user mcstepp prefers to keep mock data fallbacks in POC/demonstration code for simplicity, even if it wouldn't be production-ready. This aligns with the PR being work-in-progress for demonstration purposes.
Applied to files:
apps/dashboard/lib/trpc/routers/deploy/project/active-deployment/getBuildLogs.tsapps/dashboard/lib/trpc/routers/deploy/project/active-deployment/getDetails.tsapps/dashboard/lib/trpc/routers/index.ts
📚 Learning: 2025-07-28T20:36:36.865Z
Learnt from: mcstepp
PR: unkeyed/unkey#3662
File: apps/dashboard/lib/trpc/routers/branch/getByName.ts:0-0
Timestamp: 2025-07-28T20:36:36.865Z
Learning: In apps/dashboard/lib/trpc/routers/branch/getByName.ts, mcstepp prefers to keep mock data (gitCommitMessage, buildDuration, lastCommitAuthor, etc.) in the branch procedure during POC phases to demonstrate what the UI would look like with proper schema changes, rather than returning null/undefined values.
Applied to files:
apps/dashboard/lib/trpc/routers/deploy/project/active-deployment/getBuildLogs.ts
📚 Learning: 2025-07-28T19:42:37.047Z
Learnt from: mcstepp
PR: unkeyed/unkey#3662
File: apps/dashboard/app/(app)/projects/page.tsx:74-81
Timestamp: 2025-07-28T19:42:37.047Z
Learning: In apps/dashboard/app/(app)/projects/page.tsx, the user mcstepp prefers to keep placeholder functions like generateSlug inline during POC/demonstration phases rather than extracting them to utility modules, with plans to refactor later when the feature matures beyond the proof-of-concept stage.
Applied to files:
apps/dashboard/app/(app)/projects/[projectId]/logs/page.tsx
📚 Learning: 2025-07-28T20:38:53.244Z
Learnt from: mcstepp
PR: unkeyed/unkey#3662
File: apps/dashboard/app/(app)/projects/[projectId]/diff/[...compare]/components/client.tsx:322-341
Timestamp: 2025-07-28T20:38:53.244Z
Learning: In apps/dashboard/app/(app)/projects/[projectId]/diff/[...compare]/components/client.tsx, mcstepp prefers to keep hardcoded endpoint logic in the getDiffType function during POC phases for demonstrating diff functionality, rather than implementing a generic diff algorithm. This follows the pattern of keeping simplified implementations for demonstration purposes.
Applied to files:
apps/dashboard/app/(app)/projects/[projectId]/logs/page.tsxapps/dashboard/app/(app)/projects/[projectId]/layout.tsx
📚 Learning: 2025-08-18T10:28:47.391Z
Learnt from: ogzhanolguncu
PR: unkeyed/unkey#3797
File: apps/dashboard/app/(app)/projects/[projectId]/deployments/components/control-cloud/index.tsx:1-4
Timestamp: 2025-08-18T10:28:47.391Z
Learning: In Next.js App Router, components that use React hooks don't need their own "use client" directive if they are rendered within a client component that already has the directive. The client boundary propagates to child components.
Applied to files:
apps/dashboard/app/(app)/projects/[projectId]/logs/page.tsx
📚 Learning: 2025-06-02T11:09:58.791Z
Learnt from: ogzhanolguncu
PR: unkeyed/unkey#3292
File: apps/dashboard/lib/trpc/routers/key/create.ts:11-14
Timestamp: 2025-06-02T11:09:58.791Z
Learning: In the unkey codebase, TypeScript and the env() function implementation already provide sufficient validation for environment variables, so additional runtime error handling for missing env vars is not needed.
Applied to files:
apps/dashboard/lib/trpc/routers/deploy/project/envs/list.ts
🧬 Code graph analysis (32)
internal/icons/src/icons/heart.tsx (1)
internal/icons/src/props.ts (2)
IconProps(30-36)sizeMap(7-28)
internal/icons/src/icons/list-radio.tsx (1)
internal/icons/src/props.ts (2)
IconProps(30-36)sizeMap(7-28)
internal/icons/src/icons/double-chevron-right.tsx (1)
internal/icons/src/props.ts (2)
IconProps(30-36)sizeMap(7-28)
internal/icons/src/icons/location2.tsx (1)
internal/icons/src/props.ts (2)
IconProps(30-36)sizeMap(7-28)
apps/dashboard/app/(app)/projects/[projectId]/details/env-variables-section/env-var-row.tsx (5)
apps/dashboard/lib/trpc/routers/deploy/project/envs/list.ts (1)
EnvVar(18-18)internal/icons/src/icons/eye-slash.tsx (1)
EyeSlash(15-64)internal/icons/src/icons/eye.tsx (1)
Eye(15-47)internal/icons/src/icons/pen-writing-3.tsx (1)
PenWriting3(15-45)internal/icons/src/icons/trash.tsx (1)
Trash(16-57)
internal/icons/src/icons/circle-xmark.tsx (1)
internal/icons/src/props.ts (2)
IconProps(30-36)sizeMap(7-28)
internal/icons/src/icons/paperclip-2.tsx (1)
internal/icons/src/props.ts (2)
IconProps(30-36)sizeMap(7-28)
apps/dashboard/app/(app)/projects/[projectId]/details/active-deployment-card/filter-button.tsx (1)
internal/icons/src/props.ts (1)
IconProps(30-36)
apps/dashboard/lib/trpc/routers/deploy/project/active-deployment/getBuildLogs.ts (1)
apps/dashboard/lib/trpc/trpc.ts (4)
t(8-8)requireUser(10-21)requireWorkspace(23-36)withRatelimit(122-138)
internal/icons/src/icons/share-up-right.tsx (1)
internal/icons/src/props.ts (2)
IconProps(30-36)sizeMap(7-28)
internal/icons/src/icons/chevron-down.tsx (1)
internal/icons/src/props.ts (1)
sizeMap(7-28)
internal/icons/src/icons/double-chevron-left.tsx (1)
internal/icons/src/props.ts (2)
IconProps(30-36)sizeMap(7-28)
apps/dashboard/app/(app)/projects/[projectId]/details/active-deployment-card/hooks/use-deployment-logs.tsx (1)
internal/clickhouse/src/logs.ts (1)
log(24-38)
apps/dashboard/app/(app)/projects/[projectId]/details/active-deployment-card/info-chip.tsx (1)
internal/icons/src/props.ts (1)
IconProps(30-36)
internal/icons/src/icons/grid-circle.tsx (1)
internal/icons/src/props.ts (2)
IconProps(30-36)sizeMap(7-28)
internal/icons/src/icons/chart-activity.tsx (1)
internal/icons/src/props.ts (2)
IconProps(30-36)sizeMap(7-28)
apps/dashboard/app/(app)/projects/[projectId]/details/project-details-expandables/index.tsx (3)
apps/dashboard/lib/trpc/server.ts (1)
trpc(7-14)apps/dashboard/app/(app)/projects/[projectId]/details/project-details-expandables/sections.tsx (2)
createDetailSections(35-271)DetailSection(30-33)apps/dashboard/app/(app)/projects/[projectId]/details/project-details-expandables/detail-section.tsx (1)
DetailSection(33-55)
apps/dashboard/app/(app)/projects/[projectId]/details/env-variables-section/hooks/use-env-var.tsx (2)
apps/dashboard/lib/trpc/server.ts (1)
trpc(7-14)apps/dashboard/lib/trpc/routers/deploy/project/envs/list.ts (1)
EnvVar(18-18)
apps/dashboard/app/(app)/projects/[projectId]/details/project-details-expandables/sections.tsx (2)
apps/dashboard/app/(app)/projects/[projectId]/details/project-details-expandables/detail-section.tsx (1)
DetailSection(33-55)apps/dashboard/lib/trpc/routers/deploy/project/active-deployment/getDetails.ts (1)
DeploymentDetails(46-46)
apps/dashboard/app/(app)/projects/[projectId]/navigations/project-sub-navigation.tsx (4)
internal/icons/src/props.ts (1)
IconProps(30-36)internal/icons/src/icons/grid-circle.tsx (1)
GridCircle(15-69)internal/icons/src/icons/cloud.tsx (1)
Cloud(15-38)internal/icons/src/icons/layers-3.tsx (1)
Layers3(16-54)
apps/dashboard/app/(app)/projects/[projectId]/details/project-details-expandables/detail-section.tsx (1)
apps/dashboard/app/(app)/projects/[projectId]/details/project-details-expandables/sections.tsx (2)
DetailItem(23-28)DetailSection(30-33)
internal/icons/src/icons/hard-drive.tsx (1)
internal/icons/src/props.ts (2)
IconProps(30-36)sizeMap(7-28)
apps/dashboard/app/(app)/projects/[projectId]/details/env-variables-section/index.tsx (3)
apps/dashboard/app/(app)/projects/[projectId]/details/env-variables-section/hooks/use-env-var.tsx (1)
useEnvVars(10-91)apps/dashboard/app/(app)/projects/[projectId]/details/env-variables-section/env-var-row.tsx (1)
EnvVarRow(15-120)apps/dashboard/app/(app)/projects/[projectId]/details/env-variables-section/add-env-var-row.tsx (1)
AddEnvVarRow(11-71)
apps/dashboard/lib/trpc/routers/deploy/project/active-deployment/getDetails.ts (1)
apps/dashboard/lib/trpc/trpc.ts (4)
t(8-8)requireUser(10-21)requireWorkspace(23-36)withRatelimit(122-138)
apps/dashboard/app/(app)/projects/[projectId]/layout.tsx (5)
apps/dashboard/lib/trpc/server.ts (1)
trpc(7-14)apps/dashboard/app/(app)/projects/[projectId]/layout-provider.tsx (1)
ProjectLayoutContext(14-14)apps/dashboard/app/(app)/projects/[projectId]/navigations/project-navigation.tsx (1)
ProjectNavigation(14-96)apps/dashboard/app/(app)/projects/[projectId]/navigations/project-sub-navigation.tsx (1)
ProjectSubNavigation(16-111)apps/dashboard/app/(app)/projects/[projectId]/details/project-details-expandables/index.tsx (1)
ProjectDetailsExpandable(15-157)
internal/icons/src/icons/bolt.tsx (1)
internal/icons/src/props.ts (2)
IconProps(30-36)sizeMap(7-28)
apps/dashboard/app/(app)/projects/[projectId]/details/active-deployment-card/index.tsx (5)
apps/dashboard/app/(app)/projects/[projectId]/layout-provider.tsx (1)
useProjectLayout(16-22)apps/dashboard/app/(app)/projects/[projectId]/details/active-deployment-card/hooks/use-deployment-logs.tsx (1)
useDeploymentLogs(52-171)apps/dashboard/app/(app)/projects/[projectId]/details/active-deployment-card/info-chip.tsx (1)
InfoChip(8-13)apps/dashboard/app/(app)/projects/[projectId]/details/active-deployment-card/filter-button.tsx (1)
FilterButton(13-34)internal/ui/src/components/buttons/copy-button.tsx (1)
CopyButton(27-81)
apps/dashboard/app/(app)/projects/[projectId]/page.tsx (6)
apps/dashboard/app/(app)/projects/[projectId]/layout-provider.tsx (1)
useProjectLayout(16-22)internal/icons/src/icons/cloud.tsx (1)
Cloud(15-38)internal/icons/src/icons/earth.tsx (1)
Earth(15-40)internal/icons/src/icons/folder-cloud.tsx (1)
FolderCloud(16-47)apps/dashboard/app/(app)/projects/[projectId]/details/env-variables-section/index.tsx (1)
EnvironmentVariablesSection(21-168)internal/icons/src/icons/page-2.tsx (1)
Page2(15-76)
apps/dashboard/lib/trpc/routers/deploy/project/envs/list.ts (1)
apps/dashboard/lib/trpc/trpc.ts (4)
t(8-8)requireUser(10-21)requireWorkspace(23-36)withRatelimit(122-138)
internal/icons/src/icons/message-writing.tsx (1)
internal/icons/src/props.ts (2)
IconProps(30-36)sizeMap(7-28)
apps/dashboard/lib/trpc/routers/index.ts (5)
apps/dashboard/lib/trpc/trpc.ts (1)
t(8-8)apps/dashboard/lib/trpc/routers/deploy/project/active-deployment/getDetails.ts (1)
getDeploymentDetails(48-99)apps/dashboard/lib/trpc/routers/deploy/project/active-deployment/getBuildLogs.ts (1)
getDeploymentBuildLogs(217-230)apps/dashboard/lib/trpc/routers/deploy/project/deployment/list.ts (1)
queryDeployments(70-253)apps/dashboard/lib/trpc/routers/deploy/project/deployment/llm-search/index.ts (1)
deploymentListLlmSearch(13-20)
apps/dashboard/app/(app)/projects/[projectId]/navigations/project-navigation.tsx (6)
internal/icons/src/icons/refresh-3.tsx (1)
Refresh3(15-46)apps/dashboard/app/(app)/projects/_components/list/repo-display.tsx (1)
RepoDisplay(12-34)apps/dashboard/components/navigation/action-button.tsx (1)
NavbarActionButton(22-53)internal/icons/src/icons/list-radio.tsx (1)
ListRadio(15-72)internal/icons/src/icons/arrow-dotted-rotate-anticlockwise.tsx (1)
ArrowDottedRotateAnticlockwise(15-57)internal/icons/src/icons/dots.tsx (1)
Dots(15-60)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: Test API / API Test Local
- GitHub Check: Test Go API Local / Test
- GitHub Check: Test Packages / Test
- GitHub Check: Build / Build
🔇 Additional comments (23)
apps/dashboard/app/(app)/projects/[projectId]/layout-provider.tsx (1)
16-22: Hook error message is clear; LGTM.internal/icons/src/icons/connections.tsx (1)
18-51: LGTM — consistent with icon system (sizeMap, per-shape stroke, prop forwarding).internal/icons/src/icons/share-up-right.tsx (1)
15-56: New icon looks good; follows sizeMap + strokeWidth patternComponent API, sizing, and strokes are consistent with the icon system.
apps/dashboard/app/(app)/projects/[projectId]/deployments/components/controls/components/deployment-list-search/index.tsx (1)
9-10: Verified:trpc.deploy.project.deployment.searchexists and client types are up-to-date
Thesearchprocedure is implemented in apps/dashboard/lib/trpc/routers/deploy/project/deployment/llm-search/index.ts and wired into the root router at apps/dashboard/lib/trpc/routers/index.ts, matching the client call in deployment-list-search/index.tsx.internal/icons/src/icons/location2.tsx (1)
15-59: Solid addition; matches icon system patternsSized via sizeMap, uses strokeWidth consistently, and forwards props. Looks good.
apps/dashboard/app/(app)/projects/[projectId]/deployments/components/table/hooks/use-deployments-list-query.ts (2)
93-98: Good migration to project-scoped TRPC endpoint.The switch to
trpc.deploy.project.deployment.list.useInfiniteQuerywith sane query options looks correct and aligns with the PR’s project scoping.
1-3: Remove verification note—Deploymenttype andproject.deployment.listroute confirmed available.internal/icons/src/icons/hard-drive.tsx (1)
1-11: Ensure Nucleo-licensed icons aren’t publicly distributed
No “files” field in package.json and no .npmignore present, so internal/icons/ will be bundled on publish. The Nucleo license forbids redistribution—either exclude this folder from your npm package (via a files entry or .npmignore) or replace these icons with an OSS or custom alternative.apps/dashboard/lib/trpc/routers/index.ts (1)
319-322: LGTM: scoped active deployment routesAdding
activeDeployment.detailsandactiveDeployment.buildLogsunderdeploy.projectscopes routes cleanly and avoids top-level bloat.internal/icons/src/icons/bolt.tsx (1)
15-35: LGTM: sizeMap integrationBinding
height/widthandstrokeWidthtosizeMapaligns with the new icon system.apps/dashboard/app/(app)/projects/[projectId]/details/active-deployment-card/filter-button.tsx (2)
13-19: LGTM overall.Clear API and styling; props are well-typed and usage of composition via icon prop is solid.
1-3: Prefer public barrels over deep importsAvoid coupling to internal paths—import IconProps and cn directly from the package root (assuming they’re publicly exported; otherwise add them to the exports):
-import type { IconProps } from "@unkey/icons/src/props"; -import { Button } from "@unkey/ui"; -import { cn } from "@unkey/ui/src/lib/utils"; +import type { IconProps } from "@unkey/icons"; +import { Button, cn } from "@unkey/ui";Verify that
IconPropsandcnare exposed in the respective package barrels; if not, re-export them at the top level.apps/dashboard/app/(app)/projects/[projectId]/details/active-deployment-card/hooks/use-deployment-logs.tsx (1)
61-65: Verify API shape of build logs (timestamp units, level values).Confirm tRPC endpoint returns timestamp in ms (or s), and level strictly in "info" | "warning" | "error". If different, adjust formatter and filters accordingly.
Would you like me to scan the PR for getBuildLogs.ts and validate the Zod schema and return types?
Also applies to: 72-77
apps/dashboard/app/(app)/projects/[projectId]/details/active-deployment-card/skeleton.tsx (1)
7-67: LGTM for UX.Skeleton is cohesive and mirrors the final layout well.
internal/icons/src/icons/code-commit.tsx (1)
22-58: LGTM: Icon matches library conventions.Consistent viewBox, stroke handling, and props usage. No issues.
apps/dashboard/app/(app)/projects/[projectId]/page.tsx (1)
3-3: Confirmcnre-export in@unkey/ui
Could not locate an entry-point export forcn—please verify that@unkey/ui’s root (e.g.src/index.ts) re-exportscn(for example,export { cn } from './lib/utils'). If it isn’t exported, add that re-export or maintain a local wrapper.apps/dashboard/app/(app)/projects/[projectId]/navigations/project-navigation.tsx (1)
15-23: Useproject.getinstead of listing all projectsReplace the infinite query on
trpc.deploy.project.list(lines 15–23 and 25–27) with atrpc.deploy.project.get({ id: projectId }).useQuery()to fetch only the needed project and reduce payload.apps/dashboard/app/(app)/projects/[projectId]/details/project-details-expandables/index.tsx (1)
21-29: Render a lightweight skeleton when details aren’t cached yet, notnull.
nullmakes the drawer silently disappear on first open. Add a simple loader so UX remains coherent.⛔ Skipped due to learnings
Learnt from: ogzhanolguncu PR: unkeyed/unkey#3380 File: apps/dashboard/app/(app)/ratelimits/[namespaceId]/namespace-navbar.tsx:40-66 Timestamp: 2025-06-19T10:39:29.388Z Learning: tRPC has built-in caching that prevents skeleton flashing during component re-renders and navigation, so concerns about `!data || isLoading` conditions causing loading state flashes are generally not needed.apps/dashboard/app/(app)/projects/[projectId]/details/active-deployment-card/index.tsx (3)
41-42: Guard against missing activeDeploymentIdAvoid firing queries with undefined id and show skeleton early.
export function ActiveDeploymentCard() { const { activeDeploymentId } = useProjectLayout(); + if (!activeDeploymentId) return <ActiveDeploymentCardSkeleton />;
191-236: Potential performance issue rendering many log rowsConsider windowing (e.g., react-virtualized/react-window) for large logs to avoid heavy DOM/animation costs.
⛔ Skipped due to learnings
Learnt from: ogzhanolguncu PR: unkeyed/unkey#2143 File: apps/dashboard/app/(app)/logs/logs-page.tsx:77-83 Timestamp: 2024-12-03T14:17:08.016Z Learning: The `<LogsTable />` component already implements virtualization to handle large datasets efficiently.
74-74: Verify StatusIndicator props
Confirm whether<StatusIndicator>requires astatusprop—if so, supply it here or update the component to handle missing props.internal/icons/src/index.ts (2)
27-27: Barrel re-exports look good; additive and consistentNo functional risk; names match the icon file slugs.
Also applies to: 49-49, 65-66, 77-81, 91-92, 95-95, 101-101, 107-107, 112-116, 117-131
27-27: No missing or duplicate exports found – all icon modules referenced in internal/icons/src/index.ts exist and no duplicate entries were detected.
apps/dashboard/app/(app)/projects/[projectId]/details/active-deployment-card/card.tsx
Show resolved
Hide resolved
apps/dashboard/app/(app)/projects/[projectId]/details/active-deployment-card/card.tsx
Show resolved
Hide resolved
...dashboard/app/(app)/projects/[projectId]/details/active-deployment-card/status-indicator.tsx
Show resolved
Hide resolved
apps/dashboard/app/(app)/projects/[projectId]/details/active-deployment-card/filter-button.tsx
Show resolved
Hide resolved
apps/dashboard/app/(app)/projects/[projectId]/details/active-deployment-card/filter-button.tsx
Show resolved
Hide resolved
.../app/(app)/projects/[projectId]/details/active-deployment-card/hooks/use-deployment-logs.tsx
Outdated
Show resolved
Hide resolved
.../app/(app)/projects/[projectId]/details/active-deployment-card/hooks/use-deployment-logs.tsx
Show resolved
Hide resolved
.../app/(app)/projects/[projectId]/details/active-deployment-card/hooks/use-deployment-logs.tsx
Show resolved
Hide resolved
apps/dashboard/app/(app)/projects/[projectId]/details/active-deployment-card/index.tsx
Show resolved
Hide resolved
apps/dashboard/app/(app)/projects/[projectId]/details/active-deployment-card/index.tsx
Show resolved
Hide resolved
apps/dashboard/app/(app)/projects/[projectId]/details/active-deployment-card/index.tsx
Show resolved
Hide resolved
apps/dashboard/app/(app)/projects/[projectId]/details/active-deployment-card/index.tsx
Show resolved
Hide resolved
apps/dashboard/app/(app)/projects/[projectId]/details/active-deployment-card/index.tsx
Show resolved
Hide resolved
apps/dashboard/app/(app)/projects/[projectId]/details/project-details-expandables/sections.tsx
Show resolved
Hide resolved
apps/dashboard/app/(app)/projects/[projectId]/details/project-details-expandables/sections.tsx
Show resolved
Hide resolved
apps/dashboard/app/(app)/projects/[projectId]/details/project-details-expandables/sections.tsx
Show resolved
Hide resolved
There was a problem hiding this comment.
Actionable comments posted: 9
♻️ Duplicate comments (7)
apps/dashboard/app/(app)/projects/[projectId]/details/active-deployment-card/hooks/use-deployment-logs.tsx (5)
53-55: Guard the query with enabled; consider sensible fetch options.Prevents accidental fires on empty deploymentId and reduces UI jitter from refetches.
- const { data: logsData, isLoading } = trpc.deploy.project.activeDeployment.buildLogs.useQuery({ - deploymentId, - }); + const { data: logsData, isLoading } = + trpc.deploy.project.activeDeployment.buildLogs.useQuery( + { deploymentId }, + { + enabled: Boolean(deploymentId), + staleTime: 5_000, + refetchOnWindowFocus: false, + }, + );
63-68: Normalize timestamps (s vs ms) and sort before mapping to avoid janky ordering.Handles seconds vs milliseconds and ensures chronological order.
- return logsData.logs.map((log) => ({ - timestamp: format(new Date(log.timestamp), "HH:mm:ss.SSS"), - level: log.level, - message: log.message, - })); + return [...logsData.logs] + .sort((a, b) => Number(a.timestamp) - Number(b.timestamp)) + .map((log) => ({ + timestamp: formatTimestamp(log.timestamp), + level: log.level, + message: log.message, + }));Add this helper near the top of the file:
// Helper: format number/string/Date -> "HH:mm:ss.SSS"; accepts seconds or milliseconds const formatTimestamp = (timestamp: number | string | Date): string => { let ms: number; if (timestamp instanceof Date) { ms = timestamp.getTime(); } else if (typeof timestamp === "string") { const n = Number(timestamp); ms = Number.isFinite(n) ? n : Date.parse(timestamp); } else { ms = timestamp; } if (ms < 1_000_000_000_000) ms *= 1000; // treat as seconds return format(new Date(ms), "HH:mm:ss.SSS"); };
78-85: Compute log counts in one pass.Reduces work from multiple filters to a single O(n) reduce.
- const logCounts = useMemo( - () => ({ - total: logs.length, - errors: logs.filter((log) => log.level === "error").length, - warnings: logs.filter((log) => log.level === "warning").length, - }), - [logs], - ); + const logCounts = useMemo(() => { + return logs.reduce( + (acc, l) => { + acc.total += 1; + if (l.level === "error") acc.errors += 1; + else if (l.level === "warning") acc.warnings += 1; + return acc; + }, + { total: 0, errors: 0, warnings: 0 }, + ); + }, [logs]);
98-106: Precompute lowercased search term once.Avoids repeated allocations and clarifies intent.
- if (searchTerm.trim()) { - filtered = filtered.filter( - (log) => - log.message.toLowerCase().includes(searchTerm.toLowerCase()) || - log.timestamp.includes(searchTerm) || - log.level?.toLowerCase().includes(searchTerm.toLowerCase()), - ); - } + const term = searchTerm.trim().toLowerCase(); + if (term) { + filtered = filtered.filter( + (log) => + log.message.toLowerCase().includes(term) || + log.timestamp.includes(term) || + log.level?.toLowerCase().includes(term), + ); + }
118-123: Use requestAnimationFrame instead of magic timeout.rAF syncs with layout and avoids flakiness.
const setExpanded = (expanded: boolean) => { setIsExpanded(expanded); if (!expanded) { - setTimeout(resetScroll, 50); + requestAnimationFrame(() => resetScroll()); } };apps/dashboard/app/(app)/projects/[projectId]/details/project-details-expandables/sections.tsx (2)
30-33: Rename the exported type to avoid colliding with the DetailSection component.This name collides with apps/dashboard/app/(app)/projects/[projectId]/details/project-details-expandables/detail-section.tsx’s exported component name and causes confusing imports.
-export type DetailSection = { +export type DetailSectionData = { title: string; items: DetailItem[]; };Outside this range, update the return type accordingly:
-export const createDetailSections = (details: DeploymentDetails): DetailSection[] => [ +export const createDetailSections = (details: DeploymentDetails): DetailSectionData[] => [
146-148: Use “MB” (uppercase) for units.Keep unit casing consistent.
- <span className="text-gray-12 font-medium">{details.memory}</span>mb + <span className="text-gray-12 font-medium">{details.memory}</span> MB- <span className="text-gray-12 font-medium">{details.imageSize}</span> - mb + <span className="text-gray-12 font-medium">{details.imageSize}</span> MBAlso applies to: 214-216
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (2)
apps/dashboard/app/(app)/projects/[projectId]/details/active-deployment-card/hooks/use-deployment-logs.tsx(1 hunks)apps/dashboard/app/(app)/projects/[projectId]/details/project-details-expandables/sections.tsx(1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{js,jsx,ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{js,jsx,ts,tsx}: Use Biome for formatting and linting in TypeScript/JavaScript projects
Prefer named exports over default exports in TypeScript/JavaScript, except for Next.js pages
Files:
apps/dashboard/app/(app)/projects/[projectId]/details/project-details-expandables/sections.tsxapps/dashboard/app/(app)/projects/[projectId]/details/active-deployment-card/hooks/use-deployment-logs.tsx
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx}: Follow strict TypeScript configuration
Use Zod for runtime validation in TypeScript projects
Files:
apps/dashboard/app/(app)/projects/[projectId]/details/project-details-expandables/sections.tsxapps/dashboard/app/(app)/projects/[projectId]/details/active-deployment-card/hooks/use-deployment-logs.tsx
🧠 Learnings (3)
📓 Common learnings
Learnt from: mcstepp
PR: unkeyed/unkey#3662
File: apps/dashboard/lib/trpc/routers/deployment/list.ts:11-11
Timestamp: 2025-07-25T19:09:43.284Z
Learning: In apps/dashboard/lib/trpc/routers/deployment/list.ts, the listDeployments procedure intentionally queries the versions table rather than a deployments table. The user mcstepp indicated that renaming the table would require a database migration, which was deferred for the current PR focused on UI features.
📚 Learning: 2025-06-24T13:29:10.129Z
Learnt from: ogzhanolguncu
PR: unkeyed/unkey#3401
File: apps/dashboard/app/(app)/logs/filters.query-params.ts:10-0
Timestamp: 2025-06-24T13:29:10.129Z
Learning: The `buildQueryParams` function in `apps/dashboard/app/(app)/logs/filters.query-params.ts` calls `useFilters()` hook inside it, but this is valid because the function is only called from within other React hooks, maintaining the Rules of Hooks compliance.
Applied to files:
apps/dashboard/app/(app)/projects/[projectId]/details/active-deployment-card/hooks/use-deployment-logs.tsx
📚 Learning: 2025-07-25T19:11:00.208Z
Learnt from: mcstepp
PR: unkeyed/unkey#3662
File: apps/dashboard/lib/trpc/routers/deployment/getOpenApiDiff.ts:110-147
Timestamp: 2025-07-25T19:11:00.208Z
Learning: In apps/dashboard/lib/trpc/routers/deployment/getOpenApiDiff.ts, the user mcstepp prefers to keep mock data fallbacks in POC/demonstration code for simplicity, even if it wouldn't be production-ready. This aligns with the PR being work-in-progress for demonstration purposes.
Applied to files:
apps/dashboard/app/(app)/projects/[projectId]/details/active-deployment-card/hooks/use-deployment-logs.tsx
🧬 Code graph analysis (2)
apps/dashboard/app/(app)/projects/[projectId]/details/project-details-expandables/sections.tsx (2)
apps/dashboard/app/(app)/projects/[projectId]/details/project-details-expandables/detail-section.tsx (1)
DetailSection(33-55)apps/dashboard/lib/trpc/routers/deploy/project/active-deployment/getDetails.ts (1)
DeploymentDetails(46-46)
apps/dashboard/app/(app)/projects/[projectId]/details/active-deployment-card/hooks/use-deployment-logs.tsx (1)
apps/dashboard/lib/trpc/server.ts (1)
trpc(7-14)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
- GitHub Check: Test Go API Local / Test
- GitHub Check: Test API / API Test Local
- GitHub Check: Test Packages / Test
- GitHub Check: Build / Build
- GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (3)
apps/dashboard/app/(app)/projects/[projectId]/details/active-deployment-card/hooks/use-deployment-logs.tsx (1)
43-51: Verified useDeploymentLogs is only used in Client Components. All callers (e.g. apps/dashboard/app/(app)/projects/[projectId]/details/active-deployment-card/index.tsx) include the"use client"directive.apps/dashboard/app/(app)/projects/[projectId]/details/project-details-expandables/sections.tsx (2)
172-176: Regex fix looks good.Now only leading slashes are removed.
82-86: Configure Next.js Image Domains
Noimages.domainsorremotePatternsentries were found inapps/dashboard/next.config.js. You must add your avatar host (e.g.avatars.example.com) underimages.domainsor define a matchingremotePatternsentry so the<Image>component can load it.
.../app/(app)/projects/[projectId]/details/active-deployment-card/hooks/use-deployment-logs.tsx
Show resolved
Hide resolved
.../app/(app)/projects/[projectId]/details/active-deployment-card/hooks/use-deployment-logs.tsx
Show resolved
Hide resolved
apps/dashboard/app/(app)/projects/[projectId]/details/project-details-expandables/sections.tsx
Show resolved
Hide resolved
apps/dashboard/app/(app)/projects/[projectId]/details/project-details-expandables/sections.tsx
Show resolved
Hide resolved
apps/dashboard/app/(app)/projects/[projectId]/details/project-details-expandables/sections.tsx
Show resolved
Hide resolved
apps/dashboard/app/(app)/projects/[projectId]/details/project-details-expandables/sections.tsx
Show resolved
Hide resolved
apps/dashboard/app/(app)/projects/[projectId]/details/project-details-expandables/sections.tsx
Show resolved
Hide resolved
apps/dashboard/app/(app)/projects/[projectId]/details/project-details-expandables/sections.tsx
Show resolved
Hide resolved
apps/dashboard/app/(app)/projects/[projectId]/details/project-details-expandables/sections.tsx
Show resolved
Hide resolved
Graphite Automations"Post a GIF when PR approved" took an action on this PR • (09/01/25)1 gif was posted to this PR based on Andreas Thomas's automation. |

What does this PR do?
This PR adds new UI for project details, which includes active production deployment details with logs, a drawer for more details about the active deployment. The environment section is rough currently, it doesn't handle CRUD fully and just lists data directly. Most of the hardcoded data is coming from tRPC, so if we happen to go to production with deployment, anyone can change the data source and get the deployment UI ready.
Edit: Environment Variable section is very very very rough. I'll do a proper refactor when I return. This one should give us some insight about our actual logic.
Type of change
How should this be tested?
Checklist
Required
pnpm buildpnpm fmtconsole.logsgit pull origin mainAppreciated
Summary by CodeRabbit
New Features
Refactor