Jeppe Bundgaard 56685d7bf3 Add tests and functionality for edge gateway updates and lifecycle
This commit introduces unit tests, E2E tests, and implementation updates related to edge gateway lifecycle management, including update handling, artifact validation, and rollback mechanisms. It also refines routing, component interaction, and backend methods to improve update tracking, status transitions, and artifact management.
2026-04-15 11:53:45 +02:00
2025-01-29 14:27:44 +01:00

Copenhagen Truck Wash API

Backend API for Copenhagen Truck Wash services.

Architecture & Stack

  • Edge Proxy: Traefik 2.11 (Handles TLS termination, routing, and rate limiting).
  • Web Server: Caddy 2.7 (Serves the PHP application via FastCGI).
  • PHP Runtime: PHP 8.2-FPM (Scale out with workers php1 to php5).
  • Cache/Queue: Redis 7.
  • Observability: Jaeger (Tracing), Prometheus (Metrics).

Getting Started

Prerequisites

  • Docker Desktop 4.x+
  • PHP 8.2 CLI (optional, for host-side testing)

Local Development

To bring up the minimal development stack (Traefik, Redis, MySQL debug DB, Caddy, and one PHP worker):

docker compose up -d traefik redis mysql-debug php1 caddy

The API is accessible at:

  • http://localhost
  • https://localhost (using Traefik default cert)
  • http(s)://localhost/api/ (proxied with /api prefix stripped)

To start all services including multiple PHP workers and development tools (Jaeger, Portainer):

docker compose --profile dev up -d

Configuration

Configuration is primarily managed via environment variables.

  • The application root is located at services/nginx/app.
  • services/nginx/app/config.php loads configuration from the environment (requires USE_ENV=true).
  • php1 performs an automatic composer install on startup if AUTO_COMPOSER_INSTALL=true.

Environment Change Runbook

When updating .env values used by PHP containers (for example e-conomic tokens), recreate affected services so Docker applies the new env:

docker compose up -d --force-recreate php1 php2 php3 php4 php5 php-cron

Testing

The project now uses Pest as the primary test runner in services/nginx/app.

Running Tests

All commands are run from services/nginx/app:

composer test
composer test:unit
composer test:integration
composer test:api
composer test:coverage

For local Docker development, run the PHP suites inside php1:

docker exec php1 sh -lc "cd /var/www/html && composer test:unit"
docker exec php1 sh -lc "cd /var/www/html && composer test:integration"
docker exec php1 sh -lc "cd /var/www/html && composer test:api"

Integration tests are opt-in and should be run with required services available:

$env:RUN_INTEGRATION_TESTS='1'
composer test:integration

API Test Suite

The Api suite exercises real HTTP endpoints instead of calling route handlers in-process.

  • composer test:api enables RUN_API_TESTS=1 automatically.
  • By default the suite starts a temporary PHP server with php -S 127.0.0.1:18080 index.php and hits the app over HTTP.
  • The suite covers the real router, request parsing, auth headers, status codes, and JSON response envelopes.
  • Tests run serially and use explicit database/Redis fixtures plus reverse-order cleanup instead of transaction rollbacks.
  • The default phase-1 coverage includes /ping, auth session routes, departments, department categories, and orders CRUD including the legacy PUT /order alias.
  • API server logs are written to services/nginx/app/build/logs/api-server.out.log and services/nginx/app/build/logs/api-server.err.log.

To point the suite at an already-running base URL instead of the self-started PHP server:

$env:API_TEST_BASE_URL='http://127.0.0.1:18080'
composer test:api

The suite requires an initialized application schema. Redis-backed flows are used when Redis is configured, but the suite can still boot without caddy or the full reverse-proxy stack.

Run Tests Against A Cloned Live DB (Docker-Isolated)

Use the helper scripts in scripts/ to:

  1. Clone the configured live DB into a local MySQL Docker container.
  2. Start an isolated Redis container.
  3. Run tests in a separate temporary PHP Docker container pointed at that clone.

PowerShell:

powershell -ExecutionPolicy Bypass -File .\scripts\clone-live-db-and-test.ps1 -Force

Bash:

FORCE=1 ./scripts/clone-live-db-and-test.sh

Optional overrides:

  • Test command: -TestCommand "composer test:integration" or TEST_COMMAND="composer test:integration"
  • Keep containers after run: -KeepContainers or KEEP_CONTAINERS=1
  • Skip image build: -SkipBuild or SKIP_BUILD=1
  • Force image rebuild: -ForceBuild or FORCE_BUILD=1

Clone Live DB Into mysql-debug Service

To refresh the docker-compose debug DB from live credentials in .env:

PowerShell:

powershell -ExecutionPolicy Bypass -File .\scripts\clone-live-to-debug-db.ps1 -Force

Bash:

FORCE=1 ./scripts/clone-live-to-debug-db.sh

Test Layout

  • tests/Unit/*: isolated unit and route-level behavior tests.
  • tests/Integration/*: Redis/DB-backed tests intended for Docker/CI environments.
  • tests/Api/*: real HTTP endpoint tests that boot a temporary PHP server and assert full request/response behavior.
  • tests/Api/api_coverage_manifest.php: selected phase-1 endpoint manifest used by the API meta-test to enforce happy-path and failure coverage.
  • tests/<legacy-domain>/*: legacy procedural scripts retained during migration; keep them runnable until matching Pest coverage exists.

Logs & Monitoring

  • Logs: docker compose logs -f [service_name] (e.g., php1, caddy, traefik).
  • Traefik Dashboard: http://traefik.localhost (available in dev).
  • Jaeger (Tracing): http://localhost:16686 (when running with --profile dev).
  • Portainer: http://localhost:9000 (when running with --profile dev).

API Documentation

  • OpenAPI: The authoritative OpenAPI 3.0 contract is at openapi.yaml.
  • Self-Serve Module Guide: Implementation and API guide at services/nginx/app/modules/selfserve/selfserve.md.
  • Writerside: Documentation projects are located in /Writerside and /Writerside2.
  • Generated Writerside API Reference: The active Writerside project lives in /documentation and is generated from openapi.yaml.

Writerside OpenAPI Generation Workflow

Prerequisite:

  • Python 3 with PyYAML (pip install pyyaml)

Run from repository root:

python scripts/generate_writerside_openapi_docs.py generate
python scripts/generate_writerside_openapi_docs.py check

Contribution rule:

  1. Update openapi.yaml.
  2. Regenerate docs (python scripts/generate_writerside_openapi_docs.py generate).
  3. Verify (python scripts/generate_writerside_openapi_docs.py check).
S
Description
Staging repo for api (CI + promotion to GitHub)
Readme
40 MiB
Languages
PHP 93.5%
HTML 3.5%
JavaScript 1.9%
Shell 0.4%
Python 0.3%
Other 0.3%