# AGENT.md — PHP Coding Standard This file defines the coding standards and working rules for AI agents and developers contributing to this PHP codebase. It is based on the principles from **PHP: The Right Way** and adapted into practical project instructions. Source reference: https://phptherightway.com/ --- ## 1. Core Philosophy Write PHP that is: - **Readable** before clever. - **Secure by default**. - **Consistent with community standards**. - **Easy to test, debug, and refactor**. - **Separated by responsibility**: routing, controllers, services, models, persistence, templates, and configuration should not be mixed together. PHP does not have only one canonical “right way,” so prefer widely accepted standards, documented project conventions, and clear tradeoffs over personal style. --- ## 2. PHP Version Standard Use the current stable PHP version supported by the project. Default expectation: ```text PHP 8.x+ ``` Do not introduce code that depends on unsupported PHP versions unless the project explicitly targets a legacy runtime. When adding a language feature, verify that it is supported by the project’s configured PHP version in `composer.json`. Example: ```json { "require": { "php": ">=8.2" } } ``` --- ## 3. Coding Style Follow recognized PHP standards unless the repository already defines stricter rules. Preferred standards: - **PSR-1**: Basic Coding Standard - **PSR-12**: Extended Coding Style - **PSR-4**: Autoloading Use automated tooling rather than manual formatting arguments. Recommended tools: ```bash composer require --dev squizlabs/php_codesniffer composer require --dev friendsofphp/php-cs-fixer ``` Example checks: ```bash vendor/bin/phpcs --standard=PSR12 src tests vendor/bin/php-cs-fixer fix --dry-run --diff ``` Example fix: ```bash vendor/bin/php-cs-fixer fix ``` ### Naming Rules Use English names for code symbols and infrastructure. Use: ```php class InvoiceRepository { public function findByCustomerId(int $customerId): array { // ... } } ``` Avoid unclear abbreviations: ```php class InvRepo { public function fbcid($cid) { // ... } } ``` ### Formatting Rules - Use `value; } } ``` Guidelines: - Keep controllers thin. - Put business rules in services or domain objects. - Put persistence logic in repositories or data access classes. - Use interfaces when multiple implementations are expected or when it improves testing. - Avoid huge “utility” classes. - Avoid magic methods unless they provide clear framework integration or a documented benefit. --- ## 8. Dependency Injection Prefer dependency injection over creating dependencies inside classes. Good: ```php final class RegisterUser { public function __construct( private UserRepository $users, private PasswordHasher $passwords ) { } public function handle(string $email, string $plainPassword): void { $hash = $this->passwords->hash($plainPassword); $this->users->create($email, $hash); } } ``` Avoid: ```php final class RegisterUser { public function handle(string $email, string $plainPassword): void { $users = new UserRepository(); $passwords = new PasswordHasher(); // ... } } ``` Rules: - Constructor injection is preferred for required dependencies. - Do not use service locators casually. - Do not hide dependencies in global variables. - Keep dependency containers at application boundaries, not inside domain logic. --- ## 9. Database Access Use PDO or a well-maintained database abstraction layer/ORM. Never concatenate untrusted input into SQL. Bad: ```php $sql = "SELECT * FROM users WHERE id = " . $_GET['id']; ``` Good: ```php $stmt = $pdo->prepare('SELECT * FROM users WHERE id = :id'); $stmt->bindValue(':id', $id, PDO::PARAM_INT); $stmt->execute(); $user = $stmt->fetch(PDO::FETCH_ASSOC); ``` Rules: - Use prepared statements and bound parameters. - Validate input before using it in writes. - Keep SQL out of templates. - Keep database access out of controllers where practical. - Use transactions when multiple writes must succeed or fail together. - Do not rely only on client-side validation. - Do not expose raw database errors to users. Transaction example: ```php $pdo->beginTransaction(); try { $orders->create($order); $auditLog->record('order.created', $order->id()); $pdo->commit(); } catch (Throwable $e) { $pdo->rollBack(); throw $e; } ``` --- ## 10. Input Validation and Output Escaping Treat all external data as untrusted. Untrusted data includes: - `$_GET` - `$_POST` - `$_REQUEST` - `$_COOKIE` - `$_SERVER` - uploaded files - request bodies - session values - database values originally supplied by users - third-party API responses ### Validate on Input Example: ```php $email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL); if ($email === false || $email === null) { throw new InvalidArgumentException('A valid email address is required.'); } ``` ### Escape on Output For HTML output: ```php function e(string $value): string { return htmlspecialchars($value, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'); } ``` Usage: ```php

