Files
michaelschiemer/AGENTS.md
Michael Schiemer 8919da8a5c refactor(logging, queue): replace RedisQueue with FileQueue for async logging
- Update `LoggerInitializer` to use `FileQueue` instead of `RedisQueue` for async logging, improving local file-based queuing.
- Remove unused `RedisQueue` and related Redis configurations.
- Modify `createQueue` to accept `PathProvider` for file path resolution.
- Revise `AGENTS.md` to add detailed AI agent usage and updated guidelines.
- Refactor `ComponentRegistryInitializer` to use explicit dependency injection for `__invoke` method, ensuring cleaner and more maintainable initialization logic.
2025-11-03 20:09:32 +01:00

15 KiB

AI Agent Guidelines

This file provides comprehensive guidance for AI agents (like Claude Code, Cursor AI, etc.) when working with code in this repository.

See also: CLAUDE.md for Claude-specific guidance and docs/claude/ for detailed documentation.

Quick Reference

  • Framework: Custom PHP Framework (PHP 8.5+)
  • Local URL: https://localhost (HTTPS required)
  • Docker: Use make up to start containers
  • MCP Server: docker exec -i php php console.php mcp:server
  • Testing: Pest Framework (preferred), PHPUnit (legacy)
  • Code Style: PSR-12 with php-cs-fixer

MCP Server Integration ??

IMPORTANT: This project has a fully functional MCP (Model Context Protocol) server that provides direct access to framework internals.

Quick Access Commands

# Start MCP server
docker exec -i php php console.php mcp:server

# Test MCP server
echo '{"jsonrpc": "2.0", "method": "initialize", "params": {}}' | docker exec -i php php console.php mcp:server

Available MCP Tools

Framework Analysis:

  • analyze_routes: Get all registered routes in the framework
  • analyze_container_bindings: Analyze DI container bindings
  • discover_attributes: Discover attributes by type
  • framework_health_check: Health check of framework components
  • list_framework_modules: List all framework modules

Codebase Analysis:

  • analyze_codebase: Intelligent codebase analysis with semantic search
  • find_controllers: Find all controller classes
  • find_services: Find all services, managers, repositories
  • find_value_objects: Find all Value Object classes
  • find_initializers: Find all DI container initializers
  • find_mcp_tools: Find all MCP tool methods
  • find_commands: Find all console commands
  • search_by_pattern: Search by class name patterns

File System:

  • list_directory: List directory contents (project-scoped)
  • read_file: Read file contents with line limits
  • find_files: Find files by pattern

Git Operations:

  • git_status: Git status with staged/unstaged/untracked changes
  • git_diff: Diff for staged or unstaged changes
  • git_add: Stage files for commit
  • git_commit: Create commit with message
  • git_generate_commit_message: AI-generated commit messages
  • git_log: Get commit history
  • git_branch_info: Branch information
  • git_changed_files: List changed files with types
  • git_stash: Stash changes
  • git_stash_list: Show stash list

MCP Resources

  • framework://config: Framework configuration and environment

Configuration for Claude Desktop

{
  "mcpServers": {
    "custom-php-framework": {
      "command": "docker",
      "args": ["exec", "-i", "php", "php", "console.php", "mcp:server"],
      "cwd": "/home/michael/dev/michaelschiemer"
    }
  }
}

Framework Architecture Principles

Core Principles (MANDATORY)

  1. No Inheritance: Composition over inheritance - avoid extends completely
  2. Immutable by Design: Objects should be immutable whenever possible
  3. Readonly Everywhere: Classes and properties readonly where possible
  4. Final by Default: Classes are final unless specifically designed for extension
  5. Explicit Dependency Injection: No global state or service locators
  6. Value Objects over Primitives: Use Value Objects instead of arrays/primitives
  7. Variadic Parameters: Use variadic parameters instead of arrays where possible
  8. Event-Driven Architecture: Loose coupling through domain events

Example: Correct Class Design

// ? CORRECT: Final readonly class with composition
final readonly class OrderProcessor
{
    public function __construct(
        private readonly PaymentGateway $paymentGateway,
        private readonly InventoryService $inventory,
        private readonly EmailService $emailService,
        private readonly Logger $logger
    ) {}
    
    public function process(Order $order): void
    {
        // Business logic with injected dependencies
    }
}

// ? WRONG: Inheritance and mutable state
class OrderProcessor extends BaseProcessor
{
    private $paymentGateway; // Mutable, no DI
}

Value Objects Usage

// ? WRONG: Primitive obsession
function createUser(string $email, array $preferences): array

// ? CORRECT: Value Objects
function createUser(Email $email, UserPreferences $preferences): User

Development Commands

PHP Development

composer install      # Install PHP dependencies
composer cs           # Run code style checks (dry-run)
composer cs-fix       # Fix code style issues
composer reload       # Dump autoloader with optimization
./vendor/bin/pest     # Run PHP tests (Pest framework)
make phpstan          # Run PHPStan (always use make command)

