ids.alfacom.it/shared/schema.ts
marco370 7eb0991cb5 Update Mikrotik router connection settings and remove redundant tests
Removes the connection testing functionality and updates the default API port to 8729 for Mikrotik routers.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 7a657272-55ba-4a79-9a2e-f1ed9bc7a528
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Event-Id: 54ecaeb2-ec77-4629-8d8d-e3bc4f663bec
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/449cf7c4-c97a-45ae-8234-e5c5b8d6a84f/7a657272-55ba-4a79-9a2e-f1ed9bc7a528/31VdIyL
2025-11-25 11:29:12 +00:00

200 lines
7.7 KiB
TypeScript

import { sql, relations } from "drizzle-orm";
import { pgTable, text, varchar, integer, timestamp, decimal, boolean, index, bigint, unique } from "drizzle-orm/pg-core";
import { createInsertSchema } from "drizzle-zod";
import { z } from "zod";
// Router MikroTik configuration
export const routers = pgTable("routers", {
id: varchar("id").primaryKey().default(sql`gen_random_uuid()`),
name: text("name").notNull(),
ipAddress: text("ip_address").notNull().unique(),
apiPort: integer("api_port").notNull().default(8729),
username: text("username").notNull(),
password: text("password").notNull(),
enabled: boolean("enabled").notNull().default(true),
lastSync: timestamp("last_sync"),
createdAt: timestamp("created_at").defaultNow().notNull(),
});
// Network logs from MikroTik (syslog)
export const networkLogs = pgTable("network_logs", {
id: varchar("id").primaryKey().default(sql`gen_random_uuid()`),
routerName: text("router_name").notNull(), // Hostname dal syslog
timestamp: timestamp("timestamp").notNull(),
sourceIp: text("source_ip").notNull(),
sourcePort: integer("source_port"),
destinationIp: text("destination_ip"),
destinationPort: integer("destination_port"),
protocol: text("protocol"),
action: text("action"),
packetLength: integer("packet_length"),
rawMessage: text("raw_message"),
createdAt: timestamp("created_at").defaultNow().notNull(),
}, (table) => ({
sourceIpIdx: index("source_ip_idx").on(table.sourceIp),
timestampIdx: index("timestamp_idx").on(table.timestamp),
routerNameIdx: index("router_name_idx").on(table.routerName),
}));
// Detected threats/anomalies
export const detections = pgTable("detections", {
id: varchar("id").primaryKey().default(sql`gen_random_uuid()`),
sourceIp: text("source_ip").notNull(),
riskScore: decimal("risk_score", { precision: 5, scale: 2 }).notNull(),
confidence: decimal("confidence", { precision: 5, scale: 2 }).notNull(),
anomalyType: text("anomaly_type").notNull(),
reason: text("reason"),
logCount: integer("log_count").notNull(),
firstSeen: timestamp("first_seen").notNull(),
lastSeen: timestamp("last_seen").notNull(),
blocked: boolean("blocked").notNull().default(false),
blockedAt: timestamp("blocked_at"),
detectedAt: timestamp("detected_at").defaultNow().notNull(),
// Geolocation & AS info
country: text("country"),
countryCode: text("country_code"),
city: text("city"),
organization: text("organization"),
asNumber: text("as_number"),
asName: text("as_name"),
isp: text("isp"),
}, (table) => ({
sourceIpIdx: index("detection_source_ip_idx").on(table.sourceIp),
riskScoreIdx: index("risk_score_idx").on(table.riskScore),
detectedAtIdx: index("detected_at_idx").on(table.detectedAt),
countryIdx: index("country_idx").on(table.country),
}));
// Whitelist per IP fidati
export const whitelist = pgTable("whitelist", {
id: varchar("id").primaryKey().default(sql`gen_random_uuid()`),
ipAddress: text("ip_address").notNull().unique(),
comment: text("comment"),
reason: text("reason"),
createdBy: text("created_by"),
active: boolean("active").notNull().default(true),
createdAt: timestamp("created_at").defaultNow().notNull(),
});
// ML Training history
export const trainingHistory = pgTable("training_history", {
id: varchar("id").primaryKey().default(sql`gen_random_uuid()`),
modelVersion: text("model_version").notNull(),
recordsProcessed: integer("records_processed").notNull(),
featuresCount: integer("features_count").notNull(),
accuracy: decimal("accuracy", { precision: 5, scale: 2 }),
trainingDuration: integer("training_duration"),
status: text("status").notNull(),
notes: text("notes"),
trainedAt: timestamp("trained_at").defaultNow().notNull(),
});
// Network analytics - aggregazioni permanenti per statistiche long-term
export const networkAnalytics = pgTable("network_analytics", {
id: varchar("id").primaryKey().default(sql`gen_random_uuid()`),
date: timestamp("date", { mode: 'date' }).notNull(),
hour: integer("hour"), // NULL = giornaliera, 0-23 = oraria
// Traffico totale
totalPackets: integer("total_packets").notNull().default(0),
totalBytes: bigint("total_bytes", { mode: 'number' }).notNull().default(0),
uniqueIps: integer("unique_ips").notNull().default(0),
// Traffico normale (non anomalo)
normalPackets: integer("normal_packets").notNull().default(0),
normalBytes: bigint("normal_bytes", { mode: 'number' }).notNull().default(0),
normalUniqueIps: integer("normal_unique_ips").notNull().default(0),
topNormalIps: text("top_normal_ips"), // JSON: [{ip, packets, bytes, country}]
// Attacchi/Anomalie
attackPackets: integer("attack_packets").notNull().default(0),
attackBytes: bigint("attack_bytes", { mode: 'number' }).notNull().default(0),
attackUniqueIps: integer("attack_unique_ips").notNull().default(0),
attacksByCountry: text("attacks_by_country"), // JSON: {IT: 5, RU: 30}
attacksByType: text("attacks_by_type"), // JSON: {ddos: 10, port_scan: 5}
topAttackers: text("top_attackers"), // JSON: [{ip, country, risk_score, packets}]
// Dettagli geografici (tutto il traffico)
trafficByCountry: text("traffic_by_country"), // JSON: {IT: {normal: 100, attacks: 5}}
createdAt: timestamp("created_at").defaultNow().notNull(),
}, (table) => ({
dateHourIdx: index("network_analytics_date_hour_idx").on(table.date, table.hour),
dateIdx: index("network_analytics_date_idx").on(table.date),
// CRITICAL: Vincolo UNIQUE per ON CONFLICT in aggregator
dateHourUnique: unique("network_analytics_date_hour_key").on(table.date, table.hour),
}));
// Schema version tracking for database migrations
export const schemaVersion = pgTable("schema_version", {
id: integer("id").primaryKey().default(1),
version: integer("version").notNull().default(0),
appliedAt: timestamp("applied_at").defaultNow().notNull(),
description: text("description"),
});
// Relations
export const routersRelations = relations(routers, ({ many }) => ({
logs: many(networkLogs),
}));
// Rimossa relazione router (non più FK)
// Insert schemas
export const insertRouterSchema = createInsertSchema(routers).omit({
id: true,
createdAt: true,
lastSync: true,
});
export const insertNetworkLogSchema = createInsertSchema(networkLogs).omit({
id: true,
createdAt: true,
});
export const insertDetectionSchema = createInsertSchema(detections).omit({
id: true,
detectedAt: true,
});
export const insertWhitelistSchema = createInsertSchema(whitelist).omit({
id: true,
createdAt: true,
});
export const insertTrainingHistorySchema = createInsertSchema(trainingHistory).omit({
id: true,
trainedAt: true,
});
export const insertSchemaVersionSchema = createInsertSchema(schemaVersion).omit({
appliedAt: true,
});
export const insertNetworkAnalyticsSchema = createInsertSchema(networkAnalytics).omit({
id: true,
createdAt: true,
});
// Types
export type Router = typeof routers.$inferSelect;
export type InsertRouter = z.infer<typeof insertRouterSchema>;
export type NetworkLog = typeof networkLogs.$inferSelect;
export type InsertNetworkLog = z.infer<typeof insertNetworkLogSchema>;
export type Detection = typeof detections.$inferSelect;
export type InsertDetection = z.infer<typeof insertDetectionSchema>;
export type Whitelist = typeof whitelist.$inferSelect;
export type InsertWhitelist = z.infer<typeof insertWhitelistSchema>;
export type TrainingHistory = typeof trainingHistory.$inferSelect;
export type InsertTrainingHistory = z.infer<typeof insertTrainingHistorySchema>;
export type SchemaVersion = typeof schemaVersion.$inferSelect;
export type InsertSchemaVersion = z.infer<typeof insertSchemaVersionSchema>;
export type NetworkAnalytics = typeof networkAnalytics.$inferSelect;
export type InsertNetworkAnalytics = z.infer<typeof insertNetworkAnalyticsSchema>;