# Kaiser Natron — SPA static serve config.
# Mounted into /etc/nginx/conf.d/default.conf by the Dockerfile.

server {
    listen      80 default_server;
    listen      [::]:80 default_server;
    server_name _;

    root  /usr/share/nginx/html;
    index index.html;

    # ── Compression ───────────────────────────────────────────────────────
    gzip              on;
    gzip_vary         on;
    gzip_min_length   1024;
    gzip_comp_level   6;
    gzip_types        text/plain
                      text/css
                      text/javascript
                      application/javascript
                      application/json
                      image/svg+xml
                      font/woff2;

    # ── Security headers ─────────────────────────────────────────────────
    # Mirror the hardening we observed on the live site and tighten where possible.
    add_header X-Frame-Options           "SAMEORIGIN"                        always;
    add_header X-Content-Type-Options    "nosniff"                           always;
    add_header Referrer-Policy           "strict-origin-when-cross-origin"   always;
    add_header Permissions-Policy        "camera=(), microphone=(), geolocation=()" always;
    # Keep CSP loose enough for Vue + Tailwind inline styles. Tighten once the
    # backend is wired and we know which origins we need to whitelist.
    add_header Content-Security-Policy   "default-src 'self'; img-src 'self' data: blob:; style-src 'self' 'unsafe-inline'; script-src 'self'; font-src 'self' data:; connect-src 'self'; frame-ancestors 'self'; base-uri 'self'; form-action 'self'" always;

    # ── Healthcheck ──────────────────────────────────────────────────────
    location = /health {
        access_log off;
        add_header Content-Type text/plain;
        return 200 "ok\n";
    }

    # ── Hashed build assets — long-cache ─────────────────────────────────
    # Vite emits filenames like assets/foo-<hash>.js, safe to cache for a year.
    location /assets/ {
        access_log off;
        expires    1y;
        add_header Cache-Control "public, max-age=31536000, immutable";
        try_files  $uri =404;
    }

    # ── Everything else: SPA fallback ────────────────────────────────────
    # index.html must never be cached so users pick up new asset hashes on deploy.
    location = /index.html {
        add_header Cache-Control "no-store, must-revalidate" always;
    }

    location / {
        try_files $uri $uri/ /index.html;
    }

    # Don't serve dotfiles that somehow end up in the doc root.
    location ~ /\. {
        deny all;
        return 404;
    }
}
