upstream panel {
    server roboco-panel:3000;
}

upstream orchestrator {
    server roboco-orchestrator:8000;
}

server {
    listen 80;
    server_name _;

    # Health check -> orchestrator (no auth needed)
    location /health {
        proxy_pass http://orchestrator;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    # Readiness check -> orchestrator
    location /ready {
        proxy_pass http://orchestrator;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    # API requests -> orchestrator
    location /api/ {
        proxy_pass http://orchestrator;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        # The browser never holds the signing secret. nginx (the only trusted
        # hop for the human panel) attaches the CEO token so secure mode
        # (ROBOCO_AGENT_AUTH_REQUIRED=true) does not lock the panel out. Empty
        # when unset, in which case nginx sends no header (dev/header-trust).
        proxy_set_header X-Agent-Token "${ROBOCO_PANEL_AGENT_TOKEN}";
    }

    # WebSocket requests -> orchestrator
    location /ws/ {
        proxy_pass http://orchestrator;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Agent-Token "${ROBOCO_PANEL_AGENT_TOKEN}";
        proxy_read_timeout 86400;
    }

    # Edge honeytrap (Surface N). Classic scanner/probe paths never reach the
    # orchestrator (only /api|/ws|/health|/ready are proxied there), so guard's
    # recon auto-ban can't see them — they would otherwise hit the panel. Drop
    # them here with 444 (close the connection, no response). Anchored to known
    # scanner fingerprints; /.well-known and every real panel/API route are
    # untouched. The /api-path probes that DO reach the app are handled by
    # guard's threat_ban_config recon/sensitive_file/cms_probing categories.
    location ~* "^/(\.env|\.git|\.aws|\.ssh|\.svn|\.hg|wp-login\.php|wp-admin|xmlrpc\.php|phpmyadmin|admin\.php|server-status|actuator|debug/pprof|cgi-bin|vendor/)" {
        return 444;
    }

    # Everything else -> panel
    location / {
        proxy_pass http://panel;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}
