From ebc588c460d0734929f3484badc7b06f8d6abb41 Mon Sep 17 00:00:00 2001 From: Oliver Kieselbach Date: Tue, 14 Apr 2026 11:29:55 +0200 Subject: [PATCH] refactor web structure (re-org to utils) --- .../admin/components/DiagnosticsLogPathsSection.tsx | 11 ++++------- .../app/admin/components/SessionExportSection.tsx | 2 +- .../app/dashboard/hooks/useDashboardSessions.ts | 2 +- .../app/docs/sections/SectionGatherRules.tsx | 2 +- .../app/gather-rules/components/GatherRuleCard.tsx | 2 +- .../gather-rules/components/GatherRuleFormFields.tsx | 2 +- src/Web/autopilot-monitor-web/app/go/[code]/route.ts | 4 ++-- .../[sessionId]/components/DeviceDetailsCard.tsx | 2 +- .../sessions/[sessionId]/hooks/useSessionAnalysis.ts | 2 +- .../app/sessions/[sessionId]/page.tsx | 4 ++-- .../app/settings/components/DiagnosticsSection.tsx | 2 +- src/Web/autopilot-monitor-web/app/settings/types.ts | 7 +------ src/Web/autopilot-monitor-web/app/sitemap.ts | 2 +- .../components/ScriptExecutions.tsx | 2 +- .../components/ValidationIndicator.tsx | 2 +- src/Web/autopilot-monitor-web/lib/api.ts | 2 +- .../autopilot-monitor-web/scripts/generate-lastmod.js | 2 +- src/Web/autopilot-monitor-web/types/diagnostics.ts | 6 ++++++ src/Web/autopilot-monitor-web/types/index.ts | 1 + 19 files changed, 29 insertions(+), 30 deletions(-) create mode 100644 src/Web/autopilot-monitor-web/types/diagnostics.ts diff --git a/src/Web/autopilot-monitor-web/app/admin/components/DiagnosticsLogPathsSection.tsx b/src/Web/autopilot-monitor-web/app/admin/components/DiagnosticsLogPathsSection.tsx index 7c39c2f6..5d69f27e 100644 --- a/src/Web/autopilot-monitor-web/app/admin/components/DiagnosticsLogPathsSection.tsx +++ b/src/Web/autopilot-monitor-web/app/admin/components/DiagnosticsLogPathsSection.tsx @@ -1,15 +1,12 @@ "use client"; import { useState, useMemo } from "react"; -import { validateDiagnosticsPath } from "@/lib/guardValidation"; +import { validateDiagnosticsPath } from "@/utils/guardValidation"; import { ValidationIndicator } from "@/components/ValidationIndicator"; +import type { DiagnosticsLogPath } from "@/types/diagnostics"; -export interface DiagnosticsLogPath { - path: string; - description: string; - isBuiltIn: boolean; - includeSubfolders?: boolean; -} +// Re-export so existing consumers importing from this component keep working +export type { DiagnosticsLogPath }; interface DiagnosticsLogPathsSectionProps { globalDiagPaths: DiagnosticsLogPath[]; diff --git a/src/Web/autopilot-monitor-web/app/admin/components/SessionExportSection.tsx b/src/Web/autopilot-monitor-web/app/admin/components/SessionExportSection.tsx index 551db1f9..ce4dd220 100644 --- a/src/Web/autopilot-monitor-web/app/admin/components/SessionExportSection.tsx +++ b/src/Web/autopilot-monitor-web/app/admin/components/SessionExportSection.tsx @@ -5,7 +5,7 @@ import { api } from "@/lib/api"; import { authenticatedFetch, TokenExpiredError } from "@/lib/authenticatedFetch"; import { TenantConfiguration } from "./TenantManagementSection"; import { TenantSearchSelect } from "./TenantSearchSelect"; -import { SessionExportEvent, generateCsvExport, generateUiExport } from "@/lib/sessionExportUtils"; +import { SessionExportEvent, generateCsvExport, generateUiExport } from "@/utils/sessionExportUtils"; import { trackEvent } from "@/lib/appInsights"; function downloadFile(content: string, filename: string, mimeType: string) { diff --git a/src/Web/autopilot-monitor-web/app/dashboard/hooks/useDashboardSessions.ts b/src/Web/autopilot-monitor-web/app/dashboard/hooks/useDashboardSessions.ts index a82e63d7..607775f4 100644 --- a/src/Web/autopilot-monitor-web/app/dashboard/hooks/useDashboardSessions.ts +++ b/src/Web/autopilot-monitor-web/app/dashboard/hooks/useDashboardSessions.ts @@ -3,7 +3,7 @@ import { useCallback, useEffect, useRef, useState } from "react"; import { api } from "@/lib/api"; import { authenticatedFetch, TokenExpiredError } from "@/lib/authenticatedFetch"; -import { asGuidOrUndefined } from "@/lib/inputValidation"; +import { asGuidOrUndefined } from "@/utils/inputValidation"; import type { NotificationType } from "@/contexts/NotificationContext"; import type { Session } from "../types"; diff --git a/src/Web/autopilot-monitor-web/app/docs/sections/SectionGatherRules.tsx b/src/Web/autopilot-monitor-web/app/docs/sections/SectionGatherRules.tsx index 2d807aa8..5f0b55e5 100644 --- a/src/Web/autopilot-monitor-web/app/docs/sections/SectionGatherRules.tsx +++ b/src/Web/autopilot-monitor-web/app/docs/sections/SectionGatherRules.tsx @@ -6,7 +6,7 @@ import { COMMAND_CATEGORIES, ALLOWED_FILE_PREFIXES, ALLOWED_WMI_QUERY_PREFIXES, -} from "@/lib/guardrails.generated"; +} from "@/utils/guardrails.generated"; function GuardToggle({ label, children }: { label: string; children: React.ReactNode }) { const [open, setOpen] = useState(false); diff --git a/src/Web/autopilot-monitor-web/app/gather-rules/components/GatherRuleCard.tsx b/src/Web/autopilot-monitor-web/app/gather-rules/components/GatherRuleCard.tsx index 666f4bd1..a3d2e7b3 100644 --- a/src/Web/autopilot-monitor-web/app/gather-rules/components/GatherRuleCard.tsx +++ b/src/Web/autopilot-monitor-web/app/gather-rules/components/GatherRuleCard.tsx @@ -4,7 +4,7 @@ import { useMemo, useState } from "react"; import { GatherRule, NewRuleForm, CATEGORY_COLORS, COLLECTOR_TYPE_LABELS, EMPTY_FORM, formatTrigger } from "../types"; import { GatherRuleFormFields } from "./GatherRuleFormFields"; import { FormJsonToggle, JsonModeToggleButtons, ReadOnlyJsonView } from "@/components/rules/FormJsonToggle"; -import { validateGatherRuleTarget } from "@/lib/guardValidation"; +import { validateGatherRuleTarget } from "@/utils/guardValidation"; import { ValidationIndicator } from "@/components/ValidationIndicator"; import { stripInternalFields } from "@/lib/rulePageHelpers"; diff --git a/src/Web/autopilot-monitor-web/app/gather-rules/components/GatherRuleFormFields.tsx b/src/Web/autopilot-monitor-web/app/gather-rules/components/GatherRuleFormFields.tsx index e989aecc..0efb1a7c 100644 --- a/src/Web/autopilot-monitor-web/app/gather-rules/components/GatherRuleFormFields.tsx +++ b/src/Web/autopilot-monitor-web/app/gather-rules/components/GatherRuleFormFields.tsx @@ -13,7 +13,7 @@ import { formatTrigger, } from "../types"; import { KNOWN_EVENT_TYPES, findEventType } from "../eventTypes"; -import { validateGatherRuleTarget } from "@/lib/guardValidation"; +import { validateGatherRuleTarget } from "@/utils/guardValidation"; import { ValidationIndicator } from "@/components/ValidationIndicator"; interface GatherRuleFormFieldsProps { diff --git a/src/Web/autopilot-monitor-web/app/go/[code]/route.ts b/src/Web/autopilot-monitor-web/app/go/[code]/route.ts index 633c3c37..318bb6d4 100644 --- a/src/Web/autopilot-monitor-web/app/go/[code]/route.ts +++ b/src/Web/autopilot-monitor-web/app/go/[code]/route.ts @@ -1,4 +1,4 @@ -import { validateBootstrapResponse } from "@/lib/bootstrapValidation"; +import { validateBootstrapResponse } from "@/utils/bootstrapValidation"; export const runtime = "nodejs"; @@ -79,7 +79,7 @@ function errorScript(message: string): Response { } // SECURITY INVARIANT: All template parameters MUST come from -// validateBootstrapResponse() in @/lib/bootstrapValidation. The single-quoted +// validateBootstrapResponse() in @/utils/bootstrapValidation. The single-quoted // PowerShell string literals below are the second line of defense against // injection (single-quoted PS strings do NOT expand $(...), $var, or // backticks). Do NOT change to double-quoted without re-reviewing the diff --git a/src/Web/autopilot-monitor-web/app/sessions/[sessionId]/components/DeviceDetailsCard.tsx b/src/Web/autopilot-monitor-web/app/sessions/[sessionId]/components/DeviceDetailsCard.tsx index d5a973a8..47a0f739 100644 --- a/src/Web/autopilot-monitor-web/app/sessions/[sessionId]/components/DeviceDetailsCard.tsx +++ b/src/Web/autopilot-monitor-web/app/sessions/[sessionId]/components/DeviceDetailsCard.tsx @@ -3,7 +3,7 @@ import { useState, useMemo } from "react"; import { EnrollmentEvent } from "@/types"; import OobeConfigModal from "./OobeConfigModal"; -import { compareVersions, stripGitHashSuffix } from "@/lib/bootstrapVersion"; +import { compareVersions, stripGitHashSuffix } from "@/utils/bootstrapVersion"; export default function DeviceDetailsCard({ events, latestAgentVersion }: { events: EnrollmentEvent[]; latestAgentVersion?: string | null }) { const [expanded, setExpanded] = useState(false); diff --git a/src/Web/autopilot-monitor-web/app/sessions/[sessionId]/hooks/useSessionAnalysis.ts b/src/Web/autopilot-monitor-web/app/sessions/[sessionId]/hooks/useSessionAnalysis.ts index 0b099542..f1942590 100644 --- a/src/Web/autopilot-monitor-web/app/sessions/[sessionId]/hooks/useSessionAnalysis.ts +++ b/src/Web/autopilot-monitor-web/app/sessions/[sessionId]/hooks/useSessionAnalysis.ts @@ -3,7 +3,7 @@ import { useState, useCallback } from "react"; import { api } from "@/lib/api"; import { authenticatedFetch } from "@/lib/authenticatedFetch"; import { RuleResult } from "@/types"; -import { isGuid } from "@/lib/inputValidation"; +import { isGuid } from "@/utils/inputValidation"; export function useSessionAnalysis( sessionId: string, diff --git a/src/Web/autopilot-monitor-web/app/sessions/[sessionId]/page.tsx b/src/Web/autopilot-monitor-web/app/sessions/[sessionId]/page.tsx index 577ef85e..5bc363c6 100644 --- a/src/Web/autopilot-monitor-web/app/sessions/[sessionId]/page.tsx +++ b/src/Web/autopilot-monitor-web/app/sessions/[sessionId]/page.tsx @@ -30,11 +30,11 @@ import { usePageSections } from "../../../hooks/usePageSections"; import { PageSectionItem } from "../../../contexts/SidebarContext"; import { InformationCircleIcon, ComputerDesktopIcon, PlayCircleIcon, SparklesIcon, ChartBarIcon, CodeBracketIcon, ArrowDownTrayIcon, ListBulletIcon, ClockIcon, ShieldCheckIcon } from "../../../lib/sidebarIcons"; import DeviceDetailsCard from "./components/DeviceDetailsCard"; -import { generateUiExport, generateCsvExport, generateSessionCsvExport, generateRuleResultsCsvExport, SessionExportEvent } from "@/lib/sessionExportUtils"; +import { generateUiExport, generateCsvExport, generateSessionCsvExport, generateRuleResultsCsvExport, SessionExportEvent } from "@/utils/sessionExportUtils"; import { Session, EnrollmentEvent, RuleResult } from "@/types"; import { trackEvent } from "@/lib/appInsights"; import { useAdminMode } from "@/hooks/useAdminMode"; -import { isGuid } from "@/lib/inputValidation"; +import { isGuid } from "@/utils/inputValidation"; export default function SessionDetailPage() { const params = useParams(); diff --git a/src/Web/autopilot-monitor-web/app/settings/components/DiagnosticsSection.tsx b/src/Web/autopilot-monitor-web/app/settings/components/DiagnosticsSection.tsx index 69cf42af..c6eea805 100644 --- a/src/Web/autopilot-monitor-web/app/settings/components/DiagnosticsSection.tsx +++ b/src/Web/autopilot-monitor-web/app/settings/components/DiagnosticsSection.tsx @@ -2,7 +2,7 @@ import { useMemo, useState } from "react"; import { DiagnosticsLogPath } from "../types"; -import { validateDiagnosticsPath } from "@/lib/guardValidation"; +import { validateDiagnosticsPath } from "@/utils/guardValidation"; import { ValidationIndicator } from "@/components/ValidationIndicator"; import SaveResetBar from "./SaveResetBar"; diff --git a/src/Web/autopilot-monitor-web/app/settings/types.ts b/src/Web/autopilot-monitor-web/app/settings/types.ts index a898cc4c..2e16e1b4 100644 --- a/src/Web/autopilot-monitor-web/app/settings/types.ts +++ b/src/Web/autopilot-monitor-web/app/settings/types.ts @@ -1,9 +1,4 @@ -export interface DiagnosticsLogPath { - path: string; - description: string; - isBuiltIn: boolean; - includeSubfolders?: boolean; -} +export type { DiagnosticsLogPath } from "@/types/diagnostics"; export interface TenantConfiguration { tenantId: string; diff --git a/src/Web/autopilot-monitor-web/app/sitemap.ts b/src/Web/autopilot-monitor-web/app/sitemap.ts index 3410bac1..2cfc0aff 100644 --- a/src/Web/autopilot-monitor-web/app/sitemap.ts +++ b/src/Web/autopilot-monitor-web/app/sitemap.ts @@ -1,6 +1,6 @@ import type { MetadataRoute } from "next"; import { NAV_SECTIONS } from "./docs/docsNavSections"; -import { PAGE_LASTMOD } from "../lib/page-lastmod.generated"; +import { PAGE_LASTMOD } from "@/utils/page-lastmod.generated"; const BASE_URL = "https://www.autopilotmonitor.com"; diff --git a/src/Web/autopilot-monitor-web/components/ScriptExecutions.tsx b/src/Web/autopilot-monitor-web/components/ScriptExecutions.tsx index e9704d05..97ba55ce 100644 --- a/src/Web/autopilot-monitor-web/components/ScriptExecutions.tsx +++ b/src/Web/autopilot-monitor-web/components/ScriptExecutions.tsx @@ -1,7 +1,7 @@ "use client"; import { useMemo, useState } from "react"; -import { compareVersions, extractBootstrapVersion } from "@/lib/bootstrapVersion"; +import { compareVersions, extractBootstrapVersion } from "@/utils/bootstrapVersion"; interface ScriptEvent { timestamp: string; diff --git a/src/Web/autopilot-monitor-web/components/ValidationIndicator.tsx b/src/Web/autopilot-monitor-web/components/ValidationIndicator.tsx index 0c6db610..f110a4c8 100644 --- a/src/Web/autopilot-monitor-web/components/ValidationIndicator.tsx +++ b/src/Web/autopilot-monitor-web/components/ValidationIndicator.tsx @@ -1,6 +1,6 @@ "use client"; -import { ValidationResult } from "@/lib/guardValidation"; +import { ValidationResult } from "@/utils/guardValidation"; interface ValidationIndicatorProps { result: ValidationResult | null; diff --git a/src/Web/autopilot-monitor-web/lib/api.ts b/src/Web/autopilot-monitor-web/lib/api.ts index 8ae6a902..12f0cd2c 100644 --- a/src/Web/autopilot-monitor-web/lib/api.ts +++ b/src/Web/autopilot-monitor-web/lib/api.ts @@ -2,7 +2,7 @@ * Typed API URL builder * All backend endpoint URLs are defined here for type-safety and maintainability. */ -import { API_BASE_URL } from "./config"; +import { API_BASE_URL } from "@/utils/config"; function qs(params: Record): string { const p = new URLSearchParams(); diff --git a/src/Web/autopilot-monitor-web/scripts/generate-lastmod.js b/src/Web/autopilot-monitor-web/scripts/generate-lastmod.js index 3664479d..0b51607a 100644 --- a/src/Web/autopilot-monitor-web/scripts/generate-lastmod.js +++ b/src/Web/autopilot-monitor-web/scripts/generate-lastmod.js @@ -11,7 +11,7 @@ const fs = require("fs"); const path = require("path"); const WEB_ROOT = path.resolve(__dirname, ".."); -const OUTPUT_FILE = path.join(WEB_ROOT, "lib/page-lastmod.generated.ts"); +const OUTPUT_FILE = path.join(WEB_ROOT, "utils/page-lastmod.generated.ts"); // URL path -> source file(s) relative to WEB_ROOT // For docs sections, we check the section component file diff --git a/src/Web/autopilot-monitor-web/types/diagnostics.ts b/src/Web/autopilot-monitor-web/types/diagnostics.ts new file mode 100644 index 00000000..d425a09f --- /dev/null +++ b/src/Web/autopilot-monitor-web/types/diagnostics.ts @@ -0,0 +1,6 @@ +export interface DiagnosticsLogPath { + path: string; + description: string; + isBuiltIn: boolean; + includeSubfolders?: boolean; +} diff --git a/src/Web/autopilot-monitor-web/types/index.ts b/src/Web/autopilot-monitor-web/types/index.ts index 3abb7dfe..ecd39d4c 100644 --- a/src/Web/autopilot-monitor-web/types/index.ts +++ b/src/Web/autopilot-monitor-web/types/index.ts @@ -1,3 +1,4 @@ export type { Session } from "./session"; export type { EnrollmentEvent, RuleResult } from "./enrollment"; export type { AdminConfiguration, OpsAlertRule } from "./adminConfig"; +export type { DiagnosticsLogPath } from "./diagnostics";