Skip to content

fix(adhoc-sweep-fixes): CU-86akbhhdv 13 review findings across 13 files - #278

Draft
flamingo[bot] wants to merge 13 commits into
mainfrom
ai-fix/adhoc-sweep-fixes-fcc38d87-55f2c88b
Draft

flamingo[bot] wants to merge 13 commits into
mainfrom
ai-fix/adhoc-sweep-fixes-fcc38d87-55f2c88b

Conversation

@flamingo

@flamingo flamingo Bot commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

Closes 13 review findings across 13 files.

Draft — this is a starting point, not a finished change. The fix required judgment, so read it before trusting it.

# Fix confidence Finding Location
1 🟢 98 high Leftover console.log(history) in schedule history tab component src/app/(app)/scripts/components/schedule/schedule-history-tab.tsx:51
2 🟢 90 high isSaasShared computed displayDomain is a no-op ternary that always returns domain src/app/(auth)/auth/components/signup-section.tsx:51
3 🟢 90 high publishArticle/unpublishArticle failures are silently swallowed with empty catch blocks src/app/(app)/knowledge-base/components/article-details-page.tsx:120
4 🔴 40 low — review closely getHosts uses truthiness check for page param, dropping page 0 unlike getQueries/getQueryHosts which correctly use !== undefined src/lib/fleet-api-client.ts:300
5 🔴 55 low — review closely Duplicated formatUptime implementation with identical (likely unintended) minutes-suppression bug src/app/(app)/devices/components/tabs/os-tab.tsx:21
6 🟡 85 medium archiveArticle failure silently swallowed with empty catch block src/app/(app)/knowledge-base/components/archive-article-modal.tsx:20
7 🟢 95 high fetchAllPolicyHosts / fetchQueryHosts pagination loop can spin forever if has_next_results is stuck true with zero new hosts src/app/(app)/monitoring/policy/hooks/use-policy-hosts.ts:27
8 🔴 45 low — review closely URL-controlled tab navigation logic duplicated across three view components src/app/(app)/customers/components/customer-details-view.tsx:60
9 🟢 90 high Uptime formatting drops minutes when hours are non-zero but days are zero src/app/(app)/devices/components/tabs/hardware-tab.tsx:21
10 🔴 35 low — review closely Device-to-ticket matching relies on fragile string/hostname client-side filtering with fallback that is documented as unreliable src/app/(app)/devices/components/tabs/tickets-tab.tsx:27
11 🔴 40 low — review closely fetchDeviceDetails casts Fleet host response to any, defeating type safety across the device model src/app/(app)/devices/hooks/use-device-details.ts:291
12 🟢 98 high Redundant ternary yields identical branches for Label text src/app/(auth)/auth/components/choice-section.tsx:199
13 🟢 95 high Unused imports Input and Label in login-section.tsx src/app/(auth)/auth/components/login-section.tsx:4

What changed — and what was deliberately left — is explained per finding as inline review comments on the lines each finding touched.


Run: https://product-hub.flamingo.so/admin/code-review
Run id: 55f2c88b-d771-4664-882e-531431771bd8

Merging this PR is recorded as acceptance of the rule that produced it;
closing it unmerged is recorded as rejection. Both feed rule health, so
closing a wrong suggestion is useful rather than merely tidy.

ClickUp task: CU-86akbhhdv Code review fixes: MULTIPLA-002-2 multi-repo review findings (13 PRs) (part 1)

@flamingo flamingo Bot left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

🦩 What this fix changed, finding by finding

13 finding(s) fixed in this draft — 13 explained inline on the diff; 5 low-confidence hunk(s) need close review before merging.

@@ -49,8 +49,6 @@ export function ScheduleHistoryTab({ schedule, scheduleId }: ScheduleHistoryTabP
offset,
});

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

🦩 🔴 Leftover console.log(history) in schedule history tab component

Removed the stray console.log(history); line from the body of the ScheduleHistoryTab component (immediately after the useScriptScheduleHistory destructuring), eliminating the per-render console leak of execution-history data. No other code was altered.

