# PiCloud dev Caddyfile.
#
# Same routing shape as prod, with two differences:
#   - bound to plain HTTP (no domain, no automatic TLS)
#   - upstreams are the docker-compose service names
#
# Control plane (`/api/admin/*`) and data plane (`/api/execute/*`, `/exec/*`)
# both terminate on the `picloud` all-in-one for now; in cluster mode the
# data-plane handles will list multiple orchestrator upstreams here while
# the admin handle still points at a single manager.

{
	auto_https off
	admin off
	log {
		output stdout
		format console
	}
}

:80 {
	# Health + version are unversioned (k8s probes, monitoring).
	handle /healthz {
		reverse_proxy picloud:8080
	}
	handle /version {
		reverse_proxy picloud:8080
	}

	# Versioned API (see docs/versioning.md). When v2 ships, add a
	# second `handle /api/v2/...` block while keeping v1 live for at
	# least one product-minor deprecation window.

	# Control plane → manager (single-process: picloud).
	handle /api/v1/admin/* {
		reverse_proxy picloud:8080
	}

	# Data plane → orchestrator (single-process: picloud).
	handle /api/v1/execute/* {
		reverse_proxy picloud:8080
	}

	# Unversioned: user-defined script paths (v1.1+). Contract is just
	# "your script runs against this body", so no API versioning applies.
	handle /exec/* {
		reverse_proxy picloud:8080
	}

	# Anything else under /api/* — old major versions that have been
	# fully sunset, or typos. Fail loudly rather than silently serving
	# the dashboard SPA.
	handle /api/* {
		respond 404 {
			body "{\"error\":\"no such API version — see /version for supported routes\"}"
			close
		}
	}

	# Everything else → dashboard SPA (Caddy serves a self-contained
	# dashboard container that already runs file_server with index.html
	# fallback for client-side routing).
	handle {
		reverse_proxy dashboard:80
	}

	log {
		output stdout
		format console
	}
}
