From dd747f74740643dfd7d17ac1dabbb53c737c66f4 Mon Sep 17 00:00:00 2001 From: Alan Buscaglia Date: Tue, 25 Nov 2025 14:22:03 +0100 Subject: [PATCH] feat(ui): hide new overview route and filter mongo providers (#9314) --- ui/actions/scans/scans.ts | 45 +++++- .../components/accounts-selector.tsx | 0 .../check-findings/check-findings.ssr.tsx | 0 .../components/check-findings/index.ts | 0 .../finding-severity-over-time-detail.ssr.tsx | 0 .../finding-severity-over-time.ssr.tsx | 0 .../finding-severity-over-time.tsx | 0 .../finding-severity-over-time/index.ts | 0 .../time-range-selector.tsx | 0 .../graphs-tabs/graphs-tabs-client.tsx | 0 .../graphs-tabs/graphs-tabs-config.ts | 0 .../graphs-tabs/graphs-tabs-wrapper.tsx | 0 .../risk-pipeline-view.ssr.tsx | 0 .../risk-plot/risk-plot-client.tsx | 0 .../graphs-tabs/risk-plot/risk-plot-view.tsx | 0 .../risk-radar-view-client.tsx | 0 .../risk-radar-view/risk-radar-view.ssr.tsx | 0 .../threat-map-view/threat-map-view.ssr.tsx | 0 .../components/provider-type-selector.tsx | 0 .../components/risk-severity-chart/index.ts | 0 .../risk-severity-chart-detail.ssr.tsx | 0 .../risk-severity-chart.ssr.tsx | 0 .../risk-severity-chart.tsx | 0 .../components/status-chart/index.ts | 0 .../components/status-chart/status-chart.tsx | 0 .../components/threat-score/index.ts | 0 .../threat-score/threat-score.ssr.tsx | 0 .../components/threat-score/threat-score.tsx | 0 .../lib/filter-params.ts | 0 .../{new-overview => _new-overview}/page.tsx | 0 ui/app/(prowler)/findings/page.tsx | 4 +- ui/app/(prowler)/page.tsx | 12 +- ui/ui/.husky/pre-commit | 151 ------------------ 33 files changed, 52 insertions(+), 160 deletions(-) rename ui/app/(prowler)/{new-overview => _new-overview}/components/accounts-selector.tsx (100%) rename ui/app/(prowler)/{new-overview => _new-overview}/components/check-findings/check-findings.ssr.tsx (100%) rename ui/app/(prowler)/{new-overview => _new-overview}/components/check-findings/index.ts (100%) rename ui/app/(prowler)/{new-overview => _new-overview}/components/finding-severity-over-time/finding-severity-over-time-detail.ssr.tsx (100%) rename ui/app/(prowler)/{new-overview => _new-overview}/components/finding-severity-over-time/finding-severity-over-time.ssr.tsx (100%) rename ui/app/(prowler)/{new-overview => _new-overview}/components/finding-severity-over-time/finding-severity-over-time.tsx (100%) rename ui/app/(prowler)/{new-overview => _new-overview}/components/finding-severity-over-time/index.ts (100%) rename ui/app/(prowler)/{new-overview => _new-overview}/components/finding-severity-over-time/time-range-selector.tsx (100%) rename ui/app/(prowler)/{new-overview => _new-overview}/components/graphs-tabs/graphs-tabs-client.tsx (100%) rename ui/app/(prowler)/{new-overview => _new-overview}/components/graphs-tabs/graphs-tabs-config.ts (100%) rename ui/app/(prowler)/{new-overview => _new-overview}/components/graphs-tabs/graphs-tabs-wrapper.tsx (100%) rename ui/app/(prowler)/{new-overview => _new-overview}/components/graphs-tabs/risk-pipeline-view/risk-pipeline-view.ssr.tsx (100%) rename ui/app/(prowler)/{new-overview => _new-overview}/components/graphs-tabs/risk-plot/risk-plot-client.tsx (100%) rename ui/app/(prowler)/{new-overview => _new-overview}/components/graphs-tabs/risk-plot/risk-plot-view.tsx (100%) rename ui/app/(prowler)/{new-overview => _new-overview}/components/graphs-tabs/risk-radar-view/risk-radar-view-client.tsx (100%) rename ui/app/(prowler)/{new-overview => _new-overview}/components/graphs-tabs/risk-radar-view/risk-radar-view.ssr.tsx (100%) rename ui/app/(prowler)/{new-overview => _new-overview}/components/graphs-tabs/threat-map-view/threat-map-view.ssr.tsx (100%) rename ui/app/(prowler)/{new-overview => _new-overview}/components/provider-type-selector.tsx (100%) rename ui/app/(prowler)/{new-overview => _new-overview}/components/risk-severity-chart/index.ts (100%) rename ui/app/(prowler)/{new-overview => _new-overview}/components/risk-severity-chart/risk-severity-chart-detail.ssr.tsx (100%) rename ui/app/(prowler)/{new-overview => _new-overview}/components/risk-severity-chart/risk-severity-chart.ssr.tsx (100%) rename ui/app/(prowler)/{new-overview => _new-overview}/components/risk-severity-chart/risk-severity-chart.tsx (100%) rename ui/app/(prowler)/{new-overview => _new-overview}/components/status-chart/index.ts (100%) rename ui/app/(prowler)/{new-overview => _new-overview}/components/status-chart/status-chart.tsx (100%) rename ui/app/(prowler)/{new-overview => _new-overview}/components/threat-score/index.ts (100%) rename ui/app/(prowler)/{new-overview => _new-overview}/components/threat-score/threat-score.ssr.tsx (100%) rename ui/app/(prowler)/{new-overview => _new-overview}/components/threat-score/threat-score.tsx (100%) rename ui/app/(prowler)/{new-overview => _new-overview}/lib/filter-params.ts (100%) rename ui/app/(prowler)/{new-overview => _new-overview}/page.tsx (100%) delete mode 100644 ui/ui/.husky/pre-commit diff --git a/ui/actions/scans/scans.ts b/ui/actions/scans/scans.ts index 5f2caaeee9..f050c8b76e 100644 --- a/ui/actions/scans/scans.ts +++ b/ui/actions/scans/scans.ts @@ -9,6 +9,46 @@ import { } from "@/lib/compliance/compliance-report-types"; import { addScanOperation } from "@/lib/sentry-breadcrumbs"; import { handleApiError, handleApiResponse } from "@/lib/server-actions-helper"; +import { ScansApiResponse } from "@/types"; + +const filterMongoScans = (result: ScansApiResponse | undefined) => { + if (!result?.data) return result; + + const included = result.included || []; + + // Get IDs of providers containing "mongo" + const mongoProviderIds = new Set( + included + .filter( + (item) => + item.type === "providers" && + item.attributes?.provider?.toLowerCase().includes("mongo"), + ) + .map((item) => item.id), + ); + + // If no mongo providers found, return as-is + if (mongoProviderIds.size === 0) return result; + + // Filter out scans associated with mongo providers + result.data = result.data.filter((scan) => { + const providerId = scan.relationships?.provider?.data?.id; + return !providerId || !mongoProviderIds.has(providerId); + }); + + // Filter out mongo-related included items + if (result.included) { + result.included = included.filter( + (item) => + !( + item.type === "providers" && + item.attributes?.provider?.toLowerCase().includes("mongo") + ), + ); + } + + return result; +}; export const getScans = async ({ page = 1, @@ -44,7 +84,10 @@ export const getScans = async ({ try { const response = await fetch(url.toString(), { headers }); - return handleApiResponse(response); + const result = await handleApiResponse(response); + + // Filter out mongo-related scans when provider is included + return filterMongoScans(result); } catch (error) { console.error("Error fetching scans:", error); return undefined; diff --git a/ui/app/(prowler)/new-overview/components/accounts-selector.tsx b/ui/app/(prowler)/_new-overview/components/accounts-selector.tsx similarity index 100% rename from ui/app/(prowler)/new-overview/components/accounts-selector.tsx rename to ui/app/(prowler)/_new-overview/components/accounts-selector.tsx diff --git a/ui/app/(prowler)/new-overview/components/check-findings/check-findings.ssr.tsx b/ui/app/(prowler)/_new-overview/components/check-findings/check-findings.ssr.tsx similarity index 100% rename from ui/app/(prowler)/new-overview/components/check-findings/check-findings.ssr.tsx rename to ui/app/(prowler)/_new-overview/components/check-findings/check-findings.ssr.tsx diff --git a/ui/app/(prowler)/new-overview/components/check-findings/index.ts b/ui/app/(prowler)/_new-overview/components/check-findings/index.ts similarity index 100% rename from ui/app/(prowler)/new-overview/components/check-findings/index.ts rename to ui/app/(prowler)/_new-overview/components/check-findings/index.ts diff --git a/ui/app/(prowler)/new-overview/components/finding-severity-over-time/finding-severity-over-time-detail.ssr.tsx b/ui/app/(prowler)/_new-overview/components/finding-severity-over-time/finding-severity-over-time-detail.ssr.tsx similarity index 100% rename from ui/app/(prowler)/new-overview/components/finding-severity-over-time/finding-severity-over-time-detail.ssr.tsx rename to ui/app/(prowler)/_new-overview/components/finding-severity-over-time/finding-severity-over-time-detail.ssr.tsx diff --git a/ui/app/(prowler)/new-overview/components/finding-severity-over-time/finding-severity-over-time.ssr.tsx b/ui/app/(prowler)/_new-overview/components/finding-severity-over-time/finding-severity-over-time.ssr.tsx similarity index 100% rename from ui/app/(prowler)/new-overview/components/finding-severity-over-time/finding-severity-over-time.ssr.tsx rename to ui/app/(prowler)/_new-overview/components/finding-severity-over-time/finding-severity-over-time.ssr.tsx diff --git a/ui/app/(prowler)/new-overview/components/finding-severity-over-time/finding-severity-over-time.tsx b/ui/app/(prowler)/_new-overview/components/finding-severity-over-time/finding-severity-over-time.tsx similarity index 100% rename from ui/app/(prowler)/new-overview/components/finding-severity-over-time/finding-severity-over-time.tsx rename to ui/app/(prowler)/_new-overview/components/finding-severity-over-time/finding-severity-over-time.tsx diff --git a/ui/app/(prowler)/new-overview/components/finding-severity-over-time/index.ts b/ui/app/(prowler)/_new-overview/components/finding-severity-over-time/index.ts similarity index 100% rename from ui/app/(prowler)/new-overview/components/finding-severity-over-time/index.ts rename to ui/app/(prowler)/_new-overview/components/finding-severity-over-time/index.ts diff --git a/ui/app/(prowler)/new-overview/components/finding-severity-over-time/time-range-selector.tsx b/ui/app/(prowler)/_new-overview/components/finding-severity-over-time/time-range-selector.tsx similarity index 100% rename from ui/app/(prowler)/new-overview/components/finding-severity-over-time/time-range-selector.tsx rename to ui/app/(prowler)/_new-overview/components/finding-severity-over-time/time-range-selector.tsx diff --git a/ui/app/(prowler)/new-overview/components/graphs-tabs/graphs-tabs-client.tsx b/ui/app/(prowler)/_new-overview/components/graphs-tabs/graphs-tabs-client.tsx similarity index 100% rename from ui/app/(prowler)/new-overview/components/graphs-tabs/graphs-tabs-client.tsx rename to ui/app/(prowler)/_new-overview/components/graphs-tabs/graphs-tabs-client.tsx diff --git a/ui/app/(prowler)/new-overview/components/graphs-tabs/graphs-tabs-config.ts b/ui/app/(prowler)/_new-overview/components/graphs-tabs/graphs-tabs-config.ts similarity index 100% rename from ui/app/(prowler)/new-overview/components/graphs-tabs/graphs-tabs-config.ts rename to ui/app/(prowler)/_new-overview/components/graphs-tabs/graphs-tabs-config.ts diff --git a/ui/app/(prowler)/new-overview/components/graphs-tabs/graphs-tabs-wrapper.tsx b/ui/app/(prowler)/_new-overview/components/graphs-tabs/graphs-tabs-wrapper.tsx similarity index 100% rename from ui/app/(prowler)/new-overview/components/graphs-tabs/graphs-tabs-wrapper.tsx rename to ui/app/(prowler)/_new-overview/components/graphs-tabs/graphs-tabs-wrapper.tsx diff --git a/ui/app/(prowler)/new-overview/components/graphs-tabs/risk-pipeline-view/risk-pipeline-view.ssr.tsx b/ui/app/(prowler)/_new-overview/components/graphs-tabs/risk-pipeline-view/risk-pipeline-view.ssr.tsx similarity index 100% rename from ui/app/(prowler)/new-overview/components/graphs-tabs/risk-pipeline-view/risk-pipeline-view.ssr.tsx rename to ui/app/(prowler)/_new-overview/components/graphs-tabs/risk-pipeline-view/risk-pipeline-view.ssr.tsx diff --git a/ui/app/(prowler)/new-overview/components/graphs-tabs/risk-plot/risk-plot-client.tsx b/ui/app/(prowler)/_new-overview/components/graphs-tabs/risk-plot/risk-plot-client.tsx similarity index 100% rename from ui/app/(prowler)/new-overview/components/graphs-tabs/risk-plot/risk-plot-client.tsx rename to ui/app/(prowler)/_new-overview/components/graphs-tabs/risk-plot/risk-plot-client.tsx diff --git a/ui/app/(prowler)/new-overview/components/graphs-tabs/risk-plot/risk-plot-view.tsx b/ui/app/(prowler)/_new-overview/components/graphs-tabs/risk-plot/risk-plot-view.tsx similarity index 100% rename from ui/app/(prowler)/new-overview/components/graphs-tabs/risk-plot/risk-plot-view.tsx rename to ui/app/(prowler)/_new-overview/components/graphs-tabs/risk-plot/risk-plot-view.tsx diff --git a/ui/app/(prowler)/new-overview/components/graphs-tabs/risk-radar-view/risk-radar-view-client.tsx b/ui/app/(prowler)/_new-overview/components/graphs-tabs/risk-radar-view/risk-radar-view-client.tsx similarity index 100% rename from ui/app/(prowler)/new-overview/components/graphs-tabs/risk-radar-view/risk-radar-view-client.tsx rename to ui/app/(prowler)/_new-overview/components/graphs-tabs/risk-radar-view/risk-radar-view-client.tsx diff --git a/ui/app/(prowler)/new-overview/components/graphs-tabs/risk-radar-view/risk-radar-view.ssr.tsx b/ui/app/(prowler)/_new-overview/components/graphs-tabs/risk-radar-view/risk-radar-view.ssr.tsx similarity index 100% rename from ui/app/(prowler)/new-overview/components/graphs-tabs/risk-radar-view/risk-radar-view.ssr.tsx rename to ui/app/(prowler)/_new-overview/components/graphs-tabs/risk-radar-view/risk-radar-view.ssr.tsx diff --git a/ui/app/(prowler)/new-overview/components/graphs-tabs/threat-map-view/threat-map-view.ssr.tsx b/ui/app/(prowler)/_new-overview/components/graphs-tabs/threat-map-view/threat-map-view.ssr.tsx similarity index 100% rename from ui/app/(prowler)/new-overview/components/graphs-tabs/threat-map-view/threat-map-view.ssr.tsx rename to ui/app/(prowler)/_new-overview/components/graphs-tabs/threat-map-view/threat-map-view.ssr.tsx diff --git a/ui/app/(prowler)/new-overview/components/provider-type-selector.tsx b/ui/app/(prowler)/_new-overview/components/provider-type-selector.tsx similarity index 100% rename from ui/app/(prowler)/new-overview/components/provider-type-selector.tsx rename to ui/app/(prowler)/_new-overview/components/provider-type-selector.tsx diff --git a/ui/app/(prowler)/new-overview/components/risk-severity-chart/index.ts b/ui/app/(prowler)/_new-overview/components/risk-severity-chart/index.ts similarity index 100% rename from ui/app/(prowler)/new-overview/components/risk-severity-chart/index.ts rename to ui/app/(prowler)/_new-overview/components/risk-severity-chart/index.ts diff --git a/ui/app/(prowler)/new-overview/components/risk-severity-chart/risk-severity-chart-detail.ssr.tsx b/ui/app/(prowler)/_new-overview/components/risk-severity-chart/risk-severity-chart-detail.ssr.tsx similarity index 100% rename from ui/app/(prowler)/new-overview/components/risk-severity-chart/risk-severity-chart-detail.ssr.tsx rename to ui/app/(prowler)/_new-overview/components/risk-severity-chart/risk-severity-chart-detail.ssr.tsx diff --git a/ui/app/(prowler)/new-overview/components/risk-severity-chart/risk-severity-chart.ssr.tsx b/ui/app/(prowler)/_new-overview/components/risk-severity-chart/risk-severity-chart.ssr.tsx similarity index 100% rename from ui/app/(prowler)/new-overview/components/risk-severity-chart/risk-severity-chart.ssr.tsx rename to ui/app/(prowler)/_new-overview/components/risk-severity-chart/risk-severity-chart.ssr.tsx diff --git a/ui/app/(prowler)/new-overview/components/risk-severity-chart/risk-severity-chart.tsx b/ui/app/(prowler)/_new-overview/components/risk-severity-chart/risk-severity-chart.tsx similarity index 100% rename from ui/app/(prowler)/new-overview/components/risk-severity-chart/risk-severity-chart.tsx rename to ui/app/(prowler)/_new-overview/components/risk-severity-chart/risk-severity-chart.tsx diff --git a/ui/app/(prowler)/new-overview/components/status-chart/index.ts b/ui/app/(prowler)/_new-overview/components/status-chart/index.ts similarity index 100% rename from ui/app/(prowler)/new-overview/components/status-chart/index.ts rename to ui/app/(prowler)/_new-overview/components/status-chart/index.ts diff --git a/ui/app/(prowler)/new-overview/components/status-chart/status-chart.tsx b/ui/app/(prowler)/_new-overview/components/status-chart/status-chart.tsx similarity index 100% rename from ui/app/(prowler)/new-overview/components/status-chart/status-chart.tsx rename to ui/app/(prowler)/_new-overview/components/status-chart/status-chart.tsx diff --git a/ui/app/(prowler)/new-overview/components/threat-score/index.ts b/ui/app/(prowler)/_new-overview/components/threat-score/index.ts similarity index 100% rename from ui/app/(prowler)/new-overview/components/threat-score/index.ts rename to ui/app/(prowler)/_new-overview/components/threat-score/index.ts diff --git a/ui/app/(prowler)/new-overview/components/threat-score/threat-score.ssr.tsx b/ui/app/(prowler)/_new-overview/components/threat-score/threat-score.ssr.tsx similarity index 100% rename from ui/app/(prowler)/new-overview/components/threat-score/threat-score.ssr.tsx rename to ui/app/(prowler)/_new-overview/components/threat-score/threat-score.ssr.tsx diff --git a/ui/app/(prowler)/new-overview/components/threat-score/threat-score.tsx b/ui/app/(prowler)/_new-overview/components/threat-score/threat-score.tsx similarity index 100% rename from ui/app/(prowler)/new-overview/components/threat-score/threat-score.tsx rename to ui/app/(prowler)/_new-overview/components/threat-score/threat-score.tsx diff --git a/ui/app/(prowler)/new-overview/lib/filter-params.ts b/ui/app/(prowler)/_new-overview/lib/filter-params.ts similarity index 100% rename from ui/app/(prowler)/new-overview/lib/filter-params.ts rename to ui/app/(prowler)/_new-overview/lib/filter-params.ts diff --git a/ui/app/(prowler)/new-overview/page.tsx b/ui/app/(prowler)/_new-overview/page.tsx similarity index 100% rename from ui/app/(prowler)/new-overview/page.tsx rename to ui/app/(prowler)/_new-overview/page.tsx diff --git a/ui/app/(prowler)/findings/page.tsx b/ui/app/(prowler)/findings/page.tsx index f0f80d6f79..f41b556375 100644 --- a/ui/app/(prowler)/findings/page.tsx +++ b/ui/app/(prowler)/findings/page.tsx @@ -1,5 +1,5 @@ import { Spacer } from "@heroui/spacer"; -import React, { Suspense } from "react"; +import { Suspense } from "react"; import { getFindings, @@ -78,7 +78,7 @@ export default async function Findings({ completedScans?.map((scan: ScanProps) => scan.id) || []; const scanDetails = createScanDetailsMapping( - completedScans, + completedScans || [], providersData, ) as { [uid: string]: ScanEntity }[]; diff --git a/ui/app/(prowler)/page.tsx b/ui/app/(prowler)/page.tsx index d382dc57a6..6c78664142 100644 --- a/ui/app/(prowler)/page.tsx +++ b/ui/app/(prowler)/page.tsx @@ -12,18 +12,18 @@ import { createDict } from "@/lib/helper"; import { FindingProps, SearchParamsProps } from "@/types"; import { LighthouseBanner } from "../../components/lighthouse/banner"; -import { AccountsSelector } from "./new-overview/components/accounts-selector"; -import { CheckFindingsSSR } from "./new-overview/components/check-findings"; -import { ProviderTypeSelector } from "./new-overview/components/provider-type-selector"; +import { AccountsSelector } from "./_new-overview/components/accounts-selector"; +import { CheckFindingsSSR } from "./_new-overview/components/check-findings"; +import { ProviderTypeSelector } from "./_new-overview/components/provider-type-selector"; import { RiskSeverityChartSkeleton, RiskSeverityChartSSR, -} from "./new-overview/components/risk-severity-chart"; -import { StatusChartSkeleton } from "./new-overview/components/status-chart"; +} from "./_new-overview/components/risk-severity-chart"; +import { StatusChartSkeleton } from "./_new-overview/components/status-chart"; import { ThreatScoreSkeleton, ThreatScoreSSR, -} from "./new-overview/components/threat-score"; +} from "./_new-overview/components/threat-score"; const FILTER_PREFIX = "filter["; diff --git a/ui/ui/.husky/pre-commit b/ui/ui/.husky/pre-commit deleted file mode 100644 index d212545421..0000000000 --- a/ui/ui/.husky/pre-commit +++ /dev/null @@ -1,151 +0,0 @@ -#!/bin/bash - -# Prowler UI - Pre-Commit Hook -# Optionally validates ONLY staged files against AGENTS.md standards using Claude Code -# Controlled by CODE_REVIEW_ENABLED in .env - -set -e - -# Colors -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -BLUE='\033[0;34m' -NC='\033[0m' # No Color - -echo "" -echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" -echo "🚀 Prowler UI - Pre-Commit Hook" -echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" -echo "" - -# Load .env file (look in git root directory) -GIT_ROOT=$(git rev-parse --show-toplevel) -if [ -f "$GIT_ROOT/ui/.env" ]; then - CODE_REVIEW_ENABLED=$(grep "^CODE_REVIEW_ENABLED" "$GIT_ROOT/ui/.env" | cut -d'=' -f2 | tr -d ' ') -elif [ -f "$GIT_ROOT/.env" ]; then - CODE_REVIEW_ENABLED=$(grep "^CODE_REVIEW_ENABLED" "$GIT_ROOT/.env" | cut -d'=' -f2 | tr -d ' ') -elif [ -f ".env" ]; then - CODE_REVIEW_ENABLED=$(grep "^CODE_REVIEW_ENABLED" .env | cut -d'=' -f2 | tr -d ' ') -else - CODE_REVIEW_ENABLED="false" -fi - -# Normalize the value to lowercase -CODE_REVIEW_ENABLED=$(echo "$CODE_REVIEW_ENABLED" | tr '[:upper:]' '[:lower:]') - -echo -e "${BLUE}ℹ️ Code Review Status: ${CODE_REVIEW_ENABLED}${NC}" -echo "" - -# Get staged files (what will be committed) -STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACM | grep -E '\.(tsx?|jsx?)$' || true) - -if [ "$CODE_REVIEW_ENABLED" = "true" ]; then - if [ -z "$STAGED_FILES" ]; then - echo -e "${YELLOW}⚠️ No TypeScript/JavaScript files staged to validate${NC}" - echo "" - else - echo -e "${YELLOW}🔍 Running Claude Code standards validation...${NC}" - echo "" - echo -e "${BLUE}📋 Files to validate:${NC}" - echo "$STAGED_FILES" | sed 's/^/ - /' - echo "" - - echo -e "${BLUE}📤 Sending to Claude Code for validation...${NC}" - echo "" - - # Build prompt with git diff of changes AND full context - VALIDATION_PROMPT=$( - cat <<'PROMPT_EOF' -You are a code reviewer for the Prowler UI project. Analyze the code changes (git diff with full context) below and validate they comply with AGENTS.md standards. - -**CRITICAL: You MUST check BOTH the changed lines AND the surrounding context for violations.** - -**RULES TO CHECK:** -1. React Imports: NO `import * as React` or `import React, {` → Use `import { useState }` -2. TypeScript: NO union types like `type X = "a" | "b"` → Use const-based: `const X = {...} as const` -3. Tailwind: NO `var()` or hex colors in className → Use Tailwind utilities and semantic color classes (e.g., `bg-bg-neutral-tertiary`, `border-border-neutral-primary`) -4. cn(): Use for merging multiple classes or for conditionals (handles Tailwind conflicts with twMerge) → `cn(BUTTON_STYLES.base, BUTTON_STYLES.active, isLoading && "opacity-50")` -5. React 19: NO `useMemo`/`useCallback` without reason -6. Zod v4: Use `.min(1)` not `.nonempty()`, `z.email()` not `z.string().email()`. All inputs must be validated with Zod. -7. File Org: 1 feature = local, 2+ features = shared -8. Directives: Server Actions need "use server", clients need "use client" -9. Implement DRY, KISS principles. (example: reusable components, avoid repetition) -10. Layout must work for all the responsive breakpoints (mobile, tablet, desktop) -11. ANY types cannot be used - CRITICAL: Check for `: any` in all visible lines -12. Use the components inside components/shadcn if possible -13. Check Accessibility best practices (like alt tags in images, semantic HTML, Aria labels, etc.) - -=== GIT DIFF WITH CONTEXT === -PROMPT_EOF - ) - - # Add git diff to prompt with more context (U5 = 5 lines before/after) - VALIDATION_PROMPT="$VALIDATION_PROMPT -$(git diff --cached -U5)" - - VALIDATION_PROMPT="$VALIDATION_PROMPT - -=== END DIFF === - -**IMPORTANT: Your response MUST start with exactly one of these lines:** -STATUS: PASSED -STATUS: FAILED - -**If FAILED:** List each violation with File, Line Number, Rule Number, and Issue. -**If PASSED:** Confirm all visible code (including context) complies with AGENTS.md standards. - -**Start your response now with STATUS:**" - - # Send to Claude Code - if VALIDATION_OUTPUT=$(echo "$VALIDATION_PROMPT" | claude 2>&1); then - echo "$VALIDATION_OUTPUT" - echo "" - - # Check result - STRICT MODE: fail if status unclear - if echo "$VALIDATION_OUTPUT" | grep -q "^STATUS: PASSED"; then - echo "" - echo -e "${GREEN}✅ VALIDATION PASSED${NC}" - echo "" - elif echo "$VALIDATION_OUTPUT" | grep -q "^STATUS: FAILED"; then - echo "" - echo -e "${RED}❌ VALIDATION FAILED${NC}" - echo -e "${RED}Fix violations before committing${NC}" - echo "" - exit 1 - else - echo "" - echo -e "${RED}❌ VALIDATION ERROR${NC}" - echo -e "${RED}Could not determine validation status from Claude Code response${NC}" - echo -e "${YELLOW}Response must start with 'STATUS: PASSED' or 'STATUS: FAILED'${NC}" - echo "" - echo -e "${YELLOW}To bypass validation temporarily, set CODE_REVIEW_ENABLED=false in .env${NC}" - echo "" - exit 1 - fi - else - echo -e "${YELLOW}⚠️ Claude Code not available${NC}" - fi - echo "" - fi -else - echo -e "${YELLOW}⏭️ Code review disabled (CODE_REVIEW_ENABLED=false)${NC}" - echo "" -fi - -# Run healthcheck (typecheck and lint check) -echo -e "${BLUE}🏥 Running healthcheck...${NC}" -echo "" - -cd ui || cd . -if npm run healthcheck; then - echo "" - echo -e "${GREEN}✅ Healthcheck passed${NC}" - echo "" -else - echo "" - echo -e "${RED}❌ Healthcheck failed${NC}" - echo -e "${RED}Fix type errors and linting issues before committing${NC}" - echo "" - exit 1 -fi