import { useQuery, useMutation } from "@tanstack/react-query"; import { queryClient, apiRequest } from "@/lib/queryClient"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Button } from "@/components/ui/button"; import { Badge } from "@/components/ui/badge"; import { Brain, Play, Search, CheckCircle2, XCircle, Clock, TrendingUp } from "lucide-react"; import { format } from "date-fns"; import type { TrainingHistory } from "@shared/schema"; import { useToast } from "@/hooks/use-toast"; import { useState } from "react"; import { useForm } from "react-hook-form"; import { zodResolver } from "@hookform/resolvers/zod"; import { z } from "zod"; import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogTrigger, DialogFooter, } from "@/components/ui/dialog"; import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage, FormDescription, } from "@/components/ui/form"; import { Input } from "@/components/ui/input"; import { Checkbox } from "@/components/ui/checkbox"; interface MLStatsResponse { logs?: { total: number; last_hour: number }; detections?: { total: number; blocked: number }; routers?: { active: number }; latest_training?: any; } const trainFormSchema = z.object({ max_records: z.coerce.number().min(1, "Minimo 1 record").max(1000000, "Massimo 1M record"), hours_back: z.coerce.number().min(1, "Minimo 1 ora").max(720, "Massimo 720 ore (30 giorni)"), }); const detectFormSchema = z.object({ max_records: z.coerce.number().min(1, "Minimo 1 record").max(1000000, "Massimo 1M record"), hours_back: z.coerce.number().min(1, "Minimo 1 ora").max(720, "Massimo 720 ore"), risk_threshold: z.coerce.number().min(0, "Minimo 0").max(100, "Massimo 100"), auto_block: z.boolean().default(true), }); export default function TrainingPage() { const { toast } = useToast(); const [isTrainDialogOpen, setIsTrainDialogOpen] = useState(false); const [isDetectDialogOpen, setIsDetectDialogOpen] = useState(false); const trainForm = useForm>({ resolver: zodResolver(trainFormSchema), defaultValues: { max_records: 100000, hours_back: 24, }, }); const detectForm = useForm>({ resolver: zodResolver(detectFormSchema), defaultValues: { max_records: 50000, hours_back: 1, risk_threshold: 75, auto_block: true, }, }); const { data: history, isLoading } = useQuery({ queryKey: ["/api/training-history"], refetchInterval: 10000, }); const { data: mlStats } = useQuery({ queryKey: ["/api/ml/stats"], refetchInterval: 10000, }); const trainMutation = useMutation({ mutationFn: async (params: z.infer) => { return await apiRequest("POST", "/api/ml/train", params); }, onSuccess: () => { queryClient.invalidateQueries({ queryKey: ["/api/training-history"] }); queryClient.invalidateQueries({ queryKey: ["/api/ml/stats"] }); toast({ title: "Training avviato", description: "Il modello ML è in addestramento. Controlla lo storico tra qualche minuto.", }); setIsTrainDialogOpen(false); trainForm.reset(); }, onError: (error: any) => { toast({ title: "Errore", description: error.message || "Impossibile avviare il training", variant: "destructive", }); }, }); const detectMutation = useMutation({ mutationFn: async (params: z.infer) => { return await apiRequest("POST", "/api/ml/detect", params); }, onSuccess: () => { queryClient.invalidateQueries({ queryKey: ["/api/detections"] }); queryClient.invalidateQueries({ queryKey: ["/api/stats"] }); toast({ title: "Detection avviata", description: "Analisi anomalie in corso. Controlla i rilevamenti tra qualche secondo.", }); setIsDetectDialogOpen(false); detectForm.reset(); }, onError: (error: any) => { toast({ title: "Errore", description: error.message || "Impossibile avviare la detection", variant: "destructive", }); }, }); const onTrainSubmit = (data: z.infer) => { trainMutation.mutate(data); }; const onDetectSubmit = (data: z.infer) => { detectMutation.mutate(data); }; return (

Machine Learning

Training e detection del modello Isolation Forest

{/* ML Stats */} {mlStats && (
Log Totali
{mlStats.logs?.total?.toLocaleString() || 0}

Ultima ora: {mlStats.logs?.last_hour?.toLocaleString() || 0}

Detection Totali
{mlStats.detections?.total || 0}

Bloccati: {mlStats.detections?.blocked || 0}

Router Attivi
{mlStats.routers?.active || 0}
)} {/* Actions */}
Addestramento Modello

Addestra il modello Isolation Forest analizzando i log recenti per rilevare pattern di traffico normale.

Avvia Training ML Configura i parametri per l'addestramento del modello
( Numero Record Consigliato: 100000 )} /> ( Ore Precedenti Consigliato: 24 )} />
Rilevamento Anomalie

Analizza i log recenti per rilevare anomalie e IP sospetti. Opzionalmente blocca automaticamente gli IP critici.

Avvia Detection Anomalie Configura i parametri per il rilevamento anomalie
( Numero Record Consigliato: 50000 )} /> ( Ore Precedenti Consigliato: 1 )} /> ( Soglia Rischio (%) Consigliato: 75 )} /> (
Blocco automatico IP critici (≥80)
)} />
{/* Training History */} Storico Training ({history?.length || 0}) {isLoading ? (
Caricamento...
) : history && history.length > 0 ? (
{history.map((item) => (

Versione {item.modelVersion}

{item.status === "success" ? ( Successo ) : ( Fallito )}
Record: {item.recordsProcessed.toLocaleString()}
Feature: {item.featuresCount}
{item.accuracy && (
Accuracy: {item.accuracy}%
)} {item.trainingDuration && (
Durata: {item.trainingDuration}s
)}

{format(new Date(item.trainedAt), "dd/MM/yyyy HH:mm:ss")}

{item.notes && (

{item.notes}

)}
))}
) : (

Nessun training eseguito

Avvia il primo training per addestrare il modello ML

)}
); }