Add Serena configuration and project memories; update report controller and view scripts
This commit is contained in:
parent
ea32cdab67
commit
4990934126
3
.gitignore
vendored
3
.gitignore
vendored
@ -124,6 +124,3 @@ _modules/*
|
|||||||
|
|
||||||
/results/
|
/results/
|
||||||
/phpunit*.xml
|
/phpunit*.xml
|
||||||
|
|
||||||
.claude/
|
|
||||||
.serena/
|
|
||||||
1
.serena/.gitignore
vendored
Normal file
1
.serena/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
/cache
|
||||||
103
.serena/memories/coding_conventions.md
Normal file
103
.serena/memories/coding_conventions.md
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
# Coding Conventions & Standards
|
||||||
|
|
||||||
|
## 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` |
|
||||||
|
| Routes | lowercase | `/admin/users` |
|
||||||
|
|
||||||
|
## 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,
|
||||||
|
]);
|
||||||
|
```
|
||||||
|
|
||||||
|
## Security Guidelines
|
||||||
|
- Use parameterized queries (never interpolate directly)
|
||||||
|
- Hash passwords with `password_hash()` / `password_verify()`
|
||||||
|
- Validate and sanitize all input before use
|
||||||
|
- Use `esc()` when outputting user data in views
|
||||||
|
|
||||||
|
## Validation Endpoints
|
||||||
|
- `POST /api/{resource}/validate/{id}` - validate a record
|
||||||
|
- `DELETE /api/{resource}/validate/{id}` - unvalidate a record
|
||||||
134
.serena/memories/project_commands.md
Normal file
134
.serena/memories/project_commands.md
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
# Development Commands
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
```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
|
||||||
|
|
||||||
|
# Generate code coverage report
|
||||||
|
./vendor/bin/phpunit --colors --coverage-text=tests/coverage.txt --coverage-html=tests/coverage/ -d memory_limit=1024m
|
||||||
|
```
|
||||||
|
|
||||||
|
## Development Server
|
||||||
|
```bash
|
||||||
|
# Start development server
|
||||||
|
php spark serve
|
||||||
|
```
|
||||||
|
|
||||||
|
## Code Generation (CLI)
|
||||||
|
```bash
|
||||||
|
# Create controller
|
||||||
|
php spark make:controller Admin
|
||||||
|
|
||||||
|
# Create model
|
||||||
|
php spark make:model User
|
||||||
|
```
|
||||||
|
|
||||||
|
## Routing
|
||||||
|
```bash
|
||||||
|
# List all routes
|
||||||
|
php spark list
|
||||||
|
```
|
||||||
|
|
||||||
|
## Git Commands (Windows)
|
||||||
|
```bash
|
||||||
|
# Check git status
|
||||||
|
git status
|
||||||
|
|
||||||
|
# Check git diff
|
||||||
|
git diff
|
||||||
|
|
||||||
|
# View recent commits
|
||||||
|
git log
|
||||||
|
|
||||||
|
# Add files to staging
|
||||||
|
git add .
|
||||||
|
|
||||||
|
# Create commit
|
||||||
|
git commit -m "message"
|
||||||
|
|
||||||
|
# Push to remote
|
||||||
|
git push
|
||||||
|
|
||||||
|
# Pull from remote
|
||||||
|
git pull
|
||||||
|
```
|
||||||
|
|
||||||
|
## File System Commands (Windows)
|
||||||
|
```bash
|
||||||
|
# List directory contents
|
||||||
|
ls
|
||||||
|
dir
|
||||||
|
|
||||||
|
# Change directory
|
||||||
|
cd directory_name
|
||||||
|
|
||||||
|
# Create directory
|
||||||
|
mkdir directory_name
|
||||||
|
|
||||||
|
# Copy files
|
||||||
|
copy source destination
|
||||||
|
|
||||||
|
# Move files
|
||||||
|
move source destination
|
||||||
|
|
||||||
|
# Remove files
|
||||||
|
del filename
|
||||||
|
rm filename
|
||||||
|
|
||||||
|
# Find files by name
|
||||||
|
dir /s /b filename
|
||||||
|
|
||||||
|
# Search content in files
|
||||||
|
findstr /s /i "search_term" *.php
|
||||||
|
```
|
||||||
|
|
||||||
|
## CodeIgniter-Specific
|
||||||
|
```bash
|
||||||
|
# Clear cache
|
||||||
|
php spark cache:clear
|
||||||
|
|
||||||
|
# Clear view cache
|
||||||
|
php spark cache:clear
|
||||||
|
|
||||||
|
# Install dependencies
|
||||||
|
composer install
|
||||||
|
composer update
|
||||||
|
|
||||||
|
# Dump autoload
|
||||||
|
composer dump-autoload
|
||||||
|
```
|
||||||
|
|
||||||
|
## What to do after completing a task
|
||||||
|
|
||||||
|
1. **Run tests**
|
||||||
|
```bash
|
||||||
|
composer test
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Check for errors**
|
||||||
|
- Review any output from tests
|
||||||
|
- Check for lint errors or warnings
|
||||||
|
|
||||||
|
3. **Verify the changes**
|
||||||
|
- Test the functionality manually
|
||||||
|
- Check if any routes or filters were affected
|
||||||
|
|
||||||
|
4. **Update documentation** (if needed)
|
||||||
|
- Add new routes to documentation
|
||||||
|
- Update CHECKLIST.md if it's a new feature
|
||||||
|
|
||||||
|
5. **Commit changes** (only when explicitly asked)
|
||||||
|
```bash
|
||||||
|
git add .
|
||||||
|
git commit -m "describe changes"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Important**: Never commit changes unless explicitly asked by the user.
|
||||||
38
.serena/memories/project_overview.md
Normal file
38
.serena/memories/project_overview.md
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
# GDC CMOD - Laboratory Management System
|
||||||
|
|
||||||
|
## Purpose
|
||||||
|
CodeIgniter 4 PHP application for laboratory management (GDC CMOD - Laboratory Request Management System). Handles specimen collection tracking, request validation, and result management with role-based access control.
|
||||||
|
|
||||||
|
## Tech Stack
|
||||||
|
- **Framework**: CodeIgniter 4 (PHP 8.1+)
|
||||||
|
- **Database**: SQL Server (primary) + Firebird/InterBase (legacy patient data via ODBC)
|
||||||
|
- **Frontend**: TailwindCSS + DaisyUI 5 + Alpine.js + Font Awesome 7
|
||||||
|
- **Testing**: PHPUnit 10.x
|
||||||
|
- **Server**: Windows (XAMPP/IIS)
|
||||||
|
|
||||||
|
## Database Architecture
|
||||||
|
- **Primary DB**: SQL Server (`GDC_CMOD.dbo`) via Microsoft ODBC Driver (MSOLEDBSQL)
|
||||||
|
- **Legacy DB**: Firebird/InterBase (`GLENEAGLES` via ODBC)
|
||||||
|
- **Connection**: `\Config\Database::connect()` returns MySQLi connection (configured as SQLSRV)
|
||||||
|
- **No CI4 Models**: Uses raw SQL queries via `Database::connect()->query()`
|
||||||
|
|
||||||
|
## Key Database Tables
|
||||||
|
- `GDC_CMOD.dbo.USERS` - Users with `USERID`, `USERROLEID`, `PASSWORD`
|
||||||
|
- `GDC_CMOD.dbo.CM_REQUESTS` - Validation tracking (`ISVAL1`, `ISVAL2`, validation users/dates)
|
||||||
|
- `GDC_CMOD.dbo.TUBES` - Sample collection status
|
||||||
|
- `GDC_CMOD.dbo.V_DASHBOARD_DEV` - Dashboard data view
|
||||||
|
- `glendb.dbo.*` - Legacy Firebird patient data
|
||||||
|
|
||||||
|
## Architecture Overview
|
||||||
|
- **Session-based authentication** with role-based access control (RBAC)
|
||||||
|
- **Dual-level validation** system requiring 2 different users to validate the same request
|
||||||
|
- **Role groups** filter middleware for routing control
|
||||||
|
- **API endpoints** for JSON responses
|
||||||
|
- **Page controllers** for HTML views
|
||||||
|
|
||||||
|
## Current Pending Features (CHECKLIST.md)
|
||||||
|
- Restrict Print/Save-to-PDF to CS Role only
|
||||||
|
- Add Dedicated Print Button
|
||||||
|
- Update PDF Report Metadata (Replace 'Printed By' with validating user's name)
|
||||||
|
- Reprint Label functionality
|
||||||
|
- Print Result Audit (Track when result reports are printed/exported)
|
||||||
107
.serena/memories/project_structure.md
Normal file
107
.serena/memories/project_structure.md
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
# Project Structure
|
||||||
|
|
||||||
|
## Directory Layout
|
||||||
|
```
|
||||||
|
gdc_cmod/
|
||||||
|
├── app/ # Application code
|
||||||
|
│ ├── Controllers/ # Controllers (API & Pages)
|
||||||
|
│ │ ├── Pages/ # Page controllers by role
|
||||||
|
│ │ │ ├── AdminController.php
|
||||||
|
│ │ │ ├── CsController.php
|
||||||
|
│ │ │ ├── LabController.php
|
||||||
|
│ │ │ ├── PhlebotomistController.php
|
||||||
|
│ │ │ └── SuperuserController.php
|
||||||
|
│ │ ├── ApiDashboard.php
|
||||||
|
│ │ ├── ApiRequestsAuditController.php
|
||||||
|
│ │ ├── ApiValidateController.php
|
||||||
|
│ │ ├── AuthController.php
|
||||||
|
│ │ ├── BaseController.php
|
||||||
|
│ │ ├── ErrorPage.php
|
||||||
|
│ │ ├── Home.php
|
||||||
|
│ │ ├── LabelController.php
|
||||||
|
│ │ ├── RequestsController.php
|
||||||
|
│ │ ├── SamplesController.php
|
||||||
|
│ │ └── UsersController.php
|
||||||
|
│ ├── Config/ # Configuration
|
||||||
|
│ │ ├── App.php
|
||||||
|
│ │ ├── Database.php
|
||||||
|
│ │ ├── Filters.php # Filter definitions
|
||||||
|
│ │ ├── Routes.php # Route definitions
|
||||||
|
│ │ └── ...
|
||||||
|
│ ├── Database/ # Database configurations
|
||||||
|
│ ├── Filters/ # Custom filters
|
||||||
|
│ │ ├── GuestFilter.php
|
||||||
|
│ │ ├── RoleFilter.php
|
||||||
|
│ │ └── .gitkeep
|
||||||
|
│ ├── Helpers/ # Helper functions
|
||||||
|
│ ├── Language/ # Language files
|
||||||
|
│ ├── Libraries/ # Custom libraries
|
||||||
|
│ ├── Models/ # Models (none used in this project)
|
||||||
|
│ ├── ThirdParty/ # Third-party code
|
||||||
|
│ └── Views/ # Views
|
||||||
|
│ ├── admin/ # Admin views
|
||||||
|
│ ├── cs/ # CS views
|
||||||
|
│ ├── errors/ # Error pages
|
||||||
|
│ ├── lab/ # Lab views
|
||||||
|
│ ├── phlebo/ # Phlebo views
|
||||||
|
│ ├── shared/ # Shared components
|
||||||
|
│ ├── superuser/ # Superuser views
|
||||||
|
│ └── ...
|
||||||
|
├── public/ # Web root
|
||||||
|
│ ├── index.php # Front controller
|
||||||
|
│ ├── .htaccess
|
||||||
|
│ ├── web.config
|
||||||
|
│ ├── css/ # Local CSS
|
||||||
|
│ └── js/ # Local JavaScript
|
||||||
|
├── tests/ # PHPUnit tests
|
||||||
|
│ ├── _support/ # Test support files
|
||||||
|
│ ├── database/ # Database tests
|
||||||
|
│ ├── session/ # Session tests
|
||||||
|
│ ├── unit/ # Unit tests
|
||||||
|
│ └── README.md
|
||||||
|
├── writable/ # Writeable directories
|
||||||
|
├── vendor/ # Composer dependencies
|
||||||
|
├── .env # Environment variables (git ignored)
|
||||||
|
├── env # Example environment file
|
||||||
|
├── .gitignore # Git ignore rules
|
||||||
|
├── AGENTS.md # Agent guidelines (this file)
|
||||||
|
├── CHECKLIST.md # Feature checklist
|
||||||
|
├── CLAUDE.md # Claude Code guidelines
|
||||||
|
├── composer.json # Composer dependencies
|
||||||
|
├── composer.lock # Locked dependencies
|
||||||
|
├── phpunit.xml.dist # PHPUnit configuration
|
||||||
|
├── preload.php # PHP OpCache preload
|
||||||
|
├── README.md # Project README
|
||||||
|
├── spark # CodeIgniter CLI tool
|
||||||
|
└── LICENSE # MIT License
|
||||||
|
```
|
||||||
|
|
||||||
|
## Key Files & Their Purposes
|
||||||
|
|
||||||
|
### Configuration
|
||||||
|
- **app/Config/Database.php** - Database connections (SQL Server + Firebird ODBC)
|
||||||
|
- **app/Config/Filters.php** - Filter definitions (RoleFilter, GuestFilter)
|
||||||
|
- **app/Config/Routes.php** - Route definitions (API and page routes)
|
||||||
|
- **app/Config/App.php** - Application settings (baseURL, etc.)
|
||||||
|
|
||||||
|
### Controllers
|
||||||
|
- **Pages/[Role]Controller.php** - Page controllers for each role
|
||||||
|
- **Api[Resource]Controller.php** - API controllers for JSON endpoints
|
||||||
|
- **AuthController.php** - Authentication (login/logout)
|
||||||
|
- **UsersController.php** - User management API
|
||||||
|
- **RequestsController.php** - Request validation API
|
||||||
|
- **SamplesController.php** - Sample collection API
|
||||||
|
|
||||||
|
### Filters
|
||||||
|
- **app/Filters/RoleFilter.php** - Check user role on protected routes
|
||||||
|
- **app/Filters/GuestFilter.php** - Redirect logged-in users from public pages
|
||||||
|
|
||||||
|
### Views
|
||||||
|
- **views/shared/** - Shared components used across roles
|
||||||
|
- **views/{role}/** - Role-specific views
|
||||||
|
- **views/login.php** - Login page
|
||||||
|
|
||||||
|
### Tests
|
||||||
|
- **tests/unit/** - Unit tests (HealthTest, etc.)
|
||||||
|
- **tests/database/** - Database tests
|
||||||
|
- **tests/session/** - Session tests
|
||||||
104
.serena/memories/rbac_system.md
Normal file
104
.serena/memories/rbac_system.md
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
# Role-Based Access Control (RBAC)
|
||||||
|
|
||||||
|
## Role Definitions
|
||||||
|
|
||||||
|
| Role ID | Name | Route Prefix | Permissions |
|
||||||
|
|---------|------|--------------|-------------|
|
||||||
|
| 0 | Superuser | `/superuser` | Full access + Users CRUD |
|
||||||
|
| 1 | Admin | `/admin` | Full access + Users CRUD |
|
||||||
|
| 2 | Lab | `/lab` | Request validation, Sample collection |
|
||||||
|
| 3 | Phlebo | `/phlebo` | Specimen collection, Dashboard |
|
||||||
|
| 4 | CS | `/cs` | Dashboard, Status Monitoring, Patient Inquiry |
|
||||||
|
|
||||||
|
## Route Filtering
|
||||||
|
|
||||||
|
### Role Filter
|
||||||
|
```php
|
||||||
|
// Single role
|
||||||
|
['filter' => 'role:1']
|
||||||
|
|
||||||
|
// Multiple roles
|
||||||
|
['filter' => 'role:1,2']
|
||||||
|
```
|
||||||
|
|
||||||
|
### Filter Usage
|
||||||
|
|
||||||
|
**app/Filters/RoleFilter.php**
|
||||||
|
- Checks `session()->get('isLoggedIn')` - redirects to `/login` if not logged in
|
||||||
|
- Checks role ID against allowed roles from route arguments
|
||||||
|
- Redirects to `/unauthorized` if role not authorized
|
||||||
|
|
||||||
|
**app/Filters/GuestFilter.php**
|
||||||
|
- Redirects logged-in users to role-based dashboard
|
||||||
|
- Use for public-only routes (e.g., `/login`)
|
||||||
|
|
||||||
|
## Route Prefixes & Controllers
|
||||||
|
|
||||||
|
### Superuser (Role 0)
|
||||||
|
- `/superuser` - Pages\SuperuserController::index
|
||||||
|
- `/superuser/users` - Pages\SuperuserController::users
|
||||||
|
- `/superuser/validate` - Pages\SuperuserController::validatePage
|
||||||
|
|
||||||
|
### Admin (Role 1)
|
||||||
|
- `/admin` - Pages\AdminController::index
|
||||||
|
- `/admin/users` - Pages\AdminController::users
|
||||||
|
- `/admin/validate` - Pages\AdminController::validationPage
|
||||||
|
|
||||||
|
### Lab (Role 2)
|
||||||
|
- `/lab` - Pages\LabController::index
|
||||||
|
- `/lab/validate` - Pages\LabController::validationPage
|
||||||
|
|
||||||
|
### Phlebo (Role 3)
|
||||||
|
- `/phlebo` - Pages\PhlebotomistController::index
|
||||||
|
|
||||||
|
### CS (Role 4)
|
||||||
|
- `/cs` - Pages\CsController::index
|
||||||
|
|
||||||
|
## Validation System (Dual-Level)
|
||||||
|
|
||||||
|
Validation requires 2 different users to validate the same request:
|
||||||
|
|
||||||
|
**First Validation:**
|
||||||
|
- Sets `ISVAL1=1`
|
||||||
|
- Records `VAL1USER` (username)
|
||||||
|
- Records `VAL1DATE` (datetime)
|
||||||
|
|
||||||
|
**Second Validation (different user):**
|
||||||
|
- Sets `ISVAL2=1`
|
||||||
|
- Records `VAL2USER` (username)
|
||||||
|
- Records `VAL2DATE` (datetime)
|
||||||
|
|
||||||
|
**Validation Permission:**
|
||||||
|
- Available to Role 0, 1, 2 (Superuser, Admin, Lab)
|
||||||
|
|
||||||
|
## Unvalidation
|
||||||
|
- Available to Role 0, 1 (Superuser, Admin)
|
||||||
|
- Sets `ISVAL1=0` and `ISVAL2=0`, clears validation user/date fields
|
||||||
|
|
||||||
|
## Authentication Flow
|
||||||
|
|
||||||
|
1. **AuthController::login()** - Verifies credentials against `GDC_CMOD.dbo.USERS`, sets session
|
||||||
|
2. **RoleFilter** - Runs on protected routes, checks `session()->get('isLoggedIn')` and role ID
|
||||||
|
3. **GuestFilter** - Runs on public routes, redirects logged-in users to dashboard
|
||||||
|
|
||||||
|
## API Endpoint Permissions
|
||||||
|
|
||||||
|
### Users Management
|
||||||
|
- **Access**: Role 0, 1 (Superuser, Admin)
|
||||||
|
- **Endpoints**: GET, POST, PATCH, DELETE on `/api/users`
|
||||||
|
|
||||||
|
### Requests
|
||||||
|
- **Access**: Role 0, 1, 2, 3, 4 (All Roles)
|
||||||
|
- **Endpoints**:
|
||||||
|
- `GET /api/requests` - Dashboard data
|
||||||
|
- `POST /api/requests/validate/:id` - Validate request
|
||||||
|
- `DELETE /api/requests/validate/:id` - Unvalidate request
|
||||||
|
- `GET /api/requests/:id/audit` - Audit trail
|
||||||
|
|
||||||
|
### Samples
|
||||||
|
- **Access**: All Roles for collect/show
|
||||||
|
- **Unreceive**: Role 0, 1 only
|
||||||
|
- **Endpoints**:
|
||||||
|
- `POST /api/samples/collect/:accessnumber` - Mark sample collected
|
||||||
|
- `GET /api/samples/:accessnumber` - Show sample info
|
||||||
|
- `DELETE /api/samples/receive/:accessnumber` - Unreceive sample
|
||||||
136
.serena/memories/routes_patterns.md
Normal file
136
.serena/memories/routes_patterns.md
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
# Route Patterns
|
||||||
|
|
||||||
|
## Route File Structure
|
||||||
|
File: **app/Config/Routes.php**
|
||||||
|
|
||||||
|
## Public Routes
|
||||||
|
```php
|
||||||
|
$routes->get('/', 'Home::index');
|
||||||
|
$routes->get('/login', 'AuthController::loginPage', ['filter' => 'guest']);
|
||||||
|
$routes->post('/login', 'AuthController::login', ['filter' => 'guest']);
|
||||||
|
$routes->get('/logout', 'AuthController::logout');
|
||||||
|
$routes->patch('/setPassword', 'AuthController::setPassword');
|
||||||
|
```
|
||||||
|
|
||||||
|
## Label Routes (Public)
|
||||||
|
```php
|
||||||
|
$routes->get('label/coll/(:any)', 'LabelController::coll/$1');
|
||||||
|
$routes->get('label/dispatch/(:any)/(:any)', 'LabelController::dispatch/$1/$2');
|
||||||
|
$routes->get('label/all/(:any)', 'LabelController::print_all/$1');
|
||||||
|
```
|
||||||
|
|
||||||
|
## API Routes (Protected by Role Filter)
|
||||||
|
File: **app/Config/Routes.php** - `$routes->group('api', ...)` block
|
||||||
|
|
||||||
|
### Users Management
|
||||||
|
```php
|
||||||
|
$routes->group('users', ['filter' => 'role:0,1'], function ($routes) {
|
||||||
|
$routes->get('', 'UsersController::index'); // Get all users
|
||||||
|
$routes->post('', 'UsersController::create'); // Create user
|
||||||
|
$routes->patch('(:any)', 'UsersController::update/$1'); // Update user
|
||||||
|
$routes->delete('(:any)', 'UsersController::delete/$1'); // Delete user
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### Requests
|
||||||
|
```php
|
||||||
|
$routes->group('requests', ['filter' => 'role:0,1,2,3,4'], function ($routes) {
|
||||||
|
$routes->get('', 'RequestsController::index'); // Dashboard data
|
||||||
|
$routes->get('(:any)/audit', 'ApiRequestsAuditController::show/$1'); // Audit trail
|
||||||
|
$routes->post('validate/(:any)', 'RequestsController::val/$1'); // Validate request
|
||||||
|
$routes->delete('validate/(:any)', 'RequestsController::unval/$1'); // Unvalidate request
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### Validate API
|
||||||
|
```php
|
||||||
|
$routes->group('validate', ['filter' => 'role:0,1,2'], function ($routes) {
|
||||||
|
$routes->get('unvalidated', 'ApiValidateController::unvalidated'); // Get unvalidated requests
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### Samples
|
||||||
|
```php
|
||||||
|
$routes->group('samples', function ($routes) {
|
||||||
|
// Collect & Show - All Roles
|
||||||
|
$routes->group('', ['filter' => 'role:0,1,2,3,4'], function ($routes) {
|
||||||
|
$routes->post('collect/(:any)', 'SamplesController::collect/$1');
|
||||||
|
$routes->get('(:any)', 'SamplesController::show/$1');
|
||||||
|
});
|
||||||
|
|
||||||
|
// Unreceive - Only Superuser (0) and Admin (1)
|
||||||
|
$routes->group('', ['filter' => 'role:0,1'], function ($routes) {
|
||||||
|
$routes->delete('receive/(:any)', 'SamplesController::unreceive/$1');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
## Page Routes (Protected by Role Filter)
|
||||||
|
|
||||||
|
### Superuser (Role 0)
|
||||||
|
```php
|
||||||
|
$routes->group('superuser', ['filter' => 'role:0'], function ($routes) {
|
||||||
|
$routes->get('', 'Pages\SuperuserController::index');
|
||||||
|
$routes->get('users', 'Pages\SuperuserController::users');
|
||||||
|
$routes->get('validate', 'Pages\SuperuserController::validatePage');
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### Admin (Role 1)
|
||||||
|
```php
|
||||||
|
$routes->group('admin', ['filter' => 'role:1'], function ($routes) {
|
||||||
|
$routes->get('', 'Pages\AdminController::index');
|
||||||
|
$routes->get('users', 'Pages\AdminController::users');
|
||||||
|
$routes->get('validate', 'Pages\AdminController::validationPage');
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### Lab (Role 2)
|
||||||
|
```php
|
||||||
|
$routes->group('lab', ['filter' => 'role:2'], function ($routes) {
|
||||||
|
$routes->get('', 'Pages\LabController::index');
|
||||||
|
$routes->get('validate', 'Pages\LabController::validationPage');
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### Phlebo (Role 3)
|
||||||
|
```php
|
||||||
|
$routes->group('phlebo', ['filter' => 'role:3'], function ($routes) {
|
||||||
|
$routes->get('', 'Pages\PhlebotomistController::index');
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### CS (Role 4)
|
||||||
|
```php
|
||||||
|
$routes->group('cs', ['filter' => 'role:4'], function ($routes) {
|
||||||
|
$routes->get('', 'Pages\CsController::index');
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
## Error Handling
|
||||||
|
```php
|
||||||
|
$routes->set404Override(function () {
|
||||||
|
$response = service('response');
|
||||||
|
$response->setStatusCode(404);
|
||||||
|
echo view('errors/notfound');
|
||||||
|
});
|
||||||
|
$routes->get('/unauthorized', 'ErrorPage::unauthorized');
|
||||||
|
```
|
||||||
|
|
||||||
|
## Route Filter Order
|
||||||
|
1. **Before filters** (run before request):
|
||||||
|
- `forcehttps` - Force HTTPS
|
||||||
|
- `pagecache` - Web page caching
|
||||||
|
- `role` - Role-based access (on protected routes)
|
||||||
|
- `guest` - Guest-only (on public routes)
|
||||||
|
|
||||||
|
2. **After filters** (run after response):
|
||||||
|
- `pagecache` - Web page caching
|
||||||
|
- `performance` - Performance metrics
|
||||||
|
- `toolbar` - Debug toolbar
|
||||||
|
|
||||||
|
## Route Naming Conventions
|
||||||
|
- API endpoints: kebab-case, under `/api/` prefix
|
||||||
|
- Page routes: kebab-case, grouped by role
|
||||||
|
- Resource endpoints: standard REST pattern (`/resource/{id}`)
|
||||||
|
- Action endpoints: kebab-case, snake_case for parameters
|
||||||
123
.serena/project.yml
Normal file
123
.serena/project.yml
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
# the name by which the project can be referenced within Serena
|
||||||
|
project_name: "gdc_cmod"
|
||||||
|
|
||||||
|
|
||||||
|
# list of languages for which language servers are started; choose from:
|
||||||
|
# al bash clojure cpp csharp
|
||||||
|
# csharp_omnisharp dart elixir elm erlang
|
||||||
|
# fortran fsharp go groovy haskell
|
||||||
|
# java julia kotlin lua markdown
|
||||||
|
# matlab nix pascal perl php
|
||||||
|
# powershell python python_jedi r rego
|
||||||
|
# ruby ruby_solargraph rust scala swift
|
||||||
|
# terraform toml typescript typescript_vts vue
|
||||||
|
# yaml zig
|
||||||
|
# (This list may be outdated. For the current list, see values of Language enum here:
|
||||||
|
# https://github.com/oraios/serena/blob/main/src/solidlsp/ls_config.py
|
||||||
|
# For some languages, there are alternative language servers, e.g. csharp_omnisharp, ruby_solargraph.)
|
||||||
|
# Note:
|
||||||
|
# - For C, use cpp
|
||||||
|
# - For JavaScript, use typescript
|
||||||
|
# - For Free Pascal/Lazarus, use pascal
|
||||||
|
# Special requirements:
|
||||||
|
# Some languages require additional setup/installations.
|
||||||
|
# See here for details: https://oraios.github.io/serena/01-about/020_programming-languages.html#language-servers
|
||||||
|
# When using multiple languages, the first language server that supports a given file will be used for that file.
|
||||||
|
# The first language is the default language and the respective language server will be used as a fallback.
|
||||||
|
# Note that when using the JetBrains backend, language servers are not used and this list is correspondingly ignored.
|
||||||
|
languages:
|
||||||
|
- php
|
||||||
|
|
||||||
|
# the encoding used by text files in the project
|
||||||
|
# For a list of possible encodings, see https://docs.python.org/3.11/library/codecs.html#standard-encodings
|
||||||
|
encoding: "utf-8"
|
||||||
|
|
||||||
|
# whether to use project's .gitignore files to ignore files
|
||||||
|
ignore_all_files_in_gitignore: true
|
||||||
|
|
||||||
|
# list of additional paths to ignore in all projects
|
||||||
|
# same syntax as gitignore, so you can use * and **
|
||||||
|
ignored_paths: []
|
||||||
|
|
||||||
|
# whether the project is in read-only mode
|
||||||
|
# If set to true, all editing tools will be disabled and attempts to use them will result in an error
|
||||||
|
# Added on 2025-04-18
|
||||||
|
read_only: false
|
||||||
|
|
||||||
|
# list of tool names to exclude. We recommend not excluding any tools, see the readme for more details.
|
||||||
|
# Below is the complete list of tools for convenience.
|
||||||
|
# To make sure you have the latest list of tools, and to view their descriptions,
|
||||||
|
# execute `uv run scripts/print_tool_overview.py`.
|
||||||
|
#
|
||||||
|
# * `activate_project`: Activates a project by name.
|
||||||
|
# * `check_onboarding_performed`: Checks whether project onboarding was already performed.
|
||||||
|
# * `create_text_file`: Creates/overwrites a file in the project directory.
|
||||||
|
# * `delete_lines`: Deletes a range of lines within a file.
|
||||||
|
# * `delete_memory`: Deletes a memory from Serena's project-specific memory store.
|
||||||
|
# * `execute_shell_command`: Executes a shell command.
|
||||||
|
# * `find_referencing_code_snippets`: Finds code snippets in which the symbol at the given location is referenced.
|
||||||
|
# * `find_referencing_symbols`: Finds symbols that reference the symbol at the given location (optionally filtered by type).
|
||||||
|
# * `find_symbol`: Performs a global (or local) search for symbols with/containing a given name/substring (optionally filtered by type).
|
||||||
|
# * `get_current_config`: Prints the current configuration of the agent, including the active and available projects, tools, contexts, and modes.
|
||||||
|
# * `get_symbols_overview`: Gets an overview of the top-level symbols defined in a given file.
|
||||||
|
# * `initial_instructions`: Gets the initial instructions for the current project.
|
||||||
|
# Should only be used in settings where the system prompt cannot be set,
|
||||||
|
# e.g. in clients you have no control over, like Claude Desktop.
|
||||||
|
# * `insert_after_symbol`: Inserts content after the end of the definition of a given symbol.
|
||||||
|
# * `insert_at_line`: Inserts content at a given line in a file.
|
||||||
|
# * `insert_before_symbol`: Inserts content before the beginning of the definition of a given symbol.
|
||||||
|
# * `list_dir`: Lists files and directories in the given directory (optionally with recursion).
|
||||||
|
# * `list_memories`: Lists memories in Serena's project-specific memory store.
|
||||||
|
# * `onboarding`: Performs onboarding (identifying the project structure and essential tasks, e.g. for testing or building).
|
||||||
|
# * `prepare_for_new_conversation`: Provides instructions for preparing for a new conversation (in order to continue with the necessary context).
|
||||||
|
# * `read_file`: Reads a file within the project directory.
|
||||||
|
# * `read_memory`: Reads the memory with the given name from Serena's project-specific memory store.
|
||||||
|
# * `remove_project`: Removes a project from the Serena configuration.
|
||||||
|
# * `replace_lines`: Replaces a range of lines within a file with new content.
|
||||||
|
# * `replace_symbol_body`: Replaces the full definition of a symbol.
|
||||||
|
# * `restart_language_server`: Restarts the language server, may be necessary when edits not through Serena happen.
|
||||||
|
# * `search_for_pattern`: Performs a search for a pattern in the project.
|
||||||
|
# * `summarize_changes`: Provides instructions for summarizing the changes made to the codebase.
|
||||||
|
# * `switch_modes`: Activates modes by providing a list of their names
|
||||||
|
# * `think_about_collected_information`: Thinking tool for pondering the completeness of collected information.
|
||||||
|
# * `think_about_task_adherence`: Thinking tool for determining whether the agent is still on track with the current task.
|
||||||
|
# * `think_about_whether_you_are_done`: Thinking tool for determining whether the task is truly completed.
|
||||||
|
# * `write_memory`: Writes a named memory (for future reference) to Serena's project-specific memory store.
|
||||||
|
excluded_tools: []
|
||||||
|
|
||||||
|
# list of tools to include that would otherwise be disabled (particularly optional tools that are disabled by default)
|
||||||
|
included_optional_tools: []
|
||||||
|
|
||||||
|
# fixed set of tools to use as the base tool set (if non-empty), replacing Serena's default set of tools.
|
||||||
|
# This cannot be combined with non-empty excluded_tools or included_optional_tools.
|
||||||
|
fixed_tools: []
|
||||||
|
|
||||||
|
# list of mode names to that are always to be included in the set of active modes
|
||||||
|
# The full set of modes to be activated is base_modes + default_modes.
|
||||||
|
# If the setting is undefined, the base_modes from the global configuration (serena_config.yml) apply.
|
||||||
|
# Otherwise, this setting overrides the global configuration.
|
||||||
|
# Set this to [] to disable base modes for this project.
|
||||||
|
# Set this to a list of mode names to always include the respective modes for this project.
|
||||||
|
base_modes:
|
||||||
|
|
||||||
|
# list of mode names that are to be activated by default.
|
||||||
|
# The full set of modes to be activated is base_modes + default_modes.
|
||||||
|
# If the setting is undefined, the default_modes from the global configuration (serena_config.yml) apply.
|
||||||
|
# Otherwise, this overrides the setting from the global configuration (serena_config.yml).
|
||||||
|
# This setting can, in turn, be overridden by CLI parameters (--mode).
|
||||||
|
default_modes:
|
||||||
|
|
||||||
|
# initial prompt for the project. It will always be given to the LLM upon activating the project
|
||||||
|
# (contrary to the memories, which are loaded on demand).
|
||||||
|
initial_prompt: ""
|
||||||
|
|
||||||
|
# override of the corresponding setting in serena_config.yml, see the documentation there.
|
||||||
|
# If null or missing, the value from the global config is used.
|
||||||
|
symbol_info_budget:
|
||||||
|
|
||||||
|
# The language backend to use for this project.
|
||||||
|
# If not set, the global setting from serena_config.yml is used.
|
||||||
|
# Valid values: LSP, JetBrains
|
||||||
|
# Note: the backend is fixed at startup. If a project with a different backend
|
||||||
|
# is activated post-init, an error will be returned.
|
||||||
|
language_backend:
|
||||||
@ -117,9 +117,10 @@ class ReportController extends BaseController
|
|||||||
$html = view('report/template', $data);
|
$html = view('report/template', $data);
|
||||||
$filename = $accessnumber . ($eng == 1 ? '_eng' : '') . '.pdf';
|
$filename = $accessnumber . ($eng == 1 ? '_eng' : '') . '.pdf';
|
||||||
$collectionDate = $data['collectionDate'] ?? '';
|
$collectionDate = $data['collectionDate'] ?? '';
|
||||||
|
$hostnumber = $data['hostnumber'] ?? '';
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$jobId = $this->postToSpooler($html, $filename, $collectionDate, $accessnumber);
|
$jobId = $this->postToSpooler($html, $filename, $collectionDate, $accessnumber, $hostnumber);
|
||||||
|
|
||||||
$sqlCheck = "SELECT COUNT(*) as cnt FROM GDC_CMOD.dbo.AUDIT_REQUESTS
|
$sqlCheck = "SELECT COUNT(*) as cnt FROM GDC_CMOD.dbo.AUDIT_REQUESTS
|
||||||
WHERE ACCESSNUMBER = ? AND STEPTYPE IN ('GEN_PDF', 'REGEN_PDF')";
|
WHERE ACCESSNUMBER = ? AND STEPTYPE IN ('GEN_PDF', 'REGEN_PDF')";
|
||||||
@ -171,7 +172,7 @@ try {
|
|||||||
return $this->response->setJSON($response);
|
return $this->response->setJSON($response);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function postToSpooler($html, $filename, $collectionDate = '', $accessnumber = '')
|
private function postToSpooler($html, $filename, $collectionDate = '', $accessnumber = '', $hostnumber = '')
|
||||||
{
|
{
|
||||||
$ch = curl_init();
|
$ch = curl_init();
|
||||||
curl_setopt($ch, CURLOPT_URL, 'http://glenlis:3000/api/pdf/generate');
|
curl_setopt($ch, CURLOPT_URL, 'http://glenlis:3000/api/pdf/generate');
|
||||||
@ -190,6 +191,10 @@ try {
|
|||||||
$payload['accessnumber'] = $accessnumber;
|
$payload['accessnumber'] = $accessnumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($hostnumber) {
|
||||||
|
$payload['hostnumber'] = $hostnumber;
|
||||||
|
}
|
||||||
|
|
||||||
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
|
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
|
||||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||||
curl_setopt($ch, CURLOPT_HTTPHEADER, [
|
curl_setopt($ch, CURLOPT_HTTPHEADER, [
|
||||||
|
|||||||
@ -419,7 +419,7 @@ document.addEventListener('alpine:init', () => {
|
|||||||
},
|
},
|
||||||
|
|
||||||
async generatePdfFromDialog() {
|
async generatePdfFromDialog() {
|
||||||
const eng = this.generateLang === 1 ? '?eng=1' : '';
|
const eng = this.generateLang === 1 ? '?eng=1' : '?eng=0';
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const res = await fetch(`${BASEURL}report/${this.generateAccessnumber}/pdf${eng}`);
|
const res = await fetch(`${BASEURL}report/${this.generateAccessnumber}/pdf${eng}`);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user