# FleetOps — static analytics SPA served by Caddy.
# Traefik (via Coolify) terminates TLS, so Caddy is a plain :80 file server.
# The only moving part is runtime API-base injection: Caddy's `templates`
# directive evaluates {{env "API_BASE"}} inside /env.js at request time, so the
# SAME image serves staging (fleetapi.fivetitude.com) and prod
# (fleetapi.rahamafresh.com) — set API_BASE per Coolify app.
:80 {
	root * /srv
	encode zstd gzip

	# Security headers (FO-SEC-03). CSP allows self + the two pinned CDNs, the
	# CARTO basemap (styles/tiles/fonts) and the fleet APIs; SRI in index.html
	# pins the CDN payloads themselves. frame-ancestors 'none' = no clickjacking.
	# script-src keeps 'unsafe-inline' because the whole app is one inline
	# <script> block — the CSP's job here is limiting external script origins
	# and exfil targets (connect-src), not inline policy.
	header {
		X-Content-Type-Options "nosniff"
		Referrer-Policy "strict-origin-when-cross-origin"
		Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net https://unpkg.com; style-src 'self' 'unsafe-inline' https://unpkg.com; img-src 'self' data: blob: https://*.cartocdn.com; font-src https://*.cartocdn.com; connect-src 'self' https://fleetapi.rahamafresh.com https://fleetapi.fivetitude.com https://*.cartocdn.com; worker-src blob:; frame-ancestors 'none'"
		-Server
	}

	# Health endpoint for Coolify / Traefik probes.
	handle /healthz {
		respond "ok" 200
	}

	# Runtime config: Caddy renders {{env "API_BASE"}} into env.js. Never cache it.
	# `templates` only acts on text/html + text/plain by default, so JS responses
	# are skipped unless their MIME type is named explicitly here.
	handle /env.js {
		header Cache-Control "no-store"
		templates {
			mime text/javascript application/javascript
		}
		file_server
	}

	# SPA: never cache the shell, fall back to index.html for client routes.
	handle {
		header /index.html Cache-Control "no-store"
		try_files {path} /index.html
		file_server
	}
}
