import { z } from 'zod' export const agentPlatformSchema = z.enum(['linux', 'mikrotik']) export const agentStatusSchema = z.enum([ 'invited', 'pending', 'approved', 'revoked', ]) export const policyModeSchema = z.enum(['blacklist', 'whitelist']) export const policyActionSchema = z.enum(['allow', 'deny']) export const ipListTypeSchema = z.enum([ 'static', 'json_url', 'domains', 'evobgp_community', ]) export const agentSchema = z.object({ id: z.string(), name: z.string(), hostname: z.string().nullable().optional(), platform: agentPlatformSchema, token_prefix: z.string(), status: agentStatusSchema, policy_mode: policyModeSchema, policy_generation: z.number().int(), last_seen_at: z.string().nullable().optional(), last_seen_ip: z.string().nullable().optional(), last_apply_at: z.string().nullable().optional(), last_apply_status: z.string().nullable().optional(), last_apply_error: z.string().nullable().optional(), last_apply_prefix_count: z.number().int().nullable().optional(), last_apply_packets_dropped: z.number().int().optional(), last_apply_packets_accepted: z.number().int().optional(), last_apply_kernel_method: z.string().nullable().optional(), client_version: z.string().nullable().optional(), settings_json: z.string().optional(), created_at: z.string(), approved_at: z.string().nullable().optional(), revoked_at: z.string().nullable().optional(), install_curl: z.string().nullable().optional(), install_link_id: z.string().nullable().optional(), }) export const ipListSchema = z.object({ id: z.string(), name: z.string(), type: ipListTypeSchema, config_json: z.string(), content_hash: z.string().nullable().optional(), refreshed_at: z.string().nullable().optional(), last_error: z.string().nullable().optional(), entry_count: z.number().int().optional(), created_at: z.string(), updated_at: z.string(), }) export const policyRuleSchema = z.object({ id: z.string(), set_id: z.string(), priority: z.number().int(), action: policyActionSchema, enabled: z.boolean().optional().default(true), list_id: z.string().nullable().optional(), cidr: z.string().nullable().optional(), hostname: z.string().nullable().optional(), resolved_count: z.number().int().optional(), comment: z.string().nullable().optional(), created_at: z.string(), updated_at: z.string(), }) export const policySetSchema = z.object({ id: z.string(), name: z.string(), description: z.string().nullable().optional(), enabled: z.boolean(), policy_mode: policyModeSchema, rules_count: z.number().int().optional(), agents_count: z.number().int().optional(), created_at: z.string(), updated_at: z.string(), }) export const ipOverrideSchema = z.object({ id: z.string(), agent_id: z.string(), cidr: z.string(), action: policyActionSchema, comment: z.string().nullable().optional(), created_at: z.string(), }) export const createIpListBodySchema = z.object({ name: z.string().min(1), /** Prefer static | json_url | evobgp_community; domains accepted for legacy. */ type: ipListTypeSchema, config: z.record(z.string(), z.unknown()).optional(), entries: z.array(z.string()).optional(), }) export const createPolicySetBodySchema = z.object({ name: z.string().min(1), description: z.string().nullable().optional(), enabled: z.boolean().optional().default(true), policy_mode: policyModeSchema.optional().default('blacklist'), }) export const patchPolicySetBodySchema = z.object({ name: z.string().min(1).optional(), description: z.string().nullable().optional(), enabled: z.boolean().optional(), policy_mode: policyModeSchema.optional(), }) export const createPolicyRuleBodySchema = z .object({ set_id: z.string().min(1), priority: z.number().int().min(1).max(10000).optional(), action: policyActionSchema, enabled: z.boolean().optional().default(true), list_id: z.string().nullable().optional(), cidr: z.string().nullable().optional(), hostname: z.string().nullable().optional(), comment: z.string().nullable().optional(), }) .superRefine((v, ctx) => { const sources = [v.list_id, v.cidr, v.hostname].filter( (x) => typeof x === 'string' && x.trim().length > 0, ) if (sources.length !== 1) { ctx.addIssue({ code: 'custom', message: 'Укажите ровно один источник: list_id, cidr или hostname', }) } }) export const patchPolicyRuleBodySchema = z.object({ enabled: z.boolean().optional(), action: policyActionSchema.optional(), comment: z.string().nullable().optional(), priority: z.number().int().min(1).max(10000).optional(), }) export const reorderPolicyRulesBodySchema = z.object({ ordered_ids: z.array(z.string()).min(1), }) export const putAgentPolicySetsBodySchema = z.object({ set_ids: z.array(z.string()), }) export const createOverrideBodySchema = z.object({ cidr: z.string().min(1), action: policyActionSchema, comment: z.string().nullable().optional(), }) export const patchAgentBodySchema = z.object({ name: z.string().min(1).optional(), policy_mode: policyModeSchema.optional(), settings: z.record(z.string(), z.unknown()).optional(), }) export const cloneFromBodySchema = z.object({ include_overrides: z.boolean().optional().default(false), }) export const enrollBodySchema = z.object({ name: z.string().min(1), hostname: z.string().optional(), platform: agentPlatformSchema.optional().default('linux'), token: z.string().min(16), client_version: z.string().optional(), install_link_id: z.string().optional(), }) export const applyReportBodySchema = z.object({ status: z.string(), prefix_count: z.number().int().optional(), packets_dropped: z.number().int().optional(), packets_accepted: z.number().int().optional(), kernel_method: z.string().optional(), error: z.string().optional(), source: z.string().optional(), }) export const agentPolicySchema = z.object({ generation: z.number().int(), hash: z.string(), policy_mode: policyModeSchema, deny_cidrs: z.array(z.string()), allow_cidrs: z.array(z.string()), sync_interval_sec: z.number().int(), }) export const dashboardStatsSchema = z.object({ agents_total: z.number().int(), agents_approved: z.number().int(), agents_online: z.number().int(), agents_pending: z.number().int(), packets_dropped: z.number().int(), packets_accepted: z.number().int(), lists_total: z.number().int(), }) export const createInstallLinkBodySchema = z.object({ name: z.string().min(1), platform: agentPlatformSchema.optional().default('linux'), }) export const installLinkSchema = z.object({ id: z.string(), slug: z.string(), client_name: z.string(), platform: agentPlatformSchema, agent_id: z.string().nullable().optional(), created_at: z.string(), revoked_at: z.string().nullable().optional(), last_used_at: z.string().nullable().optional(), use_count: z.number().int(), urls: z .object({ by_id: z.string(), by_slug: z.string(), }) .optional(), curl: z .object({ by_id: z.string(), by_slug: z.string(), }) .optional(), }) export type Agent = z.infer export type IpList = z.infer export type PolicyRule = z.infer export type PolicySet = z.infer export type IpOverride = z.infer export type AgentPolicy = z.infer export type DashboardStats = z.infer export type InstallLink = z.infer