import { routers, networkLogs, detections, whitelist, trainingHistory, networkAnalytics, type Router, type InsertRouter, type NetworkLog, type InsertNetworkLog, type Detection, type InsertDetection, type Whitelist, type InsertWhitelist, type TrainingHistory, type InsertTrainingHistory, type NetworkAnalytics, } from "@shared/schema"; import { db } from "./db"; import { eq, desc, and, gte, sql, inArray } from "drizzle-orm"; export interface IStorage { // Routers getAllRouters(): Promise; getRouterById(id: string): Promise; createRouter(router: InsertRouter): Promise; updateRouter(id: string, router: Partial): Promise; deleteRouter(id: string): Promise; // Network Logs getRecentLogs(limit: number): Promise; getLogsByIp(sourceIp: string, limit: number): Promise; createLog(log: InsertNetworkLog): Promise; getLogsForTraining(limit: number, minTimestamp?: Date): Promise; // Detections getAllDetections(limit: number): Promise; getDetectionByIp(sourceIp: string): Promise; createDetection(detection: InsertDetection): Promise; updateDetection(id: string, detection: Partial): Promise; getUnblockedDetections(): Promise; // Whitelist getAllWhitelist(): Promise; getWhitelistByIp(ipAddress: string): Promise; createWhitelist(whitelist: InsertWhitelist): Promise; deleteWhitelist(id: string): Promise; isWhitelisted(ipAddress: string): Promise; // Training History getTrainingHistory(limit: number): Promise; createTrainingHistory(history: InsertTrainingHistory): Promise; getLatestTraining(): Promise; // Network Analytics getAnalyticsByDateRange(startDate: Date, endDate: Date, hourly?: boolean): Promise; getRecentAnalytics(days: number, hourly?: boolean): Promise; // System testConnection(): Promise; } export class DatabaseStorage implements IStorage { // Routers async getAllRouters(): Promise { return await db.select().from(routers).orderBy(desc(routers.createdAt)); } async getRouterById(id: string): Promise { const [router] = await db.select().from(routers).where(eq(routers.id, id)); return router || undefined; } async createRouter(insertRouter: InsertRouter): Promise { const [router] = await db.insert(routers).values(insertRouter).returning(); return router; } async updateRouter(id: string, updateData: Partial): Promise { const [router] = await db .update(routers) .set(updateData) .where(eq(routers.id, id)) .returning(); return router || undefined; } async deleteRouter(id: string): Promise { const result = await db.delete(routers).where(eq(routers.id, id)); return result.rowCount !== null && result.rowCount > 0; } // Network Logs async getRecentLogs(limit: number): Promise { return await db .select() .from(networkLogs) .orderBy(desc(networkLogs.timestamp)) .limit(limit); } async getLogsByIp(sourceIp: string, limit: number): Promise { return await db .select() .from(networkLogs) .where(eq(networkLogs.sourceIp, sourceIp)) .orderBy(desc(networkLogs.timestamp)) .limit(limit); } async createLog(insertLog: InsertNetworkLog): Promise { const [log] = await db.insert(networkLogs).values(insertLog).returning(); return log; } async getLogsForTraining(limit: number, minTimestamp?: Date): Promise { const conditions = minTimestamp ? and(gte(networkLogs.timestamp, minTimestamp)) : undefined; return await db .select() .from(networkLogs) .where(conditions) .orderBy(desc(networkLogs.timestamp)) .limit(limit); } // Detections async getAllDetections(limit: number): Promise { return await db .select() .from(detections) .orderBy(desc(detections.detectedAt)) .limit(limit); } async getDetectionByIp(sourceIp: string): Promise { const [detection] = await db .select() .from(detections) .where(eq(detections.sourceIp, sourceIp)) .orderBy(desc(detections.detectedAt)) .limit(1); return detection || undefined; } async createDetection(insertDetection: InsertDetection): Promise { const [detection] = await db .insert(detections) .values(insertDetection) .returning(); return detection; } async updateDetection( id: string, updateData: Partial ): Promise { const [detection] = await db .update(detections) .set(updateData) .where(eq(detections.id, id)) .returning(); return detection || undefined; } async getUnblockedDetections(): Promise { return await db .select() .from(detections) .where(eq(detections.blocked, false)) .orderBy(desc(detections.riskScore)); } // Whitelist async getAllWhitelist(): Promise { return await db .select() .from(whitelist) .where(eq(whitelist.active, true)) .orderBy(desc(whitelist.createdAt)); } async getWhitelistByIp(ipAddress: string): Promise { const [item] = await db .select() .from(whitelist) .where(and(eq(whitelist.ipAddress, ipAddress), eq(whitelist.active, true))); return item || undefined; } async createWhitelist(insertWhitelist: InsertWhitelist): Promise { const [item] = await db.insert(whitelist).values(insertWhitelist).returning(); return item; } async deleteWhitelist(id: string): Promise { const result = await db.delete(whitelist).where(eq(whitelist.id, id)); return result.rowCount !== null && result.rowCount > 0; } async isWhitelisted(ipAddress: string): Promise { const item = await this.getWhitelistByIp(ipAddress); return item !== undefined; } // Training History async getTrainingHistory(limit: number): Promise { return await db .select() .from(trainingHistory) .orderBy(desc(trainingHistory.trainedAt)) .limit(limit); } async createTrainingHistory(insertHistory: InsertTrainingHistory): Promise { const [history] = await db .insert(trainingHistory) .values(insertHistory) .returning(); return history; } async getLatestTraining(): Promise { const [history] = await db .select() .from(trainingHistory) .orderBy(desc(trainingHistory.trainedAt)) .limit(1); return history || undefined; } // Network Analytics async getAnalyticsByDateRange(startDate: Date, endDate: Date, hourly: boolean = false): Promise { const hourCondition = hourly ? sql`hour IS NOT NULL` : sql`hour IS NULL`; // DEBUG: Log query parameters console.log('[ANALYTICS QUERY]', { startDate: startDate.toISOString(), endDate: endDate.toISOString(), hourly, hourCondition: hourly ? 'NOT NULL' : 'NULL' }); const results = await db .select() .from(networkAnalytics) .where( and( gte(networkAnalytics.date, startDate), sql`${networkAnalytics.date} <= ${endDate}`, hourCondition ) ) .orderBy(desc(networkAnalytics.date), desc(networkAnalytics.hour)); console.log('[ANALYTICS RESULTS]', results.length, 'records found'); if (results.length > 0) { console.log('[ANALYTICS SAMPLE]', results[0]); } return results; } async getRecentAnalytics(days: number, hourly: boolean = false): Promise { const startDate = new Date(); startDate.setDate(startDate.getDate() - days); return this.getAnalyticsByDateRange(startDate, new Date(), hourly); } async testConnection(): Promise { try { await db.execute(sql`SELECT 1`); return true; } catch (error) { console.error('[DB ERROR] Connection test failed:', error); return false; } } } export const storage = new DatabaseStorage();