"""A UniFi Access device (reader / hub / lock)."""
type AccessDevice {
  id: ID
  name: String
  type: String
  isOnline: Boolean
  firmwareVersion: String
  location: String
}

"""Paginated page of UniFi Access devices."""
type AccessDevicePage {
  items: [AccessDevice!]!
  nextCursor: String
}

"""A UniFi Access event row (list + detail share this shape)."""
type AccessEvent {
  id: ID
  type: String
  timestamp: String
  doorId: String
  userId: String
  credentialId: String
  result: String

  """The door this event references."""
  door: Door

  """The user this event references."""
  user: User
}

"""Paginated page of UniFi Access events."""
type AccessEventPage {
  items: [AccessEvent!]!
  nextCursor: String
}

"""UniFi Access health probe summary."""
type AccessHealth {
  status: String!
  numDoors: Int
  numDevices: Int
  numOfflineDevices: Int
}

"""Read-only access to UniFi Access resources."""
type AccessQuery {
  """List doors on the Access controller (paginated)."""
  doors(controller: ID!, limit: Int! = 50, cursor: String = null): DoorPage!

  """Look up a single Access door by id."""
  door(controller: ID!, id: ID!): Door

  """List Access door groups (paginated)."""
  doorGroups(controller: ID!, limit: Int! = 50, cursor: String = null): DoorGroupPage!

  """Get the live status (lock state + last event) of a door."""
  doorStatus(controller: ID!, id: ID!): DoorStatus

  """List Access devices (readers / hubs / locks, paginated)."""
  devices(controller: ID!, limit: Int! = 50, cursor: String = null): AccessDevicePage!

  """Look up a single Access device by id."""
  device(controller: ID!, id: ID!): AccessDevice

  """List Access users (employees / cardholders, paginated)."""
  users(controller: ID!, limit: Int! = 50, cursor: String = null): UserPage!

  """List Access credentials (NFC / PIN / etc., paginated)."""
  credentials(controller: ID!, limit: Int! = 50, cursor: String = null): CredentialPage!

  """Look up a single Access credential by id."""
  credential(controller: ID!, id: ID!): Credential

  """List Access policies (who-can-access-what bindings)."""
  policies(controller: ID!, limit: Int! = 50, cursor: String = null): PolicyPage!

  """Look up a single Access policy by id."""
  policy(controller: ID!, id: ID!): Policy

  """List Access schedules (weekly access windows)."""
  schedules(controller: ID!, limit: Int! = 50, cursor: String = null): SchedulePage!

  """List Access visitors (time-bounded guest passes)."""
  visitors(controller: ID!, limit: Int! = 50, cursor: String = null): VisitorPage!

  """Look up a single Access visitor by id."""
  visitor(controller: ID!, id: ID!): Visitor

  """List Access events (paginated, most recent first)."""
  events(controller: ID!, limit: Int! = 50, cursor: String = null): AccessEventPage!

  """Look up a single Access event by id."""
  event(controller: ID!, id: ID!): AccessEvent

  """Get the access activity histogram summary."""
  activitySummary(controller: ID!, doorId: String = null, days: Int! = 7): ActivitySummary

  """Get the Access application info (name + version + host)."""
  systemInfo(controller: ID!): AccessSystemInfo

  """Get the Access health probe summary."""
  health(controller: ID!): AccessHealth
}

"""UniFi Access application info (name + version + host)."""
type AccessSystemInfo {
  name: String
  version: String
  hostname: String
  uptime: Int
}

"""A MAC ACL rule (V2 /acl-rules entry)."""
type AclRule {
  id: ID
  name: String
  enabled: Boolean!
  action: String
  aclIndex: Int
  networkId: String
  sourceType: String
  destinationType: String
  sourceMacs: [String!]!
  destinationMacs: [String!]!
}

"""Paginated page of ACL rules."""
type AclRulePage {
  items: [AclRule!]!
  nextCursor: String
}

"""An active kernel routing-table entry on a gateway."""
type ActiveRoute {
  targetSubnet: String
  gateway: String
  interface: String
  distance: Int
}

"""Paginated page of active kernel routes."""
type ActiveRoutePage {
  items: [ActiveRoute!]!
  nextCursor: String
}

"""Access activity histogram summary."""
type ActivitySummary {
  periodStart: String
  periodEnd: String
  totalEvents: Int
  grantedCount: Int
  deniedCount: Int
  topUsers: JSON
  buckets: JSON
}

"""A controller alarm (V1 /list/alarm entry)."""
type Alarm {
  id: ID
  key: String
  msg: String
  archived: Boolean!
  time: Int
}

"""Paginated page of controller alarms."""
type AlarmPage {
  items: [Alarm!]!
  nextCursor: String
}

"""Wrapper for protect_alarm_list_profiles — {profiles, count}."""
type AlarmProfileList {
  profiles: JSON
  count: Int
}

"""UniFi Protect alarm system arm-state snapshot."""
type AlarmStatus {
  armed: Boolean
  status: String
  activeProfileId: String
  activeProfileName: String
  armedAt: String
  willBeArmedAt: String
  breachDetectedAt: String
  breachEventCount: Int
  profileCount: Int
}

"""A UniFi AP group (collection of AP MAC addresses)."""
type ApGroup {
  id: ID
  name: String
  apCount: Int!
  deviceMacs: [String!]!
  wlanGroupIds: [String!]!
}

"""Paginated page of AP groups."""
type ApGroupPage {
  items: [ApGroup!]!
  nextCursor: String
}

"""Auto-backup schedule + retention settings."""
type AutoBackupSettings {
  enabled: Boolean!
  schedule: String
  maxCount: Int
  autobackupEnabled: Boolean
  autobackupCronExpr: String
  autobackupDays: Int
  autobackupMaxFiles: Int
  autobackupTimezone: String
  autobackupCloudEnabled: Boolean
}

"""A wireless channel allowed by the regulatory domain."""
type AvailableChannel {
  channel: Int
  frequencyMhz: Int
  widthMhz: Int
  allowed: Boolean!
}

"""A controller backup file metadata record."""
type Backup {
  id: ID
  filename: String
  size: Int
  createdAt: Int
}

