Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
1 Skipped Deployment
|
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughRemoves four legacy connector list page modules and adds a new api-key-connectors feature (types, params, hooks, server prefetch/router, UI components/layout) plus new connectors route pages that wire into the new feature; several list UIs were migrated to a DataTable + drawer pattern and minor routing/validation fixes applied. Changes
Sequence Diagram(s)sequenceDiagram
participant Page as Client Page
participant Loader as Server Loader (connectorsParamsLoader)
participant Prefetch as Server Prefetch
participant TRPC as TRPC Router (getManyByTypeInternal)
participant DB as Prisma DB
Page->>Loader: read pagination/search params
Page->>Prefetch: request prefetch for ResourceType
Prefetch->>TRPC: call getManyByTypeInternal(params + resourceType)
TRPC->>DB: fetch paginated connectors (where resourceType, include user)
DB-->>TRPC: return rows + counts
TRPC-->>Prefetch: return data (cached)
Prefetch-->>Page: hydrate prefetched data
Page->>Page: render ConnectorsList (columns, search, pagination)
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (3)
src/features/api-key-connectors/types.ts (1)
32-34: Consider using PascalCase for the exported type name.The type
paginatedConnectorsByTypeInputuses camelCase, while other types in this file (ConnectorResponse) and TypeScript convention typically use PascalCase for type aliases.✏️ Suggested fix
-export type paginatedConnectorsByTypeInput = z.infer< +export type PaginatedConnectorsByTypeInput = z.infer< typeof paginatedConnectorInputSchema >;🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/features/api-key-connectors/types.ts` around lines 32 - 34, The exported type name paginatedConnectorsByTypeInput should use PascalCase: rename it to PaginatedConnectorsByTypeInput and update its declaration to export type PaginatedConnectorsByTypeInput = z.infer<typeof paginatedConnectorInputSchema>; then search and update all usages/imports of paginatedConnectorsByTypeInput across the codebase (tests, consumers, and index exports) to the new PaginatedConnectorsByTypeInput identifier so imports and references remain consistent with ConnectorResponse and TS naming conventions.src/features/api-key-connectors/server/prefetch.ts (1)
1-3: Add'server-only'directive to prevent client-side imports.This is a server-side prefetch utility that should not be imported on the client. Adding the directive ensures bundler errors if accidentally imported client-side.
🛡️ Suggested fix
+import "server-only"; + import type { inferInput } from "@trpc/tanstack-react-query"; import { ResourceType } from "@/generated/prisma"; import { prefetch, trpc } from "@/trpc/server";As per coding guidelines: "Mark server-side files with 'server-only' directive".
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/features/api-key-connectors/server/prefetch.ts` around lines 1 - 3, Add the top-of-file "server-only" directive (a single line containing 'server-only') as the very first line to prevent client-side imports; update src features referenced symbols such as inferInput, ResourceType, prefetch, and trpc remain unchanged — just insert the directive before the existing imports so the bundler will error if this server-side prefetch utility is imported on the client.src/features/api-key-connectors/components/connectors.tsx (1)
107-117: Inconsistent use of hardcoded string vs enum forresourceType.
DeviceArtifactConnectorsContaineruses the string"Device Artifact"for display, while other containers useResourceType.*enum values directly. This works becauseConnectorsContaineracceptsResourceType | string, but it's inconsistent.Consider creating a display-name mapping to keep the prop type strict while still showing user-friendly names:
💡 Suggested approach
// At top of file or in a shared utility const resourceTypeDisplayNames: Record<ResourceType, string> = { [ResourceType.Asset]: "Asset", [ResourceType.DeviceArtifact]: "Device Artifact", [ResourceType.Remediation]: "Remediation", [ResourceType.Vulnerability]: "Vulnerability", }; // Then in ConnectorsHeader, use: // title={`${resourceTypeDisplayNames[resourceType as ResourceType] ?? resourceType} Connectors`}This would allow
ConnectorsContainerto always receiveResourceTypewhile still displaying "Device Artifact" with a space.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/features/api-key-connectors/components/connectors.tsx` around lines 107 - 117, DeviceArtifactConnectorsContainer currently passes the literal string "Device Artifact" into ConnectorsContainer which accepts ResourceType | string; change this to pass the ResourceType enum (ResourceType.DeviceArtifact) and add a display-name mapping (e.g., resourceTypeDisplayNames: Record<ResourceType,string>) used by ConnectorsHeader (or whatever renders the title) to convert ResourceType.DeviceArtifact into the user-friendly "Device Artifact"; update ConnectorsContainer prop typing to require ResourceType and ensure ConnectorsHeader uses resourceTypeDisplayNames[resourceType] ?? resourceType for its title.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/features/api-key-connectors/components/columns.tsx`:
- Around line 53-58: The status logic in the columns renderer (where text and
color are set based on row.original.apiKeyId) mislabels connectors that have a
valid integrationId as expired; update the condition in that component (the
block that sets text and color for status) to treat a row as Active when either
row.original.apiKeyId or row.original.integrationId is present, and mark Expired
only when both are missing, keeping the same color mapping (e.g., bg-green-300
for Active, bg-red-400 for Expired).
In `@src/features/api-key-connectors/server/params-loader.ts`:
- Around line 1-2: Add the "server-only" directive as the very first line of the
file and update the local import to use the project alias: keep the createLoader
import from "nuqs/server" but replace the relative connectors import
(connectorsParams from "../params") with the aliased path connectorsParams from
"@/features/api-key-connectors/params"; ensure the "server-only" string literal
appears before any imports so the file is explicitly marked server-side.
---
Nitpick comments:
In `@src/features/api-key-connectors/components/connectors.tsx`:
- Around line 107-117: DeviceArtifactConnectorsContainer currently passes the
literal string "Device Artifact" into ConnectorsContainer which accepts
ResourceType | string; change this to pass the ResourceType enum
(ResourceType.DeviceArtifact) and add a display-name mapping (e.g.,
resourceTypeDisplayNames: Record<ResourceType,string>) used by ConnectorsHeader
(or whatever renders the title) to convert ResourceType.DeviceArtifact into the
user-friendly "Device Artifact"; update ConnectorsContainer prop typing to
require ResourceType and ensure ConnectorsHeader uses
resourceTypeDisplayNames[resourceType] ?? resourceType for its title.
In `@src/features/api-key-connectors/server/prefetch.ts`:
- Around line 1-3: Add the top-of-file "server-only" directive (a single line
containing 'server-only') as the very first line to prevent client-side imports;
update src features referenced symbols such as inferInput, ResourceType,
prefetch, and trpc remain unchanged — just insert the directive before the
existing imports so the bundler will error if this server-side prefetch utility
is imported on the client.
In `@src/features/api-key-connectors/types.ts`:
- Around line 32-34: The exported type name paginatedConnectorsByTypeInput
should use PascalCase: rename it to PaginatedConnectorsByTypeInput and update
its declaration to export type PaginatedConnectorsByTypeInput = z.infer<typeof
paginatedConnectorInputSchema>; then search and update all usages/imports of
paginatedConnectorsByTypeInput across the codebase (tests, consumers, and index
exports) to the new PaginatedConnectorsByTypeInput identifier so imports and
references remain consistent with ConnectorResponse and TS naming conventions.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 41069a9f-826c-4444-bf02-64fff5d01bec
📒 Files selected for processing (13)
src/app/(dashboard)/(rest)/connectors/assets/page.tsxsrc/app/(dashboard)/(rest)/connectors/deviceArtifacts/page.tsxsrc/app/(dashboard)/(rest)/connectors/remediations/page.tsxsrc/app/(dashboard)/(rest)/connectors/vulnerabilities/page.tsxsrc/features/api-key-connectors/components/columns.tsxsrc/features/api-key-connectors/components/connectors.tsxsrc/features/api-key-connectors/hooks/use-connectors.tssrc/features/api-key-connectors/params.tssrc/features/api-key-connectors/server/params-loader.tssrc/features/api-key-connectors/server/prefetch.tssrc/features/api-key-connectors/server/routers.tssrc/features/api-key-connectors/types.tssrc/features/assets/components/asset.tsx
timrcm
left a comment
There was a problem hiding this comment.
Note Cassidy's feedback in Slack -- it looks like there might still be some issues with this after all.
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (2)
src/app/api/trpc/[trpc]/route.ts (1)
12-14: Consider structured logging and environment-aware verbosity.The error logging is functional, but for production use:
- Logging the full
errorobject may expose sensitive data or stack traces in production logs.- A more structured format would improve observability and log parsing.
♻️ Optional: Structured error logging
onError: ({ path, error }) => { - console.error(path, error); + console.error(`[tRPC Error] ${path}:`, { + code: error.code, + message: error.message, + ...(process.env.NODE_ENV === "development" && { stack: error.stack }), + }); },🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/app/api/trpc/`[trpc]/route.ts around lines 12 - 14, The onError handler currently logs the raw error object (onError: ({ path, error }) => { console.error(path, error); }) which can leak sensitive info and is unstructured; update the handler to emit structured logs (an object with path, error.message, error.name, optional status/code) and gate stack traces behind an environment check (e.g., include error.stack only when NODE_ENV !== 'production'), and redact any sensitive properties before logging or use an existing structured logger instance if available; ensure the handler still captures the path and a concise message for observability while avoiding full error dumps in production.src/features/api-key-connectors/components/connectors.tsx (1)
1-1: Rename this component file to PascalCase for consistency.This component lives in
src/features/.../components/but the filename isconnectors.tsx; please rename it toConnectors.tsxto match repo conventions.As per coding guidelines, "Use PascalCase for component file names and kebab-case for utility/helper file names".
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/features/api-key-connectors/components/connectors.tsx` at line 1, Rename the component file from connectors.tsx to Connectors.tsx and update all imports referencing it to the new filename; ensure the exported React component (Connectors) and any default export usages still match after the rename so imports like import Connectors from "…/components/Connectors" resolve correctly, and run project/type-check to catch any missed import paths.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/features/api-key-connectors/components/connectors.tsx`:
- Line 85: Remove the debug console logging of connector payloads: delete the
console.log("useSuspenseConnectorsByResourceType:", connectors) statement in the
connectors.tsx implementation (the useSuspenseConnectorsByResourceType flow that
handles the connectors variable) so fetched connector data is not printed to the
browser console; ensure no equivalent debug logs remain in the same module or
helper functions that expose connector payloads.
---
Nitpick comments:
In `@src/app/api/trpc/`[trpc]/route.ts:
- Around line 12-14: The onError handler currently logs the raw error object
(onError: ({ path, error }) => { console.error(path, error); }) which can leak
sensitive info and is unstructured; update the handler to emit structured logs
(an object with path, error.message, error.name, optional status/code) and gate
stack traces behind an environment check (e.g., include error.stack only when
NODE_ENV !== 'production'), and redact any sensitive properties before logging
or use an existing structured logger instance if available; ensure the handler
still captures the path and a concise message for observability while avoiding
full error dumps in production.
In `@src/features/api-key-connectors/components/connectors.tsx`:
- Line 1: Rename the component file from connectors.tsx to Connectors.tsx and
update all imports referencing it to the new filename; ensure the exported React
component (Connectors) and any default export usages still match after the
rename so imports like import Connectors from "…/components/Connectors" resolve
correctly, and run project/type-check to catch any missed import paths.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 56631c87-204d-4f97-adf6-2e0ac36f1c78
📒 Files selected for processing (2)
src/app/api/trpc/[trpc]/route.tssrc/features/api-key-connectors/components/connectors.tsx
There was a problem hiding this comment.
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)
src/features/assets/components/assets.tsx (1)
228-250:⚠️ Potential issue | 🟠 MajorFix type mismatch:
AssetsListWithDrawerreceivesAssetResponsebut expectsAssetWithIssues.The
columnsandcolumnsWithDrawerare typed asColumnDef<AssetResponse>[], butrow.original(passed tosetAsset) should be typed as data that includes theissuesfield. AlthoughgetManyInternalexplicitly includes issues in the Prisma query (include: { ...assetInclude, issues: true }), theAssetResponsetype definition doesn't reflect this. Either update the columns type to match whatgetManyInternalactually returns, or create a separate columns definition for this component.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/features/assets/components/assets.tsx` around lines 228 - 250, AssetsListWithDrawer is calling setAsset(row.original) but the table columns are typed as ColumnDef<AssetResponse>[] while the data returned by getManyInternal includes issues (AssetWithIssues); fix by aligning types: either change the columns/columnsWithActions type to ColumnDef<AssetWithIssues>[] so row.original is correctly typed for AssetDrawer, or update the AssetResponse type to include the issues field to match getManyInternal, or create a separate columns definition (e.g., columnsWithIssues) typed as ColumnDef<AssetWithIssues>[] and use that in AssetsListWithDrawer; ensure references to AssetsListWithDrawer, columnsWithActions, columns, AssetResponse, AssetWithIssues and getManyInternal are updated consistently.
🧹 Nitpick comments (4)
src/features/device-artifacts/components/columns.tsx (1)
19-24: Clarify theaccessorKeyvsaccessorFnmismatch.The column uses
accessorKey: "userId"butaccessorFnreturnsrow.user.name, and the header displays "Source Tool". This creates a semantic mismatch: TanStack Table will use"userId"as the column identifier for sorting/filtering state, but the actual displayed/accessed value is the user's name.Consider using
id: "sourceTool"(orid: "userName") instead ofaccessorKey: "userId"to better reflect the column's purpose:♻️ Suggested improvement
{ - accessorKey: "userId", + id: "sourceTool", meta: { title: "Source Tool" }, header: "Source Tool", accessorFn: (row) => row.user.name, },🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/features/device-artifacts/components/columns.tsx` around lines 19 - 24, The column has a semantic mismatch: it sets accessorKey: "userId" but uses accessorFn: (row) => row.user.name and header: "Source Tool"; update the column definition to use a clear identifier (e.g., replace accessorKey with id: "sourceTool" or id: "userName") and keep accessorFn as the source of truth so sorting/filtering uses the correct column id; ensure the id matches the displayed value and update any references that relied on "userId" for state or tests to the new id.src/features/assets/components/columns.tsx (1)
92-97: TODO: Implement delete action or add tracking issue.The delete action currently only logs
"TODO". Consider implementing the delete functionality or creating a tracking issue.Would you like me to help generate the delete implementation or open an issue to track this?
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/features/assets/components/columns.tsx` around lines 92 - 97, The TODO stub in the DropdownMenuItem onClick must be replaced with a real delete flow: add a handleDeleteAsset function and wire it to the onClick instead of console.log, call your existing delete mutation (e.g., deleteAssetMutation or deleteAsset) passing the asset id from the row props, show a confirmation prompt before calling it, handle success by refreshing the list or calling onDeleted/invalidating queries and show an error toast on failure; ensure the handler is referenced where DropdownMenuItem currently uses onClick and import/use the appropriate mutation hook (deleteAssetMutation/deleteAsset) and any toast/confirm utilities.src/features/api-key-connectors/components/connectors.tsx (1)
111-121: InconsistentresourceTypehandling for DeviceArtifact container.
DeviceArtifactConnectorsContaineruses a hardcoded string"Device Artifact"while all other containers use theResourceTypeenum. This inconsistency suggests theresourceTypeprop is being overloaded for both data fetching (enum) and display (human-readable string).Consider using a display name mapping (similar to
integrationsMappingwhich has anamefield) to keep the enum usage consistent.Proposed approach
+import { integrationsMapping } from "@/features/integrations/types"; + +const getDisplayName = (type: ResourceType): string => { + const entry = Object.values(integrationsMapping).find(m => m.type === type); + return entry?.name ?? type; +}; export const DeviceArtifactConnectorsContainer = ({ children, }: { children: React.ReactNode; }) => { return ( - <ConnectorsContainer resourceType={"Device Artifact"}> + <ConnectorsContainer resourceType={ResourceType.DeviceArtifact}> {children} </ConnectorsContainer> ); };Then update
ConnectorsHeaderto use the display name mapping:export const ConnectorsHeader = ({ disabled, resourceType, }: { disabled?: boolean; - resourceType: string; + resourceType: ResourceType; }) => { return ( <EntityHeader - title={`${resourceType} Connectors`} + title={`${getDisplayName(resourceType)} Connectors`}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/features/api-key-connectors/components/connectors.tsx` around lines 111 - 121, DeviceArtifactConnectorsContainer currently passes a hardcoded "Device Artifact" string to ConnectorsContainer; change it to pass the ResourceType enum value and use a display-name mapping for UI text so enum remains the single source for data-fetching. Update DeviceArtifactConnectorsContainer to pass ResourceType.DeviceArtifact (or the equivalent enum key), add or reuse a mapping (similar to integrationsMapping.name) that maps ResourceType values to human-readable names, and update ConnectorsHeader to read the display name from that mapping instead of relying on the prop string; reference the symbols DeviceArtifactConnectorsContainer, ConnectorsContainer, ConnectorsHeader, ResourceType, and integrationsMapping when making these edits.src/features/api-key-connectors/components/connectors-layout.tsx (1)
43-45: Active tab detection could be fragile.Using
pathname.includes(tabs[1].value)to detect the "items" tab may produce false positives if "items" appears elsewhere in the pathname (e.g., a future nested route). Consider a more precise check.Proposed improvement
- const activeTab = pathname.includes(tabs[1].value) - ? tabs[1].value - : tabs[0].value; + const activeTab = pathname.endsWith("/items") || pathname.includes("/items/") + ? tabs[1].value + : tabs[0].value;Or use exact segment matching:
const activeTab = split.at(-1) === "items" ? tabs[1].value : tabs[0].value;🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/features/api-key-connectors/components/connectors-layout.tsx` around lines 43 - 45, The active tab detection using pathname.includes(tabs[1].value) in the activeTab assignment is fragile and can produce false positives; update the logic in the activeTab computation to split the pathname into segments (e.g., by "/"), ignore empty segments, and compare the last segment exactly to tabs[1].value (handling trailing slashes) so you only set activeTab to tabs[1].value when the final path segment equals "items", otherwise default to tabs[0].value; modify the activeTab expression accordingly (referencing activeTab, pathname, and tabs).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/app/`(dashboard)/(rest)/connectors/[resourceTypeUrl]/items/page.tsx:
- Around line 51-58: Add an authentication guard to the top of the Page
component by calling requireAuth() before any route logic: import requireAuth
from "@/lib/auth" and invoke requireAuth() as the first statement inside the
Page function (before accessing params or calling
isValidResourceTypeKey/resourceTypeUrl); this ensures unauthenticated users are
redirected to /login and preserves existing validation with
isValidResourceTypeKey and notFound().
- Around line 63-64: The call to config.prefetch should be awaited so prefetch
completes before render: change the usage in page.tsx to await config.prefetch({
...paginationParams }) after obtaining paginationParams from
paginationParamsLoader, and update the surrounding function/type signature
(wherever config.prefetch is declared/typed) to reflect it returns a Promise
(i.e., mark the caller as async and update the prefetch type to return
Promise<void> or the appropriate Promise type) so TypeScript correctly enforces
the async behavior; reference paginationParamsLoader and config.prefetch to
locate the changes.
In `@src/app/`(dashboard)/(rest)/connectors/[resourceTypeUrl]/page.tsx:
- Around line 10-21: The Page component currently lacks authentication and a
Suspense boundary; call requireAuth() at the top of the Page (or in the
surrounding layout) to protect the dashboard route, and wrap the ConnectorsList
render in a React.Suspense with a fallback (e.g., ConnectorsLoading) because
ConnectorsList uses useSuspenseConnectorsByResourceType which will suspend;
update the Page function (the component named Page) to validate
resourceTypePlural as before, invoke requireAuth(), then return <Suspense
fallback={<ConnectorsLoading />}> around <ConnectorsList
resourceType={resourceType} /> so suspended queries are handled.
In `@src/features/api-key-connectors/components/connectors-layout.tsx`:
- Around line 1-11: This component uses the client-side hook usePathname from
next/navigation but is missing the "use client" directive; add a top-of-file
"use client" directive to connectors-layout.tsx (above the imports) so the file
is treated as a client component, then ensure components referenced here (e.g.,
ConnectorsHeader, Tabs/TabsTrigger/TabsList) are client-safe or updated
accordingly; verify that usePathname calls remain in the component scope after
adding the directive.
---
Outside diff comments:
In `@src/features/assets/components/assets.tsx`:
- Around line 228-250: AssetsListWithDrawer is calling setAsset(row.original)
but the table columns are typed as ColumnDef<AssetResponse>[] while the data
returned by getManyInternal includes issues (AssetWithIssues); fix by aligning
types: either change the columns/columnsWithActions type to
ColumnDef<AssetWithIssues>[] so row.original is correctly typed for AssetDrawer,
or update the AssetResponse type to include the issues field to match
getManyInternal, or create a separate columns definition (e.g.,
columnsWithIssues) typed as ColumnDef<AssetWithIssues>[] and use that in
AssetsListWithDrawer; ensure references to AssetsListWithDrawer,
columnsWithActions, columns, AssetResponse, AssetWithIssues and getManyInternal
are updated consistently.
---
Nitpick comments:
In `@src/features/api-key-connectors/components/connectors-layout.tsx`:
- Around line 43-45: The active tab detection using
pathname.includes(tabs[1].value) in the activeTab assignment is fragile and can
produce false positives; update the logic in the activeTab computation to split
the pathname into segments (e.g., by "/"), ignore empty segments, and compare
the last segment exactly to tabs[1].value (handling trailing slashes) so you
only set activeTab to tabs[1].value when the final path segment equals "items",
otherwise default to tabs[0].value; modify the activeTab expression accordingly
(referencing activeTab, pathname, and tabs).
In `@src/features/api-key-connectors/components/connectors.tsx`:
- Around line 111-121: DeviceArtifactConnectorsContainer currently passes a
hardcoded "Device Artifact" string to ConnectorsContainer; change it to pass the
ResourceType enum value and use a display-name mapping for UI text so enum
remains the single source for data-fetching. Update
DeviceArtifactConnectorsContainer to pass ResourceType.DeviceArtifact (or the
equivalent enum key), add or reuse a mapping (similar to
integrationsMapping.name) that maps ResourceType values to human-readable names,
and update ConnectorsHeader to read the display name from that mapping instead
of relying on the prop string; reference the symbols
DeviceArtifactConnectorsContainer, ConnectorsContainer, ConnectorsHeader,
ResourceType, and integrationsMapping when making these edits.
In `@src/features/assets/components/columns.tsx`:
- Around line 92-97: The TODO stub in the DropdownMenuItem onClick must be
replaced with a real delete flow: add a handleDeleteAsset function and wire it
to the onClick instead of console.log, call your existing delete mutation (e.g.,
deleteAssetMutation or deleteAsset) passing the asset id from the row props,
show a confirmation prompt before calling it, handle success by refreshing the
list or calling onDeleted/invalidating queries and show an error toast on
failure; ensure the handler is referenced where DropdownMenuItem currently uses
onClick and import/use the appropriate mutation hook
(deleteAssetMutation/deleteAsset) and any toast/confirm utilities.
In `@src/features/device-artifacts/components/columns.tsx`:
- Around line 19-24: The column has a semantic mismatch: it sets accessorKey:
"userId" but uses accessorFn: (row) => row.user.name and header: "Source Tool";
update the column definition to use a clear identifier (e.g., replace
accessorKey with id: "sourceTool" or id: "userName") and keep accessorFn as the
source of truth so sorting/filtering uses the correct column id; ensure the id
matches the displayed value and update any references that relied on "userId"
for state or tests to the new id.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 685b1893-5a8b-4ced-a4a5-11b1efef206b
📒 Files selected for processing (21)
src/app/(dashboard)/(rest)/connectors/[resourceTypeUrl]/items/page.tsxsrc/app/(dashboard)/(rest)/connectors/[resourceTypeUrl]/layout.tsxsrc/app/(dashboard)/(rest)/connectors/[resourceTypeUrl]/page.tsxsrc/app/(dashboard)/(rest)/connectors/assets/page.tsxsrc/app/(dashboard)/(rest)/connectors/deviceArtifacts/page.tsxsrc/app/(dashboard)/(rest)/connectors/remediations/page.tsxsrc/app/(dashboard)/(rest)/connectors/vulnerabilities/page.tsxsrc/app/(dashboard)/(rest)/settings/integrations/[resourceTypeUrl]/page.tsxsrc/features/api-key-connectors/components/connectors-layout.tsxsrc/features/api-key-connectors/components/connectors.tsxsrc/features/assets/components/assets.tsxsrc/features/assets/components/columns.tsxsrc/features/device-artifacts/components/columns.tsxsrc/features/device-artifacts/components/device-artifacts.tsxsrc/features/integrations/components/integrations-layout.tsxsrc/features/integrations/types.tssrc/features/remediations/components/columns.tsxsrc/features/remediations/components/remediations.tsxsrc/features/vulnerabilities/components/vulnerabilities.tsxsrc/lib/schemas.tstsconfig.json
💤 Files with no reviewable changes (4)
- src/app/(dashboard)/(rest)/connectors/assets/page.tsx
- src/app/(dashboard)/(rest)/connectors/deviceArtifacts/page.tsx
- src/app/(dashboard)/(rest)/connectors/remediations/page.tsx
- src/app/(dashboard)/(rest)/connectors/vulnerabilities/page.tsx
✅ Files skipped from review due to trivial changes (4)
- src/features/integrations/types.ts
- src/features/remediations/components/columns.tsx
- src/lib/schemas.ts
- tsconfig.json
| const Page = async ({ | ||
| params, | ||
| searchParams, | ||
| }: CombinedPageProps<"resourceTypeUrl">) => { | ||
| const { resourceTypeUrl } = await params; | ||
| if (!isValidResourceTypeKey(resourceTypeUrl)) { | ||
| return notFound(); | ||
| } |
There was a problem hiding this comment.
Missing requireAuth() for route protection.
Dashboard routes should verify authentication before processing. Add requireAuth() at the start of the page function.
As per coding guidelines: "Protect routes requiring authentication using requireAuth() utility and redirect to /login if unauthenticated".
Proposed fix
const Page = async ({
params,
searchParams,
}: CombinedPageProps<"resourceTypeUrl">) => {
+ await requireAuth();
const { resourceTypeUrl } = await params;Also add the import:
import { requireAuth } from "@/lib/auth";🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/app/`(dashboard)/(rest)/connectors/[resourceTypeUrl]/items/page.tsx
around lines 51 - 58, Add an authentication guard to the top of the Page
component by calling requireAuth() before any route logic: import requireAuth
from "@/lib/auth" and invoke requireAuth() as the first statement inside the
Page function (before accessing params or calling
isValidResourceTypeKey/resourceTypeUrl); this ensures unauthenticated users are
redirected to /login and preserves existing validation with
isValidResourceTypeKey and notFound().
| const paginationParams = await paginationParamsLoader(searchParams); | ||
| config.prefetch({ ...paginationParams }); |
There was a problem hiding this comment.
Prefetch call should be awaited.
The prefetch function returns a Promise that should be awaited to ensure data is prefetched before rendering. Without await, the prefetch may not complete before the component renders, defeating its purpose.
Proposed fix
const paginationParams = await paginationParamsLoader(searchParams);
- config.prefetch({ ...paginationParams });
+ await config.prefetch({ ...paginationParams });Also update the type definition to reflect the async nature:
interface ConnectorResourceTypeConfig {
listElement: React.FC;
- prefetch: (params: PaginationInput) => void;
+ prefetch: (params: PaginationInput) => Promise<void>;
}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/app/`(dashboard)/(rest)/connectors/[resourceTypeUrl]/items/page.tsx
around lines 63 - 64, The call to config.prefetch should be awaited so prefetch
completes before render: change the usage in page.tsx to await config.prefetch({
...paginationParams }) after obtaining paginationParams from
paginationParamsLoader, and update the surrounding function/type signature
(wherever config.prefetch is declared/typed) to reflect it returns a Promise
(i.e., mark the caller as async and update the prefetch type to return
Promise<void> or the appropriate Promise type) so TypeScript correctly enforces
the async behavior; reference paginationParamsLoader and config.prefetch to
locate the changes.
| const Page = () => { | ||
| const pathname = usePathname(); | ||
| const resourceTypePlural = pathname.split("/").pop(); | ||
|
|
||
| if (!resourceTypePlural || !isValidResourceTypeKey(resourceTypePlural)) { | ||
| return notFound(); | ||
| } | ||
|
|
||
| const resourceType = integrationsMapping[resourceTypePlural].type; | ||
|
|
||
| return <ConnectorsList resourceType={resourceType} />; | ||
| }; |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Check if the layout.tsx for this route provides auth/Suspense wrappers
fd -t f "layout.tsx" src/app/ --exec cat {} \; | rg -A 10 -B 2 "requireAuth|Suspense|ErrorBoundary"Repository: PATCH-UPGRADE/viper
Length of output: 45
🏁 Script executed:
# First, verify the actual page.tsx file content
cat -n src/app/\(dashboard\)/\(rest\)/connectors/\[resourceTypeUrl\]/page.tsxRepository: PATCH-UPGRADE/viper
Length of output: 848
🏁 Script executed:
# Check the parent layout files
echo "=== (rest) layout ===" && cat -n src/app/\(dashboard\)/\(rest\)/layout.tsx && echo "" && echo "=== connectors layout ===" && cat -n src/app/\(dashboard\)/\(rest\)/connectors/layout.tsx && echo "" && echo "=== (dashboard) layout ===" && cat -n src/app/\(dashboard\)/layout.tsxRepository: PATCH-UPGRADE/viper
Length of output: 542
🏁 Script executed:
# Compare with items/page.tsx mentioned in the review
cat -n src/app/\(dashboard\)/\(rest\)/items/page.tsxRepository: PATCH-UPGRADE/viper
Length of output: 138
🏁 Script executed:
# Check the ConnectorsList component implementation
fd -t f "ConnectorsList" src/ --exec cat -n {} \;Repository: PATCH-UPGRADE/viper
Length of output: 45
🏁 Script executed:
fd -t f -i "connectors" src/features --type f | head -20Repository: PATCH-UPGRADE/viper
Length of output: 241
🏁 Script executed:
# Search for ConnectorsList component definition
rg -t tsx "export.*ConnectorsList|function ConnectorsList|const ConnectorsList" src/Repository: PATCH-UPGRADE/viper
Length of output: 90
🏁 Script executed:
# Check the (dashboard) layout for authentication
cat -n src/app/\(dashboard\)/layout.tsxRepository: PATCH-UPGRADE/viper
Length of output: 528
🏁 Script executed:
# Look for useSuspenseConnectorsByResourceType to verify if it's actually used
rg -t tsx "useSuspenseConnectorsByResourceType" src/Repository: PATCH-UPGRADE/viper
Length of output: 90
🏁 Script executed:
# Read the ConnectorsList component
cat -n src/features/api-key-connectors/components/connectors.tsxRepository: PATCH-UPGRADE/viper
Length of output: 4692
🏁 Script executed:
# Check the hooks file
cat -n src/features/api-key-connectors/hooks/use-connectors.tsRepository: PATCH-UPGRADE/viper
Length of output: 1122
🏁 Script executed:
# Search for suspense hook usage with correct rg syntax
rg "useSuspenseConnectorsByResourceType|useSuspense" src/Repository: PATCH-UPGRADE/viper
Length of output: 10732
🏁 Script executed:
# Check if there's a (dashboard) layout that provides authentication
fd -t f "layout.tsx" src/app/\(dashboard\)/ --exec cat -n {} \;Repository: PATCH-UPGRADE/viper
Length of output: 1760
🏁 Script executed:
# Look for requireAuth anywhere in the codebase
rg "requireAuth" src/Repository: PATCH-UPGRADE/viper
Length of output: 2176
🏁 Script executed:
cat -n src/features/api-key-connectors/components/connectors-layout.tsxRepository: PATCH-UPGRADE/viper
Length of output: 2597
Add authentication protection and Suspense boundary for client-side data fetching.
This page is missing requireAuth() for authentication protection (required for dashboard routes) and lacks a Suspense boundary. The ConnectorsList component uses useSuspenseConnectorsByResourceType, a suspense query that will throw a promise when suspended, requiring a parent Suspense boundary to catch it. Without this, the component may fail to render properly.
Add requireAuth() at the top of this page or at the layout level, and wrap the ConnectorsList with a Suspense boundary in the layout or page:
<details>
<summary>Example: Adding Suspense wrapper</summary>
const Page = () => {
// ...validation logic...
return (
<Suspense fallback={<ConnectorsLoading />}>
<ConnectorsList resourceType={resourceType} />
</Suspense>
);
};🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/app/`(dashboard)/(rest)/connectors/[resourceTypeUrl]/page.tsx around
lines 10 - 21, The Page component currently lacks authentication and a Suspense
boundary; call requireAuth() at the top of the Page (or in the surrounding
layout) to protect the dashboard route, and wrap the ConnectorsList render in a
React.Suspense with a fallback (e.g., ConnectorsLoading) because ConnectorsList
uses useSuspenseConnectorsByResourceType which will suspend; update the Page
function (the component named Page) to validate resourceTypePlural as before,
invoke requireAuth(), then return <Suspense fallback={<ConnectorsLoading />}>
around <ConnectorsList resourceType={resourceType} /> so suspended queries are
handled.
| import { ActivityIcon, PlugIcon } from "lucide-react"; | ||
| import Link from "next/link"; | ||
| import { notFound, usePathname } from "next/navigation"; | ||
| import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs"; | ||
| import { mainPadding } from "@/config/constants"; | ||
| import { | ||
| integrationsMapping, | ||
| isValidResourceTypeKey, | ||
| } from "@/features/integrations/types"; | ||
| import { cn } from "@/lib/utils"; | ||
| import { ConnectorsHeader } from "./connectors"; |
There was a problem hiding this comment.
Missing "use client" directive.
This component uses usePathname() from next/navigation, which is a client-side hook. The file should be marked with the "use client" directive.
As per coding guidelines: "Mark server-side files with 'server-only' directive and client components with 'use client' directive".
Proposed fix
+"use client";
+
import { ActivityIcon, PlugIcon } from "lucide-react";
import Link from "next/link";📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| import { ActivityIcon, PlugIcon } from "lucide-react"; | |
| import Link from "next/link"; | |
| import { notFound, usePathname } from "next/navigation"; | |
| import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs"; | |
| import { mainPadding } from "@/config/constants"; | |
| import { | |
| integrationsMapping, | |
| isValidResourceTypeKey, | |
| } from "@/features/integrations/types"; | |
| import { cn } from "@/lib/utils"; | |
| import { ConnectorsHeader } from "./connectors"; | |
| "use client"; | |
| import { ActivityIcon, PlugIcon } from "lucide-react"; | |
| import Link from "next/link"; | |
| import { notFound, usePathname } from "next/navigation"; | |
| import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs"; | |
| import { mainPadding } from "@/config/constants"; | |
| import { | |
| integrationsMapping, | |
| isValidResourceTypeKey, | |
| } from "@/features/integrations/types"; | |
| import { cn } from "@/lib/utils"; | |
| import { ConnectorsHeader } from "./connectors"; |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/features/api-key-connectors/components/connectors-layout.tsx` around
lines 1 - 11, This component uses the client-side hook usePathname from
next/navigation but is missing the "use client" directive; add a top-of-file
"use client" directive to connectors-layout.tsx (above the imports) so the file
is treated as a client component, then ensure components referenced here (e.g.,
ConnectorsHeader, Tabs/TabsTrigger/TabsList) are client-safe or updated
accordingly; verify that usePathname calls remain in the component scope after
adding the directive.
New table views for each of the 4 connector types (asset, device artifact, remediation, vulnerability)
Summary by CodeRabbit
New Features
Removed
Bug Fixes
Chores