diff --git a/surfsense_web/contracts/types/log.types.ts b/surfsense_web/contracts/types/log.types.ts new file mode 100644 index 000000000..c3e2ec9f5 --- /dev/null +++ b/surfsense_web/contracts/types/log.types.ts @@ -0,0 +1,131 @@ +import { z } from "zod"; + +/** + * ENUMS + */ +export const logLevelEnum = z.enum([ + "DEBUG", + "INFO", + "WARNING", + "ERROR", + "CRITICAL" +]); + +export const logStatusEnum = z.enum([ + "IN_PROGRESS", + "SUCCESS", + "FAILED" +]); + +/** + * Base log schema + */ +export const log = z.object({ + id: z.number(), + level: logLevelEnum, + status: logStatusEnum, + message: z.string(), + source: z.string().nullable().optional(), + log_metadata: z.record(z.string(), z.any()).nullable().optional(), + created_at: z.string(), + search_space_id: z.number(), +}); + +export const logBase = log.omit({ id: true, created_at: true }); + +/** + * Create log + */ +export const createLogRequest = logBase.extend({ search_space_id: z.number() }); +export const createLogResponse = log; + +/** + * Update log + */ +export const updateLogRequest = logBase.partial(); +export const updateLogResponse = log; + +/** + * Delete log + */ +export const deleteLogRequest = z.object({ id: z.number() }); +export const deleteLogResponse = z.object({ message: z.string().default("Log deleted successfully") }); + +/** + * Get logs (list) + */ +export const logFilters = z.object({ + search_space_id: z.number().optional(), + level: logLevelEnum.optional(), + status: logStatusEnum.optional(), + source: z.string().optional(), + start_date: z.string().optional(), + end_date: z.string().optional(), +}); +export const getLogsRequest = logFilters.extend({ + skip: z.number().optional(), + limit: z.number().optional() +}); +export const getLogsResponse = z.array(log); + +/** + * Get single log + */ +export const getLogRequest = z.object({ id: z.number() }); +export const getLogResponse = log; + +/** + * Log summary (used for summary dashboard) + */ +export const logActiveTask = z.object({ + id: z.number(), + task_name: z.string(), + message: z.string(), + started_at: z.string(), + source: z.string().nullable().optional() +}); +export const logFailure = z.object({ + id: z.number(), + task_name: z.string(), + message: z.string(), + failed_at: z.string(), + source: z.string().nullable().optional(), + error_details: z.string().nullable().optional(), +}); +export const logSummary = z.object({ + total_logs: z.number(), + time_window_hours: z.number(), + by_status: z.record(z.string(), z.number()), + by_level: z.record(z.string(), z.number()), + by_source: z.record(z.string(), z.number()), + active_tasks: z.array(logActiveTask), + recent_failures: z.array(logFailure), +}); +export const getLogSummaryRequest = z.object({ + search_space_id: z.number(), + hours: z.number().optional(), +}); +export const getLogSummaryResponse = logSummary; + +/** + * Typescript types + */ +export type Log = z.infer; +export type LogLevelEnum = z.infer; +export type LogStatusEnum = z.infer; +export type LogFilters = z.infer; +export type CreateLogRequest = z.infer; +export type CreateLogResponse = z.infer; +export type UpdateLogRequest = z.infer; +export type UpdateLogResponse = z.infer; +export type DeleteLogRequest = z.infer; +export type DeleteLogResponse = z.infer; +export type GetLogsRequest = z.infer; +export type GetLogsResponse = z.infer; +export type GetLogRequest = z.infer; +export type GetLogResponse = z.infer; +export type LogSummary = z.infer; +export type LogFailure = z.infer; +export type LogActiveTask = z.infer; +export type GetLogSummaryRequest = z.infer; +export type GetLogSummaryResponse = z.infer;