"""Paginated page of controller backup descriptors."""
type BackupPage {
  items: [Backup!]!
  nextCursor: String
}

"""A client currently blocked on the UniFi Network controller."""
type BlockedClient {
  mac: ID
  hostname: String
  lastSeen: String
  blocked: Boolean!
}

"""Paginated page of blocked clients."""
type BlockedClientPage {
  items: [BlockedClient!]!
  nextCursor: String
}

"""A UniFi Protect camera (list + detail shape)."""
type Camera {
  id: ID
  mac: String
  name: String
  model: String
  type: String
  state: String
  isRecording: Boolean
  isMotionDetected: Boolean
  isSmartDetected: Boolean
  host: String
  channels: JSON
  irLedMode: String
  hdrMode: String
  micEnabled: Boolean
  micVolume: Int
  statusLightOn: Boolean
  speakerVolume: Int
  motionDetection: Boolean

  """Events generated by this camera."""
  events: [Event!]!

  """Recordings from this camera."""
  recordings: [Recording!]!
}

"""Analytics summary for a Protect camera."""
type CameraAnalytics {
  cameraId: ID
  cameraName: String
  detections: JSON
  smartDetects: JSON
  smartAudioDetects: JSON
  currentlyDetected: JSON
  motionZoneCount: Int!
  smartDetectZoneCount: Int!
  stats: JSON
}

"""Paginated page of UniFi Protect cameras."""
type CameraPage {
  items: [Camera!]!
  nextCursor: String
}

"""Stream catalog for a Protect camera (channels + RTSPS URLs)."""
type CameraStreams {
  cameraId: ID
  cameraName: String
  channels: JSON
  rtspsStreams: JSON
}

"""A UniFi Protect chime (paired-camera doorbell ringer)."""
type Chime {
  id: ID
  mac: String
  name: String
  model: String
  type: String
  state: String
  isConnected: Boolean
  firmwareVersion: String
  volume: Int
  repeatTimes: Int
  pairedCameras: [String!]!
  ringSettings: JSON
  availableTracks: JSON
}

"""Paginated page of UniFi Protect chimes."""
type ChimePage {
  items: [Chime!]!
  nextCursor: String
}

"""A client device on the UniFi Network controller."""
type Client {
  mac: ID
  ip: String
  hostname: String
  isWired: Boolean!
  isGuest: Boolean!
  status: String!
  lastSeen: String
  firstSeen: String
  note: String
  usergroupId: String

  """The AP or switch this client connects through."""
  device: Device
}

"""A network member client group (V2 /network-members-group entry)."""
type ClientGroup {
  id: ID
  name: String
  qosRateMaxDown: Int
  qosRateMaxUp: Int
  members: [String!]!
}

"""Paginated page of network member client groups."""
type ClientGroupPage {
  items: [ClientGroup!]!
  nextCursor: String
}

"""Result of a by-IP client lookup — online presence + last seen."""
type ClientLookup {
  mac: ID
  ip: String
  hostname: String
  isOnline: Boolean!
  lastSeen: String
}

"""Paginated page of clients."""
type ClientPage {
  items: [Client!]!
  nextCursor: String
}

"""A client association session entry."""
type ClientSession {
  mac: String
  hostname: String
  ap: String
  ssid: String
  connectedAt: Int
  disconnectedAt: Int
  duration: Int
}

"""Paginated page of client association sessions."""
type ClientSessionPage {
  items: [ClientSession!]!
  nextCursor: String
}

"""Current WiFi parameters for a client."""
type ClientWifiDetails {
  mac: String
  ssid: String
  ap: String
  signal: Int
  txRate: Int
  rxRate: Int
  channel: Int
}

"""A content-filtering profile (V2 /content-filtering entry)."""
type ContentFilter {
  id: ID
  name: String
  enabled: Boolean!
  profile: String
  appliesTo: JSON!
  blockedCategories: [String!]!
  safeSearch: [String!]!
  clientMacs: [String!]!
  networkIds: [String!]!
  scheduleMode: String
}

"""Paginated page of content filters."""
type ContentFilterPage {
  items: [ContentFilter!]!
  nextCursor: String
}

"""A UniFi Access credential (NFC, PIN, etc.)."""
type Credential {
  id: ID
  userId: String
  type: String
  status: String
  expiry: String
  lastUsed: String
  token: String
  pinCode: String
}

"""Paginated page of UniFi Access credentials."""
type CredentialPage {
  items: [Credential!]!
  nextCursor: String
}

"""A UniFi network device (AP, switch, gateway)."""
type Device {
  mac: ID
  name: String
  model: String
  type: String
  version: String
  uptime: Int
  state: String
  ip: String
  ports: JSON

  """Clients currently connected through this AP/switch."""
  portClients: [Client!]!
}

"""Paginated page of devices."""
type DevicePage {
  items: [Device!]!
  nextCursor: String
}

"""Wrapper dict containing the radio table for a device."""
type DeviceRadio {
  mac: ID
  name: String
  model: String
  radios: [RadioEntry!]!
  txPowerMode: String
  txPower: Int
  channel: Int
  ht: String
  minRssiEnabled: Boolean
  minRssi: Int
  assistedRoamingEnabled: Boolean
  antennaGain: Int
  vwireEnabled: Boolean
  sensLevelEnabled: Boolean
  sensLevel: Int
}

"""A static DNS record served by the controller."""
type DnsRecord {
  id: ID
  hostname: String
  ip: String
  type: String
  ttl: Int
  enabled: Boolean!
  key: String
  value: String
  recordType: String
  port: Int
  priority: Int
  weight: Int
}

"""Paginated page of DNS records."""
type DnsRecordPage {
  items: [DnsRecord!]!
  nextCursor: String
}

"""A UniFi Access door (list + detail shape)."""
type Door {
  id: ID
  name: String
  location: String
  isOnline: Boolean
  isLocked: Boolean
  lockState: String
  lastEvent: JSON

  """Policies assigned to this door."""
  policyAssignments: [Policy!]!
}

"""A UniFi Access door group (list of doors)."""
type DoorGroup {
  id: ID
  name: String
  doorIds: [String!]!
  location: String
}

