# local-dev-environment Specification

## Requirements

### Requirement: Docker Compose development stack

The project MUST provide a Docker Compose stack with an `app` service (`php:8.4-fpm`), a `web`
service (`nginx`), and a `db` service (`mysql:8.4`). The stack MAY include a `redis` service and
MUST provide a `node` tooling service for asset tasks.

#### Scenario: Stack starts all required services

- GIVEN a configured Docker Compose environment
- WHEN the developer runs the documented stack-up command
- THEN `app`, `web`, and `db` containers are running
- AND the `web` service serves the application over HTTP

#### Scenario: Optional services remain isolated

- GIVEN the stack is started without the optional `redis` service
- WHEN the application boots
- THEN the application starts successfully without Redis connectivity

### Requirement: Reproducible provisioning commands

The project MUST document, for Windows PowerShell, the commands to build images, start the stack,
create the Laravel project, run migrations, and install/build frontend assets. The commands MUST be
copy-paste reproducible on a fresh clone.

#### Scenario: Documented commands bootstrap the app

- GIVEN a fresh clone on Windows with Docker Desktop, PHP 8.3+, Composer, and Node 20+
- WHEN the developer runs the documented commands in order
- THEN the project installs dependencies, migrates the database, and builds assets without errors

#### Scenario: Asset build runs through the node tooling service

- GIVEN the stack is running
- WHEN the developer runs the documented `npm install` and `npm run build` commands
- THEN assets are produced and served by the `web` service

### Requirement: Environment wiring

The `.env` configuration MUST set `APP_URL` to `http://127.0.0.1:8001`, `DB_HOST` to `db`, and
`DB_PORT` to `3306` so the application connects to the Compose database. The `web` service MUST be
published on host port `8001` because host port `8000` is occupied by another project on the
development machine; clients MUST use `127.0.0.1` instead of `localhost` (which resolves to IPv6
`::1` on Windows and times out).

#### Scenario: Application reaches the database by service name

- GIVEN the stack is running with default environment values
- WHEN the application executes a database query
- THEN the connection is established to host `db` on port `3306`

#### Scenario: App is reachable at the documented URL

- GIVEN the stack is running
- WHEN a client requests `http://127.0.0.1:8001`
- THEN the application responds with HTTP 200

### Requirement: Repository hygiene and line-ending policy

The repository MUST enforce LF line endings via `.gitattributes` and `.editorconfig`, MUST include
a `.dockerignore`, and MUST use named volumes for `vendor/` and `node_modules/`.

#### Scenario: Checkout normalizes line endings

- GIVEN a checkout on Windows
- WHEN files are read by the editor and Git
- THEN text files use LF line endings per the repository policy

#### Scenario: Dependencies persist across container rebuilds

- GIVEN `vendor/` and `node_modules/` are backed by named volumes
- WHEN containers are recreated without removing volumes
- THEN installed dependencies remain available

### Requirement: Fresh clone responds at 127.0.0.1:8001

A fresh clone MUST be brought up using only the documented commands and MUST respond at
`http://127.0.0.1:8001` with the application rendered.

#### Scenario: End-to-end fresh clone bootstrap

- GIVEN no containers, volumes, or local dependencies exist
- WHEN the developer executes the documented bootstrap sequence
- THEN the site loads at `http://127.0.0.1:8001`
- AND the database schema is migrated
