import { z } from "zod" export const logLevels = ["critical", "error", "warning", "info", "debug", "unknown"] as const export const logLevelSchema = z.enum(logLevels) export type LogLevel = z.infer const id = z.string().regex(/^\d+$/) const instant = z.string().datetime({ offset: true }) export const logEntrySchema = z.object({ id, serverId: z.number().int(), serverName: z.string(), host: z.string(), routerId: z.string(), rawTime: z.string(), eventAt: instant.nullable(), receivedAt: instant, effectiveAt: instant, timeKind: z.enum(["router", "receipt"]), topics: z.array(z.string()), level: logLevelSchema, message: z.string(), generation: z.number().int(), }) export type LogEntry = z.infer export const logFiltersSchema = z.object({ serverId: z.coerce.number().int().positive().optional(), from: instant.default(() => new Date(Date.now() - 900000).toISOString()), to: instant.optional(), levels: z.string().max(100).default("").refine(v => !v || v.split(",").every(x => (logLevels as readonly string[]).includes(x))), topics: z.string().max(500).default(""), q: z.string().max(500).default(""), preset: z.enum(["", "login-failure", "interfaces", "routing", "firewall"]).default(""), }).refine(v => !v.from || !v.to || Date.parse(v.from) <= Date.parse(v.to), "Некорректный период") export type LogFilters = z.infer export const logPageQuerySchema = logFiltersSchema.safeExtend({ cursor: z.string().max(200).optional(), watermark: id.optional(), limit: z.coerce.number().int().min(1).max(200).default(200), }) export const logStateSchema = z.object({ serverId: z.number().int(), serverName: z.string(), host: z.string(), lastCollectedAt: instant.nullable(), lastError: z.string().nullable(), gapAt: instant.nullable(), nextPollAt: instant.nullable(), failures: z.number().int(), generation: z.number().int() }) export const logPageSchema = z.object({ entries: z.array(logEntrySchema), nextCursor: z.string().nullable(), watermark: id }) export type LogPage = z.infer export const logSettingsSchema = z.object({ enabled: z.boolean(), intervalSec: z.number().int().min(5).max(3600), retentionDays: z.number().int().min(1).max(365) }) export type LogSettings = z.infer export const logSettingsPatchSchema = logSettingsSchema.partial().strict().refine(v => Object.keys(v).length > 0) export const logSummarySchema = z.object({ total: z.number(), levels: z.record(logLevelSchema, z.number()), buckets: z.array(z.object({ at: instant, critical: z.number(), error: z.number(), warning: z.number(), info: z.number(), debug: z.number(), unknown: z.number() })), settings: logSettingsSchema, states: z.array(logStateSchema) }) export type LogSummary = z.infer export const logStreamSchema = z.object({ entries: z.array(logEntrySchema), cursor: id, state: logStateSchema.nullable(), enabled: z.boolean() }) export type LogStream = z.infer export type LogStreamReset = { reason: "database-maintenance" }