name()) ?>

``` Rules: - Escape based on context: HTML, attribute, JavaScript, CSS, URL, SQL, shell. - Do not use the same escaping function for every context. - Prefer template engines with automatic escaping when appropriate. - Avoid allowing raw HTML from users. If required, sanitize with a proven whitelist sanitizer. - Use `escapeshellarg()` when passing controlled values to shell commands, and avoid shell execution when possible. - Never trust file paths supplied by users. Reject path traversal values such as `../`, `/`, `\`, and null bytes. --- ## 11. Passwords and Authentication Never store plain-text passwords. Use PHP’s password API: ```php $hash = password_hash($plainPassword, PASSWORD_DEFAULT); if (! password_verify($plainPassword, $hash)) { throw new RuntimeException('Invalid credentials.'); } ``` Rules: - Use `password_hash()` for new password hashes. - Use `password_verify()` for login checks. - Use `password_needs_rehash()` when algorithm/cost settings change. - Do not create your own password hashing algorithm. - Do not use general-purpose hashes like `md5`, `sha1`, or raw `sha256` for passwords. - Rate-limit login attempts. - Regenerate session IDs after login. - Use secure, HTTP-only, SameSite cookies for sessions. --- ## 12. Serialization and Data Exchange Do not call `unserialize()` on untrusted data. Prefer JSON for data exchange: ```php $data = json_decode($json, true, flags: JSON_THROW_ON_ERROR); $json = json_encode($data, JSON_THROW_ON_ERROR); ``` Rules: - Use `JSON_THROW_ON_ERROR` for new code. - Validate decoded data before using it. - Avoid PHP serialization for data that crosses trust boundaries. --- ## 13. Configuration and Secrets Rules: - Keep secrets out of source control. - Do not commit passwords, API keys, private keys, tokens, or production DSNs. - Store configuration outside the public web root. - Use environment variables or ignored local config files for secrets. - Provide a safe example file such as `.env.example`. Example `.gitignore` entries: ```text .env .env.local /config/local.php /var/cache/ /var/log/ /vendor/ ``` Example `.env.example`: ```text APP_ENV=local APP_DEBUG=true DATABASE_URL=mysql://user:password@localhost:3306/app ``` --- ## 14. Error Handling and Logging Use exceptions for exceptional failure paths. Development: - Show errors locally. - Log errors. - Use Xdebug when debugging complex issues. Production: - Do not display errors to users. - Log errors to a secure log destination. - Return safe, generic error messages. - Preserve enough context in logs for troubleshooting. Do not leak: - stack traces to users - SQL statements with secrets - environment variables - full filesystem paths - tokens or passwords Example: ```php try { $service->handle($request); } catch (Throwable $e) { $logger->error('Order processing failed.', [ 'exception' => $e, 'requestId' => $requestId, ]); http_response_code(500); echo 'An unexpected error occurred.'; } ``` --- ## 15. Templates and Views Keep presentation separate from business logic. Rules: - Do not query the database from templates. - Do not place business rules in templates. - Escape output by default. - Prefer simple view models or arrays passed into templates. - Use a template engine with automatic escaping when it fits the project. Plain PHP template example: ```php

