/** * Hoover — schema.js * * State-store schema defaults — one module per subsystem. * * `defaults` initializes model.data so pages don't need null guards * during the first render (before the WS snapshot or HTTP fallback * delivers real data). The shapes match the daemon state store * (docs/state-model.md); the WebSocket streams these exact shapes. * * `POLL_INTERVALS` is client-side awareness of the daemon's expected * refresh cadence per subsystem (for "last updated" displays). */ export const SUBSYSTEMS = { firewall: { defaults: { config: {}, active_zones: {}, interfaces: [], available_services: [], zones: {}, rich_rules: {}, pending: {}, }, }, dnsmasq: { defaults: { config: {}, status: { service_active: false, config_file_exists: false, active_leases: 0, pending_changes: false }, leases: [], }, }, nginx: { defaults: { config: {}, domains: [], status: { pending_changes: false }, }, }, acme: { defaults: { certs: [], email: '', account: { registered: false, email: '', ca: '', key_length: null }, }, }, wireguard: { defaults: { config: {}, status: { up: false, interface: {}, peers: [], classes: {}, pending_changes: false }, peers: [], }, }, networkd: { defaults: { config: {}, interfaces: {}, status: { pending_changes: false }, }, }, system: { defaults: { load: { load1: 0, load5: 0, load15: 0 }, memory: { total: 0, available: 0, used: 0, used_pct: 0 }, swap: { total: 0, used: 0, used_pct: 0 }, traffic: {}, }, }, }; export const POLL_INTERVALS = { firewall: 30, wireguard: 10, dnsmasq: 10, networkd: 10, system: 1, // Phase 5: 30 → 1 (real-time metrics) nginx: 60, // matches _DEFAULT_POLL_INTERVALS (config-drift self-heal) acme: 300, // matches _DEFAULT_POLL_INTERVALS (config-drift self-heal) };