{
  "backend_model_hints": {
    "agent_api_excerpt": {
      "rc": 0,
      "stderr": "",
      "stdout": "18:        raise HTTPException(status_code=401, detail=\"invalid agent token\")\n21:class AgentPeerResponse(BaseModel):\n26:    tunnel_ip: str\n30:    class Config:\n34:@router.get(\"/peers\", response_model=list[AgentPeerResponse])\n35:def get_enabled_peers(\n50:class AgentJobResponse(BaseModel):\n55:    payload_json: dict\n56:    status: str\n60:    class Config:\n64:class FailRequest(BaseModel):\n68:@router.get(\"/jobs\", response_model=list[AgentJobResponse])\n69:def get_pending_jobs(\n78:        .where(ProvisioningJob.status == \"pending\")\n85:@router.post(\"/jobs/{job_id}/start\", response_model=AgentJobResponse)\n93:        raise HTTPException(status_code=404, detail=\"job not found\")\n94:    if job.status != \"pending\":\n95:        raise HTTPException(status_code=409, detail=f\"job status is {job.status}\")\n97:    job.status = \"running\"\n106:@router.post(\"/jobs/{job_id}/complete\", response_model=AgentJobResponse)\n107:def complete_job(\n114:        raise HTTPException(status_code=404, detail=\"job not found\")\n115:    if job.status not in (\"pending\", \"running\"):\n116:        raise HTTPException(status_code=409, detail=f\"job status is {job.status}\")\n118:    job.status = \"completed\"\n119:    job.completed_at = datetime.now(timezone.utc)\n127:@router.post(\"/jobs/{job_id}/fail\", response_model=AgentJobResponse)\n128:def fail_job(\n130:    payload: FailRequest,\n136:        raise HTTPException(status_code=404, detail=\"job not found\")\n137:    if job.status not in (\"pending\", \"running\"):\n138:        raise HTTPException(status_code=409, detail=f\"job status is {job.status}\")\n140:    job.status = \"failed\""
    },
    "models_core_excerpt": {
      "rc": 0,
      "stderr": "",
      "stdout": "19:class User(Base):\n20:    __tablename__ = \"users\"\n24:    created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=datetime.utcnow, nullable=False)\n30:class InviteCode(Base):\n31:    __tablename__ = \"invite_codes\"\n39:    created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=datetime.utcnow, nullable=False)\n42:class Order(Base):\n43:    __tablename__ = \"orders\"\n52:    status: Mapped[str] = mapped_column(String(32), default=\"created\", nullable=False, index=True)\n56:    created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=datetime.utcnow, nullable=False)\n62:class Subscription(Base):\n63:    __tablename__ = \"subscriptions\"\n68:    status: Mapped[str] = mapped_column(String(32), default=\"active\", nullable=False, index=True)\n77:    created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=datetime.utcnow, nullable=False)\n81:class Peer(Base):\n82:    __tablename__ = \"peers\"\n84:        # tunnel_ip uniqueness is enforced in PostgreSQL by partial unique index:\n85:        # uq_peers_node_tunnel_ip_enabled (node_id, tunnel_ip) WHERE enabled = true,\n92:    public_key: Mapped[str] = mapped_column(String(128), unique=True, nullable=False)\n94:    tunnel_ip: Mapped[str] = mapped_column(String(64), nullable=False)\n97:    enabled: Mapped[bool] = mapped_column(Boolean, default=True, nullable=False, index=True)\n99:    created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=datetime.utcnow, nullable=False)\n100:    disabled_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)\n105:class ProvisioningJob(Base):\n106:    __tablename__ = \"provisioning_jobs\"\n111:    action: Mapped[str] = mapped_column(String(64), nullable=False)\n114:    payload_json: Mapped[dict] = mapped_column(JSONB, nullable=False)\n115:    status: Mapped[str] = mapped_column(String(32), default=\"pending\", nullable=False, index=True)\n118:    created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=datetime.utcnow, nullable=False)"
    },
    "wireguard_service_excerpt": {
      "rc": 0,
      "stderr": "",
      "stdout": "41:def next_tunnel_ip(db: Session, node_id: str) -> str:\n47:    pool_cidr = os.environ.get(\"WG_CLIENT_POOL_CIDR\", \"10.253.0.0/16\").strip()\n48:    first_client_ip = os.environ.get(\"WG_CLIENT_FIRST_IP\", \"10.253.1.10\").strip()\n54:        raise RuntimeError(f\"WG_CLIENT_FIRST_IP {first_client_ip} is outside {pool_cidr}\")\n58:            select(Peer.tunnel_ip).where(\n77:def build_client_config(private_key: str, tunnel_ip: str, preshared_key: str) -> str:\n79:    endpoint = os.environ.get(\"WG_CLIENT_ENDPOINT\", \"\").strip()\n80:    allowed_ips = os.environ.get(\"WG_CLIENT_ALLOWED_IPS\", \"10.253.1.1/32\").strip()\n81:    dns = os.environ.get(\"WG_CLIENT_DNS\", \"\").strip()\n86:        raise RuntimeError(\"WG_CLIENT_ENDPOINT is not configured\")\n91:        f\"Address = {tunnel_ip}/32\",\n103:        f\"AllowedIPs = {allowed_ips}\","
    }
  },
  "containers": {
    "backend": "wgaccess-backend",
    "docker_ps": {
      "rc": 0,
      "stderr": "",
      "stdout": "wgaccess-backend Up 2 hours\nwgaccess-postgres Up 19 hours (healthy)"
    },
    "postgres": "wgaccess-postgres"
  },
  "db": {},
  "errors": [],
  "mode": "READONLY_VM121_DB_SCHEMA_INVENTORY_SQL_STDIN",
  "queries": {
    "db_identity": {
      "rc": 0,
      "stderr": "",
      "stdout": "current_database|wg_access\ncurrent_user|wg_access\nserver_version|16.14"
    },
    "jobs_summary": {
      "rc": 0,
      "stderr": "",
      "stdout": "disable_peer|completed|23\nenable_peer|completed|32"
    },
    "lease_egress_column_search": {
      "rc": 0,
      "stderr": "",
      "stdout": ""
    },
    "lease_egress_table_search": {
      "rc": 0,
      "stderr": "",
      "stdout": ""
    },
    "peer_subscription_job_columns": {
      "rc": 0,
      "stderr": "",
      "stdout": "peers|1|id|uuid|NO\npeers|2|user_id|uuid|NO\npeers|3|node_id|character varying|NO\npeers|4|public_key|character varying|NO\npeers|5|preshared_key|character varying|NO\npeers|6|tunnel_ip|character varying|NO\npeers|7|paid_until|timestamp with time zone|NO\npeers|8|enabled|boolean|NO\npeers|9|created_at|timestamp with time zone|NO\npeers|10|disabled_at|timestamp with time zone|YES\nprovisioning_jobs|1|id|uuid|NO\nprovisioning_jobs|2|node_id|character varying|NO\nprovisioning_jobs|3|action|character varying|NO\nprovisioning_jobs|4|peer_id|uuid|YES\nprovisioning_jobs|5|payload_json|jsonb|NO\nprovisioning_jobs|6|status|character varying|NO\nprovisioning_jobs|7|attempts|integer|NO\nprovisioning_jobs|8|created_at|timestamp with time zone|NO\nprovisioning_jobs|9|started_at|timestamp with time zone|YES\nprovisioning_jobs|10|completed_at|timestamp with time zone|YES\nprovisioning_jobs|11|last_error|text|YES\nsubscriptions|1|id|uuid|NO\nsubscriptions|2|user_id|uuid|NO\nsubscriptions|3|status|character varying|NO\nsubscriptions|4|plan_code|character varying|NO\nsubscriptions|5|auto_renew|boolean|NO\nsubscriptions|6|paid_until|timestamp with time zone|NO\nsubscriptions|7|payment_method_id|character varying|YES\nsubscriptions|8|next_charge_at|timestamp with time zone|YES\nsubscriptions|9|retry_count|integer|NO\nsubscriptions|10|created_at|timestamp with time zone|NO\nsubscriptions|11|canceled_at|timestamp with time zone|YES"
    },
    "public_columns_all": {
      "rc": 0,
      "stderr": "",
      "stdout": "alembic_version|1|version_num|character varying|NO\ninvite_codes|1|id|uuid|NO\ninvite_codes|2|code|character varying|NO\ninvite_codes|3|note|text|YES\ninvite_codes|4|max_uses|integer|NO\ninvite_codes|5|used_count|integer|NO\ninvite_codes|6|active|boolean|NO\ninvite_codes|7|created_at|timestamp with time zone|NO\norders|1|id|uuid|NO\norders|2|user_id|uuid|NO\norders|3|plan_code|character varying|NO\norders|4|months|integer|NO\norders|5|amount_rub|numeric|NO\norders|6|status|character varying|NO\norders|7|yookassa_payment_id|character varying|YES\norders|8|idempotence_key|character varying|YES\norders|9|created_at|timestamp with time zone|NO\norders|10|paid_at|timestamp with time zone|YES\npeers|1|id|uuid|NO\npeers|2|user_id|uuid|NO\npeers|3|node_id|character varying|NO\npeers|4|public_key|character varying|NO\npeers|5|preshared_key|character varying|NO\npeers|6|tunnel_ip|character varying|NO\npeers|7|paid_until|timestamp with time zone|NO\npeers|8|enabled|boolean|NO\npeers|9|created_at|timestamp with time zone|NO\npeers|10|disabled_at|timestamp with time zone|YES\nprovisioning_jobs|1|id|uuid|NO\nprovisioning_jobs|2|node_id|character varying|NO\nprovisioning_jobs|3|action|character varying|NO\nprovisioning_jobs|4|peer_id|uuid|YES\nprovisioning_jobs|5|payload_json|jsonb|NO\nprovisioning_jobs|6|status|character varying|NO\nprovisioning_jobs|7|attempts|integer|NO\nprovisioning_jobs|8|created_at|timestamp with time zone|NO\nprovisioning_jobs|9|started_at|timestamp with time zone|YES\nprovisioning_jobs|10|completed_at|timestamp with time zone|YES\nprovisioning_jobs|11|last_error|text|YES\nsubscriptions|1|id|uuid|NO\nsubscriptions|2|user_id|uuid|NO\nsubscriptions|3|status|character varying|NO\nsubscriptions|4|plan_code|character varying|NO\nsubscriptions|5|auto_renew|boolean|NO\nsubscriptions|6|paid_until|timestamp with time zone|NO\nsubscriptions|7|payment_method_id|character varying|YES\nsubscriptions|8|next_charge_at|timestamp with time zone|YES\nsubscriptions|9|retry_count|integer|NO\nsubscriptions|10|created_at|timestamp with time zone|NO\nsubscriptions|11|canceled_at|timestamp with time zone|YES\nusers|1|id|uuid|NO\nusers|2|email|character varying|YES\nusers|3|created_at|timestamp with time zone|NO"
    },
    "public_indexes": {
      "rc": 0,
      "stderr": "",
      "stdout": "alembic_version|alembic_version_pkc|CREATE UNIQUE INDEX alembic_version_pkc ON public.alembic_version USING btree (version_num)\ninvite_codes|invite_codes_pkey|CREATE UNIQUE INDEX invite_codes_pkey ON public.invite_codes USING btree (id)\ninvite_codes|ix_invite_codes_code|CREATE UNIQUE INDEX ix_invite_codes_code ON public.invite_codes USING btree (code)\norders|ix_orders_status|CREATE INDEX ix_orders_status ON public.orders USING btree (status)\norders|ix_orders_user_id|CREATE INDEX ix_orders_user_id ON public.orders USING btree (user_id)\norders|orders_pkey|CREATE UNIQUE INDEX orders_pkey ON public.orders USING btree (id)\norders|uq_orders_idempotence_key|CREATE UNIQUE INDEX uq_orders_idempotence_key ON public.orders USING btree (idempotence_key)\norders|uq_orders_yookassa_payment_id|CREATE UNIQUE INDEX uq_orders_yookassa_payment_id ON public.orders USING btree (yookassa_payment_id)\npeers|ix_peers_enabled|CREATE INDEX ix_peers_enabled ON public.peers USING btree (enabled)\npeers|ix_peers_node_id|CREATE INDEX ix_peers_node_id ON public.peers USING btree (node_id)\npeers|ix_peers_user_id|CREATE INDEX ix_peers_user_id ON public.peers USING btree (user_id)\npeers|peers_pkey|CREATE UNIQUE INDEX peers_pkey ON public.peers USING btree (id)\npeers|uq_peers_node_tunnel_ip_enabled|CREATE UNIQUE INDEX uq_peers_node_tunnel_ip_enabled ON public.peers USING btree (node_id, tunnel_ip) WHERE (enabled = true)\npeers|uq_peers_public_key|CREATE UNIQUE INDEX uq_peers_public_key ON public.peers USING btree (public_key)\nprovisioning_jobs|ix_provisioning_jobs_node_id|CREATE INDEX ix_provisioning_jobs_node_id ON public.provisioning_jobs USING btree (node_id)\nprovisioning_jobs|ix_provisioning_jobs_peer_id|CREATE INDEX ix_provisioning_jobs_peer_id ON public.provisioning_jobs USING btree (peer_id)\nprovisioning_jobs|ix_provisioning_jobs_status|CREATE INDEX ix_provisioning_jobs_status ON public.provisioning_jobs USING btree (status)\nprovisioning_jobs|provisioning_jobs_pkey|CREATE UNIQUE INDEX provisioning_jobs_pkey ON public.provisioning_jobs USING btree (id)\nsubscriptions|ix_subscriptions_status|CREATE INDEX ix_subscriptions_status ON public.subscriptions USING btree (status)\nsubscriptions|ix_subscriptions_user_id|CREATE INDEX ix_subscriptions_user_id ON public.subscriptions USING btree (user_id)\nsubscriptions|subscriptions_pkey|CREATE UNIQUE INDEX subscriptions_pkey ON public.subscriptions USING btree (id)\nusers|ix_users_email|CREATE INDEX ix_users_email ON public.users USING btree (email)\nusers|users_pkey|CREATE UNIQUE INDEX users_pkey ON public.users USING btree (id)"
    },
    "public_tables": {
      "rc": 0,
      "stderr": "",
      "stdout": "public|alembic_version|BASE TABLE\npublic|invite_codes|BASE TABLE\npublic|orders|BASE TABLE\npublic|peers|BASE TABLE\npublic|provisioning_jobs|BASE TABLE\npublic|subscriptions|BASE TABLE\npublic|users|BASE TABLE"
    },
    "safe_counts": {
      "rc": 0,
      "stderr": "",
      "stdout": "users|32\nsubscriptions|19\npeers|32\nenabled_peers|5\nprovisioning_jobs|55\npending_jobs|0"
    },
    "safe_peer_inventory_no_keys": {
      "rc": 0,
      "stderr": "ERROR:  column \"subscription_id\" does not exist\nLINE 4:   subscription_id::text,\n          ^",
      "stdout": ""
    }
  }
}