``` --- ## 16. HTTP and Web Application Rules Rules: - Use the front controller pattern where appropriate. - Keep routing separate from business logic. - Validate request methods. - Use CSRF protection for state-changing forms. - Use proper HTTP status codes. - Redirect after successful POST to avoid duplicate form submission. - Do not trust headers such as `X-Forwarded-For` unless configured behind a trusted proxy. Example POST guard: ```php if ($_SERVER['REQUEST_METHOD'] !== 'POST') { http_response_code(405); exit('Method Not Allowed'); } ``` --- ## 17. Security Checklist Before completing any feature, verify: - [ ] All external input is validated. - [ ] All output is escaped for the correct context. - [ ] SQL uses prepared statements or safe query builders. - [ ] Authentication and authorization are checked server-side. - [ ] Secrets are not committed. - [ ] Errors are not exposed in production responses. - [ ] File uploads validate size, extension, MIME type, and storage path. - [ ] Passwords use `password_hash()` and `password_verify()`. - [ ] CSRF protection exists for state-changing requests. - [ ] Dangerous functions are avoided or justified: `eval`, `exec`, `shell_exec`, `system`, `passthru`, `unserialize`. - [ ] Dependencies have no known vulnerabilities according to `composer audit`. --- ## 18. Testing Standard Automated tests are expected for new behavior. Preferred tools: - PHPUnit - Pest, if the project already uses it Rules: - Add or update tests with every behavior change. - Cover success paths and failure paths. - Unit-test business logic. - Integration-test database and framework wiring where useful. - Functional-test important user flows. - Avoid relying on `var_dump()` or manual browser testing as the only verification. Example PHPUnit test: ```php final class InvoiceCalculatorTest extends TestCase { public function testItCalculatesTotalInCents(): void { $calculator = new InvoiceCalculator(); $total = $calculator->calculateTotal([ ['amountCents' => 1000], ['amountCents' => 2500], ]); self::assertSame(3500, $total); } } ``` Run tests: ```bash vendor/bin/phpunit ``` --- ## 19. Static Analysis and Quality Gates Use static analysis when available. Recommended tools: ```bash composer require --dev phpstan/phpstan composer require --dev vimeo/psalm ``` Common quality commands: ```bash composer validate composer audit vendor/bin/phpcs --standard=PSR12 src tests vendor/bin/phpunit vendor/bin/phpstan analyse src tests ``` Do not ignore tool failures without documenting why. --- ## 20. Documentation Use PHPDoc where it adds clarity, especially for arrays, generics-like structures, complex return values, and public APIs. Good: ```php /** * @return list */ public function findActiveCustomers(): array { // ... } ``` Avoid noisy comments that repeat the code: ```php // Increment i by one. $i++; ``` Rules: - Explain why, not just what. - Document non-obvious tradeoffs. - Keep README setup instructions current. - Update examples when behavior changes. --- ## 21. Performance and Caching Rules: - Measure before optimizing. - Avoid unnecessary database queries in loops. - Use pagination for large result sets. - Cache expensive reads where appropriate. - Use OPcache in production. - Do not cache user-specific sensitive data in shared caches without a clear key strategy. --- ## 22. Agent Workflow When modifying this codebase, the AI agent must: 1. Inspect existing project conventions before adding new patterns. 2. Prefer small, focused changes. 3. Preserve public behavior unless explicitly asked to change it. 4. Add or update tests when behavior changes. 5. Run relevant checks when possible. 6. Explain any checks that could not be run. 7. Avoid introducing new dependencies unless they solve a clear problem. 8. Never place secrets in code, tests, fixtures, logs, or documentation. 9. Keep generated code consistent with this file. 10. Leave the repository better organized than it was found. --- ## 23. Pull Request / Review Checklist Before considering work complete: - [ ] Code follows PSR-12 or project-specific style. - [ ] Namespaces and autoloading are correct. - [ ] Composer files are valid. - [ ] No unrelated dependency updates were introduced. - [ ] New behavior is tested. - [ ] Existing tests pass. - [ ] SQL is parameterized. - [ ] User input is validated. - [ ] Output is escaped. - [ ] No secrets are committed. - [ ] Errors are handled safely. - [ ] Documentation was updated where needed. --- ## 24. Legacy PHP Exception Policy If this project contains legacy PHP: - Do not rewrite large areas without approval. - Add tests around legacy behavior before refactoring. - Improve safety incrementally. - Replace deprecated patterns as touched. - Avoid mixing modernization with unrelated feature work. - Document any compatibility constraints. Legacy code should still move toward: - Composer autoloading - Namespaces - PDO/prepared statements - Centralized configuration - Automated tests - Safer error handling --- ## 25. Non-Negotiable Rules The agent must not: - Commit secrets. - Build SQL using untrusted string concatenation. - Store plain-text passwords. - Use `md5`, `sha1`, or raw fast hashes for passwords. - Display production errors to users. - `unserialize()` untrusted data. - Put database queries in templates. - Edit files under `vendor/`. - Add dependencies without a clear reason. - Ignore failing tests or quality checks without explanation. --- ## 26. Recommended Composer Scripts A project may include scripts like this: ```json { "scripts": { "test": "phpunit", "style": "phpcs --standard=PSR12 src tests", "style:fix": "php-cs-fixer fix", "analyse": "phpstan analyse src tests", "quality": [ "@style", "@test", "@analyse" ] } } ``` Then run: ```bash composer quality ``` --- ## 27. Final Instruction to Coding Agents When in doubt, choose the boring, obvious, secure PHP solution: - Composer-managed dependencies - PSR-style code - Namespaced classes - Dependency injection - PDO prepared statements - Escaped output - Tested behavior - Clear errors and logs - No secrets in source control ## Project Overview This project is a small PHP MVC framework called MindVisionCode PHP. It is intentionally inspired by a Classic ASP MVC framework style: - Central dispatcher - Controllers and actions - ViewModels - Repository classes - Simple validation - Database migrations - Small, readable files - Minimal dependencies Do not turn this into Laravel, Symfony, Slim, or another large framework. ## Tech Stack - PHP 8.2+ - Composer - PSR-4 autoloading - PDO - PHP views - Optional SQLite/MySQL/SQL Server through PDO ## Development Commands Install dependencies: ```bash composer install ``` Regenerate autoload files: ```bash composer dump-autoload ``` Run local server: ```bash php -S localhost:8000 -t public ``` Run basic tests: ```bash php tests/run.php ``` ## Coding Rules - Keep code simple and readable. - Prefer small classes. - Use typed properties and return types where practical. - Avoid hidden magic. - Do not add dependencies without a clear reason. - Preserve the framework style. - Explain any architectural changes. ## Request Flow Browser → public/index.php → Request → Dispatcher → Router → Route → Controller → ViewModel/Repository → View → Response ## Creating Table When you create tables and code for a table you will need a corrisponding _audit table with audit_id , id that refrences the object id , an action R I U D , the fields in json , username and created at ### Color System Visual direction: calm operational clarity with high-signal status semantics. Core palette: - Primary: `#1F4E79` (municipal navy; trust and structure) - Secondary: `#0F766E` (teal support/action) - Accent: `#2563EB` (interactive focus/action emphasis) Semantic status palette: - Success / On Track: `#2E7D32` - Warning / At Risk: `#B45309` - Error / Blocked: `#B91C1C` - Info / Neutral Progress: `#2563EB` - Overdue / Critical Flag: `#7F1D1D` Neutral foundation: - Background: `#F7F9FC` - Surface: `#FFFFFF` - Border: `#D0D7E2` - Primary Text: `#111827` - Secondary Text: `#4B5563` Ant Design token strategy: - Configure global tokens first (`colorPrimary`, `colorSuccess`, `colorWarning`, `colorError`, `colorInfo`, `colorBgBase`, `colorText`, `borderRadius`, density-related sizing). - Keep status meaning consistent across tables, tags, timelines, and alerts. ### Typography System Tone: professional, clear, non-decorative, optimized for dense operational reading. Type stack: - Primary UI text: `Public Sans`, `Segoe UI`, `Arial`, sans-serif - Data-heavy/labels fallback: `IBM Plex Sans`, `Segoe UI`, sans-serif - Monospace for IDs/reference codes: `IBM Plex Mono`, `Consolas`, monospace Type hierarchy (desktop-first): - H1: 28px / 36px / 600 - H2: 22px / 30px / 600 - H3: 18px / 26px / 600 - Body default: 14px / 22px / 400 - Dense table/body compact: 13px / 20px / 400 - Caption/meta: 12px / 18px / 400 Typography principles: - Prioritize legibility over brand flourish. - Keep numeric/date fields highly scannable. - Use consistent casing and label patterns for form-heavy workflows. ### Spacing & Layout Foundation Layout direction: compact, structured, desktop-optimized operational workspace. Spacing system: - Base unit: 8px - Micro spacing for dense table controls: 4px - Section spacing rhythm: 16px / 24px / 32px Grid and containers: - Desktop-first 12-column grid - Content max-width bands for readability in wide monitors - Persistent side regions for risk queue/filter panels when useful Component density rules: - Default to compact controls for grid and forms - Keep touch-target inflation out of scope (PC-only product) - Reserve larger spacing only for high-risk confirmations/modals Visual rhythm: - Clear row grouping and section boundaries - Strong alignment around key operational identifiers (municipality, cycle, status, due date) ### Accessibility Considerations - WCAG 2.2 AA minimum contrast targets: - 4.5:1 for normal text - 3:1 for large text and UI components - Keyboard-first operation: - Visible 2px focus indicators on interactive elements - Logical tab order in grids, forms, drawers, and modals - Do not rely on color alone: - Pair status colors with labels/icons/patterns - Motion and feedback: - Subtle motion only for orientation, not decoration - Respect reduced-motion preferences - Dense-data readability: - Preserve minimum font sizes and row heights that remain readable during long operational sessions # UI desgin - Refer to template info in the files docs\ux-color-themes.html and docs\ux-design-directions.html