--- phase: 01-dev-environment plan: 01 type: execute wave: 1 depends_on: [] files_modified: - flake.nix - dev/process-compose.yaml - dev/setup.sh - .gitignore - .envrc autonomous: true requirements: - DEV-01 must_haves: truths: - "nix develop drops into a shell with PHP 8.2+, Composer 2.x, Node 22.x, MariaDB, symfony-cli, and process-compose" - "process-compose up starts MariaDB on port 3307 with a local data directory and Symfony dev server" - "setup.sh clones Kimai, installs deps, creates DB, loads fixtures, and symlinks plugin" artifacts: - path: "flake.nix" provides: "Nix devshell with all required packages and PHP extensions" contains: "php82" - path: "dev/process-compose.yaml" provides: "MariaDB + Symfony dev server process definitions" contains: "mariadb" - path: "dev/setup.sh" provides: "One-time Kimai bootstrap script" contains: "kimai:reset:dev" - path: ".gitignore" provides: "Ignore dev artifacts (kimai clone, mariadb data, node_modules)" contains: "dev/kimai" key_links: - from: "dev/process-compose.yaml" to: "dev/.mariadb-data" via: "mysqld --datadir" pattern: "mariadb-data" - from: "dev/setup.sh" to: "dev/kimai" via: "git clone kimai" pattern: "git clone.*kimai" --- Create the Nix flake, process-compose config, and bootstrap script for the Kimai dev environment. Purpose: Provide a reproducible, one-command dev setup that gives the developer PHP 8.2+, MariaDB, Composer, Node, and all tooling needed for Kimai plugin development. Output: flake.nix, dev/process-compose.yaml, dev/setup.sh, .gitignore @/home/toph/code/toph/kimai-heatmap/.claude/get-shit-done/workflows/execute-plan.md @/home/toph/code/toph/kimai-heatmap/.claude/get-shit-done/templates/summary.md @.planning/PROJECT.md @.planning/ROADMAP.md @.planning/phase-1/RESEARCH.md Task 1: Create Nix flake with devshell flake.nix, .envrc, .gitignore Create `flake.nix` with a devshell providing: **Packages:** - PHP 8.2 with extensions: gd, intl, mbstring, pdo, pdo_mysql, xml, xsl, zip, tokenizer (use `pkgs.php82.buildEnv { extensions = { enabled, all }: enabled ++ (with all; [ xsl pdo_mysql ]); }`) - `pkgs.php82Packages.composer` for Composer - `pkgs.nodejs` (22.x) for JS tooling - `pkgs.mariadb` (11.4.x) for database - `pkgs.symfony-cli` for Symfony dev server - `pkgs.process-compose` for multi-service management **Flake structure:** - Use `flake-utils.lib.eachDefaultSystem` for portability - Input: `nixpkgs` (use `github:NixOS/nixpkgs/nixpkgs-unstable`) - Single devShell output - Shell hook: print a short message with available commands (setup, start) **Also create:** - `.envrc` with `use flake` for direnv integration - `.gitignore` with entries for: - `dev/kimai/` (cloned Kimai instance) - `dev/.mariadb-data/` (MariaDB data directory) - `dev/.mariadb.sock` (MariaDB socket) - `dev/.mariadb.pid` (MariaDB PID file) - `node_modules/` - `vendor/` - `.direnv/` - `result` (nix build output) - `*.js.map` (source maps) - `dist/` (built JS output) cd /home/toph/code/toph/kimai-heatmap && nix develop --command bash -c "php --version && composer --version && node --version && mysqld --version && symfony version && process-compose version" 2>&1 | head -20 nix develop provides PHP 8.2+, Composer, Node 22.x, MariaDB, symfony-cli, and process-compose. All commands resolve. Task 2: Create process-compose config and setup script dev/process-compose.yaml, dev/setup.sh **Create `dev/process-compose.yaml`:** ```yaml version: "0.5" processes: mariadb: command: | mysqld --datadir=$PWD/dev/.mariadb-data \ --socket=$PWD/dev/.mariadb.sock \ --port=3307 \ --skip-grant-tables \ --skip-networking=false \ --bind-address=127.0.0.1 readiness_probe: exec: command: mysqladmin --socket=$PWD/dev/.mariadb.sock ping initial_delay_seconds: 2 period_seconds: 1 shutdown: command: mysqladmin --socket=$PWD/dev/.mariadb.sock shutdown kimai: command: symfony server:start --no-tls --dir=$PWD/dev/kimai --port=8010 depends_on: mariadb: condition: process_healthy ``` Use port 8010 for Kimai to avoid conflicts. Use `$PWD` for paths so process-compose works from project root. **Create `dev/setup.sh`** (make executable with `chmod +x`): The script should: 1. Check if already set up (if `dev/kimai` exists, skip clone) 2. Initialize MariaDB data directory if not present: ```bash mysql_install_db --datadir=./dev/.mariadb-data --auth-root-authentication-method=normal ``` 3. Start MariaDB temporarily for setup (background, wait for ready): ```bash mysqld --datadir=./dev/.mariadb-data --socket=./dev/.mariadb.sock --port=3307 --skip-grant-tables --bind-address=127.0.0.1 & MARIADB_PID=$! # Wait for MariaDB to be ready for i in $(seq 1 30); do mysqladmin --socket=./dev/.mariadb.sock ping 2>/dev/null && break; sleep 1; done ``` 4. Create the `kimai` database: ```bash mysql --socket=./dev/.mariadb.sock -e "CREATE DATABASE IF NOT EXISTS kimai;" ``` 5. Clone Kimai 2.52.0: ```bash git clone -b 2.52.0 --depth 1 https://github.com/kimai/kimai.git dev/kimai ``` 6. Configure Kimai `.env.local` (NOT .env -- .env.local overrides): ```bash cat > dev/kimai/.env.local << 'ENVEOF' DATABASE_URL=mysql://root@127.0.0.1:3307/kimai?charset=utf8mb4&serverVersion=11.4.8-MariaDB APP_SECRET=change-me-dev-only-not-production APP_ENV=dev ENVEOF ``` 7. Run Composer install in Kimai: ```bash cd dev/kimai && composer install --no-interaction ``` 8. Run Kimai install (creates schema): ```bash bin/console kimai:install -n ``` 9. Load dev fixtures (seeds test data): ```bash bin/console kimai:reset:dev -n ``` 10. Symlink plugin directory: ```bash mkdir -p var/plugins ln -sf "$(cd ../.. && pwd)" var/plugins/KimaiHeatmapBundle ``` 11. Clear Kimai cache: ```bash bin/console cache:clear ``` 12. Stop temporary MariaDB: ```bash kill $MARIADB_PID 2>/dev/null wait $MARIADB_PID 2>/dev/null ``` 13. Print success message with instructions to run `process-compose -f dev/process-compose.yaml up` **Important details:** - Use `set -euo pipefail` at the top - Use `127.0.0.1` NOT `localhost` in DATABASE_URL (localhost triggers Unix socket mode on Linux) - The symlink target name MUST be `KimaiHeatmapBundle` (matches bundle class name) - Use `--skip-grant-tables` for MariaDB since this is local dev only - The script must be idempotent: skip steps that are already done (check for existing directories) cd /home/toph/code/toph/kimai-heatmap && test -x dev/setup.sh && test -f dev/process-compose.yaml && head -5 dev/process-compose.yaml | grep -q "version" && echo "OK" dev/process-compose.yaml defines MariaDB + Kimai processes with health checks. dev/setup.sh is executable and contains the full bootstrap sequence (clone, install, seed, symlink). ## Trust Boundaries | Boundary | Description | |----------|-------------| | Local dev only | No external network exposure; MariaDB binds to 127.0.0.1, Kimai on localhost:8010 | ## STRIDE Threat Register | Threat ID | Category | Component | Disposition | Mitigation Plan | |-----------|----------|-----------|-------------|-----------------| | T-01-01 | Information Disclosure | MariaDB --skip-grant-tables | accept | Local dev only, bound to 127.0.0.1, no production data. Acceptable for dev environment. | | T-01-02 | Information Disclosure | APP_SECRET in .env.local | accept | Dev-only value, .env.local is gitignored inside dev/kimai/ (Kimai's own .gitignore), not committed to plugin repo | 1. `nix develop` provides all required tools (PHP 8.2+, Composer, Node, MariaDB, symfony-cli, process-compose) 2. `dev/setup.sh` exists, is executable, and contains the complete bootstrap sequence 3. `dev/process-compose.yaml` defines MariaDB and Kimai processes with dependency ordering 4. `.gitignore` excludes dev artifacts Running `nix develop` enters a shell with all dev tools. The setup script and process-compose config are ready to be executed in Plan 02. After completion, create `.planning/phases/01-dev-environment/01-01-SUMMARY.md`