From 09a1c6715fb3857443e2cffc88bd2f1da1c33bff Mon Sep 17 00:00:00 2001 From: mahdahar <89adham@gmail.com> Date: Thu, 12 Mar 2026 12:49:52 +0700 Subject: [PATCH] fix: show UnVal button for validated but incomplete requests - Update UnVal visibility condition from ISVAL check to VAL1USER && VAL2USER - Fix validated-but-incomplete requests missing the UnVal action button - Align isValidated() function with same logic for consistency - Refactor AGENTS.md formatting --- AGENTS.md | 265 ++++++++++++-------------- app/Views/shared/content_requests.php | 2 +- app/Views/shared/script_requests.php | 2 +- 3 files changed, 127 insertions(+), 142 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 6634ca2..b787798 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,173 +1,158 @@ # AGENTS.md +Guidance for coding agents working in `D:\data\www\gdc_cmod`. -This file provides guidance to agents when working with code in this repository. +## 1) Repository Summary +- Stack: CodeIgniter 4 + PHP 8.1+. +- Package manager: Composer. +- Test framework: PHPUnit 10 (`phpunit.xml.dist`). +- App domain: laboratory workflow (requests, samples, validation, reporting). +- Auth: session-based, route filters (`role`, `guest`). +- Data sources: SQL Server (`GDC_CMOD.dbo`) + legacy Firebird integration. +- Frontend: PHP views with Tailwind/DaisyUI/Alpine assets from `public/`. -## Project Overview +## 2) Rule Files Check +- Cursor rules: not found (`.cursor/rules/` and `.cursorrules` absent). +- Copilot rules: not found (`.github/copilot-instructions.md` absent). +- If these files are later added, treat them as high-priority instructions. -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. - -## Tool Usage - -Always use Serena MCP tools for anything possible: -- Use `serena_find_symbol` instead of grep when looking for classes, methods, or functions -- Use `serena_search_for_pattern` instead of grep for code pattern searches -- Use `serena_read_file` or `serena_replace_content` instead of Read/Edit tools -- Use `serena_find_referencing_symbols` to find where symbols are used -- Use `serena_replace_symbol_body` or `serena_insert_after_symbol` for code modifications -- Only use Bash for shell commands (git, composer, php, etc.) - -## Commands +## 2.1) Codebase-Memory MCP Workflow (Default) +- This repository is indexed in `codebase-memory-mcp` (session project `D-data-www-gdc_cmod`). +- Before broad architecture analysis, run: + - `index_status` (confirm graph is ready) + - `get_architecture` for `languages`, `packages`, `layers`, `file_tree` +- Prefer `search_graph` + `get_code_snippet` + `trace_call_path` for impact/call-chain questions. +- For change impact before commits, use `detect_changes(scope='all'|'branch')`. +- Important: results can be noisy due to minified vendor assets in `public/js/*.min.js`. +- When querying routes/hotspots, scope to app PHP files (`file_pattern='app/**/*.php'`) where possible. +## 3) Core Commands ```bash -# Run all tests -composer test -./vendor/bin/phpunit +# install deps +composer install -# 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 +# run dev server php spark serve -# List all routes +# list spark commands +php spark + +# list routes (preferred) +php spark routes + +# alternate command used in this repo php spark list - -# Create controller/model -php spark make:controller Admin -php spark make:model User ``` -## PHP Standards +## 4) Test Commands (Use These) +```bash +# full suite +composer test -- 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 +# full suite (direct) +./vendor/bin/phpunit -## Naming Conventions +# windows direct +vendor\bin\phpunit -| 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` | +# single test file +./vendor/bin/phpunit tests/unit/ReportTest.php -## Role-Based Access Control +# single test class +./vendor/bin/phpunit --filter ReportTest -| Role ID | Name | Route Prefix | -|---------|------|--------------| -| 0 | Superuser | `/superuser` | -| 1 | Admin | `/admin` | -| 2 | Lab | `/lab` | -| 3 | Phlebo | `/phlebo` | -| 4 | CS | `/cs` | +# single test method +./vendor/bin/phpunit tests/unit/HealthTest.php --filter testIsDefinedAppPath -```php -// Single role -['filter' => 'role:1'] -// Multiple roles -['filter' => 'role:1,2'] +# single test directory +./vendor/bin/phpunit tests/unit ``` -## 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']); - } -} +## 5) Lint / Static Analysis +- No dedicated linter/formatter configs were found (`phpcs`, `php-cs-fixer`, `pint`). +- No static analysis configs were found (`phpstan`, `psalm`). +- Use syntax lint for changed PHP files: +```bash +php -l app/Controllers/RequestsController.php +php -l app/Config/Routes.php ``` +- If you add QA tooling, update this file with exact commands. -## Database Operations +## 6) Code Organization +- Controllers: `app/Controllers` and `app/Controllers/Pages`. +- Filters: `app/Filters`, aliases in `app/Config/Filters.php`. +- Routes: `app/Config/Routes.php`. +- Views: `app/Views/...`. +- Tests: `tests/unit`, `tests/database`, `tests/session`, `tests/_support`. +- Most DB access uses raw SQL (`\Config\Database::connect()`), not CI models. -```php -$this->db = \Config\Database::connect(); +## 7) Style Rules (PHP) -// Parameterized queries only -$query = $this->db->query("SELECT * FROM table WHERE id = ?", [$id]); -$row = $query->getRowArray(); -$results = $query->getResultArray(); +### Imports and namespaces +- Keep valid namespace per folder. +- Use `use` imports for frequently referenced classes. +- Remove unused imports. +- Keep one class per file. -// Transactions -$this->db->transBegin(); -try { - $this->db->query("INSERT INTO ...", [$data]); - $this->db->transCommit(); -} catch (\Throwable $e) { - $this->db->transRollback(); -} -``` +### Formatting +- Prefer 4 spaces in new/edited code. +- Existing files may contain mixed tabs/spaces; avoid full-file reformat churn. +- Keep methods small; extract helpers for complex branching. +- Keep comments sparse; only explain non-obvious logic. -## Request/Response Patterns +### Types +- Add parameter and return types in new/modified methods when practical. +- Prefer explicit casts for session/DB values used in role or numeric logic. +- Prefer strict comparisons (`===`, `!==`) over loose comparisons. -```php -// GET input -$date1 = $this->request->getVar('date1') ?? date('Y-m-d'); +### Naming +- Classes: `PascalCase`. +- Methods/variables: `camelCase`. +- Constants: `UPPER_SNAKE_CASE` (`ROLE_NAMES`). +- SQL identifiers follow existing DB naming (often uppercase). +- Views use existing naming conventions (lowercase/underscores). -// POST JSON -$input = $this->request->getJSON(true); +## 8) Imports, Responses, and Controller Patterns +- API endpoints commonly use `CodeIgniter\API\ResponseTrait`. +- JSON responses: `$this->response->setJSON([...])` or `$this->respond([...])`. +- HTML responses: `return view('path/to/view', $data);`. +- Inputs: `getGet()`, `getPost()`, `getJSON(true)` based on content type. +- Validate required inputs early and return errors promptly. -// JSON response -return $this->respond(['data' => $results]); -return $this->response->setJSON(['message' => 'Success']); +## 9) SQL and Data Safety +- Prefer parameterized queries for all user/session-controlled values. + - Good: `$db->query('... WHERE ACCESSNUMBER = ?', [$accessNumber]);` + - Avoid: SQL string interpolation with raw request/session data. +- Use transactions for multi-step writes that must be atomic. +- Preserve dual-validation behavior (`ISVAL1/ISVAL2`, two distinct users). +- Keep audit logging writes (`AUDIT_EVENTS`, `AUDIT_REQUESTS`) intact when changing flows. -// View response -return view('admin/index', $data); +## 10) Error Handling and Logging +- Return consistent JSON shape for API failures (`status`, `message`). +- For external HTTP/cURL calls, check HTTP code and handle failures explicitly. +- Use `log_message('error', ...)` for operational failures. +- Do not expose secrets, stack traces, or sensitive internals to clients. -// Redirect with errors -return redirect()->back()->with('errors', ['key' => 'message']); -``` +## 11) Security Requirements +- Escape user-facing output in views with `esc()`. +- Enforce auth + role checks through route filters and session state. +- Use `password_hash()` and `password_verify()` for credentials. +- Never commit `.env` or secrets. -## Session Structure +## 12) Role and Routing Conventions +- Role IDs: + - `0` Superuser + - `1` Admin + - `2` Lab + - `3` Phlebo + - `4` CS +- Route filter examples: + - Single role: `['filter' => 'role:1']` + - Multiple roles: `['filter' => 'role:0,1,2']` -```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` +## 13) Agent Change Checklist +- Make minimal, targeted changes. +- Do not revert unrelated local modifications. +- Keep backward compatibility for response payloads unless asked otherwise. +- Run at least one relevant test file after code changes. +- If no tests exist for a changed behavior, add focused tests when feasible. +- Update this file when commands/conventions/tooling change. diff --git a/app/Views/shared/content_requests.php b/app/Views/shared/content_requests.php index 4551a86..576e36e 100644 --- a/app/Views/shared/content_requests.php +++ b/app/Views/shared/content_requests.php @@ -326,7 +326,7 @@ $canUnval = $userLevel <= 1;