Frontend Development

npm install           # Install Node.js dependencies
npm run dev           # Start Vite dev server with HTTPS
npm run build         # Build production assets
npm run preview       # Preview production build
npm run test          # Run Jest tests
npm run deploy        # Build and deploy assets to public/

Docker & Environment

make up               # Start all Docker containers
make down             # Stop all containers
make build            # Build Docker images
make logs             # View Docker logs
make reload           # Dump autoloader and restart PHP container
make console          # Run console commands in Docker PHP container
make cs               # Run code style checks in Docker
make cs-fix           # Fix code style in Docker
make cs-fix-file FILE=path/to/file.php  # Fix code style for specific file
make fix-perms        # Fix file permissions
make doctor           # Check prerequisites and project health

Console Commands

php console.php                    # Run console application
docker exec php php console.php     # Run console in Docker
php console.php mcp:server          # Start MCP server for AI integration

Database & Migration Commands

php console.php make:migration CreateUsersTable [Domain]  # Generate migration
php console.php db:migrate                                 # Apply migrations
php console.php db:rollback [steps]                        # Rollback migrations
php console.php db:status                                  # Show migration status

Local Development Access

  • Framework URL: https://localhost
  • HTTPS Required: HTTPS is mandatory - HTTP requests will be rejected
  • SSL Certificates: Automatically configured for local development
  • User Agent Required: Always use a browser User-Agent header to avoid triggering firewall rules

HTTP Client Configuration

When making HTTP requests to the framework, always include a browser User-Agent:

curl -H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" \
     https://localhost/api/endpoint

Testing Guidelines

Test Organization

Test Directory Structure:

tests/
??? debug/           # Debug and development scripts
?   ??? test-*.php   # Debug scripts for testing functionality
??? Unit/            # Unit tests mirroring src/ structure
??? Feature/         # Feature/integration tests
??? tmp/             # Temporary test files (gitignored)
??? pest.php         # Pest configuration

Important Test Rules:

  • All test files must be placed in tests/ directory
  • PHP test scripts (including non-Pest tests) belong in tests/ directory
  • Debug scripts: Place debug PHP scripts in tests/debug/ directory
  • Pest preferred: Always prefer Pest over PHPUnit for new tests
  • No mocking: Avoid mocking - use real implementations and test data
  • Directory structure: Tests should mirror source directory structure
  • Temporary files: All test temporary files must be created in tests/tmp/ or tests/ directory
  • Never create files in the project root directory during tests
  • Clean up: Tests should clean up their temporary files after execution
  • Isolation: Each test should use unique filenames to avoid conflicts

Test Example (Pest)

it('can calculate order total with tax', function () {
    $order = new Order([
        new OrderItem(new Price(1000, Currency::EUR), quantity: 2),
        new OrderItem(new Price(500, Currency::EUR), quantity: 1)
    ]);
    
    $calculator = new OrderCalculator(new TaxRate(0.19));
    $total = $calculator->calculateTotal($order);
    
    expect($total->cents)->toBe(2975);
});

Project Structure & Module Organization

  • src/ layers PHP code (Application, Domain, Framework, Infrastructure)
  • resources/ stores Vite-managed frontend code (resources/js, resources/css)
  • public/assets contains build artifacts under the public/ web root
  • tests/ mirrors PHP namespaces and houses Playwright suites in tests/e2e
  • docs/, docker/, deployment/ contain operational docs and tooling

Directory Structure

src/
??? Application/          # Application-specific controllers and logic
??? Domain/              # Domain models and business logic
??? Framework/           # Framework core components
?   ??? Mcp/            # MCP server and tools for AI integration
??? Infrastructure/      # External service integrations

Code Style & Naming Conventions

  • PSR-12: Follow PSR-12 coding standards with strict types
  • Strict Types: declare(strict_types=1) in all PHP files
  • Constructor Injection: Prefer constructor injection over setters
  • Naming: Suffix integrations with their role (MailerAdapter, RedisCache)
  • Immutability: Keep PHP objects immutable unless Domain logic requires mutation
  • Interfaces: Colocate interfaces with their consuming layer
  • Indentation: 4-space indents in PHP, Prettier defaults for TypeScript
  • Frontend: PascalCase for components, camelCase for utilities

Architecture Components

Application Bootstrap

  • src/Framework/Core/Application.php - Main application class orchestrating request lifecycle
  • src/Framework/Core/AppBootstrapper.php - Bootstraps application and DI container
  • Uses event system for application lifecycle (ApplicationBooted, BeforeHandleRequest, etc.)

Dependency Injection

  • src/Framework/DI/Container.php - DI container interface
  • src/Framework/DI/DefaultContainer.php - Default container implementation
  • Supports binding, singletons, and instance registration
  • Automatic dependency resolution and method invocation