"""Paginated page of UniFi Access door groups."""
type DoorGroupPage {
  items: [DoorGroup!]!
  nextCursor: String
}

"""Paginated page of UniFi Access doors."""
type DoorPage {
  items: [Door!]!
  nextCursor: String
}

"""Per-door live status (lock state + last event)."""
type DoorStatus {
  doorId: ID
  name: String
  isLocked: Boolean
  lockState: String
  doorPositionStatus: String
  lastEventAt: String
  lastEventType: String
}

"""A DPI application classification entry."""
type DpiApplication {
  id: Int
  name: String
  categoryId: Int
}

"""Paginated page of DPI applications."""
type DpiApplicationPage {
  items: [DpiApplication!]!
  nextCursor: String
}

"""A DPI application category."""
type DpiCategory {
  id: Int
  name: String
}

"""Paginated page of DPI categories."""
type DpiCategoryPage {
  items: [DpiCategory!]!
  nextCursor: String
}

"""DPI stats wrapper: applications + categories arrays."""
type DpiStats {
  applications: JSON!
  categories: JSON!
}

"""A UniFi Protect event row (list + detail share this shape)."""
type Event {
  id: ID
  type: String
  start: String
  end: String
  score: Int
  smartDetectTypes: [String!]!
  camera: ID
  thumbnail: ID
  recognizedPersonId: ID
  recognizedPersonName: String
  recognizedPersonConfidence: Int
  detectedThumbnailId: ID
}

"""A curated event-log entry."""
type EventLog {
  id: ID
  key: String
  msg: String
  time: Int
  mac: String
  ip: String
  severity: String
}

"""Paginated page of event-log entries."""
type EventLogPage {
  items: [EventLog!]!
  nextCursor: String
}

"""Paginated page of UniFi Protect events."""
type EventPage {
  items: [Event!]!
  nextCursor: String
}

"""Thumbnail metadata for a Protect event."""
type EventThumbnail {
  eventId: ID
  thumbnailId: ID
  thumbnailAvailable: Boolean
  imageBase64: String
  contentType: String
  message: String
  url: String
  sizeBytes: Int
}

"""Wrapper for event-type prefix descriptors."""
type EventTypes {
  eventTypes: JSON!
}

"""A firewall address/port group (V1 /rest/firewallgroup)."""
type FirewallGroup {
  id: ID
  name: String
  groupType: String
  members: [String!]!
}

"""Paginated page of firewall groups."""
type FirewallGroupPage {
  items: [FirewallGroup!]!
  nextCursor: String
}

"""A firewall policy rule."""
type FirewallRule {
  id: ID
  name: String
  action: String
  enabled: Boolean!
  predefined: Boolean!
  source: JSON
  destination: JSON
  index: Int
  protocol: String
  ipVersion: String
  connectionStateType: String
  connectionStates: [String!]!
  createAllowRespond: Boolean
  matchIpSec: Boolean
  matchOppositeProtocol: Boolean
  icmpTypename: String
  icmpV6Typename: String
  schedule: JSON
  logging: Boolean
}

"""Paginated page of firewall policies/rules."""
type FirewallRulePage {
  items: [FirewallRule!]!
  nextCursor: String
}

"""A firewall zone (V2 /firewall/zone-matrix entry)."""
type FirewallZone {
  id: ID
  name: String
  networks: JSON!
  defaultPolicy: String
}

"""Firmware status for the NVR plus its devices."""
type FirmwareStatus {
  nvr: JSON
  devices: JSON
  totalDevices: Int
  devicesWithUpdates: Int
}

"""Service health snapshot — smoke field for the GraphQL endpoint."""
type HealthSnapshot {
  ok: Boolean!
  version: String!
  pythonVersion: String!
}

"""
The `JSON` scalar type represents JSON values as specified by [ECMA-404](https://ecma-international.org/wp-content/uploads/ECMA-404_2nd_edition_december_2017.pdf).
"""
scalar JSON @specifiedBy(url: "https://ecma-international.org/wp-content/uploads/ECMA-404_2nd_edition_december_2017.pdf")

"""A UniFi Protect Known Face / assigned face recognition group."""
type KnownFace {
  id: ID
  name: String
  matchedName: String
  type: String
  imagePath: String
  enhancedPath: String
  detectionsCount: Int
  firstDetectedAt: String
  lastDetectedAt: String
  isNotificationEnabled: Boolean
  isDegraded: Boolean
  tags: JSON
  description: String
  createdAt: String
  metadata: JSON
}

"""Paginated page of UniFi Protect Known Faces."""
type KnownFacePage {
  items: [KnownFace!]!
  nextCursor: String
}

"""A UniFi Protect light (PIR-triggered floodlight)."""
type Light {
  id: ID
  mac: String
  name: String
  model: String
  state: String
  isPirMotionDetected: Boolean
  isLightOn: Boolean
  ledLevel: Int
  sensitivity: Int
  durationSeconds: Int
  statusLight: Boolean
}

"""Paginated page of UniFi Protect lights."""
type LightPage {
  items: [Light!]!
  nextCursor: String
}

"""A UniFi Protect liveview (multi-camera grid layout)."""
type Liveview {
  id: ID
  name: String
  layout: Int
  isDefault: Boolean
  isGlobal: Boolean
  ownerId: String
  cameras: [String!]!
  slots: JSON
  slotCount: Int
  cameraCount: Int

  """Cameras included in this liveview's slots."""
  cameraDetails: [Camera!]!
}

"""Paginated page of UniFi Protect liveviews."""
type LiveviewPage {
  items: [Liveview!]!
  nextCursor: String
}

"""Wrapper dict containing LLDP neighbors for a switch."""
type LldpNeighbors {
  name: String
  model: String
  lldpTable: [LldpRow!]!
}

"""A single LLDP neighbor row reported by a switch."""
type LldpRow {
  localPortIdx: Int
  chassisId: String
  portId: String
  systemName: String
  capabilities: [String!]!
}