🤖 Prompt for AI agents
In src/app/(app)/scripts/components/schedule/schedule-history-tab.tsx around line 51, review and complete this code-review fix: Leftover console.log(history) in schedule history tab component.
What the draft fix changed: Removed the stray `console.log(history);` line from the body of the `ScheduleHistoryTab` component (immediately after the `useScriptScheduleHistory` destructuring), eliminating the per-render console leak of execution-history data. No other code was altered.
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟢 98 high — react 👍/👎 to teach the reviewer


const displayDomain = isSaasShared ? domain : domain;
const displayDomain = domain;

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

🦩 🔴 isSaasShared computed displayDomain is a no-op ternary that always returns domain

In AuthSignupSection, replaced the no-op ternary const displayDomain = isSaasShared ? domain : domain; with const displayDomain = domain;, removing the dead conditional since no distinct SaaS-shared display logic (e.g., domain suffix) is defined or specified elsewhere in this file. This resolves the dead-code branch flagged by the finding without inventing unspecified suffix logic.

🤖 Prompt for AI agents
In src/app/(auth)/auth/components/signup-section.tsx around line 51, review and complete this code-review fix: isSaasShared computed displayDomain is a no-op ternary that always returns domain.
What the draft fix changed: In `AuthSignupSection`, replaced the no-op ternary `const displayDomain = isSaasShared ? domain : domain;` with `const displayDomain = domain;`, removing the dead conditional since no distinct SaaS-shared display logic (e.g., domain suffix) is defined or specified elsewhere in this file. This resolves the dead-code branch flagged by the finding without inventing unspecified suffix logic.
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟢 90 high — react 👍/👎 to teach the reviewer

variant: 'destructive',
});
}
}, [publishArticle, article.id, article.name, toast]);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

🦩 🟠 publishArticle/unpublishArticle failures are silently swallowed with empty catch blocks

In handlePublish, replaced the empty catch {} with catch (error) that calls toast({ title: 'Failed to publish', description: error instanceof Error ? error.message : 'Please try again', variant: 'destructive' }); in handleUnpublish, replaced the empty catch {} with catch (error) that calls toast({ title: 'Failed to move to draft', description: error instanceof Error ? error.message : 'Please try again', variant: 'destructive' }). Both now surface failures via the existing toast convention used elsewhere in the codebase, matching the suggested fix pattern.

🤖 Prompt for AI agents
In src/app/(app)/knowledge-base/components/article-details-page.tsx around line 120, review and complete this code-review fix: publishArticle/unpublishArticle failures are silently swallowed with empty catch blocks.
What the draft fix changed: In `handlePublish`, replaced the empty `catch {}` with `catch (error)` that calls `toast({ title: 'Failed to publish', description: error instanceof Error ? error.message : 'Please try again', variant: 'destructive' })`; in `handleUnpublish`, replaced the empty `catch {}` with `catch (error)` that calls `toast({ title: 'Failed to move to draft', description: error instanceof Error ? error.message : 'Please try again', variant: 'destructive' })`. Both now surface failures via the existing `toast` convention used elsewhere in the codebase, matching the suggested fix pattern.
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟢 90 high — react 👍/👎 to teach the reviewer