HTTP & Routing

  • Attribute-based routing using #[Route] attributes
  • src/Framework/Http/Middlewares/RoutingMiddleware.php - Core routing middleware
  • Middleware chain pattern for request processing
  • Support for different result types (JsonResult, ViewResult, Redirect, etc.)

Database System

  • EntityManager with UnitOfWork Pattern
  • Schema Builder: Database-agnostic migrations with fluent API
  • Connection Pooling: Health monitoring and automatic recovery
  • Value Objects: Use TableName, ColumnName, IndexName, etc. for database identifiers

Event System

  • Event Dispatcher for Application Events
  • Domain Events for Business Logic
  • Extensible Event Handling Architecture

Exception Handling

Exception Types

  • FrameworkException: Base framework exception
  • ConfigurationException: Configuration-related errors
  • DatabaseException: Database connection and query errors
  • ValidationException: Input validation failures
  • AuthorizationException: Access control violations
  • ResourceNotFoundException: Missing resources
  • DependencyInjectionException: DI container errors
  • SerializationException: Serialization/deserialization issues

Error Handling Pattern

final class UserNotFoundException extends FrameworkException
{
    public static function byId(UserId $id): self
    {
        return self::create(
            DatabaseErrorCode::ENTITY_NOT_FOUND,
            "User with ID '{$id->toString()}' not found"
        )->withData([
            'user_id' => $id->toString(),
            'search_type' => 'by_id'
        ]);
    }
}

Security Guidelines

Authentication & Authorization

  • IP-based authentication for Admin Routes
  • Route protection via #[Auth] attributes
  • Session-based authentication with roles

Input Validation

  • Use Request Objects for validation
  • Value Objects for type-safe inputs
  • Never use superglobals - use HttpRequest instead

Security Best Practices

  • Never expose sensitive error details in production
  • Mask internal system information
  • Use generic error messages for security-sensitive scenarios
  • Log detailed errors server-side
  • Implement rate limiting for repeated error conditions

Template System

Important: The template system does NOT use PHP. It uses HTML template components with placeholders in curly braces {}.

Collections and Interfaces

  • Collections implement IteratorAggregate + Countable

Parameter Design

  • Variadic Parameters: Use variadic parameters instead of arrays wherever possible

Commit & Pull Request Guidelines

  • Use Conventional Commands (fix:, feat:, optional scope) for commit messages
  • PRs must outline the change, list executed checks, and link issues
  • Attach screenshots for UI work or config diffs for ops updates
  • Confirm CI covers Pest, Jest, Playwright, PHPStan, and php-cs-fixer before requesting review

Security & Configuration Tips

  • Never commit .env or secrets
  • Follow ENV_SETUP.md for environment setup
  • Store deployment credentials in Vault
  • Run make security-check ahead of releases
  • Reflect infrastructure changes in docs/deployment/

Performance Guidelines

Database Optimization

  • Use bulk operations with EntityManager
  • Prevent N+1 queries with eager loading
  • Use transactions for multiple operations

Caching Strategy

  • Use framework Cache interface with Value Objects (CacheKey, CacheItem, Duration)
  • Use remember() pattern for caching
  • Support for cache tags for grouped invalidation

Configuration Management

Typed Configuration

Use Environment class with EnvKey enums:

final readonly class DatabaseConfig
{
    public static function fromEnvironment(Environment $env): self
    {
        return new self(
            host: $env->get(EnvKey::DB_HOST, 'localhost'),
            port: $env->getInt(EnvKey::DB_PORT, 3306),
            database: $env->require(EnvKey::DB_NAME),
            username: $env->require(EnvKey::DB_USER),
            password: $env->require(EnvKey::DB_PASS)
        );
    }
}

Additional Documentation

For detailed information, see:

  • docs/claude/guidelines.md - Detailed coding guidelines
  • docs/claude/architecture.md - Architecture documentation
  • docs/claude/development-commands.md - Command reference
  • docs/claude/common-workflows.md - Common development workflows
  • docs/claude/error-handling.md - Error handling patterns
  • docs/claude/security-patterns.md - Security patterns
  • docs/claude/mcp-integration.md - MCP integration details
  • And other files in docs/claude/

Quick Checklist for AI Agents

Before making changes:

  • Follow framework principles (no inheritance, readonly, final, immutable)
  • Use Value Objects instead of primitives/arrays
  • Place test files in tests/ directory
  • Use Pest for new tests (avoid mocking)
  • Include browser User-Agent in HTTP requests
  • Use make commands for Docker operations
  • Run code style checks: make cs or composer cs
  • Ensure HTTPS for local development
  • Clean up temporary files in tests
  • Use variadic parameters instead of arrays where possible
  • Use MCP tools for framework analysis when available