# AGENTS.md ## Build, Lint, and Test Commands ### Running Tests ```bash # Run all tests composer test ./phpunit # Run all tests (Windows) vendor\bin\phpunit # Run a single test file ./phpunit tests/unit/HealthTest.php # Run a single test method ./phpunit --filter testIsDefinedAppPath # Run tests in a specific directory ./phpunit tests/unit/ # Run tests with coverage report ./phpunit --colors --coverage-text=tests/coverage.txt --coverage-html=tests/coverage/ -d memory_limit=1024m # Generate HTML coverage report ./phpunit --coverage-html build/logs/html ``` ### Dependencies ```bash # Install dependencies composer install # Update dependencies composer update ``` ### CodeIgniter Spark Commands ```bash # List available spark commands php spark list # Clear all caches php spark cache:clear # Run migrations php spark migrate # Rollback migrations php spark migrate:rollback ``` ## Code Style Guidelines ### General Principles - Write clean, readable code without unnecessary comments - Follow CodeIgniter 4 conventions and PSR-12 PHP standards - Keep methods focused and under 100 lines when possible - Avoid deep nesting (max 3-4 levels) ### Naming Conventions | Element | Convention | Examples | |---------|------------|----------| | Classes | PascalCase | `ProductsModel`, `BaseController`, `UsersLogModel` | | Files | Match class name | `ProductsModel.php`, `BaseController.php` | | Methods | camelCase | `getProductAlias()`, `productslog_edit()` | | Variables | camelCase | `$productid`, `$data`, `$results` | | Properties | snake_case | `$table`, `$primaryKey`, `$allowedFields` | | Constants | UPPER_SNAKE_CASE | `APPPATH`, `HOMEPATH` | | Namespaces | PascalCase | `App\Controllers`, `App\Models`, `Config` | ### File Structure ```php data['productowners'] = ['S' => 'Summit', 'C' => 'Customer']; // Multi-line array with proper alignment protected $allowedFields = [ 'siteid', 'productnumber', 'productname', 'catalogid', ]; ``` ### Control Structures ```php // Single-line condition with braces if ($productid !== null) { // code } // Multi-line conditions if ($areaid !== '' || $producttypeid !== '') { $sql .= ' AND '; } // Ternary for simple conditions $locationstartdate = ($this->request->getVar('locationstartdate') === '') ? null : $this->request->getVar('locationstartdate'); ``` ### Database Operations - Use `$db = \Config\Database::connect();` for direct queries - Use Query Builder when possible: `$db->table()->get()->getResultArray()` - Always escape user input: `$db->escapeString($value)` - Use parameterized queries to prevent SQL injection ```php $builder = $db->table('products'); $builder->where('productid', $productid); $query = $builder->get(); $results = $query->getResultArray(); ``` ### Controllers - All controllers extend `BaseController` - Use `$this->request->getMethod()` to check request type - Use `$this->request->getVar()` or `$this->request->getPost()` for input - Return views with `return view('view_name', $data);` - Validate input with `$this->validate($rules)` before processing ```php public function edit($productid = null) { if ($this->request->getMethod() === 'POST') { $rules = [ 'productid' => 'required', 'productnumber' => 'required', ]; if ($this->validate($rules)) { // process form } } return view('products_edit', $data); } ``` ### Models - All models extend `CodeIgniter\Model` - Define `$table`, `$primaryKey`, `$allowedFields` - Use `$useSoftDeletes` for soft delete functionality - Define `$useTimestamps` if using created_at/updated_at ```php validate($rules)` - Return appropriate HTTP status codes in API controllers - Use `try/catch` for operations that may throw exceptions - Log errors using CodeIgniter's logging: `log_message('error', $message)` ```php try { $productsModel = new ProductsModel(); $productsModel->update($productid, $data['new_value']); return view('form_success', $data); } catch (\Exception $e) { log_message('error', $e->getMessage()); return view('error_page'); } ``` ### Views - Place views in `app/Views/` directory - Use `.php` extension - Access data via associative array: `$products`, `$data['products']` - Use CodeIgniter's view parser or raw PHP ### API Responses ```php // Return JSON response return $this->response->setJSON([ 'status' => 'success', 'data' => $data, ]); // Error response return $this->response->setJSON([ 'status' => 'error', 'message' => 'No data found', ]); ``` ### Testing - Extend `CodeIgniter\Test\CIUnitTestCase` for all tests - Test methods must start with `test` prefix - Use `@internal` docblock for test classes ```php assertTrue(defined('APPPATH')); } } ``` ### PHP Requirements - PHP 8.1 or higher - Extensions required: `intl`, `mbstring`, `json` - MySQLi database driver by default