From 5ae612227ebc35084bd21f08fc849c023249f24e Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 4 Nov 2025 21:41:27 +0000 Subject: [PATCH 1/2] Add Claude.md and Foundation skills - Created Claude.md with comprehensive project context for AI assistant - Added 7 skills for common development workflows: - docker-setup: Initialize Docker development environment - create-module: Scaffold new DDD modules following framework architecture - run-tests: Execute PHPUnit test suites with coverage - static-analysis: Run PHPStan and Deptrac for code quality - database-operations: Database import, export, and management - troubleshoot-docker: Diagnostic steps for Docker issues - debug-setup: Configure Xdebug for PHPStorm and VS Code Each skill includes step-by-step instructions, verification steps, troubleshooting guides, and quick reference commands. --- .claude/skills/foundation/create-module.md | 320 +++++++++++ .../skills/foundation/database-operations.md | 364 ++++++++++++ .claude/skills/foundation/debug-setup.md | 433 +++++++++++++++ .claude/skills/foundation/docker-setup.md | 155 ++++++ .claude/skills/foundation/run-tests.md | 332 +++++++++++ .claude/skills/foundation/static-analysis.md | 402 ++++++++++++++ .../skills/foundation/troubleshoot-docker.md | 524 ++++++++++++++++++ Claude.md | 382 +++++++++++++ 8 files changed, 2912 insertions(+) create mode 100644 .claude/skills/foundation/create-module.md create mode 100644 .claude/skills/foundation/database-operations.md create mode 100644 .claude/skills/foundation/debug-setup.md create mode 100644 .claude/skills/foundation/docker-setup.md create mode 100644 .claude/skills/foundation/run-tests.md create mode 100644 .claude/skills/foundation/static-analysis.md create mode 100644 .claude/skills/foundation/troubleshoot-docker.md create mode 100644 Claude.md diff --git a/.claude/skills/foundation/create-module.md b/.claude/skills/foundation/create-module.md new file mode 100644 index 0000000..c62087e --- /dev/null +++ b/.claude/skills/foundation/create-module.md @@ -0,0 +1,320 @@ +# Create Module + +Create a new module in the Foundation framework following Domain-Driven Design principles and clean architecture. + +## When to use this skill + +- User asks to "create a new module" +- User asks to "add a module" +- User asks to "scaffold a module" +- User wants to add new business functionality +- User mentions "new feature module" + +## Steps + +1. **Create Module Directory Structure** + + Create the base directory and three-layer architecture: + ```bash + mkdir -p src/Modules/{ModuleName}/Domain + mkdir -p src/Modules/{ModuleName}/Application + mkdir -p src/Modules/{ModuleName}/Infrastructure/Api + mkdir -p src/Modules/{ModuleName}/Infrastructure/Web + mkdir -p src/Modules/{ModuleName}/Infrastructure/Database/Commands + mkdir -p src/Modules/{ModuleName}/Infrastructure/Database/Queries + ``` + +2. **Create Domain Layer** (Pure business logic) + + Create domain entities, value objects, and repository interfaces: + + ```php + // src/Modules/{ModuleName}/Domain/{Entity}.php + id; } + // Add getters and business methods + } + ``` + + ```php + // src/Modules/{ModuleName}/Domain/{Repository}Interface.php + fetchById->execute($id); + } + + public function save({Entity} $entity): void + { + $this->save->execute($entity); + } + } + ``` + + **b) Create Database Commands/Queries:** + ```php + // src/Modules/{ModuleName}/Infrastructure/Database/Queries/FetchByIdQuery.php + pdo->prepare("SELECT * FROM {table} WHERE id = ?"); + $stmt->execute([$id]); + $data = $stmt->fetch(PDO::FETCH_ASSOC); + + return $data ? new {Entity}(/* map data */) : null; + } + } + ``` + + **c) Create Controller:** + ```php + // src/Modules/{ModuleName}/Infrastructure/Api/{Controller}.php + register(FetchByIdQuery::class, [\PDO::class]); + + // Register commands + $container->register(SaveCommand::class, [\PDO::class]); + + // Register repository + $container->bind( + {Repository}Interface::class, + {Repository}::class, + [FetchByIdQuery::class, SaveCommand::class] + ); + + // Register use cases + $container->register( + {UseCase}::class, + [{Repository}Interface::class] + ); + + // Register controllers (routes auto-discovered via attributes) + $container->register( + {Controller}::class, + [{UseCase}::class] + ); + } + } + ``` + +6. **Refresh Autoloader** + ```bash + make dump-autoload + ``` + +## Verification + +1. **Check Module is Auto-Discovered** + + The `ModuleLoader` bootstrapper automatically discovers service providers in `src/Modules/*/`. + No additional registration needed. + +2. **Verify Routes are Registered** + + Access the controller endpoint to verify routes are working: + ```bash + curl http://localhost:8000/api/{module-name} + ``` + +3. **Check Service Container** + + Verify services are properly registered by accessing them in a controller or test. + +## Layer Dependency Rules + +**IMPORTANT**: Always follow these strict dependency rules: + +- **Domain Layer**: NO dependencies on other layers + - Only pure PHP and domain concepts + - No framework dependencies + - No database or HTTP concerns + +- **Application Layer**: Can depend on Domain only + - Orchestrates domain logic + - Defines use cases + - No framework dependencies + +- **Infrastructure Layer**: Can depend on Application and itself + - Implements repository interfaces + - Contains controllers, commands, queries + - Has framework dependencies + +## Troubleshooting + +### Module Not Auto-Discovered + +**Problem**: Service provider not loaded automatically. + +**Solution**: +1. Verify service provider is in: `src/Modules/{ModuleName}/{ModuleName}ServiceProvider.php` +2. Verify it extends `Foundation\Core\Application\ServiceProvider\ServiceProvider` +3. Check namespace matches directory structure +4. Run `make dump-autoload` + +### Routes Not Working + +**Problem**: Controller routes not accessible. + +**Solution**: +1. Verify controller implements `Foundation\Core\Infrastructure\ControllerInterface` +2. Check route attributes are properly imported and used +3. Verify controller is registered in service provider +4. Check for route conflicts with existing routes + +### Autoloading Issues + +**Problem**: Class not found errors. + +**Solution**: +```bash +make dump-autoload +``` + +Verify namespace matches directory structure following PSR-4: +- `Foundation\Modules\{ModuleName}` → `src/Modules/{ModuleName}` + +## Examples + +See existing modules for reference: +- `src/Modules/WelcomeScreen/` - Complete example module + +## Quick Checklist + +- [ ] Created Domain layer (entities, interfaces) +- [ ] Created Application layer (use cases) +- [ ] Created Infrastructure layer (controllers, repositories, commands, queries) +- [ ] Created Service Provider +- [ ] Service provider extends `ServiceProvider` +- [ ] Service provider in correct location +- [ ] Controllers implement `ControllerInterface` +- [ ] Routes use attributes (#[Get], #[Post], etc.) +- [ ] Repository interfaces in Domain layer +- [ ] Repository implementations in Infrastructure layer +- [ ] Followed layer dependency rules +- [ ] Ran `make dump-autoload` +- [ ] Verified routes are accessible diff --git a/.claude/skills/foundation/database-operations.md b/.claude/skills/foundation/database-operations.md new file mode 100644 index 0000000..bee918d --- /dev/null +++ b/.claude/skills/foundation/database-operations.md @@ -0,0 +1,364 @@ +# Database Operations + +Perform common database operations in the Foundation framework Docker environment. + +## When to use this skill + +- User asks to "import database schema" +- User asks to "backup database" +- User asks to "restore database" +- User asks to "access database" +- User asks to "export database" +- User mentions "database migration" or "schema setup" +- Setting up project for first time +- Need to reset database to clean state + +## Steps + +### Import Database Schema + +1. **Import SQL Schema File** + ```bash + docker compose exec -T db mysql -u foundation_user -pfoundation_password foundation < database/schema.sql + ``` + + This imports the database schema from `database/schema.sql` into the `foundation` database. + +### Access Database CLI + +2. **Access MySQL Command Line** + ```bash + docker compose exec db mysql -u foundation_user -pfoundation_password foundation + ``` + + You'll be in the MySQL CLI. Common commands: + ```sql + -- Show all tables + SHOW TABLES; + + -- Describe table structure + DESCRIBE table_name; + + -- Query data + SELECT * FROM table_name; + + -- Exit + exit; + ``` + +### Backup Database + +3. **Export Database to File** + ```bash + docker compose exec db mysqldump -u foundation_user -pfoundation_password foundation > backup.sql + ``` + + Creates `backup.sql` in current directory with complete database dump. + +4. **Export with Timestamp** + ```bash + docker compose exec db mysqldump -u foundation_user -pfoundation_password foundation > backup-$(date +%Y%m%d-%H%M%S).sql + ``` + + Creates timestamped backup file (e.g., `backup-20240115-143022.sql`). + +### Restore Database + +5. **Restore from Backup** + ```bash + docker compose exec -T db mysql -u foundation_user -pfoundation_password foundation < backup.sql + ``` + + Restores database from backup file. + +### Reset Database + +6. **Drop and Recreate Database** + ```bash + docker compose exec db mysql -u foundation_user -pfoundation_password -e "DROP DATABASE IF EXISTS foundation; CREATE DATABASE foundation;" + docker compose exec -T db mysql -u foundation_user -pfoundation_password foundation < database/schema.sql + ``` + + Completely resets database to clean state from schema file. + +### Access via phpMyAdmin + +7. **Use phpMyAdmin GUI** + - Open browser: http://localhost:8080 + - Server: `db` + - Username: `foundation_user` + - Password: `foundation_password` + - Database: `foundation` + +## Verification + +### Verify Import Success + +1. **Check Tables Exist** + ```bash + docker compose exec db mysql -u foundation_user -pfoundation_password foundation -e "SHOW TABLES;" + ``` + + Should list all tables from the schema. + +2. **Verify Table Structure** + ```bash + docker compose exec db mysql -u foundation_user -pfoundation_password foundation -e "DESCRIBE users;" + ``` + + Shows structure of `users` table (adjust table name as needed). + +### Verify Backup Success + +```bash +# Check file was created and has content +ls -lh backup.sql +head -n 20 backup.sql +``` + +Should show file with SQL dump content. + +## Common Database Tasks + +### Create New Table + +```bash +docker compose exec db mysql -u foundation_user -pfoundation_password foundation << EOF +CREATE TABLE example ( + id INT PRIMARY KEY AUTO_INCREMENT, + name VARCHAR(255) NOT NULL, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP +); +EOF +``` + +### Run SQL File + +```bash +docker compose exec -T db mysql -u foundation_user -pfoundation_password foundation < path/to/file.sql +``` + +### Execute Single SQL Command + +```bash +docker compose exec db mysql -u foundation_user -pfoundation_password foundation -e "SELECT COUNT(*) FROM users;" +``` + +### Export Specific Table + +```bash +docker compose exec db mysqldump -u foundation_user -pfoundation_password foundation table_name > table_backup.sql +``` + +### Copy Database + +```bash +# Backup +docker compose exec db mysqldump -u foundation_user -pfoundation_password foundation > temp_backup.sql + +# Restore to new database +docker compose exec db mysql -u foundation_user -pfoundation_password -e "CREATE DATABASE foundation_copy;" +docker compose exec -T db mysql -u foundation_user -pfoundation_password foundation_copy < temp_backup.sql +``` + +## Troubleshooting + +### Connection Refused + +**Problem**: Can't connect to database. + +**Solution**: +1. Check database container is running: + ```bash + docker compose ps + ``` +2. Verify database service is healthy: + ```bash + docker compose logs db + ``` +3. Restart database: + ```bash + docker compose restart db + ``` + +### Access Denied + +**Problem**: Authentication failed with error "Access denied for user". + +**Solution**: +1. Verify credentials in command match Docker environment: + - Username: `foundation_user` + - Password: `foundation_password` + - Database: `foundation` +2. Check environment variables in `docker-compose.yml` +3. If changed, rebuild containers: + ```bash + make down + make up + ``` + +### Schema Import Errors + +**Problem**: Import fails with SQL syntax errors. + +**Solution**: +1. Check SQL file syntax is valid +2. Verify file encoding (should be UTF-8) +3. Check for incompatible MySQL version syntax +4. Try importing via phpMyAdmin to see detailed error + +### Table Already Exists + +**Problem**: Import fails because tables already exist. + +**Solution**: + +**Option 1**: Drop database first: +```bash +docker compose exec db mysql -u foundation_user -pfoundation_password -e "DROP DATABASE foundation; CREATE DATABASE foundation;" +docker compose exec -T db mysql -u foundation_user -pfoundation_password foundation < database/schema.sql +``` + +**Option 2**: Use `IF NOT EXISTS` in schema: +```sql +CREATE TABLE IF NOT EXISTS users (...); +``` + +### Backup File Too Large + +**Problem**: Backup file is very large and slow. + +**Solution**: +1. **Compress during backup**: + ```bash + docker compose exec db mysqldump -u foundation_user -pfoundation_password foundation | gzip > backup.sql.gz + ``` + +2. **Restore from compressed**: + ```bash + gunzip < backup.sql.gz | docker compose exec -T db mysql -u foundation_user -pfoundation_password foundation + ``` + +### Database Locked + +**Problem**: Operations timeout or fail with "database is locked". + +**Solution**: +1. Check for long-running queries: + ```bash + docker compose exec db mysql -u foundation_user -pfoundation_password foundation -e "SHOW PROCESSLIST;" + ``` +2. Kill problematic query (get ID from processlist): + ```bash + docker compose exec db mysql -u foundation_user -pfoundation_password foundation -e "KILL ;" + ``` + +## Advanced Operations + +### Database Performance Analysis + +```bash +# Show database size +docker compose exec db mysql -u foundation_user -pfoundation_password foundation -e " +SELECT + table_name AS 'Table', + ROUND(((data_length + index_length) / 1024 / 1024), 2) AS 'Size (MB)' +FROM information_schema.TABLES +WHERE table_schema = 'foundation' +ORDER BY (data_length + index_length) DESC; +" +``` + +### Export Structure Only (No Data) + +```bash +docker compose exec db mysqldump -u foundation_user -pfoundation_password --no-data foundation > schema-only.sql +``` + +### Export Data Only (No Structure) + +```bash +docker compose exec db mysqldump -u foundation_user -pfoundation_password --no-create-info foundation > data-only.sql +``` + +### Create Migration File + +```bash +# Export current state as migration +docker compose exec db mysqldump -u foundation_user -pfoundation_password foundation > database/migrations/$(date +%Y%m%d_%H%M%S)_migration.sql +``` + +## Database Connection Parameters + +**Environment Variables** (in Docker): +```env +DB_HOST=db +DB_PORT=3306 +DB_DATABASE=foundation +DB_USERNAME=foundation_user +DB_PASSWORD=foundation_password +``` + +**Connection from Host** (outside Docker): +```bash +mysql -h 127.0.0.1 -P 3306 -u foundation_user -pfoundation_password foundation +``` + +**PDO Connection String** (in PHP): +```php +$dsn = "mysql:host=db;port=3306;dbname=foundation;charset=utf8mb4"; +$pdo = new PDO($dsn, 'foundation_user', 'foundation_password'); +``` + +## Quick Reference + +```bash +# Import schema +docker compose exec -T db mysql -u foundation_user -pfoundation_password foundation < database/schema.sql + +# Backup database +docker compose exec db mysqldump -u foundation_user -pfoundation_password foundation > backup.sql + +# Restore database +docker compose exec -T db mysql -u foundation_user -pfoundation_password foundation < backup.sql + +# Access MySQL CLI +docker compose exec db mysql -u foundation_user -pfoundation_password foundation + +# Execute SQL command +docker compose exec db mysql -u foundation_user -pfoundation_password foundation -e "SHOW TABLES;" + +# Reset database +docker compose exec db mysql -u foundation_user -pfoundation_password -e "DROP DATABASE foundation; CREATE DATABASE foundation;" +docker compose exec -T db mysql -u foundation_user -pfoundation_password foundation < database/schema.sql + +# Compressed backup +docker compose exec db mysqldump -u foundation_user -pfoundation_password foundation | gzip > backup.sql.gz + +# View logs +docker compose logs db + +# Restart database +docker compose restart db +``` + +## Best Practices + +1. **Regular Backups** - Backup before major changes +2. **Timestamped Backups** - Use timestamps in backup filenames +3. **Test Restores** - Periodically verify backups can be restored +4. **Version Control Schema** - Keep schema files in git +5. **Use Migrations** - For production, use migration system +6. **Separate Test Data** - Keep test data separate from schema +7. **Document Changes** - Comment complex SQL in schema files +8. **Review Before Import** - Check schema files before importing +9. **Monitor Size** - Watch database growth over time +10. **Use Transactions** - Wrap multiple operations in transactions + +## Security Notes + +1. **Don't Commit Credentials** - Never commit database passwords +2. **Change Default Password** - Use strong passwords in production +3. **Limit Privileges** - Use least privilege principle for users +4. **Encrypt Backups** - Encrypt backup files if they contain sensitive data +5. **Secure phpMyAdmin** - Disable or secure phpMyAdmin in production diff --git a/.claude/skills/foundation/debug-setup.md b/.claude/skills/foundation/debug-setup.md new file mode 100644 index 0000000..1522520 --- /dev/null +++ b/.claude/skills/foundation/debug-setup.md @@ -0,0 +1,433 @@ +# Debug Setup + +Configure Xdebug for debugging PHP applications in the Foundation framework Docker environment. + +## When to use this skill + +- User asks to "set up debugging" +- User asks to "configure xdebug" +- User asks "how to debug" +- User wants to "use breakpoints" +- User mentions "step through code" +- Setting up IDE for first time +- Debugging not working + +## Prerequisites + +- Docker environment running (`make up`) +- IDE installed (PHPStorm or VS Code) +- Xdebug already installed in Docker container (included by default) + +## Steps for PHPStorm + +### 1. Configure PHP Interpreter + +**a) Open Interpreter Settings** + - Go to `Settings/Preferences > PHP` + - Click `...` next to CLI Interpreter + +**b) Add Docker Compose Interpreter** + - Click `+` → `From Docker, Vagrant, VM, WSL...` + - Select `Docker Compose` + - Configuration file: `docker-compose.yml` + - Service: `app` + - Click `OK` + +**c) Verify Configuration** + - PHP version should show: `8.1.x` + - Xdebug should be listed under Configuration file + +### 2. Configure Debug Settings + +**a) Open Debug Settings** + - Go to `Settings/Preferences > PHP > Debug` + +**b) Configure Xdebug** + - Xdebug port: `9003` + - Check: `Can accept external connections` + - Uncheck: `Break at first line in PHP scripts` (optional) + - Max simultaneous connections: `5` + +### 3. Configure Server Mapping + +**a) Open Server Settings** + - Go to `Settings/Preferences > PHP > Servers` + +**b) Add New Server** + - Click `+` to add new server + - Name: `foundation-docker` + - Host: `localhost` + - Port: `8000` + - Debugger: `Xdebug` + - Check: `Use path mappings` + +**c) Configure Path Mappings** + - Project root: `/var/www/html` + - Example: + ``` + /home/user/foundation → /var/www/html + ``` + +### 4. Start Debugging Session + +**a) Set Breakpoint** + - Click in the gutter next to line number in any PHP file + - Red dot should appear + +**b) Start Listening** + - Click `Start Listening for PHP Debug Connections` (phone icon) in toolbar + - Icon should turn green + +**c) Trigger Request** + - Open browser: http://localhost:8000 + - PHPStorm should pause at breakpoint + +## Steps for VS Code + +### 1. Install PHP Debug Extension + +**a) Install Extension** + - Open Extensions panel (`Ctrl+Shift+X` or `Cmd+Shift+X`) + - Search for: `PHP Debug` + - Install: `PHP Debug` by Xdebug + +### 2. Configure Launch Configuration + +**a) Create launch.json** + - Click `Run > Add Configuration...` + - Select `PHP` from dropdown + +**b) Edit launch.json** + +Create `.vscode/launch.json`: +```json +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Listen for Xdebug", + "type": "php", + "request": "launch", + "port": 9003, + "pathMappings": { + "/var/www/html": "${workspaceFolder}" + }, + "log": true + } + ] +} +``` + +### 3. Start Debugging Session + +**a) Set Breakpoint** + - Click in the gutter next to line number + - Red dot should appear + +**b) Start Debug Session** + - Press `F5` or click `Run > Start Debugging` + - Select `Listen for Xdebug` + +**c) Trigger Request** + - Open browser: http://localhost:8000 + - VS Code should pause at breakpoint + +## Verification + +### Test Debug Connection + +1. **Set Breakpoint** + ```php + // In any controller, e.g., src/Modules/WelcomeScreen/Infrastructure/Web/WelcomeController.php + public function index(): ResponseInterface + { + $test = "debug test"; // Set breakpoint on this line + // ... + } + ``` + +2. **Start Listening** (in IDE) + +3. **Access Application** + ```bash + curl http://localhost:8000 + # or open in browser + ``` + +4. **Verify Pause** + - IDE should pause execution at breakpoint + - Variables panel should show local variables + - Call stack should show current execution path + +### Debug Controls + +Once paused at breakpoint: + +**PHPStorm**: +- `F8` - Step Over +- `F7` - Step Into +- `Shift+F8` - Step Out +- `F9` - Resume Program +- `Ctrl+F8` - Toggle Breakpoint + +**VS Code**: +- `F10` - Step Over +- `F11` - Step Into +- `Shift+F11` - Step Out +- `F5` - Continue +- `F9` - Toggle Breakpoint + +## Troubleshooting + +### Breakpoint Not Hit + +**Problem**: Debugger doesn't pause at breakpoint. + +**Diagnostic**: +```bash +# Check Xdebug is loaded +docker compose exec app php -v + +# Should show: +# with Xdebug v3.x.x +``` + +**Solutions**: + +**A) Verify Xdebug Configuration** +```bash +docker compose exec app php -i | grep xdebug +``` + +Should show: +- `xdebug.mode = debug` +- `xdebug.start_with_request = yes` +- `xdebug.client_host = host.docker.internal` +- `xdebug.client_port = 9003` + +**B) Check IDE is Listening** +- Verify debug listener is active (green phone icon in PHPStorm) +- Verify debug session started in VS Code + +**C) Verify Path Mappings** +- Project root must map to `/var/www/html` +- Check for typos in paths + +### Connection Refused + +**Problem**: IDE shows "Connection refused" or timeout. + +**Solutions**: + +**A) Check Port Configuration** +- IDE listening on port 9003 +- Xdebug connecting to port 9003 +- No firewall blocking port 9003 + +**B) Verify Docker Network** +```bash +# Test connection from container +docker compose exec app ping -c 3 host.docker.internal +``` + +**C) Check Xdebug Configuration** +```bash +docker compose exec app cat /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini +``` + +### Path Mapping Issues + +**Problem**: Debugger can't find source files. + +**Solutions**: + +**A) Verify Mapping** +- Local path: `/home/user/foundation` +- Container path: `/var/www/html` +- Must match exactly + +**B) Check Working Directory** +```bash +docker compose exec app pwd +# Should output: /var/www/html +``` + +**C) Restart IDE and Docker** +```bash +# Restart Docker +make down +make up + +# Restart IDE completely +``` + +### Multiple Debug Sessions + +**Problem**: Multiple IDE instances or debug sessions conflict. + +**Solutions**: + +**A) Close Other IDEs** +- Only one IDE should listen for Xdebug at a time + +**B) Change Port in One IDE** +- Use different port (e.g., 9004) in second IDE +- Update Xdebug config to match + +### Browser Extension Conflicts + +**Problem**: Debug session starts unexpectedly or not at all. + +**Solutions**: + +**A) Install Xdebug Helper** +- Chrome: Install "Xdebug Helper" extension +- Firefox: Install "Xdebug Helper" addon + +**B) Configure Extension** +- Set IDE key to `PHPSTORM` or `VSCODE` +- Enable debug mode in extension icon + +## Advanced Configuration + +### Xdebug Configuration File + +Location in container: `/usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini` + +Example configuration: +```ini +zend_extension=xdebug.so +xdebug.mode=debug +xdebug.start_with_request=yes +xdebug.client_host=host.docker.internal +xdebug.client_port=9003 +xdebug.log=/tmp/xdebug.log +xdebug.log_level=0 +``` + +### Enable Xdebug Logging + +For troubleshooting: +```bash +# Edit Xdebug config +docker compose exec app bash -c "echo 'xdebug.log=/tmp/xdebug.log' >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini" +docker compose exec app bash -c "echo 'xdebug.log_level=7' >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini" + +# Restart container +docker compose restart app + +# View log +docker compose exec app tail -f /tmp/xdebug.log +``` + +### Conditional Breakpoints + +**PHPStorm**: +- Right-click breakpoint → Add condition +- Example: `$userId === 123` + +**VS Code**: +- Right-click breakpoint → Edit Breakpoint +- Add expression: `$userId === 123` + +### Remote Debugging + +For debugging CLI scripts: +```bash +# Set environment variable +docker compose exec app bash +export XDEBUG_SESSION=PHPSTORM + +# Run script +php script.php +``` + +## Testing Specific Scenarios + +### Debug API Requests + +```bash +# With debug cookie +curl -b "XDEBUG_SESSION=PHPSTORM" http://localhost:8000/api/endpoint +``` + +### Debug CLI Commands + +```bash +# Start listening in IDE first +docker compose exec app bash +export XDEBUG_SESSION=PHPSTORM +php artisan command +``` + +### Debug Tests + +```bash +# Start listening in IDE first +docker compose exec app bash +export XDEBUG_SESSION=PHPSTORM +vendor/bin/phpunit tests/Unit/MyTest.php +``` + +## Best Practices + +1. **Disable Xdebug for Tests** (faster execution) + ```bash + docker compose exec app php -d xdebug.mode=off vendor/bin/phpunit + ``` + +2. **Use Logging Breakpoints** (don't pause execution) + - Evaluate and log instead of stopping + +3. **Conditional Breakpoints** (reduce noise) + - Only break when specific conditions met + +4. **Watch Expressions** (monitor variables) + - Add variables to watch list for continuous monitoring + +5. **Clear Breakpoints** (avoid clutter) + - Remove breakpoints when done debugging + +## Quick Reference + +### PHPStorm +``` +Settings > PHP > CLI Interpreter → Add Docker Compose (app service) +Settings > PHP > Debug → Port 9003, Accept external connections +Settings > PHP > Servers → Add server, path mapping: /var/www/html +Start Listening (phone icon) → Set breakpoint → Access app +``` + +### VS Code +```json +// .vscode/launch.json +{ + "type": "php", + "request": "launch", + "port": 9003, + "pathMappings": { + "/var/www/html": "${workspaceFolder}" + } +} +``` +``` +F5 to start → Set breakpoint → Access app +``` + +### Xdebug Info +```bash +# Check Xdebug is loaded +docker compose exec app php -v + +# View Xdebug configuration +docker compose exec app php -i | grep xdebug + +# View config file +docker compose exec app cat /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini +``` + +### Common Issues +- Not hitting breakpoint → Check IDE is listening, verify path mappings +- Connection refused → Check port 9003, verify Xdebug config +- Wrong file shown → Fix path mappings +- Multiple sessions → Close other IDEs listening on same port diff --git a/.claude/skills/foundation/docker-setup.md b/.claude/skills/foundation/docker-setup.md new file mode 100644 index 0000000..e16b207 --- /dev/null +++ b/.claude/skills/foundation/docker-setup.md @@ -0,0 +1,155 @@ +# Docker Setup + +Initialize and configure the Docker development environment for Foundation framework. + +## When to use this skill + +- User asks to "set up docker environment" +- User asks to "initialize development environment" +- User asks to "start the project" +- User mentions "docker setup" or "docker configuration" +- First time project setup + +## Steps + +1. **Verify Prerequisites** + ```bash + docker --version + docker compose version + ``` + Ensure Docker and Docker Compose are installed on the system. + +2. **Set User Permissions (Linux/macOS)** + ```bash + export USER_ID=$(id -u) && export GROUP_ID=$(id -g) + ``` + This ensures files created in containers have correct ownership. + +3. **Start Docker Environment** + ```bash + make up + ``` + This command: + - Builds Docker images if needed + - Starts app, db, and phpmyadmin containers + - Creates necessary networks and volumes + +4. **Install Dependencies** + ```bash + make install + ``` + Installs all Composer dependencies inside the app container. + +5. **Import Database Schema** (if schema exists) + ```bash + docker compose exec -T db mysql -u foundation_user -pfoundation_password foundation < database/schema.sql + ``` + +6. **Copy Environment Configuration** (if not exists) + ```bash + cp .env.example .env + ``` + Edit `.env` if custom configuration is needed (usually Docker defaults work). + +## Verification + +1. **Check Container Status** + ```bash + docker compose ps + ``` + All three containers (app, db, phpmyadmin) should be in "running" state. + +2. **Verify Application Access** + - Open browser: http://localhost:8000 + - Should see the application homepage + +3. **Verify Database Access** + - Open browser: http://localhost:8080 (phpMyAdmin) + - Login with: foundation_user / foundation_password + - Should see "foundation" database + +4. **Test Container Shell Access** + ```bash + make shell + ``` + Should enter the app container bash shell. Type `exit` to leave. + +## Troubleshooting + +### Port Conflicts + +**Problem**: Error about port 8000, 8080, or 3306 already in use. + +**Solution**: +```bash +# Check what's using the port (example for port 8000) +sudo lsof -i :8000 + +# Stop conflicting service or modify docker-compose.yml ports +``` + +### Permission Errors + +**Problem**: Files created by Docker have wrong ownership. + +**Solution**: +```bash +# Set user/group IDs and rebuild +export USER_ID=$(id -u) && export GROUP_ID=$(id -g) +make down +make up +``` + +### Container Won't Start + +**Problem**: Containers fail to start or crash immediately. + +**Solution**: +```bash +# Check logs for specific container +docker compose logs app +docker compose logs db + +# Try rebuilding +make down +docker compose up -d --build +``` + +### Database Connection Failed + +**Problem**: Application can't connect to database. + +**Solution**: +1. Verify database container is running: `docker compose ps` +2. Check environment variables in `.env` match Docker defaults: + ``` + DB_HOST=db + DB_PORT=3306 + DB_DATABASE=foundation + DB_USERNAME=foundation_user + DB_PASSWORD=foundation_password + ``` +3. Restart containers: `make down && make up` + +## Quick Reference + +```bash +# Start environment +make up + +# Stop environment +make down + +# View logs +docker compose logs -f app + +# Restart a service +docker compose restart app + +# Rebuild containers +make down +docker compose up -d --build + +# Access container shell +make shell +``` diff --git a/.claude/skills/foundation/run-tests.md b/.claude/skills/foundation/run-tests.md new file mode 100644 index 0000000..4408248 --- /dev/null +++ b/.claude/skills/foundation/run-tests.md @@ -0,0 +1,332 @@ +# Run Tests + +Execute the testing suite for Foundation framework using PHPUnit. + +## When to use this skill + +- User asks to "run tests" +- User asks to "execute test suite" +- User asks to "check if tests pass" +- User mentions "test coverage" +- User asks to "run unit tests" or "run integration tests" +- After making code changes that need verification + +## Steps + +### Run All Tests + +1. **Execute Full Test Suite** + ```bash + make test + ``` + This runs all unit and integration tests. + +### Run Specific Test Suites + +2. **Run Unit Tests Only** + ```bash + make test-unit + ``` + Unit tests focus on testing individual components in isolation. + +3. **Run Integration Tests Only** + ```bash + make test-integration + ``` + Integration tests verify components work together correctly. + +### Generate Coverage Report + +4. **Run Tests with Coverage** + ```bash + make test-coverage + ``` + Generates an HTML coverage report in `coverage-html/` directory. + +5. **View Coverage Report** + ```bash + # Open in browser (adjust path as needed) + open coverage-html/index.html + # or + xdg-open coverage-html/index.html + ``` + +### Run Specific Test Files + +6. **Run Single Test File** (if needed) + ```bash + docker compose exec app vendor/bin/phpunit tests/Unit/Path/To/TestFile.php + ``` + +7. **Run Single Test Method** (if needed) + ```bash + docker compose exec app vendor/bin/phpunit --filter testMethodName + ``` + +## Verification + +### Successful Test Run + +``` +PHPUnit 10.x.x + +................................................... 50 / 100 ( 50%) +.................................................. 100 / 100 (100%) + +Time: 00:01.234, Memory: 10.00 MB + +OK (100 tests, 250 assertions) +``` + +### Failed Test Example + +``` +F + +Time: 00:00.123, Memory: 8.00 MB + +There was 1 failure: + +1) Foundation\Tests\Unit\ExampleTest::testExample +Failed asserting that false is true. + +/var/www/html/tests/Unit/ExampleTest.php:15 + +FAILURES! +Tests: 1, Assertions: 1, Failures: 1. +``` + +## Test Organization + +Tests are organized by type: + +``` +tests/ +├── Unit/ # Unit tests +│ ├── Core/ +│ └── Modules/ +└── Integration/ # Integration tests + ├── Api/ + └── Database/ +``` + +### Unit Tests + +- Test individual classes in isolation +- Mock dependencies +- Fast execution +- No database or HTTP calls + +**Example:** +```php +namespace Foundation\Tests\Unit\Core; + +use PHPUnit\Framework\TestCase; + +final class ExampleTest extends TestCase +{ + public function testExample(): void + { + $this->assertTrue(true); + } +} +``` + +### Integration Tests + +- Test components working together +- May use real database (test database) +- Test full request/response cycle +- Slower than unit tests + +**Example:** +```php +namespace Foundation\Tests\Integration\Api; + +use PHPUnit\Framework\TestCase; + +final class ApiTest extends TestCase +{ + public function testApiEndpoint(): void + { + // Test full HTTP request/response + } +} +``` + +## Troubleshooting + +### Tests Not Found + +**Problem**: PHPUnit can't find test files. + +**Solution**: +1. Check phpunit.xml or phpunit.xml.dist configuration +2. Verify test files end with `Test.php` +3. Verify test classes extend `PHPUnit\Framework\TestCase` +4. Run `make dump-autoload` + +### Database Connection Errors (Integration Tests) + +**Problem**: Tests fail with database connection errors. + +**Solution**: +1. Ensure Docker containers are running: `docker compose ps` +2. Check test environment configuration +3. Verify test database exists and is accessible +4. Check `.env` or test configuration for correct database credentials + +### Memory Limit Errors + +**Problem**: Tests fail with "Allowed memory size exhausted" error. + +**Solution**: +```bash +# Increase memory limit for tests +docker compose exec app php -d memory_limit=512M vendor/bin/phpunit +``` + +Or modify `phpunit.xml`: +```xml + + + +``` + +### Slow Test Execution + +**Problem**: Tests take too long to run. + +**Solution**: +1. Run only unit tests during development: `make test-unit` +2. Run specific test files instead of full suite +3. Use `--stop-on-failure` flag to stop at first failure: + ```bash + docker compose exec app vendor/bin/phpunit --stop-on-failure + ``` + +### Coverage Report Not Generated + +**Problem**: Coverage report directory is empty. + +**Solution**: +1. Verify Xdebug is installed in Docker container +2. Check phpunit.xml coverage configuration +3. Run coverage command with verbose output: + ```bash + docker compose exec app vendor/bin/phpunit --coverage-html=coverage-html --verbose + ``` + +## Advanced Usage + +### Parallel Test Execution + +For faster execution (if paratest is installed): +```bash +docker compose exec app vendor/bin/paratest +``` + +### Watch Mode (Continuous Testing) + +Using phpunit-watcher (if installed): +```bash +docker compose exec app vendor/bin/phpunit-watcher watch +``` + +### Test Filtering + +```bash +# Run tests in specific namespace +docker compose exec app vendor/bin/phpunit --filter "Foundation\\Tests\\Unit\\Core" + +# Run tests matching pattern +docker compose exec app vendor/bin/phpunit --filter testUserCreation + +# Run tests from specific group +docker compose exec app vendor/bin/phpunit --group integration +``` + +## Best Practices + +1. **Run tests before committing** + ```bash + make test + ``` + +2. **Run unit tests during development** (faster feedback) + ```bash + make test-unit + ``` + +3. **Run full suite before pushing** + ```bash + make test && make static-analysis + ``` + +4. **Check coverage periodically** + ```bash + make test-coverage + ``` + +5. **Write tests for new features** - Ensure new code is covered + +6. **Keep tests fast** - Mock external dependencies in unit tests + +7. **Use meaningful test names** - Test method names should describe what they test + +## Quick Reference + +```bash +# All tests +make test + +# Unit tests only +make test-unit + +# Integration tests only +make test-integration + +# With coverage report +make test-coverage + +# Single file +docker compose exec app vendor/bin/phpunit tests/Unit/Path/To/TestFile.php + +# Single method +docker compose exec app vendor/bin/phpunit --filter testMethodName + +# Stop on first failure +docker compose exec app vendor/bin/phpunit --stop-on-failure + +# Verbose output +docker compose exec app vendor/bin/phpunit --verbose +``` + +## Test Writing Tips + +1. **Follow AAA Pattern** + - Arrange: Set up test data + - Act: Execute the code under test + - Assert: Verify the results + +2. **One Assertion Per Test** (when possible) + - Makes failures easier to diagnose + +3. **Use Descriptive Names** + ```php + // Good + public function testUserCanBeCreatedWithValidEmail(): void + + // Bad + public function testUser(): void + ``` + +4. **Test Edge Cases** + - Empty inputs + - Null values + - Boundary conditions + - Error cases + +5. **Keep Tests Independent** + - Tests should not depend on each other + - Each test should set up its own data diff --git a/.claude/skills/foundation/static-analysis.md b/.claude/skills/foundation/static-analysis.md new file mode 100644 index 0000000..9dc6eeb --- /dev/null +++ b/.claude/skills/foundation/static-analysis.md @@ -0,0 +1,402 @@ +# Static Analysis + +Run static analysis tools to check code quality, type safety, and architectural boundaries in the Foundation framework. + +## When to use this skill + +- User asks to "run static analysis" +- User asks to "check code quality" +- User asks to "run phpstan" or "run deptrac" +- User asks to "analyze code" +- User mentions "type checking" or "architecture validation" +- Before committing code +- After making significant changes + +## Steps + +### Run Complete Static Analysis + +1. **Run All Static Analysis Tools** + ```bash + make static-analysis + ``` + This runs both PHPStan and Deptrac in sequence. + +### Run Individual Tools + +2. **Run PHPStan** (Type and Code Analysis) + ```bash + make phpstan + ``` + PHPStan checks for: + - Type errors + - Undefined variables + - Invalid method calls + - Dead code + - Strict rules violations + +3. **Run Deptrac** (Architecture Layer Analysis) + ```bash + make deptrac + ``` + Deptrac validates: + - Layer dependency rules (Domain → Application → Infrastructure) + - Module boundaries + - Architectural violations + +### Generate Baselines (When Needed) + +4. **Generate PHPStan Baseline** + ```bash + make phpstan-baseline + ``` + Creates `phpstan-baseline.neon` to suppress existing errors while preventing new ones. + +5. **Generate Deptrac Baseline** + ```bash + make deptrac-baseline + ``` + Creates `deptrac-baseline.yaml` to track existing architectural violations. + +## Verification + +### PHPStan Success + +``` +PHPStan - PHP Static Analysis Tool + + [OK] No errors + +``` + +### Deptrac Success + +``` +Deptrac + + [OK] No violations found + +``` + +### PHPStan Errors Example + +``` +------ -------------------------------------------------------- + Line src/Modules/Example/Domain/Example.php +------ -------------------------------------------------------- + 15 Property Example::$name has no type hint + 23 Method Example::getData() has no return type specified + 45 Call to undefined method PDO::executeQuery() +------ -------------------------------------------------------- + + [ERROR] Found 3 errors +``` + +### Deptrac Violations Example + +``` +------ -------------------------------------------------------- + From To +------ -------------------------------------------------------- + Domain\Example (Domain Layer) Infrastructure\Database (Infrastructure Layer) +------ -------------------------------------------------------- + + [ERROR] Found 1 violation + +Violation: Domain layer must not depend on Infrastructure layer +``` + +## Analysis Tools Overview + +### PHPStan + +**Purpose**: Static analysis for type safety and code quality + +**Configuration**: `phpstan.neon` or `phpstan.neon.dist` + +**Key Features**: +- Level-based strictness (0-9, higher = stricter) +- Type inference and checking +- Dead code detection +- Strict rules for code quality + +**What It Checks**: +- Type mismatches +- Undefined variables and methods +- Invalid array access +- Return type compatibility +- Parameter type compatibility +- Property type hints + +### Deptrac + +**Purpose**: Architecture and dependency rule validation + +**Configuration**: `deptrac.yaml` or `deptrac.yaml.dist` + +**Key Features**: +- Layer dependency enforcement +- Module boundary validation +- Custom rule definition + +**What It Checks**: +- Domain layer has no dependencies +- Application layer only depends on Domain +- Infrastructure layer only depends on Application +- No circular dependencies +- Custom architectural rules + +## Troubleshooting + +### PHPStan Errors After Dependency Updates + +**Problem**: New errors appear after updating dependencies. + +**Solution**: +1. Review and fix legitimate errors +2. If errors are unavoidable (third-party library issues): + ```bash + make phpstan-baseline + ``` +3. Commit the baseline file + +### Deptrac False Positives + +**Problem**: Deptrac reports violations that are intentional or unavoidable. + +**Solution**: +1. Review the violation - ensure it's truly acceptable +2. If legitimate, update `deptrac.yaml` to allow specific exception +3. Or generate baseline: + ```bash + make deptrac-baseline + ``` + +### PHPStan Memory Limit + +**Problem**: PHPStan crashes with memory exhausted error. + +**Solution**: +```bash +# Run with increased memory +docker compose exec app php -d memory_limit=1G vendor/bin/phpstan analyse +``` + +Or modify `phpstan.neon`: +```yaml +parameters: + memory_limit: 1G +``` + +### Slow Analysis + +**Problem**: Static analysis takes too long. + +**Solution**: +1. **Enable result cache** in `phpstan.neon`: + ```yaml + parameters: + tmpDir: var/cache/phpstan + ``` +2. **Analyze specific paths** during development: + ```bash + docker compose exec app vendor/bin/phpstan analyse src/Modules/MyModule + ``` + +### Configuration Not Found + +**Problem**: Tool can't find configuration file. + +**Solution**: +1. Verify configuration file exists: + - PHPStan: `phpstan.neon` or `phpstan.neon.dist` + - Deptrac: `deptrac.yaml` or `deptrac.yaml.dist` +2. Check file is in project root +3. Verify file syntax is valid YAML/NEON + +## Advanced Usage + +### PHPStan Commands + +```bash +# Analyze specific directory +docker compose exec app vendor/bin/phpstan analyse src/Modules/MyModule + +# Different error level (0-9) +docker compose exec app vendor/bin/phpstan analyse --level=9 + +# Show progress +docker compose exec app vendor/bin/phpstan analyse --verbose + +# Clear cache +docker compose exec app vendor/bin/phpstan clear-result-cache +``` + +### Deptrac Commands + +```bash +# Analyze with specific configuration +docker compose exec app vendor/bin/deptrac analyse --config-file=deptrac.yaml + +# Generate dependency graph +docker compose exec app vendor/bin/deptrac analyse --formatter=graphviz + +# Different output format +docker compose exec app vendor/bin/deptrac analyse --formatter=console +``` + +## Common Layer Violations and Fixes + +### Domain Depending on Infrastructure + +**Violation**: +``` +Domain\UserRepository → Infrastructure\Database\PDO +``` + +**Fix**: +Move repository interface to Domain, implementation to Infrastructure: +```php +// Domain/UserRepositoryInterface.php (in Domain layer) +interface UserRepositoryInterface +{ + public function findById(int $id): ?User; +} + +// Infrastructure/Database/UserRepository.php (in Infrastructure layer) +class UserRepository implements UserRepositoryInterface +{ + public function __construct(private PDO $pdo) {} +} +``` + +### Application Depending on Infrastructure + +**Violation**: +``` +Application\UseCase → Infrastructure\Api\Controller +``` + +**Fix**: +Reverse the dependency - Controllers should call use cases, not vice versa: +```php +// Infrastructure/Api/UserController.php +class UserController +{ + public function __construct( + private CreateUserUseCase $createUser // Application layer + ) {} +} +``` + +## Best Practices + +1. **Run Before Committing** + ```bash + make test && make static-analysis + ``` + +2. **Fix Issues Immediately** - Don't let violations accumulate + +3. **Use Baselines Sparingly** - Fix issues rather than suppressing them + +4. **Review Violations** - Understand why a violation occurs before suppressing + +5. **Keep Configuration Strict** - Higher PHPStan levels catch more issues + +6. **Respect Layer Boundaries** - Domain should never depend on outer layers + +7. **Type Everything** - Add type hints to all methods and properties + +## Integration with CI/CD + +Add to your CI pipeline: +```bash +#!/bin/bash +set -e + +echo "Running static analysis..." +make phpstan +make deptrac + +echo "All checks passed!" +``` + +## Quick Reference + +```bash +# Run all static analysis +make static-analysis + +# PHPStan only +make phpstan + +# Deptrac only +make deptrac + +# Generate baselines +make phpstan-baseline +make deptrac-baseline + +# PHPStan specific path +docker compose exec app vendor/bin/phpstan analyse src/Modules/MyModule + +# Deptrac with graph output +docker compose exec app vendor/bin/deptrac analyse --formatter=graphviz + +# Clear PHPStan cache +docker compose exec app vendor/bin/phpstan clear-result-cache +``` + +## Understanding Error Levels + +### PHPStan Levels (0-9) + +- **Level 0**: Basic checks, few false positives +- **Level 5**: Reasonable balance, good starting point +- **Level 9**: Maximum strictness, requires extensive type hints + +Recommendation: Start at level 5, gradually increase to 9. + +## Configuration Examples + +### PHPStan Configuration + +```yaml +# phpstan.neon +parameters: + level: 9 + paths: + - src + tmpDir: var/cache/phpstan + excludePaths: + - src/old-code/ +``` + +### Deptrac Configuration + +```yaml +# deptrac.yaml +deptrac: + paths: + - ./src + layers: + - name: Domain + collectors: + - type: directory + regex: src/.*/Domain/.* + - name: Application + collectors: + - type: directory + regex: src/.*/Application/.* + - name: Infrastructure + collectors: + - type: directory + regex: src/.*/Infrastructure/.* + ruleset: + Domain: [] + Application: + - Domain + Infrastructure: + - Application +``` diff --git a/.claude/skills/foundation/troubleshoot-docker.md b/.claude/skills/foundation/troubleshoot-docker.md new file mode 100644 index 0000000..a1e968d --- /dev/null +++ b/.claude/skills/foundation/troubleshoot-docker.md @@ -0,0 +1,524 @@ +# Troubleshoot Docker + +Diagnostic steps and solutions for common Docker issues in the Foundation framework. + +## When to use this skill + +- User reports "Docker not working" +- User mentions "containers won't start" +- User reports "connection refused" errors +- User asks "why isn't the app working?" +- User mentions "port already in use" +- User reports "permission denied" errors +- Application not accessible via browser +- Database connection failures + +## Diagnostic Steps + +### Step 1: Check Container Status + +1. **List All Containers** + ```bash + docker compose ps + ``` + + **Expected Output**: + ``` + NAME STATUS PORTS + foundation-app Up X minutes 0.0.0.0:8000->80/tcp + foundation-db Up X minutes 0.0.0.0:3306->3306/tcp + foundation-phpmyadmin Up X minutes 0.0.0.0:8080->80/tcp + ``` + + All containers should show "Up" status. + +### Step 2: Check Container Logs + +2. **View Container Logs** + ```bash + # All containers + docker compose logs + + # Specific container + docker compose logs app + docker compose logs db + docker compose logs phpmyadmin + + # Follow logs in real-time + docker compose logs -f app + ``` + + Look for error messages, warnings, or stack traces. + +### Step 3: Check Port Availability + +3. **Check if Ports are Available** + ```bash + # Check port 8000 (app) + sudo lsof -i :8000 + + # Check port 8080 (phpmyadmin) + sudo lsof -i :8080 + + # Check port 3306 (mysql) + sudo lsof -i :3306 + ``` + + If output shows other processes using these ports, you have a port conflict. + +### Step 4: Verify Docker Service + +4. **Check Docker Daemon Status** + ```bash + docker --version + docker compose version + systemctl status docker # Linux + ``` + + Ensure Docker daemon is running. + +### Step 5: Test Application Access + +5. **Test HTTP Endpoints** + ```bash + # Test app + curl http://localhost:8000 + + # Test phpMyAdmin + curl http://localhost:8080 + ``` + + Should return HTML content, not connection errors. + +## Common Issues and Solutions + +### Issue 1: Containers Won't Start + +**Symptoms**: +- `docker compose ps` shows containers with "Exit" status +- Containers restart repeatedly + +**Diagnostic**: +```bash +docker compose logs app +docker compose logs db +``` + +**Solutions**: + +**A) Port Conflict** +```bash +# Find process using port +sudo lsof -i :8000 + +# Kill process or change port in docker-compose.yml +``` + +**B) Configuration Error** +```bash +# Check docker-compose.yml syntax +docker compose config + +# Rebuild containers +make down +docker compose up -d --build +``` + +**C) Previous Container Data Issues** +```bash +# Remove containers and volumes +docker compose down -v + +# Restart fresh +make up +``` + +### Issue 2: Application Returns 500 Error + +**Symptoms**: +- Browser shows "Internal Server Error" +- HTTP 500 status code + +**Diagnostic**: +```bash +docker compose logs -f app +docker compose exec app tail -f storage/logs/app.log +``` + +**Solutions**: + +**A) Check File Permissions** +```bash +# Fix permissions in container +docker compose exec app chown -R www-data:www-data storage/ +docker compose exec app chmod -R 775 storage/ +``` + +**B) Check PHP Errors** +```bash +# View PHP error log +docker compose exec app tail -f /var/log/apache2/error.log +``` + +**C) Missing Dependencies** +```bash +# Reinstall dependencies +make install +``` + +### Issue 3: Database Connection Failed + +**Symptoms**: +- "Connection refused" to database +- "SQLSTATE[HY000] [2002]" errors +- Application can't connect to MySQL + +**Diagnostic**: +```bash +# Check database container +docker compose ps db + +# Check database logs +docker compose logs db + +# Test connection from app container +docker compose exec app mysql -h db -u foundation_user -pfoundation_password foundation +``` + +**Solutions**: + +**A) Database Container Not Running** +```bash +# Restart database +docker compose restart db + +# Check startup logs +docker compose logs db +``` + +**B) Wrong Credentials** +```bash +# Verify environment variables +docker compose exec app env | grep DB_ + +# Should show: +# DB_HOST=db +# DB_PORT=3306 +# DB_DATABASE=foundation +# DB_USERNAME=foundation_user +# DB_PASSWORD=foundation_password +``` + +**C) Database Not Initialized** +```bash +# Import schema +docker compose exec -T db mysql -u foundation_user -pfoundation_password foundation < database/schema.sql +``` + +### Issue 4: Port Already in Use + +**Symptoms**: +- Error: "port is already allocated" +- Error: "bind: address already in use" + +**Diagnostic**: +```bash +sudo lsof -i :8000 +sudo lsof -i :8080 +sudo lsof -i :3306 +``` + +**Solutions**: + +**A) Stop Conflicting Service** +```bash +# If Apache/Nginx is running +sudo systemctl stop apache2 +# or +sudo systemctl stop nginx + +# If MySQL is running +sudo systemctl stop mysql +``` + +**B) Change Docker Ports** + +Edit `docker-compose.yml`: +```yaml +services: + app: + ports: + - "8001:80" # Change 8000 to 8001 +``` + +Then restart: +```bash +make down +make up +``` + +### Issue 5: Permission Denied Errors + +**Symptoms**: +- Can't write to files +- Can't create directories +- Permission denied in logs + +**Diagnostic**: +```bash +# Check file ownership +docker compose exec app ls -la /var/www/html/storage + +# Check user in container +docker compose exec app whoami +``` + +**Solutions**: + +**A) Fix Ownership (Linux/macOS)** +```bash +export USER_ID=$(id -u) && export GROUP_ID=$(id -g) +make down +make up +``` + +**B) Fix Permissions in Container** +```bash +docker compose exec app chown -R www-data:www-data /var/www/html +docker compose exec app chmod -R 775 /var/www/html/storage +``` + +### Issue 6: Changes Not Reflected + +**Symptoms**: +- Code changes don't appear in browser +- Old version still running + +**Diagnostic**: +```bash +# Check if volumes are mounted +docker compose exec app ls -la /var/www/html +``` + +**Solutions**: + +**A) Clear Caches** +```bash +# Clear application cache +docker compose exec app rm -rf storage/cache/* + +# Clear browser cache +# Use Ctrl+Shift+R or Cmd+Shift+R +``` + +**B) Restart Container** +```bash +docker compose restart app +``` + +**C) Rebuild Container** +```bash +make down +docker compose up -d --build +``` + +### Issue 7: Slow Performance + +**Symptoms**: +- Application very slow to respond +- High CPU/memory usage +- Timeouts + +**Diagnostic**: +```bash +# Check container resource usage +docker stats + +# Check logs for errors +docker compose logs app +``` + +**Solutions**: + +**A) Increase Docker Resources** + +In Docker Desktop: Settings → Resources → Increase CPU/Memory + +**B) Clear Logs** +```bash +docker compose exec app rm -f storage/logs/* +docker compose exec app truncate -s 0 /var/log/apache2/error.log +``` + +**C) Optimize Autoloader** +```bash +make dump-autoload +``` + +### Issue 8: Cannot Access Container Shell + +**Symptoms**: +- `make shell` or `docker compose exec app bash` fails + +**Diagnostic**: +```bash +docker compose ps app +``` + +**Solutions**: + +**A) Container Not Running** +```bash +make up +``` + +**B) Use Different Shell** +```bash +docker compose exec app sh +``` + +## Complete Reset Procedure + +If all else fails, completely reset the environment: + +```bash +# 1. Stop and remove everything +docker compose down -v + +# 2. Remove dangling images +docker system prune -f + +# 3. Rebuild from scratch +export USER_ID=$(id -u) && export GROUP_ID=$(id -g) +docker compose up -d --build + +# 4. Reinstall dependencies +make install + +# 5. Import database schema +docker compose exec -T db mysql -u foundation_user -pfoundation_password foundation < database/schema.sql + +# 6. Verify +docker compose ps +curl http://localhost:8000 +``` + +## Diagnostic Command Checklist + +Run these commands to gather diagnostic information: + +```bash +# 1. Container status +docker compose ps + +# 2. Container logs +docker compose logs --tail=50 + +# 3. Docker version +docker --version +docker compose version + +# 4. Port availability +sudo lsof -i :8000 +sudo lsof -i :8080 +sudo lsof -i :3306 + +# 5. Disk space +df -h + +# 6. Docker disk usage +docker system df + +# 7. Network connectivity +docker compose exec app ping -c 3 db + +# 8. Environment variables +docker compose exec app env | grep DB_ + +# 9. File permissions +docker compose exec app ls -la /var/www/html/storage + +# 10. Test database connection +docker compose exec app mysql -h db -u foundation_user -pfoundation_password foundation -e "SELECT 1;" +``` + +## Prevention Best Practices + +1. **Regular Cleanup** + ```bash + docker system prune -f + ``` + +2. **Monitor Logs** + ```bash + docker compose logs -f + ``` + +3. **Use Make Commands** + - Prefer `make up` over direct `docker compose` commands + - Ensures consistent environment setup + +4. **Keep Docker Updated** + ```bash + # Check for updates + docker --version + ``` + +5. **Document Environment** + - Note any custom ports or configurations + - Keep `.env` file up to date + +## Getting Help + +If issues persist: + +1. **Collect Information**: + ```bash + docker compose ps > debug-status.txt + docker compose logs > debug-logs.txt + docker compose config > debug-config.txt + ``` + +2. **Check Docker Documentation**: https://docs.docker.com + +3. **Review Project Issues**: Check if it's a known issue + +4. **System Requirements**: + - Docker Engine 20.10+ + - Docker Compose 2.0+ + - At least 4GB RAM allocated to Docker + - 10GB free disk space + +## Quick Reference + +```bash +# Status and logs +docker compose ps +docker compose logs -f app + +# Restart +docker compose restart app +docker compose restart db + +# Full reset +docker compose down -v +make up + +# Access shell +make shell + +# Check ports +sudo lsof -i :8000 +sudo lsof -i :8080 +sudo lsof -i :3306 + +# View resource usage +docker stats + +# Clean up +docker system prune -f + +# Rebuild +make down +docker compose up -d --build +``` diff --git a/Claude.md b/Claude.md new file mode 100644 index 0000000..5d57780 --- /dev/null +++ b/Claude.md @@ -0,0 +1,382 @@ +# Foundation Framework - Claude Context + +## Project Overview + +Foundation is a PHP framework built with Domain-Driven Design (DDD) principles, featuring clean architecture, modular design, and modern PHP 8+ capabilities. The framework emphasizes separation of concerns, testability, and maintainability. + +## Technology Stack + +- **PHP**: 8.1+ +- **HTTP Framework**: Slim 4 +- **Dependency Injection**: PHP-DI 7.0 +- **Database**: MySQL 8.0 with PDO and Repository pattern +- **Logging**: Monolog 3.0 +- **Environment Config**: phpdotenv +- **Development**: Docker + Docker Compose with Xdebug + +## Architecture Principles + +### Clean Architecture Layers + +The framework follows strict layered architecture with clear dependency rules: + +``` +Domain (Pure business logic - No dependencies) + ↑ +Application (Use cases - Depends on Domain only) + ↑ +Infrastructure (External adapters - Depends on Application only) +``` + +**Layer Dependency Rules:** +- **Domain Layer**: Completely independent, no external dependencies +- **Application Layer**: Can depend on Domain and itself only +- **Infrastructure Layer**: Can depend on Application and itself only + +### Module Structure + +Each module follows this structure: + +``` +src/Modules/{ModuleName}/ +├── Domain/ # Pure business logic +│ ├── {Entity}.php # Entities with identity +│ ├── {ValueObject}.php # Immutable value objects +│ └── {Repository}Interface.php # Repository contracts +├── Application/ # Use cases and orchestration +│ └── {UseCase}/ +│ └── {UseCase}.php +└── Infrastructure/ # External implementations + ├── Api/ # API controllers + ├── Web/ # Web controllers + └── Database/ # Repository implementations + ├── {Repository}.php + ├── Commands/ + └── Queries/ +``` + +### Core Framework Structure + +``` +src/Core/ +├── Application/ # Application orchestration +│ ├── Application.php # Main application class +│ ├── Kernel/HttpKernel.php # HTTP request handling +│ ├── DependencyInjection/ # DI container setup +│ ├── Bootstrapper/ # Application initialization +│ └── ServiceProvider/ # Service registration abstractions +├── ErrorHandling/ # Error handling and responses +├── Logging/ # Logging infrastructure +├── Session/ # Session management +└── Cache/ # Caching interfaces +``` + +## Key Concepts + +### 1. Service Providers + +Service Providers register services and bootstrap module-specific functionality: + +- Register services in the DI container +- Bootstrap module-specific functionality +- Register HTTP routes via attribute scanning +- Auto-discovered by `ModuleLoader` from `src/Modules/*/` directories + +### 2. Bootstrappers + +Framework components that set up the application before handling requests: + +- `ConfigInitializer` - Environment configuration +- `DatabaseInitializer` - Database connections +- `SessionInitializer` - Session management +- `ModuleLoader` - Auto-discovers and loads module service providers + +### 3. Dependency Injection Container + +The framework uses `InflectableContainer`, a wrapper around PHP-DI with enhanced features: + +- **Container Inflection**: Automatic method invocation during object resolution +- **Smart Parameter Resolution**: Intelligent detection of class names vs static values +- **Simplified Registration**: Clean syntax for dependency declaration + +**Example:** +```php +// Basic registration +$container->register(ServiceClass::class, [DependencyClass::class]); + +// Interface binding +$container->bind(InterfaceClass::class, ImplementationClass::class, [Dep1::class]); + +// Container inflection (automatic method calls) +$container->inflect(UnitOfWork::class) + ->invokeMethod('registerPersister', [ActivityPersister::class]); +``` + +### 4. Attribute-Based Routing + +Controllers use PHP 8+ attributes for route definitions: + +- Controllers must implement `ControllerInterface` +- Routes automatically discovered during controller registration +- Available attributes: `#[Get]`, `#[Post]`, `#[Put]`, `#[Delete]`, `#[Route]`, `#[Group]` + +**Example:** +```php +#[Group('/api/v1/users')] +class UserController implements ControllerInterface +{ + #[Get('')] + public function index(): ResponseInterface { } + + #[Get('/{id}')] + public function show(string $id): ResponseInterface { } + + #[Post('', middleware: [AuthMiddleware::class])] + public function create(): ResponseInterface { } +} +``` + +### 5. Unit of Work Pattern + +Manages database transactions and entity persistence: + +- **Entity Persisters**: Handle database operations for specific entity types +- **Registration**: Via container inflection +- **Transactional**: All operations executed in single transaction + +### 6. CQRS Separation + +Commands (write operations) and Queries (read operations) are separated: + +- Commands in `Infrastructure/Database/Commands/` +- Queries in `Infrastructure/Database/Queries/` + +## Development Workflow + +### Docker Environment + +All development happens in Docker containers: + +```bash +# Start environment +make up + +# Install dependencies +make install + +# Access container shell +make shell +``` + +**Available Services:** +- **App**: PHP 8.1 + Apache (http://localhost:8000) +- **Database**: MySQL 8.0 (port 3306) +- **phpMyAdmin**: Database management (http://localhost:8080) + +### Testing + +Comprehensive testing suite with PHPUnit: + +```bash +make test # Run all tests +make test-unit # Unit tests only +make test-integration # Integration tests only +make test-coverage # Coverage report +``` + +### Code Quality + +Static analysis and code quality tools: + +```bash +make phpstan # PHPStan static analysis +make deptrac # Deptrac layer analysis +make static-analysis # Run both +make rector # Preview Rector changes +make rector-fix # Apply Rector changes +``` + +## Important Patterns + +### Adding New Modules + +1. Create directory: `src/Modules/{ModuleName}/` +2. Implement Domain, Application, and Infrastructure layers +3. Create `{ModuleName}ServiceProvider.php` in module root +4. ModuleLoader automatically discovers and registers it + +### Creating Service Provider + +```php +class MyModuleServiceProvider extends ServiceProvider +{ + public function register(InflectableContainer $container): void + { + // Register services + $container->register(MyController::class, [MyService::class]); + + // Bind interfaces + $container->bind(MyRepositoryInterface::class, MyRepository::class); + } +} +``` + +### Repository Implementation + +Repositories use Commands/Queries pattern: + +```php +class MyRepository implements MyRepositoryInterface +{ + public function __construct( + private FetchAllQuery $fetchAll, + private SaveCommand $save, + private UnitOfWorkInterface $unitOfWork + ) {} + + public function save(Entity $entity): void + { + $this->unitOfWork->registerNew($entity); + $this->unitOfWork->commit(); + } +} +``` + +## Authentication System + +Two authentication modes available: + +- **Session-based**: Traditional session authentication +- **JWT-based**: Token-based authentication with firebase/php-jwt + +Configured via `AUTH_TYPE` environment variable. + +## Internationalization + +Multi-language support using Symfony Translation: + +- Default locale configurable via environment +- YAML translation files +- Module-specific translations supported + +## Environment Variables + +Key environment variables (see `.env.example`): + +```env +# Database +DB_HOST=db +DB_PORT=3306 +DB_DATABASE=foundation +DB_USERNAME=foundation_user +DB_PASSWORD=foundation_password + +# Authentication +AUTH_TYPE=session +JWT_SECRET=your-secret-key +JWT_ACCESS_TOKEN_TTL=900 + +# Locale +APP_LOCALE=en +APP_SUPPORTED_LOCALES=en,de,fr +``` + +## Debugging + +Xdebug is configured for debugging: + +- Set breakpoints in IDE +- Access application via http://localhost:8000 +- Debug sessions automatically connect on port 9003 + +## Documentation + +Complete documentation available in `./documentation/`: + +- `application-core.md` - Framework architecture overview +- `application-layers.md` - Layer dependency rules +- `attribute-routing.md` - Route attribute system +- `dependency-injection.md` - DI container guide +- `docker-setup.md` - Docker environment details +- `unit-of-work.md` - Unit of Work pattern +- `authentication.md` - Authentication implementation +- `internationalization.md` - i18n setup + +## Common Commands Reference + +**Docker:** +```bash +make up # Start Docker environment +make down # Stop Docker environment +make shell # Access container shell +``` + +**Dependencies:** +```bash +make install # Install composer dependencies +make dump-autoload # Refresh autoload files +``` + +**Testing:** +```bash +make test # Run all tests +make test-unit # Run unit tests +make test-coverage # Generate coverage report +``` + +**Quality:** +```bash +make phpstan # Static analysis +make deptrac # Layer analysis +make rector # Code quality preview +``` + +**Database:** +```bash +# Import schema +docker compose exec -T db mysql -u foundation_user -pfoundation_password foundation < database/schema.sql + +# Access MySQL CLI +docker compose exec db mysql -u foundation_user -p foundation + +# Export database +docker compose exec db mysqldump -u foundation_user -pfoundation_password foundation > backup.sql +``` + +## Best Practices + +1. **Always respect layer boundaries** - Domain must remain pure +2. **Use value objects** for primitive obsession +3. **Keep controllers thin** - Delegate to application services +4. **Use repository interfaces** in Domain layer +5. **Implement CQRS** - Separate read and write operations +6. **Write tests** - Unit tests for domain, integration for infrastructure +7. **Use attributes for routes** - Don't register routes manually +8. **Follow PSR standards** - PSR-4 autoloading, PSR-7 HTTP messages +9. **Document public APIs** - Clear docblocks for interfaces +10. **Use type hints** - Leverage PHP 8.1+ type system + +## Troubleshooting + +### Docker Issues + +- Ensure Docker and Docker Compose are installed +- Check port conflicts (8000, 8080, 3306) +- Verify user permissions: `export USER_ID=$(id -u) && export GROUP_ID=$(id -g)` + +### Database Connection Issues + +- Verify database container is running: `docker compose ps` +- Check environment variables in `.env` +- Ensure database schema is imported + +### Routing Issues + +- Verify controller implements `ControllerInterface` +- Check route attributes syntax +- Ensure controller is registered in service provider + +### Autoloading Issues + +- Run `make dump-autoload` after adding new classes +- Verify PSR-4 namespace matches directory structure From 215564868f58b837b9e83f9ef43c8382cbd577a1 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 4 Nov 2025 21:49:56 +0000 Subject: [PATCH 2/2] Update Claude.md to reference skills with brief overviews MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace detailed instructions with skill references and 2-3 sentence overviews for: - Docker Environment → /docker-setup - Testing → /run-tests - Code Quality → /static-analysis - Adding New Modules → /create-module - Database Operations → /database-operations - Debugging → /debug-setup - Troubleshooting Docker → /troubleshoot-docker This reduces duplication and keeps Claude.md concise while maintaining comprehensive guidance through skills. --- Claude.md | 65 +++++++++++++++---------------------------------------- 1 file changed, 17 insertions(+), 48 deletions(-) diff --git a/Claude.md b/Claude.md index 5d57780..7b39416 100644 --- a/Claude.md +++ b/Claude.md @@ -155,55 +155,29 @@ Commands (write operations) and Queries (read operations) are separated: ### Docker Environment -All development happens in Docker containers: +See skill: `/docker-setup` for detailed instructions. -```bash -# Start environment -make up - -# Install dependencies -make install - -# Access container shell -make shell -``` - -**Available Services:** -- **App**: PHP 8.1 + Apache (http://localhost:8000) -- **Database**: MySQL 8.0 (port 3306) -- **phpMyAdmin**: Database management (http://localhost:8080) +All development happens in Docker containers with PHP 8.1, MySQL 8.0, and phpMyAdmin. Use `make up` to start the environment and `make install` to install dependencies. ### Testing -Comprehensive testing suite with PHPUnit: +See skill: `/run-tests` for detailed instructions. -```bash -make test # Run all tests -make test-unit # Unit tests only -make test-integration # Integration tests only -make test-coverage # Coverage report -``` +Comprehensive testing suite with PHPUnit supporting unit tests, integration tests, and coverage reports. Use `make test` to run all tests. ### Code Quality -Static analysis and code quality tools: +See skill: `/static-analysis` for detailed instructions. -```bash -make phpstan # PHPStan static analysis -make deptrac # Deptrac layer analysis -make static-analysis # Run both -make rector # Preview Rector changes -make rector-fix # Apply Rector changes -``` +Static analysis with PHPStan and Deptrac to enforce type safety and architectural boundaries. Use `make static-analysis` to run both tools. ## Important Patterns ### Adding New Modules -1. Create directory: `src/Modules/{ModuleName}/` -2. Implement Domain, Application, and Infrastructure layers -3. Create `{ModuleName}ServiceProvider.php` in module root -4. ModuleLoader automatically discovers and registers it +See skill: `/create-module` for detailed instructions. + +Create modules following DDD principles with Domain, Application, and Infrastructure layers. The ModuleLoader automatically discovers service providers in `src/Modules/*/`. ### Creating Service Provider @@ -283,11 +257,9 @@ APP_SUPPORTED_LOCALES=en,de,fr ## Debugging -Xdebug is configured for debugging: +See skill: `/debug-setup` for detailed instructions. -- Set breakpoints in IDE -- Access application via http://localhost:8000 -- Debug sessions automatically connect on port 9003 +Xdebug is pre-configured in the Docker environment for PHPStorm and VS Code. Debug sessions connect on port 9003 with automatic path mapping to `/var/www/html`. ## Documentation @@ -332,15 +304,12 @@ make rector # Code quality preview ``` **Database:** + +See skill: `/database-operations` for detailed instructions. + ```bash # Import schema docker compose exec -T db mysql -u foundation_user -pfoundation_password foundation < database/schema.sql - -# Access MySQL CLI -docker compose exec db mysql -u foundation_user -p foundation - -# Export database -docker compose exec db mysqldump -u foundation_user -pfoundation_password foundation > backup.sql ``` ## Best Practices @@ -360,9 +329,9 @@ docker compose exec db mysqldump -u foundation_user -pfoundation_password founda ### Docker Issues -- Ensure Docker and Docker Compose are installed -- Check port conflicts (8000, 8080, 3306) -- Verify user permissions: `export USER_ID=$(id -u) && export GROUP_ID=$(id -g)` +See skill: `/troubleshoot-docker` for detailed diagnostic steps and solutions. + +Common issues include port conflicts (8000, 8080, 3306), permission errors, and container startup failures. Use `docker compose ps` and `docker compose logs` to diagnose problems. ### Database Connection Issues