# AGENTS.md This file provides guidance to agents when working with code in this repository. ## Project Overview CodeIgniter 4 PHP application for laboratory management (GDC CMOD). Handles specimen tracking, request validation, and result management with role-based access control. SQL Server database with Firebird legacy patient data. ## Commands ```bash # Run all tests composer test ./vendor/bin/phpunit # Run single test file ./vendor/bin/phpunit tests/unit/HealthTest.php # Run single test method ./vendor/bin/phpunit tests/unit/HealthTest.php --filter testIsDefinedAppPath # Development server php spark serve # List all routes php spark list # Create controller/model php spark make:controller Admin php spark make:model User ``` ## PHP Standards - PHP 8.1+ features (typed properties, match expressions) - Always declare return types for public methods - No comments unless explaining complex logic - Use `esc()` when outputting user data in views ## Naming Conventions | Type | Convention | Example | |------|------------|---------| | Classes | PascalCase | `Admin`, `UserController` | | Methods/Variables | camelCase | `getUsers()`, `$userId` | | Constants | UPPER_SNAKE_CASE | `DB_HOST` | | Database tables | UPPER_SNAKE_CASE | `GDC_CMOD.dbo.USERS` | | Views | lowercase_underscores | `admin/index.php` | ## Role-Based Access Control | Role ID | Name | Route Prefix | |---------|------|--------------| | 0 | Superuser | `/superuser` | | 1 | Admin | `/admin` | | 2 | Lab | `/lab` | | 3 | Phlebo | `/phlebo` | | 4 | CS | `/cs` | ```php // Single role ['filter' => 'role:1'] // Multiple roles ['filter' => 'role:1,2'] ``` ## Controller Patterns ```php namespace App\Controllers; class Admin extends BaseController { public function index() { } } // API Controllers use ResponseTrait use App\Controllers\BaseController; use CodeIgniter\API\ResponseTrait; class Users extends BaseController { use ResponseTrait; protected $db; public function __construct() { $this->db = \Config\Database::connect(); helper(['url', 'form', 'text']); } } ``` ## Database Operations ```php $this->db = \Config\Database::connect(); // Parameterized queries only $query = $this->db->query("SELECT * FROM table WHERE id = ?", [$id]); $row = $query->getRowArray(); $results = $query->getResultArray(); // Transactions $this->db->transBegin(); try { $this->db->query("INSERT INTO ...", [$data]); $this->db->transCommit(); } catch (\Throwable $e) { $this->db->transRollback(); } ``` ## Request/Response Patterns ```php // GET input $date1 = $this->request->getVar('date1') ?? date('Y-m-d'); // POST JSON $input = $this->request->getJSON(true); // JSON response return $this->respond(['data' => $results]); return $this->response->setJSON(['message' => 'Success']); // View response return view('admin/index', $data); // Redirect with errors return redirect()->back()->with('errors', ['key' => 'message']); ``` ## Session Structure ```php session()->set([ 'isLoggedIn' => true, 'userid' => (string) $user['USERID'], 'userroleid' => (int) $user['USERROLEID'], 'userrole' => (string) $role, ]); ``` ## Validation Endpoints - `POST /api/{resource}/validate/{id}` - validate a record - `DELETE /api/{resource}/validate/{id}` - unvalidate a record ## Security - Use parameterized queries (never interpolate directly) - Hash passwords with `password_hash()` / `password_verify()` - Validate and sanitize all input before use ## Database Schema - Primary: SQL Server (`GDC_CMOD.dbo`) - Legacy: Firebird (`GLENEAGLES` via ODBC) - No CI4 Models - raw SQL queries via `Database::connect()` ## Dual-Level Validation Validation requires 2 different users: 1. First: `ISVAL1=1`, `VAL1USER`, `VAL1DATE` 2. Second (different user): `ISVAL2=1`, `VAL2USER`, `VAL2DATE`