# Swansea Airport Website

Production-ready airfield website stack built with Astro, Directus, PostgreSQL, and Docker Compose.

## Local setup

1. Copy `.env.example` to `.env` and fill in the values.
2. Start the stack with Docker Compose.
3. Point your external Caddy instance at the frontend and Directus ports defined in `.env`.

## Services

- Frontend: Astro dev server running in a bind-mounted container for live preview
- CMS: Directus
- Database: PostgreSQL
- CMS bootstrap: one-shot schema initializer (`directus-bootstrap`)

## Notes

- All deploy-time variables live in `.env`.
- `PUBLIC_PPR_API_BASE` controls the browser-side PPR API base URL; PPR and drone request endpoints are derived from it at build/dev-server startup.
- `DIRECTUS_TOKEN` is the preferred read-only token for Astro content builds; `DIRECTUS_ADMIN_TOKEN` is still used by Directus/bootstrap setup.
- `DIRECTUS_DEBUG=true` makes Astro log Directus fetch/fallback reasons during builds.
- `DIRECTUS_HOMEPAGE_BANNER_FOLDER` names the Directus file folder used for rotating homepage banner images. If the folder is missing or empty, the site falls back to `/images/banner.png`.
- The frontend service bind-mounts the project into `/app`, keeps `node_modules` and `.astro` in named volumes, and serves the site with `astro dev` on the published frontend port.
- Layout and page structure are controlled entirely by Astro.
- Frontend source edits should appear without rebuilding the container image.
- Cloudflare Worker deployment uses Wrangler static assets. See `docs/cloudflare-worker.md` for the test/prod URL workflow.

## Cloudflare Worker deployment

This project is normally developed through Docker Compose, so run the Worker build/deploy scripts inside the `web` service.

Copy the Worker env files first:

```bash
cp .env.worker.test.example .env.worker.test
cp .env.worker.prod.example .env.worker.prod
```

Build static files with the test URL set:

```bash
docker compose exec web npm run build:worker:test
```

Deploy the test build to the test Cloudflare Worker:

```bash
docker compose exec web npm run deploy:worker:test
```

Deploy production with the production URL set:

```bash
docker compose exec web npm run deploy:worker:prod
```

The deploy scripts build first, then upload `dist/` with Wrangler. The `test` command uses `.env.worker.test`; the production command uses `.env.worker.prod`.

## Programmatic Directus schema bootstrap

The schema bootstrap is automatic on `docker compose up` via the `directus-bootstrap` service.
It creates collections, fields, and core tag relations idempotently.

If the frontend dependency graph changes, restart the frontend container to rerun `npm install` inside the container volume:

```bash
docker compose up --build -d web
```

You can still run the script manually if needed:

```bash
docker compose run --rm directus-bootstrap
```

The bootstrap script is idempotent, so reruns are safe.

## Troubleshooting bootstrap permissions

If you see `403 FORBIDDEN` during bootstrap:

- Most commonly, the Directus database volume was initialized earlier with different admin credentials.
- `DIRECTUS_ADMIN_EMAIL` and `DIRECTUS_ADMIN_PASSWORD` are only used when Directus initializes a new database.
- For stable bootstrap auth across restarts, set `DIRECTUS_ADMIN_TOKEN` in `.env` and keep it constant.

To start from a clean Directus state (development only):

```bash
docker compose down -v
docker compose up -d
```