"""A UniFi LAN/VLAN network configuration."""
type Network {
  id: ID
  name: String
  purpose: String
  enabled: Boolean!
  vlanEnabled: Boolean
  vlan: String
  ipSubnet: String
  subnet: String
  domainName: String
  dhcpdEnabled: Boolean
  dhcpdStart: String
  dhcpdStop: String
  dhcpdLeasetime: Int
  dhcpdGateway: String
  dhcpdGatewayEnabled: Boolean
  dhcpdDns1: String
  dhcpdDns2: String
  dhcpdDnsEnabled: Boolean
  dhcpdNtp1: String
  dhcpdNtp2: String
  dhcpdNtpEnabled: Boolean
  dhcpdWins1: String
  dhcpdWins2: String
  dhcpdWinsEnabled: Boolean
  dhcpdUnifiController: String
  dhcpdTftpServer: String
  dhcpdBootServer: String
  dhcpdBootFilename: String
  dhcpdBootEnabled: Boolean
  dhcpdConflictChecking: Boolean
  dhcpRelayEnabled: Boolean
  dhcpdIp1: String
  dhcpguardEnabled: Boolean
  igmpSnooping: Boolean
  igmpQuerierSwitches: JSON
  igmpFloodUnknownMulticast: Boolean
  mdnsEnabled: Boolean
  networkIsolationEnabled: Boolean
  internetAccessEnabled: Boolean
  upnpLanEnabled: Boolean

  """Clients on this network."""
  clients: [Client!]!
}

"""A network-health subsystem entry."""
type NetworkHealth {
  subsystem: String
  status: String
  numUser: Int
  numGuest: Int
  numIot: Int
  rxBytes: Int
  txBytes: Int
}

"""Paginated page of network configurations."""
type NetworkPage {
  items: [Network!]!
  nextCursor: String
}

"""Read-only access to UniFi Network resources."""
type NetworkQuery {
  """List clients on the given controller/site (paginated)."""
  clients(controller: ID!, site: String! = "default", limit: Int! = 50, cursor: String = null): ClientPage!

  """Look up a single client by MAC address."""
  client(controller: ID!, mac: ID!, site: String! = "default"): Client

  """List clients currently blocked from the network (paginated)."""
  blockedClients(controller: ID!, site: String! = "default", limit: Int! = 50, cursor: String = null): BlockedClientPage!

  """Look up a client by IP address (online-presence check)."""
  clientByIp(controller: ID!, ip: String!, site: String! = "default"): ClientLookup

  """List devices on the given controller/site (paginated)."""
  devices(controller: ID!, site: String! = "default", limit: Int! = 50, cursor: String = null): DevicePage!

  """Look up a single device by MAC address."""
  device(controller: ID!, mac: ID!, site: String! = "default"): Device

  """Get the radio configuration for a UniFi access point."""
  deviceRadio(controller: ID!, mac: ID!, site: String! = "default"): DeviceRadio

  """Get LLDP neighbors reported by a switch."""
  lldpNeighbors(controller: ID!, deviceMac: ID!, site: String! = "default"): LldpNeighbors

  """Get per-outlet state for a UniFi Smart Power PDU (UP6 / USP-Strip)."""
  pduOutlets(controller: ID!, mac: ID!, site: String! = "default"): PduOutlets

  """List rogue (unknown) APs detected within a window (paginated)."""
  rogueAps(controller: ID!, site: String! = "default", withinHours: Int! = 24, limit: Int! = 50, cursor: String = null): RogueApPage!

  """List RF-scan results for a specific access point."""
  rfScanResults(controller: ID!, apMac: ID!, site: String! = "default"): [RfScanResult!]!

  """List wireless channels allowed by the regulatory domain."""
  availableChannels(controller: ID!, site: String! = "default"): [AvailableChannel!]!

  """Get the gateway speedtest status (idle/running + last results)."""
  speedtestStatus(controller: ID!, gatewayMac: ID!, site: String! = "default"): SpeedtestStatus

  """
  List configured LAN/VLAN networks on the given controller/site (paginated).
  """
  networks(controller: ID!, site: String! = "default", limit: Int! = 50, cursor: String = null): NetworkPage!

  """
  Look up a single LAN/VLAN network by id. (Named ``networkDetail`` because ``network`` is reserved for the namespace.)
  """
  networkDetail(controller: ID!, id: ID!, site: String! = "default"): Network

  """Get the controller's network-health subsystems list."""
  networkHealth(controller: ID!, site: String! = "default"): [NetworkHealth!]!

  """
  List WLAN/SSID configurations on the given controller/site (paginated).
  """
  wlans(controller: ID!, site: String! = "default", limit: Int! = 50, cursor: String = null): WlanPage!

  """Look up a single WLAN/SSID by id."""
  wlan(controller: ID!, id: ID!, site: String! = "default"): Wlan

  """List configured VPN clients (outbound tunnels) (paginated)."""
  vpnClients(controller: ID!, site: String! = "default", limit: Int! = 50, cursor: String = null): VpnClientPage!

  """Look up a single VPN client by id."""
  vpnClient(controller: ID!, id: ID!, site: String! = "default"): VpnClient

  """List configured VPN servers (inbound tunnels) (paginated)."""
  vpnServers(controller: ID!, site: String! = "default", limit: Int! = 50, cursor: String = null): VpnServerPage!

  """Look up a single VPN server by id."""
  vpnServer(controller: ID!, id: ID!, site: String! = "default"): VpnServer

  """List static DNS records on the given controller/site (paginated)."""
  dnsRecords(controller: ID!, site: String! = "default", limit: Int! = 50, cursor: String = null): DnsRecordPage!

  """Look up a single DNS record by id."""
  dnsRecord(controller: ID!, id: ID!, site: String! = "default"): DnsRecord

  """List configured static routes (paginated)."""
  routes(controller: ID!, site: String! = "default", limit: Int! = 50, cursor: String = null): RoutePage!

  """Look up a single static route by id."""
  route(controller: ID!, id: ID!, site: String! = "default"): Route

  """List the gateway's active kernel routing-table entries (paginated)."""
  activeRoutes(controller: ID!, site: String! = "default", limit: Int! = 50, cursor: String = null): ActiveRoutePage!

  """List traffic-route policies (V2 /trafficroutes) (paginated)."""
  trafficRoutes(controller: ID!, site: String! = "default", limit: Int! = 50, cursor: String = null): TrafficRoutePage!

  """Look up a single traffic-route policy by id."""
  trafficRoute(controller: ID!, id: ID!, site: String! = "default"): TrafficRoute

  """List firewall policies/rules on the given controller/site (paginated)."""
  firewallPolicies(controller: ID!, site: String! = "default", limit: Int! = 50, cursor: String = null): FirewallRulePage!

  """Look up a single firewall policy/rule by id."""
  firewallPolicy(controller: ID!, id: ID!, site: String! = "default"): FirewallRule

  """List firewall address/port groups (paginated)."""
  firewallGroups(controller: ID!, site: String! = "default", limit: Int! = 50, cursor: String = null): FirewallGroupPage!

  """Look up a single firewall group by id."""
  firewallGroup(controller: ID!, id: ID!, site: String! = "default"): FirewallGroup

  """List firewall zones (typically a small flat list — no pagination)."""
  firewallZones(controller: ID!, site: String! = "default"): [FirewallZone!]!

  """List QoS rules on the given controller/site (paginated)."""
  qosRules(controller: ID!, site: String! = "default", limit: Int! = 50, cursor: String = null): QosRulePage!

  """Look up a single QoS rule by id."""
  qosRule(controller: ID!, id: ID!, site: String! = "default"): QosRule

  """List DPI applications (paginated)."""
  dpiApplications(controller: ID!, site: String! = "default", limit: Int! = 50, cursor: String = null): DpiApplicationPage!

  """List DPI categories (paginated)."""
  dpiCategories(controller: ID!, site: String! = "default", limit: Int! = 50, cursor: String = null): DpiCategoryPage!

  """List content filters on the given controller/site (paginated)."""
  contentFilters(controller: ID!, site: String! = "default", limit: Int! = 50, cursor: String = null): ContentFilterPage!

  """Look up a single content filter by id."""
  contentFilter(controller: ID!, id: ID!, site: String! = "default"): ContentFilter

  """List ACL rules on the given controller/site (paginated)."""
  aclRules(controller: ID!, site: String! = "default", limit: Int! = 50, cursor: String = null): AclRulePage!

  """Look up a single ACL rule by id."""
  aclRule(controller: ID!, id: ID!, site: String! = "default"): AclRule

  """List OON (out-of-network) policies (paginated)."""
  oonPolicies(controller: ID!, site: String! = "default", limit: Int! = 50, cursor: String = null): OonPolicyPage!

  """Look up a single OON policy by id."""
  oonPolicy(controller: ID!, id: ID!, site: String! = "default"): OonPolicy

  """List port forwards on the given controller/site (paginated)."""
  portForwards(controller: ID!, site: String! = "default", limit: Int! = 50, cursor: String = null): PortForwardPage!

  """Look up a single port forward by id."""
  portForward(controller: ID!, id: ID!, site: String! = "default"): PortForward

  """Site dashboard timeseries (all-points)."""
  dashboardStats(controller: ID!, site: String! = "default", durationHours: Int! = 1): [StatPoint!]!

  """Network-wide stats timeseries."""
  networkStats(controller: ID!, site: String! = "default", durationHours: Int! = 1): [StatPoint!]!

  """Gateway stats timeseries."""
  gatewayStats(controller: ID!, site: String! = "default", durationHours: Int! = 24): [StatPoint!]!

  """Per-client stats timeseries (by MAC)."""
  clientStats(controller: ID!, mac: ID!, site: String! = "default", durationHours: Int! = 1): [StatPoint!]!

  """Per-device stats timeseries (by MAC)."""
  deviceStats(controller: ID!, mac: ID!, site: String! = "default", durationHours: Int! = 1): [StatPoint!]!

  """Per-client DPI traffic breakdown."""
  clientDpiTraffic(controller: ID!, mac: ID!, site: String! = "default"): [StatPoint!]!

  """Site-wide DPI traffic breakdown."""
  siteDpiTraffic(controller: ID!, site: String! = "default"): [StatPoint!]!

  """DPI stats catalog (applications + categories)."""
  dpiStats(controller: ID!, site: String! = "default"): DpiStats

  """List recent controller events (paginated)."""
  eventLog(controller: ID!, site: String! = "default", limit: Int! = 50, cursor: String = null): EventLogPage!

  """List active alerts (paginated)."""
  alerts(controller: ID!, site: String! = "default", limit: Int! = 50, cursor: String = null): EventLogPage!

  """List recent anomalies (paginated)."""
  anomalies(controller: ID!, site: String! = "default", limit: Int! = 50, cursor: String = null): EventLogPage!

  """List recent IPS/IDS events (paginated)."""
  ipsEvents(controller: ID!, site: String! = "default", limit: Int! = 50, cursor: String = null): EventLogPage!

  """List controller alarms (paginated)."""
  alarms(controller: ID!, site: String! = "default", limit: Int! = 50, cursor: String = null): AlarmPage!

  """Get controller system info (build, uptime, hardware)."""
  systemInfo(controller: ID!, site: String! = "default"): SystemInfo

  """Get site-level settings (locale, timezone, advanced)."""
  siteSettings(controller: ID!, site: String! = "default"): SiteSettings

  """Get SNMP settings."""
  snmpSettings(controller: ID!, site: String! = "default"): SnmpSettings

  """Get the controller's event-type prefix catalog."""
  eventTypes(controller: ID!, site: String! = "default"): EventTypes

  """Get auto-backup schedule + retention settings."""
  autobackupSettings(controller: ID!, site: String! = "default"): AutoBackupSettings

  """List controller backups (paginated)."""
  backups(controller: ID!, site: String! = "default", limit: Int! = 50, cursor: String = null): BackupPage!

  """List recent speedtest results (paginated)."""
  speedtestResults(controller: ID!, site: String! = "default", durationHours: Int! = 24, limit: Int! = 50, cursor: String = null): SpeedtestResultPage!

  """List top-traffic clients within a window."""
  topClients(controller: ID!, site: String! = "default", withinHours: Int! = 24): [TopClient!]!

  """List hotspot vouchers on the given controller/site (paginated)."""
  vouchers(controller: ID!, site: String! = "default", limit: Int! = 50, cursor: String = null): VoucherPage!

  """Look up a single hotspot voucher by id."""
  voucher(controller: ID!, id: ID!, site: String! = "default"): Voucher

  """List a client's association sessions (paginated)."""
  clientSessions(controller: ID!, site: String! = "default", mac: String = null, durationHours: Int! = 24, limit: Int! = 50, cursor: String = null): ClientSessionPage!

  """Get a client's current WiFi parameters (signal, rates)."""
  clientWifiDetails(controller: ID!, mac: ID!, site: String! = "default"): ClientWifiDetails

  """List switch port profiles on the given controller/site (paginated)."""
  portProfiles(controller: ID!, site: String! = "default", limit: Int! = 50, cursor: String = null): PortProfilePage!

  """Look up a single switch port profile by id."""
  portProfile(controller: ID!, id: ID!, site: String! = "default"): PortProfile

  """
  Get the port-override wrapper for a switch (name/model + per-port overrides).
  """
  switchPorts(controller: ID!, deviceMac: ID!, site: String! = "default"): SwitchPorts

  """Get the per-port stats wrapper for a switch (name/model + port_table)."""
  portStats(controller: ID!, deviceMac: ID!, site: String! = "default"): PortStats

  """Get switch capabilities (caps dict + STP / dot1x flags)."""
  switchCapabilities(controller: ID!, deviceMac: ID!, site: String! = "default"): SwitchCapabilities

  """List AP groups on the given controller/site (paginated)."""
  apGroups(controller: ID!, site: String! = "default", limit: Int! = 50, cursor: String = null): ApGroupPage!

  """Look up a single AP group by id."""
  apGroup(controller: ID!, id: ID!, site: String! = "default"): ApGroup

  """
  List network member client groups on the given controller/site (paginated).
  """
  clientGroups(controller: ID!, site: String! = "default", limit: Int! = 50, cursor: String = null): ClientGroupPage!

  """Look up a single network member client group by id."""
  clientGroup(controller: ID!, id: ID!, site: String! = "default"): ClientGroup

  """
  List QoS user groups (V1 /rest/usergroup) on the given controller/site (paginated).
  """
  userGroups(controller: ID!, site: String! = "default", limit: Int! = 50, cursor: String = null): UserGroupPage!

  """Look up a single QoS user group by id."""
  userGroup(controller: ID!, id: ID!, site: String! = "default"): UserGroup
}

