kimai-plugin-heatmap/.planning/phases/01-dev-environment/01-01-PLAN.md
Christopher Mühl 5bdb8bf3f5
docs(01): create phase 1 dev environment plans
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-08 11:05:45 +02:00

8.6 KiB

phase plan type wave depends_on files_modified autonomous requirements must_haves
01-dev-environment 01 execute 1
flake.nix
dev/process-compose.yaml
dev/setup.sh
.gitignore
.envrc
true
DEV-01
truths artifacts key_links
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
path provides contains
flake.nix Nix devshell with all required packages and PHP extensions php82
path provides contains
dev/process-compose.yaml MariaDB + Symfony dev server process definitions mariadb
path provides contains
dev/setup.sh One-time Kimai bootstrap script kimai:reset:dev
path provides contains
.gitignore Ignore dev artifacts (kimai clone, mariadb data, node_modules) dev/kimai
from to via pattern
dev/process-compose.yaml dev/.mariadb-data mysqld --datadir mariadb-data
from to via pattern
dev/setup.sh dev/kimai git clone kimai 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

<execution_context> @/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 </execution_context>

@.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`:**
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:
    mysql_install_db --datadir=./dev/.mariadb-data --auth-root-authentication-method=normal
    
  3. Start MariaDB temporarily for setup (background, wait for ready):
    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:
    mysql --socket=./dev/.mariadb.sock -e "CREATE DATABASE IF NOT EXISTS kimai;"
    
  5. Clone Kimai 2.52.0:
    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):
    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:
    cd dev/kimai && composer install --no-interaction
    
  8. Run Kimai install (creates schema):
    bin/console kimai:install -n
    
  9. Load dev fixtures (seeds test data):
    bin/console kimai:reset:dev -n
    
  10. Symlink plugin directory:
    mkdir -p var/plugins
    ln -sf "$(cd ../.. && pwd)" var/plugins/KimaiHeatmapBundle
    
  11. Clear Kimai cache:
    bin/console cache:clear
    
  12. Stop temporary MariaDB:
    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).

<threat_model>

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
</threat_model>
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

<success_criteria> 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. </success_criteria>

After completion, create `.planning/phases/01-dev-environment/01-01-SUMMARY.md`