{
  "apply": {
    "migration": {
      "rc": 0,
      "stderr": "",
      "stdout": "BEGIN\nCREATE EXTENSION\nCREATE TABLE\nINSERT 0 14\nCREATE TABLE\nINSERT 0 5\nCREATE TABLE\nCREATE INDEX\nCREATE INDEX\nCREATE INDEX\nCREATE INDEX\nCREATE INDEX\nCREATE INDEX\nCOMMIT"
    }
  },
  "containers": {
    "postgres": "wgaccess-postgres"
  },
  "errors": [],
  "mode": "APPLY_DB_SCHEMA_FOR_RUNTIME_EGRESS_LEASE_ALLOCATOR_WITH_EMERGENCY_OVERRIDE",
  "post": {
    "indexes": {
      "rc": 0,
      "stderr": "",
      "stdout": "egress_allocator_settings|egress_allocator_settings_pkey|CREATE UNIQUE INDEX egress_allocator_settings_pkey ON public.egress_allocator_settings USING btree (key)\negress_targets|egress_targets_egress_class_key|CREATE UNIQUE INDEX egress_targets_egress_class_key ON public.egress_targets USING btree (egress_class)\negress_targets|egress_targets_pkey|CREATE UNIQUE INDEX egress_targets_pkey ON public.egress_targets USING btree (id)\npeer_egress_leases|peer_egress_leases_class_state_idx|CREATE INDEX peer_egress_leases_class_state_idx ON public.peer_egress_leases USING btree (egress_class, state)\npeer_egress_leases|peer_egress_leases_forced_idx|CREATE INDEX peer_egress_leases_forced_idx ON public.peer_egress_leases USING btree (forced)\npeer_egress_leases|peer_egress_leases_peer_id_uq|CREATE UNIQUE INDEX peer_egress_leases_peer_id_uq ON public.peer_egress_leases USING btree (peer_id)\npeer_egress_leases|peer_egress_leases_pkey|CREATE UNIQUE INDEX peer_egress_leases_pkey ON public.peer_egress_leases USING btree (id)\npeer_egress_leases|peer_egress_leases_target_id_idx|CREATE INDEX peer_egress_leases_target_id_idx ON public.peer_egress_leases USING btree (target_id)\npeer_egress_leases|peer_egress_leases_tunnel_ip_uq|CREATE UNIQUE INDEX peer_egress_leases_tunnel_ip_uq ON public.peer_egress_leases USING btree (tunnel_ip)\npeer_egress_leases|peer_egress_leases_updated_at_idx|CREATE INDEX peer_egress_leases_updated_at_idx ON public.peer_egress_leases USING btree (updated_at)"
    },
    "lease_columns": {
      "rc": 0,
      "stderr": "",
      "stdout": "id|uuid|NO\npeer_id|uuid|NO\ntunnel_ip|inet|NO\negress_class|text|NO\ntarget_id|text|YES\nassigned_at|timestamp with time zone|NO\nlast_activity_at|timestamp with time zone|YES\nlast_rx_packets|bigint|NO\nlast_tx_packets|bigint|NO\nlast_rx_bytes|bigint|NO\nlast_tx_bytes|bigint|NO\nstate|text|NO\nassignment_source|text|NO\nforced|boolean|NO\nreason|text|NO\ncooldown_until|timestamp with time zone|YES\nupdated_at|timestamp with time zone|NO"
    },
    "settings": {
      "rc": 0,
      "stderr": "",
      "stdout": "ROUTER_EGRESS_ACTIVE_MIN_BYTES|16384|16384|Minimum inner forwarded byte delta to consider peer active.\nROUTER_EGRESS_ACTIVE_MIN_PACKETS|10|10|Minimum inner forwarded packet delta to consider peer active.\nROUTER_EGRESS_ACTIVITY_METRIC|inner_forwarded_transit_vpn||Use inner client traffic after wg_paid decrypt, preferably transit_vpn-bound; not WireGuard handshake.\nROUTER_EGRESS_ALLOCATOR_ENABLED|1|1|Global allocator enable switch. 0 disables automatic allocation.\nROUTER_EGRESS_CLASSES|cs1,cs2,cs3,cs4,cs5||Ordered egress classes available to allocator.\nROUTER_EGRESS_FORCE_CLASS|||Forced class cs1..cs5 when FORCE_MODE=all_to_class.\nROUTER_EGRESS_FORCE_MODE|off||Global override mode: off, all_to_class, all_to_target.\nROUTER_EGRESS_FORCE_REASON|||Human reason for forced emergency/maintenance mode.\nROUTER_EGRESS_FORCE_TARGET_ID|||Forced egress target id when FORCE_MODE=all_to_target.\nROUTER_EGRESS_FORCE_UNTIL|||Optional timestamp/comment for planned force-mode end.\nROUTER_EGRESS_IDLE_SECONDS|900|900|Idle time before peer lease can be reassigned.\nROUTER_EGRESS_REASSIGN_COOLDOWN_SECONDS|900|900|Minimum cooldown between egress reassignments.\nROUTER_EGRESS_REBALANCE_PAUSED|0|0|Pause automatic rebalance/reassignment while preserving current leases.\nROUTER_EGRESS_SAMPLE_SECONDS|120|120|Activity sampling window in seconds."
    },
    "summary": {
      "rc": 0,
      "stderr": "",
      "stdout": "peer_egress_leases_regclass|peer_egress_leases\negress_targets_regclass|egress_targets\negress_allocator_settings_regclass|egress_allocator_settings\nlease_rows|0\ntarget_rows|5\nsettings_rows|14\nenabled_peers|5\npending_jobs|0"
    },
    "targets": {
      "rc": 0,
      "stderr": "",
      "stdout": "cs1_vpn3|cs1|203|0x203|vpn3|vpn|enabled|100|false\ncs2_vpn4|cs2|204|0x204|vpn4|vpn|enabled|100|false\ncs3_vpn5|cs3|205|0x205|vpn5|vpn|enabled|100|false\ncs4_vpn1|cs4|201|0x201|vpn1|vpn|enabled|100|false\ncs5_vpn2|cs5|202|0x202|vpn2|vpn|enabled|100|false"
    }
  },
  "pre": {
    "existing_schema": {
      "rc": 0,
      "stderr": "",
      "stdout": "peer_egress_leases|\negress_targets|\negress_allocator_settings|"
    }
  },
  "rollback": {
    "note": "Drops peer_egress_leases, egress_targets, egress_allocator_settings. Use only before production lease rows exist or after explicit approval.",
    "path_vm121": "/opt/wg-access/rollbacks/rollback-step044c-runtime-egress-lease-schema-20260709-123451.sql"
  }
}