"""An out-of-network (OON) policy entry."""
type OonPolicy {
  id: ID
  name: String
  enabled: Boolean!
  targetType: String
  targets: JSON
  appliesTo: JSON
  secure: JSON
  qos: JSON
  qosEnabled: Boolean
  route: JSON
  routeEnabled: Boolean
  restrictionLevel: String
}

"""Paginated page of OON (out-of-network) policies."""
type OonPolicyPage {
  items: [OonPolicy!]!
  nextCursor: String
}

"""A single outlet on a UniFi Smart Power PDU (UP6 / USP-Strip)."""
type PduOutletEntry {
  index: Int
  name: String
  hasRelay: Boolean
  hasMetering: Boolean
  relayState: Boolean
  cycleEnabled: Boolean
  overrideRelayState: Boolean
  overrideCycleEnabled: Boolean
  hasOverride: Boolean!
}

"""Wrapper dict containing per-outlet state for a Smart Power PDU."""
type PduOutlets {
  mac: ID
  name: String
  model: String
  outlets: [PduOutletEntry!]!
}

"""A UniFi Access policy (who-can-access-what binding)."""
type Policy {
  id: ID
  name: String
  scheduleId: String
  doorIds: [String!]!
  userGroupIds: [String!]!
  enabled: Boolean!
}

"""Paginated page of UniFi Access policies."""
type PolicyPage {
  items: [Policy!]!
  nextCursor: String
}

"""A port-forward rule (V1 /rest/portforward entry)."""
type PortForward {
  id: ID
  name: String
  enabled: Boolean!
  fwdProtocol: String
  dstPort: String
  fwdPort: String
  fwdIp: String
  src: String
  log: Boolean!
}

"""Paginated page of port forwards."""
type PortForwardPage {
  items: [PortForward!]!
  nextCursor: String
}

"""A single port-override row on a switch."""
type PortOverrideRow {
  portIdx: Int
  name: String
  portconfId: String
  poeMode: String
  opMode: String
}

"""A switch port profile (PoE / VLAN tagging template)."""
type PortProfile {
  id: ID
  name: String
  forward: String
  nativeNetworkconfId: String
  taggedNetworkconfIds: [String!]!
  voiceNetworkconfId: String
  poeMode: String
  isolation: Boolean
  stpPortMode: Boolean
  dot1xCtrl: String
}

"""Paginated page of switch port profiles."""
type PortProfilePage {
  items: [PortProfile!]!
  nextCursor: String
}

"""A single port-table row reporting per-port stats."""
type PortStatRow {
  portIdx: Int
  name: String
  enable: Boolean!
  speed: Int
  duplex: Boolean
  txBytes: Int!
  rxBytes: Int!
  txPackets: Int!
  rxPackets: Int!
  txDropped: Int!
  rxDropped: Int!
  poeEnable: Boolean!
  poeMode: String
  poePower: Float
}

"""Wrapper dict containing the per-port stats table for a switch."""
type PortStats {
  name: String
  model: String
  portTable: [PortStatRow!]!
}

"""UniFi Protect NVR health snapshot (pass-through)."""
type ProtectHealth {
  cpu: JSON
  memory: JSON
  storage: JSON
  isUpdating: Boolean
  uptimeSeconds: Int
}