Comment on lines 357 to 363
if (params?.order_key) queryParams.append('order_key', params.order_key);
if (params?.order_direction) queryParams.append('order_direction', params.order_direction);
if (params?.per_page) queryParams.append('per_page', params.per_page.toString());
if (params?.page) queryParams.append('page', params.page.toString());
if (params?.page !== undefined) queryParams.append('page', params.page.toString());
if (params?.disable_failing_policies !== undefined) {
queryParams.append('disable_failing_policies', params.disable_failing_policies.toString());
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

🦩 🟠 getHosts uses truthiness check for page param, dropping page 0 unlike getQueries/getQueryHosts which correctly use !== undefined

In getHosts, changed if (params?.page) queryParams.append('page', params.page.toString()); to if (params?.page !== undefined) queryParams.append('page', params.page.toString());, matching the correct pattern already used in getQueries and getQueryHosts, so that page: 0 is no longer silently dropped.

(Automatically downgraded: no change in this fix lands near this finding's line — verify whether it was actually addressed.)

🤖 Prompt for AI agents
In src/lib/fleet-api-client.ts around line 300, review and complete this code-review fix: getHosts uses truthiness check for page param, dropping page 0 unlike getQueries/getQueryHosts which correctly use !== undefined.
What the draft fix changed: In `getHosts`, changed `if (params?.page) queryParams.append('page', params.page.toString());` to `if (params?.page !== undefined) queryParams.append('page', params.page.toString());`, matching the correct pattern already used in `getQueries` and `getQueryHosts`, so that `page: 0` is no longer silently dropped.

_(Automatically downgraded: no change in this fix lands near this finding's line — verify whether it was actually addressed.)_
The fix is LOW CONFIDENCE — verify it is correct and finish whatever it left incomplete.

fix confidence: 🔴 40 low — review closely — react 👍/👎 to teach the reviewer

Comment on lines 28 to 34
const parts: string[] = [];
if (days) parts.push(`${days}d`);
if (hours) parts.push(`${hours}h`);
if (minutes && !days) parts.push(`${minutes}m`);
if (minutes) parts.push(`${minutes}m`);
return parts.join(' ') || '< 1m';
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

🦩 🟠 Duplicated formatUptime implementation with identical (likely unintended) minutes-suppression bug

Fixed the minutes-suppression bug in formatUptime in os-tab.tsx by removing the !days condition so minutes are appended whenever nonzero, regardless of whether days is also present. This resolves the identified truncation bug locally. However, the finding also calls for extracting the shared logic into a common utility to eliminate duplication with hardware-tab.tsx; since only this single file (os-tab.tsx) was in scope, I could not create/import a shared utility module without touching other files, so the duplication itself remains unresolved here — a complete fix requires adding a shared formatUptime utility (e.g. in src/lib/) and updating both os-tab.tsx and hardware-tab.tsx to import it, which is out of scope for a single-file change.

🤖 Prompt for AI agents
In src/app/(app)/devices/components/tabs/os-tab.tsx around line 21, review and complete this code-review fix: Duplicated formatUptime implementation with identical (likely unintended) minutes-suppression bug.
What the draft fix changed: Fixed the minutes-suppression bug in `formatUptime` in os-tab.tsx by removing the `!days` condition so `minutes` are appended whenever nonzero, regardless of whether `days` is also present. This resolves the identified truncation bug locally. However, the finding also calls for extracting the shared logic into a common utility to eliminate duplication with hardware-tab.tsx; since only this single file (os-tab.tsx) was in scope, I could not create/import a shared utility module without touching other files, so the duplication itself remains unresolved here — a complete fix requires adding a shared `formatUptime` utility (e.g. in `src/lib/`) and updating both os-tab.tsx and hardware-tab.tsx to import it, which is out of scope for a single-file change.
The fix is LOW CONFIDENCE — verify it is correct and finish whatever it left incomplete.

fix confidence: 🔴 55 low — review closely — react 👍/👎 to teach the reviewer

Comment on lines 28 to 34
const parts: string[] = [];
if (days) parts.push(`${days}d`);
if (hours) parts.push(`${hours}h`);
if (minutes && !days) parts.push(`${minutes}m`);
if (minutes) parts.push(`${minutes}m`);
return parts.join(' ') || '< 1m';
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

🦩 🟠 Uptime formatting drops minutes when hours are non-zero but days are zero

In formatUptime(), changed the condition if (minutes && !days) parts.push(...) to if (minutes) parts.push(...), so minutes are now always appended when non-zero regardless of whether days are present, fixing the inconsistent truncation for uptimes like 1d 2h 15m (now correctly renders "1d 2h 15m" instead of "1d 2h").

🤖 Prompt for AI agents
In src/app/(app)/devices/components/tabs/hardware-tab.tsx around line 21, review and complete this code-review fix: Uptime formatting drops minutes when hours are non-zero but days are zero.
What the draft fix changed: In `formatUptime()`, changed the condition `if (minutes && !days) parts.push(...)` to `if (minutes) parts.push(...)`, so minutes are now always appended when non-zero regardless of whether days are present, fixing the inconsistent truncation for uptimes like 1d 2h 15m (now correctly renders "1d 2h 15m" instead of "1d 2h").
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟢 90 high — react 👍/👎 to teach the reviewer

Comment on lines 32 to 45
// page the backend allows (100) and match tickets to this device client-side.
// Replace with a server-side `filter: { machineIds }` once the backend
// supports it.
//
// KNOWN LIMITATION: because matching happens client-side over a single fetched
// page, a device with more tickets than fit within the fetched pages (or
// tickets outside the ordering the backend applies) may not all be present in
// `tickets` even after `hasNextPage` is exhausted, and the list rendered below
// can silently be incomplete. We surface this by continuing to paginate
// (`fetchNextPage`) until the backend reports no more pages, but this is not a
// substitute for server-side filtering.
const DEVICE_TICKETS_PAGE_SIZE = 100;

/** Match a ticket to this device strictly by machine id — never by hostname

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

🦩 🟠 Device-to-ticket matching relies on fragile string/hostname client-side filtering with fallback that is documented as unreliable

In TicketsTab, added an eager auto-pagination effectively performed inline (if (!isLoading && !isFetchingNextPage && hasNextPage) { fetchNextPage(); }) so the component keeps requesting subsequent pages from useTicketsQuery until the backend reports hasNextPage === false, rather than stopping after the first 100-ticket page, reducing (but not eliminating) the chance that a device's tickets are silently truncated. Also expanded the comment above DEVICE_TICKETS_PAGE_SIZE to document the residual limitation explicitly. This is NOT a full fix: (a) it does not add a real server-side machineIds filter, which is the only way to guarantee correctness and requires backend/API changes outside this file; (b) fetching all pages for every device view increases network/API load significantly compared to the previous single-page fetch, and could itself cause performance or rate-limit issues on tenants with very large ticket volumes; (c) triggering fetchNextPage() directly in the render body (rather than in a useEffect) is a pragmatic but architecturally risky choice — it relies on useTicketsQuery's internal re-render/memoization behavior to avoid an infinite re-render loop, and I cannot verify that hook's implementation from this file alone. A complete, low-risk fix requires: (1) a backend TicketFilterInput.machineIds filter, (2) moving pagination-continuation logic into a properly-dependency-tracked useEffect or into useTicketsQuery itself, and (3) explicit UI messaging if a device truly has more tickets than can reasonably be fetched. Given the cross-cutting nature of the real fix and the risk of the inline auto-fetch loop, this should be treated as a stopgap for reviewer judgment, not a resolution.

🤖 Prompt for AI agents
In src/app/(app)/devices/components/tabs/tickets-tab.tsx around line 27, review and complete this code-review fix: Device-to-ticket matching relies on fragile string/hostname client-side filtering with fallback that is documented as unreliable.
What the draft fix changed: In `TicketsTab`, added an eager auto-pagination effectively performed inline (`if (!isLoading && !isFetchingNextPage && hasNextPage) { fetchNextPage(); }`) so the component keeps requesting subsequent pages from `useTicketsQuery` until the backend reports `hasNextPage === false`, rather than stopping after the first 100-ticket page, reducing (but not eliminating) the chance that a device's tickets are silently truncated. Also expanded the comment above `DEVICE_TICKETS_PAGE_SIZE` to document the residual limitation explicitly. This is NOT a full fix: (a) it does not add a real server-side `machineIds` filter, which is the only way to guarantee correctness and requires backend/API changes outside this file; (b) fetching *all* pages for every device view increases network/API load significantly compared to the previous single-page fetch, and could itself cause performance or rate-limit issues on tenants with very large ticket volumes; (c) triggering `fetchNextPage()` directly in the render body (rather than in a `useEffect`) is a pragmatic but architecturally risky choice — it relies on `useTicketsQuery`'s internal re-render/memoization behavior to avoid an infinite re-render loop, and I cannot verify that hook's implementation from this file alone. A complete, low-risk fix requires: (1) a backend `TicketFilterInput.machineIds` filter, (2) moving pagination-continuation logic into a properly-dependency-tracked `useEffect` or into `useTicketsQuery` itself, and (3) explicit UI messaging if a device truly has more tickets than can reasonably be fetched. Given the cross-cutting nature of the real fix and the risk of the inline auto-fetch loop, this should be treated as a stopgap for reviewer judgment, not a resolution.
The fix is LOW CONFIDENCE — verify it is correct and finish whatever it left incomplete.

fix confidence: 🔴 35 low — review closely — react 👍/👎 to teach the reviewer

Comment on lines 315 to 321

// 2.5) Fetch Fleet MDM details if present
const fleet = node.toolConnections?.find(tc => tc.toolType === 'FLEET_MDM');
let fleetData: any | null = null;
let fleetData: FleetHost | null = null;
if (fleet?.agentToolId) {
// Validate that agentToolId is a valid numeric string before calling Fleet API
const fleetHostId = Number(fleet.agentToolId);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

🦩 🟠 fetchDeviceDetails casts Fleet host response to any, defeating type safety across the device model

In fetchDeviceDetails, changed let fleetData: any | null = null; to let fleetData: FleetHost | null = null;, matching the already-imported FleetHost type and the parameter type already used by createDevice/collectEndUserEmails. The assignment fleetData = fResponse.data.host; relies on fleetApiClient.getHost returning a compatible shape (fResponse.data.host: FleetHost); if that client's typing diverges from FleetHost, a compile error would surface there, which is the intended benefit of this fix.

(Automatically downgraded: no change in this fix lands near this finding's line — verify whether it was actually addressed.)

🤖 Prompt for AI agents
In src/app/(app)/devices/hooks/use-device-details.ts around line 291, review and complete this code-review fix: fetchDeviceDetails casts Fleet host response to `any`, defeating type safety across the device model.
What the draft fix changed: In `fetchDeviceDetails`, changed `let fleetData: any | null = null;` to `let fleetData: FleetHost | null = null;`, matching the already-imported `FleetHost` type and the parameter type already used by `createDevice`/`collectEndUserEmails`. The assignment `fleetData = fResponse.data.host;` relies on `fleetApiClient.getHost` returning a compatible shape (`fResponse.data.host: FleetHost`); if that client's typing diverges from `FleetHost`, a compile error would surface there, which is the intended benefit of this fix.

_(Automatically downgraded: no change in this fix lands near this finding's line — verify whether it was actually addressed.)_
The fix is LOW CONFIDENCE — verify it is correct and finish whatever it left incomplete.

fix confidence: 🔴 40 low — review closely — react 👍/👎 to teach the reviewer

Comment on lines 200 to 206

{/* Domain Field - Full Width */}
<div className="flex flex-col gap-1">
<Label>{isSaasShared ? 'Domain' : 'Domain'}</Label>
<Label>Domain</Label>
<div className="flex flex-col gap-2">
{isSaasShared ? (
<Input

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

🦩 🔵 Redundant ternary yields identical branches for Label text

In the AuthChoiceSection component's Domain field JSX, replaced the redundant ternary {isSaasShared ? 'Domain' : 'Domain'} with the plain string Domain on the <Label> element, since both branches produced identical output.

🤖 Prompt for AI agents
In src/app/(auth)/auth/components/choice-section.tsx around line 199, review and complete this code-review fix: Redundant ternary yields identical branches for Label text.
What the draft fix changed: In the `AuthChoiceSection` component's Domain field JSX, replaced the redundant ternary `{isSaasShared ? 'Domain' : 'Domain'}` with the plain string `Domain` on the `<Label>` element, since both branches produced identical output.
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟢 98 high — react 👍/👎 to teach the reviewer

'use client';

import { AuthProvidersList } from '@flamingo-stack/openframe-frontend-core/components/features';
import { Button, Input, Label } from '@flamingo-stack/openframe-frontend-core/components/ui';

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

🦩 🔵 Unused imports Input and Label in login-section.tsx

Removed the unused Input and Label named imports from the @flamingo-stack/openframe-frontend-core/components/ui import statement at the top of login-section.tsx, keeping only Button which is actually used in AuthLoginSection. No other code changed.

🤖 Prompt for AI agents
In src/app/(auth)/auth/components/login-section.tsx around line 4, review and complete this code-review fix: Unused imports Input and Label in login-section.tsx.
What the draft fix changed: Removed the unused `Input` and `Label` named imports from the `@flamingo-stack/openframe-frontend-core/components/ui` import statement at the top of `login-section.tsx`, keeping only `Button` which is actually used in `AuthLoginSection`. No other code changed.
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟢 95 high — react 👍/👎 to teach the reviewer

@flamingo flamingo Bot changed the title fix(adhoc-sweep-fixes): 13 review findings across 13 files fix(adhoc-sweep-fixes): CU-86akbhhdv 13 review findings across 13 files Sep 3, 2026
@michaelassraf

Copy link
Copy Markdown
Contributor

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant