gdc_cmod/AGENTS.md
mahdahar b29f807295 Refactor: Remove V2 namespace and consolidate role-based architecture
- Moved all V2 controllers (Lab, Requests, Samples, Users) to App\Controllers
- Removed deprecated role controllers (Admin, Doctor, Analyst, CustomerService)
- Simplified routes by removing /v2 prefix
- Added AGENTS.md with project conventions and TODO.md with task tracking
- Updated README.md with RBAC documentation
- Fixed hardcoded dates, status color mappings, and duplicate database calls
2026-01-19 10:55:10 +07:00

268 lines
6.0 KiB
Markdown

# AGENTS.md
This file provides guidance to agents when working with code in this repository.
## Project Overview
This is a CodeIgniter 4 PHP application for a laboratory management system (CMOD). It uses SQL Server database with role-based access control for different user types (admin, doctor/analyst, customer service).
## Commands
```bash
# Run all tests
./vendor/bin/phpunit
composer test
# 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 (Linux/Mac)
php spark serve
# List all routes
php spark list
# Create controller
php spark make:controller Admin
# Create model
php spark make:model User
```
## Code Style Guidelines
### PHP Standards
- Use PHP 8.1+ features (typed properties, match expressions where appropriate)
- Always declare return types for public methods
- Use `strict_types=1` not required (CodeIgniter doesn't use it)
- No comments unless explaining complex logic (per project convention)
### Naming Conventions
- **Classes**: PascalCase (e.g., `Admin`, `UserController`)
- **Methods**: camelCase (e.g., `index()`, `getUsers()`)
- **Variables**: camelCase (e.g., `$userId`, `$dataList`)
- **Constants**: UPPER_SNAKE_CASE (e.g., `DB_HOST`)
- **Database tables**: UPPER_SNAKE_CASE (e.g., `GDC_CMOD.dbo.USERS`)
- **Views**: lowercase with underscores (e.g., `admin/index.php`)
### Controller Patterns
#### Base Controllers
- All controllers extend `App\Controllers\BaseController`
- BaseController extends CodeIgniter\Controller
```php
namespace App\Controllers;
class Admin extends BaseController {
public function index() {
// Method body
}
}
```
#### API Controllers
- Controllers use `ResponseTrait` for API responses
- Use `$this->respond()` or `$this->response->setJSON()` for responses
```php
namespace App\Controllers;
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']);
}
public function index() {
$query = $this->db->query("SELECT * FROM table");
return $this->respond(['data' => $query->getResultArray()]);
}
}
```
### Database Operations
#### Connection Pattern
```php
$this->db = \Config\Database::connect();
```
#### Query Methods
- `getRowArray()` - returns single row as associative array
- `getResultArray()` - returns multiple rows as array of arrays
- Use parameterized queries to prevent SQL injection
```php
$query = $this->db->query("SELECT * FROM table WHERE id = ?", [$id]);
$row = $query->getRowArray();
$results = $query->getResultArray();
```
#### Transactions
```php
$this->db->transBegin();
try {
$this->db->query("INSERT INTO ...", [$data]);
$this->db->transCommit();
} catch (\Throwable $e) {
$this->db->transRollback();
return $this->response->setJSON(['message' => 'Error']);
}
```
### Session Management
#### Session Structure
```php
$session->set([
'isLoggedIn' => true,
'userid' => (string) $user['USERID'],
'userlevel' => (int) $user['USERLEVEL'],
'userrole' => (string) $role, // 'admin', 'doctor', 'analyst', 'cs'
]);
```
#### Session Values
- `isLoggedIn`: bool
- `userid`: string
- `userlevel`: int
- `userrole`: string
### Role-Based Access Control
#### Role Values
- `1` = admin
- `2` = doctor (or lab/analyst)
- `3` = analyst
- `4` = cs (customer service)
#### Route Filter Syntax
```php
// Single role
['filter' => 'role:1']
// Multiple roles
['filter' => 'role:1,2']
```
### Request/Response Patterns
#### Getting Input
```php
// POST data
$input = $this->request->getJSON(true);
$userid = $input['userid'];
// Query parameters
$date1 = $this->request->getVar('date1') ?? date('Y-m-d');
```
#### JSON Response (V2 API)
```php
return $this->respond(['data' => $results]);
return $this->response->setJSON(['message' => 'Success']);
```
#### View Response (Traditional)
```php
return view('admin/index', $data);
```
#### Redirect with Errors
```php
return redirect()->back()->with('errors', ['key' => 'message']);
```
### API Endpoint Patterns
#### Validation Endpoints
- `POST /api/{resource}/validate/{id}` - validate a record
- `DELETE /api/{resource}/validate/{id}` - unvalidate a record
#### Route Examples
```php
// Admin routes
$routes->group('admin', ['filter' => 'role:1'], function($routes) {
$routes->get('/', 'Admin::index');
$routes->get('users', 'Admin::users');
$routes->get('api/users', 'Users::index');
$routes->post('api/users', 'Users::create');
});
// Lab routes
$routes->group('lab', ['filter' => 'role:2'], function($routes) {
$routes->get('/', 'Lab::index');
$routes->get('api/requests', 'Requests::index');
});
```
### Error Handling
#### Database Operations
```php
try {
// DB operations
} catch (\Throwable $e) {
// Handle error
return $this->response->setJSON(['message' => 'Server error']);
}
```
#### Validation Errors
```php
if ($condition) {
return $this->response->setJSON(['message' => 'Error message']);
}
```
### Views
#### View Pattern
- Views are plain PHP files in `app/Views/`
- Use `<?php echo $variable; ?>` syntax
- Pass data as associative array
```php
// Controller
$data['dataList'] = $results;
return view('admin/index', $data);
// View
<?php foreach ($dataList as $item): ?>
<tr><td><?= esc($item['name']) ?></td></tr>
<?php endforeach; ?>
```
### Security
- Always use parameterized queries (never interpolate directly)
- Use `esc()` when outputting user data in views
- Hash passwords with `password_hash()` and verify with `password_verify()`
- Validate and sanitize all input before use
### Helper Functions
Available helpers loaded via `helper(['name', 'name2'])`:
- `url` - URL helpers
- `form` - Form helpers
- `text` - Text formatting
### Database Schema
- Database: SQL Server
- Schema: `dbo`
- Main database: `GDC_CMOD`
- Reference database: `glendb`
- Table naming: `GDC_CMOD.dbo.TABLENAME`