"""Read-only access to UniFi Protect resources."""
type ProtectQuery {
  """List cameras on the Protect controller (paginated)."""
  cameras(controller: ID!, limit: Int! = 50, cursor: String = null): CameraPage!

  """Look up a single Protect camera by id."""
  camera(controller: ID!, id: ID!): Camera

  """Get analytics summary for a Protect camera."""
  cameraAnalytics(controller: ID!, id: ID!): CameraAnalytics

  """Get the stream catalog (channels + RTSPS URLs) for a camera."""
  cameraStreams(controller: ID!, id: ID!): CameraStreams

  """Capture a JPEG snapshot from a camera (metadata only)."""
  snapshot(controller: ID!, id: ID!, width: Int = null, height: Int = null): Snapshot

  """List assigned Protect Known Faces / named face recognition groups."""
  knownFaces(controller: ID!, limit: Int! = 50, cursor: String = null, minConfidence: Int! = 30, includeInterest: Boolean! = true, groupTypes: [String!] = null, orderBy: String! = "name", orderDirection: String! = "asc"): KnownFacePage!

  """List paired Protect chimes (paginated)."""
  chimes(controller: ID!, limit: Int! = 50, cursor: String = null): ChimePage!

  """Get the alarm system arm-state snapshot."""
  alarmStatus(controller: ID!): AlarmStatus

  """List configured alarm profiles ({profiles, count})."""
  alarmProfiles(controller: ID!): AlarmProfileList

  """List Protect events (paginated, most recent first)."""
  events(controller: ID!, limit: Int! = 50, cursor: String = null, eventType: String = null, cameraId: String = null): EventPage!

  """Look up a single Protect event by id."""
  event(controller: ID!, id: ID!): Event

  """Get the thumbnail for a Protect event."""
  eventThumbnail(controller: ID!, eventId: ID!, width: Int = null, height: Int = null): EventThumbnail

  """List Protect smart-detection events (paginated, most recent first)."""
  smartDetections(controller: ID!, limit: Int! = 50, cursor: String = null, cameraId: String = null, detectionType: String = null, minConfidence: Int = null): SmartDetectionPage!

  """
  List Protect recording windows for a camera. UniFi Protect exposes a single continuous recording window per camera.
  """
  recordings(controller: ID!, cameraId: ID!, limit: Int! = 50, cursor: String = null): RecordingPage!

  """Get current recording state for one or all cameras ({cameras, count})."""
  recordingStatus(controller: ID!, cameraId: String = null): RecordingStatusList

  """List Protect lights (PIR-triggered floodlights)."""
  lights(controller: ID!, limit: Int! = 50, cursor: String = null): LightPage!

  """List Protect sensors (motion / leak / temperature)."""
  sensors(controller: ID!, limit: Int! = 50, cursor: String = null): SensorPage!

  """List Protect liveviews (multi-camera grid layouts)."""
  liveviews(controller: ID!, limit: Int! = 50, cursor: String = null): LiveviewPage!

  """Get the NVR-level system info snapshot."""
  systemInfo(controller: ID!): ProtectSystemInfo

  """Get the NVR health snapshot (cpu / memory / storage)."""
  health(controller: ID!): ProtectHealth

  """Get firmware status for the NVR plus its devices."""
  firmwareStatus(controller: ID!): FirmwareStatus

  """List Protect viewers ({viewers, count})."""
  viewers(controller: ID!): ViewerList
}

"""UniFi Protect NVR-level system info (pass-through)."""
type ProtectSystemInfo {
  id: ID
  name: String
  model: String
  firmwareVersion: String
  version: String
  host: String
  mac: String
  uptimeSeconds: Int
  upSince: String
  isUpdating: Boolean
  storage: JSON
  cameraCount: Int
  lightCount: Int
  sensorCount: Int
  viewerCount: Int
  chimeCount: Int
}

"""A QoS rate-limit rule (V2 /qos-rules entry)."""
type QosRule {
  id: ID
  name: String
  enabled: Boolean!
  interface: String
  direction: String
  bandwidthLimitKbps: Int
  targetIpAddress: String
  targetSubnet: String
  dscpValue: Int
  rateMaxDown: Int
  rateMaxUp: Int
  priority: Int
}

"""Paginated page of QoS rules."""
type QosRulePage {
  items: [QosRule!]!
  nextCursor: String
}

type Query {
  """Liveness probe; mirrors GET /v1/health/ready."""
  health: HealthSnapshot!

  """Read-only access to UniFi Network resources."""
  network: NetworkQuery!

  """Read-only access to UniFi Protect resources."""
  protect: ProtectQuery!

  """Read-only access to UniFi Access resources."""
  access: AccessQuery!
}

"""Radio configuration entry on a UniFi access point."""
type RadioEntry {
  name: String
  radio: String
  channel: Int
  ht: Int
  txPower: Int
  txPowerMode: String
  currentChannel: Int
  currentTxPower: Int
  numSta: Int
}

"""A UniFi Protect recording window for a camera."""
type Recording {
  id: ID
  type: String
  camera: ID
  start: String
  end: String
  fileSize: Int

  """The camera this recording came from."""
  cameraDetail: Camera
}

"""Paginated page of UniFi Protect recording windows."""
type RecordingPage {
  items: [Recording!]!
  nextCursor: String
}

"""Recording-status wrapper for protect_get_recording_status."""
type RecordingStatusList {
  cameras: JSON
  count: Int
}

"""A single RF-scan result row reported by an AP."""
type RfScanResult {
  bssid: ID
  ssid: String
  channel: Int
  signalDbm: Int
  capturedAt: Int
}

"""A rogue (unknown) AP detected by the controller."""
type RogueAp {
  bssid: ID
  ssid: String
  channel: Int
  signalDbm: Int
  lastSeen: Int
  isKnown: Boolean!
}

"""Paginated page of detected rogue APs."""
type RogueApPage {
  items: [RogueAp!]!
  nextCursor: String
}

"""A static route configured on the gateway."""
type Route {
  id: ID
  name: String
  targetSubnet: String
  gateway: String
  distance: Int
  enabled: Boolean!
}

"""Paginated page of static routes."""
type RoutePage {
  items: [Route!]!
  nextCursor: String
}

"""A UniFi Access schedule (weekly access window)."""
type Schedule {
  id: ID
  name: String
  weeklyPattern: JSON!
  enabled: Boolean!
}

"""Paginated page of UniFi Access schedules."""
type SchedulePage {
  items: [Schedule!]!
  nextCursor: String
}

"""A UniFi Protect sensor (motion / leak / temperature)."""
type Sensor {
  id: ID
  mac: String
  name: String
  type: String
  batteryStatus: String
  humidityStatus: String
  lightStatus: String
  motionDetectedAt: String
}

"""Paginated page of UniFi Protect sensors."""
type SensorPage {
  items: [Sensor!]!
  nextCursor: String
}

"""Controller site settings."""
type SiteSettings {
  siteId: String
  name: String
  role: String
  country: Int
}

"""A UniFi Protect smart-detection event row."""
type SmartDetection {
  id: ID
  type: String
  start: String
  end: String
  score: Int
  smartDetectTypes: [String!]!
  camera: ID
  thumbnail: ID
  recognizedPersonId: ID
  recognizedPersonName: String
  recognizedPersonConfidence: Int
  detectedThumbnailId: ID
}

"""Paginated page of UniFi Protect smart-detections."""
type SmartDetectionPage {
  items: [SmartDetection!]!
  nextCursor: String
}

"""Metadata for a JPEG snapshot captured from a Protect camera."""
type Snapshot {
  sizeBytes: Int
  contentType: String
  capturedAt: String
  url: String
}

"""Controller SNMP settings."""
type SnmpSettings {
  enabled: Boolean!
  community: String
  port: Int
  version: String
}

"""A speedtest result entry."""
type SpeedtestResult {
  timestamp: Int
  downloadMbps: Float
  uploadMbps: Float
  latencyMs: Float
}

"""Paginated page of speedtest result entries."""
type SpeedtestResultPage {
  items: [SpeedtestResult!]!
  nextCursor: String
}

"""Speedtest status reported by a UniFi gateway."""
type SpeedtestStatus {
  status: String
  downloadMbps: Float
  uploadMbps: Float
  latencyMs: Int
  lastRun: Int
}

"""A single timeseries point: {ts: <ms>, ...metrics}."""
type StatPoint {
  ts: Int!
}

"""Switch capabilities (caps dict + STP / dot1x flags)."""
type SwitchCapabilities {
  name: String
  model: String
  switchCaps: JSON
  stpVersion: String
  stpPriority: String
  jumboframeEnabled: Boolean
  dot1xPortctrlEnabled: Boolean
}

"""Wrapper dict containing port-override rows for a switch."""
type SwitchPorts {
  name: String
  model: String
  portOverrides: [PortOverrideRow!]!
}

"""Controller system information."""
type SystemInfo {
  name: String
  version: String
  hostname: String
  uptime: Int
  numDevices: Int
  numClients: Int
}

"""A top-traffic client entry."""
type TopClient {
  mac: String
  hostname: String
  txBytes: Int
  rxBytes: Int
  totalBytes: Int
}

"""A traffic-route policy (V2 /trafficroutes entry)."""
type TrafficRoute {
  id: ID
  name: String
  matchingTarget: String
  networkId: String
  nextHop: String
  enabled: Boolean!
  killSwitchEnabled: Boolean
  sourceTargets: JSON
  destinationTargets: JSON
}

"""Paginated page of traffic-route policies."""
type TrafficRoutePage {
  items: [TrafficRoute!]!
  nextCursor: String
}

"""A UniFi Access user (employee / cardholder)."""
type User {
  id: ID
  name: String
  employeeId: String
  status: String
  role: String
  createdAt: String

  """Credentials registered for this user."""
  credentials: [Credential!]!
}

"""A QoS user group (V1 /rest/usergroup entry)."""
type UserGroup {
  id: ID
  name: String
  qosRateMaxDown: Int
  qosRateMaxUp: Int
}

"""Paginated page of QoS user groups."""
type UserGroupPage {
  items: [UserGroup!]!
  nextCursor: String
}

"""Paginated page of UniFi Access users."""
type UserPage {
  items: [User!]!
  nextCursor: String
}

"""Wrapper for protect_list_viewers — {viewers, count}."""
type ViewerList {
  viewers: JSON
  count: Int
}

"""A UniFi Access visitor (time-bounded guest pass)."""
type Visitor {
  id: ID
  name: String
  hostUserId: String
  validFrom: String
  validUntil: String
  status: String
  credentialCount: Int
  email: String
  phone: String
}

"""Paginated page of UniFi Access visitors."""
type VisitorPage {
  items: [Visitor!]!
  nextCursor: String
}

"""A hotspot voucher (V1 /stat/voucher entry)."""
type Voucher {
  id: ID
  code: String
  status: String
  duration: Int
  qosOverwrite: Boolean!
  createdAt: Int
  usedAt: Int
}

"""Paginated page of hotspot vouchers."""
type VoucherPage {
  items: [Voucher!]!
  nextCursor: String
}

"""A configured VPN client (outbound tunnel)."""
type VpnClient {
  id: ID
  name: String
  type: String
  enabled: Boolean!
  serverAddress: String
  lastHandshake: Int
}

"""Paginated page of VPN clients."""
type VpnClientPage {
  items: [VpnClient!]!
  nextCursor: String
}

"""A configured VPN server (inbound tunnel)."""
type VpnServer {
  id: ID
  name: String
  type: String
  enabled: Boolean!
  listenPort: Int
  allowedSubnets: [String!]
}

"""Paginated page of VPN servers."""
type VpnServerPage {
  items: [VpnServer!]!
  nextCursor: String
}

"""A UniFi WLAN/SSID configuration."""
type Wlan {
  id: ID
  name: String
  enabled: Boolean!
  security: String
  networkId: String
  hideSsid: Boolean
  vlanId: Int
  xPassphrase: String
  guestPolicy: Boolean
  usergroupId: String
  fastRoamingEnabled: Boolean
  pmfMode: String
  wpa3Support: Boolean
  wpa3Transition: Boolean
  macFilterEnabled: Boolean
  macFilterPolicy: String
  macFilterList: [String!]
  scheduleEnabled: Boolean
  l2Isolation: Boolean
  wlanBand: String
  multicastEnhanceEnabled: Boolean
  dtimMode: String
  dtimNa: Int
  dtimNg: Int
  minrateNgEnabled: Boolean
  minrateNgDataRateKbps: Int
  minrateNaEnabled: Boolean
  minrateNaDataRateKbps: Int
  groupRekey: Int
  uapsdEnabled: Boolean
  proxyArp: Boolean
  iappEnabled: Boolean
  apGroupIds: [String!]
  apGroupMode: String
}

"""Paginated page of WLAN/SSID configurations."""
type WlanPage {
  items: [Wlan!]!
  nextCursor: String
}
